svn commit: r356050 - in head: share/man/man9 sys/arm/arm sys/arm64/arm64 sys/mips/mips sys/powerpc/powerpc sys/riscv/riscv sys/sparc64/sparc64 sys/sys sys/x86/x86

Scott Long scottl at FreeBSD.org
Tue Dec 24 14:48:49 UTC 2019


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


More information about the svn-src-head mailing list