summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/dev/usb/dwc2/dwc2.c16
-rw-r--r--sys/dev/usb/ehci.c22
-rw-r--r--sys/dev/usb/ohci.c37
-rw-r--r--sys/dev/usb/uhci.c17
-rw-r--r--sys/dev/usb/usbdi.c32
-rw-r--r--sys/dev/usb/xhci.c26
6 files changed, 114 insertions, 36 deletions
diff --git a/sys/dev/usb/dwc2/dwc2.c b/sys/dev/usb/dwc2/dwc2.c
index 6ca3cc658e5..3ad7dc479f4 100644
--- a/sys/dev/usb/dwc2/dwc2.c
+++ b/sys/dev/usb/dwc2/dwc2.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dwc2.c,v 1.51 2020/03/21 12:08:31 patrick Exp $ */
+/* $OpenBSD: dwc2.c,v 1.52 2020/04/03 20:11:47 patrick Exp $ */
/* $NetBSD: dwc2.c,v 1.32 2014/09/02 23:26:20 macallan Exp $ */
/*-
@@ -1260,6 +1260,9 @@ dwc2_device_start(struct usbd_xfer *xfer)
dwc2_urb->usbdma = &xfer->dmabuf;
dwc2_urb->buf = KERNADDR(dwc2_urb->usbdma, 0);
dwc2_urb->dma = DMAADDR(dwc2_urb->usbdma, 0);
+ usb_syncmem(&xfer->dmabuf, 0, xfer->length,
+ usbd_xfer_isread(xfer) ?
+ BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
}
dwc2_urb->length = len;
dwc2_urb->flags = flags;
@@ -1649,6 +1652,17 @@ void dwc2_host_complete(struct dwc2_hsotg *hsotg, struct dwc2_qtd *qtd,
xfer);
}
+ if (xfer->status == USBD_NORMAL_COMPLETION) {
+ if (xfertype == UE_ISOCHRONOUS)
+ usb_syncmem(&xfer->dmabuf, 0, xfer->length,
+ usbd_xfer_isread(xfer) ?
+ BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
+ else if (xfer->actlen)
+ usb_syncmem(&xfer->dmabuf, 0, xfer->actlen,
+ usbd_xfer_isread(xfer) ?
+ BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
+ }
+
qtd->urb = NULL;
timeout_del(&xfer->timeout_handle);
usb_rem_task(xfer->device, &xfer->abort_task);
diff --git a/sys/dev/usb/ehci.c b/sys/dev/usb/ehci.c
index a352d83eaf4..41851defe4f 100644
--- a/sys/dev/usb/ehci.c
+++ b/sys/dev/usb/ehci.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ehci.c,v 1.209 2020/03/30 22:29:04 krw Exp $ */
+/* $OpenBSD: ehci.c,v 1.210 2020/04/03 20:11:47 patrick Exp $ */
/* $NetBSD: ehci.c,v 1.66 2004/06/30 03:11:56 mycroft Exp $ */
/*
@@ -856,6 +856,10 @@ ehci_isoc_idone(struct usbd_xfer *xfer)
#endif
xfer->actlen = actlen;
xfer->status = USBD_NORMAL_COMPLETION;
+
+ usb_syncmem(&xfer->dmabuf, 0, xfer->length,
+ usbd_xfer_isread(xfer) ?
+ BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
usb_transfer_complete(xfer);
}
@@ -911,9 +915,10 @@ ehci_idone(struct usbd_xfer *xfer)
} else
xfer->status = USBD_NORMAL_COMPLETION;
- /* XXX transfer_complete memcpys out transfer data (for in endpoints)
- * during this call, before methods->done is called: dma sync required
- * beforehand? */
+ if (xfer->actlen)
+ usb_syncmem(&xfer->dmabuf, 0, xfer->actlen,
+ usbd_xfer_isread(xfer) ?
+ BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
usb_transfer_complete(xfer);
DPRINTFN(/*12*/2, ("ehci_idone: ex=%p done\n", ex));
}
@@ -3208,9 +3213,6 @@ ehci_device_intr_done(struct usbd_xfer *xfer)
if (xfer->pipe->repeat) {
ehci_free_sqtd_chain(sc, ex);
- usb_syncmem(&xfer->dmabuf, 0, xfer->length,
- usbd_xfer_isread(xfer) ?
- BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
sqh = epipe->sqh;
err = ehci_alloc_sqtd_chain(sc, xfer->length, xfer, &data, &dataend);
@@ -3408,6 +3410,9 @@ ehci_alloc_itd_chain(struct ehci_softc *sc, struct usbd_xfer *xfer)
if (nframes == 0)
return (1);
+ usb_syncmem(&xfer->dmabuf, 0, xfer->length,
+ usbd_xfer_isread(xfer) ?
+ BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
for (i = 0; i < nframes; i++) {
uint32_t froffs = offs;
@@ -3522,6 +3527,9 @@ ehci_alloc_sitd_chain(struct ehci_softc *sc, struct usbd_xfer *xfer)
if (usbd_xfer_isread(xfer))
endp |= EHCI_SITD_SET_DIR(1);
+ usb_syncmem(&xfer->dmabuf, 0, xfer->length,
+ usbd_xfer_isread(xfer) ?
+ BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
for (i = 0; i < nframes; i++) {
uint32_t addr = DMAADDR(&xfer->dmabuf, offs);
uint32_t page = EHCI_PAGE(addr + xfer->frlengths[i] - 1);
diff --git a/sys/dev/usb/ohci.c b/sys/dev/usb/ohci.c
index 7aa2303eabd..3155068633e 100644
--- a/sys/dev/usb/ohci.c
+++ b/sys/dev/usb/ohci.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ohci.c,v 1.160 2020/03/21 12:08:31 patrick Exp $ */
+/* $OpenBSD: ohci.c,v 1.161 2020/04/03 20:11:47 patrick Exp $ */
/* $NetBSD: ohci.c,v 1.139 2003/02/22 05:24:16 tsutsui Exp $ */
/* $FreeBSD: src/sys/dev/usb/ohci.c,v 1.22 1999/11/17 22:33:40 n_hibma Exp $ */
@@ -491,6 +491,10 @@ ohci_alloc_std_chain(struct ohci_softc *sc, u_int alen, struct usbd_xfer *xfer,
DPRINTFN(alen < 4096,("ohci_alloc_std_chain: start len=%u\n", alen));
+ usb_syncmem(&xfer->dmabuf, 0, xfer->length,
+ usbd_xfer_isread(xfer) ?
+ BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
+
len = alen;
cur = sp;
end = NULL;
@@ -1279,6 +1283,12 @@ ohci_softintr(void *v)
ohci_free_std(sc, std);
if (done) {
+ if (xfer->actlen)
+ usb_syncmem(&xfer->dmabuf, 0,
+ xfer->actlen,
+ usbd_xfer_isread(xfer) ?
+ BUS_DMASYNC_POSTREAD :
+ BUS_DMASYNC_POSTWRITE);
xfer->status = USBD_NORMAL_COMPLETION;
s = splusb();
usb_transfer_complete(xfer);
@@ -1309,9 +1319,15 @@ ohci_softintr(void *v)
if (cc == OHCI_CC_STALL)
xfer->status = USBD_STALLED;
- else if (cc == OHCI_CC_DATA_UNDERRUN)
+ else if (cc == OHCI_CC_DATA_UNDERRUN) {
+ if (xfer->actlen)
+ usb_syncmem(&xfer->dmabuf, 0,
+ xfer->actlen,
+ usbd_xfer_isread(xfer) ?
+ BUS_DMASYNC_POSTREAD :
+ BUS_DMASYNC_POSTWRITE);
xfer->status = USBD_NORMAL_COMPLETION;
- else
+ } else
xfer->status = USBD_IOERROR;
s = splusb();
usb_transfer_complete(xfer);
@@ -1389,6 +1405,13 @@ ohci_softintr(void *v)
xfer->actlen = actlen;
xfer->hcpriv = NULL;
+ if (xfer->status == USBD_NORMAL_COMPLETION) {
+ usb_syncmem(&xfer->dmabuf, 0, xfer->length,
+ usbd_xfer_isread(xfer) ?
+ BUS_DMASYNC_POSTREAD :
+ BUS_DMASYNC_POSTWRITE);
+ }
+
s = splusb();
usb_transfer_complete(xfer);
splx(s);
@@ -2846,6 +2869,10 @@ ohci_device_intr_start(struct usbd_xfer *xfer)
panic("ohci_device_intr_transfer: a request");
#endif
+ usb_syncmem(&xfer->dmabuf, 0, xfer->length,
+ usbd_xfer_isread(xfer) ?
+ BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
+
len = xfer->length;
endpt = xfer->pipe->endpoint->edesc->bEndpointAddress;
@@ -3057,6 +3084,10 @@ ohci_device_isoc_enter(struct usbd_xfer *xfer)
if (sc->sc_bus.dying)
return;
+ usb_syncmem(&xfer->dmabuf, 0, xfer->length,
+ usbd_xfer_isread(xfer) ?
+ BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
+
if (iso->next == -1) {
/* Not in use yet, schedule it a few frames ahead. */
iso->next = letoh32(sc->sc_hcca->hcca_frame_number) + 5;
diff --git a/sys/dev/usb/uhci.c b/sys/dev/usb/uhci.c
index bae6c1b81a9..ff4eb530fcb 100644
--- a/sys/dev/usb/uhci.c
+++ b/sys/dev/usb/uhci.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uhci.c,v 1.151 2020/03/21 12:08:31 patrick Exp $ */
+/* $OpenBSD: uhci.c,v 1.152 2020/04/03 20:11:47 patrick Exp $ */
/* $NetBSD: uhci.c,v 1.172 2003/02/23 04:19:26 simonb Exp $ */
/* $FreeBSD: src/sys/dev/usb/uhci.c,v 1.33 1999/11/17 22:33:41 n_hibma Exp $ */
@@ -1236,6 +1236,9 @@ uhci_idone(struct usbd_xfer *xfer)
actlen += len;
}
upipe->u.iso.inuse -= nframes;
+ usb_syncmem(&xfer->dmabuf, 0, xfer->length,
+ usbd_xfer_isread(xfer) ?
+ BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
xfer->actlen = actlen;
xfer->status = USBD_NORMAL_COMPLETION;
goto end;
@@ -1299,6 +1302,10 @@ uhci_idone(struct usbd_xfer *xfer)
else
xfer->status = USBD_IOERROR; /* more info XXX */
} else {
+ if (xfer->actlen)
+ usb_syncmem(&xfer->dmabuf, 0, xfer->actlen,
+ usbd_xfer_isread(xfer) ?
+ BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
xfer->status = USBD_NORMAL_COMPLETION;
}
@@ -1527,6 +1534,10 @@ uhci_alloc_std_chain(struct uhci_softc *sc, u_int len, struct usbd_xfer *xfer,
__func__, addr, UE_GET_ADDR(endpt), len, xfer->device->speed,
flags));
+ usb_syncmem(&xfer->dmabuf, 0, xfer->length,
+ usbd_xfer_isread(xfer) ?
+ BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
+
mps = UGETW(xfer->pipe->endpoint->edesc->wMaxPacketSize);
if (mps == 0) {
printf("uhci_alloc_std_chain: mps=0\n");
@@ -2127,6 +2138,10 @@ uhci_device_isoc_enter(struct usbd_xfer *xfer)
printf("uhci_device_isoc_enter: overflow!\n");
#endif
+ usb_syncmem(&xfer->dmabuf, 0, xfer->length,
+ usbd_xfer_isread(xfer) ?
+ BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
+
next = iso->next;
if (next == -1) {
/* Not in use yet, schedule it a few frames ahead. */
diff --git a/sys/dev/usb/usbdi.c b/sys/dev/usb/usbdi.c
index f6707432e41..ecb17c3bf4f 100644
--- a/sys/dev/usb/usbdi.c
+++ b/sys/dev/usb/usbdi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: usbdi.c,v 1.105 2020/04/01 08:43:33 patrick Exp $ */
+/* $OpenBSD: usbdi.c,v 1.106 2020/04/03 20:11:47 patrick Exp $ */
/* $NetBSD: usbdi.c,v 1.103 2002/09/27 15:37:38 provos Exp $ */
/* $FreeBSD: src/sys/dev/usb/usbdi.c,v 1.28 1999/11/17 22:33:49 n_hibma Exp $ */
@@ -305,22 +305,15 @@ usbd_transfer(struct usbd_xfer *xfer)
if (xfer->rqflags & URQ_AUTO_DMABUF)
printf("usbd_transfer: has old buffer!\n");
#endif
- err = usb_allocmem(bus, xfer->length, 0, USB_DMA_COHERENT,
- &xfer->dmabuf);
+ err = usb_allocmem(bus, xfer->length, 0, 0, &xfer->dmabuf);
if (err)
return (err);
xfer->rqflags |= URQ_AUTO_DMABUF;
}
- if (!usbd_xfer_isread(xfer)) {
- if ((xfer->flags & USBD_NO_COPY) == 0)
- memcpy(KERNADDR(&xfer->dmabuf, 0), xfer->buffer,
- xfer->length);
- usb_syncmem(&xfer->dmabuf, 0, xfer->length,
- BUS_DMASYNC_PREWRITE);
- } else
- usb_syncmem(&xfer->dmabuf, 0, xfer->length,
- BUS_DMASYNC_PREREAD);
+ if (!usbd_xfer_isread(xfer) && (xfer->flags & USBD_NO_COPY) == 0)
+ memcpy(KERNADDR(&xfer->dmabuf, 0), xfer->buffer,
+ xfer->length);
usb_tap(bus, xfer, USBTAP_DIR_OUT);
@@ -750,17 +743,10 @@ usb_transfer_complete(struct usbd_xfer *xfer)
}
#endif
- if (xfer->actlen != 0) {
- if (usbd_xfer_isread(xfer)) {
- usb_syncmem(&xfer->dmabuf, 0, xfer->actlen,
- BUS_DMASYNC_POSTREAD);
- if (!(xfer->flags & USBD_NO_COPY))
- memcpy(xfer->buffer, KERNADDR(&xfer->dmabuf, 0),
- xfer->actlen);
- } else
- usb_syncmem(&xfer->dmabuf, 0, xfer->actlen,
- BUS_DMASYNC_POSTWRITE);
- }
+ if (usbd_xfer_isread(xfer) && xfer->actlen != 0 &&
+ (xfer->flags & USBD_NO_COPY) == 0)
+ memcpy(xfer->buffer, KERNADDR(&xfer->dmabuf, 0),
+ xfer->actlen);
/* if we allocated the buffer in usbd_transfer() we free it here. */
if (xfer->rqflags & URQ_AUTO_DMABUF) {
diff --git a/sys/dev/usb/xhci.c b/sys/dev/usb/xhci.c
index f98f9a0b8fe..2d65208f3db 100644
--- a/sys/dev/usb/xhci.c
+++ b/sys/dev/usb/xhci.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: xhci.c,v 1.113 2020/03/02 16:30:39 visa Exp $ */
+/* $OpenBSD: xhci.c,v 1.114 2020/04/03 20:11:47 patrick Exp $ */
/*
* Copyright (c) 2014-2015 Martin Pieuchot
@@ -851,6 +851,10 @@ xhci_event_xfer_generic(struct xhci_softc *sc, struct usbd_xfer *xfer,
else
xfer->actlen = xfer->length;
}
+ if (xfer->actlen)
+ usb_syncmem(&xfer->dmabuf, 0, xfer->actlen,
+ usbd_xfer_isread(xfer) ?
+ BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
xfer->status = USBD_NORMAL_COMPLETION;
break;
case XHCI_CODE_SHORT_XFER:
@@ -871,6 +875,10 @@ xhci_event_xfer_generic(struct xhci_softc *sc, struct usbd_xfer *xfer,
DEVNAME(sc), xfer, xx->index));
return (1);
}
+ if (xfer->actlen)
+ usb_syncmem(&xfer->dmabuf, 0, xfer->actlen,
+ usbd_xfer_isread(xfer) ?
+ BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
xfer->status = USBD_NORMAL_COMPLETION;
break;
case XHCI_CODE_TXERR:
@@ -975,6 +983,9 @@ xhci_event_xfer_isoc(struct usbd_xfer *xfer, struct xhci_pipe *xp,
xp->skip = 0;
}
+ usb_syncmem(&xfer->dmabuf, 0, xfer->length,
+ usbd_xfer_isread(xfer) ?
+ BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
xfer->status = USBD_NORMAL_COMPLETION;
return (0);
@@ -2809,6 +2820,11 @@ xhci_device_ctrl_start(struct usbd_xfer *xfer)
if (xp->free_trbs < 3)
return (USBD_NOMEM);
+ if (len != 0)
+ usb_syncmem(&xfer->dmabuf, 0, len,
+ usbd_xfer_isread(xfer) ?
+ BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
+
/* We'll toggle the setup TRB once we're finished with the stages. */
trb0 = xhci_xfer_get_trb(sc, xfer, &toggle, 0);
@@ -2935,6 +2951,10 @@ xhci_device_generic_start(struct usbd_xfer *xfer)
if (xp->free_trbs < (ntrb + zerotd))
return (USBD_NOMEM);
+ usb_syncmem(&xfer->dmabuf, 0, xfer->length,
+ usbd_xfer_isread(xfer) ?
+ BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
+
/* We'll toggle the first TRB once we're finished with the chain. */
trb0 = xhci_xfer_get_trb(sc, xfer, &toggle, (ntrb == 1));
flags = XHCI_TRB_TYPE_NORMAL | (toggle ^ 1);
@@ -3091,6 +3111,10 @@ xhci_device_isoc_start(struct usbd_xfer *xfer)
if (xp->free_trbs < ntrb)
return (USBD_NOMEM);
+ usb_syncmem(&xfer->dmabuf, 0, xfer->length,
+ usbd_xfer_isread(xfer) ?
+ BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
+
paddr = DMAADDR(&xfer->dmabuf, 0);
for (i = 0, trb0 = NULL; i < xfer->nframes; i++) {