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