diff options
author | Martin Pieuchot <mpi@cvs.openbsd.org> | 2014-03-28 14:14:12 +0000 |
---|---|---|
committer | Martin Pieuchot <mpi@cvs.openbsd.org> | 2014-03-28 14:14:12 +0000 |
commit | 0ddf7acfdbe2b2ddc2e0930bb1d789b1f5c21228 (patch) | |
tree | e6eb50959b4208f9c337e44eb9793a36d6c21540 | |
parent | 50134cf6c99460df3685b520d280294cad4f5d96 (diff) |
If a command is submitted when the hardware is already gone, it will
obviously time out. That is what happen when pipes are closed after
unplugging an xhci(4) express card for example. In such case, make
sure the command TRB is reset.
-rw-r--r-- | sys/dev/usb/xhci.c | 14 |
1 files changed, 7 insertions, 7 deletions
diff --git a/sys/dev/usb/xhci.c b/sys/dev/usb/xhci.c index 7a08d57b65b..a953aa5bb52 100644 --- a/sys/dev/usb/xhci.c +++ b/sys/dev/usb/xhci.c @@ -1,4 +1,4 @@ -/* $OpenBSD: xhci.c,v 1.5 2014/03/25 20:27:37 mpi Exp $ */ +/* $OpenBSD: xhci.c,v 1.6 2014/03/28 14:14:11 mpi Exp $ */ /* * Copyright (c) 2014 Martin Pieuchot @@ -688,14 +688,16 @@ xhci_event_xfer(struct xhci_softc *sc, uint64_t paddr, uint32_t status, void xhci_event_command(struct xhci_softc *sc, uint64_t paddr) { - uint32_t flags = letoh32(sc->sc_cmd_trb->trb_flags); struct usbd_xfer *xfer; struct xhci_pipe *xp; + uint32_t flags; uint8_t dci, slot; int i; KASSERT(paddr == TRBADDR(sc->sc_cmd_ring, sc->sc_cmd_trb)); + flags = letoh32(sc->sc_cmd_trb->trb_flags); + slot = XHCI_TRB_GET_SLOT(flags); dci = XHCI_TRB_GET_EP(flags); xp = sc->sc_sdevs[slot].pipes[dci - 1]; @@ -1331,13 +1333,12 @@ xhci_command_submit(struct xhci_softc *sc, struct xhci_trb *trb0, int timeout) (timeout*hz+999)/ 1000 + 1); if (error) { #ifdef XHCI_DEBUG + printf("%s: tsleep() = %d\n", __func__, error); printf("cmd = %d " ,XHCI_TRB_TYPE(letoh32(trb->trb_flags))); xhci_dump_trb(trb); #endif -#ifdef DIAGNOSTIC - printf("%s: tsleep() = %d\n", __func__, error); -#endif - goto timedout; + sc->sc_cmd_trb = NULL; + return (error); } memcpy(trb0, &sc->sc_result_trb, sizeof(struct xhci_trb)); @@ -1348,7 +1349,6 @@ xhci_command_submit(struct xhci_softc *sc, struct xhci_trb *trb0, int timeout) error = EIO; } -timedout: #ifdef XHCI_DEBUG if (error) { printf("result = %d ", XHCI_TRB_TYPE(letoh32(trb0->trb_flags))); |