diff options
Diffstat (limited to 'sys/dev/usb/xhci.c')
-rw-r--r-- | sys/dev/usb/xhci.c | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/sys/dev/usb/xhci.c b/sys/dev/usb/xhci.c index 32c4315..2206bb7 100644 --- a/sys/dev/usb/xhci.c +++ b/sys/dev/usb/xhci.c @@ -379,6 +379,26 @@ xhci_start_hc(struct xhci_hc *hc) return 0; } +/* + * Stop and bring down the host controller. + * Returns 0 on success. + */ +static int +xhci_stop_hc(struct xhci_hc *hc) +{ + struct xhci_opregs *opregs = hc->opregs; + uint32_t usbcmd; + + /* Don't continue if we aren't running */ + usbcmd = mmio_read32(&opregs->usbcmd); + if (!ISSET(usbcmd, USBCMD_RUN)) + return 0; + + usbcmd &= ~USBCMD_RUN; + mmio_write32(&opregs->usbcmd, usbcmd); + return 0; +} + static int xhci_init_ports(struct xhci_hc *hc) { @@ -461,6 +481,12 @@ xhci_init_hc(struct xhci_hc *hc) return -1; } + pr_trace("stopping xHC chip...\n"); + if ((error = xhci_stop_hc(hc)) != 0) { + pr_error("run/stop timeout\n"); + return error; + } + pr_trace("resetting xHC chip...\n"); if ((error = xhci_reset(hc)) != 0) { pr_error("reset timeout\n"); |