Module Name:    src
Committed By:   skrll
Date:           Sun Apr  5 20:59:39 UTC 2020

Modified Files:
        src/sys/arch/mips/adm5120/dev: ahci.c
        src/sys/dev/usb: ehci.c ohci.c uhci.c usb_mem.c usb_mem.h usbdi.c
            xhci.c
        src/sys/external/bsd/dwc2: dwc2.c
        src/sys/external/bsd/dwc2/dist: dwc2_hcd.c dwc2_hcdddma.c

Log Message:
Switch USB to use non-coherent buffers for data transfers in the
same way as OpenBSD.

The use of coherent (uncacheable on ARM and other arches) mappings
for transfer buffers impacts performance, espcially where memcpys
are involved.

Audit the necessary usb_syncmem operations - a few were missing.


To generate a diff of this commit:
cvs rdiff -u -r1.21 -r1.22 src/sys/arch/mips/adm5120/dev/ahci.c
cvs rdiff -u -r1.277 -r1.278 src/sys/dev/usb/ehci.c
cvs rdiff -u -r1.300 -r1.301 src/sys/dev/usb/ohci.c
cvs rdiff -u -r1.299 -r1.300 src/sys/dev/usb/uhci.c
cvs rdiff -u -r1.75 -r1.76 src/sys/dev/usb/usb_mem.c
cvs rdiff -u -r1.31 -r1.32 src/sys/dev/usb/usb_mem.h
cvs rdiff -u -r1.199 -r1.200 src/sys/dev/usb/usbdi.c
cvs rdiff -u -r1.123 -r1.124 src/sys/dev/usb/xhci.c
cvs rdiff -u -r1.72 -r1.73 src/sys/external/bsd/dwc2/dwc2.c
cvs rdiff -u -r1.23 -r1.24 src/sys/external/bsd/dwc2/dist/dwc2_hcd.c
cvs rdiff -u -r1.8 -r1.9 src/sys/external/bsd/dwc2/dist/dwc2_hcdddma.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/mips/adm5120/dev/ahci.c
diff -u src/sys/arch/mips/adm5120/dev/ahci.c:1.21 src/sys/arch/mips/adm5120/dev/ahci.c:1.22
--- src/sys/arch/mips/adm5120/dev/ahci.c:1.21	Fri Feb 21 12:41:29 2020
+++ src/sys/arch/mips/adm5120/dev/ahci.c	Sun Apr  5 20:59:38 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: ahci.c,v 1.21 2020/02/21 12:41:29 skrll Exp $	*/
+/*	$NetBSD: ahci.c,v 1.22 2020/04/05 20:59:38 skrll Exp $	*/
 
 /*-
  * Copyright (c) 2007 Ruslan Ermilov and Vsevolod Lobko.
@@ -64,7 +64,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ahci.c,v 1.21 2020/02/21 12:41:29 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ahci.c,v 1.22 2020/04/05 20:59:38 skrll Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -879,7 +879,7 @@ ahci_device_ctrl_start(struct usbd_xfer 
 		td3 = (struct admhcd_td *)KSEG1ADDR(&td_v[3]);
 		err = usb_allocmem(&sc->sc_bus,
 			sizeof(usb_device_request_t),
-			0, &reqdma);
+			0, USBMALLOC_COHERENT, &reqdma);
 		if (err)
 			return USBD_NOMEM;
 
@@ -1259,6 +1259,10 @@ ahci_device_bulk_start(struct usbd_xfer 
 	segs = i;
 	len = 0;
 
+	if (xfer->ux_length)
+		usb_syncmem(&xfer->ux_dmabuf, 0, xfer->ux_length,
+		    isread ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
+
 /*	printf("segs: %d\n",segs);
 	printf("ep: %p\n",ep);
 	printf("ep->control: %x\n",ep->control);
@@ -1317,6 +1321,10 @@ ahci_device_bulk_start(struct usbd_xfer 
 	level--;
 /*	printf("bulk_start<<<\n"); */
 
+	if (xfer->ux_length)
+		usb_syncmem(&xfer->ux_dmabuf, 0, xfer->ux_length,
+		    isread ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
+
 	usb_transfer_complete(xfer);
 	mutex_exit(&sc->sc_lock);
 

Index: src/sys/dev/usb/ehci.c
diff -u src/sys/dev/usb/ehci.c:1.277 src/sys/dev/usb/ehci.c:1.278
--- src/sys/dev/usb/ehci.c:1.277	Sat Mar 14 02:35:33 2020
+++ src/sys/dev/usb/ehci.c	Sun Apr  5 20:59:38 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: ehci.c,v 1.277 2020/03/14 02:35:33 christos Exp $ */
+/*	$NetBSD: ehci.c,v 1.278 2020/04/05 20:59:38 skrll Exp $ */
 
 /*
  * Copyright (c) 2004-2012 The NetBSD Foundation, Inc.
@@ -53,7 +53,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.277 2020/03/14 02:35:33 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.278 2020/04/05 20:59:38 skrll Exp $");
 
 #include "ohci.h"
 #include "uhci.h"
@@ -517,7 +517,7 @@ ehci_init(ehci_softc_t *sc)
 	case 3: return EIO;
 	}
 	err = usb_allocmem(&sc->sc_bus, sc->sc_flsize * sizeof(ehci_link_t),
-	    EHCI_FLALIGN_ALIGN, &sc->sc_fldma);
+	    EHCI_FLALIGN_ALIGN, USBMALLOC_COHERENT, &sc->sc_fldma);
 	if (err)
 		return err;
 	DPRINTF("flsize=%jd", sc->sc_flsize, 0, 0, 0);
@@ -2003,7 +2003,7 @@ ehci_open(struct usbd_pipe *pipe)
 	switch (xfertype) {
 	case UE_CONTROL:
 		err = usb_allocmem(&sc->sc_bus, sizeof(usb_device_request_t),
-				   0, &epipe->ctrl.reqdma);
+		    0, USBMALLOC_COHERENT, &epipe->ctrl.reqdma);
 #ifdef EHCI_DEBUG
 		if (err)
 			printf("ehci_open: usb_allocmem()=%d\n", err);
@@ -2803,7 +2803,7 @@ ehci_alloc_sqh(ehci_softc_t *sc)
 		mutex_exit(&sc->sc_lock);
 
 		err = usb_allocmem(&sc->sc_bus, EHCI_SQH_SIZE * EHCI_SQH_CHUNK,
-			  EHCI_PAGE_SIZE, &dma);
+		    EHCI_PAGE_SIZE, USBMALLOC_COHERENT, &dma);
 #ifdef EHCI_DEBUG
 		if (err)
 			printf("ehci_alloc_sqh: usb_allocmem()=%d\n", err);
@@ -2856,7 +2856,7 @@ ehci_alloc_sqtd(ehci_softc_t *sc)
 		mutex_exit(&sc->sc_lock);
 
 		err = usb_allocmem(&sc->sc_bus, EHCI_SQTD_SIZE*EHCI_SQTD_CHUNK,
-			  EHCI_PAGE_SIZE, &dma);
+		    EHCI_PAGE_SIZE, USBMALLOC_COHERENT, &dma);
 #ifdef EHCI_DEBUG
 		if (err)
 			printf("ehci_alloc_sqtd: usb_allocmem()=%d\n", err);
@@ -3113,8 +3113,9 @@ ehci_alloc_itd(ehci_softc_t *sc)
 	if (freeitd == NULL) {
 		DPRINTF("allocating chunk", 0, 0, 0, 0);
 		mutex_exit(&sc->sc_lock);
+
 		err = usb_allocmem(&sc->sc_bus, EHCI_ITD_SIZE * EHCI_ITD_CHUNK,
-				EHCI_PAGE_SIZE, &dma);
+		    EHCI_PAGE_SIZE, USBMALLOC_COHERENT, &dma);
 
 		if (err) {
 			DPRINTF("alloc returned %jd", err, 0, 0, 0);
@@ -3161,8 +3162,9 @@ ehci_alloc_sitd(ehci_softc_t *sc)
 	if (freesitd == NULL) {
 		DPRINTF("allocating chunk", 0, 0, 0, 0);
 		mutex_exit(&sc->sc_lock);
+
 		err = usb_allocmem(&sc->sc_bus, EHCI_SITD_SIZE * EHCI_SITD_CHUNK,
-				EHCI_PAGE_SIZE, &dma);
+		    EHCI_PAGE_SIZE, USBMALLOC_COHERENT, &dma);
 
 		if (err) {
 			DPRINTF("alloc returned %jd", err, 0, 0,

Index: src/sys/dev/usb/ohci.c
diff -u src/sys/dev/usb/ohci.c:1.300 src/sys/dev/usb/ohci.c:1.301
--- src/sys/dev/usb/ohci.c:1.300	Sat Mar 14 02:35:33 2020
+++ src/sys/dev/usb/ohci.c	Sun Apr  5 20:59:38 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: ohci.c,v 1.300 2020/03/14 02:35:33 christos Exp $	*/
+/*	$NetBSD: ohci.c,v 1.301 2020/04/05 20:59:38 skrll Exp $	*/
 
 /*
  * Copyright (c) 1998, 2004, 2005, 2012 The NetBSD Foundation, Inc.
@@ -41,7 +41,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ohci.c,v 1.300 2020/03/14 02:35:33 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ohci.c,v 1.301 2020/04/05 20:59:38 skrll Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -409,7 +409,7 @@ ohci_alloc_sed(ohci_softc_t *sc)
 		mutex_exit(&sc->sc_lock);
 
 		err = usb_allocmem(&sc->sc_bus, OHCI_SED_SIZE * OHCI_SED_CHUNK,
-			  OHCI_ED_ALIGN, &dma);
+		    OHCI_ED_ALIGN, USBMALLOC_COHERENT, &dma);
 		if (err)
 			return 0;
 
@@ -468,7 +468,7 @@ ohci_alloc_std(ohci_softc_t *sc)
 		mutex_exit(&sc->sc_lock);
 
 		err = usb_allocmem(&sc->sc_bus, OHCI_STD_SIZE * OHCI_STD_CHUNK,
-			  OHCI_TD_ALIGN, &dma);
+		    OHCI_TD_ALIGN, USBMALLOC_COHERENT, &dma);
 		if (err)
 			return NULL;
 
@@ -712,7 +712,7 @@ ohci_alloc_sitd(ohci_softc_t *sc)
 		mutex_exit(&sc->sc_lock);
 
 		err = usb_allocmem(&sc->sc_bus, OHCI_SITD_SIZE * OHCI_SITD_CHUNK,
-			  OHCI_ITD_ALIGN, &dma);
+		    OHCI_ITD_ALIGN, USBMALLOC_COHERENT, &dma);
 		if (err)
 			return NULL;
 		mutex_enter(&sc->sc_lock);
@@ -815,7 +815,7 @@ ohci_init(ohci_softc_t *sc)
 	/* XXX determine alignment by R/W */
 	/* Allocate the HCCA area. */
 	err = usb_allocmem(&sc->sc_bus, OHCI_HCCA_SIZE,
-			 OHCI_HCCA_ALIGN, &sc->sc_hccadma);
+	    OHCI_HCCA_ALIGN, USBMALLOC_COHERENT, &sc->sc_hccadma);
 	if (err) {
 		sc->sc_hcca = NULL;
 		return err;
@@ -2081,8 +2081,8 @@ ohci_open(struct usbd_pipe *pipe)
 		case UE_CONTROL:
 			pipe->up_methods = &ohci_device_ctrl_methods;
 			err = usb_allocmem(&sc->sc_bus,
-				  sizeof(usb_device_request_t),
-				  0, &opipe->ctrl.reqdma);
+			    sizeof(usb_device_request_t), 0,
+			    USBMALLOC_COHERENT, &opipe->ctrl.reqdma);
 			if (err)
 				goto bad;
 			mutex_enter(&sc->sc_lock);
@@ -3460,6 +3460,12 @@ ohci_device_isoc_enter(struct usbd_xfer 
 	DPRINTFN(1, "used=%jd next=%jd xfer=%#jx nframes=%jd",
 	     isoc->inuse, isoc->next, (uintptr_t)xfer, xfer->ux_nframes);
 
+	int isread =
+	    (UE_GET_DIR(xfer->ux_pipe->up_endpoint->ue_edesc->bEndpointAddress) == UE_DIR_IN);
+
+	usb_syncmem(&xfer->ux_dmabuf, 0, xfer->ux_length,
+	    isread ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
+
 	if (isoc->next == -1) {
 		/* Not in use yet, schedule it a few frames ahead. */
 		isoc->next = O32TOH(sc->sc_hcca->hcca_frame_number) + 5;
@@ -3630,6 +3636,14 @@ ohci_device_isoc_done(struct usbd_xfer *
 {
 	OHCIHIST_FUNC(); OHCIHIST_CALLED();
 	DPRINTFN(1, "xfer=%#jx", (uintptr_t)xfer, 0, 0, 0);
+
+	int isread =
+	    (UE_GET_DIR(xfer->ux_pipe->up_endpoint->ue_edesc->bEndpointAddress) == UE_DIR_IN);
+
+	DPRINTFN(10, "xfer=%#jx, actlen=%jd", (uintptr_t)xfer, xfer->ux_actlen,
+	    0, 0);
+	usb_syncmem(&xfer->ux_dmabuf, 0, xfer->ux_length,
+	    isread ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
 }
 
 usbd_status

Index: src/sys/dev/usb/uhci.c
diff -u src/sys/dev/usb/uhci.c:1.299 src/sys/dev/usb/uhci.c:1.300
--- src/sys/dev/usb/uhci.c:1.299	Sun Mar 15 15:00:14 2020
+++ src/sys/dev/usb/uhci.c	Sun Apr  5 20:59:38 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: uhci.c,v 1.299 2020/03/15 15:00:14 skrll Exp $	*/
+/*	$NetBSD: uhci.c,v 1.300 2020/04/05 20:59:38 skrll Exp $	*/
 
 /*
  * Copyright (c) 1998, 2004, 2011, 2012 The NetBSD Foundation, Inc.
@@ -42,7 +42,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uhci.c,v 1.299 2020/03/15 15:00:14 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uhci.c,v 1.300 2020/04/05 20:59:38 skrll Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -456,7 +456,7 @@ uhci_init(uhci_softc_t *sc)
 	/* Allocate and initialize real frame array. */
 	err = usb_allocmem(&sc->sc_bus,
 	    UHCI_FRAMELIST_COUNT * sizeof(uhci_physaddr_t),
-	    UHCI_FRAMELIST_ALIGN, &sc->sc_dma);
+	    UHCI_FRAMELIST_ALIGN, USBMALLOC_COHERENT, &sc->sc_dma);
 	if (err)
 		return err;
 	sc->sc_pframes = KERNADDR(&sc->sc_dma, 0);
@@ -1847,7 +1847,7 @@ uhci_alloc_std(uhci_softc_t *sc)
 		mutex_exit(&sc->sc_lock);
 
 		err = usb_allocmem(&sc->sc_bus, UHCI_STD_SIZE * UHCI_STD_CHUNK,
-			  UHCI_TD_ALIGN, &dma);
+		    UHCI_TD_ALIGN, USBMALLOC_COHERENT, &dma);
 		if (err)
 			return NULL;
 
@@ -1914,7 +1914,7 @@ uhci_alloc_sqh(uhci_softc_t *sc)
 		mutex_exit(&sc->sc_lock);
 
 		err = usb_allocmem(&sc->sc_bus, UHCI_SQH_SIZE * UHCI_SQH_CHUNK,
-			  UHCI_QH_ALIGN, &dma);
+		    UHCI_QH_ALIGN, USBMALLOC_COHERENT, &dma);
 		if (err)
 			return NULL;
 
@@ -2201,7 +2201,6 @@ uhci_device_bulk_init(struct usbd_xfer *
 	int len = xfer->ux_bufsize;
 	int err = 0;
 
-
 	UHCIHIST_FUNC(); UHCIHIST_CALLED();
 	DPRINTFN(3, "xfer=%#jx len=%jd flags=%jd", (uintptr_t)xfer, len,
 	    xfer->ux_flags, 0);
@@ -2919,6 +2918,9 @@ uhci_device_isoc_transfer(struct usbd_xf
 
 	KASSERT(xfer->ux_nframes != 0);
 
+	usb_syncmem(&xfer->ux_dmabuf, 0, xfer->ux_length,
+	    rd ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
+
 	mutex_enter(&sc->sc_lock);
 	next = isoc->next;
 	if (next == -1) {
@@ -3482,8 +3484,8 @@ uhci_open(struct usbd_pipe *pipe)
 				goto bad;
 			}
 			err = usb_allocmem(&sc->sc_bus,
-				  sizeof(usb_device_request_t),
-				  0, &upipe->ctrl.reqdma);
+			    sizeof(usb_device_request_t), 0,
+			    USBMALLOC_COHERENT, &upipe->ctrl.reqdma);
 			if (err) {
 				uhci_free_sqh(sc, upipe->ctrl.sqh);
 				uhci_free_std(sc, upipe->ctrl.setup);

Index: src/sys/dev/usb/usb_mem.c
diff -u src/sys/dev/usb/usb_mem.c:1.75 src/sys/dev/usb/usb_mem.c:1.76
--- src/sys/dev/usb/usb_mem.c:1.75	Sun Mar 15 14:19:04 2020
+++ src/sys/dev/usb/usb_mem.c	Sun Apr  5 20:59:38 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: usb_mem.c,v 1.75 2020/03/15 14:19:04 skrll Exp $	*/
+/*	$NetBSD: usb_mem.c,v 1.76 2020/04/05 20:59:38 skrll Exp $	*/
 
 /*
  * Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -38,7 +38,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: usb_mem.c,v 1.75 2020/03/15 14:19:04 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: usb_mem.c,v 1.76 2020/04/05 20:59:38 skrll Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -75,7 +75,7 @@ struct usb_frag_dma {
 };
 
 Static usbd_status	usb_block_allocmem(bus_dma_tag_t, size_t, size_t,
-					   usb_dma_block_t **, bool);
+			    u_int, usb_dma_block_t **);
 Static void		usb_block_freemem(usb_dma_block_t *);
 
 LIST_HEAD(usb_dma_block_qh, usb_dma_block);
@@ -106,24 +106,31 @@ usb_mem_init(void)
 
 Static usbd_status
 usb_block_allocmem(bus_dma_tag_t tag, size_t size, size_t align,
-		   usb_dma_block_t **dmap, bool multiseg)
+    u_int flags, usb_dma_block_t **dmap)
 {
 	usb_dma_block_t *b;
 	int error;
 
 	USBHIST_FUNC();
-	USBHIST_CALLARGS(usbdebug, "size=%ju align=%ju", size, align, 0, 0);
+	USBHIST_CALLARGS(usbdebug, "size=%ju align=%ju flags=%#jx", size, align, flags, 0);
 
 	ASSERT_SLEEPABLE();
 	KASSERT(size != 0);
 	KASSERT(mutex_owned(&usb_blk_lock));
 
+	bool multiseg = (flags & USBMALLOC_MULTISEG) != 0;
+	bool coherent = (flags & USBMALLOC_COHERENT) != 0;
+	u_int dmaflags = coherent ? USB_DMA_COHERENT : 0;
+
 	/* First check the free list. */
 	LIST_FOREACH(b, &usb_blk_freelist, next) {
 		/* Don't allocate multiple segments to unwilling callers */
 		if (b->nsegs != 1 && !multiseg)
 			continue;
-		if (b->tag == tag && b->size >= size && b->align >= align) {
+		if (b->tag == tag &&
+		    b->size >= size &&
+		    b->align >= align &&
+		    (b->flags & USB_DMA_COHERENT) == dmaflags) {
 			LIST_REMOVE(b, next);
 			usb_blk_nfree--;
 			*dmap = b;
@@ -139,6 +146,7 @@ usb_block_allocmem(bus_dma_tag_t tag, si
 	b->tag = tag;
 	b->size = size;
 	b->align = align;
+	b->flags = dmaflags;
 
 	if (!multiseg)
 		/* Caller wants one segment */
@@ -155,8 +163,8 @@ usb_block_allocmem(bus_dma_tag_t tag, si
 	if (error)
 		goto free0;
 
-	error = bus_dmamem_map(tag, b->segs, b->nsegs, b->size,
-			       &b->kaddr, BUS_DMA_WAITOK|BUS_DMA_COHERENT);
+	error = bus_dmamem_map(tag, b->segs, b->nsegs, b->size, &b->kaddr,
+	    BUS_DMA_WAITOK | (coherent ? BUS_DMA_COHERENT : 0));
 	if (error)
 		goto free1;
 
@@ -245,15 +253,8 @@ usb_block_freemem(usb_dma_block_t *b)
 }
 
 usbd_status
-usb_allocmem(struct usbd_bus *bus, size_t size, size_t align, usb_dma_t *p)
-{
-
-	return usb_allocmem_flags(bus, size, align, p, 0);
-}
-
-usbd_status
-usb_allocmem_flags(struct usbd_bus *bus, size_t size, size_t align, usb_dma_t *p,
-		   int flags)
+usb_allocmem(struct usbd_bus *bus, size_t size, size_t align, u_int flags,
+    usb_dma_t *p)
 {
 	bus_dma_tag_t tag = bus->ub_dmatag;
 	usbd_status err;
@@ -261,7 +262,6 @@ usb_allocmem_flags(struct usbd_bus *bus,
 	usb_dma_block_t *b;
 	int i;
 	static ONCE_DECL(init_control);
-	bool frag;
 
 	USBHIST_FUNC(); USBHIST_CALLED(usbdebug);
 
@@ -269,19 +269,20 @@ usb_allocmem_flags(struct usbd_bus *bus,
 
 	RUN_ONCE(&init_control, usb_mem_init);
 
-	frag = (flags & USBMALLOC_MULTISEG);
+	u_int dmaflags = (flags & USBMALLOC_COHERENT) ? USB_DMA_COHERENT : 0;
 
 	/* If the request is large then just use a full block. */
 	if (size > USB_MEM_SMALL || align > USB_MEM_SMALL) {
 		DPRINTFN(1, "large alloc %jd", size, 0, 0, 0);
 		size = (size + USB_MEM_BLOCK - 1) & ~(USB_MEM_BLOCK - 1);
 		mutex_enter(&usb_blk_lock);
-		err = usb_block_allocmem(tag, size, align, &p->udma_block, frag);
+		err = usb_block_allocmem(tag, size, align, flags,
+		    &p->udma_block);
 		if (!err) {
 #ifdef DEBUG
 			LIST_INSERT_HEAD(&usb_blk_fulllist, p->udma_block, next);
 #endif
-			p->udma_block->flags = USB_DMA_FULLBLOCK;
+			p->udma_block->flags = USB_DMA_FULLBLOCK | dmaflags;
 			p->udma_offs = 0;
 		}
 		mutex_exit(&usb_blk_lock);
@@ -294,13 +295,15 @@ usb_allocmem_flags(struct usbd_bus *bus,
 		KDASSERTMSG(usb_valid_block_p(f->ufd_block, &usb_blk_fraglist),
 		    "%s: usb frag %p: unknown block pointer %p",
 		    __func__, f, f->ufd_block);
-		if (f->ufd_block->tag == tag)
+		if (f->ufd_block->tag == tag &&
+		    (f->ufd_block->flags & USB_DMA_COHERENT) == dmaflags)
 			break;
 	}
 	if (f == NULL) {
 		DPRINTFN(1, "adding fragments", 0, 0, 0, 0);
-		err = usb_block_allocmem(tag, USB_MEM_BLOCK, USB_MEM_SMALL, &b,
-					 false);
+
+		err = usb_block_allocmem(tag, USB_MEM_BLOCK, USB_MEM_SMALL,
+		    flags, &b);
 		if (err) {
 			mutex_exit(&usb_blk_lock);
 			return err;
@@ -406,6 +409,6 @@ void
 usb_syncmem(usb_dma_t *p, bus_addr_t offset, bus_size_t len, int ops)
 {
 
-	bus_dmamap_sync(p->udma_block->tag, p->udma_block->map, p->udma_offs + offset,
-	    len, ops);
+	bus_dmamap_sync(p->udma_block->tag, p->udma_block->map,
+	    p->udma_offs + offset, len, ops);
 }

Index: src/sys/dev/usb/usb_mem.h
diff -u src/sys/dev/usb/usb_mem.h:1.31 src/sys/dev/usb/usb_mem.h:1.32
--- src/sys/dev/usb/usb_mem.h:1.31	Sat Apr 23 10:15:32 2016
+++ src/sys/dev/usb/usb_mem.h	Sun Apr  5 20:59:38 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: usb_mem.h,v 1.31 2016/04/23 10:15:32 skrll Exp $	*/
+/*	$NetBSD: usb_mem.h,v 1.32 2020/04/05 20:59:38 skrll Exp $	*/
 /*	$FreeBSD: src/sys/dev/usb/usb_mem.h,v 1.9 1999/11/17 22:33:47 n_hibma Exp $	*/
 
 /*
@@ -41,15 +41,16 @@ typedef struct usb_dma_block {
 	size_t size;
 	size_t align;
 	int flags;
-#define USB_DMA_FULLBLOCK	0x0001
+#define USB_DMA_FULLBLOCK	__BIT(0)
+#define USB_DMA_COHERENT	__BIT(1)
+
 	LIST_ENTRY(usb_dma_block) next;
 } usb_dma_block_t;
 
-#define USBMALLOC_MULTISEG	1
+#define USBMALLOC_MULTISEG	__BIT(0)
+#define USBMALLOC_COHERENT	__BIT(1)
 
-usbd_status	usb_allocmem(struct usbd_bus *, size_t, size_t, usb_dma_t *);
-usbd_status	usb_allocmem_flags(struct usbd_bus *, size_t, size_t, usb_dma_t *,
-			int);
+usbd_status	usb_allocmem(struct usbd_bus *, size_t, size_t, u_int, usb_dma_t *);
 void		usb_freemem(struct usbd_bus *, usb_dma_t *);
 void		usb_syncmem(usb_dma_t *, bus_addr_t, bus_size_t, int);
 

Index: src/sys/dev/usb/usbdi.c
diff -u src/sys/dev/usb/usbdi.c:1.199 src/sys/dev/usb/usbdi.c:1.200
--- src/sys/dev/usb/usbdi.c:1.199	Fri Apr  3 06:05:00 2020
+++ src/sys/dev/usb/usbdi.c	Sun Apr  5 20:59:38 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: usbdi.c,v 1.199 2020/04/03 06:05:00 skrll Exp $	*/
+/*	$NetBSD: usbdi.c,v 1.200 2020/04/05 20:59:38 skrll Exp $	*/
 
 /*
  * Copyright (c) 1998, 2012, 2015 The NetBSD Foundation, Inc.
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: usbdi.c,v 1.199 2020/04/03 06:05:00 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: usbdi.c,v 1.200 2020/04/05 20:59:38 skrll Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -478,7 +478,8 @@ usbd_alloc_buffer(struct usbd_xfer *xfer
 	if (bus->ub_usedma) {
 		usb_dma_t *dmap = &xfer->ux_dmabuf;
 
-		int err = usb_allocmem_flags(bus, size, 0, dmap, bus->ub_dmaflags);
+		KASSERT((bus->ub_dmaflags & USBMALLOC_COHERENT) == 0);
+		int err = usb_allocmem(bus, size, 0, bus->ub_dmaflags, dmap);
 		if (err) {
 			return NULL;
 		}

Index: src/sys/dev/usb/xhci.c
diff -u src/sys/dev/usb/xhci.c:1.123 src/sys/dev/usb/xhci.c:1.124
--- src/sys/dev/usb/xhci.c:1.123	Thu Apr  2 11:37:23 2020
+++ src/sys/dev/usb/xhci.c	Sun Apr  5 20:59:38 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: xhci.c,v 1.123 2020/04/02 11:37:23 skrll Exp $	*/
+/*	$NetBSD: xhci.c,v 1.124 2020/04/05 20:59:38 skrll Exp $	*/
 
 /*
  * Copyright (c) 2013 Jonathan A. Kollasch
@@ -34,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: xhci.c,v 1.123 2020/04/02 11:37:23 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xhci.c,v 1.124 2020/04/05 20:59:38 skrll Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -1069,7 +1069,7 @@ xhci_init(struct xhci_softc *sc)
 	if (sc->sc_maxspbuf != 0) {
 		err = usb_allocmem(&sc->sc_bus,
 		    sizeof(uint64_t) * sc->sc_maxspbuf, sizeof(uint64_t),
-		    &sc->sc_spbufarray_dma);
+		    USBMALLOC_COHERENT, &sc->sc_spbufarray_dma);
 		if (err) {
 			aprint_error_dev(sc->sc_dev,
 			    "spbufarray init fail, err %d\n", err);
@@ -1083,7 +1083,7 @@ xhci_init(struct xhci_softc *sc)
 			usb_dma_t * const dma = &sc->sc_spbuf_dma[i];
 			/* allocate contexts */
 			err = usb_allocmem(&sc->sc_bus, sc->sc_pgsz,
-			    sc->sc_pgsz, dma);
+			    sc->sc_pgsz, USBMALLOC_COHERENT, dma);
 			if (err) {
 				aprint_error_dev(sc->sc_dev,
 				    "spbufarray_dma init fail, err %d\n", err);
@@ -1131,7 +1131,7 @@ xhci_init(struct xhci_softc *sc)
 	    XHCI_EVENT_RING_SEGMENT_TABLE_ALIGN);
 	KASSERTMSG(size <= (512 * 1024), "eventst size %zu too large", size);
 	align = XHCI_EVENT_RING_SEGMENT_TABLE_ALIGN;
-	err = usb_allocmem(&sc->sc_bus, size, align, dma);
+	err = usb_allocmem(&sc->sc_bus, size, align, USBMALLOC_COHERENT, dma);
 	if (err) {
 		aprint_error_dev(sc->sc_dev, "eventst init fail, err %d\n",
 		    err);
@@ -1150,7 +1150,7 @@ xhci_init(struct xhci_softc *sc)
 	size = (1 + sc->sc_maxslots) * sizeof(uint64_t);
 	KASSERTMSG(size <= 2048, "dcbaa size %zu too large", size);
 	align = XHCI_DEVICE_CONTEXT_BASE_ADDRESS_ARRAY_ALIGN;
-	err = usb_allocmem(&sc->sc_bus, size, align, dma);
+	err = usb_allocmem(&sc->sc_bus, size, align, USBMALLOC_COHERENT, dma);
 	if (err) {
 		aprint_error_dev(sc->sc_dev, "dcbaa init fail, err %d\n", err);
 		rv = ENOMEM;
@@ -2529,7 +2529,8 @@ xhci_ring_init(struct xhci_softc * const
 	xr = kmem_zalloc(sizeof(struct xhci_ring), KM_SLEEP);
 	DPRINTFN(1, "ring %#jx", (uintptr_t)xr, 0, 0, 0);
 
-	err = usb_allocmem(&sc->sc_bus, size, align, &xr->xr_dma);
+	err = usb_allocmem(&sc->sc_bus, size, align, USBMALLOC_COHERENT,
+	    &xr->xr_dma);
 	if (err) {
 		kmem_free(xr, sizeof(struct xhci_ring));
 		DPRINTFN(1, "alloc xr_dma failed %jd", err, 0, 0, 0);
@@ -2959,7 +2960,7 @@ xhci_init_slot(struct usbd_device *dev, 
 
 	/* allocate contexts */
 	err = usb_allocmem(&sc->sc_bus, sc->sc_pgsz, sc->sc_pgsz,
-	    &xs->xs_dc_dma);
+	    USBMALLOC_COHERENT, &xs->xs_dc_dma);
 	if (err) {
 		DPRINTFN(1, "failed to allocmem output device context %jd",
 		    err, 0, 0, 0);
@@ -2968,7 +2969,7 @@ xhci_init_slot(struct usbd_device *dev, 
 	memset(KERNADDR(&xs->xs_dc_dma, 0), 0, sc->sc_pgsz);
 
 	err = usb_allocmem(&sc->sc_bus, sc->sc_pgsz, sc->sc_pgsz,
-	    &xs->xs_ic_dma);
+	    USBMALLOC_COHERENT, &xs->xs_ic_dma);
 	if (err) {
 		DPRINTFN(1, "failed to allocmem input device context %jd",
 		    err, 0, 0, 0);
@@ -3844,7 +3845,7 @@ xhci_device_ctrl_start(struct usbd_xfer 
 	struct xhci_ring * const tr = xs->xs_xr[dci];
 	struct xhci_xfer * const xx = XHCI_XFER2XXFER(xfer);
 	usb_device_request_t * const req = &xfer->ux_request;
-	const int isread = usbd_xfer_isread(xfer);
+	const bool isread = usbd_xfer_isread(xfer);
 	const uint32_t len = UGETW(req->wLength);
 	usb_dma_t * const dma = &xfer->ux_dmabuf;
 	uint64_t parameter;
@@ -3885,9 +3886,12 @@ xhci_device_ctrl_start(struct usbd_xfer 
 		    XHCI_TRB_2_BYTES_SET(len);
 		control = (isread ? XHCI_TRB_3_DIR_IN : 0) |
 		    XHCI_TRB_3_TYPE_SET(XHCI_TRB_TYPE_DATA_STAGE) |
-		    (usbd_xfer_isread(xfer) ? XHCI_TRB_3_ISP_BIT : 0) |
+		    (isread ? XHCI_TRB_3_ISP_BIT : 0) |
 		    XHCI_TRB_3_IOC_BIT;
 		xhci_soft_trb_put(&xx->xx_trb[i++], parameter, status, control);
+
+		usb_syncmem(dma, 0, len,
+		    isread ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
 	}
 
 	parameter = 0;
@@ -3998,6 +4002,11 @@ xhci_device_bulk_start(struct usbd_xfer 
 	KASSERT((xfer->ux_rqflags & URQ_REQUEST) == 0);
 
 	parameter = DMAADDR(dma, 0);
+	const bool isread = usbd_xfer_isread(xfer);
+	if (len)
+		usb_syncmem(dma, 0, len,
+		    isread ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
+
 	/*
 	 * XXX: (dsl) The physical buffer must not cross a 64k boundary.
 	 * If the user supplied buffer crosses such a boundary then 2
@@ -4014,7 +4023,7 @@ xhci_device_bulk_start(struct usbd_xfer 
 	    XHCI_TRB_2_TDSZ_SET(0) |
 	    XHCI_TRB_2_BYTES_SET(len);
 	control = XHCI_TRB_3_TYPE_SET(XHCI_TRB_TYPE_NORMAL) |
-	    (usbd_xfer_isread(xfer) ? XHCI_TRB_3_ISP_BIT : 0) |
+	    (isread ? XHCI_TRB_3_ISP_BIT : 0) |
 	    XHCI_TRB_3_IOC_BIT;
 	xhci_soft_trb_put(&xx->xx_trb[i++], parameter, status, control);
 
@@ -4042,7 +4051,7 @@ xhci_device_bulk_done(struct usbd_xfer *
 	struct xhci_slot * const xs = xfer->ux_pipe->up_dev->ud_hcpriv;
 	const u_int dci = xhci_ep_get_dci(xfer->ux_pipe->up_endpoint->ue_edesc);
 #endif
-	const int isread = usbd_xfer_isread(xfer);
+	const bool isread = usbd_xfer_isread(xfer);
 
 	XHCIHIST_FUNC();
 	XHCIHIST_CALLARGS("%#jx slot %ju dci %ju",
@@ -4118,14 +4127,18 @@ xhci_device_intr_start(struct usbd_xfer 
 
 	KASSERT((xfer->ux_rqflags & URQ_REQUEST) == 0);
 
+	const bool isread = usbd_xfer_isread(xfer);
+	if (len)
+		usb_syncmem(dma, 0, len,
+		    isread ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
+
 	parameter = DMAADDR(dma, 0);
 	KASSERTMSG(len <= 0x10000, "len %d", len);
 	status = XHCI_TRB_2_IRQ_SET(0) |
 	    XHCI_TRB_2_TDSZ_SET(0) |
 	    XHCI_TRB_2_BYTES_SET(len);
 	control = XHCI_TRB_3_TYPE_SET(XHCI_TRB_TYPE_NORMAL) |
-	    (usbd_xfer_isread(xfer) ? XHCI_TRB_3_ISP_BIT : 0) |
-	    XHCI_TRB_3_IOC_BIT;
+	    (isread ? XHCI_TRB_3_ISP_BIT : 0) | XHCI_TRB_3_IOC_BIT;
 	xhci_soft_trb_put(&xx->xx_trb[i++], parameter, status, control);
 
 	if (!polling)
@@ -4153,7 +4166,7 @@ xhci_device_intr_done(struct usbd_xfer *
 	struct xhci_slot * const xs = xfer->ux_pipe->up_dev->ud_hcpriv;
 	const u_int dci = xhci_ep_get_dci(xfer->ux_pipe->up_endpoint->ue_edesc);
 #endif
-	const int isread = usbd_xfer_isread(xfer);
+	const bool isread = usbd_xfer_isread(xfer);
 
 	XHCIHIST_FUNC();
 	XHCIHIST_CALLARGS("%#jx slot %ju dci %ju",

Index: src/sys/external/bsd/dwc2/dwc2.c
diff -u src/sys/external/bsd/dwc2/dwc2.c:1.72 src/sys/external/bsd/dwc2/dwc2.c:1.73
--- src/sys/external/bsd/dwc2/dwc2.c:1.72	Fri Feb 21 12:41:29 2020
+++ src/sys/external/bsd/dwc2/dwc2.c	Sun Apr  5 20:59:38 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: dwc2.c,v 1.72 2020/02/21 12:41:29 skrll Exp $	*/
+/*	$NetBSD: dwc2.c,v 1.73 2020/04/05 20:59:38 skrll Exp $	*/
 
 /*-
  * Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: dwc2.c,v 1.72 2020/02/21 12:41:29 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: dwc2.c,v 1.73 2020/04/05 20:59:38 skrll Exp $");
 
 #include "opt_usb.h"
 
@@ -405,7 +405,7 @@ dwc2_open(struct usbd_pipe *pipe)
 	case UE_CONTROL:
 		pipe->up_methods = &dwc2_device_ctrl_methods;
 		err = usb_allocmem(&sc->sc_bus, sizeof(usb_device_request_t),
-		    0, &dpipe->req_dma);
+		    0, USBMALLOC_COHERENT, &dpipe->req_dma);
 		if (err)
 			return err;
 		break;

Index: src/sys/external/bsd/dwc2/dist/dwc2_hcd.c
diff -u src/sys/external/bsd/dwc2/dist/dwc2_hcd.c:1.23 src/sys/external/bsd/dwc2/dist/dwc2_hcd.c:1.24
--- src/sys/external/bsd/dwc2/dist/dwc2_hcd.c:1.23	Sun Jul 14 13:55:43 2019
+++ src/sys/external/bsd/dwc2/dist/dwc2_hcd.c	Sun Apr  5 20:59:38 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: dwc2_hcd.c,v 1.23 2019/07/14 13:55:43 mlelstv Exp $	*/
+/*	$NetBSD: dwc2_hcd.c,v 1.24 2020/04/05 20:59:38 skrll Exp $	*/
 
 /*
  * hcd.c - DesignWare HS OTG Controller host-mode routines
@@ -42,7 +42,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: dwc2_hcd.c,v 1.23 2019/07/14 13:55:43 mlelstv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: dwc2_hcd.c,v 1.24 2020/04/05 20:59:38 skrll Exp $");
 
 #include <sys/types.h>
 #include <sys/kmem.h>
@@ -733,7 +733,7 @@ static int dwc2_hc_setup_align_buf(struc
 		qh->dw_align_buf = NULL;
 		qh->dw_align_buf_dma = 0;
 		err = usb_allocmem(&hsotg->hsotg_sc->sc_bus, buf_size, 0,
-				   &qh->dw_align_buf_usbdma);
+		    USBMALLOC_COHERENT, &qh->dw_align_buf_usbdma);
 		if (!err) {
 			usb_dma_t *ud = &qh->dw_align_buf_usbdma;
 
@@ -2392,8 +2392,8 @@ int dwc2_hcd_init(struct dwc2_hsotg *hso
 	hsotg->status_buf = NULL;
 	if (hsotg->core_params->dma_enable > 0) {
 		retval = usb_allocmem(&hsotg->hsotg_sc->sc_bus,
-				      DWC2_HCD_STATUS_BUF_SIZE, 0,
-				      &hsotg->status_buf_usbdma);
+		    DWC2_HCD_STATUS_BUF_SIZE, 0, USBMALLOC_COHERENT,
+		    &hsotg->status_buf_usbdma);
 		if (!retval) {
 			hsotg->status_buf = KERNADDR(&hsotg->status_buf_usbdma, 0);
 			hsotg->status_buf_dma = DMAADDR(&hsotg->status_buf_usbdma, 0);

Index: src/sys/external/bsd/dwc2/dist/dwc2_hcdddma.c
diff -u src/sys/external/bsd/dwc2/dist/dwc2_hcdddma.c:1.8 src/sys/external/bsd/dwc2/dist/dwc2_hcdddma.c:1.9
--- src/sys/external/bsd/dwc2/dist/dwc2_hcdddma.c:1.8	Wed Feb 24 22:14:39 2016
+++ src/sys/external/bsd/dwc2/dist/dwc2_hcdddma.c	Sun Apr  5 20:59:38 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: dwc2_hcdddma.c,v 1.8 2016/02/24 22:14:39 skrll Exp $	*/
+/*	$NetBSD: dwc2_hcdddma.c,v 1.9 2020/04/05 20:59:38 skrll Exp $	*/
 
 /*
  * hcd_ddma.c - DesignWare HS OTG Controller descriptor DMA routines
@@ -40,7 +40,7 @@
  * This file contains the Descriptor DMA implementation for Host mode
  */
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: dwc2_hcdddma.c,v 1.8 2016/02/24 22:14:39 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: dwc2_hcdddma.c,v 1.9 2020/04/05 20:59:38 skrll Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -106,7 +106,7 @@ static int dwc2_desc_list_alloc(struct d
 						dwc2_max_desc_num(qh);
 
 	err = usb_allocmem(&hsotg->hsotg_sc->sc_bus, qh->desc_list_sz, 0,
-	    &qh->desc_list_usbdma);
+	    USBMALLOC_COHERENT, &qh->desc_list_usbdma);
 
 	if (err)
 		return -ENOMEM;
@@ -147,7 +147,7 @@ static int dwc2_frame_list_alloc(struct 
 	hsotg->frame_list_sz = 4 * FRLISTEN_64_SIZE;
 	hsotg->frame_list = NULL;
 	err = usb_allocmem(&hsotg->hsotg_sc->sc_bus, hsotg->frame_list_sz,
-	    0, &hsotg->frame_list_usbdma);
+	    0, USBMALLOC_COHERENT, &hsotg->frame_list_usbdma);
 
 	if (!err) {
 		hsotg->frame_list = KERNADDR(&hsotg->frame_list_usbdma, 0);

Reply via email to