On Thu, 4 Jan 2007, Pete Zaitcev wrote:

> On Thu, 4 Jan 2007 16:13:40 -0800, Matthew Dharm <[EMAIL PROTECTED]> wrote:
> > On Thu, Jan 04, 2007 at 04:01:19PM -0800, Pete Zaitcev wrote:
> 
> > > ffff81003f5575c0 1779789944 S Co:004:00 s 21 00 0000 0000 000c 12 = 
> > > 12200000 24000000 00000000
> > > ffff81003f5575c0 1779792226 C Co:004:00 0 12 >
> > > ffff8100374c2980 1779792240 S Bi:004:01 -115 36 <
> > > ffff8100374c2980 1779795215 C Bi:004:01 0 36 = 00800001 1f000000 414d4920 
> > > 20202020 56697274 75616c20 466c6f70 70792020
> > > ffff81003f5575c0 1779795226 S Ii:004:03 -115 2 <
> > > ffff81003f5575c0 1779821221 C Ii:004:03 0 2 = 0000
> > 
> > What exactly happens?  I would assume that an error response to an INQUIRY
> > for LUN 1 would "Do the Right Thing".
> 
> The exchange quoted above is exactly what happens. For the CBI transport,
> we ignore the LUN in srb->device->lun and simply pass the command on;
> the command has LUN bits set by the SCSI stack as if the command was
> directed at parallel SCSI (is it what they call SPI?).

Yes it is: SCSI Parallel Interface.

>  This is discussed
> in UFI 3.2.2. The above example addresses LUN 1.
> 
> The inquiry data is for something shipped by AMI (a BIOS company: apparently
> they diversified into all kinds of firmware). It claims legacy SCSI
> compliance (not even SCSI II).

The whole issue is complicated and entangled.  For instance, right now we 
have in slave_configure():

        /* 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 = sdev->sdev_target->scsi_level = SCSI_2;

The reasoning in the comment seems no longer to be correct, and it might 
be a very good idea to get rid of this code entirely.

Pete's device is affected, since it has scsi_level equal to 0 (the three
low-order bits in the third byte of the INQUIRY response data).  This
value does indeed mean "legacy SCSI", but usb-storage has transformed it
to SCSI-2.

Now, the SCSI core doesn't fill in the LUN bits in the second byte of a
CDB when scsi_level is 0.  This is a required feature for certain types of
ATA pass-thru commands; they use those bits to mean something else.

We are led to the following reasoning:

        CB and CBI can't pass the LUN value as a control parameter,
        but only as part of the CDB.

        If scsi_level is 0 then the LUN value won't be passed in the CDB.

        Hence any device using CB or CBI with scsi_level == 0 _must_
        be single-LUN.

Pete, I imagine this will solve your problem better than your proposed 
change.

> > > Have anyone ever seen a multi-headed USB floppy?
> > 
> > I've seen floppy/CF and floppy/CD-ROM combinations on multiple LUNs.  I've
> > gotten e-mail from people with multiple-head floppies.  I've never seen
> > one, personally.
> 
> I think floppy/CF probably wasn't a UFI protocol thing... So my patch
> would continue to work. But a multi-head floppy sounds worrying.
> The UFI spec talks about LUNs as if they they ought to be used for
> something. But still, if nobody ever seen such things, I am willing
> to risk it.

The question isn't so much whether these devices are floppies; it's 
whether they are UFI.  I know, only floppy drives are supposed to use UFI 
-- but there might be some that don't, and in any case vendors don't 
always follow the rules.

So how does this patch grab you?

Alan Stern



Index: usb-2.6/drivers/usb/storage/scsiglue.c
===================================================================
--- usb-2.6.orig/drivers/usb/storage/scsiglue.c
+++ usb-2.6/drivers/usb/storage/scsiglue.c
@@ -110,23 +110,6 @@ static int slave_configure(struct scsi_d
         * 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 = sdev->sdev_target->scsi_level = SCSI_2;
-
        /* Many devices have trouble transfering more than 32KB at a time,
         * while others have trouble with more than 64K. At this time we
         * are limiting both to 32K (64 sectores).
@@ -176,7 +159,9 @@ static int slave_configure(struct scsi_d
                 * a Get-Max-LUN request, we won't lose much by setting the
                 * revision level down to 2.  The only devices that would be
                 * affected are those with sparse LUNs. */
-               sdev->scsi_level = sdev->sdev_target->scsi_level = SCSI_2;
+               if (sdev->scsi_level > SCSI_2)
+                       sdev->scsi_level = sdev->sdev_target->scsi_level =
+                                       SCSI_2;
 
                /* USB-IDE bridges tend to report SK = 0x04 (Non-recoverable
                 * Hardware Error) when any low-level error occurs,
@@ -194,6 +179,16 @@ static int slave_configure(struct scsi_d
                sdev->use_10_for_ms = 1;
        }
 
+       /* The CB and CBI transports have no way to pass LUN values
+        * other than the bits in the second byte of a CDB.  But those
+        * bits don't get set to the LUN value if the device reports
+        * scsi_level == 0 (UNKNOWN).  Hence such devices must necessarily
+        * be single-LUN.
+        */
+       if ((us->protocol == US_PR_CB || us->protocol == US_PR_CBI) &&
+                       sdev->scsi_level == SCSI_UNKNOWN)
+               us->max_lun = 0;
+
        /* Some devices choke when they receive a PREVENT-ALLOW MEDIUM
         * REMOVAL command, so suppress those commands. */
        if (us->flags & US_FL_NOT_LOCKABLE)


-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
linux-usb-devel@lists.sourceforge.net
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to