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: Arjan 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: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
parent
c11c4eebdd
commit
d3ac077880
|
@ -26,6 +26,8 @@
|
||||||
static int stub_probe(struct usb_interface *interface,
|
static int stub_probe(struct usb_interface *interface,
|
||||||
const struct usb_device_id *id);
|
const struct usb_device_id *id);
|
||||||
static void stub_disconnect(struct usb_interface *interface);
|
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.
|
* Define device IDs here if you want to explicitly limit exportable devices.
|
||||||
|
@ -59,6 +61,8 @@ struct usb_driver stub_driver = {
|
||||||
.probe = stub_probe,
|
.probe = stub_probe,
|
||||||
.disconnect = stub_disconnect,
|
.disconnect = stub_disconnect,
|
||||||
.id_table = stub_table,
|
.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);
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -175,16 +175,18 @@ static int tweak_reset_device_cmd(struct urb *urb)
|
||||||
dev_info(&urb->dev->dev, "usb_queue_reset_device\n");
|
dev_info(&urb->dev->dev, "usb_queue_reset_device\n");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* usb_lock_device_for_reset caused a deadlock: it causes the driver
|
* With the implementation of pre_reset and post_reset the driver no
|
||||||
* to unbind. In the shutdown the rx thread is signalled to shut down
|
* longer unbinds. This allows the use of synchronous reset.
|
||||||
* 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);
|
|
||||||
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue