Skip to content

Commit

Permalink
staging: usbip: bugfixes related to kthread conversion
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
arjanmels authored and gregkh committed Apr 6, 2011
1 parent 2f8c4c5 commit d2dd0b0
Showing 1 changed file with 15 additions and 25 deletions.
40 changes: 15 additions & 25 deletions drivers/staging/usbip/stub_rx.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

/*
Expand Down

0 comments on commit d2dd0b0

Please sign in to comment.