673 lines
21 KiB
Groff
673 lines
21 KiB
Groff
.\" $NetBSD: bus_dma.9,v 1.11 1999/03/16 00:40:47 garbled Exp $
|
|
.\"
|
|
.\" Copyright (c) 1996, 1997, 1998 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.
|
|
.\"
|
|
.Dd February 3, 1998
|
|
.Dt BUS_DMA 9
|
|
.Os
|
|
.Sh NAME
|
|
.Nm bus_dma ,
|
|
.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
|
|
.Fd #include <machine/bus.h>
|
|
.Ft int
|
|
.Fn bus_dmamap_create "bus_dma_tag_t tag" "bus_size_t size" "int nsegments" \
|
|
"bus_size_t maxsegsz" "bus_size_t boundary" "int flags" "bus_dmamap_t *dmamp"
|
|
.Ft void
|
|
.Fn bus_dmamap_destroy "bus_dma_tag_t tag" "bus_dmamap_t dmam"
|
|
.Ft int
|
|
.Fn bus_dmamap_load "bus_dma_tag_t tag" "bus_dmamap_t dmam" "void *buf" \
|
|
"bus_size_t buflen" "struct proc *p" "int flags"
|
|
.Ft int
|
|
.Fn bus_dmamap_load_mbuf "bus_dma_tag_t tag" "bus_dmamap_t dmam" \
|
|
"struct mbuf *chain" "int flags"
|
|
.Ft int
|
|
.Fn bus_dmamap_load_uio "bus_dma_tag_t tag" "bus_dmamap_t dmam" \
|
|
"struct uio *uio" "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 int
|
|
.Fn bus_dmamem_mmap "bus_dma_tag_t tag" "bus_dma_segment_t *segs" \
|
|
"int nsegs" "int off" "int prot" "int flags"
|
|
.Sh DESCRIPTION
|
|
Provide a bus- and machine-independent "DMA mapping interface."
|
|
.Sh NOTES
|
|
.Pp
|
|
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
|
|
.Pp
|
|
Individual implementations may name these structures whatever they
|
|
wish, providing that the external representations are:
|
|
.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 <bus>_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 <bus>_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 <bus>_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_BUS[1-4]" -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.
|
|
.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->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->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 <bus>_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
|
|
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 <bus>_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 -> memory"
|
|
operation is a
|
|
.Em READ
|
|
and a
|
|
.Em "memory -> device"
|
|
operation is a
|
|
.Em WRITE .
|
|
.Pp
|
|
.Fn bus_dmamp_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 so that multiple read and write transfers can be
|
|
performed with the same buffer, and so that drivers can explicitly
|
|
inform the
|
|
.Nm
|
|
code when their data is 'ready' in its DMA buffer.
|
|
.Pp
|
|
An example of multiple read-write use of a single mapping
|
|
might look like:
|
|
.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
|
|
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. 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.
|
|
.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 <bus>_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_BUS[1-4] -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.
|
|
.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 <bus>_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 <bus>_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_DMA_COHERENT -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_DMA_COHERENT
|
|
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 implementation of DMA coherent mappings is impossible, this
|
|
is 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 .
|
|
.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 <bus>_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 <bus>_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_DMA_COHERENT -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_DMA_COHERENT
|
|
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 AUTHOR
|
|
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.
|
|
.Sh HISTORY
|
|
The
|
|
.Nm
|
|
interface appeared in
|
|
.Nx 1.3 .
|