aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/core/driver.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/core/driver.c')
-rw-r--r--drivers/usb/core/driver.c56
1 files changed, 26 insertions, 30 deletions
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index d0a21a5f8201..69e5773abfce 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -154,16 +154,11 @@ static const struct usb_device_id *usb_match_dynamic_id(struct usb_interface *in
154static int usb_probe_device(struct device *dev) 154static int usb_probe_device(struct device *dev)
155{ 155{
156 struct usb_device_driver *udriver = to_usb_device_driver(dev->driver); 156 struct usb_device_driver *udriver = to_usb_device_driver(dev->driver);
157 struct usb_device *udev; 157 struct usb_device *udev = to_usb_device(dev);
158 int error = -ENODEV; 158 int error = -ENODEV;
159 159
160 dev_dbg(dev, "%s\n", __func__); 160 dev_dbg(dev, "%s\n", __func__);
161 161
162 if (!is_usb_device(dev)) /* Sanity check */
163 return error;
164
165 udev = to_usb_device(dev);
166
167 /* TODO: Add real matching code */ 162 /* TODO: Add real matching code */
168 163
169 /* The device should always appear to be in use 164 /* The device should always appear to be in use
@@ -203,18 +198,13 @@ static void usb_cancel_queued_reset(struct usb_interface *iface)
203static int usb_probe_interface(struct device *dev) 198static int usb_probe_interface(struct device *dev)
204{ 199{
205 struct usb_driver *driver = to_usb_driver(dev->driver); 200 struct usb_driver *driver = to_usb_driver(dev->driver);
206 struct usb_interface *intf; 201 struct usb_interface *intf = to_usb_interface(dev);
207 struct usb_device *udev; 202 struct usb_device *udev = interface_to_usbdev(intf);
208 const struct usb_device_id *id; 203 const struct usb_device_id *id;
209 int error = -ENODEV; 204 int error = -ENODEV;
210 205
211 dev_dbg(dev, "%s\n", __func__); 206 dev_dbg(dev, "%s\n", __func__);
212 207
213 if (is_usb_device(dev)) /* Sanity check */
214 return error;
215
216 intf = to_usb_interface(dev);
217 udev = interface_to_usbdev(intf);
218 intf->needs_binding = 0; 208 intf->needs_binding = 0;
219 209
220 if (udev->authorized == 0) { 210 if (udev->authorized == 0) {
@@ -385,7 +375,6 @@ void usb_driver_release_interface(struct usb_driver *driver,
385 struct usb_interface *iface) 375 struct usb_interface *iface)
386{ 376{
387 struct device *dev = &iface->dev; 377 struct device *dev = &iface->dev;
388 struct usb_device *udev = interface_to_usbdev(iface);
389 378
390 /* this should never happen, don't release something that's not ours */ 379 /* this should never happen, don't release something that's not ours */
391 if (!dev->driver || dev->driver != &driver->drvwrap.driver) 380 if (!dev->driver || dev->driver != &driver->drvwrap.driver)
@@ -394,23 +383,19 @@ void usb_driver_release_interface(struct usb_driver *driver,
394 /* don't release from within disconnect() */ 383 /* don't release from within disconnect() */
395 if (iface->condition != USB_INTERFACE_BOUND) 384 if (iface->condition != USB_INTERFACE_BOUND)
396 return; 385 return;
386 iface->condition = USB_INTERFACE_UNBINDING;
397 387
398 /* don't release if the interface hasn't been added yet */ 388 /* Release via the driver core only if the interface
389 * has already been registered
390 */
399 if (device_is_registered(dev)) { 391 if (device_is_registered(dev)) {
400 iface->condition = USB_INTERFACE_UNBINDING;
401 device_release_driver(dev); 392 device_release_driver(dev);
402 } else { 393 } else {
403 iface->condition = USB_INTERFACE_UNBOUND; 394 down(&dev->sem);
404 usb_cancel_queued_reset(iface); 395 usb_unbind_interface(dev);
396 dev->driver = NULL;
397 up(&dev->sem);
405 } 398 }
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} 399}
415EXPORT_SYMBOL_GPL(usb_driver_release_interface); 400EXPORT_SYMBOL_GPL(usb_driver_release_interface);
416 401
@@ -598,7 +583,7 @@ static int usb_device_match(struct device *dev, struct device_driver *drv)
598 /* TODO: Add real matching code */ 583 /* TODO: Add real matching code */
599 return 1; 584 return 1;
600 585
601 } else { 586 } else if (is_usb_interface(dev)) {
602 struct usb_interface *intf; 587 struct usb_interface *intf;
603 struct usb_driver *usb_drv; 588 struct usb_driver *usb_drv;
604 const struct usb_device_id *id; 589 const struct usb_device_id *id;
@@ -630,11 +615,14 @@ static int usb_uevent(struct device *dev, struct kobj_uevent_env *env)
630 /* driver is often null here; dev_dbg() would oops */ 615 /* driver is often null here; dev_dbg() would oops */
631 pr_debug("usb %s: uevent\n", dev_name(dev)); 616 pr_debug("usb %s: uevent\n", dev_name(dev));
632 617
633 if (is_usb_device(dev)) 618 if (is_usb_device(dev)) {
634 usb_dev = to_usb_device(dev); 619 usb_dev = to_usb_device(dev);
635 else { 620 } else if (is_usb_interface(dev)) {
636 struct usb_interface *intf = to_usb_interface(dev); 621 struct usb_interface *intf = to_usb_interface(dev);
622
637 usb_dev = interface_to_usbdev(intf); 623 usb_dev = interface_to_usbdev(intf);
624 } else {
625 return 0;
638 } 626 }
639 627
640 if (usb_dev->devnum < 0) { 628 if (usb_dev->devnum < 0) {
@@ -1762,6 +1750,7 @@ int usb_suspend(struct device *dev, pm_message_t msg)
1762int usb_resume(struct device *dev, pm_message_t msg) 1750int usb_resume(struct device *dev, pm_message_t msg)
1763{ 1751{
1764 struct usb_device *udev; 1752 struct usb_device *udev;
1753 int status;
1765 1754
1766 udev = to_usb_device(dev); 1755 udev = to_usb_device(dev);
1767 1756
@@ -1771,7 +1760,14 @@ int usb_resume(struct device *dev, pm_message_t msg)
1771 */ 1760 */
1772 if (udev->skip_sys_resume) 1761 if (udev->skip_sys_resume)
1773 return 0; 1762 return 0;
1774 return usb_external_resume_device(udev, msg); 1763 status = usb_external_resume_device(udev, msg);
1764
1765 /* Avoid PM error messages for devices disconnected while suspended
1766 * as we'll display regular disconnect messages just a bit later.
1767 */
1768 if (status == -ENODEV)
1769 return 0;
1770 return status;
1775} 1771}
1776 1772
1777#endif /* CONFIG_PM */ 1773#endif /* CONFIG_PM */