diff --git a/payloads/libpayload/drivers/usb/usb.c b/payloads/libpayload/drivers/usb/usb.c index 2d91cbb07a..d45cff2ab6 100644 --- a/payloads/libpayload/drivers/usb/usb.c +++ b/payloads/libpayload/drivers/usb/usb.c @@ -206,10 +206,18 @@ clear_stall (endpoint_t *ep) static int get_free_address (hci_t *controller) { - int i; - for (i = 1; i < 128; i++) { - if (controller->devices[i] == 0) + int i = controller->latest_address + 1; + for (; i != controller->latest_address; i++) { + if (i >= ARRAY_SIZE(controller->devices) || i < 1) { + usb_debug("WARNING: Device addresses for controller %#x" + " wrapped around!\n", controller->reg_base); + i = 0; + continue; + } + if (controller->devices[i] == 0) { + controller->latest_address = i; return i; + } } usb_debug ("no free address found\n"); return -1; // no free address diff --git a/payloads/libpayload/include/usb/usb.h b/payloads/libpayload/include/usb/usb.h index bb0058dfe0..b2137a534c 100644 --- a/payloads/libpayload/include/usb/usb.h +++ b/payloads/libpayload/include/usb/usb.h @@ -212,6 +212,7 @@ struct usbdev_hc { hci_t *next; u32 reg_base; hc_type type; + int latest_address; usbdev_t *devices[128]; // dev 0 is root hub, 127 is last addressable /* start(): Resume operation. */