ChangeSet 1.1122.1.1, 2003/04/21 15:53:29-07:00, stern@rowland.harvard.edu

[PATCH] USB: usb storage async unlink error code fix

Guess what I just learned today about status code reporting following an
asynchronous unlink in Linux 2.4?  While the OHCI hcd probably behaves
just fine (I haven't tested it), the UHCI hcd does something _very_
strange.

In the completion handler, the urb->status value is -ECONNRESET, as you
might expect.  But when the completion handler returns, urb->status gets
changed to -ENOENT!  Needless to say, this is rather confusing and it
probably accounts for a good deal of the difficulties we've seen during
the last half-year or so in processing aborted transfers.

The proper way to fix this is to change the UHCI driver.  But it's
complicated and a mess, so instead here's a band-aid for the usb-storage
driver.  Since the driver does not use synchronous unlinks, the patch just
changes status codes from -ENOENT back to -ECONNRESET.  I know this is
racy and not the best thing to do, but at least it may help for the time
being.


Content-Description: Async unlink status code patch for usb-storage


 drivers/usb/storage/transport.c |    4 ++++
 1 files changed, 4 insertions(+)


diff -Nru a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c
--- a/drivers/usb/storage/transport.c	Wed Apr 23 10:50:35 2003
+++ b/drivers/usb/storage/transport.c	Wed Apr 23 10:50:35 2003
@@ -406,6 +406,8 @@
 
 	/* return the actual length of the data transferred if no error*/
 	status = us->current_urb->status;
+	if (status == -ENOENT)
+		status = -ECONNRESET;
 	if (status >= 0)
 		status = us->current_urb->actual_length;
 
@@ -449,6 +451,8 @@
 	up(&(us->current_urb_sem));
 	wait_for_completion(&us->current_done);
 	down(&(us->current_urb_sem));
+	if (us->current_urb->status == -ENOENT)
+		us->current_urb->status = -ECONNRESET;
 
 	/* return the actual length of the data transferred */
 	*act_len = us->current_urb->actual_length;
