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.
This commit is contained in:
scottl 2020-09-14 05:58:12 +00:00
parent 51f4174607
commit c9d5bb55c0
14 changed files with 208 additions and 260 deletions

View File

@ -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)

View File

@ -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;

View File

@ -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");

View File

@ -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;

View File

@ -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");

View File

@ -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);

View File

@ -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;

View File

@ -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");

View File

@ -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;
}

View File

@ -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)

View File

@ -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)

View File

@ -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;

View File

@ -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.

View File

@ -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;