summaryrefslogtreecommitdiff
path: root/payloads/libpayload
diff options
context:
space:
mode:
Diffstat (limited to 'payloads/libpayload')
-rw-r--r--payloads/libpayload/drivers/usb/usb.c14
-rw-r--r--payloads/libpayload/include/usb/usb.h1
2 files changed, 12 insertions, 3 deletions
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. */