summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Pieuchot <mpi@cvs.openbsd.org>2014-03-28 14:14:12 +0000
committerMartin Pieuchot <mpi@cvs.openbsd.org>2014-03-28 14:14:12 +0000
commit0ddf7acfdbe2b2ddc2e0930bb1d789b1f5c21228 (patch)
treee6eb50959b4208f9c337e44eb9793a36d6c21540
parent50134cf6c99460df3685b520d280294cad4f5d96 (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.c14
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)));