From 74c781ed913dc866ec596e3a7875e5b0c76f7e22 Mon Sep 17 00:00:00 2001 From: Scott Long Date: Mon, 14 Sep 2020 05:58:12 +0000 Subject: [PATCH] Refine the busdma template interface. Provide tools for filling in fields that can be extended, but also ensure compile-time type checking. Refactor common code out of arch-specific implementations. Move the mpr and mps drivers to this new API. The template type remains visible to the consumer so that it can be allocated on the stack, but should be considered opaque. --- sys/arm/arm/busdma_machdep.c | 33 +---------- sys/arm64/arm64/busdma_machdep.c | 33 +---------- sys/dev/mpr/mpr.c | 52 ++++++++--------- sys/dev/mpr/mpr_pci.c | 2 +- sys/dev/mpr/mpr_user.c | 8 +-- sys/dev/mps/mps.c | 45 +++++++-------- sys/dev/mps/mps_pci.c | 2 +- sys/dev/mps/mps_user.c | 7 +-- sys/kern/subr_bus_dma.c | 85 ++++++++++++++++++++++++++++ sys/mips/mips/busdma_machdep.c | 33 +---------- sys/powerpc/powerpc/busdma_machdep.c | 33 +---------- sys/riscv/riscv/busdma_machdep.c | 33 +---------- sys/sys/bus_dma.h | 69 ++++++++++++++++++++-- sys/x86/x86/busdma_machdep.c | 33 +---------- 14 files changed, 208 insertions(+), 260 deletions(-) diff --git a/sys/arm/arm/busdma_machdep.c b/sys/arm/arm/busdma_machdep.c index 25af44c17e6..7d978ca0163 100644 --- a/sys/arm/arm/busdma_machdep.c +++ b/sys/arm/arm/busdma_machdep.c @@ -577,38 +577,7 @@ bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment, } void -bus_dma_template_init(bus_dma_tag_template_t *t, bus_dma_tag_t parent) -{ - - if (t == NULL) - return; - - t->parent = parent; - t->alignment = 1; - t->boundary = 0; - t->lowaddr = t->highaddr = BUS_SPACE_MAXADDR; - t->maxsize = t->maxsegsize = BUS_SPACE_MAXSIZE; - t->nsegments = BUS_SPACE_UNRESTRICTED; - t->lockfunc = NULL; - t->lockfuncarg = NULL; - t->flags = 0; -} - -int -bus_dma_template_tag(bus_dma_tag_template_t *t, bus_dma_tag_t *dmat) -{ - - if (t == NULL || dmat == NULL) - return (EINVAL); - - return (bus_dma_tag_create(t->parent, t->alignment, t->boundary, - t->lowaddr, t->highaddr, NULL, NULL, t->maxsize, - t->nsegments, t->maxsegsize, t->flags, t->lockfunc, t->lockfuncarg, - dmat)); -} - -void -bus_dma_template_clone(bus_dma_tag_template_t *t, bus_dma_tag_t dmat) +bus_dma_template_clone(bus_dma_template_t *t, bus_dma_tag_t dmat) { if (t == NULL || dmat == NULL) diff --git a/sys/arm64/arm64/busdma_machdep.c b/sys/arm64/arm64/busdma_machdep.c index 1a5ac67a2a4..0e672a58595 100644 --- a/sys/arm64/arm64/busdma_machdep.c +++ b/sys/arm64/arm64/busdma_machdep.c @@ -215,38 +215,7 @@ bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment, } void -bus_dma_template_init(bus_dma_tag_template_t *t, bus_dma_tag_t parent) -{ - - if (t == NULL) - return; - - t->parent = parent; - t->alignment = 1; - t->boundary = 0; - t->lowaddr = t->highaddr = BUS_SPACE_MAXADDR; - t->maxsize = t->maxsegsize = BUS_SPACE_MAXSIZE; - t->nsegments = BUS_SPACE_UNRESTRICTED; - t->lockfunc = NULL; - t->lockfuncarg = NULL; - t->flags = 0; -} - -int -bus_dma_template_tag(bus_dma_tag_template_t *t, bus_dma_tag_t *dmat) -{ - - if (t == NULL || dmat == NULL) - return (EINVAL); - - return (bus_dma_tag_create(t->parent, t->alignment, t->boundary, - t->lowaddr, t->highaddr, NULL, NULL, t->maxsize, - t->nsegments, t->maxsegsize, t->flags, t->lockfunc, t->lockfuncarg, - dmat)); -} - -void -bus_dma_template_clone(bus_dma_tag_template_t *t, bus_dma_tag_t dmat) +bus_dma_template_clone(bus_dma_template_t *t, bus_dma_tag_t dmat) { struct bus_dma_tag_common *common; diff --git a/sys/dev/mpr/mpr.c b/sys/dev/mpr/mpr.c index 335acc63638..b9ca24933ef 100644 --- a/sys/dev/mpr/mpr.c +++ b/sys/dev/mpr/mpr.c @@ -1310,7 +1310,7 @@ mpr_alloc_queues(struct mpr_softc *sc) static int mpr_alloc_hw_queues(struct mpr_softc *sc) { - bus_dma_tag_template_t t; + bus_dma_template_t t; bus_addr_t queues_busaddr; uint8_t *queues; int qsize, fqsize, pqsize; @@ -1333,10 +1333,9 @@ mpr_alloc_hw_queues(struct mpr_softc *sc) qsize = fqsize + pqsize; bus_dma_template_init(&t, sc->mpr_parent_dmat); - t.alignment = 16; - t.lowaddr = BUS_SPACE_MAXADDR_32BIT; - t.maxsize = t.maxsegsize = qsize; - t.nsegments = 1; + BUS_DMA_TEMPLATE_FILL(&t, BD_ALIGNMENT(16), BD_MAXSIZE(qsize), + BD_MAXSEGSIZE(qsize), BD_NSEGMENTS(1), + BD_LOWADDR(BUS_SPACE_MAXADDR_32BIT)); if (bus_dma_template_tag(&t, &sc->queues_dmat)) { mpr_dprint(sc, MPR_ERROR, "Cannot allocate queues DMA tag\n"); return (ENOMEM); @@ -1365,7 +1364,7 @@ mpr_alloc_hw_queues(struct mpr_softc *sc) static int mpr_alloc_replies(struct mpr_softc *sc) { - bus_dma_tag_template_t t; + bus_dma_template_t t; int rsize, num_replies; /* Store the reply frame size in bytes rather than as 32bit words */ @@ -1380,10 +1379,9 @@ mpr_alloc_replies(struct mpr_softc *sc) rsize = sc->replyframesz * num_replies; bus_dma_template_init(&t, sc->mpr_parent_dmat); - t.alignment = 4; - t.lowaddr = BUS_SPACE_MAXADDR_32BIT; - t.maxsize = t.maxsegsize = rsize; - t.nsegments = 1; + BUS_DMA_TEMPLATE_FILL(&t, BD_ALIGNMENT(4), BD_MAXSIZE(rsize), + BD_MAXSEGSIZE(rsize), BD_NSEGMENTS(1), + BD_LOWADDR(BUS_SPACE_MAXADDR_32BIT)); if (bus_dma_template_tag(&t, &sc->reply_dmat)) { mpr_dprint(sc, MPR_ERROR, "Cannot allocate replies DMA tag\n"); return (ENOMEM); @@ -1431,16 +1429,15 @@ mpr_load_chains_cb(void *arg, bus_dma_segment_t *segs, int nsegs, int error) static int mpr_alloc_requests(struct mpr_softc *sc) { - bus_dma_tag_template_t t; + bus_dma_template_t t; struct mpr_command *cm; int i, rsize, nsegs; rsize = sc->reqframesz * sc->num_reqs; bus_dma_template_init(&t, sc->mpr_parent_dmat); - t.alignment = 16; - t.lowaddr = BUS_SPACE_MAXADDR_32BIT; - t.maxsize = t.maxsegsize = rsize; - t.nsegments = 1; + BUS_DMA_TEMPLATE_FILL(&t, BD_ALIGNMENT(16), BD_MAXSIZE(rsize), + BD_MAXSEGSIZE(rsize), BD_NSEGMENTS(1), + BD_LOWADDR(BUS_SPACE_MAXADDR_32BIT)); if (bus_dma_template_tag(&t, &sc->req_dmat)) { mpr_dprint(sc, MPR_ERROR, "Cannot allocate request DMA tag\n"); return (ENOMEM); @@ -1464,9 +1461,8 @@ mpr_alloc_requests(struct mpr_softc *sc) } rsize = sc->chain_frame_size * sc->num_chains; bus_dma_template_init(&t, sc->mpr_parent_dmat); - t.alignment = 16; - t.maxsize = t.maxsegsize = rsize; - t.nsegments = howmany(rsize, PAGE_SIZE); + BUS_DMA_TEMPLATE_FILL(&t, BD_ALIGNMENT(16), BD_MAXSIZE(rsize), + BD_MAXSEGSIZE(rsize), BD_NSEGMENTS((howmany(rsize, PAGE_SIZE)))); if (bus_dma_template_tag(&t, &sc->chain_dmat)) { mpr_dprint(sc, MPR_ERROR, "Cannot allocate chain DMA tag\n"); return (ENOMEM); @@ -1486,7 +1482,8 @@ mpr_alloc_requests(struct mpr_softc *sc) rsize = MPR_SENSE_LEN * sc->num_reqs; bus_dma_template_clone(&t, sc->req_dmat); - t.maxsize = t.maxsegsize = rsize; + BUS_DMA_TEMPLATE_FILL(&t, BD_ALIGNMENT(1), BD_MAXSIZE(rsize), + BD_MAXSEGSIZE(rsize)); if (bus_dma_template_tag(&t, &sc->sense_dmat)) { mpr_dprint(sc, MPR_ERROR, "Cannot allocate sense DMA tag\n"); return (ENOMEM); @@ -1514,10 +1511,10 @@ mpr_alloc_requests(struct mpr_softc *sc) nsegs = (sc->maxio / PAGE_SIZE) + 1; bus_dma_template_init(&t, sc->mpr_parent_dmat); - t.nsegments = nsegs; - t.flags = BUS_DMA_ALLOCNOW; - t.lockfunc = busdma_lock_mutex; - t.lockfuncarg = &sc->mpr_mtx; + BUS_DMA_TEMPLATE_FILL(&t, BD_MAXSIZE(BUS_SPACE_MAXSIZE_32BIT), + BD_NSEGMENTS(nsegs), BD_MAXSEGSIZE(BUS_SPACE_MAXSIZE_32BIT), + BD_FLAGS(BUS_DMA_ALLOCNOW), BD_LOCKFUNC(busdma_lock_mutex), + BD_LOCKFUNCARG(&sc->mpr_mtx)); if (bus_dma_template_tag(&t, &sc->buffer_dmat)) { mpr_dprint(sc, MPR_ERROR, "Cannot allocate buffer DMA tag\n"); return (ENOMEM); @@ -1571,7 +1568,7 @@ mpr_alloc_requests(struct mpr_softc *sc) static int mpr_alloc_nvme_prp_pages(struct mpr_softc *sc) { - bus_dma_tag_template_t t; + bus_dma_template_t t; struct mpr_prp_page *prp_page; int PRPs_per_page, PRPs_required, pages_required; int rsize, i; @@ -1602,10 +1599,9 @@ mpr_alloc_nvme_prp_pages(struct mpr_softc *sc) sc->prp_buffer_size = PAGE_SIZE * pages_required; rsize = sc->prp_buffer_size * NVME_QDEPTH; bus_dma_template_init(&t, sc->mpr_parent_dmat); - t.alignment = 4; - t.lowaddr = BUS_SPACE_MAXADDR_32BIT; - t.maxsize = t.maxsegsize = rsize; - t.nsegments = 1; + BUS_DMA_TEMPLATE_FILL(&t, BD_ALIGNMENT(4), BD_MAXSIZE(rsize), + BD_MAXSEGSIZE(rsize), BD_NSEGMENTS(1), + BD_LOWADDR(BUS_SPACE_MAXADDR_32BIT)); if (bus_dma_template_tag(&t, &sc->prp_page_dmat)) { mpr_dprint(sc, MPR_ERROR, "Cannot allocate NVMe PRP DMA " "tag\n"); diff --git a/sys/dev/mpr/mpr_pci.c b/sys/dev/mpr/mpr_pci.c index c2a62c67aae..c7984df6c87 100644 --- a/sys/dev/mpr/mpr_pci.c +++ b/sys/dev/mpr/mpr_pci.c @@ -218,7 +218,7 @@ mpr_pci_probe(device_t dev) static int mpr_pci_attach(device_t dev) { - bus_dma_tag_template_t t; + bus_dma_template_t t; struct mpr_softc *sc; struct mpr_ident *m; int error, i; diff --git a/sys/dev/mpr/mpr_user.c b/sys/dev/mpr/mpr_user.c index 625836d6ccf..c0d35237d2f 100644 --- a/sys/dev/mpr/mpr_user.c +++ b/sys/dev/mpr/mpr_user.c @@ -1443,7 +1443,7 @@ static int mpr_diag_register(struct mpr_softc *sc, mpr_fw_diag_register_t *diag_register, uint32_t *return_code) { - bus_dma_tag_template_t t; + bus_dma_template_t t; mpr_fw_diagnostic_buffer_t *pBuffer; struct mpr_busdma_context *ctx; uint8_t extended_type, buffer_type, i; @@ -1507,9 +1507,9 @@ mpr_diag_register(struct mpr_softc *sc, mpr_fw_diag_register_t *diag_register, return (MPR_DIAG_FAILURE); } bus_dma_template_init(&t, sc->mpr_parent_dmat); - t.lowaddr = BUS_SPACE_MAXADDR_32BIT; - t.maxsize = t.maxsegsize = buffer_size; - t.nsegments = 1; + BUS_DMA_TEMPLATE_FILL(&t, BD_LOWADDR(BUS_SPACE_MAXADDR_32BIT), + BD_MAXSIZE(buffer_size), BD_MAXSEGSIZE(buffer_size), + BD_NSEGMENTS(1)); if (bus_dma_template_tag(&t, &sc->fw_diag_dmat)) { mpr_dprint(sc, MPR_ERROR, "Cannot allocate FW diag buffer DMA tag\n"); diff --git a/sys/dev/mps/mps.c b/sys/dev/mps/mps.c index f577bcb7735..e3db1e49118 100644 --- a/sys/dev/mps/mps.c +++ b/sys/dev/mps/mps.c @@ -1278,7 +1278,7 @@ mps_alloc_queues(struct mps_softc *sc) static int mps_alloc_hw_queues(struct mps_softc *sc) { - bus_dma_tag_template_t t; + bus_dma_template_t t; bus_addr_t queues_busaddr; uint8_t *queues; int qsize, fqsize, pqsize; @@ -1301,10 +1301,9 @@ mps_alloc_hw_queues(struct mps_softc *sc) qsize = fqsize + pqsize; bus_dma_template_init(&t, sc->mps_parent_dmat); - t.alignment = 16; - t.lowaddr = BUS_SPACE_MAXADDR_32BIT; - t.maxsize = t.maxsegsize = qsize; - t.nsegments = 1; + BUS_DMA_TEMPLATE_FILL(&t, BD_ALIGNMENT(16), BD_MAXSIZE(qsize), + BD_MAXSEGSIZE(qsize), BD_NSEGMENTS(1), + BD_LOWADDR(BUS_SPACE_MAXADDR_32BIT)); if (bus_dma_template_tag(&t, &sc->queues_dmat)) { mps_dprint(sc, MPS_ERROR, "Cannot allocate queues DMA tag\n"); return (ENOMEM); @@ -1333,7 +1332,7 @@ mps_alloc_hw_queues(struct mps_softc *sc) static int mps_alloc_replies(struct mps_softc *sc) { - bus_dma_tag_template_t t; + bus_dma_template_t t; int rsize, num_replies; /* Store the reply frame size in bytes rather than as 32bit words */ @@ -1348,10 +1347,9 @@ mps_alloc_replies(struct mps_softc *sc) rsize = sc->replyframesz * num_replies; bus_dma_template_init(&t, sc->mps_parent_dmat); - t.alignment = 4; - t.lowaddr = BUS_SPACE_MAXADDR_32BIT; - t.maxsize = t.maxsegsize = rsize; - t.nsegments = 1; + BUS_DMA_TEMPLATE_FILL(&t, BD_ALIGNMENT(4), BD_MAXSIZE(rsize), + BD_MAXSEGSIZE(rsize), BD_NSEGMENTS(1), + BD_LOWADDR(BUS_SPACE_MAXADDR_32BIT)); if (bus_dma_template_tag(&t, &sc->reply_dmat)) { mps_dprint(sc, MPS_ERROR, "Cannot allocate replies DMA tag\n"); return (ENOMEM); @@ -1400,16 +1398,15 @@ mps_load_chains_cb(void *arg, bus_dma_segment_t *segs, int nsegs, int error) static int mps_alloc_requests(struct mps_softc *sc) { - bus_dma_tag_template_t t; + bus_dma_template_t t; struct mps_command *cm; int i, rsize, nsegs; rsize = sc->reqframesz * sc->num_reqs; bus_dma_template_init(&t, sc->mps_parent_dmat); - t.alignment = 16; - t.lowaddr = BUS_SPACE_MAXADDR_32BIT; - t.maxsize = t.maxsegsize = rsize; - t.nsegments = 1; + BUS_DMA_TEMPLATE_FILL(&t, BD_ALIGNMENT(16), BD_MAXSIZE(rsize), + BD_MAXSEGSIZE(rsize), BD_NSEGMENTS(1), + BD_LOWADDR(BUS_SPACE_MAXADDR_32BIT)); if (bus_dma_template_tag(&t, &sc->req_dmat)) { mps_dprint(sc, MPS_ERROR, "Cannot allocate request DMA tag\n"); return (ENOMEM); @@ -1433,8 +1430,8 @@ mps_alloc_requests(struct mps_softc *sc) } rsize = sc->reqframesz * sc->num_chains; bus_dma_template_clone(&t, sc->req_dmat); - t.maxsize = t.maxsegsize = rsize; - t.nsegments = howmany(rsize, PAGE_SIZE); + BUS_DMA_TEMPLATE_FILL(&t, BD_MAXSIZE(rsize), BD_MAXSEGSIZE(rsize), + BD_NSEGMENTS(howmany(rsize, PAGE_SIZE))); if (bus_dma_template_tag(&t, &sc->chain_dmat)) { mps_dprint(sc, MPS_ERROR, "Cannot allocate chain DMA tag\n"); return (ENOMEM); @@ -1454,8 +1451,8 @@ mps_alloc_requests(struct mps_softc *sc) rsize = MPS_SENSE_LEN * sc->num_reqs; bus_dma_template_clone(&t, sc->req_dmat); - t.maxsize = t.maxsegsize = rsize; - t.alignment = 1; + BUS_DMA_TEMPLATE_FILL(&t, BD_ALIGNMENT(1), BD_MAXSIZE(rsize), + BD_MAXSEGSIZE(rsize)); if (bus_dma_template_tag(&t, &sc->sense_dmat)) { mps_dprint(sc, MPS_ERROR, "Cannot allocate sense DMA tag\n"); return (ENOMEM); @@ -1473,12 +1470,10 @@ mps_alloc_requests(struct mps_softc *sc) nsegs = (sc->maxio / PAGE_SIZE) + 1; bus_dma_template_init(&t, sc->mps_parent_dmat); - t.maxsize = BUS_SPACE_MAXSIZE_32BIT; - t.nsegments = nsegs; - t.maxsegsize = BUS_SPACE_MAXSIZE_24BIT; - t.flags = BUS_DMA_ALLOCNOW; - t.lockfunc = busdma_lock_mutex; - t.lockfuncarg = &sc->mps_mtx; + BUS_DMA_TEMPLATE_FILL(&t, BD_MAXSIZE(BUS_SPACE_MAXSIZE_32BIT), + BD_NSEGMENTS(nsegs), BD_MAXSEGSIZE(BUS_SPACE_MAXSIZE_24BIT), + BD_FLAGS(BUS_DMA_ALLOCNOW), BD_LOCKFUNC(busdma_lock_mutex), + BD_LOCKFUNCARG(&sc->mps_mtx)); if (bus_dma_template_tag(&t, &sc->buffer_dmat)) { mps_dprint(sc, MPS_ERROR, "Cannot allocate buffer DMA tag\n"); return (ENOMEM); diff --git a/sys/dev/mps/mps_pci.c b/sys/dev/mps/mps_pci.c index 3dcd646203e..51ca92c0b20 100644 --- a/sys/dev/mps/mps_pci.c +++ b/sys/dev/mps/mps_pci.c @@ -185,7 +185,7 @@ mps_pci_probe(device_t dev) static int mps_pci_attach(device_t dev) { - bus_dma_tag_template_t t; + bus_dma_template_t t; struct mps_softc *sc; struct mps_ident *m; int error; diff --git a/sys/dev/mps/mps_user.c b/sys/dev/mps/mps_user.c index fadd52fecaa..650e5d5e3e8 100644 --- a/sys/dev/mps/mps_user.c +++ b/sys/dev/mps/mps_user.c @@ -1346,7 +1346,7 @@ static int mps_diag_register(struct mps_softc *sc, mps_fw_diag_register_t *diag_register, uint32_t *return_code) { - bus_dma_tag_template_t t; + bus_dma_template_t t; mps_fw_diagnostic_buffer_t *pBuffer; struct mps_busdma_context *ctx; uint8_t extended_type, buffer_type, i; @@ -1410,9 +1410,8 @@ mps_diag_register(struct mps_softc *sc, mps_fw_diag_register_t *diag_register, return (MPS_DIAG_FAILURE); } bus_dma_template_init(&t, sc->mps_parent_dmat); - t.lowaddr = BUS_SPACE_MAXADDR_32BIT; - t.maxsize = t.maxsegsize = buffer_size; - t.nsegments = 1; + BUS_DMA_TEMPLATE_FILL(&t, BD_NSEGMENTS(1), BD_MAXSIZE(buffer_size), + BD_MAXSEGSIZE(buffer_size), BD_LOWADDR(BUS_SPACE_MAXADDR_32BIT)); if (bus_dma_template_tag(&t, &sc->fw_diag_dmat)) { mps_dprint(sc, MPS_ERROR, "Cannot allocate FW diag buffer DMA tag\n"); diff --git a/sys/kern/subr_bus_dma.c b/sys/kern/subr_bus_dma.c index a0a2287855f..030a5721585 100644 --- a/sys/kern/subr_bus_dma.c +++ b/sys/kern/subr_bus_dma.c @@ -700,3 +700,88 @@ bus_dmamap_load_crp(bus_dma_tag_t dmat, bus_dmamap_t map, struct cryptop *crp, return (bus_dmamap_load_crp_buffer(dmat, map, &crp->crp_buf, callback, callback_arg, flags)); } + +void +bus_dma_template_init(bus_dma_template_t *t, bus_dma_tag_t parent) +{ + + if (t == NULL) + return; + + t->parent = parent; + t->alignment = 1; + t->boundary = 0; + t->lowaddr = t->highaddr = BUS_SPACE_MAXADDR; + t->maxsize = t->maxsegsize = BUS_SPACE_MAXSIZE; + t->nsegments = BUS_SPACE_UNRESTRICTED; + t->lockfunc = NULL; + t->lockfuncarg = NULL; + t->flags = 0; +} + +int +bus_dma_template_tag(bus_dma_template_t *t, bus_dma_tag_t *dmat) +{ + + if (t == NULL || dmat == NULL) + return (EINVAL); + + return (bus_dma_tag_create(t->parent, t->alignment, t->boundary, + t->lowaddr, t->highaddr, NULL, NULL, t->maxsize, + t->nsegments, t->maxsegsize, t->flags, t->lockfunc, t->lockfuncarg, + dmat)); +} + +void +bus_dma_template_fill(bus_dma_template_t *t, bus_dma_param_t *kv, u_int count) +{ + bus_dma_param_t *pkv; + + while (count) { + pkv = &kv[--count]; + switch (pkv->key) { + case BD_PARAM_PARENT: + t->parent = pkv->ptr; + break; + case BD_PARAM_ALIGNMENT: + t->alignment = pkv->num; + break; + case BD_PARAM_BOUNDARY: + t->boundary = pkv->num; + break; + case BD_PARAM_LOWADDR: + t->lowaddr = pkv->pa; + break; + case BD_PARAM_HIGHADDR: + t->highaddr = pkv->pa; + break; + case BD_PARAM_MAXSIZE: + t->maxsize = pkv->num; + break; + case BD_PARAM_NSEGMENTS: + t->nsegments = pkv->num; + break; + case BD_PARAM_MAXSEGSIZE: + t->maxsegsize = pkv->num; + break; + case BD_PARAM_FLAGS: + t->flags = pkv->num; + break; + case BD_PARAM_LOCKFUNC: + t->lockfunc = pkv->ptr; + break; + case BD_PARAM_LOCKFUNCARG: + t->lockfuncarg = pkv->ptr; + break; + case BD_PARAM_NAME: + t->name = pkv->ptr; + break; + case BD_PARAM_INVALID: + default: + KASSERT(0, ("Invalid key %d\n", pkv->key)); + break; + } + } + return; +} + diff --git a/sys/mips/mips/busdma_machdep.c b/sys/mips/mips/busdma_machdep.c index 242321f1e67..c707af167ab 100644 --- a/sys/mips/mips/busdma_machdep.c +++ b/sys/mips/mips/busdma_machdep.c @@ -478,38 +478,7 @@ bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment, } void -bus_dma_template_init(bus_dma_tag_template_t *t, bus_dma_tag_t parent) -{ - - if (t == NULL) - return; - - t->parent = parent; - t->alignment = 1; - t->boundary = 0; - t->lowaddr = t->highaddr = BUS_SPACE_MAXADDR; - t->maxsize = t->maxsegsize = BUS_SPACE_MAXSIZE; - t->nsegments = BUS_SPACE_UNRESTRICTED; - t->lockfunc = NULL; - t->lockfuncarg = NULL; - t->flags = 0; -} - -int -bus_dma_template_tag(bus_dma_tag_template_t *t, bus_dma_tag_t *dmat) -{ - - if (t == NULL || dmat == NULL) - return (EINVAL); - - return (bus_dma_tag_create(t->parent, t->alignment, t->boundary, - t->lowaddr, t->highaddr, NULL, NULL, t->maxsize, - t->nsegments, t->maxsegsize, t->flags, t->lockfunc, t->lockfuncarg, - dmat)); -} - -void -bus_dma_template_clone(bus_dma_tag_template_t *t, bus_dma_tag_t dmat) +bus_dma_template_clone(bus_dma_template_t *t, bus_dma_tag_t dmat) { if (t == NULL || dmat == NULL) diff --git a/sys/powerpc/powerpc/busdma_machdep.c b/sys/powerpc/powerpc/busdma_machdep.c index 992066264b3..94f5f501501 100644 --- a/sys/powerpc/powerpc/busdma_machdep.c +++ b/sys/powerpc/powerpc/busdma_machdep.c @@ -342,38 +342,7 @@ bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment, } void -bus_dma_template_init(bus_dma_tag_template_t *t, bus_dma_tag_t parent) -{ - - if (t == NULL) - return; - - t->parent = parent; - t->alignment = 1; - t->boundary = 0; - t->lowaddr = t->highaddr = BUS_SPACE_MAXADDR; - t->maxsize = t->maxsegsize = BUS_SPACE_MAXSIZE; - t->nsegments = BUS_SPACE_UNRESTRICTED; - t->lockfunc = NULL; - t->lockfuncarg = NULL; - t->flags = 0; -} - -int -bus_dma_template_tag(bus_dma_tag_template_t *t, bus_dma_tag_t *dmat) -{ - - if (t == NULL || dmat == NULL) - return (EINVAL); - - return (bus_dma_tag_create(t->parent, t->alignment, t->boundary, - t->lowaddr, t->highaddr, NULL, NULL, t->maxsize, - t->nsegments, t->maxsegsize, t->flags, t->lockfunc, t->lockfuncarg, - dmat)); -} - -void -bus_dma_template_clone(bus_dma_tag_template_t *t, bus_dma_tag_t dmat) +bus_dma_template_clone(bus_dma_template_t *t, bus_dma_tag_t dmat) { if (t == NULL || dmat == NULL) diff --git a/sys/riscv/riscv/busdma_machdep.c b/sys/riscv/riscv/busdma_machdep.c index dc678bc166d..7b1c3027bad 100644 --- a/sys/riscv/riscv/busdma_machdep.c +++ b/sys/riscv/riscv/busdma_machdep.c @@ -215,38 +215,7 @@ bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment, } void -bus_dma_template_init(bus_dma_tag_template_t *t, bus_dma_tag_t parent) -{ - - if (t == NULL) - return; - - t->parent = parent; - t->alignment = 1; - t->boundary = 0; - t->lowaddr = t->highaddr = BUS_SPACE_MAXADDR; - t->maxsize = t->maxsegsize = BUS_SPACE_MAXSIZE; - t->nsegments = BUS_SPACE_UNRESTRICTED; - t->lockfunc = NULL; - t->lockfuncarg = NULL; - t->flags = 0; -} - -int -bus_dma_template_tag(bus_dma_tag_template_t *t, bus_dma_tag_t *dmat) -{ - - if (t == NULL || dmat == NULL) - return (EINVAL); - - return (bus_dma_tag_create(t->parent, t->alignment, t->boundary, - t->lowaddr, t->highaddr, NULL, NULL, t->maxsize, - t->nsegments, t->maxsegsize, t->flags, t->lockfunc, t->lockfuncarg, - dmat)); -} - -void -bus_dma_template_clone(bus_dma_tag_template_t *t, bus_dma_tag_t dmat) +bus_dma_template_clone(bus_dma_template_t *t, bus_dma_tag_t dmat) { struct bus_dma_tag_common *common; diff --git a/sys/sys/bus_dma.h b/sys/sys/bus_dma.h index 4b7396e6def..7eac96b5af1 100644 --- a/sys/sys/bus_dma.h +++ b/sys/sys/bus_dma.h @@ -181,7 +181,13 @@ int bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment, bus_size_t maxsegsz, int flags, bus_dma_lock_t *lockfunc, void *lockfuncarg, bus_dma_tag_t *dmat); -/* Functions for creating and cloning tags via a template */ +/* + * Functions for creating and cloning tags via a template, + * + * bus_dma_template_t is made avaialble publicly so it can be allocated + * from the caller stack. Its contents should be considered private, and + * should only be accessed via the documented APIs and macros + */ typedef struct { bus_dma_tag_t parent; bus_size_t alignment; @@ -194,10 +200,63 @@ typedef struct { int flags; bus_dma_lock_t *lockfunc; void *lockfuncarg; -} bus_dma_tag_template_t; -void bus_dma_template_init(bus_dma_tag_template_t *t, bus_dma_tag_t parent); -int bus_dma_template_tag(bus_dma_tag_template_t *t, bus_dma_tag_t *dmat); -void bus_dma_template_clone(bus_dma_tag_template_t *t, bus_dma_tag_t dmat); + const char *name; +} bus_dma_template_t; + +/* + * These enum values should not be re-ordered. BD_PARAM_INVALID is an + * invalid key and will trigger a panic. + */ +typedef enum { + BD_PARAM_INVALID = 0, + BD_PARAM_PARENT = 1, + BD_PARAM_ALIGNMENT = 2, + BD_PARAM_BOUNDARY = 3, + BD_PARAM_LOWADDR = 4, + BD_PARAM_HIGHADDR = 5, + BD_PARAM_MAXSIZE = 6, + BD_PARAM_NSEGMENTS = 7, + BD_PARAM_MAXSEGSIZE = 8, + BD_PARAM_FLAGS = 9, + BD_PARAM_LOCKFUNC = 10, + BD_PARAM_LOCKFUNCARG = 11, + BD_PARAM_NAME = 12 +} bus_dma_param_key_t; + +/* These contents should also be considered private */ +typedef struct { + bus_dma_param_key_t key; + union { + void *ptr; + vm_paddr_t pa; + uintmax_t num; + }; +} bus_dma_param_t; + +#define BD_PARENT(val) { BD_PARAM_PARENT, .ptr = val } +#define BD_ALIGNMENT(val) { BD_PARAM_ALIGNMENT, .num = val } +#define BD_BOUNDARY(val) { BD_PARAM_BOUNDARY, .num = val } +#define BD_LOWADDR(val) { BD_PARAM_LOWADDR, .pa = val } +#define BD_HIGHADDR(val) { BD_PARAM_HIGHADDR, .pa = val } +#define BD_MAXSIZE(val) { BD_PARAM_MAXSIZE, .num = val } +#define BD_NSEGMENTS(val) { BD_PARAM_NSEGMENTS, .num = val } +#define BD_MAXSEGSIZE(val) { BD_PARAM_MAXSEGSIZE, .num = val } +#define BD_FLAGS(val) { BD_PARAM_FLAGS, .num = val } +#define BD_LOCKFUNC(val) { BD_PARAM_LOCKFUNC, .ptr = val } +#define BD_LOCKFUNCARG(val) { BD_PARAM_LOCKFUNCARG, .ptr = val } +#define BD_NAME(val) { BD_PARAM_NAME, .ptr = val } + +#define BUS_DMA_TEMPLATE_FILL(t, kv...) \ +do { \ + bus_dma_param_t pm[] = { kv }; \ + bus_dma_template_fill(t, pm, howmany(sizeof(pm), sizeof(pm[0]))); \ +} while (0) + +void bus_dma_template_init(bus_dma_template_t *t, bus_dma_tag_t parent); +int bus_dma_template_tag(bus_dma_template_t *t, bus_dma_tag_t *dmat); +void bus_dma_template_clone(bus_dma_template_t *t, bus_dma_tag_t dmat); +void bus_dma_template_fill(bus_dma_template_t *t, bus_dma_param_t *kv, + u_int count); /* * Set the memory domain to be used for allocations. diff --git a/sys/x86/x86/busdma_machdep.c b/sys/x86/x86/busdma_machdep.c index 168645702bc..c2c74721d8d 100644 --- a/sys/x86/x86/busdma_machdep.c +++ b/sys/x86/x86/busdma_machdep.c @@ -237,38 +237,7 @@ bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment, } void -bus_dma_template_init(bus_dma_tag_template_t *t, bus_dma_tag_t parent) -{ - - if (t == NULL) - return; - - t->parent = parent; - t->alignment = 1; - t->boundary = 0; - t->lowaddr = t->highaddr = BUS_SPACE_MAXADDR; - t->maxsize = t->maxsegsize = BUS_SPACE_MAXSIZE; - t->nsegments = BUS_SPACE_UNRESTRICTED; - t->lockfunc = NULL; - t->lockfuncarg = NULL; - t->flags = 0; -} - -int -bus_dma_template_tag(bus_dma_tag_template_t *t, bus_dma_tag_t *dmat) -{ - - if (t == NULL || dmat == NULL) - return (EINVAL); - - return (bus_dma_tag_create(t->parent, t->alignment, t->boundary, - t->lowaddr, t->highaddr, NULL, NULL, t->maxsize, - t->nsegments, t->maxsegsize, t->flags, t->lockfunc, t->lockfuncarg, - dmat)); -} - -void -bus_dma_template_clone(bus_dma_tag_template_t *t, bus_dma_tag_t dmat) +bus_dma_template_clone(bus_dma_template_t *t, bus_dma_tag_t dmat) { struct bus_dma_tag_common *common;