summaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2007-06-21 16:26:46 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2007-07-12 16:34:39 -0700
commit8ccef0df54642f0f72f922d8aa57e8b290e31671 (patch)
tree74562c28bbdfbcb06a2da476230687ce3592a59c /drivers/usb
parentcfa59dab27d1b282886e7772a8f9548236883892 (diff)
downloadlinux-8ccef0df54642f0f72f922d8aa57e8b290e31671.tar.gz
linux-8ccef0df54642f0f72f922d8aa57e8b290e31671.tar.bz2
linux-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')
-rw-r--r--drivers/usb/core/message.c7
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;