diff options
-rw-r--r-- | sys/dev/usb/controller/xhci.c | 49 | ||||
-rw-r--r-- | sys/dev/usb/controller/xhci.h | 1 | ||||
-rw-r--r-- | sys/dev/usb/controller/xhci_pci.c | 1 |
3 files changed, 35 insertions, 16 deletions
diff --git a/sys/dev/usb/controller/xhci.c b/sys/dev/usb/controller/xhci.c index 2376cee2..14db805 100644 --- a/sys/dev/usb/controller/xhci.c +++ b/sys/dev/usb/controller/xhci.c @@ -352,6 +352,7 @@ xhci_start_controller(struct xhci_softc *sc) struct usb_page_search buf_res; struct xhci_hw_root *phwr; struct xhci_dev_ctx_addr *pdctxa; + usb_error_t err; uint64_t addr; uint32_t temp; uint16_t i; @@ -363,22 +364,9 @@ xhci_start_controller(struct xhci_softc *sc) sc->sc_command_ccs = 1; sc->sc_command_idx = 0; - /* Reset controller */ - XWRITE4(sc, oper, XHCI_USBCMD, XHCI_CMD_HCRST); - - for (i = 0; i != 100; i++) { - usb_pause_mtx(NULL, hz / 100); - temp = (XREAD4(sc, oper, XHCI_USBCMD) & XHCI_CMD_HCRST) | - (XREAD4(sc, oper, XHCI_USBSTS) & XHCI_STS_CNR); - if (!temp) - break; - } - - if (temp) { - device_printf(sc->sc_bus.parent, "Controller " - "reset timeout.\n"); - return (USB_ERR_IOERROR); - } + err = xhci_reset_controller(sc); + if (err) + return (err); /* set up number of device slots */ DPRINTF("CONFIG=0x%08x -> 0x%08x\n", @@ -526,6 +514,33 @@ xhci_halt_controller(struct xhci_softc *sc) } usb_error_t +xhci_reset_controller(struct xhci_softc *sc) +{ + uint32_t temp = 0; + uint16_t i; + + DPRINTF("\n"); + + /* Reset controller */ + XWRITE4(sc, oper, XHCI_USBCMD, XHCI_CMD_HCRST); + + for (i = 0; i != 100; i++) { + usb_pause_mtx(NULL, hz / 100); + temp = (XREAD4(sc, oper, XHCI_USBCMD) & XHCI_CMD_HCRST) | + (XREAD4(sc, oper, XHCI_USBSTS) & XHCI_STS_CNR); + if (!temp) + break; + } + + if (temp) { + device_printf(sc->sc_bus.parent, "Controller " + "reset timeout.\n"); + return (USB_ERR_IOERROR); + } + return (0); +} + +usb_error_t xhci_init(struct xhci_softc *sc, device_t self, uint8_t dma32) { uint32_t temp; @@ -676,10 +691,12 @@ xhci_set_hw_power_sleep(struct usb_bus *bus, uint32_t state) case USB_HW_POWER_SUSPEND: DPRINTF("Stopping the XHCI\n"); xhci_halt_controller(sc); + xhci_reset_controller(sc); break; case USB_HW_POWER_SHUTDOWN: DPRINTF("Stopping the XHCI\n"); xhci_halt_controller(sc); + xhci_reset_controller(sc); break; case USB_HW_POWER_RESUME: DPRINTF("Starting the XHCI\n"); diff --git a/sys/dev/usb/controller/xhci.h b/sys/dev/usb/controller/xhci.h index c50e852..f08c247 100644 --- a/sys/dev/usb/controller/xhci.h +++ b/sys/dev/usb/controller/xhci.h @@ -524,6 +524,7 @@ struct xhci_softc { uint8_t xhci_use_polling(void); usb_error_t xhci_halt_controller(struct xhci_softc *); +usb_error_t xhci_reset_controller(struct xhci_softc *); usb_error_t xhci_init(struct xhci_softc *, device_t, uint8_t); usb_error_t xhci_start_controller(struct xhci_softc *); void xhci_interrupt(struct xhci_softc *); diff --git a/sys/dev/usb/controller/xhci_pci.c b/sys/dev/usb/controller/xhci_pci.c index 967ba86..43bfb5d 100644 --- a/sys/dev/usb/controller/xhci_pci.c +++ b/sys/dev/usb/controller/xhci_pci.c @@ -326,6 +326,7 @@ xhci_pci_detach(device_t self) usb_callout_drain(&sc->sc_callout); xhci_halt_controller(sc); + xhci_reset_controller(sc); pci_disable_busmaster(self); |