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 19:34:39 -0400 |
commit | 8ccef0df54642f0f72f922d8aa57e8b290e31671 (patch) | |
tree | 74562c28bbdfbcb06a2da476230687ce3592a59c /drivers/usb | |
parent | cfa59dab27d1b282886e7772a8f9548236883892 (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.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 ( | |||
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 | ||