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

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

staging: usbip: bugfix prevent driver unbind



Implemented pre_reset and post_reset methods of the driver to prevent the
driver from being unbound upon a device reset. Because of this also the
asynchronous reset introduced to prevent a race condition is no longer necessary
(and sometimes causes problems, because it comes later then expected).

Signed-off-by: default avatarArjan Mels <arjan.mels@gmx.net>
Cc: Greg Kroah-Hartman <gregkh@suse.de>
Cc: Takahiro Hirofuchi <hirofuchi@users.sourceforge.net>
Cc: Max Vozeler <max@vozeler.com>
Cc: usbip-devel <usbip-devel@lists.sourceforge.net>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent c11c4eeb
Loading
Loading
Loading
Loading
+21 −0
Original line number Diff line number Diff line
@@ -26,6 +26,8 @@
static int stub_probe(struct usb_interface *interface,
		      const struct usb_device_id *id);
static void stub_disconnect(struct usb_interface *interface);
static int stub_pre_reset(struct usb_interface *interface);
static int stub_post_reset(struct usb_interface *interface);

/*
 * Define device IDs here if you want to explicitly limit exportable devices.
@@ -59,6 +61,8 @@ struct usb_driver stub_driver = {
	.probe		= stub_probe,
	.disconnect	= stub_disconnect,
	.id_table	= stub_table,
	.pre_reset	= stub_pre_reset,
	.post_reset	= stub_post_reset,
};

/*
@@ -541,3 +545,20 @@ static void stub_disconnect(struct usb_interface *interface)
		del_match_busid((char *)udev_busid);
	}
}

/* 
 * Presence of pre_reset and post_reset prevents the driver from being unbound
 * when the device is being reset
 */
 
int stub_pre_reset(struct usb_interface *interface)
{
	dev_dbg(&interface->dev, "pre_reset\n");
	return 0;
}

int stub_post_reset(struct usb_interface *interface)
{
	dev_dbg(&interface->dev, "post_reset\n");
	return 0;
}
+11 −9
Original line number Diff line number Diff line
@@ -175,16 +175,18 @@ static int tweak_reset_device_cmd(struct urb *urb)
	dev_info(&urb->dev->dev, "usb_queue_reset_device\n");

	/*
	 * 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.
	 * With the implementation of pre_reset and post_reset the driver no 
	 * longer unbinds. This allows the use of synchronous reset.
	 */
	usb_queue_reset_device(sdev->interface);

	if (usb_lock_device_for_reset(sdev->udev, sdev->interface)<0)
	{
		dev_err(&urb->dev->dev, "could not obtain lock to reset device\n");
		return 0;
	}
	usb_reset_device(sdev->udev);
	usb_unlock_device(sdev->udev);

	return 0;
}