Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d2dd0b07 authored by Arjan Mels's avatar Arjan Mels Committed by Greg Kroah-Hartman
Browse files

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: default avatarArjan 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: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 2f8c4c54
Loading
Loading
Loading
Loading
+15 −25
Original line number Diff line number Diff line
@@ -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;
	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 (port %d) to %s\n", index,
						dev_name(&urb->dev->dev));
	usbip_uinfo("reset_device %s\n", 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;
}

/*