This is a note to let you know that I've just added the patch titled

    staging: usbip: bugfixes related to kthread conversion

to my staging git tree which can be found at
    git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging-2.6.git
in the staging-linus branch.

The patch will show up in the next release of the linux-next tree
(usually sometime within the next 24 hours during the week.)

The patch will hopefully also will be merged in Linus's tree for the
next -rc kernel release.

If you have any questions about this process, please let me know.


>From d2dd0b07c3e725d386d20294ec906f7ddef207fa Mon Sep 17 00:00:00 2001
From: Arjan Mels <[email protected]>
Date: Tue, 5 Apr 2011 20:26:11 +0200
Subject: staging: usbip: bugfixes related to kthread conversion

When doing a usb port reset do a queued reset instead to prevent a
deadlock: the reset will cause the driver to unbind, causing the
usb_driver_lock_for_reset to stall.

Signed-off-by: Arjan Mels <[email protected]>
Cc: Takahiro Hirofuchi <[email protected]>
Cc: Max Vozeler <[email protected]>
Cc: Arnd Bergmann <[email protected]>
Cc: stable <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
 drivers/staging/usbip/stub_rx.c |   40 ++++++++++++++------------------------
 1 files changed, 15 insertions(+), 25 deletions(-)

diff --git a/drivers/staging/usbip/stub_rx.c b/drivers/staging/usbip/stub_rx.c
index 6445f12..51fbd09 100644
--- a/drivers/staging/usbip/stub_rx.c
+++ b/drivers/staging/usbip/stub_rx.c
@@ -171,33 +171,23 @@ static int tweak_set_configuration_cmd(struct urb *urb)
 
 static int tweak_reset_device_cmd(struct urb *urb)
 {
-       struct usb_ctrlrequest *req;
-       __u16 value;
-       __u16 index;
-       int ret;
-
-       req = (struct usb_ctrlrequest *) urb->setup_packet;
-       value = le16_to_cpu(req->wValue);
-       index = le16_to_cpu(req->wIndex);
-
-       usbip_uinfo("reset_device (port %d) to %s\n", index,
-                                               dev_name(&urb->dev->dev));
+       struct stub_priv *priv = (struct stub_priv *) urb->context;
+       struct stub_device *sdev = priv->sdev;
 
-       /* all interfaces should be owned by usbip driver, so just reset it.  */
-       ret = usb_lock_device_for_reset(urb->dev, NULL);
-       if (ret < 0) {
-               dev_err(&urb->dev->dev, "lock for reset\n");
-               return ret;
-       }
-
-       /* try to reset the device */
-       ret = usb_reset_device(urb->dev);
-       if (ret < 0)
-               dev_err(&urb->dev->dev, "device reset\n");
+       usbip_uinfo("reset_device %s\n", dev_name(&urb->dev->dev));
 
-       usb_unlock_device(urb->dev);
-
-       return ret;
+       /*
+        * usb_lock_device_for_reset caused a deadlock: it causes the driver
+        * to unbind. In the shutdown the rx thread is signalled to shut down
+        * but this thread is pending in the usb_lock_device_for_reset.
+        *
+        * Instead queue the reset.
+        *
+        * Unfortunatly an existing usbip connection will be dropped due to
+        * driver unbinding.
+        */
+       usb_queue_reset_device(sdev->interface);
+       return 0;
 }
 
 /*
-- 
1.7.4.2


_______________________________________________
stable mailing list
[email protected]
http://linux.kernel.org/mailman/listinfo/stable

Reply via email to