diff options
author | 2019-03-17 22:05:37 +0000 | |
---|---|---|
committer | 2019-03-17 22:05:37 +0000 | |
commit | 679fbd8f5ad316e51450b263dfc51fd21a2c765a (patch) | |
tree | 5419f7773e6003eda3dc9ae5989041a44e7773e3 | |
parent | Break description of styles into its own section. (diff) | |
download | wireguard-openbsd-679fbd8f5ad316e51450b263dfc51fd21a2c765a.tar.xz wireguard-openbsd-679fbd8f5ad316e51450b263dfc51fd21a2c765a.zip |
Since an isoc endpoint never halts, move to remaining error handling
code in xhci_event_xfer() to the generic handler function.
suggested and ok mpi@
-rw-r--r-- | sys/dev/usb/xhci.c | 106 |
1 files changed, 48 insertions, 58 deletions
diff --git a/sys/dev/usb/xhci.c b/sys/dev/usb/xhci.c index 7a6683f4be7..149ce7bbb3b 100644 --- a/sys/dev/usb/xhci.c +++ b/sys/dev/usb/xhci.c @@ -1,4 +1,4 @@ -/* $OpenBSD: xhci.c,v 1.100 2019/03/17 11:28:07 mglocker Exp $ */ +/* $OpenBSD: xhci.c,v 1.101 2019/03/17 22:05:37 mglocker Exp $ */ /* * Copyright (c) 2014-2015 Martin Pieuchot @@ -78,8 +78,8 @@ int xhci_reset(struct xhci_softc *); int xhci_intr1(struct xhci_softc *); void xhci_event_dequeue(struct xhci_softc *); void xhci_event_xfer(struct xhci_softc *, uint64_t, uint32_t, uint32_t); -int xhci_event_xfer_generic(struct usbd_xfer *, struct xhci_pipe *, - uint32_t, int, uint8_t); +int xhci_event_xfer_generic(struct xhci_softc *, struct usbd_xfer *, + struct xhci_pipe *, uint32_t, int, uint8_t, uint8_t, uint8_t); int xhci_event_xfer_isoc(struct usbd_xfer *, struct xhci_pipe *, uint32_t, int); void xhci_event_command(struct xhci_softc *, uint64_t); @@ -751,61 +751,14 @@ xhci_event_xfer(struct xhci_softc *sc, uint64_t paddr, uint32_t status, if (remain > xfer->length) remain = xfer->length; - switch (code) { - case XHCI_CODE_SUCCESS: - case XHCI_CODE_SHORT_XFER: - /* Handled per xfer type. */ - break; - case XHCI_CODE_TXERR: - case XHCI_CODE_SPLITERR: - DPRINTF(("%s: txerr? code %d\n", DEVNAME(sc), code)); - xfer->status = USBD_IOERROR; - xhci_xfer_done(xfer); - return; - case XHCI_CODE_STALL: - case XHCI_CODE_BABBLE: - DPRINTF(("%s: babble code %d\n", DEVNAME(sc), code)); - /* Prevent any timeout to kick in. */ - timeout_del(&xfer->timeout_handle); - usb_rem_task(xfer->device, &xfer->abort_task); - - /* We need to report this condition for umass(4). */ - if (code == XHCI_CODE_STALL) - xp->halted = USBD_STALLED; - else - xp->halted = USBD_IOERROR; - /* - * Since the stack might try to start a new transfer as - * soon as a pending one finishes, make sure the endpoint - * is fully reset before calling usb_transfer_complete(). - */ - xp->aborted_xfer = xfer; - xhci_cmd_reset_ep_async(sc, slot, dci); - return; - case XHCI_CODE_XFER_STOPPED: - case XHCI_CODE_XFER_STOPINV: - /* Endpoint stopped while processing a TD. */ - if (xfer == xp->aborted_xfer) { - DPRINTF(("%s: stopped xfer=%p\n", __func__, xfer)); - return; - } - - /* FALLTHROUGH */ - default: - DPRINTF(("%s: unhandled code %d\n", DEVNAME(sc), code)); - xfer->status = USBD_IOERROR; - xp->halted = 1; - xhci_xfer_done(xfer); - return; - } - xfertype = UE_GET_XFERTYPE(xfer->pipe->endpoint->edesc->bmAttributes); switch (xfertype) { case UE_BULK: case UE_INTERRUPT: case UE_CONTROL: - if (xhci_event_xfer_generic(xfer, xp, remain, trb_idx, code)) + if (xhci_event_xfer_generic(sc, xfer, xp, remain, trb_idx, + code, slot, dci)) return; break; case UE_ISOCHRONOUS: @@ -820,8 +773,9 @@ xhci_event_xfer(struct xhci_softc *sc, uint64_t paddr, uint32_t status, } int -xhci_event_xfer_generic(struct usbd_xfer *xfer, struct xhci_pipe *xp, - uint32_t remain, int trb_idx, uint8_t code) +xhci_event_xfer_generic(struct xhci_softc *sc, struct usbd_xfer *xfer, + struct xhci_pipe *xp, uint32_t remain, int trb_idx, + uint8_t code, uint8_t slot, uint8_t dci) { struct xhci_xfer *xx = (struct xhci_xfer *)xfer; @@ -833,6 +787,7 @@ xhci_event_xfer_generic(struct usbd_xfer *xfer, struct xhci_pipe *xp, */ if (xfer->actlen == 0) xfer->actlen = xfer->length - remain; + xfer->status = USBD_NORMAL_COMPLETION; break; case XHCI_CODE_SHORT_XFER: xfer->actlen = xfer->length - remain; @@ -847,14 +802,49 @@ xhci_event_xfer_generic(struct usbd_xfer *xfer, struct xhci_pipe *xp, DEVNAME(sc), xfer, xx->index)); return (1); } + xfer->status = USBD_NORMAL_COMPLETION; break; + case XHCI_CODE_TXERR: + case XHCI_CODE_SPLITERR: + DPRINTF(("%s: txerr? code %d\n", DEVNAME(sc), code)); + xfer->status = USBD_IOERROR; + break; + case XHCI_CODE_STALL: + case XHCI_CODE_BABBLE: + DPRINTF(("%s: babble code %d\n", DEVNAME(sc), code)); + /* Prevent any timeout to kick in. */ + timeout_del(&xfer->timeout_handle); + usb_rem_task(xfer->device, &xfer->abort_task); + + /* We need to report this condition for umass(4). */ + if (code == XHCI_CODE_STALL) + xp->halted = USBD_STALLED; + else + xp->halted = USBD_IOERROR; + /* + * Since the stack might try to start a new transfer as + * soon as a pending one finishes, make sure the endpoint + * is fully reset before calling usb_transfer_complete(). + */ + xp->aborted_xfer = xfer; + xhci_cmd_reset_ep_async(sc, slot, dci); + return (1); + case XHCI_CODE_XFER_STOPPED: + case XHCI_CODE_XFER_STOPINV: + /* Endpoint stopped while processing a TD. */ + if (xfer == xp->aborted_xfer) { + DPRINTF(("%s: stopped xfer=%p\n", __func__, xfer)); + return (1); + } + + /* FALLTHROUGH */ default: - panic("xhci_event_xfer_generic: unexpected completion code %u", - code); + DPRINTF(("%s: unhandled code %d\n", DEVNAME(sc), code)); + xfer->status = USBD_IOERROR; + xp->halted = 1; + break; } - xfer->status = USBD_NORMAL_COMPLETION; - return (0); } |