USB: consolidate usb_unbind_interface and usb_driver_release_interface
This patch (as1230) consolidates code in usb_unbind_interface() and usb_driver_release_interface(). In fact, it makes release_interface call unbind_interface, thereby removing the need for duplicated code. It works like this: If the interface has already been registered with the driver core when a driver releases it, then the usual driver-core mechanism will call unbind_interface. If it hasn't been unregistered then we will make the call ourselves. As a nice bonus, drivers now don't have to worry about whether their disconnect method will get called when they release an interface -- it always will. Previously it would be called only if the interface was registered. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
895f28badc
commit
91f8d063d3
@@ -385,7 +385,6 @@ void usb_driver_release_interface(struct usb_driver *driver,
|
|||||||
struct usb_interface *iface)
|
struct usb_interface *iface)
|
||||||
{
|
{
|
||||||
struct device *dev = &iface->dev;
|
struct device *dev = &iface->dev;
|
||||||
struct usb_device *udev = interface_to_usbdev(iface);
|
|
||||||
|
|
||||||
/* this should never happen, don't release something that's not ours */
|
/* this should never happen, don't release something that's not ours */
|
||||||
if (!dev->driver || dev->driver != &driver->drvwrap.driver)
|
if (!dev->driver || dev->driver != &driver->drvwrap.driver)
|
||||||
@@ -394,23 +393,19 @@ void usb_driver_release_interface(struct usb_driver *driver,
|
|||||||
/* don't release from within disconnect() */
|
/* don't release from within disconnect() */
|
||||||
if (iface->condition != USB_INTERFACE_BOUND)
|
if (iface->condition != USB_INTERFACE_BOUND)
|
||||||
return;
|
return;
|
||||||
|
iface->condition = USB_INTERFACE_UNBINDING;
|
||||||
|
|
||||||
/* don't release if the interface hasn't been added yet */
|
/* Release via the driver core only if the interface
|
||||||
|
* has already been registered
|
||||||
|
*/
|
||||||
if (device_is_registered(dev)) {
|
if (device_is_registered(dev)) {
|
||||||
iface->condition = USB_INTERFACE_UNBINDING;
|
|
||||||
device_release_driver(dev);
|
device_release_driver(dev);
|
||||||
} else {
|
} else {
|
||||||
iface->condition = USB_INTERFACE_UNBOUND;
|
down(&dev->sem);
|
||||||
usb_cancel_queued_reset(iface);
|
usb_unbind_interface(dev);
|
||||||
|
dev->driver = NULL;
|
||||||
|
up(&dev->sem);
|
||||||
}
|
}
|
||||||
dev->driver = NULL;
|
|
||||||
usb_set_intfdata(iface, NULL);
|
|
||||||
|
|
||||||
usb_pm_lock(udev);
|
|
||||||
iface->condition = USB_INTERFACE_UNBOUND;
|
|
||||||
mark_quiesced(iface);
|
|
||||||
iface->needs_remote_wakeup = 0;
|
|
||||||
usb_pm_unlock(udev);
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(usb_driver_release_interface);
|
EXPORT_SYMBOL_GPL(usb_driver_release_interface);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user