+ usb-fix-a-bug-in-usb_start_wait_urb.patch added to -mm tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The patch titled
     USB: fix a bug in usb_start_wait_urb
has been added to the -mm tree.  Its filename is
     usb-fix-a-bug-in-usb_start_wait_urb.patch

*** Remember to use Documentation/SubmitChecklist when testing your code ***

See http://www.zip.com.au/~akpm/linux/patches/stuff/added-to-mm.txt to find
out what to do about this

------------------------------------------------------
Subject: USB: fix a bug in usb_start_wait_urb
From: Alan Stern <stern@xxxxxxxxxxxxxxxxxxx>

This patch (as941) fixes a bug recently added to the USB synchronous API. 
The status of a completed URB must be preserved separately across a
completion callback.  Also, the actual_length value isn't available until
after the URB has fully completed.

Signed-off-by: Alan Stern <stern@xxxxxxxxxxxxxxxxxxx>
Cc: Greg KH <greg@xxxxxxxxx>
Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx>
---

 drivers/usb/core/message.c |   26 ++++++++++++++++----------
 1 file changed, 16 insertions(+), 10 deletions(-)

diff -puN drivers/usb/core/message.c~usb-fix-a-bug-in-usb_start_wait_urb drivers/usb/core/message.c
--- a/drivers/usb/core/message.c~usb-fix-a-bug-in-usb_start_wait_urb
+++ a/drivers/usb/core/message.c
@@ -18,9 +18,17 @@
 #include "hcd.h"	/* for usbcore internals */
 #include "usb.h"
 
+struct api_context {
+	struct completion	done;
+	int			status;
+};
+
 static void usb_api_blocking_completion(struct urb *urb)
 {
-	complete((struct completion *)urb->context);
+	struct api_context *ctx = urb->context;
+
+	ctx->status = urb->status;
+	complete(&ctx->done);
 }
 
 
@@ -32,20 +40,21 @@ static void usb_api_blocking_completion(
  */
 static int usb_start_wait_urb(struct urb *urb, int timeout, int *actual_length)
 { 
-	struct completion done;
+	struct api_context ctx;
 	unsigned long expire;
 	int retval;
-	int status = urb->status;
 
-	init_completion(&done); 	
-	urb->context = &done;
+	init_completion(&ctx.done);
+	urb->context = &ctx;
 	urb->actual_length = 0;
 	retval = usb_submit_urb(urb, GFP_NOIO);
 	if (unlikely(retval))
 		goto out;
 
 	expire = timeout ? msecs_to_jiffies(timeout) : MAX_SCHEDULE_TIMEOUT;
-	if (!wait_for_completion_timeout(&done, expire)) {
+	if (!wait_for_completion_timeout(&ctx.done, expire)) {
+		usb_kill_urb(urb);
+		retval = (ctx.status == -ENOENT ? -ETIMEDOUT : ctx.status);
 
 		dev_dbg(&urb->dev->dev,
 			"%s timed out on ep%d%s len=%d/%d\n",
@@ -54,11 +63,8 @@ static int usb_start_wait_urb(struct urb
 			usb_pipein(urb->pipe) ? "in" : "out",
 			urb->actual_length,
 			urb->transfer_buffer_length);
-
-		usb_kill_urb(urb);
-		retval = status == -ENOENT ? -ETIMEDOUT : status;
 	} else
-		retval = status;
+		retval = ctx.status;
 out:
 	if (actual_length)
 		*actual_length = urb->actual_length;
_

Patches currently in -mm which might be from stern@xxxxxxxxxxxxxxxxxxx are

nikon-d50-is-an-unusual-device.patch
usb-fix-a-bug-in-usb_start_wait_urb.patch

-
To unsubscribe from this list: send the line "unsubscribe mm-commits" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Kernel Newbies FAQ]     [Kernel Archive]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Photo]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]

  Powered by Linux