summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormpi <mpi@openbsd.org>2014-10-31 23:11:48 +0000
committermpi <mpi@openbsd.org>2014-10-31 23:11:48 +0000
commit4083ee39b2a303a7b054ff38a688267db0e1364d (patch)
treee4d8c2eb19d3b0f58447dfe82317165644efae2e
parentatheros ub94 support, from Matt Markfort (diff)
downloadwireguard-openbsd-4083ee39b2a303a7b054ff38a688267db0e1364d.tar.xz
wireguard-openbsd-4083ee39b2a303a7b054ff38a688267db0e1364d.zip
If an event is dequeued just/right after a device is detached, its pipes
might be NULL. Prevent from crashing in this case 8)
-rw-r--r--sys/dev/usb/xhci.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/sys/dev/usb/xhci.c b/sys/dev/usb/xhci.c
index b2fc7d706ac..53145f967c9 100644
--- a/sys/dev/usb/xhci.c
+++ b/sys/dev/usb/xhci.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: xhci.c,v 1.32 2014/10/31 16:39:34 mpi Exp $ */
+/* $OpenBSD: xhci.c,v 1.33 2014/10/31 23:11:48 mpi Exp $ */
/*
* Copyright (c) 2014 Martin Pieuchot
@@ -657,6 +657,8 @@ xhci_event_xfer(struct xhci_softc *sc, uint64_t paddr, uint32_t status,
}
xp = sc->sc_sdevs[slot].pipes[dci - 1];
+ if (xp == NULL)
+ return;
code = XHCI_TRB_GET_CODE(status);
remain = XHCI_TRB_REMAIN(status);
@@ -762,7 +764,6 @@ xhci_event_command(struct xhci_softc *sc, uint64_t paddr)
slot = XHCI_TRB_GET_SLOT(flags);
dci = XHCI_TRB_GET_EP(flags);
- xp = sc->sc_sdevs[slot].pipes[dci - 1];
switch (flags & XHCI_TRB_TYPE_MASK) {
case XHCI_CMD_RESET_EP:
@@ -770,6 +771,10 @@ xhci_event_command(struct xhci_softc *sc, uint64_t paddr)
* Clear the TRBs and reconfigure the dequeue pointer
* before declaring the endpoint ready.
*/
+ xp = sc->sc_sdevs[slot].pipes[dci - 1];
+ if (xp == NULL)
+ break;
+
xhci_ring_reset(sc, &xp->ring);
xp->free_trbs = xp->ring.ntrb;
xhci_cmd_set_tr_deq_async(sc, xp->slot, xp->dci,
@@ -781,6 +786,10 @@ xhci_event_command(struct xhci_softc *sc, uint64_t paddr)
* can finish all its pending transfers and let the
* stack play with it again.
*/
+ xp = sc->sc_sdevs[slot].pipes[dci - 1];
+ if (xp == NULL)
+ break;
+
xp->halted = 0;
for (i = 0; i < XHCI_MAX_TRANSFERS; i++) {
xfer = xp->pending_xfers[i];