diff options
-rw-r--r-- | drivers/usb/core/devices.c | 4 | ||||
-rw-r--r-- | drivers/usb/core/devio.c | 2 | ||||
-rw-r--r-- | drivers/usb/core/driver.c | 4 | ||||
-rw-r--r-- | drivers/usb/core/hcd.c | 5 | ||||
-rw-r--r-- | drivers/usb/core/hub.c | 48 | ||||
-rw-r--r-- | drivers/usb/core/usb.c | 114 | ||||
-rw-r--r-- | drivers/usb/core/usb.h | 3 | ||||
-rw-r--r-- | drivers/usb/host/ohci-hub.c | 2 | ||||
-rw-r--r-- | include/linux/usb.h | 9 |
9 files changed, 37 insertions, 154 deletions
diff --git a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c index 83e815d3cd52..55bc563a3256 100644 --- a/drivers/usb/core/devices.c +++ b/drivers/usb/core/devices.c | |||
@@ -545,10 +545,10 @@ static ssize_t usb_device_dump(char __user **buffer, size_t *nbytes, loff_t *ski | |||
545 | struct usb_device *childdev = usbdev->children[chix]; | 545 | struct usb_device *childdev = usbdev->children[chix]; |
546 | 546 | ||
547 | if (childdev) { | 547 | if (childdev) { |
548 | down(&childdev->serialize); | 548 | usb_lock_device(childdev); |
549 | ret = usb_device_dump(buffer, nbytes, skip_bytes, file_offset, childdev, | 549 | ret = usb_device_dump(buffer, nbytes, skip_bytes, file_offset, childdev, |
550 | bus, level + 1, chix, ++cnt); | 550 | bus, level + 1, chix, ++cnt); |
551 | up(&childdev->serialize); | 551 | usb_unlock_device(childdev); |
552 | if (ret == -EFAULT) | 552 | if (ret == -EFAULT) |
553 | return total_written; | 553 | return total_written; |
554 | total_written += ret; | 554 | total_written += ret; |
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 3a73170e95dd..2b68998fe4b3 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c | |||
@@ -1349,9 +1349,7 @@ static int proc_ioctl(struct dev_state *ps, struct usbdevfs_ioctl *ctl) | |||
1349 | /* let kernel drivers try to (re)bind to the interface */ | 1349 | /* let kernel drivers try to (re)bind to the interface */ |
1350 | case USBDEVFS_CONNECT: | 1350 | case USBDEVFS_CONNECT: |
1351 | usb_unlock_device(ps->dev); | 1351 | usb_unlock_device(ps->dev); |
1352 | usb_lock_all_devices(); | ||
1353 | bus_rescan_devices(intf->dev.bus); | 1352 | bus_rescan_devices(intf->dev.bus); |
1354 | usb_unlock_all_devices(); | ||
1355 | usb_lock_device(ps->dev); | 1353 | usb_lock_device(ps->dev); |
1356 | break; | 1354 | break; |
1357 | 1355 | ||
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index bb139f06bcd6..076462c8ba2a 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c | |||
@@ -432,9 +432,7 @@ int usb_register_driver(struct usb_driver *new_driver, struct module *owner) | |||
432 | spin_lock_init(&new_driver->dynids.lock); | 432 | spin_lock_init(&new_driver->dynids.lock); |
433 | INIT_LIST_HEAD(&new_driver->dynids.list); | 433 | INIT_LIST_HEAD(&new_driver->dynids.list); |
434 | 434 | ||
435 | usb_lock_all_devices(); | ||
436 | retval = driver_register(&new_driver->driver); | 435 | retval = driver_register(&new_driver->driver); |
437 | usb_unlock_all_devices(); | ||
438 | 436 | ||
439 | if (!retval) { | 437 | if (!retval) { |
440 | pr_info("%s: registered new driver %s\n", | 438 | pr_info("%s: registered new driver %s\n", |
@@ -465,11 +463,9 @@ void usb_deregister(struct usb_driver *driver) | |||
465 | { | 463 | { |
466 | pr_info("%s: deregistering driver %s\n", usbcore_name, driver->name); | 464 | pr_info("%s: deregistering driver %s\n", usbcore_name, driver->name); |
467 | 465 | ||
468 | usb_lock_all_devices(); | ||
469 | usb_remove_newid_file(driver); | 466 | usb_remove_newid_file(driver); |
470 | usb_free_dynids(driver); | 467 | usb_free_dynids(driver); |
471 | driver_unregister(&driver->driver); | 468 | driver_unregister(&driver->driver); |
472 | usb_unlock_all_devices(); | ||
473 | 469 | ||
474 | usbfs_update_special(); | 470 | usbfs_update_special(); |
475 | } | 471 | } |
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index da24c31ee00d..d16a0e8a7d72 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c | |||
@@ -857,9 +857,7 @@ static int register_root_hub (struct usb_device *usb_dev, | |||
857 | return (retval < 0) ? retval : -EMSGSIZE; | 857 | return (retval < 0) ? retval : -EMSGSIZE; |
858 | } | 858 | } |
859 | 859 | ||
860 | usb_lock_device (usb_dev); | ||
861 | retval = usb_new_device (usb_dev); | 860 | retval = usb_new_device (usb_dev); |
862 | usb_unlock_device (usb_dev); | ||
863 | if (retval) { | 861 | if (retval) { |
864 | usb_dev->bus->root_hub = NULL; | 862 | usb_dev->bus->root_hub = NULL; |
865 | dev_err (parent_dev, "can't register root hub for %s, %d\n", | 863 | dev_err (parent_dev, "can't register root hub for %s, %d\n", |
@@ -1891,7 +1889,10 @@ void usb_remove_hcd(struct usb_hcd *hcd) | |||
1891 | spin_lock_irq (&hcd_root_hub_lock); | 1889 | spin_lock_irq (&hcd_root_hub_lock); |
1892 | hcd->rh_registered = 0; | 1890 | hcd->rh_registered = 0; |
1893 | spin_unlock_irq (&hcd_root_hub_lock); | 1891 | spin_unlock_irq (&hcd_root_hub_lock); |
1892 | |||
1893 | down(&usb_bus_list_lock); | ||
1894 | usb_disconnect(&hcd->self.root_hub); | 1894 | usb_disconnect(&hcd->self.root_hub); |
1895 | up(&usb_bus_list_lock); | ||
1895 | 1896 | ||
1896 | hcd->poll_rh = 0; | 1897 | hcd->poll_rh = 0; |
1897 | del_timer_sync(&hcd->rh_timer); | 1898 | del_timer_sync(&hcd->rh_timer); |
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 40c6c50c6bd9..dd3bcfb2bcb6 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -32,7 +32,7 @@ | |||
32 | #include "hub.h" | 32 | #include "hub.h" |
33 | 33 | ||
34 | /* Protect struct usb_device->state and ->children members | 34 | /* Protect struct usb_device->state and ->children members |
35 | * Note: Both are also protected by ->serialize, except that ->state can | 35 | * Note: Both are also protected by ->dev.sem, except that ->state can |
36 | * change to USB_STATE_NOTATTACHED even when the semaphore isn't held. */ | 36 | * change to USB_STATE_NOTATTACHED even when the semaphore isn't held. */ |
37 | static DEFINE_SPINLOCK(device_state_lock); | 37 | static DEFINE_SPINLOCK(device_state_lock); |
38 | 38 | ||
@@ -975,8 +975,8 @@ static int locktree(struct usb_device *udev) | |||
975 | /* when everyone grabs locks top->bottom, | 975 | /* when everyone grabs locks top->bottom, |
976 | * non-overlapping work may be concurrent | 976 | * non-overlapping work may be concurrent |
977 | */ | 977 | */ |
978 | down(&udev->serialize); | 978 | usb_lock_device(udev); |
979 | up(&hdev->serialize); | 979 | usb_unlock_device(hdev); |
980 | return t + 1; | 980 | return t + 1; |
981 | } | 981 | } |
982 | } | 982 | } |
@@ -1132,16 +1132,10 @@ void usb_disconnect(struct usb_device **pdev) | |||
1132 | * this quiesces everyting except pending urbs. | 1132 | * this quiesces everyting except pending urbs. |
1133 | */ | 1133 | */ |
1134 | usb_set_device_state(udev, USB_STATE_NOTATTACHED); | 1134 | usb_set_device_state(udev, USB_STATE_NOTATTACHED); |
1135 | |||
1136 | /* lock the bus list on behalf of HCDs unregistering their root hubs */ | ||
1137 | if (!udev->parent) { | ||
1138 | down(&usb_bus_list_lock); | ||
1139 | usb_lock_device(udev); | ||
1140 | } else | ||
1141 | down(&udev->serialize); | ||
1142 | |||
1143 | dev_info (&udev->dev, "USB disconnect, address %d\n", udev->devnum); | 1135 | dev_info (&udev->dev, "USB disconnect, address %d\n", udev->devnum); |
1144 | 1136 | ||
1137 | usb_lock_device(udev); | ||
1138 | |||
1145 | /* Free up all the children before we remove this device */ | 1139 | /* Free up all the children before we remove this device */ |
1146 | for (i = 0; i < USB_MAXCHILDREN; i++) { | 1140 | for (i = 0; i < USB_MAXCHILDREN; i++) { |
1147 | if (udev->children[i]) | 1141 | if (udev->children[i]) |
@@ -1169,11 +1163,7 @@ void usb_disconnect(struct usb_device **pdev) | |||
1169 | *pdev = NULL; | 1163 | *pdev = NULL; |
1170 | spin_unlock_irq(&device_state_lock); | 1164 | spin_unlock_irq(&device_state_lock); |
1171 | 1165 | ||
1172 | if (!udev->parent) { | 1166 | usb_unlock_device(udev); |
1173 | usb_unlock_device(udev); | ||
1174 | up(&usb_bus_list_lock); | ||
1175 | } else | ||
1176 | up(&udev->serialize); | ||
1177 | 1167 | ||
1178 | device_unregister(&udev->dev); | 1168 | device_unregister(&udev->dev); |
1179 | } | 1169 | } |
@@ -1243,8 +1233,8 @@ static inline void show_string(struct usb_device *udev, char *id, char *string) | |||
1243 | * | 1233 | * |
1244 | * This is called with devices which have been enumerated, but not yet | 1234 | * This is called with devices which have been enumerated, but not yet |
1245 | * configured. The device descriptor is available, but not descriptors | 1235 | * configured. The device descriptor is available, but not descriptors |
1246 | * for any device configuration. The caller must have locked udev and | 1236 | * for any device configuration. The caller must have locked either |
1247 | * either the parent hub (if udev is a normal device) or else the | 1237 | * the parent hub (if udev is a normal device) or else the |
1248 | * usb_bus_list_lock (if udev is a root hub). The parent's pointer to | 1238 | * usb_bus_list_lock (if udev is a root hub). The parent's pointer to |
1249 | * udev has already been installed, but udev is not yet visible through | 1239 | * udev has already been installed, but udev is not yet visible through |
1250 | * sysfs or other filesystem code. | 1240 | * sysfs or other filesystem code. |
@@ -1254,8 +1244,7 @@ static inline void show_string(struct usb_device *udev, char *id, char *string) | |||
1254 | * | 1244 | * |
1255 | * This call is synchronous, and may not be used in an interrupt context. | 1245 | * This call is synchronous, and may not be used in an interrupt context. |
1256 | * | 1246 | * |
1257 | * Only the hub driver should ever call this; root hub registration | 1247 | * Only the hub driver or root-hub registrar should ever call this. |
1258 | * uses it indirectly. | ||
1259 | */ | 1248 | */ |
1260 | int usb_new_device(struct usb_device *udev) | 1249 | int usb_new_device(struct usb_device *udev) |
1261 | { | 1250 | { |
@@ -1364,6 +1353,8 @@ int usb_new_device(struct usb_device *udev) | |||
1364 | } | 1353 | } |
1365 | usb_create_sysfs_dev_files (udev); | 1354 | usb_create_sysfs_dev_files (udev); |
1366 | 1355 | ||
1356 | usb_lock_device(udev); | ||
1357 | |||
1367 | /* choose and set the configuration. that registers the interfaces | 1358 | /* choose and set the configuration. that registers the interfaces |
1368 | * with the driver core, and lets usb device drivers bind to them. | 1359 | * with the driver core, and lets usb device drivers bind to them. |
1369 | */ | 1360 | */ |
@@ -1385,6 +1376,8 @@ int usb_new_device(struct usb_device *udev) | |||
1385 | /* USB device state == configured ... usable */ | 1376 | /* USB device state == configured ... usable */ |
1386 | usb_notify_add_device(udev); | 1377 | usb_notify_add_device(udev); |
1387 | 1378 | ||
1379 | usb_unlock_device(udev); | ||
1380 | |||
1388 | return 0; | 1381 | return 0; |
1389 | 1382 | ||
1390 | fail: | 1383 | fail: |
@@ -1872,11 +1865,8 @@ int usb_resume_device(struct usb_device *udev) | |||
1872 | usb_unlock_device(udev); | 1865 | usb_unlock_device(udev); |
1873 | 1866 | ||
1874 | /* rebind drivers that had no suspend() */ | 1867 | /* rebind drivers that had no suspend() */ |
1875 | if (status == 0) { | 1868 | if (status == 0) |
1876 | usb_lock_all_devices(); | ||
1877 | bus_rescan_devices(&usb_bus_type); | 1869 | bus_rescan_devices(&usb_bus_type); |
1878 | usb_unlock_all_devices(); | ||
1879 | } | ||
1880 | return status; | 1870 | return status; |
1881 | } | 1871 | } |
1882 | 1872 | ||
@@ -1889,14 +1879,14 @@ static int remote_wakeup(struct usb_device *udev) | |||
1889 | /* don't repeat RESUME sequence if this device | 1879 | /* don't repeat RESUME sequence if this device |
1890 | * was already woken up by some other task | 1880 | * was already woken up by some other task |
1891 | */ | 1881 | */ |
1892 | down(&udev->serialize); | 1882 | usb_lock_device(udev); |
1893 | if (udev->state == USB_STATE_SUSPENDED) { | 1883 | if (udev->state == USB_STATE_SUSPENDED) { |
1894 | dev_dbg(&udev->dev, "RESUME (wakeup)\n"); | 1884 | dev_dbg(&udev->dev, "RESUME (wakeup)\n"); |
1895 | /* TRSMRCY = 10 msec */ | 1885 | /* TRSMRCY = 10 msec */ |
1896 | msleep(10); | 1886 | msleep(10); |
1897 | status = finish_device_resume(udev); | 1887 | status = finish_device_resume(udev); |
1898 | } | 1888 | } |
1899 | up(&udev->serialize); | 1889 | usb_unlock_device(udev); |
1900 | #endif | 1890 | #endif |
1901 | return status; | 1891 | return status; |
1902 | } | 1892 | } |
@@ -1997,7 +1987,7 @@ static int hub_resume(struct usb_interface *intf) | |||
1997 | 1987 | ||
1998 | if (!udev || status < 0) | 1988 | if (!udev || status < 0) |
1999 | continue; | 1989 | continue; |
2000 | down (&udev->serialize); | 1990 | usb_lock_device(udev); |
2001 | if (portstat & USB_PORT_STAT_SUSPEND) | 1991 | if (portstat & USB_PORT_STAT_SUSPEND) |
2002 | status = hub_port_resume(hub, port1, udev); | 1992 | status = hub_port_resume(hub, port1, udev); |
2003 | else { | 1993 | else { |
@@ -2008,7 +1998,7 @@ static int hub_resume(struct usb_interface *intf) | |||
2008 | hub_port_logical_disconnect(hub, port1); | 1998 | hub_port_logical_disconnect(hub, port1); |
2009 | } | 1999 | } |
2010 | } | 2000 | } |
2011 | up(&udev->serialize); | 2001 | usb_unlock_device(udev); |
2012 | } | 2002 | } |
2013 | } | 2003 | } |
2014 | #endif | 2004 | #endif |
@@ -2573,7 +2563,6 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, | |||
2573 | * udev becomes globally accessible, although presumably | 2563 | * udev becomes globally accessible, although presumably |
2574 | * no one will look at it until hdev is unlocked. | 2564 | * no one will look at it until hdev is unlocked. |
2575 | */ | 2565 | */ |
2576 | down (&udev->serialize); | ||
2577 | status = 0; | 2566 | status = 0; |
2578 | 2567 | ||
2579 | /* We mustn't add new devices if the parent hub has | 2568 | /* We mustn't add new devices if the parent hub has |
@@ -2597,7 +2586,6 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, | |||
2597 | } | 2586 | } |
2598 | } | 2587 | } |
2599 | 2588 | ||
2600 | up (&udev->serialize); | ||
2601 | if (status) | 2589 | if (status) |
2602 | goto loop_disable; | 2590 | goto loop_disable; |
2603 | 2591 | ||
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 294e9f127477..fcfda21be499 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c | |||
@@ -32,7 +32,6 @@ | |||
32 | #include <linux/spinlock.h> | 32 | #include <linux/spinlock.h> |
33 | #include <linux/errno.h> | 33 | #include <linux/errno.h> |
34 | #include <linux/smp_lock.h> | 34 | #include <linux/smp_lock.h> |
35 | #include <linux/rwsem.h> | ||
36 | #include <linux/usb.h> | 35 | #include <linux/usb.h> |
37 | 36 | ||
38 | #include <asm/io.h> | 37 | #include <asm/io.h> |
@@ -49,8 +48,6 @@ const char *usbcore_name = "usbcore"; | |||
49 | static int nousb; /* Disable USB when built into kernel image */ | 48 | static int nousb; /* Disable USB when built into kernel image */ |
50 | /* Not honored on modular build */ | 49 | /* Not honored on modular build */ |
51 | 50 | ||
52 | static DECLARE_RWSEM(usb_all_devices_rwsem); | ||
53 | |||
54 | 51 | ||
55 | /** | 52 | /** |
56 | * usb_ifnum_to_if - get the interface object with a given interface number | 53 | * usb_ifnum_to_if - get the interface object with a given interface number |
@@ -446,8 +443,6 @@ usb_alloc_dev(struct usb_device *parent, struct usb_bus *bus, unsigned port1) | |||
446 | dev->parent = parent; | 443 | dev->parent = parent; |
447 | INIT_LIST_HEAD(&dev->filelist); | 444 | INIT_LIST_HEAD(&dev->filelist); |
448 | 445 | ||
449 | init_MUTEX(&dev->serialize); | ||
450 | |||
451 | return dev; | 446 | return dev; |
452 | } | 447 | } |
453 | 448 | ||
@@ -520,76 +515,21 @@ void usb_put_intf(struct usb_interface *intf) | |||
520 | 515 | ||
521 | /* USB device locking | 516 | /* USB device locking |
522 | * | 517 | * |
523 | * Although locking USB devices should be straightforward, it is | 518 | * USB devices and interfaces are locked using the semaphore in their |
524 | * complicated by the way the driver-model core works. When a new USB | 519 | * embedded struct device. The hub driver guarantees that whenever a |
525 | * driver is registered or unregistered, the core will automatically | 520 | * device is connected or disconnected, drivers are called with the |
526 | * probe or disconnect all matching interfaces on all USB devices while | 521 | * USB device locked as well as their particular interface. |
527 | * holding the USB subsystem writelock. There's no good way for us to | ||
528 | * tell which devices will be used or to lock them beforehand; our only | ||
529 | * option is to effectively lock all the USB devices. | ||
530 | * | ||
531 | * We do that by using a private rw-semaphore, usb_all_devices_rwsem. | ||
532 | * When locking an individual device you must first acquire the rwsem's | ||
533 | * readlock. When a driver is registered or unregistered the writelock | ||
534 | * must be held. These actions are encapsulated in the subroutines | ||
535 | * below, so all a driver needs to do is call usb_lock_device() and | ||
536 | * usb_unlock_device(). | ||
537 | * | 522 | * |
538 | * Complications arise when several devices are to be locked at the same | 523 | * Complications arise when several devices are to be locked at the same |
539 | * time. Only hub-aware drivers that are part of usbcore ever have to | 524 | * time. Only hub-aware drivers that are part of usbcore ever have to |
540 | * do this; nobody else needs to worry about it. The problem is that | 525 | * do this; nobody else needs to worry about it. The rule for locking |
541 | * usb_lock_device() must not be called to lock a second device since it | 526 | * is simple: |
542 | * would acquire the rwsem's readlock reentrantly, leading to deadlock if | ||
543 | * another thread was waiting for the writelock. The solution is simple: | ||
544 | * | ||
545 | * When locking more than one device, call usb_lock_device() | ||
546 | * to lock the first one. Lock the others by calling | ||
547 | * down(&udev->serialize) directly. | ||
548 | * | ||
549 | * When unlocking multiple devices, use up(&udev->serialize) | ||
550 | * to unlock all but the last one. Unlock the last one by | ||
551 | * calling usb_unlock_device(). | ||
552 | * | 527 | * |
553 | * When locking both a device and its parent, always lock the | 528 | * When locking both a device and its parent, always lock the |
554 | * the parent first. | 529 | * the parent first. |
555 | */ | 530 | */ |
556 | 531 | ||
557 | /** | 532 | /** |
558 | * usb_lock_device - acquire the lock for a usb device structure | ||
559 | * @udev: device that's being locked | ||
560 | * | ||
561 | * Use this routine when you don't hold any other device locks; | ||
562 | * to acquire nested inner locks call down(&udev->serialize) directly. | ||
563 | * This is necessary for proper interaction with usb_lock_all_devices(). | ||
564 | */ | ||
565 | void usb_lock_device(struct usb_device *udev) | ||
566 | { | ||
567 | down_read(&usb_all_devices_rwsem); | ||
568 | down(&udev->serialize); | ||
569 | } | ||
570 | |||
571 | /** | ||
572 | * usb_trylock_device - attempt to acquire the lock for a usb device structure | ||
573 | * @udev: device that's being locked | ||
574 | * | ||
575 | * Don't use this routine if you already hold a device lock; | ||
576 | * use down_trylock(&udev->serialize) instead. | ||
577 | * This is necessary for proper interaction with usb_lock_all_devices(). | ||
578 | * | ||
579 | * Returns 1 if successful, 0 if contention. | ||
580 | */ | ||
581 | int usb_trylock_device(struct usb_device *udev) | ||
582 | { | ||
583 | if (!down_read_trylock(&usb_all_devices_rwsem)) | ||
584 | return 0; | ||
585 | if (down_trylock(&udev->serialize)) { | ||
586 | up_read(&usb_all_devices_rwsem); | ||
587 | return 0; | ||
588 | } | ||
589 | return 1; | ||
590 | } | ||
591 | |||
592 | /** | ||
593 | * usb_lock_device_for_reset - cautiously acquire the lock for a | 533 | * usb_lock_device_for_reset - cautiously acquire the lock for a |
594 | * usb device structure | 534 | * usb device structure |
595 | * @udev: device that's being locked | 535 | * @udev: device that's being locked |
@@ -627,7 +567,7 @@ int usb_lock_device_for_reset(struct usb_device *udev, | |||
627 | } | 567 | } |
628 | } | 568 | } |
629 | 569 | ||
630 | while (!usb_trylock_device(udev)) { | 570 | while (usb_trylock_device(udev) != 0) { |
631 | 571 | ||
632 | /* If we can't acquire the lock after waiting one second, | 572 | /* If we can't acquire the lock after waiting one second, |
633 | * we're probably deadlocked */ | 573 | * we're probably deadlocked */ |
@@ -645,39 +585,6 @@ int usb_lock_device_for_reset(struct usb_device *udev, | |||
645 | return 1; | 585 | return 1; |
646 | } | 586 | } |
647 | 587 | ||
648 | /** | ||
649 | * usb_unlock_device - release the lock for a usb device structure | ||
650 | * @udev: device that's being unlocked | ||
651 | * | ||
652 | * Use this routine when releasing the only device lock you hold; | ||
653 | * to release inner nested locks call up(&udev->serialize) directly. | ||
654 | * This is necessary for proper interaction with usb_lock_all_devices(). | ||
655 | */ | ||
656 | void usb_unlock_device(struct usb_device *udev) | ||
657 | { | ||
658 | up(&udev->serialize); | ||
659 | up_read(&usb_all_devices_rwsem); | ||
660 | } | ||
661 | |||
662 | /** | ||
663 | * usb_lock_all_devices - acquire the lock for all usb device structures | ||
664 | * | ||
665 | * This is necessary when registering a new driver or probing a bus, | ||
666 | * since the driver-model core may try to use any usb_device. | ||
667 | */ | ||
668 | void usb_lock_all_devices(void) | ||
669 | { | ||
670 | down_write(&usb_all_devices_rwsem); | ||
671 | } | ||
672 | |||
673 | /** | ||
674 | * usb_unlock_all_devices - release the lock for all usb device structures | ||
675 | */ | ||
676 | void usb_unlock_all_devices(void) | ||
677 | { | ||
678 | up_write(&usb_all_devices_rwsem); | ||
679 | } | ||
680 | |||
681 | 588 | ||
682 | static struct usb_device *match_device(struct usb_device *dev, | 589 | static struct usb_device *match_device(struct usb_device *dev, |
683 | u16 vendor_id, u16 product_id) | 590 | u16 vendor_id, u16 product_id) |
@@ -700,10 +607,10 @@ static struct usb_device *match_device(struct usb_device *dev, | |||
700 | /* look through all of the children of this device */ | 607 | /* look through all of the children of this device */ |
701 | for (child = 0; child < dev->maxchild; ++child) { | 608 | for (child = 0; child < dev->maxchild; ++child) { |
702 | if (dev->children[child]) { | 609 | if (dev->children[child]) { |
703 | down(&dev->children[child]->serialize); | 610 | usb_lock_device(dev->children[child]); |
704 | ret_dev = match_device(dev->children[child], | 611 | ret_dev = match_device(dev->children[child], |
705 | vendor_id, product_id); | 612 | vendor_id, product_id); |
706 | up(&dev->children[child]->serialize); | 613 | usb_unlock_device(dev->children[child]); |
707 | if (ret_dev) | 614 | if (ret_dev) |
708 | goto exit; | 615 | goto exit; |
709 | } | 616 | } |
@@ -1300,10 +1207,7 @@ EXPORT_SYMBOL(usb_put_dev); | |||
1300 | EXPORT_SYMBOL(usb_get_dev); | 1207 | EXPORT_SYMBOL(usb_get_dev); |
1301 | EXPORT_SYMBOL(usb_hub_tt_clear_buffer); | 1208 | EXPORT_SYMBOL(usb_hub_tt_clear_buffer); |
1302 | 1209 | ||
1303 | EXPORT_SYMBOL(usb_lock_device); | ||
1304 | EXPORT_SYMBOL(usb_trylock_device); | ||
1305 | EXPORT_SYMBOL(usb_lock_device_for_reset); | 1210 | EXPORT_SYMBOL(usb_lock_device_for_reset); |
1306 | EXPORT_SYMBOL(usb_unlock_device); | ||
1307 | 1211 | ||
1308 | EXPORT_SYMBOL(usb_driver_claim_interface); | 1212 | EXPORT_SYMBOL(usb_driver_claim_interface); |
1309 | EXPORT_SYMBOL(usb_driver_release_interface); | 1213 | EXPORT_SYMBOL(usb_driver_release_interface); |
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h index 98e85fb4d3b7..4647e1ebc68d 100644 --- a/drivers/usb/core/usb.h +++ b/drivers/usb/core/usb.h | |||
@@ -16,9 +16,6 @@ extern int usb_get_device_descriptor(struct usb_device *dev, | |||
16 | extern char *usb_cache_string(struct usb_device *udev, int index); | 16 | extern char *usb_cache_string(struct usb_device *udev, int index); |
17 | extern int usb_set_configuration(struct usb_device *dev, int configuration); | 17 | extern int usb_set_configuration(struct usb_device *dev, int configuration); |
18 | 18 | ||
19 | extern void usb_lock_all_devices(void); | ||
20 | extern void usb_unlock_all_devices(void); | ||
21 | |||
22 | extern void usb_kick_khubd(struct usb_device *dev); | 19 | extern void usb_kick_khubd(struct usb_device *dev); |
23 | extern void usb_suspend_root_hub(struct usb_device *hdev); | 20 | extern void usb_suspend_root_hub(struct usb_device *hdev); |
24 | extern void usb_resume_root_hub(struct usb_device *dev); | 21 | extern void usb_resume_root_hub(struct usb_device *dev); |
diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c index 72e3b12a1926..4b2226d77b34 100644 --- a/drivers/usb/host/ohci-hub.c +++ b/drivers/usb/host/ohci-hub.c | |||
@@ -372,7 +372,7 @@ done: | |||
372 | & ohci->hc_control) | 372 | & ohci->hc_control) |
373 | == OHCI_USB_OPER | 373 | == OHCI_USB_OPER |
374 | && time_after (jiffies, ohci->next_statechange) | 374 | && time_after (jiffies, ohci->next_statechange) |
375 | && usb_trylock_device (hcd->self.root_hub) | 375 | && usb_trylock_device (hcd->self.root_hub) == 0 |
376 | ) { | 376 | ) { |
377 | ohci_vdbg (ohci, "autosuspend\n"); | 377 | ohci_vdbg (ohci, "autosuspend\n"); |
378 | (void) ohci_bus_suspend (hcd); | 378 | (void) ohci_bus_suspend (hcd); |
diff --git a/include/linux/usb.h b/include/linux/usb.h index 2714814ab66c..46dc0421d19e 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h | |||
@@ -329,8 +329,6 @@ struct usb_device { | |||
329 | struct usb_tt *tt; /* low/full speed dev, highspeed hub */ | 329 | struct usb_tt *tt; /* low/full speed dev, highspeed hub */ |
330 | int ttport; /* device port on that tt hub */ | 330 | int ttport; /* device port on that tt hub */ |
331 | 331 | ||
332 | struct semaphore serialize; | ||
333 | |||
334 | unsigned int toggle[2]; /* one bit for each endpoint | 332 | unsigned int toggle[2]; /* one bit for each endpoint |
335 | * ([0] = IN, [1] = OUT) */ | 333 | * ([0] = IN, [1] = OUT) */ |
336 | 334 | ||
@@ -377,11 +375,12 @@ struct usb_device { | |||
377 | extern struct usb_device *usb_get_dev(struct usb_device *dev); | 375 | extern struct usb_device *usb_get_dev(struct usb_device *dev); |
378 | extern void usb_put_dev(struct usb_device *dev); | 376 | extern void usb_put_dev(struct usb_device *dev); |
379 | 377 | ||
380 | extern void usb_lock_device(struct usb_device *udev); | 378 | /* USB device locking */ |
381 | extern int usb_trylock_device(struct usb_device *udev); | 379 | #define usb_lock_device(udev) down(&(udev)->dev.sem) |
380 | #define usb_unlock_device(udev) up(&(udev)->dev.sem) | ||
381 | #define usb_trylock_device(udev) down_trylock(&(udev)->dev.sem) | ||
382 | extern int usb_lock_device_for_reset(struct usb_device *udev, | 382 | extern int usb_lock_device_for_reset(struct usb_device *udev, |
383 | struct usb_interface *iface); | 383 | struct usb_interface *iface); |
384 | extern void usb_unlock_device(struct usb_device *udev); | ||
385 | 384 | ||
386 | /* USB port reset for device reinitialization */ | 385 | /* USB port reset for device reinitialization */ |
387 | extern int usb_reset_device(struct usb_device *dev); | 386 | extern int usb_reset_device(struct usb_device *dev); |