diff options
author | Alan Stern <stern@rowland.harvard.edu> | 2007-06-21 16:26:46 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2007-07-12 16:34:39 -0700 |
commit | 8ccef0df54642f0f72f922d8aa57e8b290e31671 (patch) | |
tree | 74562c28bbdfbcb06a2da476230687ce3592a59c /drivers/usb/core/message.c | |
parent | cfa59dab27d1b282886e7772a8f9548236883892 (diff) | |
download | linux-stable-8ccef0df54642f0f72f922d8aa57e8b290e31671.tar.gz linux-stable-8ccef0df54642f0f72f922d8aa57e8b290e31671.tar.bz2 linux-stable-8ccef0df54642f0f72f922d8aa57e8b290e31671.zip |
USB: Fix off-by-1 error in the scatter-gather library
The loop in usb_sg_wait() is structured in a way that makes it hard to
tell, when the loop exits, whether or not the last URB submission
succeeded. This patch (as928) changes it from a "for" loop to a
"while" loop and keeps "i" always equal to the number of successful
submissions. This fixes an off-by-one error which can show up when
the first URB submission fails.
The patch also removes a couple of lines that initialize fields which
don't need to be initialized.
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/core/message.c')
-rw-r--r-- | drivers/usb/core/message.c | 7 |
1 files changed, 3 insertions, 4 deletions
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index f9fed34bf7d8..4c1432314711 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -404,8 +404,6 @@ int usb_sg_init ( io->urbs [i]->complete = sg_complete; io->urbs [i]->context = io; - io->urbs [i]->status = -EINPROGRESS; - io->urbs [i]->actual_length = 0; /* * Some systems need to revert to PIO when DMA is temporarily @@ -499,7 +497,8 @@ void usb_sg_wait (struct usb_sg_request *io) /* queue the urbs. */ spin_lock_irq (&io->lock); - for (i = 0; i < entries && !io->status; i++) { + i = 0; + while (i < entries && !io->status) { int retval; io->urbs [i]->dev = io->dev; @@ -516,7 +515,6 @@ void usb_sg_wait (struct usb_sg_request *io) case -ENOMEM: io->urbs[i]->dev = NULL; retval = 0; - i--; yield (); break; @@ -527,6 +525,7 @@ void usb_sg_wait (struct usb_sg_request *io) * URBs are queued at once; N milliseconds? */ case 0: + ++i; cpu_relax (); break; |