Keith Short has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/33671
Change subject: libpayload/usb: Increase the SET ADDRESS timeout ......................................................................
libpayload/usb: Increase the SET ADDRESS timeout
The SET ADDRESS timeout was set to only 100 ms for the xHCI driver. The USB specification indicates a maximum response time of 50 ms for the SET ADDRESS request, but this does not account for propagation time of the request through USB hubs.
Analysis of other USB host driver timeouts: EHCI: 3 seconds OHCI: 2 seconds UHCI: 30 ms DWC: 3 seconds
BUG=b:124730179 BRANCH=none TEST=Build libpayload and depthcharge on sarien/arcada. TEST=Without change replicate USB set address timeouts in depthcharge when dock and 4K monitor connected (which includes a total of 4 USB hubs). With timeout fix, depthcharge boots OS with no USB errors and the same USB topology.
Change-Id: I53e3e67d893420e7c9e8b52c47dd0edb979e5468 Signed-off-by: Keith Short keithshort@chromium.org --- M payloads/libpayload/drivers/usb/xhci_events.c 1 file changed, 6 insertions(+), 5 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/71/33671/1
diff --git a/payloads/libpayload/drivers/usb/xhci_events.c b/payloads/libpayload/drivers/usb/xhci_events.c index dacb5d86..e2c124f 100644 --- a/payloads/libpayload/drivers/usb/xhci_events.c +++ b/payloads/libpayload/drivers/usb/xhci_events.c @@ -281,12 +281,13 @@ const int clear_event) { /* - * The Address Device Command should take most time, as it has to - * communicate with the USB device. Set address processing shouldn't - * take longer than 50ms (at the slave). Let's take a timeout of - * 100ms. + * The USB specification indicates that maximum response time to a SET + * ADDRESS request is 50 ms. However, this time does not account for + * the propagation delay to send the request through any hubs connected + * between the device and the root hub. Set the timeout to the maximum + * USB processing time, 5 seconds, to allow for complex USB topologies. */ - unsigned long timeout_us = 100 * 1000; /* 100ms */ + unsigned long timeout_us = 5 * 1000 * 1000; /* 5s */ int cc = TIMEOUT; while (xhci_wait_for_event_type(xhci, TRB_EV_CMD_CMPL, &timeout_us)) { if ((xhci->er.cur->ptr_low == virt_to_phys(address)) &&