Author: scottl
Date: Tue Dec 24 14:48:46 2019
New Revision: 356050
URL: https://svnweb.freebsd.org/changeset/base/356050

Log:
  Introduce the concept of busdma tag templates. A template can be allocated
  off the stack, initialized to default values, and then filled in with
  driver-specific values, all without having to worry about the numerous
  other fields in the tag. The resulting template is then passed into
  busdma and the normal opaque tag object created.  See the man page for
  details on how to initialize a template.
  
  Templates do not support tag filters.  Filters have been broken for many
  years, and only existed for an ancient make/model of hardware that had a
  quirky DMA engine.  Instead of breaking the ABI/API and changing the
  arugment signature of bus_dma_tag_create() to remove the filter arguments,
  templates allow us to ignore them, and also significantly reduce the
  complexity of creating and managing tags.
  
  Reviewed by:  imp, kib
  Differential Revision:        https://reviews.freebsd.org/D22906

Modified:
  head/share/man/man9/bus_dma.9
  head/sys/arm/arm/busdma_machdep-v4.c
  head/sys/arm/arm/busdma_machdep-v6.c
  head/sys/arm64/arm64/busdma_machdep.c
  head/sys/mips/mips/busdma_machdep.c
  head/sys/powerpc/powerpc/busdma_machdep.c
  head/sys/riscv/riscv/busdma_machdep.c
  head/sys/sparc64/sparc64/bus_machdep.c
  head/sys/sys/bus_dma.h
  head/sys/x86/x86/busdma_machdep.c

Modified: head/share/man/man9/bus_dma.9
==============================================================================
--- head/share/man/man9/bus_dma.9       Tue Dec 24 06:08:29 2019        
(r356049)
+++ head/share/man/man9/bus_dma.9       Tue Dec 24 14:48:46 2019        
(r356050)
@@ -60,6 +60,9 @@
 .Nm bus_dma ,
 .Nm bus_dma_tag_create ,
 .Nm bus_dma_tag_destroy ,
+.Nm bus_dma_template_init ,
+.Nm bus_dma_template_tag ,
+.Nm bus_dma_template_clone ,
 .Nm bus_dmamap_create ,
 .Nm bus_dmamap_destroy ,
 .Nm bus_dmamap_load ,
@@ -83,7 +86,22 @@
 "void *lockfuncarg" "bus_dma_tag_t *dmat"
 .Ft int
 .Fn bus_dma_tag_destroy "bus_dma_tag_t dmat"
+.Ft void
+.Fo bus_dma_template_init
+.Fa "bus_dma_template_t template"
+.Fa "bus_dma_tag_t parent"
+.Fc
 .Ft int
+.Fo bus_dma_template_tag
+.Fa "bus_dma_template_t template"
+.Fa "bus_dma_tag_t *dmat"
+.Fc
+.Ft void
+.Fo bus_dma_template_clone
+.Fa "bus_dma_template_t template"
+.Fa "bus_dma_tag_t dmat"
+.Fc
+.Ft int
 .Fn bus_dmamap_create "bus_dma_tag_t dmat" "int flags" "bus_dmamap_t *mapp"
 .Ft int
 .Fn bus_dmamap_destroy "bus_dma_tag_t dmat" "bus_dmamap_t map"
@@ -282,6 +300,34 @@ DMA tags are organized into a hierarchy, with each chi
 tag inheriting the restrictions of its parent.
 This allows all devices along the path of DMA transactions
 to contribute to the constraints of those transactions.
+.It Vt bus_dma_template_t
+A template structure for creating a
+.Fa bus_dma_tag_t
+from a set of defaults.
+Once initialized with
+.Fn bus_dma_template_init ,
+a driver can over-ride individual fields to suit its needs.
+The following fields have the indicated values:
+.Bd -literal
+       alignment       1
+       boundary        0
+       lowaddr         BUS_SPACE_MAXADDR
+       highaddr        BUS_SPACE_MAXADDR
+       maxsize         BUS_SPACE_MAXSIZE
+       nsegments       BUS_SPACE_UNRESTRICTED
+       maxsegsize      BUS_SPACE_MAXSIZE
+       flags           0
+       lockfunc        NULL
+       lockfuncarg     NULL
+.Ed
+.Pp
+Descriptions of each field are documented with
+.Fn bus_dma_tag_create .
+Note that the
+.Fa filtfunc
+and
+.Fa filtfuncarg
+attributes of the DMA tag are not supported with templates.
 .It Vt bus_dma_filter_t
 Client specified address filter having the format:
 .Bl -tag -width indent
@@ -633,6 +679,25 @@ if any DMA maps remain associated with
 or
 .Ql 0
 on success.
+.It Fn bus_dma_template_init "*template" "parent"
+Initializes a
+.Fa bus_dma_template_t
+structure and associates it with an optional 
+.Fa parent .
+The
+.Fa parent
+argument may be NULL.
+.It Fn bus_dma_template_tag "*template" "*dmat"
+Unpacks a template into a tag, and returns the tag via the
+.Fa dmat .
+All return values are identical to
+.Fn bus_dma_tag_create .
+.It Fn bus_dma_template_clone "*template" "dmat"
+Clones the fields from a tag to a template.
+This is useful for cloning tags when paired with
+.Fn bus_dma_template_tag .
+A template that is filled in as a clone does not need to be initialized
+first.
 .It Fn bus_dmamap_create "dmat" "flags" "*mapp"
 Allocates and initializes a DMA map.
 Arguments are as follows:

Modified: head/sys/arm/arm/busdma_machdep-v4.c
==============================================================================
--- head/sys/arm/arm/busdma_machdep-v4.c        Tue Dec 24 06:08:29 2019        
(r356049)
+++ head/sys/arm/arm/busdma_machdep-v4.c        Tue Dec 24 14:48:46 2019        
(r356050)
@@ -501,6 +501,57 @@ bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t al
        return (error);
 }
 
+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)
+{
+
+       if (t == NULL || dmat == NULL)
+               return;
+
+       t->parent = dmat->parent;
+       t->alignment = dmat->alignment;
+       t->boundary = dmat->boundary;
+       t->lowaddr = dmat->lowaddr;
+       t->highaddr = dmat->highaddr;
+       t->maxsize = dmat->maxsize;
+       t->nsegments = dmat->nsegments;
+       t->maxsegsize = dmat->maxsegsz;
+       t->flags = dmat->flags;
+       t->lockfunc = dmat->lockfunc;
+       t->lockfuncarg = dmat->lockfuncarg;
+}
+
 int
 bus_dma_tag_set_domain(bus_dma_tag_t dmat, int domain)
 {

Modified: head/sys/arm/arm/busdma_machdep-v6.c
==============================================================================
--- head/sys/arm/arm/busdma_machdep-v6.c        Tue Dec 24 06:08:29 2019        
(r356049)
+++ head/sys/arm/arm/busdma_machdep-v6.c        Tue Dec 24 14:48:46 2019        
(r356050)
@@ -575,6 +575,57 @@ bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t al
        return (error);
 }
 
+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)
+{
+
+       if (t == NULL || dmat == NULL)
+               return;
+
+       t->parent = dmat->parent;
+       t->alignment = dmat->alignment;
+       t->boundary = dmat->boundary;
+       t->lowaddr = dmat->lowaddr;
+       t->highaddr = dmat->highaddr;
+       t->maxsize = dmat->maxsize;
+       t->nsegments = dmat->nsegments;
+       t->maxsegsize = dmat->maxsegsz;
+       t->flags = dmat->flags;
+       t->lockfunc = dmat->lockfunc;
+       t->lockfuncarg = dmat->lockfuncarg;
+}
+
 int
 bus_dma_tag_set_domain(bus_dma_tag_t dmat, int domain)
 {

Modified: head/sys/arm64/arm64/busdma_machdep.c
==============================================================================
--- head/sys/arm64/arm64/busdma_machdep.c       Tue Dec 24 06:08:29 2019        
(r356049)
+++ head/sys/arm64/arm64/busdma_machdep.c       Tue Dec 24 14:48:46 2019        
(r356050)
@@ -214,6 +214,60 @@ bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t al
        return (error);
 }
 
+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)
+{
+       struct bus_dma_tag_common *common;
+
+       if (t == NULL || dmat == NULL)
+               return;
+
+       common = (struct bus_dma_tag_common *)dmat;
+
+       t->parent = (bus_dma_tag_t)common->parent;
+       t->alignment = common->alignment;
+       t->boundary = common->boundary;
+       t->lowaddr = common->lowaddr;
+       t->highaddr = common->highaddr;
+       t->maxsize = common->maxsize;
+       t->nsegments = common->nsegments;
+       t->maxsegsize = common->maxsegsz;
+       t->flags = common->flags;
+       t->lockfunc = common->lockfunc;
+       t->lockfuncarg = common->lockfuncarg;
+}
+
 int
 bus_dma_tag_destroy(bus_dma_tag_t dmat)
 {

Modified: head/sys/mips/mips/busdma_machdep.c
==============================================================================
--- head/sys/mips/mips/busdma_machdep.c Tue Dec 24 06:08:29 2019        
(r356049)
+++ head/sys/mips/mips/busdma_machdep.c Tue Dec 24 14:48:46 2019        
(r356050)
@@ -476,6 +476,57 @@ bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t al
        return (error);
 }
 
+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)
+{
+
+       if (t == NULL || dmat == NULL)
+               return;
+
+       t->parent = dmat->parent;
+       t->alignment = dmat->alignment;
+       t->boundary = dmat->boundary;
+       t->lowaddr = dmat->lowaddr;
+       t->highaddr = dmat->highaddr;
+       t->maxsize = dmat->maxsize;
+       t->nsegments = dmat->nsegments;
+       t->maxsegsize = dmat->maxsegsz;
+       t->flags = dmat->flags;
+       t->lockfunc = dmat->lockfunc;
+       t->lockfuncarg = dmat->lockfuncarg;
+}
+
 int
 bus_dma_tag_set_domain(bus_dma_tag_t dmat, int domain)
 {

Modified: head/sys/powerpc/powerpc/busdma_machdep.c
==============================================================================
--- head/sys/powerpc/powerpc/busdma_machdep.c   Tue Dec 24 06:08:29 2019        
(r356049)
+++ head/sys/powerpc/powerpc/busdma_machdep.c   Tue Dec 24 14:48:46 2019        
(r356050)
@@ -340,6 +340,57 @@ bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t al
        return (error);
 }
 
+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)
+{
+
+       if (t == NULL || dmat == NULL)
+               return;
+
+       t->parent = dmat->parent;
+       t->alignment = dmat->alignment;
+       t->boundary = dmat->boundary;
+       t->lowaddr = dmat->lowaddr;
+       t->highaddr = dmat->highaddr;
+       t->maxsize = dmat->maxsize;
+       t->nsegments = dmat->nsegments;
+       t->maxsegsize = dmat->maxsegsz;
+       t->flags = dmat->flags;
+       t->lockfunc = dmat->lockfunc;
+       t->lockfuncarg = dmat->lockfuncarg;
+}
+
 int
 bus_dma_tag_set_domain(bus_dma_tag_t dmat, int domain)
 {

Modified: head/sys/riscv/riscv/busdma_machdep.c
==============================================================================
--- head/sys/riscv/riscv/busdma_machdep.c       Tue Dec 24 06:08:29 2019        
(r356049)
+++ head/sys/riscv/riscv/busdma_machdep.c       Tue Dec 24 14:48:46 2019        
(r356050)
@@ -214,6 +214,60 @@ bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t al
        return (error);
 }
 
+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)
+{
+       struct bus_dma_tag_common *common;
+
+       if (t == NULL || dmat == NULL)
+               return;
+
+       common = (struct bus_dma_tag_common *)dmat;
+
+       t->parent = (bus_dma_tag_t)common->parent;
+       t->alignment = common->alignment;
+       t->boundary = common->boundary;
+       t->lowaddr = common->lowaddr;
+       t->highaddr = common->highaddr;
+       t->maxsize = common->maxsize;
+       t->nsegments = common->nsegments;
+       t->maxsegsize = common->maxsegsz;
+       t->flags = common->flags;
+       t->lockfunc = common->lockfunc;
+       t->lockfuncarg = common->lockfuncarg;
+}
+
 int
 bus_dma_tag_destroy(bus_dma_tag_t dmat)
 {

Modified: head/sys/sparc64/sparc64/bus_machdep.c
==============================================================================
--- head/sys/sparc64/sparc64/bus_machdep.c      Tue Dec 24 06:08:29 2019        
(r356049)
+++ head/sys/sparc64/sparc64/bus_machdep.c      Tue Dec 24 14:48:46 2019        
(r356050)
@@ -250,6 +250,57 @@ bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t al
        return (0);
 }
 
+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)
+{
+
+       if (t == NULL || dmat == NULL)
+               return;
+
+       t->parent = dmat->dt_parent;
+       t->alignment = dmat->dt_alignment;
+       t->boundary = dmat->dt_boundary;
+       t->lowaddr = dmat->dt_lowaddr;
+       t->highaddr = dmat->dt_highaddr;
+       t->maxsize = dmat->dt_maxsize;
+       t->nsegments = dmat->dt_nsegments;
+       t->maxsegsize = dmat->dt_maxsegsz;
+       t->flags = dmat->dt_flags;
+       t->lockfunc = dmat->dt_lockfunc;
+       t->lockfuncarg = dmat->dt_lockfuncarg;
+}
+
 int
 bus_dma_tag_destroy(bus_dma_tag_t dmat)
 {

Modified: head/sys/sys/bus_dma.h
==============================================================================
--- head/sys/sys/bus_dma.h      Tue Dec 24 06:08:29 2019        (r356049)
+++ head/sys/sys/bus_dma.h      Tue Dec 24 14:48:46 2019        (r356050)
@@ -179,6 +179,24 @@ int bus_dma_tag_create(bus_dma_tag_t parent, bus_size_
                       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 */
+typedef struct {
+       bus_dma_tag_t           parent;
+       bus_size_t              alignment;
+       bus_addr_t              boundary;
+       bus_addr_t              lowaddr;
+       bus_addr_t              highaddr;
+       bus_size_t              maxsize;
+       int                     nsegments;
+       bus_size_t              maxsegsize;
+       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);
+
 /*
  * Set the memory domain to be used for allocations.
  *

Modified: head/sys/x86/x86/busdma_machdep.c
==============================================================================
--- head/sys/x86/x86/busdma_machdep.c   Tue Dec 24 06:08:29 2019        
(r356049)
+++ head/sys/x86/x86/busdma_machdep.c   Tue Dec 24 14:48:46 2019        
(r356050)
@@ -238,6 +238,60 @@ bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t al
        return (error);
 }
 
+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)
+{
+       struct bus_dma_tag_common *common;
+
+       if (t == NULL || dmat == NULL)
+               return;
+
+       common = (struct bus_dma_tag_common *)dmat;
+
+       t->parent = (bus_dma_tag_t)common->parent;
+       t->alignment = common->alignment;
+       t->boundary = common->boundary;
+       t->lowaddr = common->lowaddr;
+       t->highaddr = common->highaddr;
+       t->maxsize = common->maxsize;
+       t->nsegments = common->nsegments;
+       t->maxsegsize = common->maxsegsz;
+       t->flags = common->flags;
+       t->lockfunc = common->lockfunc;
+       t->lockfuncarg = common->lockfuncarg;
+}
+
 int
 bus_dma_tag_destroy(bus_dma_tag_t dmat)
 {
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to