xref: /openbsd/share/man/man9/bus_dma.9 (revision 78b63d65)
1.\"	$OpenBSD: bus_dma.9,v 1.9 2001/09/03 09:29:18 art 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.\" 3. All advertising materials mentioning features or use of this software
20.\"    must display the following acknowledgment:
21.\" 	This product includes software developed by the NetBSD
22.\" 	Foundation, Inc. and its contributors.
23.\" 4. Neither the name of The NetBSD Foundation nor the names of its
24.\"    contributors may be used to endorse or promote products derived
25.\"    from this software without specific prior written permission.
26.\"
27.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
28.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
29.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30.\" PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
31.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37.\" POSSIBILITY OF SUCH DAMAGE.
38.\"
39.Dd November 23, 2000
40.Dt BUS_DMA 9
41.Os
42.Sh NAME
43.Nm bus_dma ,
44.Nm bus_dmamap_create ,
45.Nm bus_dmamap_destroy ,
46.Nm bus_dmamap_load ,
47.Nm bus_dmamap_load_mbuf ,
48.Nm bus_dmamap_load_uio ,
49.Nm bus_dmamap_load_raw ,
50.Nm bus_dmamap_unload ,
51.Nm bus_dmamap_sync ,
52.Nm bus_dmamem_alloc ,
53.Nm bus_dmamem_free ,
54.Nm bus_dmamem_map ,
55.Nm bus_dmamem_unmap ,
56.Nm bus_dmamem_mmap
57.Nd bus and machine independent DMA mapping interface
58.Sh SYNOPSIS
59.Fd #include <machine/bus.h>
60.Ft int
61.Fn bus_dmamap_create "bus_dma_tag_t tag" "bus_size_t size" "int nsegments" \
62"bus_size_t maxsegsz" "bus_size_t boundary" "int flags" "bus_dmamap_t *dmamp"
63.Ft void
64.Fn bus_dmamap_destroy "bus_dma_tag_t tag" "bus_dmamap_t dmam"
65.Ft int
66.Fn bus_dmamap_load "bus_dma_tag_t tag" "bus_dmamap_t dmam" "void *buf" \
67"bus_size_t buflen" "struct proc *p" "int flags"
68.Ft int
69.Fn bus_dmamap_load_mbuf "bus_dma_tag_t tag" "bus_dmamap_t dmam" \
70"struct mbuf *chain" "int flags"
71.Ft int
72.Fn bus_dmamap_load_uio "bus_dma_tag_t tag" "bus_dmamap_t dmam" \
73"struct uio *uio" "int flags"
74.Ft int
75.Fn bus_dmamap_load_raw "bus_dma_tag_t tag" "bus_dmamap_t dmam" \
76"bus_dma_segment_t *segs" "int nsegs" "bus_size_t size" "int flags"
77.Ft void
78.Fn bus_dmamap_unload "bus_dma_tag_t tag" "bus_dmamap_t dmam"
79.Ft void
80.Fn bus_dmamap_sync "bus_dma_tag_t tag" "bus_dmamap_t dmam" "bus_dmasync_op_t ops"
81.Ft int
82.Fn bus_dmamem_alloc "bus_dma_tag_t tag" "bus_size_t size" \
83"bus_size_t alignment" "bus_size_t boundary" "bus_dma_segment_t *segs" \
84"int nsegs" "int *rsegs" "int flags"
85.Ft void
86.Fn bus_dmamem_free "bus_dma_tag_t tag" "bus_dma_segment_t *segs" "int nsegs"
87.Ft int
88.Fn bus_dmamem_map "bus_dma_tag_t tag" "bus_dma_segment_t *segs" "int nsegs" \
89"size_t size" "caddr_t *kvap" "int flags"
90.Ft void
91.Fn bus_dmamem_unmap "bus_dma_tag_t tag" "caddr_t kva" "size_t size"
92.Ft paddr_t
93.Fn bus_dmamem_mmap "bus_dma_tag_t tag" "bus_dma_segment_t *segs" \
94"int nsegs" "off_t off" "int prot" "int flags"
95.Sh DESCRIPTION
96The
97.Nm
98interface provides a bus and machine independent mechanism
99for managing DMA data transfers to and from devices.
100.Pp
101The basic abstraction is the bus_dmamap_t, a pointer to a structure
102which contains an array of bus_dma_segment_t's (dm_segs) and a count
103of how many are currently valid (dm_nsegs).
104.Pp
105Each segment in the array describes a single physical area of memory
106which can be DMA'd, with a starting address (ds_addr) and a length
107(ds_len).
108These are the values that must be communicated to the DMA device.
109Taken together the segments exactly and completely describe the buffer
110being used to transfer data.
111.Pp
112bus_dma_tag_t's are an opaque type, received from higher software
113layers and are never created, changed, deleted or even examined in
114this interface.
115.Pp
116The basic cycle to transfer data to/from a dma device is:
117.Bd -literal
118bus_dmamap_create();         /* get a dmamap to load/unload          */
119
120for each dma xfer {
121        bus_dmamem_alloc();  /* allocate some DMA'able memory        */
122        bus_dmamem_map();    /* map it into the kernel address space */
123
124        /*
125         * Fill the allocated DMA'able memory with whatever data
126         * is to be sent out, using the pointer obtained with
127         * bus_dmamem_map().
128         */
129
130        bus_dmamap_load();   /* initialize the segments of dmamap    */
131        bus_dmamap_sync();   /* synchronize/flush any dma cache      */
132
133        for (i=0; i<dm_nsegs; i++) {
134                /*
135                 * Tell the DMA device the physical address
136                 * (dmamap->dm_segs[i].ds_addr) and the length
137                 * (dmamap->dm_segs[i].ds_len) of the memory to xfer.
138                 *
139                 * Start the DMA, wait until it's done
140                 */
141        }
142
143        bus_dmamap_sync();   /* synchronize/flush any dma cache      */
144        bus_dmamap_unload(); /* prepare dmamap for reuse             */
145
146        /*
147         * copy any data desired from the DMA'able memory using the
148         * pointer created by bus_dmamem_map().
149         */
150
151        bus_dmamem_unmap();  /* free kernel virtual address space    */
152        bus_dmamem_free();   /* free DMA'able memory                 */
153}
154
155bus_dmamap_destroy();        /* release any resources used by dmamap */
156.Ed
157.Sh NOTES
158All data structures, function prototypes, and macros are defined in
159the architecture-specific header
160.Pa Aq machine/bus.h .
161Note that this document assumes the existence of types already defined
162by the current "bus.h" interface.
163.Pp
164Unless otherwise noted, all function calls in this interface may be
165defined as
166.Xr cpp 1
167macros.
168.Sh DATA TYPES
169Individual implementations may name these structures whatever they wish,
170providing that the external representations are:
171.Bl -tag -width compact
172.It Fa bus_dma_tag_t
173A machine-dependent opaque type describing the implementation of DMA for
174a given bus.
175.It Fa bus_dma_segment_t
176A structure with at least the following members:
177.Bd -literal
178	bus_addr_t	ds_addr;
179	bus_size_t	ds_len;
180.Ed
181.sp
182The structure may have machine-dependent members and arbitrary layout.
183The values in
184.Fa ds_addr
185and
186.Fa ds_len
187are suitable for programming into DMA controller address and length
188registers.
189.It Fa bus_dmamap_t
190A pointer to a structure with at least the following members:
191.Bd -literal
192	int		   dm_nsegs;
193	bus_dma_segment_t *dm_segs;
194.Ed
195.sp
196The structure may have machine-dependent members and arbitrary layout.
197The
198.Fa dm_segs
199member may be an array of segments or a pointer to an array of segments.
200The
201.Fa dm_nsegs
202member indicates the number of segments in
203.Fa dm_segs .
204.El
205.Sh FUNCTIONS
206.Bl -tag -width compact
207.It Fn bus_dmamap_create "tag" "size" "nsegments" "maxsegsz" "boundary" "flags" "dmamp"
208Allocates a DMA handle and initializes it according to the parameters
209provided.
210Arguments are as follows:
211.Bl -tag -width nsegments -compact
212.It Fa tag
213This is the bus_dma_tag_t passed down from the parent driver via
214.Fa <bus>_attach_args .
215.It Fa size
216This is the maximum DMA transfer that can be mapped by the handle.
217.It Fa nsegments
218Number of segments the device can support in a single DMA transaction.
219This may be the number of scatter-gather descriptors supported by the
220device.
221.It Fa maxsegsz
222The maximum number of bytes that may be transferred by any given DMA
223segment.
224.It Fa boundary
225Some DMA controllers are not able to transfer data that crosses a
226particular boundary.
227This argument allows this boundary to be specified.
228The boundary lines begin at 0, and occur every
229.Fa boundary
230bytes.
231Mappings may begin on a boundary line but may not end on or cross a
232boundary line.
233If no boundary condition needs to be observed, a
234.Fa boundary
235argument of 0 should be used.
236.It Fa flags
237Flags are defined as follows:
238.Bl -tag -width BUS_DMA_ALLOCNOW -compact
239.It Dv BUS_DMA_WAITOK
240It is safe to wait (sleep) for resources during this call.
241.It Dv BUS_DMA_NOWAIT
242It is not safe to wait (sleep) for resources during this call.
243.It Dv BUS_DMA_ALLOCNOW
244Perform any resource allocation this handle may need now.
245If this is not specified, the allocation may be deferred to
246.Fn bus_dmamap_load .
247If this flag is specified,
248.Fn bus_dmamap_load
249will not block on resource allocation.
250.It Dv BUS_DMA_BUS[1-4]
251These flags are placeholders, and may be used by busses to provide
252bus-dependent functionality.
253.El
254.It Fa dmamp
255This is a pointer to a bus_dmamap_t.
256A DMA map will be allocated and pointed to by
257.Fa dmamp
258upon successful completion of this routine.
259.El
260.Pp
261Behavior is not defined if invalid arguments are passed to
262.Fn bus_dmamap_create .
263.Pp
264Returns 0 on success, or an error code to indicate mode of failure.
265.It Fn bus_dmamap_destroy "tag" "dmam"
266Frees all resources associated with a given DMA handle.
267Arguments are as follows:
268.Bl -tag -width dmam -compact
269.It Fa tag
270This is the bus_dma_tag_t passed down from the parent driver via
271.Fa <bus>_attach_args .
272.It Fa dmam
273The DMA handle to destroy.
274.El
275.Pp
276In the event that the DMA handle contains a valid mapping, the mapping
277will be unloaded via the same mechanism used by
278.Fn bus_dmamap_unload .
279.Pp
280Behavior is not defined if invalid arguments are passed to
281.Fn bus_dmamap_destroy .
282.Pp
283If given valid arguments,
284.Fn bus_dmamap_destroy
285always succeeds.
286.It Fn bus_dmamap_load "tag" "dmam" "buf" "buflen" "p" "flags"
287Loads a DMA handle with mappings for a DMA transfer.
288It assumes that all pages involved in a DMA transfer are wired.
289Arguments are as follows:
290.Bl -tag -width buflen -compact
291.It Fa tag
292This is the bus_dma_tag_t passed down from the parent driver via
293.Fa <bus>_attach_args .
294.It Fa dmam
295The DMA handle with which to map the transfer.
296.It Fa buf
297The buffer to be used for the DMA transfer.
298.It Fa buflen
299The size of the buffer.
300.It Fa p
301Used to indicate the address space in which the buffer is located.
302If
303.Dv NULL ,
304the buffer is assumed to be in kernel space.
305Otherwise, the buffer is assumed to be in process
306.Fa p Ns 's
307address space.
308.It Fa flags
309are defined as follows:
310.Bl -tag -width "BUS_DMA_BUS[1-4]" -compact
311.It Dv BUS_DMA_WAITOK
312It is safe to wait (sleep) for resources during this call.
313.It Dv BUS_DMA_NOWAIT
314It is not safe to wait (sleep) for resources during this call.
315.It Dv BUS_DMA_BUS[1-4]
316These flags are placeholders, and may be used by busses to provide
317bus-dependent functionality.
318.El
319.El
320.Pp
321As noted above, if a DMA handle is created with
322.Dv BUS_DMA_ALLOCNOW ,
323.Fn bus_dmamap_load
324will never block.
325.Pp
326If a call to
327.Fn bus_dmamap_load
328fails, the mapping in the DMA handle will be invalid.
329It is the responsibility of the caller to clean up any inconsistent
330device state resulting from incomplete iteration through the uio.
331.Pp
332Behavior is not defined if invalid arguments are passed to
333.Fn bus_dmamap_load .
334.Pp
335Returns 0 on success, or an error code to indicate mode of failure.
336.It Fn bus_dmamap_load_mbuf "tag" "dmam" "chain" "flags"
337This is a variation of
338.Fn bus_dmamap_load
339which maps mbuf chains for DMA transfers.
340Mbuf chains are assumed to be in kernel virtual address space.
341.It Fn bus_dmamap_load_uio "tag" "dmam" "uio" "flags"
342This is a variation of
343.Fn bus_dmamap_load
344which maps buffers pointed to by
345.Fa uio
346for DMA transfers.
347The value of
348.Fa "uio->uio_segflg"
349will determine if the buffers are in user or kernel virtual address
350space.
351If the buffers are in user address space, the buffers are assumed to be
352in
353.Fa "uio->uio_procp" Ns 's
354address space.
355.It Fn bus_dmamap_load_raw "tag" "dmam" "segs" "nsegs" "size" "flags"
356This is a variation of
357.Fn bus_dmamap_load
358which maps buffers allocated by
359.Fn bus_dmamem_alloc
360(see below).
361The
362.Fa segs
363argument is an array of bus_dma_segment_t's filled in by
364.Fn bus_dmamem_alloc .
365The
366.Fa nsegs
367argument is the number of segments in the array.
368The
369.Fa size
370argument is the size of the DMA transfer.
371.It Fn bus_dmamap_unload "tag" "dmam"
372Deletes the mappings for a given DMA handle.
373Arguments are as follows:
374.Bl -tag -width dmam -compact
375.It Fa tag
376This is the bus_dma_tag_t passed down from the parent driver via
377.Fa <bus>_attach_args .
378.It Fa dmam
379The DMA handle containing the mappings which are to be deleted.
380.El
381.Pp
382If the DMA handle was created with
383.Dv BUS_DMA_ALLOCNOW ,
384.Fn bus_dmamap_unload
385will not free the corresponding resources which were allocated by
386.Fn bus_dmamap_create .
387This is to ensure that
388.Fn bus_dmamap_load
389will never block on resources if the handle was created with
390.Dv BUS_DMA_ALLOCNOW .
391.Pp
392Behavior is not defined if invalid arguments are passed to
393.Fn bus_dmamap_unload .
394.Pp
395If given valid arguments,
396.Fn bus_dmamap_unload
397always succeeds.
398.It Fn bus_dmamap_sync "tag" "dmam" "ops"
399Performs pre- and post-DMA operation cache and/or buffer synchronization.
400Arguments are as follows:
401.Bl -tag -width offset -compact
402.It Fa tag
403This is the bus_dma_tag_t passed down from the parent driver via
404.Fa <bus>_attach_args .
405.It Fa dmam
406The DMA mapping to be synchronized.
407.It Fa ops
408One or more synchronization operation to perform.
409The following DMA synchronization operations are defined:
410.Bl -tag -width BUS_DMASYNC_POSTWRITE -compact
411.It Dv BUS_DMASYNC_PREREAD
412Perform any pre-read DMA cache and/or bounce operations.
413.It Dv BUS_DMASYNC_POSTREAD
414Perform any post-read DMA cache and/or bounce operations.
415.It Dv BUS_DMASYNC_PREWRITE
416Perform any pre-write DMA cache and/or bounce operations.
417.It Dv BUS_DMASYNC_POSTWRITE
418Perform any post-write DMA cache and/or bounce operations.
419.El
420.Pp
421More than one operation may performed in a given synchronization call.
422Mixing of
423.Em PRE
424and
425.Em POST
426operations is not allowed, and behavior is undefined if this is attempted.
427.El
428.Pp
429Synchronization operations are expressed from the perspective of the
430host RAM, e.g. a
431.Em "device -> memory"
432operation is a
433.Em READ
434and a
435.Em "memory -> device"
436operation is a
437.Em WRITE .
438.Pp
439.Fn bus_dmamap_sync
440may consult state kept within the DMA map to determine if the memory is
441mapped in a DMA coherent fashion.
442If so,
443.Fn bus_dmamap_sync
444may elect to skip certain expensive operations, such as flushing of the
445data cache.
446See
447.Fn bus_dmamem_map
448for more information on this subject.
449.Pp
450On platforms which implement reordered stores,
451.Fn bus_dmamap_sync
452will always cause the store buffer to be flushed.
453.Pp
454This function exists so that multiple read and write transfers can be
455performed with the same buffer, and so that drivers can explicitly
456inform the
457.Nm
458code when their data is 'ready' in its DMA buffer.
459.Pp
460An example of multiple read-write use of a single mapping
461might look like:
462.Bd -literal
463bus_dmamap_load(...);
464
465while (not done) {
466	/* invalidate soon-to-be-stale cache blocks */
467	bus_dmamap_sync(..., BUS_DMASYNC_PREREAD);
468
469	[ do read DMA ]
470
471	/* copy from bounce */
472	bus_dmamap_sync(..., BUS_DMASYNC_POSTREAD);
473
474	/* read data now in driver-provided buffer */
475
476	[ computation ]
477
478	/* data to be written now in driver-provided buffer */
479
480	/* flush write buffers and writeback, copy to bounce */
481	bus_dmamap_sync(..., BUS_DMASYNC_PREWRITE);
482
483	[ do write DMA ]
484
485	/* probably a no-op, but provided for consistency */
486	bus_dmamap_sync(..., BUS_DMASYNC_POSTWRITE);
487}
488
489bus_dmamap_unload(...);
490.Ed
491.Pp
492If DMA read and write operations are not preceded and followed by the
493appropriate synchronization operations, behavior is undefined.
494.Pp
495Behavior is not defined if invalid arguments are passed to
496.Fn bus_dmamap_sync .
497.Pp
498If given valid arguments,
499.Fn bus_dmamap_sync
500always succeeds.
501.\" XXX: This does not work with all the arguments.
502.It Fn bus_dmamem_alloc "tag" "size" "alignment" "boundary" "segs" "..."
503Allocates memory that is "DMA safe" for the bus corresponding to the
504given tag.
505.Pp
506The mapping of this memory is machine-dependent (or "opaque");
507machine-independent code is not to assume that the addresses returned
508are valid in kernel virtual address space, or that the addresses
509returned are system physical addresses.
510The address value returned as part of
511.Fa segs
512can thus not be used to program DMA controller address registers.
513Only the values in the
514.Fa dm_segs
515array of a successfully loaded DMA map (using
516.Fn bus_dmamap_load
517) can be used for this purpose.
518.Pp
519Allocations will always be rounded to the hardware page size.
520Callers may wish to take advantage of this, and cluster allocation of
521small data structures.
522Arguments are as follows:
523.Bl -tag -width alignment -compact
524.It Fa tag
525The is the bus_dma_tag_t passed down from the parent driver via
526.Fa <bus>_attach_args .
527.It Fa size
528The amount of memory to allocate.
529.It Fa alignment
530Each segment in the allocated memory will be aligned to this value.
531If the alignment is less than a hardware page size, it will be rounded
532up to the hardware page size.
533This value must be a power of two.
534.It Fa boundary
535Each segment in the allocated memory must not cross this boundary
536(relative to zero).
537This value must be a power of two.
538A boundary value less than the size of the allocation is invalid.
539.It Fa segs
540An array of bus_dma_segment_t's, filled in as memory is allocated,
541representing the opaque addresses of the memory chunks.
542.It Fa nsegs
543Specifies the number of segments in
544.Fa segs ,
545and this is the maximum number of segments that the allocated memory may
546contain.
547.It Fa rsegs
548Used to return the actual number of segments the memory contains.
549.It Fa flags
550Flags are defined as follows:
551.Bl -tag -width BUS_DMA_BUS[1-4] -compact
552.It Dv BUS_DMA_WAITOK
553It is safe to wait (sleep) for resources during this call.
554.It Dv BUS_DMA_NOWAIT
555It is not safe to wait (sleep) for resources during this call.
556.It Dv BUS_DMA_BUS[1-4]
557These flags are placeholders, and may be used by busses to provide
558bus-dependent functionality.
559.El
560.El
561.Pp
562All pages allocated by
563.Fn bus_dmamem_alloc
564will be wired down until they are freed by
565.Fn bus_dmamem_free .
566.Pp
567Behavior is undefined if invalid arguments are passed to
568.Fn bus_dmamem_alloc .
569.Pp
570Returns 0 on success, or an error code indicating mode of failure.
571.It Fn bus_dmamem_free "tag" "segs" "nsegs"
572Frees memory previously allocated by
573.Fn bus_dmamem_alloc .
574Any mappings will be invalidated.
575Arguments are as follows:
576.Bl -tag -width nsegs -compact
577.It Fa tag
578This is the bus_dma_tag_t passed down from the parent driver via
579.Fa <bus>_attach_args .
580.It Fa segs
581The array of bus_dma_segment_t's filled in by
582.Fn bus_dmamem_alloc .
583.It Fa nsegs
584The number of segments in
585.Fa segs .
586.El
587.Pp
588Behavior is undefined if invalid arguments are passed to
589.Fn bus_dmamem_free .
590.Pp
591If given valid arguments,
592.Fn bus_dmamem_free
593always succeeds.
594.It Fn bus_dmamem_map "tag" "segs" "nsegs" "size" "kvap" "flags"
595Maps memory allocated with
596.Fn bus_dmamem_alloc
597into kernel virtual address space.
598Arguments are as follows:
599.Bl -tag -width flags -compact
600.It Fa tag
601This is the bus_dma_tag_t passed down from the parent driver via
602.Fa <bus>_attach_args .
603.It Fa segs
604The array of bus_dma_segment_t's filled in by
605.Fn bus_dmamem_alloc ,
606representing the memory regions to map.
607.It Fa nsegs
608The number of segments in
609.Fa segs .
610.It Fa size
611The size of the mapping.
612.It Fa kvap
613Filled in to specify the kernel virtual address where the memory is
614mapped.
615.It Fa flags
616Flags are defined as follows:
617.Bl -tag -width BUS_DMA_COHERENT -compact
618.It Dv BUS_DMA_WAITOK
619It is safe to wait (sleep) for resources during this call.
620.It Dv BUS_DMA_NOWAIT
621It is not safe to wait (sleep) for resources during this call.
622.It Dv BUS_DMA_BUS[1-4]
623These flags are placeholders, and may be used by busses to provide
624bus-dependent functionality.
625.It Dv BUS_DMA_COHERENT
626This flag is a
627.Em hint
628to machine-dependent code.
629If possible, map the memory in such a way as it will be DMA coherent.
630This may include mapping the pages into uncached address space or
631setting the cache-inhibit bits in page table entries.
632If implementation of DMA coherent mappings is impossible, this is
633ignored.
634.Pp
635Later, when this memory is loaded into a DMA map, machine-dependent code
636will take whatever steps are necessary to determine if the memory was
637mapped in a DMA coherent fashion.
638This may include checking if the kernel virtual address lies within
639uncached address space or if the cache-inhibit bits are set in page
640table entries.
641If it is determined that the mapping is DMA coherent, state may be
642placed into the DMA map for use by later calls to
643.Fn bus_dmamap_sync .
644.El
645.El
646.Pp
647Behavior is undefined if invalid arguments are passed to
648.Fn bus_dmamem_map .
649This function must not be called from an interrupt context.
650.Pp
651Returns 0 on success, or an error code indicating mode of failure.
652.It Fn bus_dmamem_unmap "tag" "kva" "size"
653Unmaps memory previously mapped with
654.Fn bus_dmamem_map ,
655freeing the kernel virtual address space used by the mapping.
656The arguments are as follows:
657.Bl -tag -width size -compact
658.It Fa tag
659This is the bus_dma_tag_t passed down from the parent driver via
660.Fa <bus>_attach_args .
661.It Fa kva
662The kernel virtual address of the mapped memory.
663.It Fa size
664The size of the mapping.
665.El
666.Pp
667Behavior is undefined if invalid arguments are passed to
668.Fn bus_dmamem_unmap .
669This function must not be called from an interrupt context.
670.Pp
671If given valid arguments,
672.Fn bus_dmamem_unmap
673always succeeds.
674.It Fn bus_dmamem_mmap "tag" "segs" "nsegs" "off" "prot" "flags"
675Provides support for user
676.Xr mmap 2 Ns 'ing
677of DMA-safe memory.
678This function is to be called by a device driver's (*d_mmap)() entry
679point, which is called by the device pager for each page to be mapped.
680The arguments are
681as follows:
682.Bl -tag -width nsegs -compact
683.It Fa tag
684This is the bus_dma_tag_t passed down from the parent driver via
685.Fa <bus>_attach_args .
686.It Fa segs
687The array of bus_dma_segment_t's filled in by
688.Fn bus_dmamem_alloc ,
689representing the memory to be
690.Xr mmap 2 Ns 'ed .
691.It Fa nsegs
692The number of elements in the
693.Fa segs
694array.
695.It Fa off
696The offset of the page in DMA memory which is to be mapped.
697.It Fa prot
698The protection codes for the mapping.
699.It Fa flags
700Flags are defined as follows:
701.Bl -tag -width BUS_DMA_COHERENT -compact
702.It Dv BUS_DMA_WAITOK
703It is safe to wait (sleep) for resources during this call.
704.It Dv BUS_DMA_NOWAIT
705It is not safe to wait (sleep) for resources during this call.
706.It Dv BUS_DMA_BUS[1-4]
707These flags are placeholders, and may be used by busses to provide
708bus-dependent functionality.
709.It Dv BUS_DMA_COHERENT
710See
711.Fn bus_dmamem_map
712above for a description of this flag.
713.El
714.El
715.Pp
716Behavior is undefined if invalid arguments are passed
717to
718.Fn bus_dmamem_mmap .
719.Pp
720Returns -1 to indicate failure.
721Otherwise, returns an opaque value to be interpreted by the device
722pager.
723.El
724.Sh SEE ALSO
725.Xr bus_space 9
726.Sh AUTHORS
727The
728.Nm
729interface was designed and implemented by Jason R. Thorpe of the
730Numerical Aerospace Simulation Facility, NASA Ames Research Center.
731Additional input on the
732.Nm
733design was provided by Chris Demetriou, Charles Hannum, Ross Harvey,
734Matthew Jacob, Jonathan Stone, and Matt Thomas.
735.Sh HISTORY
736The
737.Nm
738interface appeared in
739.Nx 1.3 .
740