mirror of
https://github.com/moibenko/mtx.git
synced 2026-01-05 19:54:50 +00:00
MTX with library.
Allows to call mtx routines.
The rpm for this version must be built as:
Replace mtx.spec in SPECS
Put *.patch into SOURCES
and build rpm.
This commit is contained in:
@@ -3,16 +3,17 @@
|
|||||||
# USE GMAKE, NOT REGULAR BSD MAKE!)
|
# USE GMAKE, NOT REGULAR BSD MAKE!)
|
||||||
#
|
#
|
||||||
# Valid targets:
|
# Valid targets:
|
||||||
# linux86 freebsd86 solarissparc sgi dec vms
|
# linux86 freebsd86 solarissparc sgi dec vms
|
||||||
#
|
#
|
||||||
# Makefile changes by Lars Kellogg-Stedman for better integration with
|
# Makefile changes by Lars Kellogg-Stedman for better integration with
|
||||||
# GNU Autoconf.
|
# GNU Autoconf.
|
||||||
|
|
||||||
# Version # for 'make dist'...
|
# Version # for 'make dist'...
|
||||||
VERSION=1.3.12
|
VERSION=1.3.12
|
||||||
|
|
||||||
BINS = mtx@EXEEXT@ tapeinfo@EXEEXT@ loaderinfo@EXEEXT@ scsitape@EXEEXT@ scsieject@EXEEXT@
|
BINS = mtx@EXEEXT@ tapeinfo@EXEEXT@ loaderinfo@EXEEXT@ scsitape@EXEEXT@ scsieject@EXEEXT@
|
||||||
EXTRA_BINS = nsmhack@EXEEXT@
|
EXTRA_BINS = nsmhack@EXEEXT@
|
||||||
|
LIB=libmtx.a
|
||||||
DBGS := $(BINS:%@EXEEXT@=%.dbg)
|
DBGS := $(BINS:%@EXEEXT@=%.dbg)
|
||||||
MAN = mtx.1 tapeinfo.1 loaderinfo.1 scsitape.1 scsieject.1
|
MAN = mtx.1 tapeinfo.1 loaderinfo.1 scsitape.1 scsieject.1
|
||||||
MAN_HTML := $(MAN:%.1=%.html)
|
MAN_HTML := $(MAN:%.1=%.html)
|
||||||
@@ -46,7 +47,7 @@ VPATH = $(srcdir)
|
|||||||
# Linux on x86...
|
# Linux on x86...
|
||||||
#
|
#
|
||||||
ifeq ($(TARGET),linux)
|
ifeq ($(TARGET),linux)
|
||||||
CFLAGS += -Wall
|
CFLAGS += -Wall -fpic -O3
|
||||||
CPPFLAGS += -DLONG_PRINT_REQUEST_SENSE=1
|
CPPFLAGS += -DLONG_PRINT_REQUEST_SENSE=1
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@@ -64,7 +65,7 @@ LIBS += -lcam
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(TARGET),hpux)
|
ifeq ($(TARGET),hpux)
|
||||||
CFLAGS += -O -D_HPUX_SOURCE -D __hpux__
|
CFLAGS += -O -D_HPUX_SOURCE -D __hpux__
|
||||||
endif
|
endif
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -105,7 +106,7 @@ else
|
|||||||
strip $< -o $@
|
strip $< -o $@
|
||||||
endif
|
endif
|
||||||
|
|
||||||
all: $(BINS)
|
all: $(BINS) $(LIB)
|
||||||
|
|
||||||
dbgs: $(DBGS)
|
dbgs: $(DBGS)
|
||||||
|
|
||||||
@@ -113,7 +114,7 @@ install: $(BINS)
|
|||||||
$(INSTALL_DIR) $(DESTDIR)$(sbindir)
|
$(INSTALL_DIR) $(DESTDIR)$(sbindir)
|
||||||
for file in $(BINS); do \
|
for file in $(BINS); do \
|
||||||
$(INSTALL_BIN) "$$file" $(DESTDIR)$(sbindir) ; \
|
$(INSTALL_BIN) "$$file" $(DESTDIR)$(sbindir) ; \
|
||||||
done
|
done
|
||||||
$(INSTALL_DIR) $(DESTDIR)$(mandir) $(DESTDIR)$(mandir)/man1
|
$(INSTALL_DIR) $(DESTDIR)$(mandir) $(DESTDIR)$(mandir)/man1
|
||||||
for file in mtx.1 tapeinfo.1 scsitape.1 scsieject.1 loaderinfo.1 ; do \
|
for file in mtx.1 tapeinfo.1 scsitape.1 scsieject.1 loaderinfo.1 ; do \
|
||||||
$(INSTALL_DOC) "$$file" $(DESTDIR)$(mandir)/man1 ; \
|
$(INSTALL_DOC) "$$file" $(DESTDIR)$(mandir)/man1 ; \
|
||||||
@@ -132,7 +133,7 @@ distclean: clean
|
|||||||
rm -f Makefile config.h config.log config.cache config.status
|
rm -f Makefile config.h config.log config.cache config.status
|
||||||
|
|
||||||
dist: distclean
|
dist: distclean
|
||||||
./makedist $(VERSION)
|
./makedist $(VERSION)
|
||||||
|
|
||||||
loaderinfo@EXEEXT@: loaderinfo.o mtxl.o mtxl.h mtx.h $(EXTRA)
|
loaderinfo@EXEEXT@: loaderinfo.o mtxl.o mtxl.h mtx.h $(EXTRA)
|
||||||
$(CC) $(LDFLAGS) -o loaderinfo@EXEEXT@ loaderinfo.o mtxl.o $(EXTRA) $(LIBS)
|
$(CC) $(LDFLAGS) -o loaderinfo@EXEEXT@ loaderinfo.o mtxl.o $(EXTRA) $(LIBS)
|
||||||
@@ -143,7 +144,7 @@ nsmhack@EXEEXT@: nsmhack.o mtxl.o $(EXTRA)
|
|||||||
mtx@EXEEXT@: mtx.o mtxl.o mtxl.h mtx.h $(EXTRA)
|
mtx@EXEEXT@: mtx.o mtxl.o mtxl.h mtx.h $(EXTRA)
|
||||||
$(CC) $(LDFLAGS) -o mtx@EXEEXT@ mtx.o mtxl.o $(EXTRA) $(LIBS)
|
$(CC) $(LDFLAGS) -o mtx@EXEEXT@ mtx.o mtxl.o $(EXTRA) $(LIBS)
|
||||||
|
|
||||||
mam2debug@EXEEXT@: mtxl.o mam2debug.o mtx.h $(EXTRA)
|
mam2debug@EXEEXT@: mtxl.o mam2debug.o mtx.h $(EXTRA)
|
||||||
$(CC) $(LDFLAGS) -o mam2debug@EXEEXT@ mtxl.o mam2debug.o $(EXTRA) $(LIBS)
|
$(CC) $(LDFLAGS) -o mam2debug@EXEEXT@ mtxl.o mam2debug.o $(EXTRA) $(LIBS)
|
||||||
|
|
||||||
tapeinfo@EXEEXT@: tapeinfo.o mtxl.o mtx.h mtxl.h $(EXTRA)
|
tapeinfo@EXEEXT@: tapeinfo.o mtxl.o mtx.h mtxl.h $(EXTRA)
|
||||||
@@ -160,6 +161,9 @@ scsitape.o: scsitape.c mtx.h mtxl.h
|
|||||||
scsieject@EXEEXT@: scsieject.o mtxl.o mtxl.h mtx.h $(EXTRA)
|
scsieject@EXEEXT@: scsieject.o mtxl.o mtxl.h mtx.h $(EXTRA)
|
||||||
$(CC) $(LDFLAGS) -o scsieject@EXEEXT@ scsieject.o mtxl.o $(EXTRA) $(LIBS)
|
$(CC) $(LDFLAGS) -o scsieject@EXEEXT@ scsieject.o mtxl.o $(EXTRA) $(LIBS)
|
||||||
|
|
||||||
|
$(LIB): mtx.o mtxl.o
|
||||||
|
ar qvs contrib/$(LIB) mtx.o mtxl.o
|
||||||
|
$(CC) $(LDFLAGS) -shared -o contrib/libmtx.so mtx.o mtxl.o
|
||||||
scsieject.o: scsieject.c mtx.h mtxl.h
|
scsieject.o: scsieject.c mtx.h mtxl.h
|
||||||
|
|
||||||
loaderinfo.o: loaderinfo.c mtx.h mtxl.h
|
loaderinfo.o: loaderinfo.c mtx.h mtxl.h
|
||||||
|
|||||||
@@ -79,7 +79,8 @@ static char *PeripheralDeviceType[32] =
|
|||||||
static int argc;
|
static int argc;
|
||||||
static char **argv;
|
static char **argv;
|
||||||
|
|
||||||
static char *device=NULL; /* the device name passed as argument */
|
char *device=NULL; /* the device name passed as argument */
|
||||||
|
int absolute_addressing=0; /* if not 0 - use absolute adresses of storage and tranport elements as known to the robot */
|
||||||
|
|
||||||
/* Unfortunately this must be true for SGI, because SGI does not
|
/* Unfortunately this must be true for SGI, because SGI does not
|
||||||
use an int :-(.
|
use an int :-(.
|
||||||
@@ -496,14 +497,24 @@ static void Status(void)
|
|||||||
TransferElementNumber < ElementStatus->DataTransferElementCount;
|
TransferElementNumber < ElementStatus->DataTransferElementCount;
|
||||||
TransferElementNumber++)
|
TransferElementNumber++)
|
||||||
{
|
{
|
||||||
|
if (absolute_addressing==0) {
|
||||||
printf("Data Transfer Element %d:", TransferElementNumber);
|
printf("Data Transfer Element %d:", TransferElementNumber);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf("Data Transfer Element %d :", ElementStatus->DataTransferElementAddress[TransferElementNumber]);
|
||||||
|
}
|
||||||
if (ElementStatus->DataTransferElementFull[TransferElementNumber])
|
if (ElementStatus->DataTransferElementFull[TransferElementNumber])
|
||||||
{
|
{
|
||||||
if (ElementStatus->DataTransferElementSourceStorageElementNumber[TransferElementNumber] > -1)
|
if (ElementStatus->DataTransferElementSourceStorageElementNumber[TransferElementNumber] > -1)
|
||||||
{
|
{
|
||||||
printf("Full (Storage Element %d Loaded)",
|
if (absolute_addressing==0) {
|
||||||
ElementStatus->DataTransferElementSourceStorageElementNumber[TransferElementNumber]+1);
|
printf("Full (Storage Element %d Loaded)",
|
||||||
|
ElementStatus->DataTransferElementSourceStorageElementNumber[TransferElementNumber]+1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf("Full (Storage Element %d Loaded)",
|
||||||
|
ElementStatus->StorageElementAddress[TransferElementNumber]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -531,9 +542,16 @@ static void Status(void)
|
|||||||
StorageElementNumber < ElementStatus->StorageElementCount;
|
StorageElementNumber < ElementStatus->StorageElementCount;
|
||||||
StorageElementNumber++)
|
StorageElementNumber++)
|
||||||
{
|
{
|
||||||
|
if (absolute_addressing==0) {
|
||||||
printf( " Storage Element %d%s:%s", StorageElementNumber + 1,
|
printf( " Storage Element %d%s:%s", StorageElementNumber + 1,
|
||||||
(ElementStatus->StorageElementIsImportExport[StorageElementNumber]) ? " IMPORT/EXPORT" : "",
|
(ElementStatus->StorageElementIsImportExport[StorageElementNumber]) ? " IMPORT/EXPORT" : "",
|
||||||
(ElementStatus->StorageElementFull[StorageElementNumber] ? "Full " : "Empty"));
|
(ElementStatus->StorageElementFull[StorageElementNumber] ? "Full " : "Empty"));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf( " Storage Element %d%s:%s", ElementStatus->StorageElementAddress[StorageElementNumber],
|
||||||
|
(ElementStatus->StorageElementIsImportExport[StorageElementNumber]) ? " IMPORT/EXPORT" : "",
|
||||||
|
(ElementStatus->StorageElementFull[StorageElementNumber] ? "Full " : "Empty"));
|
||||||
|
}
|
||||||
|
|
||||||
if (ElementStatus->PrimaryVolumeTag[StorageElementNumber][0])
|
if (ElementStatus->PrimaryVolumeTag[StorageElementNumber][0])
|
||||||
{
|
{
|
||||||
@@ -918,7 +936,6 @@ void execute_command(struct command_table_struct *command)
|
|||||||
}
|
}
|
||||||
open_device();
|
open_device();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ElementStatus && command->need_status)
|
if (!ElementStatus && command->need_status)
|
||||||
{
|
{
|
||||||
inquiry_info = RequestInquiry(MediumChangerFD,&RequestSense);
|
inquiry_info = RequestInquiry(MediumChangerFD,&RequestSense);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
Name: mtx
|
Name: mtx
|
||||||
Version: 1.3.12
|
Version: 1.3.12
|
||||||
Release: 14%{?dist}
|
Release: 14fnal_p%{?dist}
|
||||||
Summary: SCSI media changer control program
|
Summary: SCSI media changer control program
|
||||||
License: GPLv2
|
License: GPLv2
|
||||||
Group: Applications/System
|
Group: Applications/System
|
||||||
@@ -14,6 +14,7 @@ Patch2: emc-fix-fail-with-too-high-slot-count_cleanupver.patch
|
|||||||
Patch3: mtx-1.3.12-fix-resource-leak.patch
|
Patch3: mtx-1.3.12-fix-resource-leak.patch
|
||||||
Patch4: mtx-1.3.12-scsitape-usage--add-erase.patch
|
Patch4: mtx-1.3.12-scsitape-usage--add-erase.patch
|
||||||
Patch5: mtx-1.3.12-man-Document-mtx-eject-and-previous-operations.patch
|
Patch5: mtx-1.3.12-man-Document-mtx-eject-and-previous-operations.patch
|
||||||
|
Patch6: mtx-1.3.12-mtx-library.patch
|
||||||
URL: http://mtx.sourceforge.net/
|
URL: http://mtx.sourceforge.net/
|
||||||
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
|
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
|
||||||
|
|
||||||
@@ -38,6 +39,7 @@ tape at a time, you should install MTX.
|
|||||||
%patch3 -p1 -b .fixresourceleak
|
%patch3 -p1 -b .fixresourceleak
|
||||||
%patch4 -p1 -b .scsitape_adderase
|
%patch4 -p1 -b .scsitape_adderase
|
||||||
%patch5 -p1 -b .mtxman1upd
|
%patch5 -p1 -b .mtxman1upd
|
||||||
|
%patch6 -p2 -b .mtxlib
|
||||||
|
|
||||||
# remove exec permission
|
# remove exec permission
|
||||||
chmod a-x contrib/config_sgen_solaris.sh contrib/mtx-changer
|
chmod a-x contrib/config_sgen_solaris.sh contrib/mtx-changer
|
||||||
@@ -67,6 +69,8 @@ rm -rf $RPM_BUILD_ROOT
|
|||||||
|
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Tue Jul 31 2018 Alexander Moibenko <moibenko@fnal.gov> - 1.3.12-14fnal_p
|
||||||
|
- Changes to allow to use mtx as library and show absolute transfer and storage elements as output of status call
|
||||||
* Wed Mar 16 2016 David Sommerseth <davids@redhat.com> - 1.3.12-14
|
* Wed Mar 16 2016 David Sommerseth <davids@redhat.com> - 1.3.12-14
|
||||||
- Update scsitape --help screen to show the erase command and improved mtx.1 man page (#948459)
|
- Update scsitape --help screen to show the erase command and improved mtx.1 man page (#948459)
|
||||||
|
|
||||||
@@ -220,14 +224,14 @@ rm -rf $RPM_BUILD_ROOT
|
|||||||
* Thu Jun 15 2000 Preston Brown <pbrown@redhat.com>
|
* Thu Jun 15 2000 Preston Brown <pbrown@redhat.com>
|
||||||
- 1.2.7
|
- 1.2.7
|
||||||
|
|
||||||
* Tue May 23 2000 Preston Brown <pbrown@redhat.com>
|
* Tue May 23 2000 Preston Brown <pbrown@redhat.com>
|
||||||
- adopted for Winston
|
- adopted for Winston
|
||||||
|
|
||||||
* Fri May 12 2000 Kenneth Porter <shiva@well.com>
|
* Fri May 12 2000 Kenneth Porter <shiva@well.com>
|
||||||
- 1.2.6
|
- 1.2.6
|
||||||
- Fixed 'eepos' stuff to use | rather than || (whoops!)
|
- Fixed 'eepos' stuff to use | rather than || (whoops!)
|
||||||
- Accept a 4-byte element descriptor for the robot arm for certain older
|
- Accept a 4-byte element descriptor for the robot arm for certain older
|
||||||
- autochangers.
|
- autochangers.
|
||||||
|
|
||||||
* Mon May 8 2000 Kenneth Porter <shiva@well.com>
|
* Mon May 8 2000 Kenneth Porter <shiva@well.com>
|
||||||
- Spell sourceforge right so the link at rpmfind.net will work.
|
- Spell sourceforge right so the link at rpmfind.net will work.
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* FatalError: changed Feb. 2000 elg@badtux.org to eliminate a buffer
|
* FatalError: changed Feb. 2000 elg@badtux.org to eliminate a buffer
|
||||||
* overflow :-(. That could be important if mtxl is SUID for some reason.
|
* overflow :-(. That could be important if mtxl is SUID for some reason.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "mtx.h"
|
#include "mtx.h"
|
||||||
@@ -34,7 +34,7 @@
|
|||||||
/* #define DEBUG_MODE_SENSE 1 */
|
/* #define DEBUG_MODE_SENSE 1 */
|
||||||
/* #define DEBUG */
|
/* #define DEBUG */
|
||||||
/* #define DEBUG_SCSI */
|
/* #define DEBUG_SCSI */
|
||||||
#define __WEIRD_CHAR_SUPPRESS 1
|
#define __WEIRD_CHAR_SUPPRESS 1
|
||||||
|
|
||||||
/* zap the following define when we finally add real import/export support */
|
/* zap the following define when we finally add real import/export support */
|
||||||
#define IMPORT_EXPORT_HACK 1 /* for the moment, import/export == storage */
|
#define IMPORT_EXPORT_HACK 1 /* for the moment, import/export == storage */
|
||||||
@@ -100,7 +100,7 @@ Inquiry_T *RequestInquiry(DEVICE_TYPE fd, RequestSense_T *RequestSense)
|
|||||||
Inquiry_T *Inquiry;
|
Inquiry_T *Inquiry;
|
||||||
CDB_T CDB;
|
CDB_T CDB;
|
||||||
|
|
||||||
Inquiry = (Inquiry_T *) xmalloc(sizeof(Inquiry_T));
|
Inquiry = (Inquiry_T *) xmalloc(sizeof(Inquiry_T));
|
||||||
|
|
||||||
CDB[0] = 0x12; /* INQUIRY */
|
CDB[0] = 0x12; /* INQUIRY */
|
||||||
CDB[1] = 0; /* EVPD = 0 */
|
CDB[1] = 0; /* EVPD = 0 */
|
||||||
@@ -231,7 +231,8 @@ void FatalError(char *ErrorMessage, ...)
|
|||||||
va_end(ArgumentPointer);
|
va_end(ArgumentPointer);
|
||||||
|
|
||||||
#ifndef VMS
|
#ifndef VMS
|
||||||
exit(1);
|
//exit(1);
|
||||||
|
return; /* if used as library routine it can not exit, because this would terminate the caller */
|
||||||
#else
|
#else
|
||||||
sys$exit(VMS_ExitCode);
|
sys$exit(VMS_ExitCode);
|
||||||
#endif
|
#endif
|
||||||
@@ -280,10 +281,10 @@ int max(int x, int y)
|
|||||||
|
|
||||||
|
|
||||||
/* Okay, this is a hack for the NSM modular jukebox series, which
|
/* Okay, this is a hack for the NSM modular jukebox series, which
|
||||||
* uses the "SEND DIAGNOSTIC" command to do shit.
|
* uses the "SEND DIAGNOSTIC" command to do shit.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int SendNSMHack(DEVICE_TYPE MediumChangerFD, NSM_Param_T *nsm_command,
|
int SendNSMHack(DEVICE_TYPE MediumChangerFD, NSM_Param_T *nsm_command,
|
||||||
int param_len, int timeout)
|
int param_len, int timeout)
|
||||||
{
|
{
|
||||||
CDB_T CDB;
|
CDB_T CDB;
|
||||||
@@ -362,7 +363,7 @@ NSM_Result_T *RecNSMHack( DEVICE_TYPE MediumChangerFD,
|
|||||||
|
|
||||||
/* Routine to inventory the library. Needed by, e.g., some Breece Hill
|
/* Routine to inventory the library. Needed by, e.g., some Breece Hill
|
||||||
* loaders. Sends an INITIALIZE_ELEMENT_STATUS command. This command
|
* loaders. Sends an INITIALIZE_ELEMENT_STATUS command. This command
|
||||||
* has no parameters, such as a range to scan :-(.
|
* has no parameters, such as a range to scan :-(.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int Inventory(DEVICE_TYPE MediumChangerFD)
|
int Inventory(DEVICE_TYPE MediumChangerFD)
|
||||||
@@ -370,7 +371,7 @@ int Inventory(DEVICE_TYPE MediumChangerFD)
|
|||||||
CDB_T CDB;
|
CDB_T CDB;
|
||||||
|
|
||||||
/* okay, now for the command: */
|
/* okay, now for the command: */
|
||||||
CDB[0] = 0x07;
|
CDB[0] = 0x07;
|
||||||
CDB[1] = CDB[2] = CDB[3] = CDB[4] = CDB[5] = 0;
|
CDB[1] = CDB[2] = CDB[3] = CDB[4] = CDB[5] = 0;
|
||||||
|
|
||||||
/* set us a very long timeout, sigh... */
|
/* set us a very long timeout, sigh... */
|
||||||
@@ -394,8 +395,8 @@ int Inventory(DEVICE_TYPE MediumChangerFD)
|
|||||||
/* Routine to read the Mode Sense Element Address Assignment Page */
|
/* Routine to read the Mode Sense Element Address Assignment Page */
|
||||||
/* We try to read the page. If we can't read the page, we return NULL.
|
/* We try to read the page. If we can't read the page, we return NULL.
|
||||||
* Our caller really isn't too worried about why we could not read the
|
* Our caller really isn't too worried about why we could not read the
|
||||||
* page, it will simply default to some kind of default values.
|
* page, it will simply default to some kind of default values.
|
||||||
*/
|
*/
|
||||||
ElementModeSense_T *ReadAssignmentPage(DEVICE_TYPE MediumChangerFD)
|
ElementModeSense_T *ReadAssignmentPage(DEVICE_TYPE MediumChangerFD)
|
||||||
{
|
{
|
||||||
CDB_T CDB;
|
CDB_T CDB;
|
||||||
@@ -405,7 +406,7 @@ ElementModeSense_T *ReadAssignmentPage(DEVICE_TYPE MediumChangerFD)
|
|||||||
|
|
||||||
/* okay, now for the command: */
|
/* okay, now for the command: */
|
||||||
CDB[0] = 0x1A; /* Mode Sense(6) */
|
CDB[0] = 0x1A; /* Mode Sense(6) */
|
||||||
CDB[1] = 0x08;
|
CDB[1] = 0x08;
|
||||||
CDB[2] = 0x1D; /* Mode Sense Element Address Assignment Page */
|
CDB[2] = 0x1D; /* Mode Sense Element Address Assignment Page */
|
||||||
CDB[3] = 0;
|
CDB[3] = 0;
|
||||||
CDB[4] = 136; /* allocation_length... */
|
CDB[4] = 136; /* allocation_length... */
|
||||||
@@ -482,7 +483,7 @@ ElementModeSense_T *ReadAssignmentPage(DEVICE_TYPE MediumChangerFD)
|
|||||||
((int)sense_page->NumStorageHi << 8) + sense_page->NumStorageLo;
|
((int)sense_page->NumStorageHi << 8) + sense_page->NumStorageLo;
|
||||||
|
|
||||||
retval->ImportExportStart =
|
retval->ImportExportStart =
|
||||||
((int)sense_page->ImportExportStartHi << 8) + sense_page->ImportExportStartLo;
|
((int)sense_page->ImportExportStartHi << 8) + sense_page->ImportExportStartLo;
|
||||||
|
|
||||||
retval->NumImportExport =
|
retval->NumImportExport =
|
||||||
((int)sense_page->NumImportExportHi << 8) + sense_page->NumImportExportLo;
|
((int)sense_page->NumImportExportHi << 8) + sense_page->NumImportExportLo;
|
||||||
@@ -494,7 +495,7 @@ ElementModeSense_T *ReadAssignmentPage(DEVICE_TYPE MediumChangerFD)
|
|||||||
((int)sense_page->NumDataTransferHi << 8) + sense_page->NumDataTransferLo;
|
((int)sense_page->NumDataTransferHi << 8) + sense_page->NumDataTransferLo;
|
||||||
|
|
||||||
/* allocate a couple spares 'cause some HP autochangers and maybe others
|
/* allocate a couple spares 'cause some HP autochangers and maybe others
|
||||||
* don't properly report the robotics arm(s) count here...
|
* don't properly report the robotics arm(s) count here...
|
||||||
*/
|
*/
|
||||||
retval->NumElements =
|
retval->NumElements =
|
||||||
retval->NumStorage+retval->NumImportExport +
|
retval->NumStorage+retval->NumImportExport +
|
||||||
@@ -549,7 +550,7 @@ static ElementStatus_T *AllocateElementData(ElementModeSense_T *mode_sense)
|
|||||||
|
|
||||||
retval->DataTransferElementAddress =
|
retval->DataTransferElementAddress =
|
||||||
(int *)xzmalloc(sizeof(int) * (mode_sense->NumDataTransfer + 1));
|
(int *)xzmalloc(sizeof(int) * (mode_sense->NumDataTransfer + 1));
|
||||||
retval->DataTransferElementSourceStorageElementNumber =
|
retval->DataTransferElementSourceStorageElementNumber =
|
||||||
(int *)xzmalloc(sizeof(int) * (mode_sense->NumDataTransfer + 1));
|
(int *)xzmalloc(sizeof(int) * (mode_sense->NumDataTransfer + 1));
|
||||||
retval->DataTransferPrimaryVolumeTag =
|
retval->DataTransferPrimaryVolumeTag =
|
||||||
(barcode *)xzmalloc(sizeof(barcode) * (mode_sense->NumDataTransfer + 1));
|
(barcode *)xzmalloc(sizeof(barcode) * (mode_sense->NumDataTransfer + 1));
|
||||||
@@ -587,14 +588,14 @@ void copy_barcode(unsigned char *src, unsigned char *dest)
|
|||||||
|
|
||||||
dest++;
|
dest++;
|
||||||
}
|
}
|
||||||
*dest = 0; /* null-terminate */
|
*dest = 0; /* null-terminate */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This #%!@# routine has more parameters than I can count! */
|
/* This #%!@# routine has more parameters than I can count! */
|
||||||
static unsigned char *SendElementStatusRequestActual(
|
static unsigned char *SendElementStatusRequestActual(
|
||||||
DEVICE_TYPE MediumChangerFD,
|
DEVICE_TYPE MediumChangerFD,
|
||||||
RequestSense_T *RequestSense,
|
RequestSense_T *RequestSense,
|
||||||
Inquiry_T *inquiry_info,
|
Inquiry_T *inquiry_info,
|
||||||
SCSI_Flags_T *flags,
|
SCSI_Flags_T *flags,
|
||||||
int ElementStart,
|
int ElementStart,
|
||||||
int NumElements,
|
int NumElements,
|
||||||
@@ -609,7 +610,7 @@ static unsigned char *SendElementStatusRequestActual(
|
|||||||
#ifdef HAVE_GET_ID_LUN
|
#ifdef HAVE_GET_ID_LUN
|
||||||
scsi_id_t *scsi_id;
|
scsi_id_t *scsi_id;
|
||||||
#endif
|
#endif
|
||||||
if (inquiry_info->MChngr &&
|
if (inquiry_info->MChngr &&
|
||||||
inquiry_info->PeripheralDeviceType != MEDIUM_CHANGER_TYPE)
|
inquiry_info->PeripheralDeviceType != MEDIUM_CHANGER_TYPE)
|
||||||
{
|
{
|
||||||
is_attached = true;
|
is_attached = true;
|
||||||
@@ -617,7 +618,7 @@ static unsigned char *SendElementStatusRequestActual(
|
|||||||
|
|
||||||
if (flags->no_attached)
|
if (flags->no_attached)
|
||||||
{
|
{
|
||||||
/* override, sigh */
|
/* override, sigh */
|
||||||
is_attached = false;
|
is_attached = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -633,11 +634,11 @@ static unsigned char *SendElementStatusRequestActual(
|
|||||||
|
|
||||||
if (is_attached)
|
if (is_attached)
|
||||||
{
|
{
|
||||||
CDB[0] = 0xB4; /* whoops, READ_ELEMENT_STATUS_ATTACHED! */
|
CDB[0] = 0xB4; /* whoops, READ_ELEMENT_STATUS_ATTACHED! */
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_GET_ID_LUN
|
#ifdef HAVE_GET_ID_LUN
|
||||||
CDB[1] = (scsi_id->lun << 5) | ((flags->no_barcodes) ?
|
CDB[1] = (scsi_id->lun << 5) | ((flags->no_barcodes) ?
|
||||||
0 : 0x10) | flags->elementtype; /* Lun + VolTag + Type code */
|
0 : 0x10) | flags->elementtype; /* Lun + VolTag + Type code */
|
||||||
free(scsi_id);
|
free(scsi_id);
|
||||||
#else
|
#else
|
||||||
@@ -677,7 +678,7 @@ static unsigned char *SendElementStatusRequestActual(
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
First see if we have sense key of 'illegal request',
|
First see if we have sense key of 'illegal request',
|
||||||
additional sense code of '24', additional sense qualfier of
|
additional sense code of '24', additional sense qualfier of
|
||||||
'0', and field in error of '4'. This means that we issued a request
|
'0', and field in error of '4'. This means that we issued a request
|
||||||
w/bar code reader and did not have one, thus must re-issue the request
|
w/bar code reader and did not have one, thus must re-issue the request
|
||||||
w/out barcode :-(.
|
w/out barcode :-(.
|
||||||
@@ -722,14 +723,14 @@ static unsigned char *SendElementStatusRequestActual(
|
|||||||
PrintRequestSense(RequestSense); /* see what it sez :-(. */
|
PrintRequestSense(RequestSense); /* see what it sez :-(. */
|
||||||
fprintf(stderr,"Data:\n");
|
fprintf(stderr,"Data:\n");
|
||||||
PrintHex(2, DataBuffer, 40);
|
PrintHex(2, DataBuffer, 40);
|
||||||
#endif
|
#endif
|
||||||
return DataBuffer; /* we succeeded! */
|
return DataBuffer; /* we succeeded! */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
unsigned char *SendElementStatusRequest(DEVICE_TYPE MediumChangerFD,
|
unsigned char *SendElementStatusRequest(DEVICE_TYPE MediumChangerFD,
|
||||||
RequestSense_T *RequestSense,
|
RequestSense_T *RequestSense,
|
||||||
Inquiry_T *inquiry_info,
|
Inquiry_T *inquiry_info,
|
||||||
SCSI_Flags_T *flags,
|
SCSI_Flags_T *flags,
|
||||||
int ElementStart,
|
int ElementStart,
|
||||||
int NumElements,
|
int NumElements,
|
||||||
@@ -750,7 +751,7 @@ unsigned char *SendElementStatusRequest(DEVICE_TYPE MediumChangerFD,
|
|||||||
/*
|
/*
|
||||||
One weird loader wants either 8 or BYTE_COUNT_OF_REPORT
|
One weird loader wants either 8 or BYTE_COUNT_OF_REPORT
|
||||||
values for the ALLOCATION_LENGTH. Give it what it wants
|
values for the ALLOCATION_LENGTH. Give it what it wants
|
||||||
if we get an Sense Key of 05 Illegal Request with a
|
if we get an Sense Key of 05 Illegal Request with a
|
||||||
CDB position of 7 as the field in error.
|
CDB position of 7 as the field in error.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -882,7 +883,7 @@ static void ParseElementStatus( int *EmptyStorageElementAddress,
|
|||||||
{
|
{
|
||||||
/* TransportElementDescriptor =
|
/* TransportElementDescriptor =
|
||||||
(TransportElementDescriptor_T *) DataPointer; */
|
(TransportElementDescriptor_T *) DataPointer; */
|
||||||
memcpy(&TEBuf, DataPointer,
|
memcpy(&TEBuf, DataPointer,
|
||||||
(TransportElementDescriptorLength <= sizeof(TEBuf)) ?
|
(TransportElementDescriptorLength <= sizeof(TEBuf)) ?
|
||||||
TransportElementDescriptorLength :
|
TransportElementDescriptorLength :
|
||||||
sizeof(TEBuf));
|
sizeof(TEBuf));
|
||||||
@@ -909,7 +910,7 @@ static void ParseElementStatus( int *EmptyStorageElementAddress,
|
|||||||
case MediumTransportElement:
|
case MediumTransportElement:
|
||||||
ElementStatus->TransportElementAddress = BigEndian16(TransportElementDescriptor->ElementAddress);
|
ElementStatus->TransportElementAddress = BigEndian16(TransportElementDescriptor->ElementAddress);
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fprintf(stderr,"TransportElementAddress=%d\n",ElementStatus->TransportElementAddress);
|
fprintf(stderr,"TransportElementAddress=%d\n",ElementStatus->TransportElementAddress);
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -936,7 +937,7 @@ static void ParseElementStatus( int *EmptyStorageElementAddress,
|
|||||||
ElementStatus->StorageElementFull[ImportExportIndex] =
|
ElementStatus->StorageElementFull[ImportExportIndex] =
|
||||||
TransportElementDescriptor->Full;
|
TransportElementDescriptor->Full;
|
||||||
|
|
||||||
if ( (TransportElementDescriptorLength > 11) &&
|
if ( (TransportElementDescriptorLength > 11) &&
|
||||||
(ElementStatusPage->VolBits & E2_AVOLTAG))
|
(ElementStatusPage->VolBits & E2_AVOLTAG))
|
||||||
{
|
{
|
||||||
copy_barcode(TransportElementDescriptor->AlternateVolumeTag,
|
copy_barcode(TransportElementDescriptor->AlternateVolumeTag,
|
||||||
@@ -945,8 +946,8 @@ static void ParseElementStatus( int *EmptyStorageElementAddress,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
ElementStatus->AlternateVolumeTag[ImportExportIndex][0] = 0; /* null string. */;
|
ElementStatus->AlternateVolumeTag[ImportExportIndex][0] = 0; /* null string. */;
|
||||||
}
|
}
|
||||||
if ((TransportElementDescriptorLength > 11) &&
|
if ((TransportElementDescriptorLength > 11) &&
|
||||||
(ElementStatusPage->VolBits & E2_PVOLTAG))
|
(ElementStatusPage->VolBits & E2_PVOLTAG))
|
||||||
{
|
{
|
||||||
copy_barcode(TransportElementDescriptor->PrimaryVolumeTag,
|
copy_barcode(TransportElementDescriptor->PrimaryVolumeTag,
|
||||||
@@ -967,8 +968,8 @@ static void ParseElementStatus( int *EmptyStorageElementAddress,
|
|||||||
fprintf(stderr,"StorageElementCount=%d ElementAddress = %d ",ElementStatus->StorageElementCount,BigEndian16(TransportElementDescriptor->ElementAddress));
|
fprintf(stderr,"StorageElementCount=%d ElementAddress = %d ",ElementStatus->StorageElementCount,BigEndian16(TransportElementDescriptor->ElementAddress));
|
||||||
#endif
|
#endif
|
||||||
/* ATL/Exabyte kludge -- skip slots that aren't installed :-( */
|
/* ATL/Exabyte kludge -- skip slots that aren't installed :-( */
|
||||||
if (TransportElementDescriptor->AdditionalSenseCode==0x83 &&
|
if (TransportElementDescriptor->AdditionalSenseCode==0x83 &&
|
||||||
TransportElementDescriptor->AdditionalSenseCodeQualifier==0x02)
|
TransportElementDescriptor->AdditionalSenseCodeQualifier==0x02)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ElementStatus->StorageElementAddress[ElementStatus->StorageElementCount] =
|
ElementStatus->StorageElementAddress[ElementStatus->StorageElementCount] =
|
||||||
@@ -986,7 +987,7 @@ static void ParseElementStatus( int *EmptyStorageElementAddress,
|
|||||||
ElementStatus->StorageElementCount; /* slot idx. */
|
ElementStatus->StorageElementCount; /* slot idx. */
|
||||||
/* ElementStatus->StorageElementAddress[ElementStatus->StorageElementCount]; */
|
/* ElementStatus->StorageElementAddress[ElementStatus->StorageElementCount]; */
|
||||||
}
|
}
|
||||||
if ((TransportElementDescriptorLength > 11) &&
|
if ((TransportElementDescriptorLength > 11) &&
|
||||||
(ElementStatusPage->VolBits & E2_AVOLTAG))
|
(ElementStatusPage->VolBits & E2_AVOLTAG))
|
||||||
{
|
{
|
||||||
copy_barcode(TransportElementDescriptor->AlternateVolumeTag,
|
copy_barcode(TransportElementDescriptor->AlternateVolumeTag,
|
||||||
@@ -995,8 +996,8 @@ static void ParseElementStatus( int *EmptyStorageElementAddress,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
ElementStatus->AlternateVolumeTag[ElementStatus->StorageElementCount][0]=0; /* null string. */;
|
ElementStatus->AlternateVolumeTag[ElementStatus->StorageElementCount][0]=0; /* null string. */;
|
||||||
}
|
}
|
||||||
if ((TransportElementDescriptorLength > 11) &&
|
if ((TransportElementDescriptorLength > 11) &&
|
||||||
(ElementStatusPage->VolBits & E2_PVOLTAG))
|
(ElementStatusPage->VolBits & E2_PVOLTAG))
|
||||||
{
|
{
|
||||||
copy_barcode(TransportElementDescriptor->PrimaryVolumeTag,
|
copy_barcode(TransportElementDescriptor->PrimaryVolumeTag,
|
||||||
@@ -1009,9 +1010,9 @@ static void ParseElementStatus( int *EmptyStorageElementAddress,
|
|||||||
|
|
||||||
ElementStatus->StorageElementCount++;
|
ElementStatus->StorageElementCount++;
|
||||||
/*
|
/*
|
||||||
Note that the original mtx had no check here for
|
Note that the original mtx had no check here for
|
||||||
buffer overflow, though some drives might mistakingly
|
buffer overflow, though some drives might mistakingly
|
||||||
do one...
|
do one...
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (ElementStatus->StorageElementCount > mode_sense->NumStorage)
|
if (ElementStatus->StorageElementCount > mode_sense->NumStorage)
|
||||||
@@ -1033,33 +1034,33 @@ static void ParseElementStatus( int *EmptyStorageElementAddress,
|
|||||||
report that they have a 2nd tape drive when they don't. We
|
report that they have a 2nd tape drive when they don't. We
|
||||||
could generalize this in an ideal world, but my attempt to
|
could generalize this in an ideal world, but my attempt to
|
||||||
do so failed with dual-drive Exabyte tape libraries that
|
do so failed with dual-drive Exabyte tape libraries that
|
||||||
*DID* have the second drive. Sigh.
|
*DID* have the second drive. Sigh.
|
||||||
*/
|
*/
|
||||||
if (TransportElementDescriptor->AdditionalSenseCode==0x83 &&
|
if (TransportElementDescriptor->AdditionalSenseCode==0x83 &&
|
||||||
TransportElementDescriptor->AdditionalSenseCodeQualifier==0x04)
|
TransportElementDescriptor->AdditionalSenseCodeQualifier==0x04)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* generalize it. Does it work? Let's try it! */
|
/* generalize it. Does it work? Let's try it! */
|
||||||
/*
|
/*
|
||||||
No, dammit, following does not work on dual-drive Exabyte
|
No, dammit, following does not work on dual-drive Exabyte
|
||||||
'cause if a tape is in the drive, it sets the AdditionalSense
|
'cause if a tape is in the drive, it sets the AdditionalSense
|
||||||
code to something (sigh).
|
code to something (sigh).
|
||||||
*/
|
*/
|
||||||
/* if (TransportElementDescriptor->AdditionalSenseCode!=0)
|
/* if (TransportElementDescriptor->AdditionalSenseCode!=0)
|
||||||
continue;
|
continue;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ElementStatus->DataTransferElementAddress[ElementStatus->DataTransferElementCount] =
|
ElementStatus->DataTransferElementAddress[ElementStatus->DataTransferElementCount] =
|
||||||
BigEndian16(TransportElementDescriptor->ElementAddress);
|
BigEndian16(TransportElementDescriptor->ElementAddress);
|
||||||
ElementStatus->DataTransferElementFull[ElementStatus->DataTransferElementCount] =
|
ElementStatus->DataTransferElementFull[ElementStatus->DataTransferElementCount] =
|
||||||
TransportElementDescriptor->Full;
|
TransportElementDescriptor->Full;
|
||||||
ElementStatus->DataTransferElementSourceStorageElementNumber[ElementStatus->DataTransferElementCount] =
|
ElementStatus->DataTransferElementSourceStorageElementNumber[ElementStatus->DataTransferElementCount] =
|
||||||
BigEndian16(TransportElementDescriptor->SourceStorageElementAddress);
|
BigEndian16(TransportElementDescriptor->SourceStorageElementAddress);
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fprintf(stderr, "%d: ElementAddress = %d, Full = %d, SourceElement = %d\n",
|
fprintf(stderr, "%d: ElementAddress = %d, Full = %d, SourceElement = %d\n",
|
||||||
ElementStatus->DataTransferElementCount,
|
ElementStatus->DataTransferElementCount,
|
||||||
ElementStatus->DataTransferElementAddress[ElementStatus->DataTransferElementCount],
|
ElementStatus->DataTransferElementAddress[ElementStatus->DataTransferElementCount],
|
||||||
ElementStatus->DataTransferElementFull[ElementStatus->DataTransferElementCount],
|
ElementStatus->DataTransferElementFull[ElementStatus->DataTransferElementCount],
|
||||||
@@ -1118,17 +1119,17 @@ static void ParseElementStatus( int *EmptyStorageElementAddress,
|
|||||||
/*
|
/*
|
||||||
* We no longer do the funky trick to figure out ALLOCATION_LENGTH.
|
* We no longer do the funky trick to figure out ALLOCATION_LENGTH.
|
||||||
* Instead, we use the SCSI Generic command rather than SEND_SCSI_COMMAND
|
* Instead, we use the SCSI Generic command rather than SEND_SCSI_COMMAND
|
||||||
* under Linux, which gets around the @#%@ 4k buffer size in Linux.
|
* under Linux, which gets around the @#%@ 4k buffer size in Linux.
|
||||||
* We still have the restriction that Linux cuts off the last two
|
* We still have the restriction that Linux cuts off the last two
|
||||||
* bytes of the SENSE DATA (Q#@$%@#$^ Linux!). Which means that the
|
* bytes of the SENSE DATA (Q#@$%@#$^ Linux!). Which means that the
|
||||||
* verbose widget won't work :-(.
|
* verbose widget won't work :-(.
|
||||||
|
|
||||||
* We now look for that "attached" bit in the inquiry_info to see whether
|
* We now look for that "attached" bit in the inquiry_info to see whether
|
||||||
* to use READ_ELEMENT_ATTACHED or plain old READ_ELEMENT. In addition, we
|
* to use READ_ELEMENT_ATTACHED or plain old READ_ELEMENT. In addition, we
|
||||||
* look at the device type in the inquiry_info to see whether it is a media
|
* look at the device type in the inquiry_info to see whether it is a media
|
||||||
* changer or tape device, and if it's a media changer device, we ignore the
|
* changer or tape device, and if it's a media changer device, we ignore the
|
||||||
* attached bit (one beta tester found an old 4-tape DAT changer that set
|
* attached bit (one beta tester found an old 4-tape DAT changer that set
|
||||||
* the attached bit for both the tape device AND the media changer device).
|
* the attached bit for both the tape device AND the media changer device).
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -1155,7 +1156,7 @@ ElementStatus_T *ReadElementStatus(DEVICE_TYPE MediumChangerFD, RequestSense_T *
|
|||||||
|
|
||||||
if (flags->no_attached)
|
if (flags->no_attached)
|
||||||
{
|
{
|
||||||
/* override, sigh */
|
/* override, sigh */
|
||||||
is_attached = false;
|
is_attached = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1185,7 +1186,7 @@ ElementStatus_T *ReadElementStatus(DEVICE_TYPE MediumChangerFD, RequestSense_T *
|
|||||||
ElementStatus->DataTransferElementCount = 0;
|
ElementStatus->DataTransferElementCount = 0;
|
||||||
|
|
||||||
/* first, allocate some empty storage stuff: Note that we pass this
|
/* first, allocate some empty storage stuff: Note that we pass this
|
||||||
* down to ParseElementStatus (sigh!)
|
* down to ParseElementStatus (sigh!)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
EmptyStorageElementAddress = (int *)xzmalloc((mode_sense->NumStorage+1)*sizeof(int));
|
EmptyStorageElementAddress = (int *)xzmalloc((mode_sense->NumStorage+1)*sizeof(int));
|
||||||
@@ -1202,7 +1203,7 @@ ElementStatus_T *ReadElementStatus(DEVICE_TYPE MediumChangerFD, RequestSense_T *
|
|||||||
for (i = 0; i < mode_sense->NumDataTransfer; i++)
|
for (i = 0; i < mode_sense->NumDataTransfer; i++)
|
||||||
{
|
{
|
||||||
/* initialize them to an illegal # so that we can fix later... */
|
/* initialize them to an illegal # so that we can fix later... */
|
||||||
ElementStatus->DataTransferElementSourceStorageElementNumber[i] = -1;
|
ElementStatus->DataTransferElementSourceStorageElementNumber[i] = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags->querytype == MTX_ELEMENTSTATUS_ORIGINAL)
|
if (flags->querytype == MTX_ELEMENTSTATUS_ORIGINAL)
|
||||||
@@ -1308,7 +1309,7 @@ ElementStatus_T *ReadElementStatus(DEVICE_TYPE MediumChangerFD, RequestSense_T *
|
|||||||
PrintRequestSense(RequestSense);
|
PrintRequestSense(RequestSense);
|
||||||
#endif
|
#endif
|
||||||
FreeElementData(ElementStatus);
|
FreeElementData(ElementStatus);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
@@ -1323,7 +1324,7 @@ ElementStatus_T *ReadElementStatus(DEVICE_TYPE MediumChangerFD, RequestSense_T *
|
|||||||
|
|
||||||
/* grr, damned brain dead HP doesn't report that it has any! */
|
/* grr, damned brain dead HP doesn't report that it has any! */
|
||||||
if (!mode_sense->NumMediumTransport)
|
if (!mode_sense->NumMediumTransport)
|
||||||
{
|
{
|
||||||
ElementStatus->TransportElementAddress = 0; /* default it sensibly :-(. */
|
ElementStatus->TransportElementAddress = 0; /* default it sensibly :-(. */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1347,8 +1348,8 @@ ElementStatus_T *ReadElementStatus(DEVICE_TYPE MediumChangerFD, RequestSense_T *
|
|||||||
PrintRequestSense(RequestSense);
|
PrintRequestSense(RequestSense);
|
||||||
#endif
|
#endif
|
||||||
FreeElementData(ElementStatus);
|
FreeElementData(ElementStatus);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fprintf(stderr,"Parsing robot arm data\n");
|
fprintf(stderr,"Parsing robot arm data\n");
|
||||||
#endif
|
#endif
|
||||||
@@ -1366,8 +1367,8 @@ ElementStatus_T *ReadElementStatus(DEVICE_TYPE MediumChangerFD, RequestSense_T *
|
|||||||
fprintf(stderr,"Using alternative element status polling method (all elements)\n");
|
fprintf(stderr,"Using alternative element status polling method (all elements)\n");
|
||||||
#endif
|
#endif
|
||||||
/* ----------------- ALL Elements ---------------------- */
|
/* ----------------- ALL Elements ---------------------- */
|
||||||
/* Just keep asking for elements till no more are returned
|
/* Just keep asking for elements till no more are returned
|
||||||
- increment our starting address as we go acording to the
|
- increment our starting address as we go acording to the
|
||||||
number of elements returned from the last call
|
number of elements returned from the last call
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -1384,7 +1385,7 @@ ElementStatus_T *ReadElementStatus(DEVICE_TYPE MediumChangerFD, RequestSense_T *
|
|||||||
mode_sense->MaxReadElementStatusData);
|
mode_sense->MaxReadElementStatusData);
|
||||||
if (!DataBuffer)
|
if (!DataBuffer)
|
||||||
{
|
{
|
||||||
if (RequestSense->AdditionalSenseCode == 0x21 &&
|
if (RequestSense->AdditionalSenseCode == 0x21 &&
|
||||||
RequestSense->AdditionalSenseCodeQualifier == 0x01)
|
RequestSense->AdditionalSenseCodeQualifier == 0x01)
|
||||||
{
|
{
|
||||||
/* Error is invalid element address, we've probably just hit the end */
|
/* Error is invalid element address, we've probably just hit the end */
|
||||||
@@ -1393,8 +1394,8 @@ ElementStatus_T *ReadElementStatus(DEVICE_TYPE MediumChangerFD, RequestSense_T *
|
|||||||
|
|
||||||
/* darn. Free up stuff and return. */
|
/* darn. Free up stuff and return. */
|
||||||
FreeElementData(ElementStatus);
|
FreeElementData(ElementStatus);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
nLastEl = nNextEl;
|
nLastEl = nNextEl;
|
||||||
|
|
||||||
@@ -1423,7 +1424,7 @@ ElementStatus_T *ReadElementStatus(DEVICE_TYPE MediumChangerFD, RequestSense_T *
|
|||||||
*
|
*
|
||||||
* Pass1:
|
* Pass1:
|
||||||
* Translate from raw element # to our translated # (if possible).
|
* Translate from raw element # to our translated # (if possible).
|
||||||
* First, check the SourceStorageElementNumbers against the list of
|
* First, check the SourceStorageElementNumbers against the list of
|
||||||
* filled slots. If the slots indicated are empty, we accept that list as
|
* filled slots. If the slots indicated are empty, we accept that list as
|
||||||
* valid. Otherwise decide the SourceStorageElementNumbers are invalid.
|
* valid. Otherwise decide the SourceStorageElementNumbers are invalid.
|
||||||
*
|
*
|
||||||
@@ -1432,7 +1433,7 @@ ElementStatus_T *ReadElementStatus(DEVICE_TYPE MediumChangerFD, RequestSense_T *
|
|||||||
* then we must search for free slots, and assign SourceStorageElementNumbers
|
* then we must search for free slots, and assign SourceStorageElementNumbers
|
||||||
* to those free slots. We happen to already built a list of free
|
* to those free slots. We happen to already built a list of free
|
||||||
* slots as part of the process of reading the storage element numbers
|
* slots as part of the process of reading the storage element numbers
|
||||||
* from the tape. So that's easy enough to do!
|
* from the tape. So that's easy enough to do!
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef DEBUG_TAPELIST
|
#ifdef DEBUG_TAPELIST
|
||||||
@@ -1448,7 +1449,7 @@ ElementStatus_T *ReadElementStatus(DEVICE_TYPE MediumChangerFD, RequestSense_T *
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Now we re-assign origin slots if the "real" origin slot
|
* Now we re-assign origin slots if the "real" origin slot
|
||||||
* is obviously defective:
|
* is obviously defective:
|
||||||
*/
|
*/
|
||||||
/* pass one: */
|
/* pass one: */
|
||||||
for (i = 0; i < ElementStatus->DataTransferElementCount; i++)
|
for (i = 0; i < ElementStatus->DataTransferElementCount; i++)
|
||||||
@@ -1486,12 +1487,12 @@ ElementStatus_T *ReadElementStatus(DEVICE_TYPE MediumChangerFD, RequestSense_T *
|
|||||||
* drives will be assigned a -1 (see the initialization loop for
|
* drives will be assigned a -1 (see the initialization loop for
|
||||||
* EmptyStorageElementAddress above), which will be reported as "slot 0"
|
* EmptyStorageElementAddress above), which will be reported as "slot 0"
|
||||||
* by the user interface. This is an invalid value, but more useful for us
|
* by the user interface. This is an invalid value, but more useful for us
|
||||||
* to have than just crapping out here :-(.
|
* to have than just crapping out here :-(.
|
||||||
*/
|
*/
|
||||||
empty_idx=0;
|
empty_idx=0;
|
||||||
for (i = 0; i < ElementStatus->DataTransferElementCount; i++)
|
for (i = 0; i < ElementStatus->DataTransferElementCount; i++)
|
||||||
{
|
{
|
||||||
if (ElementStatus->DataTransferElementFull[i] &&
|
if (ElementStatus->DataTransferElementFull[i] &&
|
||||||
ElementStatus->DataTransferElementSourceStorageElementNumber[i] < 0)
|
ElementStatus->DataTransferElementSourceStorageElementNumber[i] < 0)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_TAPELIST
|
#ifdef DEBUG_TAPELIST
|
||||||
@@ -1543,7 +1544,7 @@ RequestSense_T *PositionElement(DEVICE_TYPE MediumChangerFD,
|
|||||||
|
|
||||||
/* Now the actual media movement routine! */
|
/* Now the actual media movement routine! */
|
||||||
RequestSense_T *MoveMedium( DEVICE_TYPE MediumChangerFD, int SourceAddress,
|
RequestSense_T *MoveMedium( DEVICE_TYPE MediumChangerFD, int SourceAddress,
|
||||||
int DestinationAddress,
|
int DestinationAddress,
|
||||||
ElementStatus_T *ElementStatus,
|
ElementStatus_T *ElementStatus,
|
||||||
Inquiry_T *inquiry_info, SCSI_Flags_T *flags)
|
Inquiry_T *inquiry_info, SCSI_Flags_T *flags)
|
||||||
{
|
{
|
||||||
@@ -1646,7 +1647,7 @@ RequestSense_T *ExchangeMedium( DEVICE_TYPE MediumChangerFD, int SourceAddress,
|
|||||||
|
|
||||||
#ifdef DEBUG_EXCHANGE
|
#ifdef DEBUG_EXCHANGE
|
||||||
dump_cdb(&CDB,12);
|
dump_cdb(&CDB,12);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (SCSI_ExecuteCommand(MediumChangerFD, Output, &CDB, 12,
|
if (SCSI_ExecuteCommand(MediumChangerFD, Output, &CDB, 12,
|
||||||
NULL, 0, RequestSense) != 0)
|
NULL, 0, RequestSense) != 0)
|
||||||
@@ -1690,8 +1691,8 @@ RequestSense_T *Erase(DEVICE_TYPE MediumChangerFD)
|
|||||||
return NULL; /* Success! */
|
return NULL; /* Success! */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Routine to send an LOAD/UNLOAD from the MMC/SSC spec to a device.
|
/* Routine to send an LOAD/UNLOAD from the MMC/SSC spec to a device.
|
||||||
* For tapes and changers this can be used either to eject a tape
|
* For tapes and changers this can be used either to eject a tape
|
||||||
* or to eject a magazine (on some Seagate changers, when sent to LUN 1 ).
|
* or to eject a magazine (on some Seagate changers, when sent to LUN 1 ).
|
||||||
* For CD/DVDs this is used to Load or Unload a disc which is required by
|
* For CD/DVDs this is used to Load or Unload a disc which is required by
|
||||||
* some media changers.
|
* some media changers.
|
||||||
@@ -1721,8 +1722,8 @@ int LoadUnload(DEVICE_TYPE fd, int bLoad)
|
|||||||
return 0; /* did do! */
|
return 0; /* did do! */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Routine to send an START/STOP from the MMC/SSC spec to a device.
|
/* Routine to send an START/STOP from the MMC/SSC spec to a device.
|
||||||
* For tape drives this may be required prior to using the changer
|
* For tape drives this may be required prior to using the changer
|
||||||
* Load or Unload commands.
|
* Load or Unload commands.
|
||||||
* For CD/DVD drives this is used to Load or Unload a disc which may be
|
* For CD/DVD drives this is used to Load or Unload a disc which may be
|
||||||
* required by some media changers.
|
* required by some media changers.
|
||||||
@@ -1746,9 +1747,9 @@ int StartStop(DEVICE_TYPE fd, int bStart)
|
|||||||
return 0; /* did do! */
|
return 0; /* did do! */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Routine to send a LOCK/UNLOCK from the SSC/MMC spec to a device.
|
/* Routine to send a LOCK/UNLOCK from the SSC/MMC spec to a device.
|
||||||
* This can be used to prevent or allow the Tape or CD/DVD from being
|
* This can be used to prevent or allow the Tape or CD/DVD from being
|
||||||
* removed.
|
* removed.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int LockUnlock(DEVICE_TYPE fd, int bLock)
|
int LockUnlock(DEVICE_TYPE fd, int bLock)
|
||||||
@@ -1876,7 +1877,7 @@ void PrintRequestSense(RequestSense_T *RequestSense)
|
|||||||
fprintf(stderr, "mtx: Request Sense: Valid Residual=%s\n", RequestSense->Valid ? Yes : No);
|
fprintf(stderr, "mtx: Request Sense: Valid Residual=%s\n", RequestSense->Valid ? Yes : No);
|
||||||
|
|
||||||
if (RequestSense->ErrorCode == 0x70)
|
if (RequestSense->ErrorCode == 0x70)
|
||||||
{
|
{
|
||||||
msg = "Current" ;
|
msg = "Current" ;
|
||||||
}
|
}
|
||||||
else if (RequestSense->ErrorCode == 0x71)
|
else if (RequestSense->ErrorCode == 0x71)
|
||||||
|
|||||||
691
mtx-1.3.12/patches/mtx-1.3.12-mtx-library.patch
Normal file
691
mtx-1.3.12/patches/mtx-1.3.12-mtx-library.patch
Normal file
@@ -0,0 +1,691 @@
|
|||||||
|
diff --git a/mtx-1.3.12/Makefile.in b/mtx-1.3.12/Makefile.in
|
||||||
|
index 05894d2..18fc35b 100644
|
||||||
|
--- a/mtx-1.3.12/Makefile.in
|
||||||
|
+++ b/mtx-1.3.12/Makefile.in
|
||||||
|
@@ -3,16 +3,17 @@
|
||||||
|
# USE GMAKE, NOT REGULAR BSD MAKE!)
|
||||||
|
#
|
||||||
|
# Valid targets:
|
||||||
|
-# linux86 freebsd86 solarissparc sgi dec vms
|
||||||
|
+# linux86 freebsd86 solarissparc sgi dec vms
|
||||||
|
#
|
||||||
|
# Makefile changes by Lars Kellogg-Stedman for better integration with
|
||||||
|
-# GNU Autoconf.
|
||||||
|
+# GNU Autoconf.
|
||||||
|
|
||||||
|
# Version # for 'make dist'...
|
||||||
|
VERSION=1.3.12
|
||||||
|
|
||||||
|
BINS = mtx@EXEEXT@ tapeinfo@EXEEXT@ loaderinfo@EXEEXT@ scsitape@EXEEXT@ scsieject@EXEEXT@
|
||||||
|
EXTRA_BINS = nsmhack@EXEEXT@
|
||||||
|
+LIB=libmtx.a
|
||||||
|
DBGS := $(BINS:%@EXEEXT@=%.dbg)
|
||||||
|
MAN = mtx.1 tapeinfo.1 loaderinfo.1 scsitape.1 scsieject.1
|
||||||
|
MAN_HTML := $(MAN:%.1=%.html)
|
||||||
|
@@ -46,7 +47,7 @@ VPATH = $(srcdir)
|
||||||
|
# Linux on x86...
|
||||||
|
#
|
||||||
|
ifeq ($(TARGET),linux)
|
||||||
|
-CFLAGS += -Wall
|
||||||
|
+CFLAGS += -Wall -fpic -O3
|
||||||
|
CPPFLAGS += -DLONG_PRINT_REQUEST_SENSE=1
|
||||||
|
endif
|
||||||
|
|
||||||
|
@@ -64,7 +65,7 @@ LIBS += -lcam
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(TARGET),hpux)
|
||||||
|
-CFLAGS += -O -D_HPUX_SOURCE -D __hpux__
|
||||||
|
+CFLAGS += -O -D_HPUX_SOURCE -D __hpux__
|
||||||
|
endif
|
||||||
|
|
||||||
|
#
|
||||||
|
@@ -105,7 +106,7 @@ else
|
||||||
|
strip $< -o $@
|
||||||
|
endif
|
||||||
|
|
||||||
|
-all: $(BINS)
|
||||||
|
+all: $(BINS) $(LIB)
|
||||||
|
|
||||||
|
dbgs: $(DBGS)
|
||||||
|
|
||||||
|
@@ -113,7 +114,7 @@ install: $(BINS)
|
||||||
|
$(INSTALL_DIR) $(DESTDIR)$(sbindir)
|
||||||
|
for file in $(BINS); do \
|
||||||
|
$(INSTALL_BIN) "$$file" $(DESTDIR)$(sbindir) ; \
|
||||||
|
- done
|
||||||
|
+ done
|
||||||
|
$(INSTALL_DIR) $(DESTDIR)$(mandir) $(DESTDIR)$(mandir)/man1
|
||||||
|
for file in mtx.1 tapeinfo.1 scsitape.1 scsieject.1 loaderinfo.1 ; do \
|
||||||
|
$(INSTALL_DOC) "$$file" $(DESTDIR)$(mandir)/man1 ; \
|
||||||
|
@@ -132,7 +133,7 @@ distclean: clean
|
||||||
|
rm -f Makefile config.h config.log config.cache config.status
|
||||||
|
|
||||||
|
dist: distclean
|
||||||
|
- ./makedist $(VERSION)
|
||||||
|
+ ./makedist $(VERSION)
|
||||||
|
|
||||||
|
loaderinfo@EXEEXT@: loaderinfo.o mtxl.o mtxl.h mtx.h $(EXTRA)
|
||||||
|
$(CC) $(LDFLAGS) -o loaderinfo@EXEEXT@ loaderinfo.o mtxl.o $(EXTRA) $(LIBS)
|
||||||
|
@@ -143,7 +144,7 @@ nsmhack@EXEEXT@: nsmhack.o mtxl.o $(EXTRA)
|
||||||
|
mtx@EXEEXT@: mtx.o mtxl.o mtxl.h mtx.h $(EXTRA)
|
||||||
|
$(CC) $(LDFLAGS) -o mtx@EXEEXT@ mtx.o mtxl.o $(EXTRA) $(LIBS)
|
||||||
|
|
||||||
|
-mam2debug@EXEEXT@: mtxl.o mam2debug.o mtx.h $(EXTRA)
|
||||||
|
+mam2debug@EXEEXT@: mtxl.o mam2debug.o mtx.h $(EXTRA)
|
||||||
|
$(CC) $(LDFLAGS) -o mam2debug@EXEEXT@ mtxl.o mam2debug.o $(EXTRA) $(LIBS)
|
||||||
|
|
||||||
|
tapeinfo@EXEEXT@: tapeinfo.o mtxl.o mtx.h mtxl.h $(EXTRA)
|
||||||
|
@@ -160,6 +161,9 @@ scsitape.o: scsitape.c mtx.h mtxl.h
|
||||||
|
scsieject@EXEEXT@: scsieject.o mtxl.o mtxl.h mtx.h $(EXTRA)
|
||||||
|
$(CC) $(LDFLAGS) -o scsieject@EXEEXT@ scsieject.o mtxl.o $(EXTRA) $(LIBS)
|
||||||
|
|
||||||
|
+$(LIB): mtx.o mtxl.o
|
||||||
|
+ ar qvs contrib/$(LIB) mtx.o mtxl.o
|
||||||
|
+ $(CC) $(LDFLAGS) -shared -o contrib/libmtx.so mtx.o mtxl.o
|
||||||
|
scsieject.o: scsieject.c mtx.h mtxl.h
|
||||||
|
|
||||||
|
loaderinfo.o: loaderinfo.c mtx.h mtxl.h
|
||||||
|
diff --git a/mtx-1.3.12/mtx.c b/mtx-1.3.12/mtx.c
|
||||||
|
index fab11bb..e09d161 100644
|
||||||
|
--- a/mtx-1.3.12/mtx.c
|
||||||
|
+++ b/mtx-1.3.12/mtx.c
|
||||||
|
@@ -79,7 +79,8 @@ static char *PeripheralDeviceType[32] =
|
||||||
|
static int argc;
|
||||||
|
static char **argv;
|
||||||
|
|
||||||
|
-static char *device=NULL; /* the device name passed as argument */
|
||||||
|
+char *device=NULL; /* the device name passed as argument */
|
||||||
|
+int absolute_addressing=0; /* if not 0 - use absolute adresses of storage and tranport elements as known to the robot */
|
||||||
|
|
||||||
|
/* Unfortunately this must be true for SGI, because SGI does not
|
||||||
|
use an int :-(.
|
||||||
|
@@ -496,14 +497,24 @@ static void Status(void)
|
||||||
|
TransferElementNumber < ElementStatus->DataTransferElementCount;
|
||||||
|
TransferElementNumber++)
|
||||||
|
{
|
||||||
|
-
|
||||||
|
+ if (absolute_addressing==0) {
|
||||||
|
printf("Data Transfer Element %d:", TransferElementNumber);
|
||||||
|
+ }
|
||||||
|
+ else {
|
||||||
|
+ printf("Data Transfer Element %d :", ElementStatus->DataTransferElementAddress[TransferElementNumber]);
|
||||||
|
+ }
|
||||||
|
if (ElementStatus->DataTransferElementFull[TransferElementNumber])
|
||||||
|
{
|
||||||
|
if (ElementStatus->DataTransferElementSourceStorageElementNumber[TransferElementNumber] > -1)
|
||||||
|
{
|
||||||
|
- printf("Full (Storage Element %d Loaded)",
|
||||||
|
- ElementStatus->DataTransferElementSourceStorageElementNumber[TransferElementNumber]+1);
|
||||||
|
+ if (absolute_addressing==0) {
|
||||||
|
+ printf("Full (Storage Element %d Loaded)",
|
||||||
|
+ ElementStatus->DataTransferElementSourceStorageElementNumber[TransferElementNumber]+1);
|
||||||
|
+ }
|
||||||
|
+ else {
|
||||||
|
+ printf("Full (Storage Element %d Loaded)",
|
||||||
|
+ ElementStatus->StorageElementAddress[TransferElementNumber]);
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
@@ -531,9 +542,16 @@ static void Status(void)
|
||||||
|
StorageElementNumber < ElementStatus->StorageElementCount;
|
||||||
|
StorageElementNumber++)
|
||||||
|
{
|
||||||
|
+ if (absolute_addressing==0) {
|
||||||
|
printf( " Storage Element %d%s:%s", StorageElementNumber + 1,
|
||||||
|
(ElementStatus->StorageElementIsImportExport[StorageElementNumber]) ? " IMPORT/EXPORT" : "",
|
||||||
|
(ElementStatus->StorageElementFull[StorageElementNumber] ? "Full " : "Empty"));
|
||||||
|
+ }
|
||||||
|
+ else {
|
||||||
|
+ printf( " Storage Element %d%s:%s", ElementStatus->StorageElementAddress[StorageElementNumber],
|
||||||
|
+ (ElementStatus->StorageElementIsImportExport[StorageElementNumber]) ? " IMPORT/EXPORT" : "",
|
||||||
|
+ (ElementStatus->StorageElementFull[StorageElementNumber] ? "Full " : "Empty"));
|
||||||
|
+ }
|
||||||
|
|
||||||
|
if (ElementStatus->PrimaryVolumeTag[StorageElementNumber][0])
|
||||||
|
{
|
||||||
|
@@ -918,7 +936,6 @@ void execute_command(struct command_table_struct *command)
|
||||||
|
}
|
||||||
|
open_device();
|
||||||
|
}
|
||||||
|
-
|
||||||
|
if (!ElementStatus && command->need_status)
|
||||||
|
{
|
||||||
|
inquiry_info = RequestInquiry(MediumChangerFD,&RequestSense);
|
||||||
|
diff --git a/mtx-1.3.12/mtxl.c b/mtx-1.3.12/mtxl.c
|
||||||
|
index c468f88..5e3b921 100644
|
||||||
|
--- a/mtx-1.3.12/mtxl.c
|
||||||
|
+++ b/mtx-1.3.12/mtxl.c
|
||||||
|
@@ -23,7 +23,7 @@
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FatalError: changed Feb. 2000 elg@badtux.org to eliminate a buffer
|
||||||
|
- * overflow :-(. That could be important if mtxl is SUID for some reason.
|
||||||
|
+ * overflow :-(. That could be important if mtxl is SUID for some reason.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mtx.h"
|
||||||
|
@@ -34,7 +34,7 @@
|
||||||
|
/* #define DEBUG_MODE_SENSE 1 */
|
||||||
|
/* #define DEBUG */
|
||||||
|
/* #define DEBUG_SCSI */
|
||||||
|
-#define __WEIRD_CHAR_SUPPRESS 1
|
||||||
|
+#define __WEIRD_CHAR_SUPPRESS 1
|
||||||
|
|
||||||
|
/* zap the following define when we finally add real import/export support */
|
||||||
|
#define IMPORT_EXPORT_HACK 1 /* for the moment, import/export == storage */
|
||||||
|
@@ -100,7 +100,7 @@ Inquiry_T *RequestInquiry(DEVICE_TYPE fd, RequestSense_T *RequestSense)
|
||||||
|
Inquiry_T *Inquiry;
|
||||||
|
CDB_T CDB;
|
||||||
|
|
||||||
|
- Inquiry = (Inquiry_T *) xmalloc(sizeof(Inquiry_T));
|
||||||
|
+ Inquiry = (Inquiry_T *) xmalloc(sizeof(Inquiry_T));
|
||||||
|
|
||||||
|
CDB[0] = 0x12; /* INQUIRY */
|
||||||
|
CDB[1] = 0; /* EVPD = 0 */
|
||||||
|
@@ -231,7 +231,8 @@ void FatalError(char *ErrorMessage, ...)
|
||||||
|
va_end(ArgumentPointer);
|
||||||
|
|
||||||
|
#ifndef VMS
|
||||||
|
- exit(1);
|
||||||
|
+ //exit(1);
|
||||||
|
+ return; /* if used as library routine it can not exit, because this would terminate the caller */
|
||||||
|
#else
|
||||||
|
sys$exit(VMS_ExitCode);
|
||||||
|
#endif
|
||||||
|
@@ -280,10 +281,10 @@ int max(int x, int y)
|
||||||
|
|
||||||
|
|
||||||
|
/* Okay, this is a hack for the NSM modular jukebox series, which
|
||||||
|
- * uses the "SEND DIAGNOSTIC" command to do shit.
|
||||||
|
+ * uses the "SEND DIAGNOSTIC" command to do shit.
|
||||||
|
*/
|
||||||
|
|
||||||
|
-int SendNSMHack(DEVICE_TYPE MediumChangerFD, NSM_Param_T *nsm_command,
|
||||||
|
+int SendNSMHack(DEVICE_TYPE MediumChangerFD, NSM_Param_T *nsm_command,
|
||||||
|
int param_len, int timeout)
|
||||||
|
{
|
||||||
|
CDB_T CDB;
|
||||||
|
@@ -362,7 +363,7 @@ NSM_Result_T *RecNSMHack( DEVICE_TYPE MediumChangerFD,
|
||||||
|
|
||||||
|
/* Routine to inventory the library. Needed by, e.g., some Breece Hill
|
||||||
|
* loaders. Sends an INITIALIZE_ELEMENT_STATUS command. This command
|
||||||
|
- * has no parameters, such as a range to scan :-(.
|
||||||
|
+ * has no parameters, such as a range to scan :-(.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int Inventory(DEVICE_TYPE MediumChangerFD)
|
||||||
|
@@ -370,7 +371,7 @@ int Inventory(DEVICE_TYPE MediumChangerFD)
|
||||||
|
CDB_T CDB;
|
||||||
|
|
||||||
|
/* okay, now for the command: */
|
||||||
|
- CDB[0] = 0x07;
|
||||||
|
+ CDB[0] = 0x07;
|
||||||
|
CDB[1] = CDB[2] = CDB[3] = CDB[4] = CDB[5] = 0;
|
||||||
|
|
||||||
|
/* set us a very long timeout, sigh... */
|
||||||
|
@@ -394,8 +395,8 @@ int Inventory(DEVICE_TYPE MediumChangerFD)
|
||||||
|
/* Routine to read the Mode Sense Element Address Assignment Page */
|
||||||
|
/* We try to read the page. If we can't read the page, we return NULL.
|
||||||
|
* Our caller really isn't too worried about why we could not read the
|
||||||
|
- * page, it will simply default to some kind of default values.
|
||||||
|
- */
|
||||||
|
+ * page, it will simply default to some kind of default values.
|
||||||
|
+ */
|
||||||
|
ElementModeSense_T *ReadAssignmentPage(DEVICE_TYPE MediumChangerFD)
|
||||||
|
{
|
||||||
|
CDB_T CDB;
|
||||||
|
@@ -405,7 +406,7 @@ ElementModeSense_T *ReadAssignmentPage(DEVICE_TYPE MediumChangerFD)
|
||||||
|
|
||||||
|
/* okay, now for the command: */
|
||||||
|
CDB[0] = 0x1A; /* Mode Sense(6) */
|
||||||
|
- CDB[1] = 0x08;
|
||||||
|
+ CDB[1] = 0x08;
|
||||||
|
CDB[2] = 0x1D; /* Mode Sense Element Address Assignment Page */
|
||||||
|
CDB[3] = 0;
|
||||||
|
CDB[4] = 136; /* allocation_length... */
|
||||||
|
@@ -482,7 +483,7 @@ ElementModeSense_T *ReadAssignmentPage(DEVICE_TYPE MediumChangerFD)
|
||||||
|
((int)sense_page->NumStorageHi << 8) + sense_page->NumStorageLo;
|
||||||
|
|
||||||
|
retval->ImportExportStart =
|
||||||
|
- ((int)sense_page->ImportExportStartHi << 8) + sense_page->ImportExportStartLo;
|
||||||
|
+ ((int)sense_page->ImportExportStartHi << 8) + sense_page->ImportExportStartLo;
|
||||||
|
|
||||||
|
retval->NumImportExport =
|
||||||
|
((int)sense_page->NumImportExportHi << 8) + sense_page->NumImportExportLo;
|
||||||
|
@@ -494,7 +495,7 @@ ElementModeSense_T *ReadAssignmentPage(DEVICE_TYPE MediumChangerFD)
|
||||||
|
((int)sense_page->NumDataTransferHi << 8) + sense_page->NumDataTransferLo;
|
||||||
|
|
||||||
|
/* allocate a couple spares 'cause some HP autochangers and maybe others
|
||||||
|
- * don't properly report the robotics arm(s) count here...
|
||||||
|
+ * don't properly report the robotics arm(s) count here...
|
||||||
|
*/
|
||||||
|
retval->NumElements =
|
||||||
|
retval->NumStorage+retval->NumImportExport +
|
||||||
|
@@ -549,7 +550,7 @@ static ElementStatus_T *AllocateElementData(ElementModeSense_T *mode_sense)
|
||||||
|
|
||||||
|
retval->DataTransferElementAddress =
|
||||||
|
(int *)xzmalloc(sizeof(int) * (mode_sense->NumDataTransfer + 1));
|
||||||
|
- retval->DataTransferElementSourceStorageElementNumber =
|
||||||
|
+ retval->DataTransferElementSourceStorageElementNumber =
|
||||||
|
(int *)xzmalloc(sizeof(int) * (mode_sense->NumDataTransfer + 1));
|
||||||
|
retval->DataTransferPrimaryVolumeTag =
|
||||||
|
(barcode *)xzmalloc(sizeof(barcode) * (mode_sense->NumDataTransfer + 1));
|
||||||
|
@@ -587,14 +588,14 @@ void copy_barcode(unsigned char *src, unsigned char *dest)
|
||||||
|
|
||||||
|
dest++;
|
||||||
|
}
|
||||||
|
- *dest = 0; /* null-terminate */
|
||||||
|
+ *dest = 0; /* null-terminate */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This #%!@# routine has more parameters than I can count! */
|
||||||
|
static unsigned char *SendElementStatusRequestActual(
|
||||||
|
DEVICE_TYPE MediumChangerFD,
|
||||||
|
RequestSense_T *RequestSense,
|
||||||
|
- Inquiry_T *inquiry_info,
|
||||||
|
+ Inquiry_T *inquiry_info,
|
||||||
|
SCSI_Flags_T *flags,
|
||||||
|
int ElementStart,
|
||||||
|
int NumElements,
|
||||||
|
@@ -609,7 +610,7 @@ static unsigned char *SendElementStatusRequestActual(
|
||||||
|
#ifdef HAVE_GET_ID_LUN
|
||||||
|
scsi_id_t *scsi_id;
|
||||||
|
#endif
|
||||||
|
- if (inquiry_info->MChngr &&
|
||||||
|
+ if (inquiry_info->MChngr &&
|
||||||
|
inquiry_info->PeripheralDeviceType != MEDIUM_CHANGER_TYPE)
|
||||||
|
{
|
||||||
|
is_attached = true;
|
||||||
|
@@ -617,7 +618,7 @@ static unsigned char *SendElementStatusRequestActual(
|
||||||
|
|
||||||
|
if (flags->no_attached)
|
||||||
|
{
|
||||||
|
- /* override, sigh */
|
||||||
|
+ /* override, sigh */
|
||||||
|
is_attached = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -633,11 +634,11 @@ static unsigned char *SendElementStatusRequestActual(
|
||||||
|
|
||||||
|
if (is_attached)
|
||||||
|
{
|
||||||
|
- CDB[0] = 0xB4; /* whoops, READ_ELEMENT_STATUS_ATTACHED! */
|
||||||
|
+ CDB[0] = 0xB4; /* whoops, READ_ELEMENT_STATUS_ATTACHED! */
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_GET_ID_LUN
|
||||||
|
- CDB[1] = (scsi_id->lun << 5) | ((flags->no_barcodes) ?
|
||||||
|
+ CDB[1] = (scsi_id->lun << 5) | ((flags->no_barcodes) ?
|
||||||
|
0 : 0x10) | flags->elementtype; /* Lun + VolTag + Type code */
|
||||||
|
free(scsi_id);
|
||||||
|
#else
|
||||||
|
@@ -677,7 +678,7 @@ static unsigned char *SendElementStatusRequestActual(
|
||||||
|
|
||||||
|
/*
|
||||||
|
First see if we have sense key of 'illegal request',
|
||||||
|
- additional sense code of '24', additional sense qualfier of
|
||||||
|
+ additional sense code of '24', additional sense qualfier of
|
||||||
|
'0', and field in error of '4'. This means that we issued a request
|
||||||
|
w/bar code reader and did not have one, thus must re-issue the request
|
||||||
|
w/out barcode :-(.
|
||||||
|
@@ -722,14 +723,14 @@ static unsigned char *SendElementStatusRequestActual(
|
||||||
|
PrintRequestSense(RequestSense); /* see what it sez :-(. */
|
||||||
|
fprintf(stderr,"Data:\n");
|
||||||
|
PrintHex(2, DataBuffer, 40);
|
||||||
|
-#endif
|
||||||
|
+#endif
|
||||||
|
return DataBuffer; /* we succeeded! */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unsigned char *SendElementStatusRequest(DEVICE_TYPE MediumChangerFD,
|
||||||
|
RequestSense_T *RequestSense,
|
||||||
|
- Inquiry_T *inquiry_info,
|
||||||
|
+ Inquiry_T *inquiry_info,
|
||||||
|
SCSI_Flags_T *flags,
|
||||||
|
int ElementStart,
|
||||||
|
int NumElements,
|
||||||
|
@@ -750,7 +751,7 @@ unsigned char *SendElementStatusRequest(DEVICE_TYPE MediumChangerFD,
|
||||||
|
/*
|
||||||
|
One weird loader wants either 8 or BYTE_COUNT_OF_REPORT
|
||||||
|
values for the ALLOCATION_LENGTH. Give it what it wants
|
||||||
|
- if we get an Sense Key of 05 Illegal Request with a
|
||||||
|
+ if we get an Sense Key of 05 Illegal Request with a
|
||||||
|
CDB position of 7 as the field in error.
|
||||||
|
*/
|
||||||
|
|
||||||
|
@@ -882,7 +883,7 @@ static void ParseElementStatus( int *EmptyStorageElementAddress,
|
||||||
|
{
|
||||||
|
/* TransportElementDescriptor =
|
||||||
|
(TransportElementDescriptor_T *) DataPointer; */
|
||||||
|
- memcpy(&TEBuf, DataPointer,
|
||||||
|
+ memcpy(&TEBuf, DataPointer,
|
||||||
|
(TransportElementDescriptorLength <= sizeof(TEBuf)) ?
|
||||||
|
TransportElementDescriptorLength :
|
||||||
|
sizeof(TEBuf));
|
||||||
|
@@ -909,7 +910,7 @@ static void ParseElementStatus( int *EmptyStorageElementAddress,
|
||||||
|
case MediumTransportElement:
|
||||||
|
ElementStatus->TransportElementAddress = BigEndian16(TransportElementDescriptor->ElementAddress);
|
||||||
|
#ifdef DEBUG
|
||||||
|
- fprintf(stderr,"TransportElementAddress=%d\n",ElementStatus->TransportElementAddress);
|
||||||
|
+ fprintf(stderr,"TransportElementAddress=%d\n",ElementStatus->TransportElementAddress);
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
|
||||||
|
@@ -936,7 +937,7 @@ static void ParseElementStatus( int *EmptyStorageElementAddress,
|
||||||
|
ElementStatus->StorageElementFull[ImportExportIndex] =
|
||||||
|
TransportElementDescriptor->Full;
|
||||||
|
|
||||||
|
- if ( (TransportElementDescriptorLength > 11) &&
|
||||||
|
+ if ( (TransportElementDescriptorLength > 11) &&
|
||||||
|
(ElementStatusPage->VolBits & E2_AVOLTAG))
|
||||||
|
{
|
||||||
|
copy_barcode(TransportElementDescriptor->AlternateVolumeTag,
|
||||||
|
@@ -945,8 +946,8 @@ static void ParseElementStatus( int *EmptyStorageElementAddress,
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ElementStatus->AlternateVolumeTag[ImportExportIndex][0] = 0; /* null string. */;
|
||||||
|
- }
|
||||||
|
- if ((TransportElementDescriptorLength > 11) &&
|
||||||
|
+ }
|
||||||
|
+ if ((TransportElementDescriptorLength > 11) &&
|
||||||
|
(ElementStatusPage->VolBits & E2_PVOLTAG))
|
||||||
|
{
|
||||||
|
copy_barcode(TransportElementDescriptor->PrimaryVolumeTag,
|
||||||
|
@@ -967,8 +968,8 @@ static void ParseElementStatus( int *EmptyStorageElementAddress,
|
||||||
|
fprintf(stderr,"StorageElementCount=%d ElementAddress = %d ",ElementStatus->StorageElementCount,BigEndian16(TransportElementDescriptor->ElementAddress));
|
||||||
|
#endif
|
||||||
|
/* ATL/Exabyte kludge -- skip slots that aren't installed :-( */
|
||||||
|
- if (TransportElementDescriptor->AdditionalSenseCode==0x83 &&
|
||||||
|
- TransportElementDescriptor->AdditionalSenseCodeQualifier==0x02)
|
||||||
|
+ if (TransportElementDescriptor->AdditionalSenseCode==0x83 &&
|
||||||
|
+ TransportElementDescriptor->AdditionalSenseCodeQualifier==0x02)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ElementStatus->StorageElementAddress[ElementStatus->StorageElementCount] =
|
||||||
|
@@ -986,7 +987,7 @@ static void ParseElementStatus( int *EmptyStorageElementAddress,
|
||||||
|
ElementStatus->StorageElementCount; /* slot idx. */
|
||||||
|
/* ElementStatus->StorageElementAddress[ElementStatus->StorageElementCount]; */
|
||||||
|
}
|
||||||
|
- if ((TransportElementDescriptorLength > 11) &&
|
||||||
|
+ if ((TransportElementDescriptorLength > 11) &&
|
||||||
|
(ElementStatusPage->VolBits & E2_AVOLTAG))
|
||||||
|
{
|
||||||
|
copy_barcode(TransportElementDescriptor->AlternateVolumeTag,
|
||||||
|
@@ -995,8 +996,8 @@ static void ParseElementStatus( int *EmptyStorageElementAddress,
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ElementStatus->AlternateVolumeTag[ElementStatus->StorageElementCount][0]=0; /* null string. */;
|
||||||
|
- }
|
||||||
|
- if ((TransportElementDescriptorLength > 11) &&
|
||||||
|
+ }
|
||||||
|
+ if ((TransportElementDescriptorLength > 11) &&
|
||||||
|
(ElementStatusPage->VolBits & E2_PVOLTAG))
|
||||||
|
{
|
||||||
|
copy_barcode(TransportElementDescriptor->PrimaryVolumeTag,
|
||||||
|
@@ -1009,9 +1010,9 @@ static void ParseElementStatus( int *EmptyStorageElementAddress,
|
||||||
|
|
||||||
|
ElementStatus->StorageElementCount++;
|
||||||
|
/*
|
||||||
|
- Note that the original mtx had no check here for
|
||||||
|
+ Note that the original mtx had no check here for
|
||||||
|
buffer overflow, though some drives might mistakingly
|
||||||
|
- do one...
|
||||||
|
+ do one...
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (ElementStatus->StorageElementCount > mode_sense->NumStorage)
|
||||||
|
@@ -1033,33 +1034,33 @@ static void ParseElementStatus( int *EmptyStorageElementAddress,
|
||||||
|
report that they have a 2nd tape drive when they don't. We
|
||||||
|
could generalize this in an ideal world, but my attempt to
|
||||||
|
do so failed with dual-drive Exabyte tape libraries that
|
||||||
|
- *DID* have the second drive. Sigh.
|
||||||
|
+ *DID* have the second drive. Sigh.
|
||||||
|
*/
|
||||||
|
- if (TransportElementDescriptor->AdditionalSenseCode==0x83 &&
|
||||||
|
+ if (TransportElementDescriptor->AdditionalSenseCode==0x83 &&
|
||||||
|
TransportElementDescriptor->AdditionalSenseCodeQualifier==0x04)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* generalize it. Does it work? Let's try it! */
|
||||||
|
- /*
|
||||||
|
+ /*
|
||||||
|
No, dammit, following does not work on dual-drive Exabyte
|
||||||
|
'cause if a tape is in the drive, it sets the AdditionalSense
|
||||||
|
code to something (sigh).
|
||||||
|
*/
|
||||||
|
/* if (TransportElementDescriptor->AdditionalSenseCode!=0)
|
||||||
|
continue;
|
||||||
|
- */
|
||||||
|
+ */
|
||||||
|
|
||||||
|
ElementStatus->DataTransferElementAddress[ElementStatus->DataTransferElementCount] =
|
||||||
|
BigEndian16(TransportElementDescriptor->ElementAddress);
|
||||||
|
- ElementStatus->DataTransferElementFull[ElementStatus->DataTransferElementCount] =
|
||||||
|
+ ElementStatus->DataTransferElementFull[ElementStatus->DataTransferElementCount] =
|
||||||
|
TransportElementDescriptor->Full;
|
||||||
|
ElementStatus->DataTransferElementSourceStorageElementNumber[ElementStatus->DataTransferElementCount] =
|
||||||
|
BigEndian16(TransportElementDescriptor->SourceStorageElementAddress);
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
- fprintf(stderr, "%d: ElementAddress = %d, Full = %d, SourceElement = %d\n",
|
||||||
|
+ fprintf(stderr, "%d: ElementAddress = %d, Full = %d, SourceElement = %d\n",
|
||||||
|
ElementStatus->DataTransferElementCount,
|
||||||
|
ElementStatus->DataTransferElementAddress[ElementStatus->DataTransferElementCount],
|
||||||
|
ElementStatus->DataTransferElementFull[ElementStatus->DataTransferElementCount],
|
||||||
|
@@ -1118,17 +1119,17 @@ static void ParseElementStatus( int *EmptyStorageElementAddress,
|
||||||
|
/*
|
||||||
|
* We no longer do the funky trick to figure out ALLOCATION_LENGTH.
|
||||||
|
* Instead, we use the SCSI Generic command rather than SEND_SCSI_COMMAND
|
||||||
|
- * under Linux, which gets around the @#%@ 4k buffer size in Linux.
|
||||||
|
+ * under Linux, which gets around the @#%@ 4k buffer size in Linux.
|
||||||
|
* We still have the restriction that Linux cuts off the last two
|
||||||
|
* bytes of the SENSE DATA (Q#@$%@#$^ Linux!). Which means that the
|
||||||
|
- * verbose widget won't work :-(.
|
||||||
|
-
|
||||||
|
+ * verbose widget won't work :-(.
|
||||||
|
+
|
||||||
|
* We now look for that "attached" bit in the inquiry_info to see whether
|
||||||
|
* to use READ_ELEMENT_ATTACHED or plain old READ_ELEMENT. In addition, we
|
||||||
|
* look at the device type in the inquiry_info to see whether it is a media
|
||||||
|
* changer or tape device, and if it's a media changer device, we ignore the
|
||||||
|
* attached bit (one beta tester found an old 4-tape DAT changer that set
|
||||||
|
- * the attached bit for both the tape device AND the media changer device).
|
||||||
|
+ * the attached bit for both the tape device AND the media changer device).
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
@@ -1155,7 +1156,7 @@ ElementStatus_T *ReadElementStatus(DEVICE_TYPE MediumChangerFD, RequestSense_T *
|
||||||
|
|
||||||
|
if (flags->no_attached)
|
||||||
|
{
|
||||||
|
- /* override, sigh */
|
||||||
|
+ /* override, sigh */
|
||||||
|
is_attached = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1185,7 +1186,7 @@ ElementStatus_T *ReadElementStatus(DEVICE_TYPE MediumChangerFD, RequestSense_T *
|
||||||
|
ElementStatus->DataTransferElementCount = 0;
|
||||||
|
|
||||||
|
/* first, allocate some empty storage stuff: Note that we pass this
|
||||||
|
- * down to ParseElementStatus (sigh!)
|
||||||
|
+ * down to ParseElementStatus (sigh!)
|
||||||
|
*/
|
||||||
|
|
||||||
|
EmptyStorageElementAddress = (int *)xzmalloc((mode_sense->NumStorage+1)*sizeof(int));
|
||||||
|
@@ -1202,7 +1203,7 @@ ElementStatus_T *ReadElementStatus(DEVICE_TYPE MediumChangerFD, RequestSense_T *
|
||||||
|
for (i = 0; i < mode_sense->NumDataTransfer; i++)
|
||||||
|
{
|
||||||
|
/* initialize them to an illegal # so that we can fix later... */
|
||||||
|
- ElementStatus->DataTransferElementSourceStorageElementNumber[i] = -1;
|
||||||
|
+ ElementStatus->DataTransferElementSourceStorageElementNumber[i] = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags->querytype == MTX_ELEMENTSTATUS_ORIGINAL)
|
||||||
|
@@ -1308,7 +1309,7 @@ ElementStatus_T *ReadElementStatus(DEVICE_TYPE MediumChangerFD, RequestSense_T *
|
||||||
|
PrintRequestSense(RequestSense);
|
||||||
|
#endif
|
||||||
|
FreeElementData(ElementStatus);
|
||||||
|
- return NULL;
|
||||||
|
+ return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
@@ -1323,7 +1324,7 @@ ElementStatus_T *ReadElementStatus(DEVICE_TYPE MediumChangerFD, RequestSense_T *
|
||||||
|
|
||||||
|
/* grr, damned brain dead HP doesn't report that it has any! */
|
||||||
|
if (!mode_sense->NumMediumTransport)
|
||||||
|
- {
|
||||||
|
+ {
|
||||||
|
ElementStatus->TransportElementAddress = 0; /* default it sensibly :-(. */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
@@ -1347,8 +1348,8 @@ ElementStatus_T *ReadElementStatus(DEVICE_TYPE MediumChangerFD, RequestSense_T *
|
||||||
|
PrintRequestSense(RequestSense);
|
||||||
|
#endif
|
||||||
|
FreeElementData(ElementStatus);
|
||||||
|
- return NULL;
|
||||||
|
- }
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
#ifdef DEBUG
|
||||||
|
fprintf(stderr,"Parsing robot arm data\n");
|
||||||
|
#endif
|
||||||
|
@@ -1366,8 +1367,8 @@ ElementStatus_T *ReadElementStatus(DEVICE_TYPE MediumChangerFD, RequestSense_T *
|
||||||
|
fprintf(stderr,"Using alternative element status polling method (all elements)\n");
|
||||||
|
#endif
|
||||||
|
/* ----------------- ALL Elements ---------------------- */
|
||||||
|
- /* Just keep asking for elements till no more are returned
|
||||||
|
- - increment our starting address as we go acording to the
|
||||||
|
+ /* Just keep asking for elements till no more are returned
|
||||||
|
+ - increment our starting address as we go acording to the
|
||||||
|
number of elements returned from the last call
|
||||||
|
*/
|
||||||
|
|
||||||
|
@@ -1384,7 +1385,7 @@ ElementStatus_T *ReadElementStatus(DEVICE_TYPE MediumChangerFD, RequestSense_T *
|
||||||
|
mode_sense->MaxReadElementStatusData);
|
||||||
|
if (!DataBuffer)
|
||||||
|
{
|
||||||
|
- if (RequestSense->AdditionalSenseCode == 0x21 &&
|
||||||
|
+ if (RequestSense->AdditionalSenseCode == 0x21 &&
|
||||||
|
RequestSense->AdditionalSenseCodeQualifier == 0x01)
|
||||||
|
{
|
||||||
|
/* Error is invalid element address, we've probably just hit the end */
|
||||||
|
@@ -1393,8 +1394,8 @@ ElementStatus_T *ReadElementStatus(DEVICE_TYPE MediumChangerFD, RequestSense_T *
|
||||||
|
|
||||||
|
/* darn. Free up stuff and return. */
|
||||||
|
FreeElementData(ElementStatus);
|
||||||
|
- return NULL;
|
||||||
|
- }
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
nLastEl = nNextEl;
|
||||||
|
|
||||||
|
@@ -1423,7 +1424,7 @@ ElementStatus_T *ReadElementStatus(DEVICE_TYPE MediumChangerFD, RequestSense_T *
|
||||||
|
*
|
||||||
|
* Pass1:
|
||||||
|
* Translate from raw element # to our translated # (if possible).
|
||||||
|
- * First, check the SourceStorageElementNumbers against the list of
|
||||||
|
+ * First, check the SourceStorageElementNumbers against the list of
|
||||||
|
* filled slots. If the slots indicated are empty, we accept that list as
|
||||||
|
* valid. Otherwise decide the SourceStorageElementNumbers are invalid.
|
||||||
|
*
|
||||||
|
@@ -1432,7 +1433,7 @@ ElementStatus_T *ReadElementStatus(DEVICE_TYPE MediumChangerFD, RequestSense_T *
|
||||||
|
* then we must search for free slots, and assign SourceStorageElementNumbers
|
||||||
|
* to those free slots. We happen to already built a list of free
|
||||||
|
* slots as part of the process of reading the storage element numbers
|
||||||
|
- * from the tape. So that's easy enough to do!
|
||||||
|
+ * from the tape. So that's easy enough to do!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef DEBUG_TAPELIST
|
||||||
|
@@ -1448,7 +1449,7 @@ ElementStatus_T *ReadElementStatus(DEVICE_TYPE MediumChangerFD, RequestSense_T *
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now we re-assign origin slots if the "real" origin slot
|
||||||
|
- * is obviously defective:
|
||||||
|
+ * is obviously defective:
|
||||||
|
*/
|
||||||
|
/* pass one: */
|
||||||
|
for (i = 0; i < ElementStatus->DataTransferElementCount; i++)
|
||||||
|
@@ -1486,12 +1487,12 @@ ElementStatus_T *ReadElementStatus(DEVICE_TYPE MediumChangerFD, RequestSense_T *
|
||||||
|
* drives will be assigned a -1 (see the initialization loop for
|
||||||
|
* EmptyStorageElementAddress above), which will be reported as "slot 0"
|
||||||
|
* by the user interface. This is an invalid value, but more useful for us
|
||||||
|
- * to have than just crapping out here :-(.
|
||||||
|
+ * to have than just crapping out here :-(.
|
||||||
|
*/
|
||||||
|
empty_idx=0;
|
||||||
|
for (i = 0; i < ElementStatus->DataTransferElementCount; i++)
|
||||||
|
{
|
||||||
|
- if (ElementStatus->DataTransferElementFull[i] &&
|
||||||
|
+ if (ElementStatus->DataTransferElementFull[i] &&
|
||||||
|
ElementStatus->DataTransferElementSourceStorageElementNumber[i] < 0)
|
||||||
|
{
|
||||||
|
#ifdef DEBUG_TAPELIST
|
||||||
|
@@ -1543,7 +1544,7 @@ RequestSense_T *PositionElement(DEVICE_TYPE MediumChangerFD,
|
||||||
|
|
||||||
|
/* Now the actual media movement routine! */
|
||||||
|
RequestSense_T *MoveMedium( DEVICE_TYPE MediumChangerFD, int SourceAddress,
|
||||||
|
- int DestinationAddress,
|
||||||
|
+ int DestinationAddress,
|
||||||
|
ElementStatus_T *ElementStatus,
|
||||||
|
Inquiry_T *inquiry_info, SCSI_Flags_T *flags)
|
||||||
|
{
|
||||||
|
@@ -1646,7 +1647,7 @@ RequestSense_T *ExchangeMedium( DEVICE_TYPE MediumChangerFD, int SourceAddress,
|
||||||
|
|
||||||
|
#ifdef DEBUG_EXCHANGE
|
||||||
|
dump_cdb(&CDB,12);
|
||||||
|
-#endif
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
if (SCSI_ExecuteCommand(MediumChangerFD, Output, &CDB, 12,
|
||||||
|
NULL, 0, RequestSense) != 0)
|
||||||
|
@@ -1690,8 +1691,8 @@ RequestSense_T *Erase(DEVICE_TYPE MediumChangerFD)
|
||||||
|
return NULL; /* Success! */
|
||||||
|
}
|
||||||
|
|
||||||
|
-/* Routine to send an LOAD/UNLOAD from the MMC/SSC spec to a device.
|
||||||
|
- * For tapes and changers this can be used either to eject a tape
|
||||||
|
+/* Routine to send an LOAD/UNLOAD from the MMC/SSC spec to a device.
|
||||||
|
+ * For tapes and changers this can be used either to eject a tape
|
||||||
|
* or to eject a magazine (on some Seagate changers, when sent to LUN 1 ).
|
||||||
|
* For CD/DVDs this is used to Load or Unload a disc which is required by
|
||||||
|
* some media changers.
|
||||||
|
@@ -1721,8 +1722,8 @@ int LoadUnload(DEVICE_TYPE fd, int bLoad)
|
||||||
|
return 0; /* did do! */
|
||||||
|
}
|
||||||
|
|
||||||
|
-/* Routine to send an START/STOP from the MMC/SSC spec to a device.
|
||||||
|
- * For tape drives this may be required prior to using the changer
|
||||||
|
+/* Routine to send an START/STOP from the MMC/SSC spec to a device.
|
||||||
|
+ * For tape drives this may be required prior to using the changer
|
||||||
|
* Load or Unload commands.
|
||||||
|
* For CD/DVD drives this is used to Load or Unload a disc which may be
|
||||||
|
* required by some media changers.
|
||||||
|
@@ -1746,9 +1747,9 @@ int StartStop(DEVICE_TYPE fd, int bStart)
|
||||||
|
return 0; /* did do! */
|
||||||
|
}
|
||||||
|
|
||||||
|
-/* Routine to send a LOCK/UNLOCK from the SSC/MMC spec to a device.
|
||||||
|
+/* Routine to send a LOCK/UNLOCK from the SSC/MMC spec to a device.
|
||||||
|
* This can be used to prevent or allow the Tape or CD/DVD from being
|
||||||
|
- * removed.
|
||||||
|
+ * removed.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int LockUnlock(DEVICE_TYPE fd, int bLock)
|
||||||
|
@@ -1876,7 +1877,7 @@ void PrintRequestSense(RequestSense_T *RequestSense)
|
||||||
|
fprintf(stderr, "mtx: Request Sense: Valid Residual=%s\n", RequestSense->Valid ? Yes : No);
|
||||||
|
|
||||||
|
if (RequestSense->ErrorCode == 0x70)
|
||||||
|
- {
|
||||||
|
+ {
|
||||||
|
msg = "Current" ;
|
||||||
|
}
|
||||||
|
else if (RequestSense->ErrorCode == 0x71)
|
||||||
Reference in New Issue
Block a user