diff options
Diffstat (limited to 'drivers/usb/core/usb.c')
-rw-r--r-- | drivers/usb/core/usb.c | 53 |
1 files changed, 32 insertions, 21 deletions
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 25cf7e9eccfa..a3c42203213a 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c | |||
@@ -293,7 +293,7 @@ int usb_driver_claim_interface(struct usb_driver *driver, | |||
293 | /* if interface was already added, bind now; else let | 293 | /* if interface was already added, bind now; else let |
294 | * the future device_add() bind it, bypassing probe() | 294 | * the future device_add() bind it, bypassing probe() |
295 | */ | 295 | */ |
296 | if (!list_empty (&dev->bus_list)) | 296 | if (klist_node_attached(&dev->knode_bus)) |
297 | device_bind_driver(dev); | 297 | device_bind_driver(dev); |
298 | 298 | ||
299 | return 0; | 299 | return 0; |
@@ -322,9 +322,15 @@ void usb_driver_release_interface(struct usb_driver *driver, | |||
322 | if (!dev->driver || dev->driver != &driver->driver) | 322 | if (!dev->driver || dev->driver != &driver->driver) |
323 | return; | 323 | return; |
324 | 324 | ||
325 | /* don't disconnect from disconnect(), or before dev_add() */ | 325 | /* don't release from within disconnect() */ |
326 | if (!list_empty (&dev->driver_list) && !list_empty (&dev->bus_list)) | 326 | if (iface->condition != USB_INTERFACE_BOUND) |
327 | return; | ||
328 | |||
329 | /* release only after device_add() */ | ||
330 | if (klist_node_attached(&dev->knode_bus)) { | ||
331 | iface->condition = USB_INTERFACE_UNBINDING; | ||
327 | device_release_driver(dev); | 332 | device_release_driver(dev); |
333 | } | ||
328 | 334 | ||
329 | dev->driver = NULL; | 335 | dev->driver = NULL; |
330 | usb_set_intfdata(iface, NULL); | 336 | usb_set_intfdata(iface, NULL); |
@@ -462,6 +468,25 @@ usb_match_id(struct usb_interface *interface, const struct usb_device_id *id) | |||
462 | return NULL; | 468 | return NULL; |
463 | } | 469 | } |
464 | 470 | ||
471 | |||
472 | static int __find_interface(struct device * dev, void * data) | ||
473 | { | ||
474 | struct usb_interface ** ret = (struct usb_interface **)data; | ||
475 | struct usb_interface * intf = *ret; | ||
476 | int *minor = (int *)data; | ||
477 | |||
478 | /* can't look at usb devices, only interfaces */ | ||
479 | if (dev->driver == &usb_generic_driver) | ||
480 | return 0; | ||
481 | |||
482 | intf = to_usb_interface(dev); | ||
483 | if (intf->minor != -1 && intf->minor == *minor) { | ||
484 | *ret = intf; | ||
485 | return 1; | ||
486 | } | ||
487 | return 0; | ||
488 | } | ||
489 | |||
465 | /** | 490 | /** |
466 | * usb_find_interface - find usb_interface pointer for driver and device | 491 | * usb_find_interface - find usb_interface pointer for driver and device |
467 | * @drv: the driver whose current configuration is considered | 492 | * @drv: the driver whose current configuration is considered |
@@ -473,26 +498,12 @@ usb_match_id(struct usb_interface *interface, const struct usb_device_id *id) | |||
473 | */ | 498 | */ |
474 | struct usb_interface *usb_find_interface(struct usb_driver *drv, int minor) | 499 | struct usb_interface *usb_find_interface(struct usb_driver *drv, int minor) |
475 | { | 500 | { |
476 | struct list_head *entry; | 501 | struct usb_interface *intf = (struct usb_interface *)(long)minor; |
477 | struct device *dev; | 502 | int ret; |
478 | struct usb_interface *intf; | ||
479 | 503 | ||
480 | list_for_each(entry, &drv->driver.devices) { | 504 | ret = driver_for_each_device(&drv->driver, NULL, &intf, __find_interface); |
481 | dev = container_of(entry, struct device, driver_list); | ||
482 | |||
483 | /* can't look at usb devices, only interfaces */ | ||
484 | if (dev->driver == &usb_generic_driver) | ||
485 | continue; | ||
486 | |||
487 | intf = to_usb_interface(dev); | ||
488 | if (intf->minor == -1) | ||
489 | continue; | ||
490 | if (intf->minor == minor) | ||
491 | return intf; | ||
492 | } | ||
493 | 505 | ||
494 | /* no device found that matches */ | 506 | return ret ? intf : NULL; |
495 | return NULL; | ||
496 | } | 507 | } |
497 | 508 | ||
498 | static int usb_device_match (struct device *dev, struct device_driver *drv) | 509 | static int usb_device_match (struct device *dev, struct device_driver *drv) |