summaryrefslogtreecommitdiff
path: root/sys/dev/usb/ohci.c
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2004-08-11 04:15:11 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2004-08-11 04:15:11 +0000
commitdc1a42c30e36f84bee21d44551650b91f6511f3d (patch)
tree4f8be153c0e01cb7ba8f432a6f9cfbe95739e6ac /sys/dev/usb/ohci.c
parent5440b90de0f61c880e4cbf254074ab2768700754 (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.c12
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);