public inbox for linux-scsi@vger.kernel.org
 help / color / mirror / Atom feed
* [example PATCH - not for applying] exclude certain commands
@ 2003-04-23 22:39 Andries.Brouwer
  2003-04-24  0:10 ` Matthew Dharm
                   ` (4 more replies)
  0 siblings, 5 replies; 48+ messages in thread
From: Andries.Brouwer @ 2003-04-23 22:39 UTC (permalink / raw)
  To: James.Bottomley
  Cc: afafc, alan, greg, linux-scsi, linux-usb-devel, mike, stelian,
	torvalds

Yesterday or so we discussed three people's problems with USB devices.
Today a fourth very similar complaint was reported.

I asked

> Could you try this patch of drivers/scsi/sd.c?
>
> --- sd.c~       Sun Apr 20 12:59:32 2003
> +++ sd.c        Wed Apr 23 21:45:10 2003
> @@ -1079,6 +1079,9 @@
>                   int dbd, int modepage, unsigned char *buffer, int len) {
>         unsigned char cmd[8];
>
> +       if (len < 8)
> +               len = 8;
> +
>         memset((void *) &cmd[0], 0, 8);
>         cmd[0] = MODE_SENSE;
>         cmd[1] = dbd;

and got the reply

#
# Wohoo! Patch worked like a charm. Thanks Andries!
#

So, for the time being I assume we know what is causing
these problems. It would be nice if the other three
(afafc@rnl.ist.utl.pt, mike@hingston.demon.co.uk, stelian@popies.net)
could report on their experiences with the above patch.

The next question is whether this is a bug in these devices
or a bug in the usb-storage code.

As Alan remarked, drivers/usb/storage/protocol.c contains
the fragment

        case MODE_SENSE:
                srb->cmnd[8] = 8;

But that is in usb_stor_ufi_command(), and
usb_stor_transparent_scsi_command() doesn't do this.
Nevertheless, MODE_SENSE has minimum length 4, and
MODE_SENSE_10 has minum length 8 for its reply.
So, possibly the latter routine should do something
similar. For example

--- protocol.c~ Fri Nov 22 22:40:13 2002
+++ protocol.c  Thu Apr 24 00:38:31 2003
@@ -366,6 +366,8 @@
                        srb->cmnd[2] = srb->cmnd[2];
                        srb->cmnd[1] = srb->cmnd[1];
                        srb->cmnd[0] = srb->cmnd[0] | 0x40;
+                       if (srb->cmnd[8] < 8)
+                               srb->cmnd[8] = 8;
                        break;
                } /* switch (srb->cmnd[0]) */
        } /* if (us->flags & US_FL_MODE_XLATE) */

(yes, ugly, no guarantee that the buffer is large enough).

Comments?

Andries

^ permalink raw reply	[flat|nested] 48+ messages in thread
* Re: [example PATCH - not for applying] exclude certain commands
@ 2003-04-24  9:08 Andries.Brouwer
  2003-04-24 18:22 ` Matthew Dharm
  0 siblings, 1 reply; 48+ messages in thread
From: Andries.Brouwer @ 2003-04-24  9:08 UTC (permalink / raw)
  To: Andries.Brouwer, mdharm-scsi
  Cc: James.Bottomley, afafc, alan, greg, linux-scsi, linux-usb-devel,
	mike, stelian, torvalds

    From: Matthew Dharm <mdharm-scsi@one-eyed-alien.net>

    > Comments?

    My only comment is that your sample of failed cases primarily seems to
    address those devices that support some variant of MODE_SENSE -- there are
    lots of devices that don't support it at all, which is why I wanted to
    filter it with the (apparently) now-dead command filter concept.

Well, before we create a new infrastructure it is a good idea
to make sure that it is needed. James mentioned three cases
in Bugzilla and it looks like these are fixed by a small correction
to the MODE_SENSE to MODE_SENSE_10 translation.

You mention lots of devices that don't support MODE_SENSE at all.
Do you have Bugzilla or l-k / l-s / l-u refs?

(Smart Media and similar cards come with a write protect bit.
I would suppose reporting it is supported by most non-broken hardware.
We get it from the header of the MODE_SENSE return value.
So there is some reason to expect that MODE_SENSE[_10] is supported,
at least in the minimum form where no page but only the header
is returned. Closer investigation of other error cases might reveal
more usb-storage flaws.)

Andries

^ permalink raw reply	[flat|nested] 48+ messages in thread
* Re: [example PATCH - not for applying] exclude certain commands
@ 2003-04-24  9:46 Andries.Brouwer
  2003-04-24  9:56 ` Stelian Pop
  2003-04-24 14:05 ` Alan Stern
  0 siblings, 2 replies; 48+ messages in thread
From: Andries.Brouwer @ 2003-04-24  9:46 UTC (permalink / raw)
  To: Andries.Brouwer, stelian
  Cc: James.Bottomley, afafc, alan, greg, linux-scsi, linux-usb-devel,
	mike, torvalds

    From: Stelian Pop <stelian@popies.net>

    [I'm not subscribed to usb-devel so I may have missed some comments 
    on my kernel bugzilla bug report - the one with the 'crusoe'
    laptop traces...]

    >> Could you try this patch of drivers/scsi/sd.c?
    >>
    >> --- sd.c~       Sun Apr 20 12:59:32 2003
    >> +++ sd.c        Wed Apr 23 21:45:10 2003
    >> @@ -1079,6 +1079,9 @@
    >>                   int dbd, int modepage, unsigned char *buffer, int len) {
    >>         unsigned char cmd[8];
    >>
    >> +       if (len < 8)
    >> +               len = 8;
    >> +
    >>         memset((void *) &cmd[0], 0, 8);
    >>         cmd[0] = MODE_SENSE;
    >>         cmd[1] = dbd;

    I confirm that this patch makes both my memory stick reader
    *and* my USB floppy drive work perfectly again.

Very good. That makes three people (and four devices) that are happy.

    > Nevertheless, MODE_SENSE has minimum length 4, and
    > MODE_SENSE_10 has minum length 8 for its reply.
    > So, possibly the latter routine should do something
    > similar. For example
    > 
    > --- protocol.c~ Fri Nov 22 22:40:13 2002
    > +++ protocol.c  Thu Apr 24 00:38:31 2003
    > @@ -366,6 +366,8 @@
    >                         srb->cmnd[2] = srb->cmnd[2];
    >                         srb->cmnd[1] = srb->cmnd[1];
    >                         srb->cmnd[0] = srb->cmnd[0] | 0x40;
    > +                       if (srb->cmnd[8] < 8)
    > +                               srb->cmnd[8] = 8;
    >                         break;
    >                 } /* switch (srb->cmnd[0]) */
    >         } /* if (us->flags & US_FL_MODE_XLATE) */

    This patch (applied without the first one) does not make any
    difference: memory stick initialisation still takes several
    minutes to complete, floppy drive initialisation takes about
    10 minutes before the block layer aborts the requests with
    a read error.

OK. That perhaps means that the mode sense command doesnt
pass through this code, e.g. because US_FL_MODE_XLATE
is not set?

At first sight your reports do not give VendorID, ProductID.
Do these devices occur in the unusual devices list?

Andries


-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf
_______________________________________________
linux-usb-devel@lists.sourceforge.net
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

^ permalink raw reply	[flat|nested] 48+ messages in thread
* Re: [example PATCH - not for applying] exclude certain commands
@ 2003-04-24 15:21 Andries.Brouwer
  2003-04-24 15:56 ` Pete
  2003-04-24 21:33 ` Stelian Pop
  0 siblings, 2 replies; 48+ messages in thread
From: Andries.Brouwer @ 2003-04-24 15:21 UTC (permalink / raw)
  To: James.Bottomley, stern
  Cc: Andries.Brouwer, afafc, greg, linux-scsi, linux-usb-devel, mike,
	pwkpete, stelian

# the better solution might be to enforce a minimum transfer length

> You probably already know this, but I'll point it out anyway.  The 
> protocol.c file contains 4 different translation routines:
>
>        usb_stor_qic157_command(),
>        usb_stor_ATAPI_command(),
>        usb_stor_ufi_command(),
>        usb_stor_transparent_scsi_command().
>
> The third one already contains the 4->8 modification and your patch adds 
> it to the fourth.  But it's still missing from the first two.

Yes indeed. I am not yet so far as James - still want to
understand everything before discussing the correct patch.

My theory was: MODE_SENSE returns 4 bytes minimum, MODE_SENSE_10
returns 8 bytes minimum, devices start returning the header and then
look how much more is desired.

Thus, we should never ask for less than 4 bytes with MODE_SENSE,
and never for less than 8 bytes with MODE_SENSE_10.

Since usb-storage translates MODE_SENSE into MODE_SENSE_10
(and does not necessarily change the requested length)
it may be a good idea [for testing] not to ask for less than 8 bytes.

(On the other hand, there are many examples of devices that react badly
when asked for more than is available, so we should not ask for
8 bytes with untranslated MODE_SENSE.)

So far the theory. I asked people to try adding
	if (len < 8)
		len = 8;
in the scsi code, and everybody reported success.

That is good. But there is one point I do not understand.
Stelian Pop reports on two devices, both US_SC_UFI.
But usb_stor_ufi_command() already contained code to
make the length 8. How can it be that my sd.c change
improved things?

Can it be that earlier tests were for 2.5.67 and later tests
for 2.5.68, and Matt's improvements of the latter over the former
are the real reason of improved behaviour?

Andries

[In other words, afafc@rnl.ist.utl.pt, mike@hingston.demon.co.uk,
pwkpete@yahoo.com, stelian@popies.net: did you compare 2.5.68
without and with this "if (len < 8) len = 8" patch?]


^ permalink raw reply	[flat|nested] 48+ messages in thread
* Re: [example PATCH - not for applying] exclude certain commands
@ 2003-04-24 18:59 Andries.Brouwer
  2003-04-24 19:14 ` Matthew Dharm
  0 siblings, 1 reply; 48+ messages in thread
From: Andries.Brouwer @ 2003-04-24 18:59 UTC (permalink / raw)
  To: Andries.Brouwer, mdharm-scsi
  Cc: James.Bottomley, afafc, alan, greg, linux-scsi, linux-usb-devel,
	mike, stelian, torvalds

    From: Matthew Dharm <mdharm-scsi@one-eyed-alien.net>

    > Well, before we create a new infrastructure it is a good idea
    > to make sure that it is needed. James mentioned three cases
    > in Bugzilla and it looks like these are fixed by a small correction
    > to the MODE_SENSE to MODE_SENSE_10 translation.
    >
    > You mention lots of devices that don't support MODE_SENSE at all.
    > Do you have Bugzilla or l-k / l-s / l-u refs?

    Unfortunately, my data comes from (a) working with this junk for several
    years, and (b) non-public conversations with hardware vendors.

Yes. So what you are saying is that you have no supporting evidence
for the need of a filtering layer.

    Yeah, I know that's a lousy answer.  But try to realize that I've been
    dealing with a long, slow, and painful discovery process of what the
    'popular OS' uses.

Yes, I do not blame you at all. Nevertheless, we must only do
things when we really understand why. If a filter is really
necessary we'll find people with problems that are cured only
that way. Today we do not know any such people, it seems.

Andries

^ permalink raw reply	[flat|nested] 48+ messages in thread
* Re: [example PATCH - not for applying] exclude certain commands
@ 2003-04-25  0:43 Andries.Brouwer
  2003-04-25  2:12 ` Matthew Dharm
  2003-04-25 14:32 ` Alan Stern
  0 siblings, 2 replies; 48+ messages in thread
From: Andries.Brouwer @ 2003-04-25  0:43 UTC (permalink / raw)
  To: Andries.Brouwer, stelian
  Cc: James.Bottomley, afafc, greg, linux-scsi, linux-usb-devel, mike,
	pwkpete, stern

> The sd.c patch *is* needed to make it work.

Thanks for confirming.

Now that we know the facts, it is easy to answer my question

: But usb_stor_ufi_command() already contained code to
: make the length 8. How can it be that my sd.c change
: improved things?

The answer is that the length occurs twice - as part of
the SCSI command, and as bufflen. The usb-storage code
that fudges the command in the hope of producing something
more agreeable to the device forgets to adapt the bufflen.

This ends, I think, the discussion of what went wrong.
We understand perfectly - I hope.

Now about fixing the code. We must do something in usb-storage
or sd.c or both. I would prefer if sr_bufflen denotes the
actually available length, instead of the length that
will be transferred. If it has that meaning, then the
fudger in usb-storage knows for sure that there is space.
And sd_do_mode_sense6 and family can store the right number.

Are there any objections against viewing sr_bufflen
as the amount of actually available buffer space
(and thus potentially different from the transferred amount)?

Andries


-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf
_______________________________________________
linux-usb-devel@lists.sourceforge.net
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

^ permalink raw reply	[flat|nested] 48+ messages in thread
* Re: [example PATCH - not for applying] exclude certain commands
@ 2003-04-26 21:44 Andries.Brouwer
  2003-04-26 22:13 ` Matthew Dharm
  2003-04-26 22:29 ` James Bottomley
  0 siblings, 2 replies; 48+ messages in thread
From: Andries.Brouwer @ 2003-04-26 21:44 UTC (permalink / raw)
  To: mdharm-scsi
  Cc: Andries.Brouwer, James.Bottomley, greg, linux-scsi,
	linux-usb-devel

[[problem solved, we understand the hardware, it seems,
now wish to find an elegant way of doing what is required
(and only what is required) in the scsi and/or usb storage code]]

(1) usb-storage is broken in the sense that it uses sr_bufflen
for the transfer size instead of the buffer length, then fudges
commands to make them transfer a different length, but without
updating sr_bufflen.

(1A)
Of course it is bad when variables have a function that differs
from what is suggested by their name. So, sr_bufflen must be
the length of the buffer and nothing else. If the length of
the transfer is needed, there must be a field sr_xferlen or so.

(1B)
Of course it is bad when usb-storage fudges commands.

(2) Also other parts of the kernel do this translation,
so there is a lot of duplication; see for example
the idescsi_transform code in ide-scsi.c.

Lazy as I am I had hoped that I would find the right setup
in my mailbox. But upon returning I see essentially two replies:

(a) Matt tells about sr_bufflen.
(b) Alan says that changing must be avoided when possible.
Of course I agree. (By the way, he says among other things
"The SCSI midlayer could try multiple forms of MODE_SENSE", but
that happens already.)

So I made a patch, but will only describe it since it is long,
and I am not quite happy yet, as you will see below.

The first part, in drivers/usb/storage/scsiglue.c is very
satisfactory:

-
-#define USB_STOR_SCSI_SENSE_HDRSZ 4
-#define USB_STOR_SCSI_SENSE_10_HDRSZ 8
-
-struct usb_stor_scsi_sense_hdr
-{
-  __u8* dataLength;
-  __u8* mediumType;
...
-       }
-    }
-
-  /* Set value of length passed in */
-  *length_p = length;
-}
-

(496 lines deleted). That is a good start.
If we do not fudge commands in usb-storage, then a lot of fudging code
can go.

The next part, in drivers/usb/storage/protocol.c, is almost
as satisfactory:

...
-       /* determine the correct (or minimum) data length for these commands */
-       switch (srb->cmnd[0]) {
-
-               /* change MODE_SENSE/MODE_SELECT from 6 to 10 byte commands */
-       case MODE_SENSE:
-       case MODE_SELECT:
-               /* save the command so we can tell what it was */
-               old_cmnd = srb->cmnd[0];
...
-               /* change READ_6/WRITE_6 to READ_10/WRITE_10, which
-                * are ATAPI commands */
-       case WRITE_6:
-       case READ_6:
-               srb->cmnd[11] = 0;
-               srb->cmnd[10] = 0;
...

(deleted some 200 lines changing READ_6 into READ_10, etc.)

These lines can be deleted because the SCSI layer does not send
such commands. (What about sg you ask? I don't care. People who
send commands "by hand" are responsible themselves. Moreover, it
is really bad when these handcrafted commands are changed by the
driver - probably they were intended precisely as written.)

Why doesnt SCSI send READ_6/WRITE_6? Because there is a field "ten"
that is initially 1 and says that READ_10 must be used. It will be
cleared only when the device returns ILLEGAL_REQUEST.

I dislike the choice of identifier "ten" - it is difficult to grep for,
and I changed it into use_10_for_rw, with the same function as before.
Added a field use_10_for_ms. Thus, in scsi.h:

+       unsigned use_10_for_rw:1; /* first try 10-byte read / write */
+       unsigned use_10_for_ms:1; /* first try 10-byte mode sense/select */

in the declaration of struct scsi_device.

Now sd_do_mode_sense6() becomes sd_do_mode_sense() and does

+       if (SRpnt->sr_device->use_10_for_ms) {
+               if (len < 8)
+                       len = 8;
+
+               cmd[0] = MODE_SENSE_10;
+               cmd[8] = len;
+       } else {
+               if (len < 4)
+                       len = 4;
+
+               cmd[0] = MODE_SENSE;
+               cmd[4] = len;
+       }

(and its first parameter can go).

All this is nice and well. Remains the question how usb-storage
makes sure that the use_10_for_rw and use_10_for_ms flags are set
for its devices.

Tonight I kludged this by setting this (in protocol.c) at the moment
the first INQUIRY is done. But that is terribly ugly.
Did I overlook some obvious means of communication?

Comments?

Andries

^ permalink raw reply	[flat|nested] 48+ messages in thread
* Re: [example PATCH - not for applying] exclude certain commands
@ 2003-04-27  2:29 Andries.Brouwer
  2003-04-27  4:32 ` James Bottomley
  0 siblings, 1 reply; 48+ messages in thread
From: Andries.Brouwer @ 2003-04-27  2:29 UTC (permalink / raw)
  To: Andries.Brouwer, James.Bottomley
  Cc: greg, linux-scsi, linux-usb-devel, mdharm-scsi

Matt asks:

> Why not just make us_10_for_ms default to 1, just like use_10_for_rw?
> The same logic (fallback if ILLEGAL_REQUEST) could apply to both.

Yes, probably that is OK.
I wanted to rewrite code without changing behaviour, and have no
opinion about how non-USB devices might react to 10-byte MODE_SENSE.


James advises:

# Well, this should be done in the USB storage slave_configure

Ah, of course.
All docs say that this routine should call scsi_adjust_queue_depth.
Is that really true? When reading the docs one gets the impression
that our code is
	if (slave_configure)
		slave_configure();
	else
		scsi_adjust_queue_depth(default);
But I read in scsi_scan.c:
        if(sdev->host->hostt->slave_configure)
                sdev->host->hostt->slave_configure(sdev);

Andries

^ permalink raw reply	[flat|nested] 48+ messages in thread

end of thread, other threads:[~2003-04-28 21:33 UTC | newest]

Thread overview: 48+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-04-23 22:39 [example PATCH - not for applying] exclude certain commands Andries.Brouwer
2003-04-24  0:10 ` Matthew Dharm
2003-04-24  8:05 ` André Cruz
2003-04-24  9:15 ` Stelian Pop
2003-04-24  9:22   ` Stelian Pop
2003-04-24 11:45 ` Mike Bursell
2003-04-24 12:44 ` James Bottomley
  -- strict thread matches above, loose matches on Subject: below --
2003-04-24  9:08 Andries.Brouwer
2003-04-24 18:22 ` Matthew Dharm
2003-04-24  9:46 Andries.Brouwer
2003-04-24  9:56 ` Stelian Pop
2003-04-24 14:05 ` Alan Stern
2003-04-24 14:26   ` James Bottomley
2003-04-24 14:46     ` Alan Stern
2003-04-24 15:26       ` James Bottomley
2003-04-24 15:21 Andries.Brouwer
2003-04-24 15:56 ` Pete
2003-04-24 21:33 ` Stelian Pop
2003-04-24 18:59 Andries.Brouwer
2003-04-24 19:14 ` Matthew Dharm
2003-04-24 20:20   ` James Bottomley
2003-04-24 20:59     ` Matthew Dharm
2003-04-24 21:43       ` Patrick Mansfield
2003-04-25  0:43 Andries.Brouwer
2003-04-25  2:12 ` Matthew Dharm
2003-04-25 14:32 ` Alan Stern
2003-04-25 15:12   ` Oliver Neukum
2003-04-26  0:58     ` Alan Stern
2003-04-26  8:24       ` Oliver Neukum
2003-04-26 15:22         ` Alan Stern
2003-04-26 21:44 Andries.Brouwer
2003-04-26 22:13 ` Matthew Dharm
2003-04-26 22:43   ` James Bottomley
2003-04-27  1:34     ` Matthew Dharm
2003-04-27  2:15       ` James Bottomley
2003-04-27  9:35         ` Matthew Dharm
2003-04-27 15:41           ` James Bottomley
2003-04-27 18:52             ` Kai Makisara
2003-04-27 19:52             ` Matthew Dharm
2003-04-28 19:05               ` Luben Tuikov
2003-04-28 19:12                 ` Luben Tuikov
2003-04-28 20:19                 ` Matthew Dharm
2003-04-28 21:33                   ` Luben Tuikov
2003-04-26 22:29 ` James Bottomley
2003-04-27  0:24   ` Patrick Mansfield
2003-04-27  1:39   ` Matthew Dharm
2003-04-27  2:29 Andries.Brouwer
2003-04-27  4:32 ` James Bottomley

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox