diff options
author | 2018-05-13 06:58:42 +0000 | |
---|---|---|
committer | 2018-05-13 06:58:42 +0000 | |
commit | 0a259b09eb69125ebe90d40fa45af74f20d9ab5e (patch) | |
tree | d1ad2a443a60f793a0fee3e15887f3efd77c9adc /sys/dev/usb/xhci.c | |
parent | Add a const qualifier to the ASN1_OBJECT * argument of the following: (diff) | |
download | wireguard-openbsd-0a259b09eb69125ebe90d40fa45af74f20d9ab5e.tar.xz wireguard-openbsd-0a259b09eb69125ebe90d40fa45af74f20d9ab5e.zip |
Add bus DMA barriers to ensure the hardware does not see a TRB cycle bit
flip before the rest of the TRB is updated.
OK dlg@, pirofti@, mpi@
Diffstat (limited to 'sys/dev/usb/xhci.c')
-rw-r--r-- | sys/dev/usb/xhci.c | 24 |
1 files changed, 19 insertions, 5 deletions
diff --git a/sys/dev/usb/xhci.c b/sys/dev/usb/xhci.c index 6d99d051479..f4c8b4665cb 100644 --- a/sys/dev/usb/xhci.c +++ b/sys/dev/usb/xhci.c @@ -1,4 +1,4 @@ -/* $OpenBSD: xhci.c,v 1.85 2018/05/08 13:41:52 mpi Exp $ */ +/* $OpenBSD: xhci.c,v 1.86 2018/05/13 06:58:42 visa Exp $ */ /* * Copyright (c) 2014-2015 Martin Pieuchot @@ -1647,11 +1647,16 @@ xhci_command_submit(struct xhci_softc *sc, struct xhci_trb *trb0, int timeout) trb = xhci_ring_produce(sc, &sc->sc_cmd_ring); if (trb == NULL) return (EAGAIN); - memcpy(trb, trb0, sizeof(struct xhci_trb)); + trb->trb_paddr = trb0->trb_paddr; + trb->trb_status = trb0->trb_status; bus_dmamap_sync(sc->sc_cmd_ring.dma.tag, sc->sc_cmd_ring.dma.map, TRBOFF(&sc->sc_cmd_ring, trb), sizeof(struct xhci_trb), BUS_DMASYNC_PREWRITE); + trb->trb_flags = trb0->trb_flags; + bus_dmamap_sync(sc->sc_cmd_ring.dma.tag, sc->sc_cmd_ring.dma.map, + TRBOFF(&sc->sc_cmd_ring, trb), sizeof(struct xhci_trb), + BUS_DMASYNC_PREWRITE); if (timeout == 0) { XDWRITE4(sc, XHCI_DOORBELL(0), 0); @@ -2635,8 +2640,11 @@ xhci_device_ctrl_start(struct usbd_xfer *xfer) memcpy(&trb0->trb_paddr, &xfer->request, sizeof(trb0->trb_paddr)); trb0->trb_status = htole32(XHCI_TRB_INTR(0) | XHCI_TRB_LEN(8)); - trb0->trb_flags = htole32(flags); + bus_dmamap_sync(xp->ring.dma.tag, xp->ring.dma.map, + TRBOFF(&xp->ring, trb0), sizeof(struct xhci_trb), + BUS_DMASYNC_PREWRITE); + trb0->trb_flags = htole32(flags); bus_dmamap_sync(xp->ring.dma.tag, xp->ring.dma.map, TRBOFF(&xp->ring, trb0), sizeof(struct xhci_trb), BUS_DMASYNC_PREWRITE); @@ -2751,8 +2759,11 @@ xhci_device_generic_start(struct usbd_xfer *xfer) XHCI_TRB_INTR(0) | XHCI_TRB_LEN(len0) | xhci_xfer_tdsize(xfer, xfer->length, len0) ); - trb0->trb_flags = htole32(flags); + bus_dmamap_sync(xp->ring.dma.tag, xp->ring.dma.map, + TRBOFF(&xp->ring, trb0), sizeof(struct xhci_trb), + BUS_DMASYNC_PREWRITE); + trb0->trb_flags = htole32(flags); bus_dmamap_sync(xp->ring.dma.tag, xp->ring.dma.map, TRBOFF(&xp->ring, trb0), sizeof(struct xhci_trb), BUS_DMASYNC_PREWRITE); @@ -2883,8 +2894,11 @@ xhci_device_isoc_start(struct usbd_xfer *xfer) XHCI_TRB_INTR(0) | XHCI_TRB_LEN(len0) | xhci_xfer_tdsize(xfer, xfer->length, len0) ); - trb0->trb_flags = htole32(flags); + bus_dmamap_sync(xp->ring.dma.tag, xp->ring.dma.map, + TRBOFF(&xp->ring, trb0), sizeof(struct xhci_trb), + BUS_DMASYNC_PREWRITE); + trb0->trb_flags = htole32(flags); bus_dmamap_sync(xp->ring.dma.tag, xp->ring.dma.map, TRBOFF(&xp->ring, trb0), sizeof(struct xhci_trb), BUS_DMASYNC_PREWRITE); |