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