diff options
author | Keith Short <keithshort@chromium.org> | 2019-06-21 16:39:59 -0600 |
---|---|---|
committer | Duncan Laurie <dlaurie@chromium.org> | 2019-07-02 17:42:18 +0000 |
commit | bf2c693f893ab6f9458f1a4840c2a9cbbd4bb9f2 (patch) | |
tree | 683f50da6fbdf15a63d08de54b5a7714ff8e310c /payloads/libpayload/drivers/usb/dwc2.c | |
parent | 9d0b7b902106e898d44f2bfc9b944a2e0c9a4f27 (diff) |
libpayload/usb: Increase USB request timeout to 5 s
Increase the timeout for USB requests to 5 seconds for all USB host
controllers.
Prior to this fix, the xCHI driver was detecting false timeouts during
SET ADDRESS requests when nested downstream hubs were connected to the
xHCI root hub.
BUG=b:124730179
BRANCH=sarien
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. Note that this tests xHCI operation only.
Change-Id: I53e3e67d893420e7c9e8b52c47dd0edb979e5468
Signed-off-by: Keith Short <keithshort@chromium.org>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/33671
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Julius Werner <jwerner@chromium.org>
Diffstat (limited to 'payloads/libpayload/drivers/usb/dwc2.c')
-rw-r--r-- | payloads/libpayload/drivers/usb/dwc2.c | 17 |
1 files changed, 11 insertions, 6 deletions
diff --git a/payloads/libpayload/drivers/usb/dwc2.c b/payloads/libpayload/drivers/usb/dwc2.c index 34de3bc42b..06c54e1030 100644 --- a/payloads/libpayload/drivers/usb/dwc2.c +++ b/payloads/libpayload/drivers/usb/dwc2.c @@ -146,6 +146,8 @@ static int dwc2_disconnected(hci_t *controller) return !(hprt.prtena && hprt.prtconnsts); } +#define DWC2_SLEEP_TIME_US 5 + /* * This function returns the actual transfer length when the transfer succeeded * or an error code if the transfer failed @@ -157,14 +159,14 @@ wait_for_complete(endpoint_t *ep, uint32_t ch_num) hcchar_t hcchar; hctsiz_t hctsiz; dwc2_reg_t *reg = DWC2_REG(ep->dev->controller); - int timeout = 600000; /* time out after 600000 * 5us == 3s */ + int timeout = USB_MAX_PROCESSING_TIME_US / DWC_SLEEP_TIME_US; /* * TODO: We should take care of up to three times of transfer error * retry here, according to the USB 2.0 spec 4.5.2 */ do { - udelay(5); + udelay(DWC_SLEEP_TIME_US); hcint.d32 = readl(®->host.hchn[ch_num].hcintn); hctsiz.d32 = readl(®->host.hchn[ch_num].hctsizn); @@ -374,12 +376,15 @@ static int dwc2_need_split(usbdev_t *dev, split_info_t *split) return 1; } +#define USB_FULL_LOW_SPEED_FRAME_US 1000 + static int dwc2_transfer(endpoint_t *ep, int size, int pid, ep_dir_t dir, uint32_t ch_num, u8 *src, uint8_t skip_nak) { split_info_t split; - int ret, short_pkt, transferred = 0, timeout = 3000; + int ret, short_pkt, transferred = 0; + int timeout = USB_MAX_PROCESSING_TIME_US / USB_FULL_LOW_SPEED_FRAME_US; ep->toggle = pid; @@ -393,11 +398,11 @@ nak_retry: /* * dwc2_split_transfer() waits for the next FullSpeed - * frame boundary, so we have one try per millisecond. - * It's 3s timeout for each split transfer. + * frame boundary, so we only need to delay 500 us + * here to have one try per millisecond. */ if (ret == -HCSTAT_NAK && !skip_nak && --timeout) { - udelay(500); + udelay(USB_FULL_LOW_SPEED_FRAME_US / 2); goto nak_retry; } } else { |