On Tue, 21 Jan 2003, Tom Collins wrote:

> When copying large amounts of data to a drive:
> 
> Logs show:
> 
> usb-storage: Command WRITE_10 (10 bytes)
> usb-storage: 2a 00 00 05 eb f0 00 00 40 00 2d 80
> usb-storage: Bulk command S 0x43425355 T 0x174a Trg 0 LUN 0 L 32768 F 0 
> CL 10
> usb-storage: Bulk command transfer result=0
> usb-storage: usb_stor_transfer_partial(): xfer 4096 bytes
> usb-storage: command_abort() called
> usb-storage: usb_stor_bulk_msg() returned -131 xferred 0/4096
> usb-storage: usb_stor_transfer_partial(): unknown error
> usb-storage: Bulk data transfer result 0x2
> usb-storage: Attempting to get CSW...
> 
> and then nothing.
> 
> This is on a system based on the Globespan IVR (MIPS, little-endian).  
> For my tests, I'm copying large amounts of data (up to 1 gigabyte) to 
> an external device formatted vfat.  The copy process gets stuck in 
> state D (uninterruptible sleep) and can't be killed (even with kill -9).
> 
> This has happened with a stock 2.4.19 kernel, and with a version of 
> 2.4.19 that includes the USB drivers from 2.4.21-pre3.  I'm unable to 
> compile and run 2.4.20 and 2.4.21-pre3 on this hardware.  Attempts at 
> using a 2.5 kernel in the past have resulted in utter failure.
> 
> Should usb_stor_transfer_partial know what to do with that result code? 
>   Any ideas why the error handling for unexpected errors isn't able to 
> reset the device?

Wow!  It looks like the error code checking in transport.c is pretty 
messed up.  How did that happen? :-)

Attached are two patches, one for 2.5 and one for 2.4.  Unfortunately, I 
don't have a copy of the full 2.4 tree, so there may be other occurrences 
of wrong error codes that need to be fixed in files other than 
transport.c.  Maybe somebody can check and see.

I don't know that this will fix all the problems observed above, but it's 
a start.

Alan Stern
# This is a BitKeeper generated patch for the following project:
# Project Name: greg k-h's linux 2.5 USB kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
#                  ChangeSet    1.1001  -> 1.1002 
#       drivers/usb/storage/transport.c 1.77    -> 1.78   
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 03/01/22      [EMAIL PROTECTED]   1.1002
# Fix error code checking for asynchronous unlinks
# --------------------------------------------
#
diff -Nru a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c
--- a/drivers/usb/storage/transport.c   Wed Jan 22 11:55:34 2003
+++ b/drivers/usb/storage/transport.c   Wed Jan 22 11:55:34 2003
@@ -314,7 +314,7 @@
                return USB_STOR_XFER_ERROR;
 
        /* the transfer was cancelled, presumably by an abort */
-       case -ENODEV:
+       case -ECONNRESET:
                US_DEBUGP("-- transfer cancelled\n");
                return USB_STOR_XFER_ERROR;
 
--- usb-2.4/drivers/usb/storage/transport.c.orig        Wed Jan 22 11:37:54 2003
+++ usb-2.4/drivers/usb/storage/transport.c     Wed Jan 22 11:41:31 2003
@@ -520,7 +520,7 @@
        }
 
        /* did we abort this command? */
-       if (result == -ENOENT) {
+       if (result == -ECONNRESET) {
                US_DEBUGP("usb_stor_transfer_partial(): transfer aborted\n");
                return US_BULK_TRANSFER_ABORTED;
        }
@@ -820,7 +820,7 @@
        }
 
        /* is the device removed? */
-       if (urb->status == -ENOENT) {
+       if (urb->status == -ENODEV) {
                US_DEBUGP("-- device has been removed\n");
                return;
        }
@@ -876,7 +876,7 @@
        }
 
        /* if the command was aborted, indicate that */
-       if (result == -ENOENT)
+       if (result == -ECONNRESET)
                return USB_STOR_TRANSPORT_ABORTED;
 
        /* STALL must be cleared when it is detected */
@@ -886,7 +886,7 @@
                        usb_sndctrlpipe(us->pusb_dev, 0));
 
                /* if the command was aborted, indicate that */
-               if (result == -ENOENT)
+               if (result == -ECONNRESET)
                        return USB_STOR_TRANSPORT_ABORTED;
                return USB_STOR_TRANSPORT_FAILED;
        }
@@ -989,7 +989,7 @@
        US_DEBUGP("Call to usb_stor_control_msg() returned %d\n", result);
        if (result < 0) {
                /* if the command was aborted, indicate that */
-               if (result == -ENOENT)
+               if (result == -ECONNRESET)
                        return USB_STOR_TRANSPORT_ABORTED;
 
                /* a stall is a fatal condition from the device */
@@ -999,7 +999,7 @@
                                usb_sndctrlpipe(us->pusb_dev, 0));
 
                        /* if the command was aborted, indicate that */
-                       if (result == -ENOENT)
+                       if (result == -ECONNRESET)
                                return USB_STOR_TRANSPORT_ABORTED;
                        return USB_STOR_TRANSPORT_FAILED;
                }
@@ -1129,7 +1129,7 @@
        US_DEBUGP("Bulk command transfer result=%d\n", result);
 
        /* if the command was aborted, indicate that */
-       if (result == -ENOENT) {
+       if (result == -ECONNRESET) {
                ret = USB_STOR_TRANSPORT_ABORTED;
                goto out;
        }
@@ -1140,7 +1140,7 @@
                result = usb_stor_clear_halt(us, pipe);
 
                /* if the command was aborted, indicate that */
-               if (result == -ENOENT) {
+               if (result == -ECONNRESET) {
                        ret = USB_STOR_TRANSPORT_ABORTED;
                        goto out;
                }
@@ -1180,7 +1180,7 @@
                                   &partial);
 
        /* if the command was aborted, indicate that */
-       if (result == -ENOENT) {
+       if (result == -ECONNRESET) {
                ret = USB_STOR_TRANSPORT_ABORTED;
                goto out;
        }
@@ -1191,7 +1191,7 @@
                result = usb_stor_clear_halt(us, pipe);
 
                /* if the command was aborted, indicate that */
-               if (result == -ENOENT) {
+               if (result == -ECONNRESET) {
                        ret = USB_STOR_TRANSPORT_ABORTED;
                        goto out;
                }
@@ -1202,7 +1202,7 @@
                                           US_BULK_CS_WRAP_LEN, &partial);
 
                /* if the command was aborted, indicate that */
-               if (result == -ENOENT) {
+               if (result == -ECONNRESET) {
                        ret = USB_STOR_TRANSPORT_ABORTED;
                        goto out;
                }
@@ -1213,7 +1213,7 @@
                        result = usb_stor_clear_halt(us, pipe);
 
                        /* if the command was aborted, indicate that */
-                       if (result == -ENOENT) {
+                       if (result == -ECONNRESET) {
                                ret = USB_STOR_TRANSPORT_ABORTED;
                        } else {
                                ret = USB_STOR_TRANSPORT_ERROR;

Reply via email to