summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormglocker <mglocker@openbsd.org>2019-03-17 22:05:37 +0000
committermglocker <mglocker@openbsd.org>2019-03-17 22:05:37 +0000
commit679fbd8f5ad316e51450b263dfc51fd21a2c765a (patch)
tree5419f7773e6003eda3dc9ae5989041a44e7773e3
parentBreak description of styles into its own section. (diff)
downloadwireguard-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.c106
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);
}