diff options
author | David Gwynne <dlg@cvs.openbsd.org> | 2004-08-11 04:15:11 +0000 |
---|---|---|
committer | David Gwynne <dlg@cvs.openbsd.org> | 2004-08-11 04:15:11 +0000 |
commit | dc1a42c30e36f84bee21d44551650b91f6511f3d (patch) | |
tree | 4f8be153c0e01cb7ba8f432a6f9cfbe95739e6ac /sys/dev/usb/ohci.c | |
parent | 5440b90de0f61c880e4cbf254074ab2768700754 (diff) |
from netbsd-bugs, pr 26545:
It's possible that the ohci interrupt can reach the CPU before the write
over PCI. This results in the done head pointer being NULL. If the
subsequent read of the interrupt status indicates that an OHCI_WDH has
occured then the done pointer should be reread and the pointer nulled.
Diffstat (limited to 'sys/dev/usb/ohci.c')
-rw-r--r-- | sys/dev/usb/ohci.c | 12 |
1 files changed, 9 insertions, 3 deletions
diff --git a/sys/dev/usb/ohci.c b/sys/dev/usb/ohci.c index 36320e40f0b..a6a81b0aacb 100644 --- a/sys/dev/usb/ohci.c +++ b/sys/dev/usb/ohci.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ohci.c,v 1.46 2004/08/11 04:12:43 dlg Exp $ */ +/* $OpenBSD: ohci.c,v 1.47 2004/08/11 04:15:10 dlg Exp $ */ /* $NetBSD: ohci.c,v 1.139 2003/02/22 05:24:16 tsutsui Exp $ */ /* $FreeBSD: src/sys/dev/usb/ohci.c,v 1.22 1999/11/17 22:33:40 n_hibma Exp $ */ @@ -1126,8 +1126,14 @@ ohci_intr1(ohci_softc_t *sc) if (done & OHCI_DONE_INTRS) intrs |= OREAD4(sc, OHCI_INTERRUPT_STATUS); sc->sc_hcca->hcca_done_head = 0; - } else - intrs = OREAD4(sc, OHCI_INTERRUPT_STATUS) & ~OHCI_WDH; + } else { + intrs = OREAD4(sc, OHCI_INTERRUPT_STATUS); + /* If we've flushed out a WDH then reread */ + if (intrs & OHCI_WDH) { + done = le32toh(sc->sc_hcca->hcca_done_head); + sc->sc_hcca->hcca_done_head = 0; + } + } if (!intrs) return (0); |