Added physical location and serial tape drive serial number to the Status output.

This commit is contained in:
Alexander Moibenko
2018-08-16 16:13:34 -05:00
parent a13704f62f
commit 7b8da461e5
4 changed files with 138 additions and 31 deletions

Binary file not shown.

View File

@@ -80,7 +80,7 @@ static int argc;
static char **argv; static char **argv;
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 */ int absolute_addressing=1; /* 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 :-(.
@@ -485,6 +485,7 @@ static void Status(void)
{ {
int StorageElementNumber; int StorageElementNumber;
int TransferElementNumber; int TransferElementNumber;
PhysicalLocation_T *phys_loc;
printf( " Storage Changer %s:%d Drives, %d Slots ( %d Import/Export )\n", printf( " Storage Changer %s:%d Drives, %d Slots ( %d Import/Export )\n",
device, device,
@@ -501,7 +502,12 @@ static void Status(void)
printf("Data Transfer Element %d:", TransferElementNumber); printf("Data Transfer Element %d:", TransferElementNumber);
} }
else { else {
printf("Data Transfer Element %d :", ElementStatus->DataTransferElementAddress[TransferElementNumber]); //printf("SSSSSNNNNN %s\n", ElementStatus->DataTransferElementSerialNumber[TransferElementNumber]);
printf("Data Transfer Element %d ", ElementStatus->DataTransferElementAddress[TransferElementNumber]);
phys_loc = (PhysicalLocation_T *) &ElementStatus->DataTransferElementPhysicalLocation[TransferElementNumber];
printf("Phys Loc F%u,C%u,R%u,Z%u SN%s:",
phys_loc->frame, phys_loc->column, phys_loc->row, phys_loc->zone,
ElementStatus->DataTransferElementSerialNumber[TransferElementNumber]);
} }
if (ElementStatus->DataTransferElementFull[TransferElementNumber]) if (ElementStatus->DataTransferElementFull[TransferElementNumber])
{ {
@@ -548,9 +554,10 @@ static void Status(void)
(ElementStatus->StorageElementFull[StorageElementNumber] ? "Full " : "Empty")); (ElementStatus->StorageElementFull[StorageElementNumber] ? "Full " : "Empty"));
} }
else { else {
printf( " Storage Element %d%s:%s", ElementStatus->StorageElementAddress[StorageElementNumber], printf( " Storage Element %d Phys Loc %s %s:%s ", ElementStatus->StorageElementAddress[StorageElementNumber],
(ElementStatus->StorageElementIsImportExport[StorageElementNumber]) ? " IMPORT/EXPORT" : "", ElementStatus->StorageElementPhysicalLocation[StorageElementNumber],
(ElementStatus->StorageElementFull[StorageElementNumber] ? "Full " : "Empty")); (ElementStatus->StorageElementIsImportExport[StorageElementNumber]) ? " IMPORT/EXPORT" : "",
(ElementStatus->StorageElementFull[StorageElementNumber] ? "Full " : "Empty"));
} }
if (ElementStatus->PrimaryVolumeTag[StorageElementNumber][0]) if (ElementStatus->PrimaryVolumeTag[StorageElementNumber][0])

View File

@@ -209,6 +209,7 @@ typedef struct SCSI_Flags_Struct
int has_barcodes; int has_barcodes;
int querytype; //MTX_ELEMENTSTATUS int querytype; //MTX_ELEMENTSTATUS
unsigned char invert2; /* used for EXCHANGE command, sigh. */ unsigned char invert2; /* used for EXCHANGE command, sigh. */
int absolute_addressing; /* indicates that asolute addresses are required */
} SCSI_Flags_T; } SCSI_Flags_T;
#ifdef _MSC_VER #ifdef _MSC_VER
@@ -306,6 +307,16 @@ typedef struct Inquiry
} }
Inquiry_T; Inquiry_T;
typedef struct InquiryShort
{
unsigned char pad[2];
unsigned char VendorIdentification[8]; /* Bytes 8-15 */
unsigned char ProductIdentification[16]; /* Bytes 16-31 */
unsigned char SerialNumber[12]; /* Bytes 32-43 */
}
InquiryShort_T;
/* Hockey Pux may define these. If so, *UN*define them. */ /* Hockey Pux may define these. If so, *UN*define them. */
#ifdef ILI #ifdef ILI
#undef ILI #undef ILI
@@ -499,6 +510,15 @@ typedef struct TransportElementDescriptorShort
} }
TransportElementDescriptorShort_T; TransportElementDescriptorShort_T;
typedef struct PhysicalLocation
{
unsigned char zone :1;
unsigned char : 3;
unsigned char row: 4;
unsigned char column :3;
unsigned char frame :5;
} PhysicalLocation_T;
typedef struct TransportElementDescriptor typedef struct TransportElementDescriptor
{ {
@@ -545,6 +565,7 @@ TransportElementDescriptor_T;
/* Now for element status data; */ /* Now for element status data; */
typedef unsigned char barcode[37]; typedef unsigned char barcode[37];
typedef unsigned char serialnumber[13];
typedef struct ElementStatus { typedef struct ElementStatus {
@@ -553,6 +574,9 @@ typedef struct ElementStatus {
int DataTransferElementCount; int DataTransferElementCount;
int *DataTransferElementAddress; /* array. */ int *DataTransferElementAddress; /* array. */
int *DataTransferElementSourceStorageElementNumber; /* array */ int *DataTransferElementSourceStorageElementNumber; /* array */
int *DataTransferElementPhysicalLocation; /*array */
serialnumber *DataTransferElementSerialNumber; /*array */
barcode *StorageElementPhysicalLocation; /*array */
barcode *DataTransferPrimaryVolumeTag; /* array. */ barcode *DataTransferPrimaryVolumeTag; /* array. */
barcode *DataTransferAlternateVolumeTag; /* array. */ barcode *DataTransferAlternateVolumeTag; /* array. */
barcode *PrimaryVolumeTag; /* array */ barcode *PrimaryVolumeTag; /* array */

View File

@@ -30,7 +30,7 @@
#include "mtxl.h" #include "mtxl.h"
/* #define DEBUG_NSM 1 */ /* #define DEBUG_NSM 1 */
/* #define DEBUG_BARCODE */
/* #define DEBUG_MODE_SENSE 1 */ /* #define DEBUG_MODE_SENSE 1 */
/* #define DEBUG */ /* #define DEBUG */
/* #define DEBUG_SCSI */ /* #define DEBUG_SCSI */
@@ -527,6 +527,9 @@ static void FreeElementData(ElementStatus_T *data)
{ {
free(data->DataTransferElementAddress); free(data->DataTransferElementAddress);
free(data->DataTransferElementSourceStorageElementNumber); free(data->DataTransferElementSourceStorageElementNumber);
free(data->DataTransferElementPhysicalLocation);
free(data->DataTransferElementSerialNumber);
free(data->StorageElementPhysicalLocation);
free(data->DataTransferPrimaryVolumeTag); free(data->DataTransferPrimaryVolumeTag);
free(data->DataTransferAlternateVolumeTag); free(data->DataTransferAlternateVolumeTag);
free(data->PrimaryVolumeTag); free(data->PrimaryVolumeTag);
@@ -552,6 +555,12 @@ static ElementStatus_T *AllocateElementData(ElementModeSense_T *mode_sense)
(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->DataTransferElementPhysicalLocation =
(int *)xzmalloc(sizeof(int) * (mode_sense->NumDataTransfer + 1));
retval->DataTransferElementSerialNumber =
(serialnumber *)xzmalloc(sizeof(serialnumber) * (mode_sense->NumDataTransfer + 1));
retval->StorageElementPhysicalLocation =
(barcode *)xzmalloc(sizeof(barcode) * (mode_sense->NumStorage + 1));
retval->DataTransferPrimaryVolumeTag = retval->DataTransferPrimaryVolumeTag =
(barcode *)xzmalloc(sizeof(barcode) * (mode_sense->NumDataTransfer + 1)); (barcode *)xzmalloc(sizeof(barcode) * (mode_sense->NumDataTransfer + 1));
retval->DataTransferAlternateVolumeTag = retval->DataTransferAlternateVolumeTag =
@@ -591,6 +600,34 @@ void copy_barcode(unsigned char *src, unsigned char *dest)
*dest = 0; /* null-terminate */ *dest = 0; /* null-terminate */
} }
void copy_physical_location(unsigned char *src, unsigned char *dest)
{
while ((*src< 32) || (*src > 127)) {
src++;
}
strcpy((char *)dest, (char *)src);
}
void copy_serial_number(unsigned char *src, unsigned char *dest)
{
int i;
while ((*src< 32) || (*src > 127)) {
src++;
}
for (i=0; i < 12; i++)
{
*dest = *src++;
if ((*dest < 32) || (*dest > 127))
{
*dest = 0;
break;
}
dest++;
}
*dest = 0;
}
/* 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,
@@ -654,6 +691,9 @@ static unsigned char *SendElementStatusRequestActual(
CDB[5]= (unsigned char)NumElements; CDB[5]= (unsigned char)NumElements;
CDB[6] = 0; /* Reserved */ CDB[6] = 0; /* Reserved */
if (((flags->elementtype == DataTransferElement || flags->elementtype == StorageElement)) && (flags->absolute_addressing == 1)) {
CDB[6] = 0x01; /* set DVCID to read physical location */
}
/* allocation length */ /* allocation length */
CDB[7]= (unsigned char)(NumBytes >> 16); CDB[7]= (unsigned char)(NumBytes >> 16);
@@ -722,7 +762,7 @@ static unsigned char *SendElementStatusRequestActual(
/* print a bunch of extra debug data :-(. */ /* print a bunch of extra debug data :-(. */
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, 100);
#endif #endif
return DataBuffer; /* we succeeded! */ return DataBuffer; /* we succeeded! */
} }
@@ -806,12 +846,13 @@ unsigned char *SendElementStatusRequest(DEVICE_TYPE MediumChangerFD,
*/ */
static void ParseElementStatus( int *EmptyStorageElementAddress, static void ParseElementStatus( int *EmptyStorageElementAddress,
int *EmptyStorageElementCount, int *EmptyStorageElementCount,
unsigned char *DataBuffer, unsigned char *DataBuffer,
ElementStatus_T *ElementStatus, ElementStatus_T *ElementStatus,
ElementModeSense_T *mode_sense, ElementModeSense_T *mode_sense,
int *pNextElement int *pNextElement,
) boolean absolute_address
)
{ {
unsigned char *DataPointer = DataBuffer; unsigned char *DataPointer = DataBuffer;
TransportElementDescriptor_T TEBuf; TransportElementDescriptor_T TEBuf;
@@ -987,12 +1028,6 @@ static void ParseElementStatus( int *EmptyStorageElementAddress,
ElementStatus->StorageElementCount; /* slot idx. */ ElementStatus->StorageElementCount; /* slot idx. */
/* ElementStatus->StorageElementAddress[ElementStatus->StorageElementCount]; */ /* ElementStatus->StorageElementAddress[ElementStatus->StorageElementCount]; */
} }
if ((TransportElementDescriptorLength > 11) &&
(ElementStatusPage->VolBits & E2_AVOLTAG))
{
copy_barcode(TransportElementDescriptor->AlternateVolumeTag,
ElementStatus->AlternateVolumeTag[ElementStatus->StorageElementCount]);
}
else else
{ {
ElementStatus->AlternateVolumeTag[ElementStatus->StorageElementCount][0]=0; /* null string. */; ElementStatus->AlternateVolumeTag[ElementStatus->StorageElementCount][0]=0; /* null string. */;
@@ -1007,7 +1042,11 @@ static void ParseElementStatus( int *EmptyStorageElementAddress,
{ {
ElementStatus->PrimaryVolumeTag[ElementStatus->StorageElementCount][0]=0; /* null string. */ ElementStatus->PrimaryVolumeTag[ElementStatus->StorageElementCount][0]=0; /* null string. */
} }
if (absolute_address){
copy_physical_location(TransportElementDescriptor->AlternateVolumeTag, ElementStatus->StorageElementPhysicalLocation[ElementStatus->StorageElementCount]);
}
ElementStatus->StorageElementCount++; ElementStatus->StorageElementCount++;
/* /*
Note that the original mtx had no check here for Note that the original mtx had no check here for
@@ -1052,19 +1091,28 @@ static void ParseElementStatus( int *EmptyStorageElementAddress,
continue; continue;
*/ */
if (absolute_address){
ElementStatus->DataTransferElementPhysicalLocation[ElementStatus->DataTransferElementCount] =
BigEndian16(TransportElementDescriptor->SourceStorageElementAddress);
InquiryShort_T *inqs;
inqs = (InquiryShort_T *) TransportElementDescriptor->PrimaryVolumeTag;
copy_serial_number(inqs->SerialNumber, ElementStatus->DataTransferElementSerialNumber[ElementStatus->DataTransferElementCount]);
ElementStatus->DataTransferElementCount++;
break;
}
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],
ElementStatus->DataTransferElementSourceStorageElementNumber[ElementStatus->DataTransferElementCount]); ElementStatus->DataTransferElementSourceStorageElementNumber[ElementStatus->DataTransferElementCount]);
#endif #endif
if (ElementStatus->DataTransferElementCount >= mode_sense->NumDataTransfer) if (ElementStatus->DataTransferElementCount >= mode_sense->NumDataTransfer)
{ {
@@ -1213,6 +1261,7 @@ ElementStatus_T *ReadElementStatus(DEVICE_TYPE MediumChangerFD, RequestSense_T *
fprintf(stderr,"Storage start %d, Num %d, max %d\n", mode_sense->StorageStart, mode_sense->NumStorage - mode_sense->NumImportExport, mode_sense->MaxReadElementStatusData); fprintf(stderr,"Storage start %d, Num %d, max %d\n", mode_sense->StorageStart, mode_sense->NumStorage - mode_sense->NumImportExport, mode_sense->MaxReadElementStatusData);
#endif #endif
flags->elementtype = StorageElement; /* sigh! */ flags->elementtype = StorageElement; /* sigh! */
flags->absolute_addressing = 1;
NumElements = mode_sense->NumStorage - mode_sense->NumImportExport; NumElements = mode_sense->NumStorage - mode_sense->NumImportExport;
FirstElem = mode_sense->StorageStart; FirstElem = mode_sense->StorageStart;
@@ -1244,13 +1293,14 @@ ElementStatus_T *ReadElementStatus(DEVICE_TYPE MediumChangerFD, RequestSense_T *
fprintf(stderr, "Parsing storage elements\n"); fprintf(stderr, "Parsing storage elements\n");
#endif #endif
ParseElementStatus(EmptyStorageElementAddress, &EmptyStorageElementCount, ParseElementStatus(EmptyStorageElementAddress, &EmptyStorageElementCount,
DataBuffer,ElementStatus,mode_sense,NULL); DataBuffer,ElementStatus,mode_sense,NULL, true);
free(DataBuffer); /* sigh! */ free(DataBuffer); /* sigh! */
FirstElem += SCSI_RES_ELEMENTS; FirstElem += SCSI_RES_ELEMENTS;
NumElements -= SCSI_RES_ELEMENTS; NumElements -= SCSI_RES_ELEMENTS;
} while ( NumElements > 0 ); } while ( NumElements > 0 );
flags->absolute_addressing = 0;
/* --------------IMPORT/EXPORT--------------- */ /* --------------IMPORT/EXPORT--------------- */
/* Next let's see if we need to do Import/Export: */ /* Next let's see if we need to do Import/Export: */
if (mode_sense->NumImportExport > 0) if (mode_sense->NumImportExport > 0)
@@ -1283,7 +1333,7 @@ ElementStatus_T *ReadElementStatus(DEVICE_TYPE MediumChangerFD, RequestSense_T *
dump_data(DataBuffer, 100); /* dump some data :-(. */ dump_data(DataBuffer, 100); /* dump some data :-(. */
#endif #endif
ParseElementStatus( EmptyStorageElementAddress, &EmptyStorageElementCount, ParseElementStatus( EmptyStorageElementAddress, &EmptyStorageElementCount,
DataBuffer, ElementStatus, mode_sense, NULL); DataBuffer, ElementStatus, mode_sense, NULL, false);
free(DataBuffer); free(DataBuffer);
ElementStatus->StorageElementCount += ElementStatus->ImportExportCount; ElementStatus->StorageElementCount += ElementStatus->ImportExportCount;
} }
@@ -1294,6 +1344,7 @@ ElementStatus_T *ReadElementStatus(DEVICE_TYPE MediumChangerFD, RequestSense_T *
fprintf(stderr,"Sending request for data transfer element (drive) status\n"); fprintf(stderr,"Sending request for data transfer element (drive) status\n");
#endif #endif
flags->elementtype = DataTransferElement; /* sigh! */ flags->elementtype = DataTransferElement; /* sigh! */
flags->absolute_addressing = 0;
DataBuffer = SendElementStatusRequest( MediumChangerFD, RequestSense, DataBuffer = SendElementStatusRequest( MediumChangerFD, RequestSense,
inquiry_info, flags, inquiry_info, flags,
mode_sense->DataTransferStart, mode_sense->DataTransferStart,
@@ -1316,7 +1367,31 @@ ElementStatus_T *ReadElementStatus(DEVICE_TYPE MediumChangerFD, RequestSense_T *
fprintf(stderr,"Parsing data for data transfer element (drive) status\n"); fprintf(stderr,"Parsing data for data transfer element (drive) status\n");
#endif #endif
ParseElementStatus( EmptyStorageElementAddress, &EmptyStorageElementCount, ParseElementStatus( EmptyStorageElementAddress, &EmptyStorageElementCount,
DataBuffer,ElementStatus, mode_sense, NULL); DataBuffer,ElementStatus, mode_sense, NULL, false);
free(DataBuffer); /* sigh! */
flags->absolute_addressing = 1;
DataBuffer = SendElementStatusRequest( MediumChangerFD, RequestSense,
inquiry_info, flags,
mode_sense->DataTransferStart,
mode_sense->NumDataTransfer,
SCSI_RES_ELEMENTS * 52 +120);
if (!DataBuffer)
{
#ifdef DEBUG
fprintf(stderr,"No data transfer element status.");
#endif
/* darn. Free up stuff and return. */
#ifdef DEBUG_MODE_SENSE
PrintRequestSense(RequestSense);
#endif
FreeElementData(ElementStatus);
return NULL;
}
ElementStatus->DataTransferElementCount = 0;
ParseElementStatus( EmptyStorageElementAddress, &EmptyStorageElementCount,
DataBuffer,ElementStatus, mode_sense, NULL, true);
free(DataBuffer); /* sigh! */ free(DataBuffer); /* sigh! */
@@ -1354,10 +1429,11 @@ ElementStatus_T *ReadElementStatus(DEVICE_TYPE MediumChangerFD, RequestSense_T *
fprintf(stderr,"Parsing robot arm data\n"); fprintf(stderr,"Parsing robot arm data\n");
#endif #endif
ParseElementStatus( EmptyStorageElementAddress, &EmptyStorageElementCount, ParseElementStatus( EmptyStorageElementAddress, &EmptyStorageElementCount,
DataBuffer, ElementStatus, mode_sense, NULL); DataBuffer, ElementStatus, mode_sense, NULL, false);
free(DataBuffer); free(DataBuffer);
} }
flags->absolute_addressing = 0;
} }
else else
{ {
@@ -1400,7 +1476,7 @@ ElementStatus_T *ReadElementStatus(DEVICE_TYPE MediumChangerFD, RequestSense_T *
nLastEl = nNextEl; nLastEl = nNextEl;
ParseElementStatus( EmptyStorageElementAddress, &EmptyStorageElementCount, ParseElementStatus( EmptyStorageElementAddress, &EmptyStorageElementCount,
DataBuffer, ElementStatus, mode_sense, &nNextEl); DataBuffer, ElementStatus, mode_sense, &nNextEl, false);
free(DataBuffer); /* sigh! */ free(DataBuffer); /* sigh! */
} }