summaryrefslogtreecommitdiffstats
path: root/drivers/usb/gadget
diff options
context:
space:
mode:
authorFelipe Balbi <felipe.balbi@nokia.com>2008-09-19 01:00:02 +0200
committerGreg Kroah-Hartman <gregkh@suse.de>2008-10-17 23:40:56 +0200
commit549c41e0ac0a3eb68cfdaeb43c1a314e2a6c289a (patch)
tree91260dbbb282993e4f6dec1f17e9d716e778e701 /drivers/usb/gadget
parentUSB: g_printer: fix handling zero-length packet (diff)
downloadlinux-549c41e0ac0a3eb68cfdaeb43c1a314e2a6c289a.tar.xz
linux-549c41e0ac0a3eb68cfdaeb43c1a314e2a6c289a.zip
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>
Diffstat (limited to 'drivers/usb/gadget')
-rw-r--r--drivers/usb/gadget/file_storage.c21
1 files changed, 17 insertions, 4 deletions
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c
index 0c632d22a631..e0f616f39ba0 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;
}