diff options
author | Martin Pieuchot <mpi@cvs.openbsd.org> | 2015-01-04 20:10:09 +0000 |
---|---|---|
committer | Martin Pieuchot <mpi@cvs.openbsd.org> | 2015-01-04 20:10:09 +0000 |
commit | 65bdaaec414a989cb901662735f4f3cf63f4307a (patch) | |
tree | 80af32c23700999eb4a0a6e75c447af2c1a17a05 /sys/dev/usb/xhci.c | |
parent | 16e2702891d485c2c4472ba32134a360f16e77ef (diff) |
Only set the status of a completed xfer just before giving it back to
the stack. This will allow stricter checks when aborting transfers.
While here update a comment about short transfer and multi-TRB TD since
bulk transfers can also use a chain now.
Diffstat (limited to 'sys/dev/usb/xhci.c')
-rw-r--r-- | sys/dev/usb/xhci.c | 25 |
1 files changed, 12 insertions, 13 deletions
diff --git a/sys/dev/usb/xhci.c b/sys/dev/usb/xhci.c index 7f50578a4e7..b2f4a3c473e 100644 --- a/sys/dev/usb/xhci.c +++ b/sys/dev/usb/xhci.c @@ -1,4 +1,4 @@ -/* $OpenBSD: xhci.c,v 1.50 2015/01/02 18:06:25 mpi Exp $ */ +/* $OpenBSD: xhci.c,v 1.51 2015/01/04 20:10:08 mpi Exp $ */ /* * Copyright (c) 2014 Martin Pieuchot @@ -744,29 +744,28 @@ xhci_event_xfer(struct xhci_softc *sc, uint64_t paddr, uint32_t status, switch (code) { case XHCI_CODE_SUCCESS: /* - * This might be the ``Event Status TRB'' of a control - * request for which the ``Event Data TRB'' triggered - * a Short Transfer condition, see below. + * This might be the last TRB of a TD that ended up + * with a Short Transfer condition, see below. */ - if (xfer->actlen) - break; + if (xfer->actlen == 0) + xfer->actlen = xfer->length - remain; - /* FALLTHROUGH */ + xfer->status = USBD_NORMAL_COMPLETION; + break; case XHCI_CODE_SHORT_XFER: xfer->actlen = xfer->length - remain; - xfer->status = USBD_NORMAL_COMPLETION; /* * If this is not the last TRB of a transfer, we should - * not assume the USB packet is finished. In the case - * of a Sort Transfer condition we should theoretically - * clear the IOC flags on the ``Event Status TRB'' but - * the HC might have already processed it since before - * we start processing the softinterrupt. + * theoretically clear the IOC at the end of the chain + * but the HC might have already processed it before we + * had a change to schedule the softinterrupt. */ xx = (struct xhci_xfer *)xfer; if (xx->index != trb_idx) return; + + xfer->status = USBD_NORMAL_COMPLETION; break; case XHCI_CODE_TXERR: case XHCI_CODE_SPLITERR: |