diff options
Diffstat (limited to 'sys/dev/usb/controller/xhci.c')
-rw-r--r-- | sys/dev/usb/controller/xhci.c | 29 |
1 files changed, 17 insertions, 12 deletions
diff --git a/sys/dev/usb/controller/xhci.c b/sys/dev/usb/controller/xhci.c index 8f721a3..c62f781 100644 --- a/sys/dev/usb/controller/xhci.c +++ b/sys/dev/usb/controller/xhci.c @@ -1440,24 +1440,33 @@ void xhci_interrupt(struct xhci_softc *sc) { uint32_t status; - uint32_t temp; + uint32_t iman; USB_BUS_LOCK(&sc->sc_bus); status = XREAD4(sc, oper, XHCI_USBSTS); + if (status == 0) + goto done; /* acknowledge interrupts */ XWRITE4(sc, oper, XHCI_USBSTS, status); - temp = XREAD4(sc, runt, XHCI_IMAN(0)); - - /* acknowledge pending event */ + DPRINTFN(16, "real interrupt (status=0x%08x)\n", status); + + if (status & XHCI_STS_EINT) { - XWRITE4(sc, runt, XHCI_IMAN(0), temp); + /* acknowledge pending event */ + iman = XREAD4(sc, runt, XHCI_IMAN(0)); - DPRINTFN(16, "real interrupt (sts=0x%08x, " - "iman=0x%08x)\n", status, temp); + /* reset interrupt */ + XWRITE4(sc, runt, XHCI_IMAN(0), iman); + + DPRINTFN(16, "real interrupt (iman=0x%08x)\n", iman); + + /* check for event(s) */ + xhci_interrupt_poll(sc); + } if (status & (XHCI_STS_PCD | XHCI_STS_HCH | XHCI_STS_HSE | XHCI_STS_HCE)) { @@ -1481,11 +1490,7 @@ xhci_interrupt(struct xhci_softc *sc) __FUNCTION__); } } - - /* check if we need to check the event rings */ - if ((status != 0) || (temp & XHCI_IMAN_INTR_PEND)) - xhci_interrupt_poll(sc); - +done: USB_BUS_UNLOCK(&sc->sc_bus); } |