The usb-storage driver 'fixes up' the INQUIRY data returned by a device so
that it reads SCSI rev 2 by intercepting the data in-flight.  This was done
to make various SCSI drivers (sd, sr, etc.) work with the device.

However, this technique also has the unfortunate side-effect that nobody
can see the real rev. -- not even sg users.

This patch changes that.  Now, the SCSI revision is changed in the
slave_configure() function.  Thus, the 'real' data is available to anyone
who wants to issue an INQUIRY directly via any means.

This also simplifies the code somewhat.

Greg, please apply.

Matt

Signed-off-by: Matthew Dharm <[EMAIL PROTECTED]>

===== drivers/usb/storage/isd200.c 1.53 vs edited =====
--- 1.53/drivers/usb/storage/isd200.c   Fri Aug  6 23:07:04 2004
+++ edited/drivers/usb/storage/isd200.c Sun Aug 22 12:17:01 2004
@@ -1052,12 +1052,6 @@
                                /* Standard IDE interface only supports disks */
                                info->InquiryData.DeviceType = DIRECT_ACCESS_DEVICE;
 
-                               /* Fix-up the return data from an INQUIRY command to 
show 
-                                * ANSI SCSI rev 2 so we don't confuse the SCSI layers 
above us
-                                * in Linux.
-                                */
-                               info->InquiryData.Versions = 0x2;
-
                                /* The length must be at least 36 (5 + 31) */
                                info->InquiryData.AdditionalLength = 0x1F;
 
===== drivers/usb/storage/protocol.c 1.25 vs edited =====
--- 1.25/drivers/usb/storage/protocol.c Fri Aug  6 23:07:05 2004
+++ edited/drivers/usb/storage/protocol.c       Sun Aug 22 12:01:29 2004
@@ -58,38 +58,6 @@
  ***********************************************************************/
 
 /*
- * Fix-up the return data from an INQUIRY command to show 
- * ANSI SCSI rev 2 so we don't confuse the SCSI layers above us
- */
-static void fix_inquiry_data(struct scsi_cmnd *srb)
-{
-       unsigned char databuf[3];
-       unsigned int index, offset;
-
-       /* verify that it's an INQUIRY command */
-       if (srb->cmnd[0] != INQUIRY)
-               return;
-
-       index = offset = 0;
-       if (usb_stor_access_xfer_buf(databuf, sizeof(databuf), srb,
-                       &index, &offset, FROM_XFER_BUF) != sizeof(databuf))
-               return;
-
-       if ((databuf[2] & 7) == 2)
-               return;
-
-       US_DEBUGP("Fixing INQUIRY data to show SCSI rev 2 - was %d\n",
-                 databuf[2] & 7);
-
-       /* Change the SCSI revision number */
-       databuf[2] = (databuf[2] & ~7) | 2;
-
-       index = offset = 0;
-       usb_stor_access_xfer_buf(databuf, sizeof(databuf), srb,
-                       &index, &offset, TO_XFER_BUF);
-}
-
-/*
  * Fix-up the return data from a READ CAPACITY command. My Feiya reader
  * returns a value that is 1 too large.
  */
@@ -137,10 +105,6 @@
 
        /* send the command to the transport layer */
        usb_stor_invoke_transport(srb, us);
-       if (srb->result == SAM_STAT_GOOD) {
-               /* fix the INQUIRY data if necessary */
-               fix_inquiry_data(srb);
-       }
 }
 
 void usb_stor_ATAPI_command(struct scsi_cmnd *srb, struct us_data *us)
@@ -160,11 +124,6 @@
 
        /* send the command to the transport layer */
        usb_stor_invoke_transport(srb, us);
-
-       if (srb->result == SAM_STAT_GOOD) {
-               /* fix the INQUIRY data if necessary */
-               fix_inquiry_data(srb);
-       }
 }
 
 
@@ -208,11 +167,6 @@
 
        /* send the command to the transport layer */
        usb_stor_invoke_transport(srb, us);
-
-       if (srb->result == SAM_STAT_GOOD) {
-               /* Fix the data for an INQUIRY, if necessary */
-               fix_inquiry_data(srb);
-       }
 }
 
 void usb_stor_transparent_scsi_command(struct scsi_cmnd *srb,
@@ -222,9 +176,6 @@
        usb_stor_invoke_transport(srb, us);
 
        if (srb->result == SAM_STAT_GOOD) {
-               /* Fix the INQUIRY data if necessary */
-               fix_inquiry_data(srb);
-
                /* Fix the READ CAPACITY result if necessary */
                if (us->flags & US_FL_FIX_CAPACITY)
                        fix_read_capacity(srb);
===== drivers/usb/storage/scsiglue.c 1.86 vs edited =====
--- 1.86/drivers/usb/storage/scsiglue.c Fri Aug  6 23:07:06 2004
+++ edited/drivers/usb/storage/scsiglue.c       Sun Aug 22 12:11:39 2004
@@ -98,6 +98,23 @@
         * the end, scatter-gather buffers follow page boundaries. */
        blk_queue_dma_alignment(sdev->request_queue, (512 - 1));
 
+       /* Set the SCSI level to at least 2.  We'll leave it at 3 if that's
+        * what is originally reported.  We need this to avoid confusing
+        * the SCSI layer with devices that report 0 or 1, but need 10-byte
+        * commands (ala ATAPI devices behind certain bridges, or devices
+        * which simply have broken INQUIRY data).
+        *
+        * NOTE: This means /dev/sg programs (ala cdrecord) will get the
+        * actual information.  This seems to be the preference for
+        * programs like that.
+        *
+        * NOTE: This also means that /proc/scsi/scsi and sysfs may report
+        * the actual value or the modified one, depending on where the
+        * data comes from.
+        */
+       if (sdev->scsi_level < SCSI_2)
+               sdev->scsi_level = SCSI_2;
+
        /* According to the technical support people at Genesys Logic,
         * devices using their chips have problems transferring more than
         * 32 KB at a time.  In practice people have found that 64 KB
-- 
Matthew Dharm                              Home: [EMAIL PROTECTED] 
Maintainer, Linux USB Mass Storage Driver

You were using cheat codes too.  You guys suck.
                                        -- Greg to General Studebaker
User Friendly, 12/16/1997

Attachment: pgpZpm2PGfzki.pgp
Description: PGP signature

Reply via email to