--- /dev/null Mon Dec 16 08:44:01 2002 +++ bus_dma.9 Mon Dec 16 08:46:15 2002 @@ -0,0 +1,799 @@ +.\" $NetBSD: bus_dma.9,v 1.25 2002/10/14 13:43:16 wiz Exp $ +.\" +.\" Copyright (c) 2002, Hiten Mahesh Pandya (hiten@uk.FreeBSD.org) +.\" 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. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgment: +.\" This product includes software developed by the NetBSD +.\" Foundation, Inc. and its contributors. +.\" 4. Neither the name of The NetBSD Foundation nor the names of its +.\" contributors may be used to endorse or promote products derived +.\" from this software without specific prior written permission. +.\" +.\" 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$ +.\" $Id: bus_dma.9,v 1.3 2002/12/16 08:46:15 hiten Exp $ +.\" +.Dd February 3, 1998 +.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_mbuf , +.Nm bus_dmamap_load_uio , +.Nm bus_dmamap_load_raw , +.Nm bus_dmamap_unload , +.Nm bus_dmamap_sync , +.Nm bus_dmamem_alloc , +.Nm bus_dmamem_free , +.Nm bus_dmamem_map , +.Nm bus_dmamem_unmap , +.Nm bus_dmamem_mmap +.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_size_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_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_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_uio "bus_dma_tag_t dmat" "bus_dmamap_t map" \ +"struct uio *ui" "bus_dmamap_callback2_t *callback" "void *callback_arg" \ +"int flags" +.Ft int +.Fn bus_dmamap_load_raw "bus_dma_tag_t tag" "bus_dmamap_t dmam" \ +"bus_dma_segment_t *segs" "int nsegs" "bus_size_t size" "int flags" +.Ft void +.Fn bus_dmamap_unload "bus_dma_tag_t tag" "bus_dmamap_t dmam" +.Ft void +.Fn bus_dmamap_sync "bus_dma_tag_t tag" "bus_dmamap_t dmam" \ +"bus_addr_t offset" "bus_size_t len" "int ops" +.Ft int +.Fn bus_dmamem_alloc "bus_dma_tag_t tag" "bus_size_t size" \ +"bus_size_t alignment" "bus_size_t boundary" "bus_dma_segment_t *segs" \ +"int nsegs" "int *rsegs" "int flags" +.Ft void +.Fn bus_dmamem_free "bus_dma_tag_t tag" "bus_dma_segment_t *segs" "int nsegs" +.Ft int +.Fn bus_dmamem_map "bus_dma_tag_t tag" "bus_dma_segment_t *segs" "int nsegs" \ +"size_t size" "caddr_t *kvap" "int flags" +.Ft void +.Fn bus_dmamem_unmap "bus_dma_tag_t tag" "caddr_t kva" "size_t size" +.Ft paddr_t +.Fn bus_dmamem_mmap "bus_dma_tag_t tag" "bus_dma_segment_t *segs" \ +"int nsegs" "off_t off" "int prot" "int flags" +.Sh DESCRIPTION +Provide a bus- and machine-independent "DMA mapping interface." +.Sh NOTES +All data structures, function prototypes, and macros will be defined +by the port-specific header +.Pa Aq machine/bus.h . +Note that this document +assumes the existence of types already defined by the current "bus.h" +interface. +.Pp +Unless otherwise noted, all function calls in this interface may be +defined as +.Xr cpp 1 +macros. +.Sh DATA TYPES +Structures and type definitions used with the +.Nm +interface: +.Bl -tag -width compact +.It Fa bus_dma_tag_t +A machine-dependent opaque type describing the implementation of +DMA for a given bus. +.It Fa bus_dma_segment_t +A structure with at least the following members: +.Bd -literal + bus_addr_t ds_addr; + bus_size_t ds_len; +.Ed +.sp +The structure may have machine-dependent members and arbitrary layout. +The values in +.Fa ds_addr +and +.Fa ds_len +are suitable for programming into +DMA controller address and length registers. +.It Fa bus_dmamap_t +A pointer to a structure with at least the following members: +.Bd -literal + bus_size_t dm_mapsize; + int dm_nsegs; + bus_dma_segment_t *dm_segs; +.Ed +.sp +The structure may have machine-dependent members and arbitrary layout. +The +.Fa dm_mapsize +member indicates the size of the mapping. +A value of 0 indicates the mapping is invalid. +The +.Fa dm_segs +member may be an array of segments or a pointer to an +array of segments. +The +.Fa dm_nsegs +member indicates the number of segments in +.Fa dm_segs . +.El +.Sh FUNCTIONS +.Bl -tag -width compact +.It Fn bus_dmamap_create "tag" "size" "nsegments" "maxsegsz" "boundary" "flags" "dmamp" +Allocates a DMA handle and initializes it according to the parameters +provided. +Arguments are as follows: +.Bl -tag -width nsegments -compact +.It Fa tag +This is the bus_dma_tag_t passed down from the parent driver via +.Fa \*[Lt]bus\*[Gt]_attach_args . +.It Fa size +This is the maximum DMA transfer that can be mapped by the handle. +.It Fa nsegments +Number of segments the device can support in a single DMA transaction. +This may be the number of scatter-gather descriptors supported by the +device. +.It Fa maxsegsz +The maximum number of bytes that may be transferred by any given DMA +segment. +.It Fa boundary +Some DMA controllers are not able to transfer data that crosses a +particular boundary. +This argument allows this boundary to be specified. +The boundary lines begin at 0, and occur every +.Fa boundary +bytes. +Mappings may begin on a boundary line but may not end on or +cross a boundary line. +If no boundary condition needs to be observed, a +.Fa boundary +argument of 0 should be used. +.It Fa flags +Flags are defined as follows: +.Bl -tag -width BUS_DMA_ALLOCNOW -compact +.It Dv BUS_DMA_WAITOK +It is safe to wait (sleep) for resources during this call. +.It Dv BUS_DMA_NOWAIT +It is not safe to wait (sleep) for resources during this call. +.It Dv BUS_DMA_ALLOCNOW +Perform any resource allocation this handle may need now. +If this is not specified, the allocation may be deferred to +.Fn bus_dmamap_load . +If this flag is specified, +.Fn bus_dmamap_load +will not block on resource +allocation. +.It Dv BUS_DMA_BUS[1-4] +These flags are placeholders, and may be used by busses to provide +bus-dependent functionality. +.El +.It Fa dmamp +This is a pointer to a bus_dmamap_t. +A DMA map will be allocated and pointed to by +.Fa dmamp +upon successful completion of this routine. +.El +.Pp +Behavior is not defined if invalid arguments are passed to +.Fn bus_dmamap_create . +.Pp +Returns 0 on success, or an error code to indicate mode of failure. +.It Fn bus_dmamap_destroy "tag" "dmam" +Frees all resources associated with a given DMA handle. +Arguments are as follows: +.Bl -tag -width dmam -compact +.It Fa tag +This is the bus_dma_tag_t passed down from the parent driver via +.Fa \*[Lt]bus\*[Gt]_attach_args . +.It Fa dmam +The DMA handle to destroy. +.El +.Pp +In the event that the DMA handle contains a valid mapping, +the mapping will be unloaded via the same mechanism used by +.Fn bus_dmamap_unload . +.Pp +Behavior is not defined if invalid arguments are passed to +.Fn bus_dmamap_destroy . +.Pp +If given valid arguments, +.Fn bus_dmamap_destroy +always succeeds. +.It Fn bus_dmamap_load "tag" "dmam" "buf" "buflen" "p" "flags" +Loads a DMA handle with mappings for a DMA transfer. +It assumes that all pages involved in a DMA transfer are wired. +Arguments are as follows: +.Bl -tag -width buflen -compact +.It Fa tag +This is the bus_dma_tag_t passed down from the parent driver via +.Fa \*[Lt]bus\*[Gt]_attach_args . +.It Fa dmam +The DMA handle with which to map the transfer. +.It Fa buf +The buffer to be used for the DMA transfer. +.It Fa buflen +The size of the buffer. +.It Fa p +Used to indicate the address space in which the buffer is located. +If +.Dv NULL , +the buffer is assumed to be in kernel space. +Otherwise, the buffer is assumed to be in process +.Fa p Ns 's +address space. +.It Fa flags +are defined as follows: +.Bl -tag -width "BUS_DMA_STREAMING" -compact +.It Dv BUS_DMA_WAITOK +It is safe to wait (sleep) for resources during this call. +.It Dv BUS_DMA_NOWAIT +It is not safe to wait (sleep) for resources during this call. +.It Dv BUS_DMA_STREAMING +By default, the +.Nm +API assumes that there is coherency between memory and the device +performing the DMA transaction. +Some platforms, however, have special hardware, such as an +.Dq I/O cache , +which may improve performance +of some types of DMA transactions, but which break the assumption +that there is coherency between memory and the device performing +the DMA transaction. +This flag allows the use of this special hardware, provided that +the device is doing sequential, unidirectional transfers which +conform to certain alignment and size constraints defined by the +platform. +If the platform does not support the feature, or if the buffer being +loaded into the DMA map does not conform to the constraints required +for use of the feature, then this flag will be silently ignored. +Also refer to the use of this flag with the +.Fn bus_dmamem_alloc +function. +.It Dv BUS_DMA_READ +This is a hint to the machine-dependent back-end that indicates the +mapping will be used only for a +.Em "device -\*[Gt] memory" +transaction. +The back-end may perform optimizations based on this information. +.It Dv BUS_DMA_WRITE +This is a hint to the machine-dependent back-end that indicates the +mapping will be used only for a +.Em "memory -\*[Gt] device" +transaction. +The back-end may perform optimizations based on this information. +.It Dv BUS_DMA_BUS[1-4] +These flags are placeholders, and may be used by busses to +provide bus-dependent functionality. +.El +.El +.Pp +As noted above, if a DMA handle is created with +.Dv BUS_DMA_ALLOCNOW , +.Fn bus_dmamap_load +will never block. +.Pp +If a call to +.Fn bus_dmamap_load +fails, the mapping in +the DMA handle will be invalid. +It is the responsibility of the caller to clean up any inconsistent +device state resulting from incomplete iteration through the uio. +.Pp +Behavior is not defined if invalid arguments are passed to +.Fn bus_dmamap_load . +.Pp +Returns 0 on success, or an error code to indicate mode of failure. +.It Fn bus_dmamap_load_mbuf "tag" "dmam" "chain" "flags" +This is a variation of +.Fn bus_dmamap_load +which maps mbuf chains +for DMA transfers. +Mbuf chains are assumed to be in kernel virtual address space. +.It Fn bus_dmamap_load_uio "tag" "dmam" "uio" "flags" +This is a variation of +.Fn bus_dmamap_load +which maps buffers pointed to by +.Fa uio +for DMA transfers. +The value of +.Fa "uio-\*[Gt]uio_segflg" +will +determine if the buffers are in user or kernel virtual address space. +If the buffers are in user address space, the buffers are assumed to be +in +.Fa "uio-\*[Gt]uio_procp" Ns 's +address space. +.It Fn bus_dmamap_load_raw "tag" "dmam" "segs" "nsegs" "size" "flags" +This is a variation of +.Fn bus_dmamap_load +which maps buffers +allocated by +.Fn bus_dmamem_alloc +(see below). +The +.Fa segs +argument is an array of bus_dma_segment_t's filled in +by +.Fn bus_dmamem_alloc . +The +.Fa nsegs +argument is the number of segments in the array. +The +.Fa size +argument is the size of the DMA transfer. +.It Fn bus_dmamap_unload "tag" "dmam" +Deletes the mappings for a given DMA handle. +Arguments are as follows: +.Bl -tag -width dmam -compact +.It Fa tag +This is the bus_dma_tag_t passed down from the parent driver via +.Fa \*[Lt]bus\*[Gt]_attach_args . +.It Fa dmam +The DMA handle containing the mappings which are to be deleted. +.El +.Pp +If the DMA handle was created with +.Dv BUS_DMA_ALLOCNOW , +.Fn bus_dmamap_unload +will not free the corresponding +resources which were allocated by +.Fn bus_dmamap_create . +This is to ensure that +.Fn bus_dmamap_load +will never block +on resources if the handle was created with +.Dv BUS_DMA_ALLOCNOW . +.Pp +.Fn bus_dmamap_unload +will not perform any implicit synchronization of DMA buffers. +This must be done explicitly by +.Fn bus_dmamap_sync . +.Pp +Behavior is not defined if invalid arguments are passed to +.Fn bus_dmamap_unload . +.Pp +If given valid arguments, +.Fn bus_dmamap_unload +always succeeds. +.It Fn bus_dmamap_sync "tag" "dmam" "offset" "len" "ops" +Performs pre- and post-DMA operation cache and/or buffer synchronization. +Arguments are as follows: +.Bl -tag -width offset -compact +.It Fa tag +This is the bus_dma_tag_t passed down from the parent driver via +.Fa \*[Lt]bus\*[Gt]_attach_args . +.It Fa dmam +The DMA mapping to be synchronized. +.It Fa offset +The offset into the DMA mapping to synchronize. +.It Fa len +The length of the mapping from +.Fa offset +to synchronize. +.It Fa ops +One or more synchronization operation to perform. +The following DMA synchronization operations are defined: +.Bl -tag -width BUS_DMASYNC_POSTWRITE -compact +.It Dv BUS_DMASYNC_PREREAD +Perform any pre-read DMA cache and/or bounce operations. +.It Dv BUS_DMASYNC_POSTREAD +Perform any post-read DMA cache and/or bounce operations. +.It Dv BUS_DMASYNC_PREWRITE +Perform any pre-write DMA cache and/or bounce operations. +.It Dv BUS_DMASYNC_POSTWRITE +Perform any post-write DMA cache and/or bounce operations. +.El +.Pp +More than one operation may performed in a given synchronization call. +Mixing of +.Em PRE +and +.Em POST +operations is not allowed, and behavior is undefined if this is attempted. +.El +.Pp +Synchronization operations are expressed from the perspective of +the host RAM, e.g., a +.Em "device -\*[Gt] memory" +operation is a +.Em READ +and a +.Em "memory -\*[Gt] device" +operation is a +.Em WRITE . +.Pp +.Fn bus_dmamap_sync +may consult state kept within the DMA map to determine if the memory +is mapped in a DMA coherent fashion. +If so, +.Fn bus_dmamap_sync +may elect to skip certain expensive operations, such as flushing +of the data cache. +See +.Fn bus_dmamem_map +for more information on this subject. +.Pp +On platforms which implement reordered stores, +.Fn bus_dmamap_sync +will always cause the store buffer to be flushed. +.Pp +This function exists to ensure that the host and the device have +a consistent view of a range of DMA memory, before and after +a DMA operation. +.Pp +An example of using +.Fn bus_dmamamp_sync , +involving multiple read-write use of a single mapping +might look like this: +.Bd -literal +bus_dmamap_load(...); + +while (not done) { + /* invalidate soon-to-be-stale cache blocks */ + bus_dmamap_sync(..., BUS_DMASYNC_PREREAD); + + [ do read DMA ] + + /* copy from bounce */ + bus_dmamap_sync(..., BUS_DMASYNC_POSTREAD); + + /* read data now in driver-provided buffer */ + + [ computation ] + + /* data to be written now in driver-provided buffer */ + + /* flush write buffers and writeback, copy to bounce */ + bus_dmamap_sync(..., BUS_DMASYNC_PREWRITE); + + [ do write DMA ] + + /* probably a no-op, but provided for consistency */ + bus_dmamap_sync(..., BUS_DMASYNC_POSTWRITE); +} + +bus_dmamap_unload(...); +.Ed +.Pp +This function +.Em must +be called to synchronize DMA buffers before and after a DMA operation. +Other +.Nm +functions can +.Em not +be relied on to do this synchronization implicitly. +If DMA read and write operations are not preceded and followed by the +appropriate synchronization operations, behavior is undefined. +.Pp +Behavior is not defined if invalid arguments are passed to +.Fn bus_dmamap_sync . +.Pp +If given valid arguments, +.Fn bus_dmamap_sync +always succeeds. +.\" XXX: This does not work with all the arguments. +.It Fn bus_dmamem_alloc "tag" "size" "alignment" "boundary" "segs" "..." +Allocates memory that is "DMA safe" for the bus corresponding to the +given tag. +.Pp +The mapping of this memory is machine-dependent (or +"opaque"); machine-independent code is not to assume that the +addresses returned are valid in kernel virtual address space, or that +the addresses returned are system physical addresses. +The address value returned as part of +.Fa segs +can thus not be used to program DMA controller address registers. +Only the values in the +.Fa dm_segs +array of a successfully loaded DMA map (using +.Fn bus_dmamap_load ) +can be used for this purpose. +.Pp +Allocations will always be rounded to the hardware page size. +Callers may wish to take advantage of this, and cluster allocation of small +data structures. +Arguments are as follows: +.Bl -tag -width alignment -compact +.It Fa tag +The is the bus_dma_tag_t passed down from the parent driver via +.Fa \*[Lt]bus\*[Gt]_attach_args . +.It Fa size +The amount of memory to allocate. +.It Fa alignment +Each segment in the allocated memory will be aligned to this value. +If the alignment is less than a hardware page size, it will be rounded up +to the hardware page size. +This value must be a power of two. +.It Fa boundary +Each segment in the allocated memory must not cross this boundary +(relative to zero). +This value must be a power of two. +A boundary value less than the size of the allocation is invalid. +.It Fa segs +An array of bus_dma_segment_t's, filled in as memory is allocated, +representing the opaque addresses of the memory chunks. +.It Fa nsegs +Specifies the number of segments in +.Fa segs , +and this is the maximum number +of segments that the allocated memory may contain. +.It Fa rsegs +Used to return the actual number of segments the memory contains. +.It Fa flags +Flags are defined as follows: +.Bl -tag -width BUS_DMA_STREAMING -compact +.It Dv BUS_DMA_WAITOK +It is safe to wait (sleep) for resources during this call. +.It Dv BUS_DMA_NOWAIT +It is not safe to wait (sleep) for resources during this call. +.It Dv BUS_DMA_STREAMING +Adjusts, if necessary, the size, alignment, and boundary constrains +to conform to the platform-dependent requirements for the use of the +.Dv BUS_DMA_STREAMING +flag with the +.Fn bus_dmamap_load +function. +If the platform does not support the +.Dv BUS_DMA_STREAMING +feature, or if the size, alignment, and boundary constraints +would already satisfy the platform's requirements, this flag +is silently ignored. +The +.Dv BUS_DMA_STREAMING +flag will never relax the constraints specified in the call. +.It Dv BUS_DMA_BUS[1-4] +These flags are placeholders, and may be used by busses to provide +bus-dependent functionality. +.El +.El +.Pp +All pages allocated by +.Fn bus_dmamem_alloc +will be wired down +until they are freed by +.Fn bus_dmamem_free . +.Pp +Behavior is undefined if invalid arguments are passed to +.Fn bus_dmamem_alloc . +.Pp +Returns 0 on success, or an error code indicating mode of failure. +.It Fn bus_dmamem_free "tag" "segs" "nsegs" +Frees memory previously allocated by +.Fn bus_dmamem_alloc . +Any mappings +will be invalidated. +Arguments are as follows: +.Bl -tag -width nsegs -compact +.It Fa tag +This is the bus_dma_tag_t passed down from the parent driver via +.Fa \*[Lt]bus\*[Gt]_attach_args . +.It Fa segs +The array of bus_dma_segment_t's filled in by +.Fn bus_dmamem_alloc . +.It Fa nsegs +The number of segments in +.Fa segs . +.El +.Pp +Behavior is undefined if invalid arguments are passed to +.Fn bus_dmamem_free . +.Pp +If given valid arguments, +.Fn bus_dmamem_free +always succeeds. +.It Fn bus_dmamem_map "tag" "segs" "nsegs" "size" "kvap" "flags" +Maps memory allocated with +.Fn bus_dmamem_alloc +into kernel virtual address space. +Arguments are as follows: +.Bl -tag -width flags -compact +.It Fa tag +This is the bus_dma_tag_t passed down from the parent driver via +.Fa \*[Lt]bus\*[Gt]_attach_args . +.It Fa segs +The array of bus_dma_segment_t's filled in by +.Fn bus_dmamem_alloc , +representing the memory regions to map. +.It Fa nsegs +The number of segments in +.Fa segs . +.It Fa size +The size of the mapping. +.It Fa kvap +Filled in to specify the kernel virtual address where the memory is mapped. +.It Fa flags +Flags are defined as follows: +.Bl -tag -width BUS_DMAMEM_NOSYNC -compact +.It Dv BUS_DMA_WAITOK +It is safe to wait (sleep) for resources during this call. +.It Dv BUS_DMA_NOWAIT +It is not safe to wait (sleep) for resources during this call. +.It Dv BUS_DMA_BUS[1-4] +These flags are placeholders, and may be used by busses to provide +bus-dependent functionality. +.It Dv BUS_DMAMEM_NOSYNC +This flag is a +.Em hint +to machine-dependent code. +If possible, map the memory in such a way as it will be DMA coherent. +This may include mapping the pages into uncached address space or +setting the cache-inhibit bits in page table entries. +If DMA coherent mappings are impossible, this flag is silently ignored. +.Pp +Later, when this memory is loaded into a DMA map, machine-dependent code +will take whatever steps are necessary to determine if the memory was +mapped in a DMA coherent fashion. +This may include checking if the kernel virtual address lies within +uncached address space or if the cache-inhibit bits are set in page +table entries. +If it is determined that the mapping is DMA coherent, state may be +placed into the DMA map for use by later calls to +.Fn bus_dmamap_sync . +.Pp +Note that a device driver must not rely on +.Dv BUS_DMAMEM_NOSYNC +for correct operation. +All calls to +.Fn bus_dmamap_sync +must still be made. +This flag is provided only as an optimization hint to machine-dependent code. +.Pp +Also note that this flag only applies to coherency between the CPU +and memory. +Coherency between memory and the device is controlled with a different flag. +See the description of the +.Fn bus_dmamap_load +function. +.El +.El +.Pp +Behavior is undefined if invalid arguments are passed to +.Fn bus_dmamem_map . +.Pp +Returns 0 on success, or an error code indicating mode of failure. +.It Fn bus_dmamem_unmap "tag" "kva" "size" +Unmaps memory previously mapped with +.Fn bus_dmamem_map , +freeing the +kernel virtual address space used by the mapping. +The arguments are as follows: +.Bl -tag -width size -compact +.It Fa tag +This is the bus_dma_tag_t passed down from the parent driver via +.Fa \*[Lt]bus\*[Gt]_attach_args . +.It Fa kva +The kernel virtual address of the mapped memory. +.It Fa size +The size of the mapping. +.El +.Pp +Behavior is undefined if invalid arguments are passed to +.Fn bus_dmamem_unmap . +.Pp +If given valid arguments, +.Fn bus_dmamem_unmap +always succeeds. +.It Fn bus_dmamem_mmap "tag" "segs" "nsegs" "off" "prot" "flags" +Provides support for user +.Xr mmap 2 Ns 'ing +of DMA-safe memory. +This function is to be called by a device driver's (*d_mmap)() entry +point, which is called by the device pager for each page to be mapped. +The arguments are as follows: +.Bl -tag -width nsegs -compact +.It Fa tag +This is the bus_dma_tag_t passed down from the parent driver via +.Fa \*[Lt]bus\*[Gt]_attach_args . +.It Fa segs +The array of bus_dma_segment_t's filled in by +.Fn bus_dmamem_alloc , +representing the memory to be +.Xr mmap 2 Ns 'ed . +.It Fa nsegs +The number of elements in the +.Fa segs +array. +.It Fa off +The offset of the page in DMA memory which is to be mapped. +.It Fa prot +The protection codes for the mapping. +.It Fa flags +Flags are defined as follows: +.Bl -tag -width BUS_DMAMEM_NOSYNC -compact +.It Dv BUS_DMA_WAITOK +It is safe to wait (sleep) for resources during this call. +.It Dv BUS_DMA_NOWAIT +It is not safe to wait (sleep) for resources during this call. +.It Dv BUS_DMA_BUS[1-4] +These flags are placeholders, and may be used by busses to provide +bus-dependent functionality. +.It Dv BUS_DMAMEM_NOSYNC +See +.Fn bus_dmamem_map +above for a description of this flag. +.El +.El +.Pp +Behavior is undefined if invalid arguments are passed +to +.Fn bus_dmamem_mmap . +.Pp +Returns -1 to indicate failure. +Otherwise, returns an opaque value to be interpreted by the device pager. +.El +.Sh SEE ALSO +.Xr bus_space 9 +.Sh HISTORY +The +.Nm +interface appeared in +.Nx 1.3 . +It was than ported to +.Fx 3.0 +.Sh IMPLEMENTATION NOTES +Some routines from the +.Nx +.Nm interface are not available currently. +.Nm . +.Sh AUTHORS +The +.Nm +interface was designed and implemented by Jason R. Thorpe of the +Numerical Aerospace Simulation Facility, NASA Ames Research Center. +Additional input on the +.Nm +design was provided by Chris Demetriou, Charles Hannum, Ross Harvey, +Matthew Jacob, Jonathan Stone, and Matt Thomas. +.Pp +.Fx +specific conversions were done by +.An Hiten Pandya .