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>
This commit is contained in:
@@ -140,6 +140,16 @@ static void dwc2_shutdown(hci_t *controller)
|
|||||||
free(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
|
* This function returns the actual transfer length when the transfer succeeded
|
||||||
* or an error code if the transfer failed
|
* or an error code if the transfer failed
|
||||||
@@ -179,9 +189,11 @@ wait_for_complete(endpoint_t *ep, uint32_t ch_num)
|
|||||||
else
|
else
|
||||||
return -HCSTAT_UNKNOW;
|
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);
|
hcchar.d32 = readl(®->host.hchn[ch_num].hccharn);
|
||||||
if (hcchar.chen) {
|
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 */
|
/* Wait for next frame boundary */
|
||||||
do {
|
do {
|
||||||
hfnum.d32 = readl(®->host.hfnum);
|
hfnum.d32 = readl(®->host.hfnum);
|
||||||
|
|
||||||
|
if (dwc2_disconnected(ep->dev->controller))
|
||||||
|
return -HCSTAT_DISCONNECTED;
|
||||||
} while (hfnum.frnum % 8 != 0);
|
} while (hfnum.frnum % 8 != 0);
|
||||||
|
|
||||||
/* Handle Start-Split */
|
/* Handle Start-Split */
|
||||||
|
@@ -54,5 +54,6 @@ typedef enum {
|
|||||||
HCSTAT_NYET,
|
HCSTAT_NYET,
|
||||||
HCSTAT_UNKNOW,
|
HCSTAT_UNKNOW,
|
||||||
HCSTAT_TIMEOUT,
|
HCSTAT_TIMEOUT,
|
||||||
|
HCSTAT_DISCONNECTED,
|
||||||
} hcstat_t;
|
} hcstat_t;
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user