ChangeSet 1.1557.49.10, 2004/02/17 16:43:54-08:00, [EMAIL PROTECTED]

[PATCH] USB Storage: Handle excess 0-length data packets

This patch is an attempt to cope with Genesys Logic's, shall we say,
creative approach to implementing the USB protocols.  Their high-speed
mass storage devices sometimes add an excess 0-length packet to the end of
a data phase transmission.  Of course we don't read that packet as part of
the data phase; we see it as a 0-length CSW message.  The real CSW follows
immediately after.  (Or sometimes a STALL follows immediately after, with
the real CSW coming after that!)

The patch checks the results of the first attempt to read the CSW.  If it
sees a normal packet (not a STALL) with length 0, it retries the read.
Reports from two users indicate that it improves the performance of their
USB-2 DVD drives.


 drivers/usb/storage/transport.c |   13 ++++++++++++-
 1 files changed, 12 insertions(+), 1 deletion(-)


diff -Nru a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c
--- a/drivers/usb/storage/transport.c   Thu Feb 19 17:22:17 2004
+++ b/drivers/usb/storage/transport.c   Thu Feb 19 17:22:17 2004
@@ -929,6 +929,7 @@
        unsigned int residue;
        int result;
        int fake_sense = 0;
+       unsigned int cswlen;
 
        /* set up the command wrapper */
        bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
@@ -985,7 +986,17 @@
        /* get CSW for device status */
        US_DEBUGP("Attempting to get CSW...\n");
        result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
-                               bcs, US_BULK_CS_WRAP_LEN, NULL);
+                               bcs, US_BULK_CS_WRAP_LEN, &cswlen);
+
+       /* Some broken devices add unnecessary zero-length packets to the
+        * end of their data transfers.  Such packets show up as 0-length
+        * CSWs.  If we encounter such a thing, try to read the CSW again.
+        */
+       if (result == USB_STOR_XFER_SHORT && cswlen == 0) {
+               US_DEBUGP("Received 0-length CSW; retrying...\n");
+               result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
+                               bcs, US_BULK_CS_WRAP_LEN, &cswlen);
+       }
 
        /* did the attempt to read the CSW fail? */
        if (result == USB_STOR_XFER_STALLED) {



-------------------------------------------------------
SF.Net is sponsored by: Speed Start Your Linux Apps Now.
Build and deploy apps & Web services for Linux with
a free DVD software kit from IBM. Click Now!
http://ads.osdn.com/?ad_id56&alloc_id438&op=click
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to