summaryrefslogtreecommitdiffstats
path: root/sys/dev/usb/xhci.c
diff options
context:
space:
mode:
authorvisa <visa@openbsd.org>2018-05-13 06:58:42 +0000
committervisa <visa@openbsd.org>2018-05-13 06:58:42 +0000
commit0a259b09eb69125ebe90d40fa45af74f20d9ab5e (patch)
treed1ad2a443a60f793a0fee3e15887f3efd77c9adc /sys/dev/usb/xhci.c
parentAdd a const qualifier to the ASN1_OBJECT * argument of the following: (diff)
downloadwireguard-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.c24
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);