xref: /openbsd-src/share/man/man9/bus_dma.9 (revision d13be5d47e4149db2549a9828e244d59dbc43f15)
1.\"	$OpenBSD: bus_dma.9,v 1.29 2010/12/26 15:40:57 miod 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: December 26 2010 $
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_ZERO
626The memory allocated should be zeroed.
627.It Dv BUS_DMA_STREAMING
628Adjusts, if necessary, the size, alignment, and boundary constraints
629to conform to the platform-dependent requirements for the use of the
630.Dv BUS_DMA_STREAMING
631flag with the
632.Fn bus_dmamap_load
633function.
634If the platform does not support the
635.Dv BUS_DMA_STREAMING
636feature, or if the size, alignment, and boundary constraints
637would already satisfy the platform's requirements, this flag
638is silently ignored.
639The
640.Dv BUS_DMA_STREAMING
641flag will never relax the constraints specified in the call.
642.It Dv BUS_DMA_BUS[1-4]
643These flags are placeholders, and may be used by buses to provide
644bus-dependent functionality.
645.El
646.El
647.Pp
648All pages allocated by
649.Fn bus_dmamem_alloc
650will be wired down until they are freed by
651.Fn bus_dmamem_free .
652.Pp
653The
654.Fn bus_dmamem_free
655function frees memory previously allocated by
656.Fn bus_dmamem_alloc ,
657invalidating any mapping.
658This function always succeeds if given valid arguments.
659.Pp
660The
661.Fn bus_dmamem_free
662arguments are as follows:
663.Bl -tag -width nsegs -compact
664.It Fa tag
665The
666.Fa bus_dma_tag_t
667passed down from the parent driver via
668.Fa <bus>_attach_args .
669.It Fa segs
670The
671.Fa bus_dma_segment_t
672array filled in by
673.Fn bus_dmamem_alloc .
674.It Fa nsegs
675The number of segments in
676.Fa segs .
677.El
678.Sh MAPPING DMA-SAFE MEMORY
679.nr nS 1
680.Ft int
681.Fn bus_dmamem_map "bus_dma_tag_t tag" "bus_dma_segment_t *segs" "int nsegs" \
682                   "size_t size" "caddr_t *kvap" "int flags"
683.Ft void
684.Fn bus_dmamem_unmap "bus_dma_tag_t tag" "caddr_t kva" "size_t size"
685.Ft paddr_t
686.Fn bus_dmamem_mmap "bus_dma_tag_t tag" "bus_dma_segment_t *segs" \
687                    "int nsegs" "off_t off" "int prot" "int flags"
688.nr nS 0
689.Pp
690The
691.Fn bus_dmamem_map
692function maps memory allocated with
693.Fn bus_dmamem_alloc
694into kernel virtual address space.
695This function returns 0 on success, an error code otherwise, and must not be
696called from an interrupt context.
697.Pp
698The
699.Fn bus_dmamem_map
700arguments are as follows:
701.Bl -tag -width flags -compact
702.It Fa tag
703The
704.Fa bus_dma_tag_t
705passed down from the parent driver via
706.Fa <bus>_attach_args .
707.It Fa segs
708The
709.Fa bus_dma_segment_t
710array filled in by
711.Fn bus_dmamem_alloc ,
712representing the memory regions to map.
713.It Fa nsegs
714The number of segments in
715.Fa segs .
716.It Fa size
717The size of the mapping.
718.It Fa kvap
719Filled in to specify the kernel virtual address where the memory is
720mapped.
721.It Fa flags
722Flags are defined as follows:
723.Bl -tag -width BUS_DMA_COHERENT -compact
724.It Dv BUS_DMA_WAITOK
725It is safe to wait (sleep) for resources during this call.
726.It Dv BUS_DMA_NOWAIT
727It is not safe to wait (sleep) for resources during this call.
728.It Dv BUS_DMA_BUS[1-4]
729These flags are placeholders, and may be used by buses to provide
730bus-dependent functionality.
731.It Dv BUS_DMA_COHERENT
732This flag is a
733.Em hint
734to machine-dependent code.
735If possible, map the memory in such a way as it will be DMA coherent.
736This may include mapping the pages into uncached address space or
737setting the cache-inhibit bits in page table entries.
738If implementation of DMA coherent mappings is impossible, this is
739ignored.
740.Pp
741Later, when this memory is loaded into a DMA map, machine-dependent code
742will take whatever steps are necessary to determine if the memory was
743mapped in a DMA coherent fashion.
744This may include checking if the kernel virtual address lies within
745uncached address space or if the cache-inhibit bits are set in page
746table entries.
747If it is determined that the mapping is DMA coherent, state may be
748placed into the DMA map for use by later calls to
749.Fn bus_dmamap_sync .
750.El
751.El
752.Pp
753The
754.Fn bus_dmamem_unmap
755function unmaps memory previously mapped with
756.Fn bus_dmamem_map ,
757freeing the kernel virtual address space used by the mapping.
758This function always succeeds if given valid arguments, but must not be
759called from an interrupt context.
760.Pp
761.Fn bus_dmamem_unmap
762arguments are as follows:
763.Bl -tag -width size -compact
764.It Fa tag
765The
766.Fa bus_dma_tag_t
767passed down from the parent driver via
768.Fa <bus>_attach_args .
769.It Fa kva
770The kernel virtual address of the mapped memory.
771.It Fa size
772The size of the mapping.
773.El
774.Pp
775The
776.Fn bus_dmamem_mmap
777function provides support for user
778.Xr mmap 2 Ns 'ing
779of DMA-safe memory.
780.Fn bus_dmamem_mmap
781is to be called by a device driver's
782.Fn (*d_mmap)
783entry point, which is called by the device pager for each page to be mapped.
784This function returns a physical address to be passed to
785.Fn pmap_enter
786by the device pager, or -1 on failure.
787.Fn bus_dmamem_mmap
788arguments are
789as follows:
790.Bl -tag -width nsegs -compact
791.It Fa tag
792The
793.Fa bus_dma_tag_t
794passed down from the parent driver via
795.Fa <bus>_attach_args .
796.It Fa segs
797The
798.Fa bus_dma_segment_t
799array filled in by
800.Fn bus_dmamem_alloc ,
801representing the memory to be
802.Xr mmap 2 Ns 'ed .
803.It Fa nsegs
804The number of elements in the
805.Fa segs
806array.
807.It Fa off
808The offset of the page in DMA memory which is to be mapped.
809.It Fa prot
810The protection codes for the mapping.
811.It Fa flags
812Flags are defined as follows:
813.Bl -tag -width BUS_DMA_COHERENT -compact
814.It Dv BUS_DMA_WAITOK
815It is safe to wait (sleep) for resources during this call.
816.It Dv BUS_DMA_NOWAIT
817It is not safe to wait (sleep) for resources during this call.
818.It Dv BUS_DMA_BUS[1-4]
819These flags are placeholders, and may be used by buses to provide
820bus-dependent functionality.
821.It Dv BUS_DMA_COHERENT
822See
823.Fn bus_dmamem_map
824above for a description of this flag.
825.El
826.El
827.Sh SEE ALSO
828.Xr bus_space 9
829.Sh HISTORY
830The
831.Nm
832interface appeared in
833.Nx 1.3 .
834.Sh AUTHORS
835The
836.Nm
837interface was designed and implemented by Jason R. Thorpe of the
838Numerical Aerospace Simulation Facility, NASA Ames Research Center.
839Additional input on the
840.Nm
841design was provided by Chris Demetriou, Charles Hannum, Ross Harvey,
842Matthew Jacob, Jonathan Stone, and Matt Thomas.
843