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:
Alan Stern 2009-04-16 15:35:09 -04:00 committed by Greg Kroah-Hartman
parent 895f28badc
commit 91f8d063d3

View File

@ -385,7 +385,6 @@ void usb_driver_release_interface(struct usb_driver *driver,
struct usb_interface *iface)
{
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 */
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() */
if (iface->condition != USB_INTERFACE_BOUND)
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)) {
iface->condition = USB_INTERFACE_UNBINDING;
device_release_driver(dev);
} else {
iface->condition = USB_INTERFACE_UNBOUND;
usb_cancel_queued_reset(iface);
down(&dev->sem);
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);