From 8ccef0df54642f0f72f922d8aa57e8b290e31671 Mon Sep 17 00:00:00 2001
From: Alan Stern <stern@rowland.harvard.edu>
Date: Thu, 21 Jun 2007 16:26:46 -0400
Subject: [PATCH] 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>
---
 drivers/usb/core/message.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index f9fed34bf7d..4c143231471 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;
 
-- 
2.41.3