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