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;
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;
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;
}
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);
*/
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;
}
/**
* 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);
}
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;
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;
if (HCD_DEAD(hcd))
usb_hc_died (hcd); /* This time clean up */
}
- mutex_unlock(&usb_bus_idr_lock);
return retval;
}
cancel_work_sync(&hcd->wakeup_work);
#endif
cancel_work_sync(&hcd->died_work);
- 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);
#endif
cancel_work_sync(&hcd->died_work);
- 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: