aboutsummaryrefslogtreecommitdiffstats
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 19:34:39 -0400
commit8ccef0df54642f0f72f922d8aa57e8b290e31671 (patch)
tree74562c28bbdfbcb06a2da476230687ce3592a59c /drivers/usb
parentcfa59dab27d1b282886e7772a8f9548236883892 (diff)
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 (
404 404
405 io->urbs [i]->complete = sg_complete; 405 io->urbs [i]->complete = sg_complete;
406 io->urbs [i]->context = io; 406 io->urbs [i]->context = io;
407 io->urbs [i]->status = -EINPROGRESS;
408 io->urbs [i]->actual_length = 0;
409 407
410 /* 408 /*
411 * Some systems need to revert to PIO when DMA is temporarily 409 * Some systems need to revert to PIO when DMA is temporarily
@@ -499,7 +497,8 @@ void usb_sg_wait (struct usb_sg_request *io)
499 497
500 /* queue the urbs. */ 498 /* queue the urbs. */
501 spin_lock_irq (&io->lock); 499 spin_lock_irq (&io->lock);
502 for (i = 0; i < entries && !io->status; i++) { 500 i = 0;
501 while (i < entries && !io->status) {
503 int retval; 502 int retval;
504 503
505 io->urbs [i]->dev = io->dev; 504 io->urbs [i]->dev = io->dev;
@@ -516,7 +515,6 @@ void usb_sg_wait (struct usb_sg_request *io)
516 case -ENOMEM: 515 case -ENOMEM:
517 io->urbs[i]->dev = NULL; 516 io->urbs[i]->dev = NULL;
518 retval = 0; 517 retval = 0;
519 i--;
520 yield (); 518 yield ();
521 break; 519 break;
522 520
@@ -527,6 +525,7 @@ void usb_sg_wait (struct usb_sg_request *io)
527 * URBs are queued at once; N milliseconds? 525 * URBs are queued at once; N milliseconds?
528 */ 526 */
529 case 0: 527 case 0:
528 ++i;
530 cpu_relax (); 529 cpu_relax ();
531 break; 530 break;
532 531