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