if (sc->sc_dying || (sc->sc_flags & OHCI_SCFLG_DONEINIT) == 0)
return (0);
- /* If we get an interrupt while polling, then just ignore it. */
+ /*
+ * If we get an interrupt while polling, then remember what it
+ * was and acknowledge it.
+ */
if (sc->sc_bus.use_polling) {
+ u_int32_t intrs = OREAD4(sc, OHCI_INTERRUPT_STATUS);
+
+ intrs &= ~OHCI_MIE;
+ if (intrs)
+ OWRITE4(sc, OHCI_INTERRUPT_STATUS, intrs);
+ sc->sc_dintrs |= intrs;
#ifdef DIAGNOSTIC
DPRINTFN(16, ("ohci_intr: ignored interrupt while polling\n"));
#endif
intrs = OHCI_WDH;
if (done & OHCI_DONE_INTRS) {
intrs |= OREAD4(sc, OHCI_INTERRUPT_STATUS);
+ intrs |= sc->sc_dintrs;
done &= ~OHCI_DONE_INTRS;
}
sc->sc_hcca->hcca_done_head = 0;
} else {
- intrs = OREAD4(sc, OHCI_INTERRUPT_STATUS) & ~OHCI_WDH;
+ intrs = OREAD4(sc, OHCI_INTERRUPT_STATUS);
+ intrs |= sc->sc_dintrs;
+ intrs &= ~OHCI_WDH;
}
if (intrs == 0) /* nothing to be done (PCI shared interrupt) */
intrs &= ~OHCI_MIE;
OWRITE4(sc, OHCI_INTERRUPT_STATUS, intrs); /* Acknowledge */
+ sc->sc_dintrs &= ~intrs;
eintrs = intrs & sc->sc_eintrs;
if (!eintrs)
return (0);
usb_delay_ms(&sc->sc_bus, 1);
if (sc->sc_dying)
break;
- intrs = OREAD4(sc, OHCI_INTERRUPT_STATUS) & sc->sc_eintrs;
+ intrs = OREAD4(sc, OHCI_INTERRUPT_STATUS);
+ intrs |= sc->sc_dintrs;
+ intrs &= sc->sc_eintrs;
DPRINTFN(15,("ohci_waitintr: 0x%04x\n", intrs));
#ifdef USB_DEBUG
if (ohcidebug > 15)