*/
/*
-* $Date: 2001/06/05 17:10:21 $
-* $Revision: 1.1.1.1 $
+* $Date: 2007-03-24 18:38:20 -0700 (Sat, 24 Mar 2007) $
+* $Revision: 167 $
*/
/* What this does: Basically dumps out contents of:
char *argv0;
/* A table for printing out the peripheral device type as ASCII. */
-static char *PeripheralDeviceType[32] = {
- "Disk Drive",
- "Tape Drive",
- "Printer",
- "Processor",
- "Write-once",
- "CD-ROM",
- "Scanner",
- "Optical",
- "Medium Changer",
- "Communications",
- "ASC IT8",
- "ASC IT8",
- "RAID Array",
- "Enclosure Services",
- "OCR/W",
- "Bridging Expander", /* 0x10 */
- "Reserved", /* 0x11 */
- "Reserved", /* 0x12 */
- "Reserved", /* 0x13 */
- "Reserved", /* 0x14 */
- "Reserved", /* 0x15 */
- "Reserved", /* 0x16 */
- "Reserved", /* 0x17 */
- "Reserved", /* 0x18 */
- "Reserved", /* 0x19 */
- "Reserved", /* 0x1a */
- "Reserved", /* 0x1b */
- "Reserved", /* 0x1c */
- "Reserved", /* 0x1d */
- "Reserved", /* 0x1e */
- "Unknown" /* 0x1f */
+static char *PeripheralDeviceType[32] =
+{
+ "Disk Drive",
+ "Tape Drive",
+ "Printer",
+ "Processor",
+ "Write-once",
+ "CD-ROM",
+ "Scanner",
+ "Optical",
+ "Medium Changer",
+ "Communications",
+ "ASC IT8",
+ "ASC IT8",
+ "RAID Array",
+ "Enclosure Services",
+ "OCR/W",
+ "Bridging Expander", /* 0x10 */
+ "Reserved", /* 0x11 */
+ "Reserved", /* 0x12 */
+ "Reserved", /* 0x13 */
+ "Reserved", /* 0x14 */
+ "Reserved", /* 0x15 */
+ "Reserved", /* 0x16 */
+ "Reserved", /* 0x17 */
+ "Reserved", /* 0x18 */
+ "Reserved", /* 0x19 */
+ "Reserved", /* 0x1a */
+ "Reserved", /* 0x1b */
+ "Reserved", /* 0x1c */
+ "Reserved", /* 0x1d */
+ "Reserved", /* 0x1e */
+ "Unknown" /* 0x1f */
};
/* okay, now for the structure of an Element Address Assignment Page: */
-typedef struct EAAP {
- unsigned char Page_Code;
- unsigned char Parameter_Length;
- unsigned char MediumTransportElementAddress[2];
- unsigned char NumMediumTransportElements[2];
- unsigned char FirstStorageElementAdddress[2];
- unsigned char NumStorageElements[2];
- unsigned char FirstImportExportElementAddress[2];
- unsigned char NumImportExportElements[2];
- unsigned char FirstDataTransferElementAddress[2];
- unsigned char NumDataTransferElements[2];
- unsigned char Reserved[2];
-} EAAP_Type;
+typedef struct EAAP
+{
+ unsigned char Page_Code;
+ unsigned char Parameter_Length;
+ unsigned char MediumTransportElementAddress[2];
+ unsigned char NumMediumTransportElements[2];
+ unsigned char FirstStorageElementAdddress[2];
+ unsigned char NumStorageElements[2];
+ unsigned char FirstImportExportElementAddress[2];
+ unsigned char NumImportExportElements[2];
+ unsigned char FirstDataTransferElementAddress[2];
+ unsigned char NumDataTransferElements[2];
+ unsigned char Reserved[2];
+} EAAP_Type;
/* okay, now for the structure of a transport geometry
* descriptor page:
*/
-typedef struct TGDP {
- unsigned char Page_Code;
- unsigned char ParameterLength;
- unsigned char Rotate;
- unsigned char ElementNumber; /* we don't care about this... */
-} TGDP_Type;
+typedef struct TGDP
+{
+ unsigned char Page_Code;
+ unsigned char ParameterLength;
+ unsigned char Rotate;
+ unsigned char ElementNumber; /* we don't care about this... */
+} TGDP_Type;
/* Structure of the Device Capabilities Page: */
-typedef struct DCP {
- unsigned char Page_Code;
- unsigned char ParameterLength;
- unsigned char CanStore; /* bits about whether elements can store carts */
- unsigned char Reserved;
- unsigned char MT_Xfer; /* bits about whether mt->xx xfers work. */
- unsigned char ST_Xfer; /* bits about whether st->xx xfers work. */
- unsigned char IE_Xfer; /* bits about whether id->xx xfers work. */
- unsigned char DT_Xfer; /* bits about whether DT->xx xfers work. */
- unsigned char Reserved2[12]; /* more reserved data */
-} DCP_Type ;
+typedef struct DCP
+{
+ unsigned char Page_Code;
+ unsigned char ParameterLength;
+ unsigned char CanStore; /* bits about whether elements can store carts */
+ unsigned char SMC2_Caps;
+ unsigned char MT_Transfer; /* bits about whether mt->xx transfers work. */
+ unsigned char ST_Transfer; /* bits about whether st->xx transfers work. */
+ unsigned char IE_Transfer; /* bits about whether id->xx transfers work. */
+ unsigned char DT_Transfer; /* bits about whether DT->xx transfers work. */
+ unsigned char Reserved[4]; /* more reserved data */
+ unsigned char MT_Exchange; /* bits about whether mt->xx exchanges work. */
+ unsigned char ST_Exchange; /* bits about whether st->xx exchanges work. */
+ unsigned char IE_Exchange; /* bits about whether id->xx exchanges work. */
+ unsigned char DT_Exchange; /* bits about whether DT->xx exchanges work. */
+ unsigned char Reserved2[4]; /* more reserved data */
+} DCP_Type;
#define MT_BIT 0x01
#define ST_BIT 0x02
static void ReportInquiry(DEVICE_TYPE MediumChangerFD)
{
- RequestSense_T RequestSense;
- Inquiry_T *Inquiry;
- int i;
-
- Inquiry = RequestInquiry(MediumChangerFD,&RequestSense);
- if (Inquiry == NULL)
- {
- PrintRequestSense(&RequestSense);
- FatalError("INQUIRY Command Failed\n");
- }
-
- printf("Product Type: %s\n",PeripheralDeviceType[Inquiry->PeripheralDeviceType]);
- printf("Vendor ID: '");
- for (i = 0; i < sizeof(Inquiry->VendorIdentification); i++)
- printf("%c", Inquiry->VendorIdentification[i]);
- printf("'\nProduct ID: '");
- for (i = 0; i < sizeof(Inquiry->ProductIdentification); i++)
- printf("%c", Inquiry->ProductIdentification[i]);
- printf("'\nRevision: '");
- for (i = 0; i < sizeof(Inquiry->ProductRevisionLevel); i++)
- printf("%c", Inquiry->ProductRevisionLevel[i]);
- printf("'\n");\
- if (Inquiry->MChngr) { /* check the attached-media-changer bit... */
- printf("Attached Changer: Yes\n");
- } else {
- printf("Attached Changer: No\n");
- }
- /* Now see if we have a bar code flag: */
- if (Inquiry->AdditionalLength > 50) { /* see if we have 56 bytes: */
- if (Inquiry->VendorFlags & 1) {
- printf("Bar Code Reader: Yes\n");
- } else {
- printf("Bar Code Reader: No\n");
- }
- }
-
- free(Inquiry); /* well, we're about to exit, but ... */
- return; /* done! */
+ RequestSense_T RequestSense;
+ Inquiry_T *Inquiry;
+ int i;
+
+ Inquiry = RequestInquiry(MediumChangerFD,&RequestSense);
+ if (Inquiry == NULL)
+ {
+ PrintRequestSense(&RequestSense);
+ FatalError("INQUIRY Command Failed\n");
+ }
+
+ printf("Product Type: %s\n",PeripheralDeviceType[Inquiry->PeripheralDeviceType]);
+
+ printf("Vendor ID: '");
+ for (i = 0; i < sizeof(Inquiry->VendorIdentification); i++)
+ printf("%c", Inquiry->VendorIdentification[i]);
+
+ printf("'\nProduct ID: '");
+ for (i = 0; i < sizeof(Inquiry->ProductIdentification); i++)
+ printf("%c", Inquiry->ProductIdentification[i]);
+
+ printf("'\nRevision: '");
+ for (i = 0; i < sizeof(Inquiry->ProductRevisionLevel); i++)
+ printf("%c", Inquiry->ProductRevisionLevel[i]);
+
+ printf("'\n");
+
+ if (Inquiry->MChngr)
+ {
+ /* check the attached-media-changer bit... */
+ printf("Attached Changer: Yes\n");
+ }
+ else
+ {
+ printf("Attached Changer: No\n");
+ }
+
+ /* Now see if we have a bar code flag: */
+ if (Inquiry->AdditionalLength > 50)
+ {
+ /* see if we have 56 bytes: */
+ if (Inquiry->VendorFlags & 1)
+ {
+ printf("Bar Code Reader: Yes\n");
+ }
+ else
+ {
+ printf("Bar Code Reader: No\n");
+ }
+ }
+
+ free(Inquiry); /* well, we're about to exit, but ... */
}
/*********** MODE SENSE *******************/
*/
static unsigned char
-*mode_sense(DEVICE_TYPE fd, int pagenum, int alloc_len, RequestSense_T *RequestSense) {
- CDB_T CDB;
- unsigned char *input_buffer; /*the input buffer -- has junk prepended to
- * actual sense page.
- */
- unsigned char *tmp;
- unsigned char *retval; /* the return value. */
- int i,pagelen;
-
- if (alloc_len > 255) {
- FatalError("mode_sense(6) can only read up to 255 characters!\n");
- }
-
- input_buffer=(unsigned char *)xzmalloc(256); /* overdo it, eh? */
-
- /* clear the sense buffer: */
- slow_bzero((char *)RequestSense,sizeof(RequestSense_T));
-
-
- /* returns an array of bytes in the page, or, if not possible, NULL. */
- CDB[0]=0x1a; /* Mode Sense(6) */
- CDB[1]=0;
- CDB[2]=pagenum; /* the page to read. */
- CDB[3]=0;
- CDB[4]=255; /* allocation length. This does max of 256 bytes! */
- CDB[5]=0;
-
- if (SCSI_ExecuteCommand(fd,Input,&CDB,6,
- input_buffer,255,RequestSense) != 0) {
+*mode_sense(DEVICE_TYPE fd, char pagenum, int alloc_len, RequestSense_T *RequestSense)
+{
+ CDB_T CDB;
+ unsigned char *input_buffer; /*the input buffer -- has junk prepended to
+ * actual sense page.
+ */
+ unsigned char *tmp;
+ unsigned char *retval; /* the return value. */
+ int i,pagelen;
+
+ if (alloc_len > 255)
+ {
+ FatalError("mode_sense(6) can only read up to 255 characters!\n");
+ }
+
+ input_buffer = (unsigned char *)xzmalloc(256); /* overdo it, eh? */
+
+ /* clear the sense buffer: */
+ slow_bzero((char *)RequestSense, sizeof(RequestSense_T));
+
+ /* returns an array of bytes in the page, or, if not possible, NULL. */
+ CDB[0] = 0x1a; /* Mode Sense(6) */
+ CDB[1] = 0x08;
+ CDB[2] = pagenum; /* the page to read. */
+ CDB[3] = 0;
+ CDB[4] = 255; /* allocation length. This does max of 256 bytes! */
+ CDB[5] = 0;
+
+ if (SCSI_ExecuteCommand(fd, Input, &CDB, 6,
+ input_buffer, 255, RequestSense) != 0)
+ {
#ifdef DEBUG_MODE_SENSE
- fprintf(stderr,"Could not execute mode sense...\n");
- fflush(stderr);
+ fprintf(stderr,"Could not execute mode sense...\n");
+ fflush(stderr);
#endif
- return NULL; /* sorry, couldn't do it. */
- }
-
- /* First skip past any header.... */
- tmp=input_buffer+4+input_buffer[3];
- /* now find out real length of page... */
- pagelen=tmp[1]+2;
- retval=xmalloc(pagelen);
- /* and copy our data to the new page. */
- for (i=0;i<pagelen;i++) {
- retval[i]=tmp[i];
- }
- /* okay, free our input buffer: */
- free(input_buffer);
- return retval;
+ return NULL; /* sorry, couldn't do it. */
+ }
+
+ /* First skip past any header.... */
+ tmp = input_buffer + 4 + input_buffer[3];
+ /* now find out real length of page... */
+ pagelen=tmp[1] + 2;
+ retval = xmalloc(pagelen);
+ /* and copy our data to the new page. */
+ for (i = 0; i < pagelen; i++)
+ {
+ retval[i] = tmp[i];
+ }
+ /* okay, free our input buffer: */
+ free(input_buffer);
+ return retval;
}
/* Report the Element Address Assignment Page */
-static EAAP_Type *ReportEAAP(DEVICE_TYPE MediumChangerFD) {
- EAAP_Type *EAAP;
- RequestSense_T RequestSense;
-
- EAAP=(EAAP_Type *)mode_sense(MediumChangerFD,0x1d,sizeof(EAAP_Type),&RequestSense);
-
- if (EAAP==NULL) {
- printf("EAAP: No\n");
- return NULL;
- }
-
- /* we did get an EAAP, so do our thing: */
- printf("EAAP: Yes\n");
- printf("Number of Medium Transport Elements: %d\n", ( ((unsigned int)EAAP->NumMediumTransportElements[0]<<8) + (unsigned int)EAAP->NumMediumTransportElements[1]));
- printf("Number of Storage Elements: %d\n", ( ((unsigned int)EAAP->NumStorageElements[0]<<8) + (unsigned int)EAAP->NumStorageElements[1]));
- printf("Number of Import/Export Element Elements: %d\n", ( ((unsigned int)EAAP->NumImportExportElements[0]<<8) + (unsigned int)EAAP->NumImportExportElements[1]));
- printf("Number of Data Transfer Elements: %d\n", ( ((unsigned int)EAAP->NumDataTransferElements[0]<<8) + (unsigned int)EAAP->NumDataTransferElements[1]));
-
- return EAAP;
+static void ReportEAAP(DEVICE_TYPE MediumChangerFD)
+{
+ EAAP_Type *EAAP;
+ RequestSense_T RequestSense;
+
+ EAAP = (EAAP_Type *)mode_sense(MediumChangerFD, 0x1d, sizeof(EAAP_Type), &RequestSense);
+
+ if (EAAP == NULL)
+ {
+ PrintRequestSense(&RequestSense);
+ printf("EAAP: No\n");
+ return;
+ }
+
+ /* we did get an EAAP, so do our thing: */
+ printf("EAAP: Yes\n");
+ printf("Number of Medium Transport Elements: %d\n", ( ((unsigned int)EAAP->NumMediumTransportElements[0]<<8) + (unsigned int)EAAP->NumMediumTransportElements[1]));
+ printf("Number of Storage Elements: %d\n", ( ((unsigned int)EAAP->NumStorageElements[0]<<8) + (unsigned int)EAAP->NumStorageElements[1]));
+ printf("Number of Import/Export Elements: %d\n", ( ((unsigned int)EAAP->NumImportExportElements[0]<<8) + (unsigned int)EAAP->NumImportExportElements[1]));
+ printf("Number of Data Transfer Elements: %d\n", ( ((unsigned int)EAAP->NumDataTransferElements[0]<<8) + (unsigned int)EAAP->NumDataTransferElements[1]));
+
+ free(EAAP);
}
/* See if we can get some invert information: */
-static void Report_TGDP(DEVICE_TYPE MediumChangerFD) {
- TGDP_Type *result;
-
- RequestSense_T RequestSense;
-
- result=(TGDP_Type *)mode_sense(MediumChangerFD,0x1e,255,&RequestSense);
-
- if (!result) {
- printf("Transport Geometry Descriptor Page: No\n");
- return;
- }
-
- printf("Transport Geometry Descriptor Page: Yes\n");
-
- /* Now print out the invert bit: */
- if ( result->Rotate & 1 ) {
- printf("Invertable: Yes\n");
- } else {
- printf("Invertable: No\n");
- }
-
- return; /* done. */
+static void Report_TGDP(DEVICE_TYPE MediumChangerFD)
+{
+ TGDP_Type *result;
+
+ RequestSense_T RequestSense;
+
+ result=(TGDP_Type *)mode_sense(MediumChangerFD,0x1e,255,&RequestSense);
+
+ if (!result)
+ {
+ printf("Transport Geometry Descriptor Page: No\n");
+ return;
+ }
+
+ printf("Transport Geometry Descriptor Page: Yes\n");
+
+ /* Now print out the invert bit: */
+ if ( result->Rotate & 1 )
+ {
+ printf("Invertable: Yes\n");
+ }
+ else
+ {
+ printf("Invertable: No\n");
+ }
+
+ free(result);
}
/* Okay, let's get the Device Capabilities Page. We don't care
* ST->ST).
*/
-static void Report_DCP(DEVICE_TYPE MediumChangerFD) {
- DCP_Type *result;
- RequestSense_T RequestSense;
-
- /* Get the page. */
- result=(DCP_Type *)mode_sense(MediumChangerFD,0x1f,sizeof(DCP_Type),&RequestSense);
- if (!result) {
- printf("Device Configuration Page: No\n");
- return;
- }
-
- printf("Device Configuration Page: Yes\n");
-
- /* okay, now see if we can do xfers: */
- if (result->ST_Xfer & ST_BIT) {
- printf("Can Transfer: Yes\n");
- } else {
- printf("Can Transfer: No\n");
- }
- /* We don't care about anything else at the moment, eventually we
- * do want to add the inport/export stuff here too...
- */
-
- return;
+void TransferExchangeTargets(unsigned char ucValue, char *szPrefix)
+{
+ if (ucValue & DT_BIT)
+ {
+ printf("%sData Transfer", szPrefix);
+ }
+
+ if (ucValue & IE_BIT)
+ {
+ printf("%s%sImport/Export", ucValue > (IE_BIT | (IE_BIT - 1)) ? ", " : "", szPrefix);
+ }
+
+ if (ucValue & ST_BIT)
+ {
+ printf("%s%sStorage", ucValue > (ST_BIT | (ST_BIT - 1)) ? ", " : "", szPrefix);
+ }
+
+ if (ucValue & MT_BIT)
+ {
+ printf("%s%sMedium Transfer", ucValue > (MT_BIT | (MT_BIT - 1)) ? ", " : "", szPrefix);
+ }
}
-void usage(void) {
- FatalError("Usage: loaderinfo -f <generic-device>\n");
+static void Report_DCP(DEVICE_TYPE MediumChangerFD)
+{
+ DCP_Type *result;
+ RequestSense_T RequestSense;
+
+ /* Get the page. */
+ result=(DCP_Type *)mode_sense(MediumChangerFD,0x1f,sizeof(DCP_Type),&RequestSense);
+ if (!result)
+ {
+ printf("Device Configuration Page: No\n");
+ return;
+ }
+
+ printf("Device Configuration Page: Yes\n");
+
+ printf("Storage: ");
+
+ if (result->CanStore & DT_BIT)
+ {
+ printf("Data Transfer");
+ }
+
+ if (result->CanStore & IE_BIT)
+ {
+ printf("%sImport/Export", result->CanStore > (IE_BIT | (IE_BIT - 1)) ? ", " : "");
+ }
+
+ if (result->CanStore & ST_BIT)
+ {
+ printf("%sStorage", result->CanStore > (ST_BIT | (ST_BIT - 1)) ? ", " : "");
+ }
+
+ if (result->CanStore & MT_BIT)
+ {
+ printf("%sMedium Transfer", result->CanStore > (MT_BIT | (MT_BIT - 1)) ? ", " : "");
+ }
+
+ printf("\n");
+
+ printf("SCSI Media Changer (rev 2): ");
+
+ if (result->SMC2_Caps & 0x01)
+ {
+ printf("Yes\n");
+
+ printf("Volume Tag Reader Present: %s\n", result->SMC2_Caps & 0x02 ? "Yes" : "No");
+ printf("Auto-Clean Enabled: %s\n", result->SMC2_Caps & 0x04 ? "Yes" : "No");
+ }
+ else
+ {
+ printf("No\n");
+ }
+
+ printf("Transfer Medium Transport: ");
+ if ((result->MT_Transfer & 0x0F) != 0)
+ {
+ TransferExchangeTargets(result->MT_Transfer, "->");
+ }
+ else
+ {
+ printf("None");
+ }
+
+ printf("\nTransfer Storage: ");
+ if ((result->ST_Transfer & 0x0F) != 0)
+ {
+ TransferExchangeTargets(result->ST_Transfer, "->");
+ }
+ else
+ {
+ printf("None");
+ }
+
+ printf("\nTransfer Import/Export: ");
+ if ((result->IE_Transfer & 0x0F) != 0)
+ {
+ TransferExchangeTargets(result->IE_Transfer, "->");
+ }
+ else
+ {
+ printf("None");
+ }
+
+ printf("\nTransfer Data Transfer: ");
+ if ((result->DT_Transfer & 0x0F) != 0)
+ {
+ TransferExchangeTargets(result->DT_Transfer, "->");
+ }
+ else
+ {
+ printf("None");
+ }
+
+ printf("\nExchange Medium Transport: ");
+ if ((result->MT_Exchange & 0x0F) != 0)
+ {
+ TransferExchangeTargets(result->MT_Exchange, "<>");
+ }
+ else
+ {
+ printf("None");
+ }
+
+ printf("\nExchange Storage: ");
+ if ((result->ST_Exchange & 0x0F) != 0)
+ {
+ TransferExchangeTargets(result->ST_Exchange, "<>");
+ }
+ else
+ {
+ printf("None");
+ }
+
+ printf("\nExchange Import/Export: ");
+ if ((result->IE_Exchange & 0x0F) != 0)
+ {
+ TransferExchangeTargets(result->IE_Exchange, "<>");
+ }
+ else
+ {
+ printf("None");
+ }
+
+ printf("\nExchange Data Transfer: ");
+ if ((result->DT_Exchange & 0x0F) != 0)
+ {
+ TransferExchangeTargets(result->DT_Exchange, "<>");
+ }
+ else
+ {
+ printf("None");
+ }
+
+ printf("\n");
+
+ free(result);
+}
+
+void usage(void)
+{
+ FatalError("Usage: loaderinfo -f <generic-device>\n");
}
/* we only have one argument: "-f <device>". */
-int main(int argc, char **argv) {
- DEVICE_TYPE fd;
- char *filename;
-
- argv0=argv[0];
- if (argc != 3) {
- fprintf(stderr,"argc=%d",argc);
- usage();
- }
-
- if (strcmp(argv[1],"-f")!=0) {
- usage();
- }
- filename=argv[2];
-
- fd=SCSI_OpenDevice(filename);
-
- /* Now to call the various routines: */
- ReportInquiry(fd);
- ReportEAAP(fd);
- Report_TGDP(fd);
- Report_DCP(fd);
- exit(0);
+int main(int argc, char **argv)
+{
+ DEVICE_TYPE fd;
+ char *filename;
+
+ argv0=argv[0];
+ if (argc != 3)
+ {
+ fprintf(stderr,"argc=%d",argc);
+ usage();
+ }
+
+ if (strcmp(argv[1],"-f")!=0)
+ {
+ usage();
+ }
+
+ filename=argv[2];
+
+ fd=SCSI_OpenDevice(filename);
+
+ /* Now to call the various routines: */
+ ReportInquiry(fd);
+ ReportEAAP(fd);
+ Report_TGDP(fd);
+ Report_DCP(fd);
+ exit(0);
}