1 .\" $NetBSD: 3.me,v 1.1 1998/07/15 00:34:54 thorpej Exp $
3 .\" Copyright (c) 1998 Jason R. Thorpe.
4 .\" All rights reserved.
6 .\" Redistribution and use in source and binary forms, with or without
7 .\" modification, are permitted provided that the following conditions
9 .\" 1. Redistributions of source code must retain the above copyright
10 .\" notice, this list of conditions and the following disclaimer.
11 .\" 2. Redistributions in binary form must reproduce the above copyright
12 .\" notice, this list of conditions and the following disclaimer in the
13 .\" documentation and/or other materials provided with the distribution.
14 .\" 3. All advertising materials mentioning features or use of this software
15 .\" must display the following acknowledgements:
16 .\" This product includes software developed for the NetBSD Project
17 .\" by Jason R. Thorpe.
18 .\" 4. The name of the author may not be used to endorse or promote products
19 .\" derived from this software without specific prior written permission.
21 .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 .\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 .\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 .\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 .\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26 .\" BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27 .\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28 .\" AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29 .\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 .sh 1 "The \fIbus_dma\fB interface"
35 What follows is a description of \fIbus_dma\fR, the DMA portion of the
36 machine-independent bus access interface in NetBSD, commonly referred to
37 as \fIbus.h\fR\**. The DMA portion of the interface is comprised of
38 three DMA-specific data types and thirteen function calls. The
39 \fIbus_dma\fR interface also shares two data types with the
40 \fIbus_space\fR interface.
42 \**The name is derived from the name of the include file that exports
46 The \fIbus_dma\fR functional interface is split into two categories:
47 mapping calls and memory handling calls. The function calls themselves
48 may be implemented as \fIcpp(1)\fR macros.
51 The first of the two data types shared with the \fIbus_space\fR
52 interface is the \fIbus_addr_t\fR type, which represents device bus
53 addresses to be used for CPU access or DMA, and must be large enough to
54 specify the largest possible bus address on the system. The second is
55 the \fIbus_size_t\fR type, which represents sizes of bus address ranges.
57 The implementation of DMA on a given host/bus combination is described
58 by the \fIbus_dma_tag_t\fR. This opaque type is passed to a bus's
59 autoconfiguration machinery by machine-dependent code. The bus layer
60 in turn passes it down to the device drivers. This tag is the first
61 argument to every function in the interface.
63 Individual DMA segments are described by the \fIbus_dma_segment_t\fR.
64 This type is a structure with two publicly accessible members. The first
65 member, \fIds_addr\fR, is a \fIbus_addr_t\fR containing the address of a
66 DMA segment. The second, \fIds_len\fR, is a
67 \fIbus_size_t\fR containing the length of the segment.
69 The third, and probably most important, data type is the \fIbus_dmamap_t\fR.
70 This type is a pointer to a structure which describes an individual DMA
71 mapping. The structure has three public members. The first member,
72 \fIdm_mapsize\fR is a \fIbus_size_t\fR describing the length of the
73 mapping, when valid. A \fIdm_mapsize\fR of 0 indicates that the
74 mapping is invalid. The second member, \fIdm_nsegs\fR, is an \fIint\fR
75 which contains the number of DMA segments that comprise the mapping.
76 The third public member, \fIdm_segs\fR, is an array or a pointer to
77 an array of \fIbus_dma_segment_t\fR structures.
79 In addition to data types, the \fIbus_dma\fR interface also defines
80 a set of flags which are passed to some of the interface's functions.
81 Two of these flags, \fBBUS_DMA_WAITOK\fR and \fBBUS_DMA_NOWAIT\fR,
82 indicate to the function that waiting for resources to become available
83 is or is not allowed\**. There
84 are also four placeholder flags, \fBBUS_DMA_BUS1\fR through
85 \fBBUS_DMA_BUS4\fR. These flags are reserved for the individual
86 bus layers, which may need to define special semantics specific to
87 that bus. An example of this is the ability of VESA local bus
88 devices to use 32-bit DMA addresses; while the kernel considers
89 such devices to be logically connected to the ISA bus, they are not
90 limited to the addressing constraints of other ISA devices.
91 The placeholder flags allow such special cases to be handled on
94 \**Waiting (also called "blocking") is allowed only if the kernel is
95 running in a process context, as opposed to the interrupt context used
96 when handling device interrupts.
98 .sh 2 "Mapping functions"
100 There are eight functions in the \fIbus_dma\fR interface that
101 operate on DMA maps. These can be sub-categorized into functions
102 that create and destroy maps, functions that load and unload mappings,
103 and functions that synchronize maps.
105 The first two functions fall into the create/destroy sub-category.
106 The \fIbus_dmamap_create()\fR function creates a DMA map and initializes
107 it according to the parameters provided. The parameters include the
108 maximum DMA transfer size the DMA map will map, the maximum number of
109 DMA segments, the maximum size of any given segment, and any DMA
110 boundary limitations. In addition to the standard flags,
111 \fIbus_dmamap_create()\fR also takes the flag \fBBUS_DMA_ALLOCNOW\fR.
112 This flag indicates that all resources necessary to map the maximum
113 size transfer should be allocated when the map is created, and is useful
114 in case the driver must load the DMA map at a time where blocking is not
115 allowed, such as in interrupt context. The \fIbus_dmamap_destroy()\fR
116 function destroys a DMA map, and frees any resources that may be assigned
119 The next five functions fall into the load/unload sub-category. The
120 two basic functions are \fIbus_dmamap_load()\fR and
121 \fIbus_dmamap_unload()\fR. The former maps a DMA transfer to or from
122 a linear buffer. This linear buffer may be mapped into either
123 kernel or a process's virtual address space.
124 The latter unloads the mappings previously
125 loaded into the DMA map. If the \fBBUS_DMA_ALLOCNOW\fR flag was
126 specified when the map was created, \fIbus_dmamap_load()\fR will not
127 block or fail on resource allocation. Similarly, when the map is
128 unloaded, the mapping resources will not be freed.
130 In addition to linear buffers handled by the basic \fIbus_dmamap_load()\fR,
131 there are three alternate data buffer structures handled by the interface.
132 The \fIbus_dmamap_load_mbuf()\fR function operates on mbuf chains. The
133 individual data buffers are assumed to be in kernel virtual
134 address space. The \fIbus_dmamap_load_uio()\fR function operates
135 on \fIuio\fR structures, from which it extracts information about the
136 address space in which the data resides. Finally, the
137 \fIbus_dmamap_load_raw()\fR function operates on raw memory, which
138 is not mapped into any virtual address space. All DMA maps loaded with
139 these functions are unloaded with the \fIbus_dmamap_unload()\fR function.
141 Finally, the map synchronization sub-category includes one function:
142 \fIbus_dmamap_sync()\fR. This function performs the four DMA
143 synchronization operations necessary to handle caches and DMA bouncing.
144 The four operations are:
150 BUS_DMASYNC_POSTWRITE
153 The direction is expressed from the perspective of the host's memory.
154 In other words, a device-to-memory transfer is a read, and a
155 memory-to-device transfer is
156 a write. The synchronization operations are expressed as flags,
157 so it is possible to combine \fBREAD\fR and \fBWRITE\fR operations
158 in a single call. This is especially useful for synchronizing
159 mappings of device control descriptors. Mixing of \fBPRE\fR and
160 \fBPOST\fR operations is not allowed.
162 In addition to the map and operation arguments, \fIbus_dmamap_sync()\fR
163 also takes offset and length arguments. This is done in order to
164 support partial syncs. In the case where a control descriptor
165 is DMA'd to a device, it may be undesirable to synchronize the entire
166 mapping, as doing so may be inefficient or even destructive to other
167 control descriptors. Synchronizing the entire mapping is supported
168 by passing an offset of 0 and the length specified by the map's
170 .sh 2 "Memory handling functions"
172 There are two sub-categories of functions that handle DMA-safe
173 memory in the \fIbus_dma\fR interface: memory allocation and
176 The first function in the memory allocation sub-category,
177 \fIbus_dmamem_alloc()\fR, allocates memory which has the specified
178 attributes. The attributes that may be specified are: the size of the
179 memory region to allocate, the alignment of each segment in the
180 allocation, any boundary limitations, and the maximum number
181 of DMA segments that may make up the allocation. The function
182 fills in a provided array of \fIbus_dma_segment_t\fRs and indicates
183 the number of valid segments in the array. Memory allocated
184 by this interface is raw memory\**; it is not mapped into any virtual
185 address space. Once it is no longer in use, it may be freed with
186 the \fIbus_dmamem_free()\fR function.
188 \**This implies that \fIbus_dmamap_load_raw()\fR is an appropriate
189 interface for mapping a DMA transfer to or from memory allocated by
193 In order for the kernel or a user process to access the memory,
194 it must be mapped either into the kernel address space or the process's
196 operations are performed by the memory mapping sub-category of DMA-safe
197 memory handling functions.
198 The \fIbus_dmamem_map()\fR function maps the specified DMA-safe
199 raw memory into the kernel address space. The address
200 of the mapping is returned by filling in a pointer passed
201 by reference. Memory mapped in this manner may be unmapped by
202 calling \fIbus_dmamem_unmap()\fR.
204 DMA-safe raw memory may be mapped into a process's address space via
205 a device driver's \fImmap()\fR entry point. In order to do this,
206 the VM system's device pager repeatedly calls the driver,
207 once for each page that is to be mapped. The driver translates
208 the user-specified mmap offset into a DMA memory offset, and
209 calls the \fIbus_dmamem_mmap()\fR function to translate the
210 memory offset into an opaque value to be interpreted
211 by the \fIpmap module\**\fR. The device pager invokes the
212 pmap module to translate the mmap cookie into a physical page
213 address which is then mapped into the process's address space.
215 \**The pmap module is the machine-dependent layer of the NetBSD
216 virtual memory system.
219 There are currently no methods for the virtual memory system to specify
220 that an mmap'd area is being unmapped, or for the device driver to specify
221 to the virtual memory system that a mmap'd region must be forcibly unmapped
222 (for example, if a hot-swapable device has been removed from the system).
223 This is widely regarded as a bug, and may be addressed in a future version
224 of the NetBSD virtual memory system. If a change to this effect is made,
225 the \fIbus_dma\fR interface will have to be adjusted accordingly.