xref: /netbsd-src/share/man/man9/bus_dma.9 (revision c2f76ff004a2cb67efe5b12d97bd3ef7fe89e18d)
1.\" $NetBSD: bus_dma.9,v 1.53 2010/05/14 18:52:46 jruoho Exp $
2.\"
3.\" Copyright (c) 1996, 1997, 1998, 2001, 2005, 2006 The NetBSD Foundation, Inc.
4.\" All rights reserved.
5.\"
6.\" This code is derived from software contributed to The NetBSD Foundation
7.\" by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
8.\" NASA Ames Research Center.
9.\"
10.\" Redistribution and use in source and binary forms, with or without
11.\" modification, are permitted provided that the following conditions
12.\" are met:
13.\" 1. Redistributions of source code must retain the above copyright
14.\"    notice, this list of conditions and the following disclaimer.
15.\" 2. Redistributions in binary form must reproduce the above copyright
16.\"    notice, this list of conditions and the following disclaimer in the
17.\"    documentation and/or other materials provided with the distribution.
18.\"
19.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22.\" PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29.\" POSSIBILITY OF SUCH DAMAGE.
30.\"
31.Dd May 14, 2010
32.Dt BUS_DMA 9
33.Os
34.Sh NAME
35.Nm bus_dma ,
36.Nm bus_dmamap_create ,
37.Nm bus_dmamap_destroy ,
38.Nm bus_dmamap_load ,
39.Nm bus_dmamap_load_mbuf ,
40.Nm bus_dmamap_load_uio ,
41.Nm bus_dmamap_load_raw ,
42.Nm bus_dmamap_unload ,
43.Nm bus_dmamap_sync ,
44.Nm bus_dmamem_alloc ,
45.Nm bus_dmamem_free ,
46.Nm bus_dmamem_map ,
47.Nm bus_dmamem_unmap ,
48.Nm bus_dmamem_mmap ,
49.Nm bus_dmatag_subregion ,
50.Nm bus_dmatag_destroy
51.Nd Bus and Machine Independent DMA Mapping Interface
52.Sh SYNOPSIS
53.In sys/bus.h
54.Ft int
55.Fn bus_dmamap_create "bus_dma_tag_t tag" "bus_size_t size" "int nsegments" \
56"bus_size_t maxsegsz" "bus_size_t boundary" "int flags" "bus_dmamap_t *dmamp"
57.Ft void
58.Fn bus_dmamap_destroy "bus_dma_tag_t tag" "bus_dmamap_t dmam"
59.Ft int
60.Fn bus_dmamap_load "bus_dma_tag_t tag" "bus_dmamap_t dmam" "void *buf" \
61"bus_size_t buflen" "struct lwp *l" "int flags"
62.Ft int
63.Fn bus_dmamap_load_mbuf "bus_dma_tag_t tag" "bus_dmamap_t dmam" \
64"struct mbuf *chain" "int flags"
65.Ft int
66.Fn bus_dmamap_load_uio "bus_dma_tag_t tag" "bus_dmamap_t dmam" \
67"struct uio *uio" "int flags"
68.Ft int
69.Fn bus_dmamap_load_raw "bus_dma_tag_t tag" "bus_dmamap_t dmam" \
70"bus_dma_segment_t *segs" "int nsegs" "bus_size_t size" "int flags"
71.Ft void
72.Fn bus_dmamap_unload "bus_dma_tag_t tag" "bus_dmamap_t dmam"
73.Ft void
74.Fn bus_dmamap_sync "bus_dma_tag_t tag" "bus_dmamap_t dmam" \
75"bus_addr_t offset" "bus_size_t len" "int ops"
76.Ft int
77.Fn bus_dmamem_alloc "bus_dma_tag_t tag" "bus_size_t size" \
78"bus_size_t alignment" "bus_size_t boundary" "bus_dma_segment_t *segs" \
79"int nsegs" "int *rsegs" "int flags"
80.Ft void
81.Fn bus_dmamem_free "bus_dma_tag_t tag" "bus_dma_segment_t *segs" "int nsegs"
82.Ft int
83.Fn bus_dmamem_map "bus_dma_tag_t tag" "bus_dma_segment_t *segs" "int nsegs" \
84"size_t size" "void **kvap" "int flags"
85.Ft void
86.Fn bus_dmamem_unmap "bus_dma_tag_t tag" "void *kva" "size_t size"
87.Ft paddr_t
88.Fn bus_dmamem_mmap "bus_dma_tag_t tag" "bus_dma_segment_t *segs" \
89"int nsegs" "off_t off" "int prot" "int flags"
90.Ft int
91.Fn bus_dmatag_subregion "bus_dma_tag_t tag" "bus_addr_t min_addr" \
92"bus_addr_t max_addr" "bus_dma_tag_t *newtag" "int flags"
93.Ft void
94.Fn bus_dmatag_destroy "bus_dma_tag_t tag"
95.Sh DESCRIPTION
96Provide a bus- and machine-independent "DMA mapping interface."
97.Sh IMPLEMENTATION NOTES
98All data structures, function prototypes, and macros will be defined
99by the port-specific header
100.In machine/bus.h .
101Note that this document
102assumes the existence of types already defined by the current "bus.h"
103interface.
104.Pp
105Unless otherwise noted, all function calls in this interface may be
106defined as
107.Xr cpp 1
108macros.
109.Sh DATA TYPES
110Individual implementations may name these structures whatever they
111wish, providing that the external representations are:
112.Bl -tag -width compact
113.It Fa bus_dma_tag_t
114A machine-dependent opaque type describing the implementation of
115DMA for a given bus.
116.It Fa bus_dma_segment_t
117A structure with at least the following members:
118.Bd -literal
119	bus_addr_t	ds_addr;
120	bus_size_t	ds_len;
121.Ed
122.Pp
123The structure may have machine-dependent members and arbitrary layout.
124The values in
125.Fa ds_addr
126and
127.Fa ds_len
128are suitable for programming into
129DMA controller address and length registers.
130.It Fa bus_dmamap_t
131A pointer to a structure with at least the following members:
132.Bd -literal
133	bus_size_t	dm_maxsegsz;
134	bus_size_t	dm_mapsize;
135	int		dm_nsegs;
136	bus_dma_segment_t *dm_segs;
137.Ed
138.Pp
139The structure may have machine-dependent members and arbitrary layout.
140The
141.Fa  dm_maxsegsz
142member indicates the maximum number of bytes that may be transferred by
143any given DMA segment.
144The
145.Fa dm_mapsize
146member indicates the size of the mapping.
147A value of 0 indicates the mapping is invalid.
148The
149.Fa dm_segs
150member may be an array of segments or a pointer to an
151array of segments.
152The
153.Fa dm_nsegs
154member indicates the number of segments in
155.Fa dm_segs .
156.El
157.Sh FUNCTIONS
158.Bl -tag -width compact
159.It Fn bus_dmamap_create "tag" "size" "nsegments" "maxsegsz" "boundary" "flags" "dmamp"
160Allocates a DMA handle and initializes it according to the parameters
161provided.
162Arguments are as follows:
163.Bl -tag -width nsegments -compact
164.It Fa tag
165This is the bus_dma_tag_t passed down from the parent driver via
166.Fa \*[Lt]bus\*[Gt]_attach_args .
167.It Fa size
168This is the maximum DMA transfer that can be mapped by the handle.
169.It Fa nsegments
170Number of segments the device can support in a single DMA transaction.
171This may be the number of scatter-gather descriptors supported by the
172device.
173.It Fa maxsegsz
174The maximum number of bytes that may be transferred by any given DMA
175segment and will be assigned to the
176.Fa dm_maxsegsz
177member.
178.It Fa boundary
179Some DMA controllers are not able to transfer data that crosses a
180particular boundary.
181This argument allows this boundary to be specified.
182The boundary lines begin at 0, and occur every
183.Fa boundary
184bytes.
185Mappings may begin on a boundary line but may not end on or
186cross a boundary line.
187If no boundary condition needs to be observed, a
188.Fa boundary
189argument of 0 should be used.
190.It Fa flags
191Flags are defined as follows:
192.Bl -tag -width BUS_DMA_ALLOCNOW -compact
193.It Dv BUS_DMA_WAITOK
194It is safe to wait (sleep) for resources during this call.
195.It Dv BUS_DMA_NOWAIT
196It is not safe to wait (sleep) for resources during this call.
197.It Dv BUS_DMA_ALLOCNOW
198Perform any resource allocation this handle may need now.
199If this is not specified, the allocation may be deferred to
200.Fn bus_dmamap_load .
201If this flag is specified,
202.Fn bus_dmamap_load
203will not block on resource
204allocation.
205.It Dv BUS_DMA_BUS[1-4]
206These flags are placeholders, and may be used by busses to provide
207bus-dependent functionality.
208.El
209.It Fa dmamp
210This is a pointer to a bus_dmamap_t.
211A DMA map will be allocated and pointed to by
212.Fa dmamp
213upon successful completion of this routine.
214.Fa dmamp
215is undefined if this routine fails.
216.El
217.Pp
218Behavior is not defined if invalid arguments are passed to
219.Fn bus_dmamap_create .
220.Pp
221Returns 0 on success, or an error code to indicate mode of failure.
222.It Fn bus_dmamap_destroy "tag" "dmam"
223Frees all resources associated with a given DMA handle.
224Arguments are as follows:
225.Bl -tag -width dmam -compact
226.It Fa tag
227This is the bus_dma_tag_t passed down from the parent driver via
228.Fa \*[Lt]bus\*[Gt]_attach_args .
229.It Fa dmam
230The DMA handle to destroy.
231.El
232.Pp
233In the event that the DMA handle contains a valid mapping,
234the mapping will be unloaded via the same mechanism used by
235.Fn bus_dmamap_unload .
236.Pp
237Behavior is not defined if invalid arguments are passed to
238.Fn bus_dmamap_destroy .
239.Pp
240If given valid arguments,
241.Fn bus_dmamap_destroy
242always succeeds.
243.It Fn bus_dmamap_load "tag" "dmam" "buf" "buflen" "l" "flags"
244Loads a DMA handle with mappings for a DMA transfer.
245It assumes that all pages involved in a DMA transfer are wired.
246Arguments are as follows:
247.Bl -tag -width buflen -compact
248.It Fa tag
249This is the bus_dma_tag_t passed down from the parent driver via
250.Fa \*[Lt]bus\*[Gt]_attach_args .
251.It Fa dmam
252The DMA handle with which to map the transfer.
253.It Fa buf
254The buffer to be used for the DMA transfer.
255.It Fa buflen
256The size of the buffer.
257.It Fa l
258Used to indicate the address space in which the buffer is located.
259If
260.Dv NULL ,
261the buffer is assumed to be in kernel space.
262Otherwise, the buffer is assumed to be in lwp
263.Fa l Ap s
264address space.
265.It Fa flags
266are defined as follows:
267.Bl -tag -width "BUS_DMA_STREAMING" -compact
268.It Dv BUS_DMA_WAITOK
269It is safe to wait (sleep) for resources during this call.
270.It Dv BUS_DMA_NOWAIT
271It is not safe to wait (sleep) for resources during this call.
272.It Dv BUS_DMA_STREAMING
273By default, the
274.Nm
275API assumes that there is coherency between memory and the device
276performing the DMA transaction.
277Some platforms, however, have special hardware, such as an
278.Dq I/O cache ,
279which may improve performance
280of some types of DMA transactions, but which break the assumption
281that there is coherency between memory and the device performing
282the DMA transaction.
283This flag allows the use of this special hardware, provided that
284the device is doing sequential, unidirectional transfers which
285conform to certain alignment and size constraints defined by the
286platform.
287If the platform does not support the feature, or if the buffer being
288loaded into the DMA map does not conform to the constraints required
289for use of the feature, then this flag will be silently ignored.
290Also refer to the use of this flag with the
291.Fn bus_dmamem_alloc
292function.
293.It Dv BUS_DMA_READ
294This is a hint to the machine-dependent back-end that indicates the
295mapping will be used only for a
296.Em "device -\*[Gt] memory"
297transaction.
298The back-end may perform optimizations based on this information.
299.It Dv BUS_DMA_WRITE
300This is a hint to the machine-dependent back-end that indicates the
301mapping will be used only for a
302.Em "memory -\*[Gt] device"
303transaction.
304The back-end may perform optimizations based on this information.
305.It Dv BUS_DMA_BUS[1-4]
306These flags are placeholders, and may be used by busses to
307provide bus-dependent functionality.
308.El
309.El
310.Pp
311As noted above, if a DMA handle is created with
312.Dv BUS_DMA_ALLOCNOW ,
313.Fn bus_dmamap_load
314will never block.
315.Pp
316If a call to
317.Fn bus_dmamap_load
318fails, the mapping in
319the DMA handle will be invalid.
320It is the responsibility of the caller to clean up any inconsistent
321device state resulting from incomplete iteration through the uio.
322.Pp
323Behavior is not defined if invalid arguments are passed to
324.Fn bus_dmamap_load .
325.Pp
326Returns 0 on success, or an error code to indicate mode of failure.
327.It Fn bus_dmamap_load_mbuf "tag" "dmam" "chain" "flags"
328This is a variation of
329.Fn bus_dmamap_load
330which maps mbuf chains
331for DMA transfers.
332Mbuf chains are assumed to be in kernel virtual address space.
333.It Fn bus_dmamap_load_uio "tag" "dmam" "uio" "flags"
334This is a variation of
335.Fn bus_dmamap_load
336which maps buffers pointed to by
337.Fa uio
338for DMA transfers.
339Determination if the buffers are in user or kernel virtual address space
340is done internally, according to
341.Fa "uio-\*[Gt]uio_vmspace" .
342See
343.Xr uiomove 9
344for details of the
345.Dv uio
346structure.
347.It Fn bus_dmamap_load_raw "tag" "dmam" "segs" "nsegs" "size" "flags"
348This is a variation of
349.Fn bus_dmamap_load
350which maps buffers
351allocated by
352.Fn bus_dmamem_alloc
353(see below).
354The
355.Fa segs
356argument is an array of bus_dma_segment_t's filled in
357by
358.Fn bus_dmamem_alloc .
359The
360.Fa nsegs
361argument is the number of segments in the array.
362The
363.Fa size
364argument is the size of the DMA transfer.
365.It Fn bus_dmamap_unload "tag" "dmam"
366Deletes the mappings for a given DMA handle.
367Arguments are as follows:
368.Bl -tag -width dmam -compact
369.It Fa tag
370This is the bus_dma_tag_t passed down from the parent driver via
371.Fa \*[Lt]bus\*[Gt]_attach_args .
372.It Fa dmam
373The DMA handle containing the mappings which are to be deleted.
374.El
375.Pp
376If the DMA handle was created with
377.Dv BUS_DMA_ALLOCNOW ,
378.Fn bus_dmamap_unload
379will not free the corresponding
380resources which were allocated by
381.Fn bus_dmamap_create .
382This is to ensure that
383.Fn bus_dmamap_load
384will never block
385on resources if the handle was created with
386.Dv BUS_DMA_ALLOCNOW .
387.Pp
388.Fn bus_dmamap_unload
389will not perform any implicit synchronization of DMA buffers.
390This must be done explicitly by
391.Fn bus_dmamap_sync .
392.Pp
393.Fn bus_dmamap_unload
394will restore the
395.Fa dm_maxsegsz
396member to its initial value assigned by
397.Fn bus_dmamap_create .
398.Pp
399Behavior is not defined if invalid arguments are passed to
400.Fn bus_dmamap_unload .
401.Pp
402If given valid arguments,
403.Fn bus_dmamap_unload
404always succeeds.
405.It Fn bus_dmamap_sync "tag" "dmam" "offset" "len" "ops"
406Performs pre- and post-DMA operation cache and/or buffer synchronization.
407Arguments are as follows:
408.Bl -tag -width offset -compact
409.It Fa tag
410This is the bus_dma_tag_t passed down from the parent driver via
411.Fa \*[Lt]bus\*[Gt]_attach_args .
412.It Fa dmam
413The DMA mapping to be synchronized.
414.It Fa offset
415The offset into the DMA mapping to synchronize.
416.It Fa len
417The length of the mapping from
418.Fa offset
419to synchronize.
420.It Fa ops
421One or more synchronization operation to perform.
422The following DMA synchronization operations are defined:
423.Bl -tag -width BUS_DMASYNC_POSTWRITE -compact
424.It Dv BUS_DMASYNC_PREREAD
425Perform any pre-read DMA cache and/or bounce operations.
426.It Dv BUS_DMASYNC_POSTREAD
427Perform any post-read DMA cache and/or bounce operations.
428.It Dv BUS_DMASYNC_PREWRITE
429Perform any pre-write DMA cache and/or bounce operations.
430.It Dv BUS_DMASYNC_POSTWRITE
431Perform any post-write DMA cache and/or bounce operations.
432.El
433.Pp
434More than one operation may performed in a given synchronization call.
435Mixing of
436.Em PRE
437and
438.Em POST
439operations is not allowed, and behavior is undefined if this is attempted.
440.El
441.Pp
442Synchronization operations are expressed from the perspective of
443the host RAM, e.g., a
444.Em "device -\*[Gt] memory"
445operation is a
446.Em READ
447and a
448.Em "memory -\*[Gt] device"
449operation is a
450.Em WRITE .
451.Pp
452.Fn bus_dmamap_sync
453may consult state kept within the DMA map to determine if the memory
454is mapped in a DMA coherent fashion.
455If so,
456.Fn bus_dmamap_sync
457may elect to skip certain expensive operations, such as flushing
458of the data cache.
459See
460.Fn bus_dmamem_map
461for more information on this subject.
462.Pp
463On platforms which implement a weak memory access ordering model,
464.Fn bus_dmamap_sync
465will always cause the appropriate memory barriers to be issued.
466.Pp
467This function exists to ensure that the host and the device have
468a consistent view of a range of DMA memory, before and after
469a DMA operation.
470.Pp
471An example of using
472.Fn bus_dmamap_sync ,
473involving multiple read-write use of a single mapping
474might look like this:
475.Bd -literal
476bus_dmamap_load(...);
477
478while (not done) {
479	/* invalidate soon-to-be-stale cache blocks */
480	bus_dmamap_sync(..., BUS_DMASYNC_PREREAD);
481
482	[ do read DMA ]
483
484	/* copy from bounce */
485	bus_dmamap_sync(..., BUS_DMASYNC_POSTREAD);
486
487	/* read data now in driver-provided buffer */
488
489	[ computation ]
490
491	/* data to be written now in driver-provided buffer */
492
493	/* flush write buffers and writeback, copy to bounce */
494	bus_dmamap_sync(..., BUS_DMASYNC_PREWRITE);
495
496	[ do write DMA ]
497
498	/* probably a no-op, but provided for consistency */
499	bus_dmamap_sync(..., BUS_DMASYNC_POSTWRITE);
500}
501
502bus_dmamap_unload(...);
503.Ed
504.Pp
505This function
506.Em must
507be called to synchronize DMA buffers before and after a DMA operation.
508Other
509.Nm
510functions can
511.Em not
512be relied on to do this synchronization implicitly.
513If DMA read and write operations are not preceded and followed by the
514appropriate synchronization operations, behavior is undefined.
515.Pp
516Behavior is not defined if invalid arguments are passed to
517.Fn bus_dmamap_sync .
518.Pp
519If given valid arguments,
520.Fn bus_dmamap_sync
521always succeeds.
522.\" XXX: This does not work with all the arguments.
523.It Fn bus_dmamem_alloc "tag" "size" "alignment" "boundary" "segs" "..."
524Allocates memory that is "DMA safe" for the bus corresponding to the
525given tag.
526.Pp
527The mapping of this memory is machine-dependent (or
528"opaque"); machine-independent code is not to assume that the
529addresses returned are valid in kernel virtual address space, or that
530the addresses returned are system physical addresses.
531The address value returned as part of
532.Fa segs
533can thus not be used to program DMA controller address registers.
534Only the values in the
535.Fa dm_segs
536array of a successfully loaded DMA map (using
537.Fn bus_dmamap_load )
538can be used for this purpose.
539.Pp
540Allocations will always be rounded to the hardware page size.
541Callers may wish to take advantage of this, and cluster allocation of small
542data structures.
543Arguments are as follows:
544.Bl -tag -width alignment -compact
545.It Fa tag
546This is the bus_dma_tag_t passed down from the parent driver via
547.Fa \*[Lt]bus\*[Gt]_attach_args .
548.It Fa size
549The amount of memory to allocate.
550.It Fa alignment
551Each segment in the allocated memory will be aligned to this value.
552If the alignment is less than a hardware page size, it will be rounded up
553to the hardware page size.
554This value must be a power of two.
555.It Fa boundary
556Each segment in the allocated memory must not cross this boundary
557(relative to zero).
558This value must be a power of two.
559A boundary value less than the size of the allocation is invalid.
560.It Fa segs
561An array of bus_dma_segment_t's, filled in as memory is allocated,
562representing the opaque addresses of the memory chunks.
563.It Fa nsegs
564Specifies the number of segments in
565.Fa segs ,
566and this is the maximum number
567of segments that the allocated memory may contain.
568.It Fa rsegs
569Used to return the actual number of segments the memory contains.
570.It Fa flags
571Flags are defined as follows:
572.Bl -tag -width BUS_DMA_STREAMING -compact
573.It Dv BUS_DMA_WAITOK
574It is safe to wait (sleep) for resources during this call.
575.It Dv BUS_DMA_NOWAIT
576It is not safe to wait (sleep) for resources during this call.
577.It Dv BUS_DMA_STREAMING
578Adjusts, if necessary, the size, alignment, and boundary constrains
579to conform to the platform-dependent requirements for the use of the
580.Dv BUS_DMA_STREAMING
581flag with the
582.Fn bus_dmamap_load
583function.
584If the platform does not support the
585.Dv BUS_DMA_STREAMING
586feature, or if the size, alignment, and boundary constraints
587would already satisfy the platform's requirements, this flag
588is silently ignored.
589The
590.Dv BUS_DMA_STREAMING
591flag will never relax the constraints specified in the call.
592.It Dv BUS_DMA_BUS[1-4]
593These flags are placeholders, and may be used by busses to provide
594bus-dependent functionality.
595.El
596.El
597.Pp
598All pages allocated by
599.Fn bus_dmamem_alloc
600will be wired down
601until they are freed by
602.Fn bus_dmamem_free .
603.Pp
604Behavior is undefined if invalid arguments are passed to
605.Fn bus_dmamem_alloc .
606.Pp
607Returns 0 on success, or an error code indicating mode of failure.
608.It Fn bus_dmamem_free "tag" "segs" "nsegs"
609Frees memory previously allocated by
610.Fn bus_dmamem_alloc .
611Any mappings
612will be invalidated.
613Arguments are as follows:
614.Bl -tag -width nsegs -compact
615.It Fa tag
616This is the bus_dma_tag_t passed down from the parent driver via
617.Fa \*[Lt]bus\*[Gt]_attach_args .
618.It Fa segs
619The array of bus_dma_segment_t's filled in by
620.Fn bus_dmamem_alloc .
621.It Fa nsegs
622The number of segments in
623.Fa segs .
624.El
625.Pp
626Behavior is undefined if invalid arguments are passed to
627.Fn bus_dmamem_free .
628.Pp
629If given valid arguments,
630.Fn bus_dmamem_free
631always succeeds.
632.It Fn bus_dmamem_map "tag" "segs" "nsegs" "size" "kvap" "flags"
633Maps memory allocated with
634.Fn bus_dmamem_alloc
635into kernel virtual address space.
636Arguments are as follows:
637.Bl -tag -width flags -compact
638.It Fa tag
639This is the bus_dma_tag_t passed down from the parent driver via
640.Fa \*[Lt]bus\*[Gt]_attach_args .
641.It Fa segs
642The array of bus_dma_segment_t's filled in by
643.Fn bus_dmamem_alloc ,
644representing the memory regions to map.
645.It Fa nsegs
646The number of segments in
647.Fa segs .
648.It Fa size
649The size of the mapping.
650.It Fa kvap
651Filled in to specify the kernel virtual address where the memory is mapped.
652.It Fa flags
653Flags are defined as follows:
654.Bl -tag -width BUS_DMA_COHERENT -compact
655.It Dv BUS_DMA_WAITOK
656It is safe to wait (sleep) for resources during this call.
657.It Dv BUS_DMA_NOWAIT
658It is not safe to wait (sleep) for resources during this call.
659.It Dv BUS_DMA_BUS[1-4]
660These flags are placeholders, and may be used by busses to provide
661bus-dependent functionality.
662.It Dv BUS_DMA_COHERENT
663This flag is a
664.Em hint
665to machine-dependent code.
666If possible, map the memory in such a way as it will be DMA coherent.
667This may include mapping the pages into uncached address space or
668setting the cache-inhibit bits in page table entries.
669If DMA coherent mappings are impossible, this flag is silently ignored.
670.Pp
671Later, when this memory is loaded into a DMA map, machine-dependent code
672will take whatever steps are necessary to determine if the memory was
673mapped in a DMA coherent fashion.
674This may include checking if the kernel virtual address lies within
675uncached address space or if the cache-inhibit bits are set in page
676table entries.
677If it is determined that the mapping is DMA coherent, state may be
678placed into the DMA map for use by later calls to
679.Fn bus_dmamap_sync .
680.Pp
681Note that a device driver must not rely on
682.Dv BUS_DMA_COHERENT
683for correct operation.
684All calls to
685.Fn bus_dmamap_sync
686must still be made.
687This flag is provided only as an optimization hint to machine-dependent code.
688.Pp
689Also note that this flag only applies to coherency between the CPU
690and memory.
691Coherency between memory and the device is controlled with a different flag.
692See the description of the
693.Fn bus_dmamap_load
694function.
695.It Dv BUS_DMA_NOCACHE
696This flag is a
697.Em hint
698to machine-dependent code.
699If possible, map the uncached memory.
700This flag may be useful in the case that the memory cache causes unexpected
701behavior of the device.
702.El
703.El
704.Pp
705Behavior is undefined if invalid arguments are passed to
706.Fn bus_dmamem_map .
707.Pp
708Returns 0 on success, or an error code indicating mode of failure.
709.It Fn bus_dmamem_unmap "tag" "kva" "size"
710Unmaps memory previously mapped with
711.Fn bus_dmamem_map ,
712freeing the
713kernel virtual address space used by the mapping.
714The arguments are as follows:
715.Bl -tag -width size -compact
716.It Fa tag
717This is the bus_dma_tag_t passed down from the parent driver via
718.Fa \*[Lt]bus\*[Gt]_attach_args .
719.It Fa kva
720The kernel virtual address of the mapped memory.
721.It Fa size
722The size of the mapping.
723.El
724.Pp
725Behavior is undefined if invalid arguments are passed to
726.Fn bus_dmamem_unmap .
727.Pp
728If given valid arguments,
729.Fn bus_dmamem_unmap
730always succeeds.
731.It Fn bus_dmamem_mmap "tag" "segs" "nsegs" "off" "prot" "flags"
732Provides support for user
733.Xr mmap 2 Ap ing
734of DMA-safe memory.
735This function is to be called by a device driver's (*d_mmap)() entry
736point, which is called by the device pager for each page to be mapped.
737The arguments are as follows:
738.Bl -tag -width nsegs -compact
739.It Fa tag
740This is the bus_dma_tag_t passed down from the parent driver via
741.Fa \*[Lt]bus\*[Gt]_attach_args .
742.It Fa segs
743The array of bus_dma_segment_t's filled in by
744.Fn bus_dmamem_alloc ,
745representing the memory to be
746.Xr mmap 2 Ap ed .
747.It Fa nsegs
748The number of elements in the
749.Fa segs
750array.
751.It Fa off
752The offset of the page in DMA memory which is to be mapped.
753.It Fa prot
754The protection codes for the mapping.
755.It Fa flags
756Flags are defined as follows:
757.Bl -tag -width BUS_DMA_COHERENT -compact
758.It Dv BUS_DMA_WAITOK
759It is safe to wait (sleep) for resources during this call.
760.It Dv BUS_DMA_NOWAIT
761It is not safe to wait (sleep) for resources during this call.
762.It Dv BUS_DMA_BUS[1-4]
763These flags are placeholders, and may be used by busses to provide
764bus-dependent functionality.
765.It Dv BUS_DMA_COHERENT
766See
767.Fn bus_dmamem_map
768above for a description of this flag.
769.It Dv BUS_DMA_NOCACHE
770See
771.Fn bus_dmamem_map
772above for a description of this flag.
773.El
774.El
775.Pp
776Behavior is undefined if invalid arguments are passed
777to
778.Fn bus_dmamem_mmap .
779.Pp
780Returns -1 to indicate failure.
781Otherwise, returns an opaque value to be interpreted by the device pager.
782.It Fn bus_dmatag_subregion "tag" "min_addr" "max_addr" "newtag" "flags"
783Given a bus_dma_tag_t
784create a new bus_dma_tag_t with a limited bus address space.
785This function should not normally be used, but is useful for devices
786that do not support the full address space of the parent bus.
787The arguments are as follows:
788.Bl -tag -width max_addr -compact
789.It Fa tag
790This is the bus_dma_tag_t to subregion.
791.It Fa min_addr
792The smallest address this new tag can address.
793.It Fa max_addr .
794The largest address this new tag can address.
795.It Fa newtag
796Pointer filled in with the address of the new bus_dma_tag_t.
797.It Fa flags
798Flags are defined as follows:
799.Bl -tag -width BUS_DMA_WAITOK -compact
800.It Dv BUS_DMA_WAITOK
801It is safe to wait (sleep) for resources during this call.
802.It Dv BUS_DMA_NOWAIT
803It is not safe to wait (sleep) for resources during this call.
804.El
805.El
806.It Fn bus_dmatag_destroy "tag"
807Free a tag created by
808.Fn bus_dmatag_subregion .
809.El
810.Sh SEE ALSO
811.Xr bus_space 9 ,
812.Xr mb 9
813.Rs
814.%A Jason Thorpe
815.%T "A Machine-Independent DMA Framework for NetBSD"
816.%I USENIX Association
817.%B Proceedings of the FREENIX Track: 1998 USENIX Annual Technical Conference
818.%P 1-12
819.%D June 15-19, 1998
820.%U http://www.usenix.org/publications/library/proceedings/usenix98/freenix/thorpe_dma.pdf
821.Re
822.Sh HISTORY
823The
824.Nm
825interface appeared in
826.Nx 1.3 .
827.Sh AUTHORS
828The
829.Nm
830interface was designed and implemented by Jason R. Thorpe of the
831Numerical Aerospace Simulation Facility, NASA Ames Research Center.
832Additional input on the
833.Nm
834design was provided by Chris Demetriou, Charles Hannum, Ross Harvey,
835Matthew Jacob, Jonathan Stone, and Matt Thomas.
836