diff options
author | Hans Petter Selasky <hselasky@FreeBSD.org> | 2017-03-14 15:27:38 +0000 |
---|---|---|
committer | Hans Petter Selasky <hselasky@FreeBSD.org> | 2017-03-14 15:27:38 +0000 |
commit | 2cb51d0599e7b35caf8657de798e4570858140cb (patch) | |
tree | 235aa3af9d9be22eb90a9f4f73b2f5487ca6ebcc | |
parent | d7ac719c768723c8fb5349088fbd5041dc0e1cff (diff) |
Notes
-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 c403b4ba45ab..b773c28a20b6 100644 --- a/sys/dev/usb/controller/xhci.c +++ b/sys/dev/usb/controller/xhci.c @@ -347,6 +347,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; @@ -358,22 +359,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", @@ -521,6 +509,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; @@ -671,10 +686,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 e8bc9addb6f8..8ca628580c94 100644 --- a/sys/dev/usb/controller/xhci.h +++ b/sys/dev/usb/controller/xhci.h @@ -525,6 +525,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 cb0f3dafef5e..cada25ad5003 100644 --- a/sys/dev/usb/controller/xhci_pci.c +++ b/sys/dev/usb/controller/xhci_pci.c @@ -348,6 +348,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); |