Improve SCSI device type decoding
Subsystems (4)
PATCH 1/2 Improve SCSI device type decoding
Change API from the scsi_device_types array to the scsi_device_type function. Gets rid of a lot of common code, as well as being easier to use. Also add the new device types in SPC4 r05a.
Index: ./drivers/block/cciss_scsi.c
===================================================================
RCS file: /var/cvs/linux-2.6/drivers/block/cciss_scsi.c,v retrieving revision 1.16
drivers/block/cciss_scsi.c +5 -9
@@ -251,10 +251,6 @@ scsi_cmd_stack_free(int ctlr) stk->pool =NULL ; } -/* scsi_device_types comes from scsi.h */ -#define DEVICETYPE (n) (n<0 || n>MAX_SCSI_DEVICE_CODE) ? \ - "Unknown" : scsi_device_types[n] -#if 0 static int xmargin=8 ;static int amargin=60 ;
@@ -389,7 +385,7 @@ cciss_scsi_add_entry(int ctlr, int hostntime anyway (the scsi layer's inquiries will show that info) */ if (hostno !=-1 )printk ("cciss%d: %s device c%db%dt%dl%d added.\n" , - ctlr,DEVICETYPE (sd->devtype), hostno, + ctlr,scsi_device_type (sd->devtype), hostno, sd->bus, sd->target, sd->lun);return 0 ; }
@@ -407,7 +403,7 @@ cciss_scsi_remove_entry(int ctlr, int ho ccissscsi[ctlr].dev[i] = ccissscsi[ctlr].dev[i+1 ]; ccissscsi[ctlr].ndevices--;printk ("cciss%d: %s device c%db%dt%dl%d removed.\n" , - ctlr,DEVICETYPE (sd.devtype), hostno, + ctlr,scsi_device_type (sd.devtype), hostno, sd.bus, sd.target, sd.lun); }
@@ -458,7 +454,7 @@ adjust_cciss_scsi_table(int ctlr, int hoif (found ==0 ) {/* device no longer present. */ changes++;/* printk("cciss%d: %s device c%db%dt%dl%d removed.\n", -ctlr, DEVICETYPE(csd->devtype), hostno, +ctlr, scsi_device_type(csd->devtype), hostno, csd->bus, csd->target, csd->lun); */ cciss_scsi_remove_entry (ctlr, hostno, i);/* note, i not incremented */
@@ -468,7 +464,7 @@ adjust_cciss_scsi_table(int ctlr, int hoprintk ("cciss%d: device c%db%dt%dl%d type changed " "(device type now %s).\n" , ctlr, hostno, csd->bus, csd->target, csd->lun, -DEVICETYPE (csd->devtype)); +scsi_device_type (csd->devtype)); csd->devtype = sd[j].devtype; i++;/* so just move along. */ }else /* device is same as it ever was, */
@@ -1098,7 +1094,7 @@ cciss_update_non_disk_devices(int cntl_nif (ncurrent >=CCISS_MAX_SCSI_DEVS_PER_HBA ) {printk (KERN_INFO "cciss%d: %s ignored, " "too many devices.\n" , cntl_num, -DEVICETYPE (devtype)); +scsi_device_type (devtype));break ; } memcpy(¤tsd[ncurrent].scsi3addr[0],
Index: ./drivers/scsi/fcal.c
===================================================================
RCS file: /var/cvs/linux-2.6/drivers/scsi/fcal.c,v retrieving revision 1.8
drivers/scsi/fcal.c +1 -2
@@ -249,8 +249,7 @@ int fcal_proc_info (struct Scsi_Host *hoif (scd->id == target) {SPRINTF (" [AL-PA: %02x, Id: %02d, Port WWN: %08x%08x, Node WWN: %08x%08x] " , alpa, target, u1[0 ], u1[1 ], u2[0 ], u2[1 ]); -SPRINTF ("%s " , (scd->type <MAX_SCSI_DEVICE_CODE ) ? - scsi_device_types[(short ) scd->type] :"Unknown device" ); +SPRINTF ("%s " ,scsi_device_type (scd->type));for (j =0 ; (j <8 ) && (scd->vendor[j] >=0x20 ); j++)SPRINTF ("%c" , scd->vendor[j]);
Index: ./drivers/scsi/g_NCR5380.c
===================================================================
RCS file: /var/cvs/linux-2.6/drivers/scsi/g_NCR5380.c,v retrieving revision 1.14
drivers/scsi/g_NCR5380.c +1 -2
@@ -813,7 +813,6 @@ static int generic_NCR5380_proc_info(strstruct NCR5380_hostdata *hostdata;#ifdef NCR5380_STATS struct scsi_device *dev; -extern const char *const scsi_device_types[MAX_SCSI_DEVICE_CODE ];#endif NCR5380_setup (scsi_ptr);
@@ -853,7 +852,7 @@ static int generic_NCR5380_proc_info(strlong tr = hostdata->time_read[dev->id] /HZ ;long tw = hostdata->time_write[dev->id] /HZ ; - PRINTP(" T:%d %s " ANDP dev->id ANDP(dev->type < MAX_SCSI_DEVICE_CODE) ? scsi_device_types[(int) dev->type] : "Unknown"); + PRINTP(" T:%d %s " ANDP dev->id ANDP scsi_device_type(dev->type));for (i =0 ; i <8 ; i++)if (dev->vendor[i] >=0x20 ) *(buffer + (len++)) = dev->vendor[i];
Index: ./drivers/scsi/megaraid.c
===================================================================
RCS file: /var/cvs/linux-2.6/drivers/scsi/megaraid.c,v retrieving revision 1.26
drivers/scsi/megaraid.c +1 -3
@@ -2822,9 +2822,7 @@ mega_print_inquiry(char *page, char *scs i = scsi_inq[0 ] &0x1f ; - len +=sprintf (page+len," Type: %s " , - i <MAX_SCSI_DEVICE_CODE ? scsi_device_types[i] : -"Unknown " ); + len +=sprintf (page+len," Type: %s " ,scsi_device_type (i)); len +=sprintf (page+len," ANSI SCSI revision: %02x" , scsi_inq[2 ] &0x07 );
Index: ./drivers/scsi/scsi.c
===================================================================
RCS file: /var/cvs/linux-2.6/drivers/scsi/scsi.c,v retrieving revision 1.34
drivers/scsi/scsi.c +18 -4
@@ -97,7 +97,7 @@ unsigned int scsi_logging_level;EXPORT_SYMBOL (scsi_logging_level);#endif -const char *const scsi_device_types[MAX_SCSI_DEVICE_CODE ] = { +static const char *const scsi_device_types[] = {"Direct-Access " ,"Sequential-Access" ,"Printer " ,
@@ -108,13 +108,27 @@ const char *const scsi_device_types[MAX_"Optical Device " ,"Medium Changer " ,"Communications " , -"Unknown " , -"Unknown " , +"ASC IT8 " , +"ASC IT8 " ,"RAID " ,"Enclosure " ,"Direct-Access-RBC" , +"Optical Card " , +"Bridge Controller" , +"Object Storage " , + "Automation/Drive ", }; -EXPORT_SYMBOL (scsi_device_types); + +const char *scsi_device_type (unsigned type) +{ +if (type ==0x1e ) +return "Well-known LUN " ; +if (type >ARRAY_SIZE (scsi_device_types)) +return "Unknown " ; +return scsi_device_types[type]; +} + +EXPORT_SYMBOL (scsi_device_type);/* * Function: scsi_allocate_request
Index: ./drivers/scsi/scsi_proc.c
===================================================================
RCS file: /var/cvs/linux-2.6/drivers/scsi/scsi_proc.c,v retrieving revision 1.9
drivers/scsi/scsi_proc.c +1 -3
@@ -178,9 +178,7 @@ static int proc_print_scsidevice(structseq_printf (s,"\n" ); -seq_printf (s," Type: %s " , - sdev->type <MAX_SCSI_DEVICE_CODE ? - scsi_device_types[(int ) sdev->type] :"Unknown " ); +seq_printf (s," Type: %s " ,scsi_device_type (sdev->type));seq_printf (s," ANSI" " SCSI revision: %02x" , (sdev->scsi_level -1 ) ? sdev->scsi_level -1 :1 );
Index: ./drivers/scsi/scsi_scan.c
===================================================================
RCS file: /var/cvs/linux-2.6/drivers/scsi/scsi_scan.c,v retrieving revision 1.41
drivers/scsi/scsi_scan.c +1 -4
@@ -226,10 +226,7 @@ static void print_inquiry(unsigned char i = inq_result[0 ] &0x1f ; -printk (KERN_NOTICE " Type: %s " , - i < -MAX_SCSI_DEVICE_CODE ? scsi_device_types[i] : -"Unknown " ); +printk (KERN_NOTICE " Type: %s " ,scsi_device_type (i));printk (" ANSI SCSI revision: %02x" , inq_result[2 ] &0x07 );if ((inq_result[2 ] &0x07 ) ==1 && (inq_result[3 ] &0x0f ) ==1 )
Index: ./include/scsi/scsi.h
===================================================================
RCS file: /var/cvs/linux-2.6/include/scsi/scsi.h,v retrieving revision 1.19
include/scsi/scsi.h +3 -7
@@ -25,13 +25,6 @@ extern const unsigned char scsi_command_#define COMMAND_SIZE (opcode) scsi_command_size[((opcode) >> 5) & 7]/* -* SCSI device types -*/ - -#define MAX_SCSI_DEVICE_CODE 15 -extern const char *const scsi_device_types[MAX_SCSI_DEVICE_CODE ]; - -/* * Special value for scanning to specify scanning or rescanning of all * possible channels, (target) ids, or luns on a given shost. */
@@ -224,6 +217,9 @@ static inline int scsi_status_is_good(in#define TYPE_ENCLOSURE 0x0d/* Enclosure Services Device */ #define TYPE_RBC 0x0e#define TYPE_NO_LUN 0x7f + +/* Returns a human-readable name for the device */ +extern const char *scsi_device_type (unsigned type);/* * standard mode-select header prepended to all mode-select commands
PATCH 2/2 Print SCSI Inquiry data more compactly
print_inquiry is rather verbose, both in implementation and in output. This patch reduces the output from two lines to one and reduces the implementation to a single printk.
Sample output:
Vendor: HP 18.2G Model: ATLAS10K3_18_SCA Rev: HP05
Type: Direct-Access ANSI SCSI revision: 02
becomes:
scsi 2:0:1:0: Direct-Access HP 18.2G ATLAS10K3_18_SCA HP05 ANSI ver: 02
Index: drivers/scsi/scsi_scan.c
===================================================================
RCS file: /var/cvs/linux-2.6/drivers/scsi/scsi_scan.c,v retrieving revision 1.41
drivers/scsi/scsi_scan.c +7 -54
@@ -186,56 +186,6 @@ static void scsi_unlock_floptical(struct }/** -* print_inquiry - printk the inquiry information -* @inq_result: printk this SCSI INQUIRY -* -* Description: -* printk the vendor, model, and other information found in the -* INQUIRY data in @inq_result. -* -* Notes: -* Remove this, and replace with a hotplug event that logs any -* relevant information. -**/ -static void print_inquiry (unsigned char *inq_result) -{ -int i; - -printk (KERN_NOTICE " Vendor: " ); -for (i =8 ; i <16 ; i++) -if (inq_result[i] >=0x20 && i < inq_result[4 ] +5 ) -printk ("%c" , inq_result[i]); -else -printk (" " ); - -printk (" Model: " ); -for (i =16 ; i <32 ; i++) -if (inq_result[i] >=0x20 && i < inq_result[4 ] +5 ) -printk ("%c" , inq_result[i]); -else -printk (" " ); - -printk (" Rev: " ); -for (i =32 ; i <36 ; i++) -if (inq_result[i] >=0x20 && i < inq_result[4 ] +5 ) -printk ("%c" , inq_result[i]); -else -printk (" " ); - -printk ("\n" ); - - i = inq_result[0 ] &0x1f ; - -printk (KERN_NOTICE " Type: %s " ,scsi_device_type (i)); -printk (" ANSI SCSI revision: %02x" , - inq_result[2 ] &0x07 ); -if ((inq_result[2 ] &0x07 ) ==1 && (inq_result[3 ] &0x0f ) ==1 ) -printk (" CCS\n" ); -else -printk ("\n" ); -} - -/** * scsi_alloc_sdev - allocate and setup a scsi_Device * * Description:
@@ -703,9 +653,8 @@ static int scsi_add_lun(struct scsi_deviif (*bflags &BLIST_ISROM ) {/* * It would be better to modify sdev->type, and set -* sdev->removable, but then the print_inquiry() output -* would not show TYPE_ROM; if print_inquiry() is removed -* the issue goes away. +* sdev->removable; this can now be done since +* print_inquiry has gone away. */ inq_result[0 ] =TYPE_ROM ; inq_result[1 ] |=0x80 ;/* removable */
@@ -734,7 +683,11 @@ static int scsi_add_lun(struct scsi_deviprintk (KERN_INFO "scsi: unknown device type %d\n" , sdev->type); } -print_inquiry (inq_result); +sdev_printk (KERN_NOTICE "scsi" , sdev,"%s %.8s %.16s %.4s " +"ANSI ver: %02x%s\n" ,scsi_device_type (sdev->type), + sdev->vendor, sdev->model, + sdev->rev, inq_result[2 ] &0x07 , + (inq_result[3 ] &0x0f ) ==1 ?" CCS" :"" );/* * For a peripheral qualifier (PQ) value of 1 (001b), the SCSI
Quoted 3 lines · Matthew Wilcox
Change API from the
scsi_device_typesarray to thescsi_device_typefunction. Gets rid of a lot of common code, as well as being easier to use. Also add the new device types in SPC4 r05a.
Not forgetting peripheral device types 1eh and 1fh which are well known logical unit and unknown or no device type respectively.
Reference: the bottom of table 84 in spc4r05a.pdf .
Well known logical units are out there, linux just doesn't look for them (see the "select report" field in REPORT LUNS command).
I have been told of special devices yielding pdf 1fh.
BTW I have tried to add these in the past but my patch wasn't accepted.
Doug Gilbert
Quoted 3 lines · Douglas Gilbert
Not forgetting peripheral device types 1eh and 1fh which are well known logical unit and unknown or no device type respectively.
I don't think you read the whole patch ;-)
+ if (type == 0x1e)
+ return "Well-known LUN ";
+ if (type > ARRAY_SIZE(scsi_device_types))
+ return "Unknown ";
Did you want to distinguish between a device of type unknown and a device type Linux doesn't know about?
Quoted 8 lines · Matthew Wilcox
Quoted 3 lines · Douglas Gilbert
Not forgetting peripheral device types 1eh and 1fh which are well known logical unit and unknown or no device type respectively.
I don't think you read the whole patch ;-)
Obviously not closely enough.
Quoted 7 lines
drivers/scsi/scsi.c +4
-0+if (type ==0x1e ) +return "Well-known LUN " ; +if (type >ARRAY_SIZE (scsi_device_types)) +return "Unknown " ;Did you want to distinguish between a device of type unknown and a device type Linux doesn't know about?
If a device server yields a peripheral qualifier of 3 in a INQUIRY response (e.g. for the "lun 0" trick when there are lun_s>0) then the associated pdt should be set to 1fh. The unallocated pdt_s are marked as "reserved" in the draft.
It is also possible that a drive with removable media may not want to commit to a pdt before it sees media. So I would prefer to see the distinction.
Doug Gilbert