diff options
author | Alan Stern <stern@rowland.harvard.edu> | 2009-04-16 15:35:09 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-06-16 00:44:41 -0400 |
commit | 91f8d063d30358fcb76831c238071f7d4b13c35e (patch) | |
tree | 7755a6a19c0cf74709fb8206f052ce8480a0086b | |
parent | 895f28badce96cd903026b0076966e3571b6968e (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.c | 21 |
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 | } |
415 | EXPORT_SYMBOL_GPL(usb_driver_release_interface); | 410 | EXPORT_SYMBOL_GPL(usb_driver_release_interface); |
416 | 411 | ||