usb: gadget: workaround storage command size issues
authorFelipe Balbi <felipe.balbi@nokia.com>
Thu, 18 Sep 2008 23:00:02 +0000 (02:00 +0300)
committerGreg Kroah-Hartman <gregkh@suse.de>
Fri, 17 Oct 2008 21:40:56 +0000 (14:40 -0700)
Try to workaround issues with bad SCSI implementations
by ignoring the command size error.

Signed-off-by: Felipe Balbi <felipe.balbi@nokia.com>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/usb/gadget/file_storage.c

index 0c632d22a6315a116beb9bb28a06b0d273322478..e0f616f39ba0118fe4391dbfc5a25d0f437f5f18 100644 (file)
@@ -2676,11 +2676,24 @@ static int check_command(struct fsg_dev *fsg, int cmnd_size,
        /* Verify the length of the command itself */
        if (cmnd_size != fsg->cmnd_size) {
 
-               /* Special case workaround: MS-Windows issues REQUEST SENSE
-                * with cbw->Length == 12 (it should be 6). */
-               if (fsg->cmnd[0] == SC_REQUEST_SENSE && fsg->cmnd_size == 12)
+               /* Special case workaround: There are plenty of buggy SCSI
+                * implementations. Many have issues with cbw->Length
+                * field passing a wrong command size. For those cases we
+                * always try to work around the problem by using the length
+                * sent by the host side provided it is at least as large
+                * as the correct command length.
+                * Examples of such cases would be MS-Windows, which issues
+                * REQUEST SENSE with cbw->Length == 12 where it should
+                * be 6, and xbox360 issuing INQUIRY, TEST UNIT READY and
+                * REQUEST SENSE with cbw->Length == 10 where it should
+                * be 6 as well.
+                */
+               if (cmnd_size <= fsg->cmnd_size) {
+                       DBG(fsg, "%s is buggy! Expected length %d "
+                                       "but we got %d\n", name,
+                                       cmnd_size, fsg->cmnd_size);
                        cmnd_size = fsg->cmnd_size;
-               else {
+               else {
                        fsg->phase_error = 1;
                        return -EINVAL;
                }