@@ -592,7 +592,7 @@ static ssize_t usb_device_read(struct file *file, char __user *buf,
struct usb_bus *bus;
ssize_t ret, total_written = 0;
loff_t skip_bytes = *ppos;
- int id;
+ unsigned long id;
if (*ppos < 0)
return -EINVAL;
@@ -601,9 +601,8 @@ static ssize_t usb_device_read(struct file *file, char __user *buf,
if (!access_ok(buf, nbytes))
return -EFAULT;
- mutex_lock(&usb_bus_idr_lock);
/* print devices for all busses */
- idr_for_each_entry(&usb_bus_idr, bus, id) {
+ xa_for_each(&usb_busses, id, bus) {
/* recurse through all children of the root hub */
if (!bus_to_hcd(bus)->rh_registered)
continue;
@@ -611,13 +610,10 @@ static ssize_t usb_device_read(struct file *file, char __user *buf,
ret = usb_device_dump(&buf, &nbytes, &skip_bytes, ppos,
bus->root_hub, bus, 0, 0, 0);
usb_unlock_device(bus->root_hub);
- if (ret < 0) {
- mutex_unlock(&usb_bus_idr_lock);
+ if (ret < 0)
return ret;
- }
total_written += ret;
}
- mutex_unlock(&usb_bus_idr_lock);
return total_written;
}
@@ -79,15 +79,11 @@ unsigned long usb_hcds_loaded;
EXPORT_SYMBOL_GPL(usb_hcds_loaded);
/* host controllers we manage */
-DEFINE_IDR (usb_bus_idr);
-EXPORT_SYMBOL_GPL (usb_bus_idr);
+DEFINE_XARRAY_ALLOC1(usb_busses);
+EXPORT_SYMBOL_GPL(usb_busses);
/* used when allocating bus numbers */
-#define USB_MAXBUS 64
-
-/* used when updating list of hcds */
-DEFINE_MUTEX(usb_bus_idr_lock); /* exported only for usbfs */
-EXPORT_SYMBOL_GPL (usb_bus_idr_lock);
+#define USB_BUS_LIMIT XA_LIMIT(0, 63)
/* used for controlling access to virtual root hubs */
static DEFINE_SPINLOCK(hcd_root_hub_lock);
@@ -1010,27 +1006,20 @@ static void usb_bus_init (struct usb_bus *bus)
*/
static int usb_register_bus(struct usb_bus *bus)
{
- int result = -E2BIG;
- int busnum;
+ int err;
- mutex_lock(&usb_bus_idr_lock);
- busnum = idr_alloc(&usb_bus_idr, bus, 1, USB_MAXBUS, GFP_KERNEL);
- if (busnum < 0) {
+ err = xa_alloc(&usb_busses, &bus->busnum, bus, USB_BUS_LIMIT,
+ GFP_KERNEL);
+ if (err < 0) {
pr_err("%s: failed to get bus number\n", usbcore_name);
- goto error_find_busnum;
+ return -E2BIG;
}
- bus->busnum = busnum;
- mutex_unlock(&usb_bus_idr_lock);
usb_notify_add_bus(bus);
dev_info (bus->controller, "new USB bus registered, assigned bus "
"number %d\n", bus->busnum);
return 0;
-
-error_find_busnum:
- mutex_unlock(&usb_bus_idr_lock);
- return result;
}
/**
@@ -1050,9 +1039,7 @@ static void usb_deregister_bus (struct usb_bus *bus)
* controller code, as well as having it call this when cleaning
* itself up
*/
- mutex_lock(&usb_bus_idr_lock);
- idr_remove(&usb_bus_idr, bus->busnum);
- mutex_unlock(&usb_bus_idr_lock);
+ xa_erase(&usb_busses, bus->busnum);
usb_notify_remove_bus(bus);
}
@@ -1080,12 +1067,9 @@ static int register_root_hub(struct usb_hcd *hcd)
set_bit (devnum, usb_dev->bus->devmap.devicemap);
usb_set_device_state(usb_dev, USB_STATE_ADDRESS);
- mutex_lock(&usb_bus_idr_lock);
-
usb_dev->ep0.desc.wMaxPacketSize = cpu_to_le16(64);
retval = usb_get_device_descriptor(usb_dev, USB_DT_DEVICE_SIZE);
if (retval != sizeof usb_dev->descriptor) {
- mutex_unlock(&usb_bus_idr_lock);
dev_dbg (parent_dev, "can't read %s device descriptor %d\n",
dev_name(&usb_dev->dev), retval);
return (retval < 0) ? retval : -EMSGSIZE;
@@ -1096,7 +1080,6 @@ static int register_root_hub(struct usb_hcd *hcd)
if (!retval) {
usb_dev->lpm_capable = usb_device_supports_lpm(usb_dev);
} else if (usb_dev->speed >= USB_SPEED_SUPER) {
- mutex_unlock(&usb_bus_idr_lock);
dev_dbg(parent_dev, "can't read %s bos descriptor %d\n",
dev_name(&usb_dev->dev), retval);
return retval;
@@ -1116,7 +1099,6 @@ static int register_root_hub(struct usb_hcd *hcd)
if (HCD_DEAD(hcd))
usb_hc_died (hcd); /* This time clean up */
}
- mutex_unlock(&usb_bus_idr_lock);
return retval;
}
@@ -2905,9 +2887,7 @@ int usb_add_hcd(struct usb_hcd *hcd,
#ifdef CONFIG_PM
cancel_work_sync(&hcd->wakeup_work);
#endif
- mutex_lock(&usb_bus_idr_lock);
usb_disconnect(&rhdev); /* Sets rhdev to NULL */
- mutex_unlock(&usb_bus_idr_lock);
err_register_root_hub:
hcd->rh_pollable = 0;
clear_bit(HCD_FLAG_POLL_RH, &hcd->flags);
@@ -2966,9 +2946,7 @@ void usb_remove_hcd(struct usb_hcd *hcd)
cancel_work_sync(&hcd->wakeup_work);
#endif
- mutex_lock(&usb_bus_idr_lock);
usb_disconnect(&rhdev); /* Sets rhdev to NULL */
- mutex_unlock(&usb_bus_idr_lock);
/*
* tasklet_kill() isn't needed here because:
@@ -1274,7 +1274,6 @@ static void __exit usb_exit(void)
bus_unregister(&usb_bus_type);
usb_acpi_unregister();
usb_debugfs_cleanup();
- idr_destroy(&usb_bus_idr);
}
subsys_initcall(usb_init);
@@ -2093,13 +2093,11 @@ static void r8a66597_check_detect_child(struct r8a66597 *r8a66597,
memset(now_map, 0, sizeof(now_map));
- mutex_lock(&usb_bus_idr_lock);
- bus = idr_find(&usb_bus_idr, hcd->self.busnum);
+ bus = xa_load(&usb_busses, hcd->self.busnum);
if (bus && bus->root_hub) {
collect_usb_address_map(bus->root_hub, now_map);
update_usb_address_map(r8a66597, bus->root_hub, now_map);
}
- mutex_unlock(&usb_bus_idr_lock);
}
static int r8a66597_hub_status_data(struct usb_hcd *hcd, char *buf)
@@ -350,7 +350,8 @@ struct mon_bus *mon_bus_lookup(unsigned int num)
static int __init mon_init(void)
{
struct usb_bus *ubus;
- int rc, id;
+ unsigned long id;
+ int rc;
if ((rc = mon_text_init()) != 0)
goto err_text;
@@ -366,11 +367,9 @@ static int __init mon_init(void)
}
// MOD_INC_USE_COUNT(which_module?);
- mutex_lock(&usb_bus_idr_lock);
- idr_for_each_entry(&usb_bus_idr, ubus, id)
+ xa_for_each(&usb_busses, id, ubus)
mon_bus_init(ubus);
usb_register_notify(&mon_nb);
- mutex_unlock(&usb_bus_idr_lock);
return 0;
err_reg:
@@ -644,8 +644,7 @@ extern void usb_set_device_state(struct usb_device *udev,
/* exported only within usbcore */
-extern struct idr usb_bus_idr;
-extern struct mutex usb_bus_idr_lock;
+extern struct xarray usb_busses;
extern wait_queue_head_t usb_kill_urb_queue;
Remove the usb_bus_idr_lock as it doesn't appear to be protecting anything more than the built-in XArray lock does. Signed-off-by: Matthew Wilcox <willy@infradead.org> --- drivers/usb/core/devices.c | 10 +++------ drivers/usb/core/hcd.c | 40 ++++++++------------------------- drivers/usb/core/usb.c | 1 - drivers/usb/host/r8a66597-hcd.c | 4 +--- drivers/usb/mon/mon_main.c | 7 +++--- include/linux/usb/hcd.h | 3 +-- 6 files changed, 17 insertions(+), 48 deletions(-)