提交 d2dd0b07 编写于 作者: A Arjan Mels 提交者: Greg Kroah-Hartman

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: NArjan Mels <arjan.mels@gmx.net>
Cc: Takahiro Hirofuchi <hirofuchi@users.sourceforge.net>
Cc: Max Vozeler <max@vozeler.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: stable <stable@kernel.org>
Signed-off-by: NGreg Kroah-Hartman <gregkh@suse.de>
上级 2f8c4c54
......@@ -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;
}
/*
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册