diff options
| author | Jeff Garzik <jgarzik@pretzel.yyz.us> | 2005-06-26 23:42:30 -0400 |
|---|---|---|
| committer | Jeff Garzik <jgarzik@pobox.com> | 2005-06-26 23:42:30 -0400 |
| commit | f45727d52d1581e9ff4df9d1a12a60789ad2d1eb (patch) | |
| tree | 773ae25f98542e6d382c688f7e85e8137d065614 /drivers/usb/core/usb.c | |
| parent | 4c925f452cfd16c690209e96821ee094e09a2404 (diff) | |
| parent | 5696c1944a33b4434a9a1ebb6383b906afd43a10 (diff) | |
Merge /spare/repo/netdev-2.6/ branch 'ieee80211'
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) |
