diff options
author | Martin Pieuchot <mpi@cvs.openbsd.org> | 2013-11-07 20:37:34 +0000 |
---|---|---|
committer | Martin Pieuchot <mpi@cvs.openbsd.org> | 2013-11-07 20:37:34 +0000 |
commit | c0e9e414685b8d59f81c28eb3f91320b5ad7f70e (patch) | |
tree | ee7fde4fcc7d12b97e5cdd6b308bdfa18747194d /sys | |
parent | f0f9459042ab0546582ff41afdfb3f4ca88f66cf (diff) |
In polling mode since r1.101 we could end up dereferencing an
uninitialized variable in case the transfer we were waiting for
timed out; problem reported by oga@bitrig.
So bring uhci_waitintr() in sync with its equivalent in ohci(4)
and ehci(4), stop using an uhci_xfer, do not dereference it and
set the correct status of the transfer.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/usb/uhci.c | 20 |
1 files changed, 11 insertions, 9 deletions
diff --git a/sys/dev/usb/uhci.c b/sys/dev/usb/uhci.c index 20b587ae435..98352f3da36 100644 --- a/sys/dev/usb/uhci.c +++ b/sys/dev/usb/uhci.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uhci.c,v 1.102 2013/11/07 10:16:27 mpi Exp $ */ +/* $OpenBSD: uhci.c,v 1.103 2013/11/07 20:37:33 mpi Exp $ */ /* $NetBSD: uhci.c,v 1.172 2003/02/23 04:19:26 simonb Exp $ */ /* $FreeBSD: src/sys/dev/usb/uhci.c,v 1.33 1999/11/17 22:33:41 n_hibma Exp $ */ @@ -1418,16 +1418,17 @@ uhci_timeout_task(void *addr) void uhci_waitintr(struct uhci_softc *sc, struct usbd_xfer *xfer) { - int timo = xfer->timeout; - struct uhci_xfer *ex; - - DPRINTFN(10,("uhci_waitintr: timeout = %dms\n", timo)); + int timo; + u_int32_t intrs; xfer->status = USBD_IN_PROGRESS; - for (; timo >= 0; timo--) { + for (timo = xfer->timeout; timo >= 0; timo--) { usb_delay_ms(&sc->sc_bus, 1); - DPRINTFN(20,("uhci_waitintr: 0x%04x\n", UREAD2(sc, UHCI_STS))); - if (UREAD2(sc, UHCI_STS) & UHCI_STS_ALLINTRS) { + if (sc->sc_bus.dying) + break; + intrs = UREAD2(sc, UHCI_STS) & UHCI_STS_ALLINTRS; + DPRINTFN(15,("uhci_waitintr: 0x%04x\n", intrs)); + if (intrs) { uhci_intr1(sc); if (xfer->status != USBD_IN_PROGRESS) return; @@ -1436,7 +1437,8 @@ uhci_waitintr(struct uhci_softc *sc, struct usbd_xfer *xfer) /* Timeout */ DPRINTF(("uhci_waitintr: timeout\n")); - uhci_idone(ex); + xfer->status = USBD_TIMEOUT; + usb_transfer_complete(xfer); } void |