diff options
author | Martin Pieuchot <mpi@cvs.openbsd.org> | 2018-04-26 10:19:32 +0000 |
---|---|---|
committer | Martin Pieuchot <mpi@cvs.openbsd.org> | 2018-04-26 10:19:32 +0000 |
commit | 70ddf8218d49c6153a70159a58caaa808a3a1e8d (patch) | |
tree | b673f6fe74e6b5f46b5eb6147bbb3e5827f5be61 /sys/dev/usb/xhci.c | |
parent | 133a1c8fbfdfa65297f2789d55273c15f68ff083 (diff) |
Reduce differences between isoch & bulk/intr routines.
ok stsp@
Diffstat (limited to 'sys/dev/usb/xhci.c')
-rw-r--r-- | sys/dev/usb/xhci.c | 41 |
1 files changed, 20 insertions, 21 deletions
diff --git a/sys/dev/usb/xhci.c b/sys/dev/usb/xhci.c index 0d91f5e0b12..df235c073dd 100644 --- a/sys/dev/usb/xhci.c +++ b/sys/dev/usb/xhci.c @@ -1,4 +1,4 @@ -/* $OpenBSD: xhci.c,v 1.78 2018/04/26 10:14:26 mpi Exp $ */ +/* $OpenBSD: xhci.c,v 1.79 2018/04/26 10:19:31 mpi Exp $ */ /* * Copyright (c) 2014-2015 Martin Pieuchot @@ -2619,7 +2619,7 @@ xhci_device_generic_start(struct usbd_xfer *xfer) struct xhci_pipe *xp = (struct xhci_pipe *)xfer->pipe; struct xhci_trb *trb0, *trb; uint32_t len, remain, flags; - uint32_t len0, mps; + uint32_t len0, mps = UGETW(xfer->pipe->endpoint->edesc->wMaxPacketSize); uint64_t paddr = DMAADDR(&xfer->dmabuf, 0); uint8_t toggle0, toggle; int s, i, ntrb; @@ -2640,7 +2640,6 @@ xhci_device_generic_start(struct usbd_xfer *xfer) len0 = xfer->length; /* If we need to append a zero length packet, we need one more. */ - mps = UGETW(xfer->pipe->endpoint->edesc->wMaxPacketSize); if ((xfer->flags & USBD_FORCE_SHORT_XFER || xfer->length == 0) && (xfer->length % mps == 0)) ntrb++; @@ -2653,10 +2652,11 @@ xhci_device_generic_start(struct usbd_xfer *xfer) remain = xfer->length - len0; paddr += len0; - len = min(remain, XHCI_TRB_MAXSIZE); /* Chain more TRBs if needed. */ for (i = ntrb - 1; i > 0; i--) { + len = min(remain, XHCI_TRB_MAXSIZE); + /* Next (or Last) TRB. */ trb = xhci_xfer_get_trb(sc, xfer, &toggle, (i == 1)); flags = XHCI_TRB_TYPE_NORMAL | toggle; @@ -2677,7 +2677,6 @@ xhci_device_generic_start(struct usbd_xfer *xfer) remain -= len; paddr += len; - len = min(remain, XHCI_TRB_MAXSIZE); } /* First TRB. */ @@ -2751,14 +2750,20 @@ xhci_device_isoc_start(struct usbd_xfer *xfer) struct xhci_trb *trb0, *trb; uint32_t len, remain, flags; uint64_t paddr = DMAADDR(&xfer->dmabuf, 0); - uint32_t len0, offs = 0; + uint32_t len0, mps = UGETW(xfer->pipe->endpoint->edesc->wMaxPacketSize); uint8_t toggle0, toggle; int s, i, ntrb = xfer->nframes, maxb; - int mps = UGETW(xfer->pipe->endpoint->edesc->wMaxPacketSize); int npkt = xfer->length / mps; KASSERT(!(xfer->rqflags & URQ_REQUEST)); + if (sc->sc_bus.dying || xp->halted) + return (USBD_IOERROR); + + /* Why would you do that anyway? */ + if (sc->sc_bus.use_polling) + return (USBD_INVAL); + /* * To allow continuous transfers, above we start all transfers * immediately. However, we're still going to get usbd_start_next call @@ -2768,15 +2773,7 @@ xhci_device_isoc_start(struct usbd_xfer *xfer) if (xx->ntrb > 0) return (USBD_IN_PROGRESS); - if (sc->sc_bus.dying || xp->halted) - return (USBD_IOERROR); - - /* Why would you do that anyway? */ - if (sc->sc_bus.use_polling) - return (USBD_INVAL); - - /* Driver MUST respect frlengths <= wMaxPacketSize. */ - if (xp->free_trbs < xfer->nframes) + if (xp->free_trbs < ntrb) return (USBD_NOMEM); len0 = xfer->frlengths[0]; @@ -2785,8 +2782,7 @@ xhci_device_isoc_start(struct usbd_xfer *xfer) trb0 = xhci_xfer_get_trb(sc, xfer, &toggle0, (ntrb == 1)); remain = xfer->length; - offs = len0; - paddr = DMAADDR(&xfer->dmabuf, offs); + paddr += len0; /* Chain more TRBs if needed. */ for (i = ntrb - 1; i > 0; i--) { @@ -2808,9 +2804,12 @@ xhci_device_isoc_start(struct usbd_xfer *xfer) ); trb->trb_flags = htole32(flags); + bus_dmamap_sync(xp->ring.dma.tag, xp->ring.dma.map, + TRBOFF(&xp->ring, trb), sizeof(struct xhci_trb), + BUS_DMASYNC_PREWRITE); + remain -= len; - offs += len; - paddr = DMAADDR(&xfer->dmabuf, offs); + paddr += len; } /* First TRB. */ @@ -2834,7 +2833,7 @@ xhci_device_isoc_start(struct usbd_xfer *xfer) trb0->trb_flags = htole32(flags); bus_dmamap_sync(xp->ring.dma.tag, xp->ring.dma.map, - TRBOFF(&xp->ring, trb0), sizeof(struct xhci_trb) * ntrb, + TRBOFF(&xp->ring, trb0), sizeof(struct xhci_trb), BUS_DMASYNC_PREWRITE); s = splusb(); |