summaryrefslogtreecommitdiffstats
path: root/share/man/man9/bus_dma.9
diff options
context:
space:
mode:
Diffstat (limited to 'share/man/man9/bus_dma.9')
-rw-r--r--share/man/man9/bus_dma.91059
1 files changed, 1059 insertions, 0 deletions
diff --git a/share/man/man9/bus_dma.9 b/share/man/man9/bus_dma.9
new file mode 100644
index 0000000..fa23fbf
--- /dev/null
+++ b/share/man/man9/bus_dma.9
@@ -0,0 +1,1059 @@
+.\" Copyright (c) 2002, 2003 Hiten M. Pandya.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions, and the following disclaimer,
+.\" without modification, immediately at the beginning of the file.
+.\" 2. The name of the author may not be used to endorse or promote products
+.\" derived from this software without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR, CONTRIBUTORS OR THE
+.\" VOICES IN HITEN PANDYA'S HEAD BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+.\" TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+.\" PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+.\" LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+.\" NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+.\" SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+.\"
+.\" Copyright (c) 1996, 1997, 1998, 2001 The NetBSD Foundation, Inc.
+.\" All rights reserved.
+.\"
+.\" This code is derived from software contributed to The NetBSD Foundation
+.\" by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
+.\" NASA Ames Research Center.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\" $NetBSD: bus_dma.9,v 1.25 2002/10/14 13:43:16 wiz Exp $
+.\"
+.Dd July 17, 2013
+.Dt BUS_DMA 9
+.Os
+.Sh NAME
+.Nm bus_dma ,
+.Nm bus_dma_tag_create ,
+.Nm bus_dma_tag_destroy ,
+.Nm bus_dmamap_create ,
+.Nm bus_dmamap_destroy ,
+.Nm bus_dmamap_load ,
+.Nm bus_dmamap_load_bio ,
+.Nm bus_dmamap_load_ccb ,
+.Nm bus_dmamap_load_mbuf ,
+.Nm bus_dmamap_load_mbuf_sg ,
+.Nm bus_dmamap_load_uio ,
+.Nm bus_dmamap_unload ,
+.Nm bus_dmamap_sync ,
+.Nm bus_dmamem_alloc ,
+.Nm bus_dmamem_free
+.Nd Bus and Machine Independent DMA Mapping Interface
+.Sh SYNOPSIS
+.In machine/bus.h
+.Ft int
+.Fn bus_dma_tag_create "bus_dma_tag_t parent" "bus_size_t alignment" \
+"bus_addr_t boundary" "bus_addr_t lowaddr" "bus_addr_t highaddr" \
+"bus_dma_filter_t *filtfunc" "void *filtfuncarg" "bus_size_t maxsize" \
+"int nsegments" "bus_size_t maxsegsz" "int flags" "bus_dma_lock_t *lockfunc" \
+"void *lockfuncarg" "bus_dma_tag_t *dmat"
+.Ft int
+.Fn bus_dma_tag_destroy "bus_dma_tag_t dmat"
+.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"
+.Ft int
+.Fn bus_dmamap_load "bus_dma_tag_t dmat" "bus_dmamap_t map" "void *buf" \
+"bus_size_t buflen" "bus_dmamap_callback_t *callback" "void *callback_arg" \
+"int flags"
+.Ft int
+.Fn bus_dmamap_load_bio "bus_dma_tag_t dmat" "bus_dmamap_t map" \
+"struct bio *bio" "bus_dmamap_callback_t *callback" "void *callback_arg" \
+"int flags"
+.Ft int
+.Fn bus_dmamap_load_ccb "bus_dma_tag_t dmat" "bus_dmamap_t map" \
+"union ccb *ccb" "bus_dmamap_callback_t *callback" "void *callback_arg" \
+"int flags"
+.Ft int
+.Fn bus_dmamap_load_mbuf "bus_dma_tag_t dmat" "bus_dmamap_t map" \
+"struct mbuf *mbuf" "bus_dmamap_callback2_t *callback" "void *callback_arg" \
+"int flags"
+.Ft int
+.Fn bus_dmamap_load_mbuf_sg "bus_dma_tag_t dmat" "bus_dmamap_t map" \
+"struct mbuf *mbuf" "bus_dma_segment_t *segs" "int *nsegs" "int flags"
+.Ft int
+.Fn bus_dmamap_load_uio "bus_dma_tag_t dmat" "bus_dmamap_t map" \
+"struct uio *uio" "bus_dmamap_callback2_t *callback" "void *callback_arg" \
+"int flags"
+.Ft void
+.Fn bus_dmamap_unload "bus_dma_tag_t dmat" "bus_dmamap_t map"
+.Ft void
+.Fn bus_dmamap_sync "bus_dma_tag_t dmat" "bus_dmamap_t map" \
+"op"
+.Ft int
+.Fn bus_dmamem_alloc "bus_dma_tag_t dmat" "void **vaddr" \
+"int flags" "bus_dmamap_t *mapp"
+.Ft void
+.Fn bus_dmamem_free "bus_dma_tag_t dmat" "void *vaddr" \
+"bus_dmamap_t map"
+.Sh DESCRIPTION
+Direct Memory Access (DMA) is a method of transferring data
+without involving the CPU, thus providing higher performance.
+A DMA transaction can be achieved between device to memory,
+device to device, or memory to memory.
+.Pp
+The
+.Nm
+API is a bus, device, and machine-independent (MI) interface to
+DMA mechanisms.
+It provides the client with flexibility and simplicity by
+abstracting machine dependent issues like setting up
+DMA mappings, handling cache issues, bus specific features
+and limitations.
+.Sh STRUCTURES AND TYPES
+.Bl -tag -width indent
+.It Vt bus_dma_tag_t
+A machine-dependent (MD) opaque type that describes the
+characteristics of DMA transactions.
+DMA tags are organized into a hierarchy, with each child
+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_filter_t
+Client specified address filter having the format:
+.Bl -tag -width indent
+.It Ft int
+.Fn "client_filter" "void *filtarg" "bus_addr_t testaddr"
+.El
+.Pp
+Address filters can be specified during tag creation to allow
+for devices whose DMA address restrictions cannot be specified
+by a single window.
+The
+.Fa filtarg
+argument is specified by the client during tag creation to be passed to all
+invocations of the callback.
+The
+.Fa testaddr
+argument contains a potential starting address of a DMA mapping.
+The filter function operates on the set of addresses from
+.Fa testaddr
+to
+.Ql trunc_page(testaddr) + PAGE_SIZE - 1 ,
+inclusive.
+The filter function should return zero if any mapping in this range
+can be accommodated by the device and non-zero otherwise.
+.It Vt bus_dma_segment_t
+A machine-dependent type that describes individual
+DMA segments.
+It contains the following fields:
+.Bd -literal
+ bus_addr_t ds_addr;
+ bus_size_t ds_len;
+.Ed
+.Pp
+The
+.Fa ds_addr
+field contains the device visible address of the DMA segment, and
+.Fa ds_len
+contains the length of the DMA segment.
+Although the DMA segments returned by a mapping call will adhere to
+all restrictions necessary for a successful DMA operation, some conversion
+(e.g.\& a conversion from host byte order to the device's byte order) is
+almost always required when presenting segment information to the device.
+.It Vt bus_dmamap_t
+A machine-dependent opaque type describing an individual mapping.
+One map is used for each memory allocation that will be loaded.
+Maps can be reused once they have been unloaded.
+Multiple maps can be associated with one DMA tag.
+While the value of the map may evaluate to
+.Dv NULL
+on some platforms under certain conditions,
+it should never be assumed that it will be
+.Dv NULL
+in all cases.
+.It Vt bus_dmamap_callback_t
+Client specified callback for receiving mapping information resulting from
+the load of a
+.Vt bus_dmamap_t
+via
+.Fn bus_dmamap_load ,
+.Fn bus_dmamap_load_bio
+or
+.Fn bus_dmamap_load_ccb .
+Callbacks are of the format:
+.Bl -tag -width indent
+.It Ft void
+.Fn "client_callback" "void *callback_arg" "bus_dma_segment_t *segs" \
+"int nseg" "int error"
+.El
+.Pp
+The
+.Fa callback_arg
+is the callback argument passed to dmamap load functions.
+The
+.Fa segs
+and
+.Fa nseg
+arguments describe an array of
+.Vt bus_dma_segment_t
+structures that represent the mapping.
+This array is only valid within the scope of the callback function.
+The success or failure of the mapping is indicated by the
+.Fa error
+argument.
+More information on the use of callbacks can be found in the
+description of the individual dmamap load functions.
+.It Vt bus_dmamap_callback2_t
+Client specified callback for receiving mapping information resulting from
+the load of a
+.Vt bus_dmamap_t
+via
+.Fn bus_dmamap_load_uio
+or
+.Fn bus_dmamap_load_mbuf .
+.Pp
+Callback2s are of the format:
+.Bl -tag -width indent
+.It Ft void
+.Fn "client_callback2" "void *callback_arg" "bus_dma_segment_t *segs" \
+"int nseg" "bus_size_t mapsize" "int error"
+.El
+.Pp
+Callback2's behavior is the same as
+.Vt bus_dmamap_callback_t
+with the addition that the length of the data mapped is provided via
+.Fa mapsize .
+.It Vt bus_dmasync_op_t
+Memory synchronization operation specifier.
+Bus DMA requires explicit synchronization of memory with its device
+visible mapping in order to guarantee memory coherency.
+The
+.Vt bus_dmasync_op_t
+allows the type of DMA operation that will be or has been performed
+to be communicated to the system so that the correct coherency measures
+are taken.
+The operations are represented as bitfield flags that can be combined together,
+though it only makes sense to combine PRE flags or POST flags, not both.
+See the
+.Fn bus_dmamap_sync
+description below for more details on how to use these operations.
+.Pp
+All operations specified below are performed from the host memory point of view,
+where a read implies data coming from the device to the host memory, and a write
+implies data going from the host memory to the device.
+Alternatively, the operations can be thought of in terms of driver operations,
+where reading a network packet or storage sector corresponds to a read operation
+in
+.Nm .
+.Bl -tag -width ".Dv BUS_DMASYNC_POSTWRITE"
+.It Dv BUS_DMASYNC_PREREAD
+Perform any synchronization required prior to an update of host memory by the
+device.
+.It Dv BUS_DMASYNC_PREWRITE
+Perform any synchronization required after an update of host memory by the CPU
+and prior to device access to host memory.
+.It Dv BUS_DMASYNC_POSTREAD
+Perform any synchronization required after an update of host memory by the
+device and prior to CPU access to host memory.
+.It Dv BUS_DMASYNC_POSTWRITE
+Perform any synchronization required after device access to host memory.
+.El
+.It Vt bus_dma_lock_t
+Client specified lock/mutex manipulation method.
+This will be called from
+within busdma whenever a client lock needs to be manipulated.
+In its current form, the function will be called immediately before
+the callback for a DMA load operation that has been deferred with
+.Dv BUS_DMA_LOCK
+and immediately after with
+.Dv BUS_DMA_UNLOCK .
+If the load operation does not need to be deferred, then it
+will not be called since the function loading the map should
+be holding the appropriate locks.
+This method is of the format:
+.Bl -tag -width indent
+.It Ft void
+.Fn "lockfunc" "void *lockfunc_arg" "bus_dma_lock_op_t op"
+.El
+.Pp
+The
+.Fa lockfuncarg
+argument is specified by the client during tag creation to be passed to all
+invocations of the callback.
+The
+.Fa op
+argument specifies the lock operation to perform.
+.Pp
+Two
+.Vt lockfunc
+implementations are provided for convenience.
+.Fn busdma_lock_mutex
+performs standard mutex operations on the sleep mutex provided via
+.Fa lockfuncarg .
+.Fn dflt_lock
+will generate a system panic if it is called.
+It is substituted into the tag when
+.Fa lockfunc
+is passed as
+.Dv NULL
+to
+.Fn bus_dma_tag_create
+and is useful for tags that should not be used with deferred load operations.
+.It Vt bus_dma_lock_op_t
+Operations to be performed by the client-specified
+.Fn lockfunc .
+.Bl -tag -width ".Dv BUS_DMA_UNLOCK"
+.It Dv BUS_DMA_LOCK
+Acquires and/or locks the client locking primitive.
+.It Dv BUS_DMA_UNLOCK
+Releases and/or unlocks the client locking primitive.
+.El
+.El
+.Sh FUNCTIONS
+.Bl -tag -width indent
+.It Fn bus_dma_tag_create "parent" "alignment" "boundary" "lowaddr" \
+"highaddr" "*filtfunc" "*filtfuncarg" "maxsize" "nsegments" "maxsegsz" \
+"flags" "lockfunc" "lockfuncarg" "*dmat"
+Allocates a device specific DMA tag, and initializes it according to
+the arguments provided:
+.Bl -tag -width ".Fa filtfuncarg"
+.It Fa parent
+Indicates restrictions between the parent bridge, CPU memory, and the
+device.
+Each device must use a master parent tag by calling
+.Fn bus_get_dma_tag .
+.It Fa alignment
+Alignment constraint, in bytes, of any mappings created using this tag.
+The alignment must be a power of 2.
+Hardware that can DMA starting at any address would specify
+.Em 1
+for byte alignment.
+Hardware requiring DMA transfers to start on a multiple of 4K
+would specify
+.Em 4096 .
+.It Fa boundary
+Boundary constraint, in bytes, of the target DMA memory region.
+The boundary indicates the set of addresses, all multiples of the
+boundary argument, that cannot be crossed by a single
+.Vt bus_dma_segment_t .
+The boundary must be a power of 2 and must be no smaller than the
+maximum segment size.
+.Ql 0
+indicates that there are no boundary restrictions.
+.It Fa lowaddr , highaddr
+Bounds of the window of bus address space that
+.Em cannot
+be directly accessed by the device.
+The window contains all addresses greater than
+.Fa lowaddr
+and less than or equal to
+.Fa highaddr .
+For example, a device incapable of DMA above 4GB, would specify a
+.Fa highaddr
+of
+.Dv BUS_SPACE_MAXADDR
+and a
+.Fa lowaddr
+of
+.Dv BUS_SPACE_MAXADDR_32BIT .
+Similarly a device that can only perform DMA to addresses below
+16MB would specify a
+.Fa highaddr
+of
+.Dv BUS_SPACE_MAXADDR
+and a
+.Fa lowaddr
+of
+.Dv BUS_SPACE_MAXADDR_24BIT .
+Some implementations requires that some region of device visible
+address space, overlapping available host memory, be outside the
+window.
+This area of
+.Ql safe memory
+is used to bounce requests that would otherwise conflict with
+the exclusion window.
+.It Fa filtfunc
+Optional filter function (may be
+.Dv NULL )
+to be called for any attempt to
+map memory into the window described by
+.Fa lowaddr
+and
+.Fa highaddr .
+A filter function is only required when the single window described
+by
+.Fa lowaddr
+and
+.Fa highaddr
+cannot adequately describe the constraints of the device.
+The filter function will be called for every machine page
+that overlaps the exclusion window.
+.It Fa filtfuncarg
+Argument passed to all calls to the filter function for this tag.
+May be
+.Dv NULL .
+.It Fa maxsize
+Maximum size, in bytes, of the sum of all segment lengths in a given
+DMA mapping associated with this tag.
+.It Fa nsegments
+Number of discontinuities (scatter/gather segments) allowed
+in a DMA mapped region.
+If there is no restriction,
+.Dv BUS_SPACE_UNRESTRICTED
+may be specified.
+.It Fa maxsegsz
+Maximum size, in bytes, of a segment in any DMA mapped region associated
+with
+.Fa dmat .
+.It Fa flags
+Are as follows:
+.Bl -tag -width ".Dv BUS_DMA_ALLOCNOW"
+.It Dv BUS_DMA_ALLOCNOW
+Pre-allocate enough resources to handle at least one map load operation on
+this tag.
+If sufficient resources are not available,
+.Er ENOMEM
+is returned.
+This should not be used for tags that only describe buffers that will be
+allocated with
+.Fn bus_dmamem_alloc .
+Also, due to resource sharing with other tags, this flag does not guarantee
+that resources will be allocated or reserved exclusively for this tag.
+It should be treated only as a minor optimization.
+.El
+.It Fa lockfunc
+Optional lock manipulation function (may be
+.Dv NULL )
+to be called when busdma
+needs to manipulate a lock on behalf of the client.
+If
+.Dv NULL
+is specified,
+.Fn dflt_lock
+is used.
+.It Fa lockfuncarg
+Optional argument to be passed to the function specified by
+.Fa lockfunc .
+.It Fa dmat
+Pointer to a bus_dma_tag_t where the resulting DMA tag will
+be stored.
+.El
+.Pp
+Returns
+.Er ENOMEM
+if sufficient memory is not available for tag creation
+or allocating mapping resources.
+.It Fn bus_dma_tag_destroy "dmat"
+Deallocate the DMA tag
+.Fa dmat
+that was created by
+.Fn bus_dma_tag_create .
+.Pp
+Returns
+.Er EBUSY
+if any DMA maps remain associated with
+.Fa dmat
+or
+.Ql 0
+on success.
+.It Fn bus_dmamap_create "dmat" "flags" "*mapp"
+Allocates and initializes a DMA map.
+Arguments are as follows:
+.Bl -tag -width ".Fa nsegments"
+.It Fa dmat
+DMA tag.
+.It Fa flags
+Are as follows:
+.Bl -tag -width ".Dv BUS_DMA_COHERENT"
+.It Dv BUS_DMA_COHERENT
+Attempt to map the memory loaded with this map such that cache sync
+operations are as cheap as possible.
+This flag is typically set on maps when the memory loaded with these will
+be accessed by both a CPU and a DMA engine, frequently such as control data
+and as opposed to streamable data such as receive and transmit buffers.
+Use of this flag does not remove the requirement of using
+.Fn bus_dmamap_sync ,
+but it may reduce the cost of performing these operations.
+For
+.Fn bus_dmamap_create ,
+the
+.Dv BUS_DMA_COHERENT
+flag is currently implemented on sparc64.
+.El
+.It Fa mapp
+Pointer to a
+.Vt bus_dmamap_t
+where the resulting DMA map will be stored.
+.El
+.Pp
+Returns
+.Er ENOMEM
+if sufficient memory is not available for creating the
+map or allocating mapping resources.
+.It Fn bus_dmamap_destroy "dmat" "map"
+Frees all resources associated with a given DMA map.
+Arguments are as follows:
+.Bl -tag -width ".Fa dmat"
+.It Fa dmat
+DMA tag used to allocate
+.Fa map .
+.It Fa map
+The DMA map to destroy.
+.El
+.Pp
+Returns
+.Er EBUSY
+if a mapping is still active for
+.Fa map .
+.It Fn bus_dmamap_load "dmat" "map" "buf" "buflen" "*callback" \
+"callback_arg" "flags"
+Creates a mapping in device visible address space of
+.Fa buflen
+bytes of
+.Fa buf ,
+associated with the DMA map
+.Fa map .
+This call will always return immediately and will not block for any reason.
+Arguments are as follows:
+.Bl -tag -width ".Fa buflen"
+.It Fa dmat
+DMA tag used to allocate
+.Fa map .
+.It Fa map
+A DMA map without a currently active mapping.
+.It Fa buf
+A kernel virtual address pointer to a contiguous (in KVA) buffer, to be
+mapped into device visible address space.
+.It Fa buflen
+The size of the buffer.
+.It Fa callback Fa callback_arg
+The callback function, and its argument.
+This function is called once sufficient mapping resources are available for
+the DMA operation.
+If resources are temporarily unavailable, this function will be deferred until
+later, but the load operation will still return immediately to the caller.
+Thus, callers should not assume that the callback will be called before the
+load returns, and code should be structured appropriately to handle this.
+See below for specific flags and error codes that control this behavior.
+.It Fa flags
+Are as follows:
+.Bl -tag -width ".Dv BUS_DMA_NOWAIT"
+.It Dv BUS_DMA_NOWAIT
+The load should not be deferred in case of insufficient mapping resources,
+and instead should return immediately with an appropriate error.
+.It Dv BUS_DMA_NOCACHE
+The generated transactions to and from the virtual page are non-cacheable.
+For
+.Fn bus_dmamap_load ,
+the
+.Dv BUS_DMA_NOCACHE
+flag is currently implemented on sparc64.
+.El
+.El
+.Pp
+Return values to the caller are as follows:
+.Bl -tag -width ".Er EINPROGRESS"
+.It 0
+The callback has been called and completed.
+The status of the mapping has been delivered to the callback.
+.It Er EINPROGRESS
+The mapping has been deferred for lack of resources.
+The callback will be called as soon as resources are available.
+Callbacks are serviced in FIFO order.
+.Pp
+Note that subsequent load operations for the same tag that do not require
+extra resources will still succeed.
+This may result in out-of-order processing of requests.
+If the caller requires the order of requests to be preserved,
+then the caller is required to stall subsequent requests until a pending
+request's callback is invoked.
+.It Er ENOMEM
+The load request has failed due to insufficient resources, and the caller
+specifically used the
+.Dv BUS_DMA_NOWAIT
+flag.
+.It Er EINVAL
+The load request was invalid.
+The callback has been called and has been provided the same error.
+This error value may indicate that
+.Fa dmat ,
+.Fa map ,
+.Fa buf ,
+or
+.Fa callback
+were invalid, or
+.Fa buflen
+was larger than the
+.Fa maxsize
+argument used to create the dma tag
+.Fa dmat .
+.El
+.Pp
+When the callback is called, it is presented with an error value
+indicating the disposition of the mapping.
+Error may be one of the following:
+.Bl -tag -width ".Er EINPROGRESS"
+.It 0
+The mapping was successful and the
+.Fa dm_segs
+callback argument contains an array of
+.Vt bus_dma_segment_t
+elements describing the mapping.
+This array is only valid during the scope of the callback function.
+.It Er EFBIG
+A mapping could not be achieved within the segment constraints provided
+in the tag even though the requested allocation size was less than maxsize.
+.El
+.It Fn bus_dmamap_load_bio "dmat" "map" "bio" "callback" "callback_arg" "flags"
+This is a variation of
+.Fn bus_dmamap_load
+which maps buffers pointed to by
+.Fa bio
+for DMA transfers.
+.Fa bio
+may point to either a mapped or unmapped buffer.
+.It Fn bus_dmamap_load_ccb "dmat" "map" "ccb" "callback" "callback_arg" "flags"
+This is a variation of
+.Fn bus_dmamap_load
+which maps data pointed to by
+.Fa ccb
+for DMA transfers.
+The data for
+.Fa ccb
+may be any of the following types:
+.Bl -tag -width ".Er CAM_DATA_SG_PADDR"
+.It CAM_DATA_VADDR
+The data is a single KVA buffer.
+.It CAM_DATA_PADDR
+The data is a single bus address range.
+.It CAM_DATA_SG
+The data is a scatter/gather list of KVA buffers.
+.It CAM_DATA_SG_PADDR
+The data is a scatter/gather list of bus address ranges.
+.It CAM_DATA_BIO
+The data is contained in a
+.Vt struct bio
+attached to the CCB.
+.El
+.Pp
+.Fn bus_dmamap_load_ccb
+supports the following CCB XPT function codes:
+.Pp
+.Bl -item -offset indent -compact
+.It
+XPT_ATA_IO
+.It
+XPT_CONT_TARGET_IO
+.It
+XPT_SCSI_IO
+.El
+.It Fn bus_dmamap_load_mbuf "dmat" "map" "mbuf" "callback2" "callback_arg" \
+"flags"
+This is a variation of
+.Fn bus_dmamap_load
+which maps mbuf chains
+for DMA transfers.
+A
+.Vt bus_size_t
+argument is also passed to the callback routine, which
+contains the mbuf chain's packet header length.
+The
+.Dv BUS_DMA_NOWAIT
+flag is implied, thus no callback deferral will happen.
+.Pp
+Mbuf chains are assumed to be in kernel virtual address space.
+.Pp
+Beside the error values listed for
+.Fn bus_dmamap_load ,
+.Er EINVAL
+will be returned if the size of the mbuf chain exceeds the maximum limit of the
+DMA tag.
+.It Fn bus_dmamap_load_mbuf_sg "dmat" "map" "mbuf" "segs" "nsegs" "flags"
+This is just like
+.Fn bus_dmamap_load_mbuf
+except that it returns immediately without calling a callback function.
+It is provided for efficiency.
+The scatter/gather segment array
+.Va segs
+is provided by the caller and filled in directly by the function.
+The
+.Va nsegs
+argument is returned with the number of segments filled in.
+Returns the same errors as
+.Fn bus_dmamap_load_mbuf .
+.It Fn bus_dmamap_load_uio "dmat" "map" "uio" "callback2" "callback_arg" "flags"
+This is a variation of
+.Fn bus_dmamap_load
+which maps buffers pointed to by
+.Fa uio
+for DMA transfers.
+A
+.Vt bus_size_t
+argument is also passed to the callback routine, which contains the size of
+.Fa uio ,
+i.e.
+.Fa uio->uio_resid .
+The
+.Dv BUS_DMA_NOWAIT
+flag is implied, thus no callback deferral will happen.
+Returns the same errors as
+.Fn bus_dmamap_load .
+.Pp
+If
+.Fa uio->uio_segflg
+is
+.Dv UIO_USERSPACE ,
+then it is assumed that the buffer,
+.Fa uio
+is in
+.Fa "uio->uio_td->td_proc" Ns 's
+address space.
+User space memory must be in-core and wired prior to attempting a map
+load operation.
+Pages may be locked using
+.Xr vslock 9 .
+.It Fn bus_dmamap_unload "dmat" "map"
+Unloads a DMA map.
+Arguments are as follows:
+.Bl -tag -width ".Fa dmam"
+.It Fa dmat
+DMA tag used to allocate
+.Fa map .
+.It Fa map
+The DMA map that is to be unloaded.
+.El
+.Pp
+.Fn bus_dmamap_unload
+will not perform any implicit synchronization of DMA buffers.
+This must be done explicitly by a call to
+.Fn bus_dmamap_sync
+prior to unloading the map.
+.It Fn bus_dmamap_sync "dmat" "map" "op"
+Performs synchronization of a device visible mapping with the CPU visible
+memory referenced by that mapping.
+Arguments are as follows:
+.Bl -tag -width ".Fa dmat"
+.It Fa dmat
+DMA tag used to allocate
+.Fa map .
+.It Fa map
+The DMA mapping to be synchronized.
+.It Fa op
+Type of synchronization operation to perform.
+See the definition of
+.Vt bus_dmasync_op_t
+for a description of the acceptable values for
+.Fa op .
+.El
+.Pp
+The
+.Fn bus_dmamap_sync
+function
+is the method used to ensure that CPU's and device's direct
+memory access (DMA) to shared
+memory is coherent.
+For example, the CPU might be used to set up the contents of a buffer
+that is to be made available to a device.
+To ensure that the data are visible via the device's mapping of that
+memory, the buffer must be loaded and a DMA sync operation of
+.Dv BUS_DMASYNC_PREWRITE
+must be performed after the CPU has updated the buffer and before the device
+access is initiated.
+If the CPU modifies this buffer again later, another
+.Dv BUS_DMASYNC_PREWRITE
+sync operation must be performed before an additional device
+access.
+Conversely, suppose a device updates memory that is to be read by a CPU.
+In this case, the buffer must be loaded, and a DMA sync operation of
+.Dv BUS_DMASYNC_PREREAD
+must be performed before the device access is initiated.
+The CPU will only be able to see the results of this memory update
+once the DMA operation has completed and a
+.Dv BUS_DMASYNC_POSTREAD
+sync operation has been performed.
+.Pp
+If read and write operations are not preceded and followed by the
+appropriate synchronization operations, behavior is undefined.
+.It Fn bus_dmamem_alloc "dmat" "**vaddr" "flags" "*mapp"
+Allocates memory that is mapped into KVA at the address returned
+in
+.Fa vaddr
+and that is permanently loaded into the newly created
+.Vt bus_dmamap_t
+returned via
+.Fa mapp .
+Arguments are as follows:
+.Bl -tag -width ".Fa alignment"
+.It Fa dmat
+DMA tag describing the constraints of the DMA mapping.
+.It Fa vaddr
+Pointer to a pointer that will hold the returned KVA mapping of
+the allocated region.
+.It Fa flags
+Flags are defined as follows:
+.Bl -tag -width ".Dv BUS_DMA_NOWAIT"
+.It Dv BUS_DMA_WAITOK
+The routine can safely wait (sleep) for resources.
+.It Dv BUS_DMA_NOWAIT
+The routine is not allowed to wait for resources.
+If resources are not available,
+.Dv ENOMEM
+is returned.
+.It Dv BUS_DMA_COHERENT
+Attempt to map this memory in a coherent fashion.
+See
+.Fn bus_dmamap_create
+above for a description of this flag.
+For
+.Fn bus_dmamem_alloc ,
+the
+.Dv BUS_DMA_COHERENT
+flag is currently implemented on arm and sparc64.
+.It Dv BUS_DMA_ZERO
+Causes the allocated memory to be set to all zeros.
+.It Dv BUS_DMA_NOCACHE
+The allocated memory will not be cached in the processor caches.
+All memory accesses appear on the bus and are executed
+without reordering.
+For
+.Fn bus_dmamem_alloc ,
+the
+.Dv BUS_DMA_NOCACHE
+flag is currently implemented on amd64 and i386 where it results in the
+Strong Uncacheable PAT to be set for the allocated virtual address range.
+.El
+.It Fa mapp
+Pointer to a
+.Vt bus_dmamap_t
+where the resulting DMA map will be stored.
+.El
+.Pp
+The size of memory to be allocated is
+.Fa maxsize
+as specified in the call to
+.Fn bus_dma_tag_create
+for
+.Fa dmat .
+.Pp
+The current implementation of
+.Fn bus_dmamem_alloc
+will allocate all requests as a single segment.
+.Pp
+An initial load operation is required to obtain the bus address of the allocated
+memory, and an unload operation is required before freeing the memory, as
+described below in
+.Fn bus_dmamem_free .
+Maps are automatically handled by this function and should not be explicitly
+allocated or destroyed.
+.Pp
+Although an explicit load is not required for each access to the memory
+referenced by the returned map, the synchronization requirements
+as described in the
+.Fn bus_dmamap_sync
+section still apply and should be used to achieve portability on architectures
+without coherent buses.
+.Pp
+Returns
+.Er ENOMEM
+if sufficient memory is not available for completing
+the operation.
+.It Fn bus_dmamem_free "dmat" "*vaddr" "map"
+Frees memory previously allocated by
+.Fn bus_dmamem_alloc .
+Any mappings
+will be invalidated.
+Arguments are as follows:
+.Bl -tag -width ".Fa vaddr"
+.It Fa dmat
+DMA tag.
+.It Fa vaddr
+Kernel virtual address of the memory.
+.It Fa map
+DMA map to be invalidated.
+.El
+.El
+.Sh RETURN VALUES
+Behavior is undefined if invalid arguments are passed to
+any of the above functions.
+If sufficient resources cannot be allocated for a given
+transaction,
+.Er ENOMEM
+is returned.
+All
+routines that are not of type
+.Vt void
+will return 0 on success or an error
+code on failure as discussed above.
+.Pp
+All
+.Vt void
+routines will succeed if provided with valid arguments.
+.Sh LOCKING
+Two locking protocols are used by
+.Nm .
+The first is a private global lock that is used to synchronize access to the
+bounce buffer pool on the architectures that make use of them.
+This lock is strictly a leaf lock that is only used internally to
+.Nm
+and is not exposed to clients of the API.
+.Pp
+The second protocol involves protecting various resources stored in the tag.
+Since almost all
+.Nm
+operations are done through requests from the driver that created the tag,
+the most efficient way to protect the tag resources is through the lock that
+the driver uses.
+In cases where
+.Nm
+acts on its own without being called by the driver, the lock primitive
+specified in the tag is acquired and released automatically.
+An example of this is when the
+.Fn bus_dmamap_load
+callback function is called from a deferred context instead of the driver
+context.
+This means that certain
+.Nm
+functions must always be called with the same lock held that is specified in the
+tag.
+These functions include:
+.Pp
+.Bl -item -offset indent -compact
+.It
+.Fn bus_dmamap_load
+.It
+.Fn bus_dmamap_load_bio
+.It
+.Fn bus_dmamap_load_ccb
+.It
+.Fn bus_dmamap_load_mbuf
+.It
+.Fn bus_dmamap_load_mbuf_sg
+.It
+.Fn bus_dmamap_load_uio
+.It
+.Fn bus_dmamap_unload
+.It
+.Fn bus_dmamap_sync
+.El
+.Pp
+There is one exception to this rule.
+It is common practice to call some of these functions during driver start-up
+without any locks held.
+So long as there is a guarantee of no possible concurrent use of the tag by
+different threads during this operation, it is safe to not hold a lock for
+these functions.
+.Pp
+Certain
+.Nm
+operations should not be called with the driver lock held, either because
+they are already protected by an internal lock, or because they might sleep
+due to memory or resource allocation.
+The following functions must not be
+called with any non-sleepable locks held:
+.Pp
+.Bl -item -offset indent -compact
+.It
+.Fn bus_dma_tag_create
+.It
+.Fn bus_dmamap_create
+.It
+.Fn bus_dmamem_alloc
+.El
+.Pp
+All other functions do not have a locking protocol and can thus be
+called with or without any system or driver locks held.
+.Sh SEE ALSO
+.Xr devclass 9 ,
+.Xr device 9 ,
+.Xr driver 9 ,
+.Xr rman 9 ,
+.Xr vslock 9
+.Pp
+.Rs
+.%A "Jason R. Thorpe"
+.%T "A Machine-Independent DMA Framework for NetBSD"
+.%J "Proceedings of the Summer 1998 USENIX Technical Conference"
+.%Q "USENIX Association"
+.%D "June 1998"
+.Re
+.Sh HISTORY
+The
+.Nm
+interface first appeared in
+.Nx 1.3 .
+.Pp
+The
+.Nm
+API was adopted from
+.Nx
+for use in the CAM SCSI subsystem.
+The alterations to the original API were aimed to remove the need for
+a
+.Vt bus_dma_segment_t
+array stored in each
+.Vt bus_dmamap_t
+while allowing callers to queue up on scarce resources.
+.Sh AUTHORS
+The
+.Nm
+interface was designed and implemented by
+.An Jason R. Thorpe
+of the Numerical Aerospace Simulation Facility, NASA Ames Research Center.
+Additional input on the
+.Nm
+design was provided by
+.An -nosplit
+.An Chris Demetriou ,
+.An Charles Hannum ,
+.An Ross Harvey ,
+.An Matthew Jacob ,
+.An Jonathan Stone ,
+and
+.An Matt Thomas .
+.Pp
+The
+.Nm
+interface in
+.Fx
+benefits from the contributions of
+.An Justin T. Gibbs ,
+.An Peter Wemm ,
+.An Doug Rabson ,
+.An Matthew N. Dodd ,
+.An Sam Leffler ,
+.An Maxime Henrion ,
+.An Jake Burkholder ,
+.An Takahashi Yoshihiro ,
+.An Scott Long
+and many others.
+.Pp
+This manual page was written by
+.An Hiten M. Pandya
+and
+.An Justin T. Gibbs .
OpenPOWER on IntegriCloud