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>
diff --git a/payloads/libpayload/drivers/usb/dwc2.c b/payloads/libpayload/drivers/usb/dwc2.c
index 267dea7..9d19bc6 100644
--- a/payloads/libpayload/drivers/usb/dwc2.c
+++ b/payloads/libpayload/drivers/usb/dwc2.c
@@ -140,6 +140,16 @@
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 @@
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 @@
/* 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 */