summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/dev/usb/xhci.c26
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");