diff options
author | Yunzhi Li <lyz@rock-chips.com> | 2015-08-11 17:58:14 +0800 |
---|---|---|
committer | Aaron Durbin <adurbin@chromium.org> | 2015-08-19 14:04:15 +0000 |
commit | 4938426783423889717e67f6be85e360a5f02d95 (patch) | |
tree | db5034d90b5624a73fe574aabcff141305b17c91 /payloads | |
parent | 416bf45480153e7a7d367d7b5da093786f4a433f (diff) |
libpayload: usb: dwc2: fix usb plug/unplug bug
Check device connect status while waiting for usb transfer complete
Avoid coreboot get stuck when usb device unplugged
BUG=chrome-os-partner:35525
TEST=None
BRANCH=None
Original-Change-Id: Id103501aa0d8b31b0b81bef773679c0fad79f689
Original-Signed-off-by: Yunzhi Li <lyz@rock-chips.com>
Original-Reviewed-on: https://chromium-review.googlesource.com/292630
Original-Reviewed-by: Patrick Georgi <pgeorgi@chromium.org>
Original-Reviewed-by: Julius Werner <jwerner@chromium.org>
Original-Commit-Queue: Lin Huang <hl@rock-chips.com>
Original-Tested-by: Lin Huang <hl@rock-chips.com>
Original-Reviewed-on: https://chromium-review.googlesource.com/292966
Original-Reviewed-by: David Hendricks <dhendrix@chromium.org>
Original-Tested-by: David Hendricks <dhendrix@chromium.org>
Original-Commit-Queue: David Hendricks <dhendrix@chromium.org>
Change-Id: I49396b74131dbfda505d9d3de5adbdc87eb92ce1
Signed-off-by: Yunzhi Li <lyz@rock-chips.com>
Reviewed-on: http://review.coreboot.org/11236
Tested-by: build bot (Jenkins)
Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
Diffstat (limited to 'payloads')
-rw-r--r-- | payloads/libpayload/drivers/usb/dwc2.c | 19 | ||||
-rw-r--r-- | payloads/libpayload/drivers/usb/dwc2_private.h | 1 |
2 files changed, 18 insertions, 2 deletions
diff --git a/payloads/libpayload/drivers/usb/dwc2.c b/payloads/libpayload/drivers/usb/dwc2.c index 267dea7c71..9d19bc6666 100644 --- a/payloads/libpayload/drivers/usb/dwc2.c +++ b/payloads/libpayload/drivers/usb/dwc2.c @@ -140,6 +140,16 @@ static void dwc2_shutdown(hci_t *controller) free(controller); } +/* Test root port device connect status */ +static int dwc2_disconnected(hci_t *controller) +{ + dwc2_reg_t *reg = DWC2_REG(controller); + hprt_t hprt; + + hprt.d32 = readl(®->host.hprt); + return !(hprt.prtena && hprt.prtconnsts); +} + /* * This function returns the actual transfer length when the transfer succeeded * or an error code if the transfer failed @@ -179,9 +189,11 @@ wait_for_complete(endpoint_t *ep, uint32_t ch_num) else return -HCSTAT_UNKNOW; } - } while (timeout--); - /* Release the channel on timeout */ + if (dwc2_disconnected(ep->dev->controller)) + return -HCSTAT_DISCONNECTED; + } while (timeout--); + /* Release the channel when hit timeout condition */ hcchar.d32 = readl(®->host.hchn[ch_num].hccharn); if (hcchar.chen) { /* @@ -310,6 +322,9 @@ dwc2_split_transfer(endpoint_t *ep, int size, int pid, ep_dir_t dir, /* Wait for next frame boundary */ do { hfnum.d32 = readl(®->host.hfnum); + + if (dwc2_disconnected(ep->dev->controller)) + return -HCSTAT_DISCONNECTED; } while (hfnum.frnum % 8 != 0); /* Handle Start-Split */ diff --git a/payloads/libpayload/drivers/usb/dwc2_private.h b/payloads/libpayload/drivers/usb/dwc2_private.h index 5b1a547f8d..73b6371069 100644 --- a/payloads/libpayload/drivers/usb/dwc2_private.h +++ b/payloads/libpayload/drivers/usb/dwc2_private.h @@ -54,5 +54,6 @@ typedef enum { HCSTAT_NYET, HCSTAT_UNKNOW, HCSTAT_TIMEOUT, + HCSTAT_DISCONNECTED, } hcstat_t; #endif |