diff --git a/payloads/libpayload/drivers/usb/usb.c b/payloads/libpayload/drivers/usb/usb.c index 25bd954ded..53006fff21 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 381d0399ed..ec9912ae7f 100644 --- a/payloads/libpayload/include/usb/usb.h +++ b/payloads/libpayload/include/usb/usb.h @@ -213,6 +213,7 @@ struct usbdev_hc { u32 reg_base; pcidev_t pcidev; // 0 if not used (eg on ARM) hc_type type; + int latest_address; usbdev_t *devices[128]; // dev 0 is root hub, 127 is last addressable /* start(): Resume operation. */