aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2009-04-16 15:35:09 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2009-06-16 00:44:41 -0400
commit91f8d063d30358fcb76831c238071f7d4b13c35e (patch)
tree7755a6a19c0cf74709fb8206f052ce8480a0086b
parent895f28badce96cd903026b0076966e3571b6968e (diff)
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>
-rw-r--r--drivers/usb/core/driver.c21
1 files changed, 8 insertions, 13 deletions
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index d0a21a5f8201..c115eed0fdc3 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -385,7 +385,6 @@ void usb_driver_release_interface(struct usb_driver *driver,
385 struct usb_interface *iface) 385 struct usb_interface *iface)
386{ 386{
387 struct device *dev = &iface->dev; 387 struct device *dev = &iface->dev;
388 struct usb_device *udev = interface_to_usbdev(iface);
389 388
390 /* this should never happen, don't release something that's not ours */ 389 /* this should never happen, don't release something that's not ours */
391 if (!dev->driver || dev->driver != &driver->drvwrap.driver) 390 if (!dev->driver || dev->driver != &driver->drvwrap.driver)
@@ -394,23 +393,19 @@ void usb_driver_release_interface(struct usb_driver *driver,
394 /* don't release from within disconnect() */ 393 /* don't release from within disconnect() */
395 if (iface->condition != USB_INTERFACE_BOUND) 394 if (iface->condition != USB_INTERFACE_BOUND)
396 return; 395 return;
396 iface->condition = USB_INTERFACE_UNBINDING;
397 397
398 /* don't release if the interface hasn't been added yet */ 398 /* Release via the driver core only if the interface
399 * has already been registered
400 */
399 if (device_is_registered(dev)) { 401 if (device_is_registered(dev)) {
400 iface->condition = USB_INTERFACE_UNBINDING;
401 device_release_driver(dev); 402 device_release_driver(dev);
402 } else { 403 } else {
403 iface->condition = USB_INTERFACE_UNBOUND; 404 down(&dev->sem);
404 usb_cancel_queued_reset(iface); 405 usb_unbind_interface(dev);
406 dev->driver = NULL;
407 up(&dev->sem);
405 } 408 }
406 dev->driver = NULL;
407 usb_set_intfdata(iface, NULL);
408
409 usb_pm_lock(udev);
410 iface->condition = USB_INTERFACE_UNBOUND;
411 mark_quiesced(iface);
412 iface->needs_remote_wakeup = 0;
413 usb_pm_unlock(udev);
414} 409}
415EXPORT_SYMBOL_GPL(usb_driver_release_interface); 410EXPORT_SYMBOL_GPL(usb_driver_release_interface);
416 411