Messages in this thread Patch in this message | | | Date | Wed, 13 Apr 2011 08:50:36 -0700 | From | Greg KH <> | Subject | [12/74] staging: usbip: bugfixes related to kthread conversion |
| |
2.6.32-longterm review patch. If anyone has any objections, please let us know.
------------------
From: Arjan Mels <arjan.mels@gmx.net>
commit d2dd0b07c3e725d386d20294ec906f7ddef207fa upstream.
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 <arjan.mels@gmx.net> Cc: Takahiro Hirofuchi <hirofuchi@users.sourceforge.net> Cc: Max Vozeler <max@vozeler.com> Cc: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
--- drivers/staging/usbip/stub_rx.c | 40 +++++++++++++++------------------------- 1 file changed, 15 insertions(+), 25 deletions(-)
--- a/drivers/staging/usbip/stub_rx.c +++ b/drivers/staging/usbip/stub_rx.c @@ -168,33 +168,23 @@ static int tweak_set_configuration_cmd(s static int tweak_reset_device_cmd(struct urb *urb) { - struct usb_ctrlrequest *req; - __u16 value; - __u16 index; - int ret; + struct stub_priv *priv = (struct stub_priv *) urb->context; + struct stub_device *sdev = priv->sdev; - req = (struct usb_ctrlrequest *) urb->setup_packet; - value = le16_to_cpu(req->wValue); - index = le16_to_cpu(req->wIndex); + usbip_uinfo("reset_device %s\n", dev_name(&urb->dev->dev)); - usbip_uinfo("reset_device (port %d) to %s\n", index, - dev_name(&urb->dev->dev)); - - /* 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"); - - 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; } /*
| |