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
pgpZpm2PGfzki.pgp
Description: PGP signature
