diff options
author | Felipe Balbi <felipe.balbi@nokia.com> | 2008-09-18 23:00:02 (GMT) |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2008-10-17 21:40:56 (GMT) |
commit | 549c41e0ac0a3eb68cfdaeb43c1a314e2a6c289a (patch) | |
tree | 91260dbbb282993e4f6dec1f17e9d716e778e701 | |
parent | 8296345a35551414b07419f4c9223734c1fc5437 (diff) | |
download | linux-fsl-qoriq-549c41e0ac0a3eb68cfdaeb43c1a314e2a6c289a.tar.xz |
usb: gadget: workaround storage command size issues
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>
-rw-r--r-- | drivers/usb/gadget/file_storage.c | 21 |
1 files changed, 17 insertions, 4 deletions
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index 0c632d2..e0f616f 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c @@ -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; } |