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