diff options
author | Alan Stern <stern@rowland.harvard.edu> | 2008-08-05 13:05:17 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-08-05 13:23:19 -0400 |
commit | 580da34847488b404218d1d7f53b156f245f5555 (patch) | |
tree | 7164190a4f25d9b389c6103d41c6bc58b2071648 /drivers/usb | |
parent | ca5de404ff036a29b25e9a83f6919c9f606c5841 (diff) |
Fix USB storage hang on command abort
Okay, I found the cause of the hang. It is a simple bug in the USB
scatter-gather library, caused by changes added in response to the S-G
chaining modification.
This patch (as1125) fixes a bug in the USB scatter-gather library.
Early exit from the S-G initialization loop does not reset the count of
outstanding URBs.
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Cc: Matthew Dharm <mdharm-usb@one-eyed-alien.net>
Cc: David Brownell <david-b@pacbell.net>
Cc: Alan Jenkins <alan-jenkins@tuffmail.co.uk>
Cc: James Bottomley <James.Bottomley@HansenPartnership.com>
Cc: Greg KH <greg@kroah.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/core/message.c | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 2fcc06eb5e60..586d6f1376cf 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c | |||
@@ -389,7 +389,6 @@ int usb_sg_init(struct usb_sg_request *io, struct usb_device *dev, | |||
389 | if (io->entries <= 0) | 389 | if (io->entries <= 0) |
390 | return io->entries; | 390 | return io->entries; |
391 | 391 | ||
392 | io->count = io->entries; | ||
393 | io->urbs = kmalloc(io->entries * sizeof *io->urbs, mem_flags); | 392 | io->urbs = kmalloc(io->entries * sizeof *io->urbs, mem_flags); |
394 | if (!io->urbs) | 393 | if (!io->urbs) |
395 | goto nomem; | 394 | goto nomem; |
@@ -458,6 +457,7 @@ int usb_sg_init(struct usb_sg_request *io, struct usb_device *dev, | |||
458 | io->urbs[--i]->transfer_flags &= ~URB_NO_INTERRUPT; | 457 | io->urbs[--i]->transfer_flags &= ~URB_NO_INTERRUPT; |
459 | 458 | ||
460 | /* transaction state */ | 459 | /* transaction state */ |
460 | io->count = io->entries; | ||
461 | io->status = 0; | 461 | io->status = 0; |
462 | io->bytes = 0; | 462 | io->bytes = 0; |
463 | init_completion(&io->complete); | 463 | init_completion(&io->complete); |