diff options
Diffstat (limited to 'share/man/man9/bus_dma.9')
-rw-r--r-- | share/man/man9/bus_dma.9 | 1059 |
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 . |