From 6d4235c7941e4ca86c85161a1d065e64291d6055 Mon Sep 17 00:00:00 2001 From: Romain Dolbeau Date: Fri, 18 Dec 2020 09:38:09 -0500 Subject: [PATCH] only alloc/map/load once per write() --- NetBSD/9.0/usr/src/sys/dev/sbus/rdfpga.c | 64 +++++++++++++----------- 1 file changed, 34 insertions(+), 30 deletions(-) diff --git a/NetBSD/9.0/usr/src/sys/dev/sbus/rdfpga.c b/NetBSD/9.0/usr/src/sys/dev/sbus/rdfpga.c index 22906f1..160fb12 100644 --- a/NetBSD/9.0/usr/src/sys/dev/sbus/rdfpga.c +++ b/NetBSD/9.0/usr/src/sys/dev/sbus/rdfpga.c @@ -158,6 +158,7 @@ rdfpga_close(dev_t dev, int flags, int mode, struct lwp *l) return (0); } +#define MAX_DMA_SZ 4096 int rdfpga_write(dev_t dev, struct uio *uio, int flags) { @@ -166,6 +167,35 @@ rdfpga_write(dev_t dev, struct uio *uio, int flags) aprint_normal_dev(sc->sc_dev, "dma uio: %zu in %d\n", uio->uio_resid, uio->uio_iovcnt); + if (uio->uio_resid >= 16 && uio->uio_iovcnt == 1) { + bus_dma_segment_t segs; + int rsegs; + if (bus_dmamem_alloc(sc->sc_dmatag, MAX_DMA_SZ, 64, 64, &segs, 1, &rsegs, BUS_DMA_NOWAIT | BUS_DMA_STREAMING)) { + aprint_error_dev(sc->sc_dev, "cannot allocate DVMA memory"); + return ENXIO; + } + /* else { */ + /* aprint_normal_dev(sc->sc_dev, "dmamem alloc: %d\n", rsegs); */ + /* } */ + + void* kvap; + if (bus_dmamem_map(sc->sc_dmatag, &segs, 1, MAX_DMA_SZ, &kvap, BUS_DMA_NOWAIT)) { + aprint_error_dev(sc->sc_dev, "cannot allocate DVMA address"); + return ENXIO; + } + /* else { */ + /* aprint_normal_dev(sc->sc_dev, "dmamem map: %p\n", kvap); */ + /* } */ + + if (bus_dmamap_load(sc->sc_dmatag, sc->sc_dmamap, kvap, MAX_DMA_SZ, /* kernel space */ NULL, + BUS_DMA_NOWAIT | BUS_DMA_STREAMING | BUS_DMA_WRITE)) { + aprint_error_dev(sc->sc_dev, "cannot load dma map"); + return ENXIO; + } + /* else { */ + /* aprint_normal_dev(sc->sc_dev, "dmamap: %lu %lu %d\n", sc->sc_dmamap->dm_maxsegsz, sc->sc_dmamap->dm_mapsize, sc->sc_dmamap->dm_nsegs); */ + /* } */ + while (!error && uio->uio_resid >= 16 && uio->uio_iovcnt == 1) { uint64_t ctrl; uint32_t nblock = uio->uio_resid/16; @@ -193,40 +223,13 @@ rdfpga_write(dev_t dev, struct uio *uio, int flags) /* } */ /* aprint_normal_dev(sc->sc_dev, "dmamem about to alloc for %d blocks...\n", nblock); */ - - bus_dma_segment_t segs; - int rsegs; - if (bus_dmamem_alloc(sc->sc_dmatag, nblock*16, 64, 64, &segs, 1, &rsegs, BUS_DMA_NOWAIT | BUS_DMA_STREAMING)) { - aprint_error_dev(sc->sc_dev, "cannot allocate DVMA memory"); - return ENXIO; - } - /* else { */ - /* aprint_normal_dev(sc->sc_dev, "dmamem alloc: %d\n", rsegs); */ - /* } */ - - void* kvap; - if (bus_dmamem_map(sc->sc_dmatag, &segs, 1, nblock*16, &kvap, BUS_DMA_NOWAIT)) { - aprint_error_dev(sc->sc_dev, "cannot allocate DVMA address"); - return ENXIO; - } - /* else { */ - /* aprint_normal_dev(sc->sc_dev, "dmamem map: %p\n", kvap); */ - /* } */ + if ((error = uiomove(kvap, nblock*16, uio)) != 0) break; /* aprint_normal_dev(sc->sc_dev, "uimove: left %zu in %d\n", uio->uio_resid, uio->uio_iovcnt); */ - if (bus_dmamap_load(sc->sc_dmatag, sc->sc_dmamap, kvap, nblock*16, /* kernel space */ NULL, - BUS_DMA_NOWAIT | BUS_DMA_STREAMING | BUS_DMA_WRITE)) { - aprint_error_dev(sc->sc_dev, "cannot load dma map"); - return ENXIO; - } - /* else { */ - /* aprint_normal_dev(sc->sc_dev, "dmamap: %lu %lu %d\n", sc->sc_dmamap->dm_maxsegsz, sc->sc_dmamap->dm_mapsize, sc->sc_dmamap->dm_nsegs); */ - /* } */ - bus_dmamap_sync(sc->sc_dmatag, sc->sc_dmamap, 0, nblock*16, BUS_DMASYNC_PREWRITE); /* aprint_normal_dev(sc->sc_dev, "dma: synced\n"); */ @@ -255,11 +258,13 @@ rdfpga_write(dev_t dev, struct uio *uio, int flags) /* if (sc->sc_dmamap->dm_nsegs > 0) { */ bus_dmamap_sync(sc->sc_dmatag, sc->sc_dmamap, 0, nblock*16, BUS_DMASYNC_POSTWRITE); /* aprint_normal_dev(sc->sc_dev, "dma: synced (2)\n"); */ + } + bus_dmamap_unload(sc->sc_dmatag, sc->sc_dmamap); /* aprint_normal_dev(sc->sc_dev, "dma: unloaded\n"); */ - bus_dmamem_unmap(sc->sc_dmatag, kvap, nblock*16); + bus_dmamem_unmap(sc->sc_dmatag, kvap, MAX_DMA_SZ); /* aprint_normal_dev(sc->sc_dev, "dma: unmapped\n"); */ bus_dmamem_free(sc->sc_dmatag, &segs, 1); @@ -356,7 +361,6 @@ rdfpga_attach(device_t parent, device_t self, void *aux) /* DMA */ /* Allocate a dmamap */ -#define MAX_DMA_SZ 4096 if (bus_dmamap_create(sc->sc_dmatag, MAX_DMA_SZ, 1, MAX_DMA_SZ, 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &sc->sc_dmamap) != 0) { aprint_error_dev(self, ": DMA map create failed\n"); } else {