xref: /dragonfly/share/man/man9/bus_dma.9 (revision 7d84b73d)
1.\"
2.\" Copyright (c) 2002, 2003, 2004 The DragonFly Project.  All rights reserved.
3.\"
4.\" This code is derived from software contributed to The DragonFly Project
5.\" by Hiten Pandya <hmp@backplane.com>.
6.\"
7.\" Redistribution and use in source and binary forms, with or without
8.\" modification, are permitted provided that the following conditions
9.\" are met:
10.\"
11.\" 1. Redistributions of source code must retain the above copyright
12.\"    notice, this list of conditions and the following disclaimer.
13.\" 2. Redistributions in binary form must reproduce the above copyright
14.\"    notice, this list of conditions and the following disclaimer in
15.\"    the documentation and/or other materials provided with the
16.\"    distribution.
17.\" 3. Neither the name of The DragonFly Project nor the names of its
18.\"    contributors may be used to endorse or promote products derived
19.\"    from this software without specific, prior written permission.
20.\"
21.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23.\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24.\" FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
25.\" COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26.\" INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27.\" BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29.\" AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31.\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.\" Copyright (c) 1996, 1997, 1998, 2001 The NetBSD Foundation, Inc.
35.\" All rights reserved.
36.\"
37.\" This code is derived from software contributed to The NetBSD Foundation
38.\" by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
39.\" NASA Ames Research Center.
40.\"
41.\" Redistribution and use in source and binary forms, with or without
42.\" modification, are permitted provided that the following conditions
43.\" are met:
44.\" 1. Redistributions of source code must retain the above copyright
45.\"    notice, this list of conditions and the following disclaimer.
46.\" 2. Redistributions in binary form must reproduce the above copyright
47.\"    notice, this list of conditions and the following disclaimer in the
48.\"    documentation and/or other materials provided with the distribution.
49.\" 3. All advertising materials mentioning features or use of this software
50.\"    must display the following acknowledgment:
51.\" 	This product includes software developed by the NetBSD
52.\" 	Foundation, Inc. and its contributors.
53.\" 4. Neither the name of The NetBSD Foundation nor the names of its
54.\"    contributors may be used to endorse or promote products derived
55.\"    from this software without specific prior written permission.
56.\"
57.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
58.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
59.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
60.\" PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
61.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
62.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
63.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
64.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
65.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
66.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
67.\" POSSIBILITY OF SUCH DAMAGE.
68.\"
69.\" $FreeBSD: /repoman/r/ncvs/src/share/man/man9/bus_dma.9,v 1.7 2003/07/27 14:05:29 mux Exp $
70.\" $NetBSD: bus_dma.9,v 1.25 2002/10/14 13:43:16 wiz Exp $
71.\"
72.Dd December 09, 2023
73.Dt BUS_DMA 9
74.Os
75.Sh NAME
76.Nm bus_dma ,
77.Nm bus_dma_tag_create ,
78.Nm bus_dma_tag_destroy ,
79.Nm bus_dmamap_create ,
80.Nm bus_dmamap_destroy ,
81.Nm bus_dmamap_load ,
82.Nm bus_dmamap_load_ccb ,
83.Nm bus_dmamap_load_mbuf ,
84.Nm bus_dmamap_load_mbuf_segment ,
85.Nm bus_dmamap_load_mbuf_defrag ,
86.Nm bus_dmamap_load_uio ,
87.Nm bus_dmamap_unload ,
88.Nm bus_dmamap_sync ,
89.Nm bus_dmamem_alloc ,
90.Nm bus_dmamem_coherent ,
91.Nm bus_dmamem_coherent_any ,
92.Nm bus_dmamem_free
93.Nd Bus and Machine Independent DMA Mapping Interface
94.Sh SYNOPSIS
95.In sys/bus.h
96.Ft int
97.Fn bus_dma_tag_create "bus_dma_tag_t parent" "bus_size_t alignment" \
98"bus_size_t boundary" "bus_addr_t lowaddr" "bus_addr_t highaddr" \
99"bus_size_t maxsize" "int nsegments" "bus_size_t maxsegsz" \
100"int flags" "bus_dma_tag_t *dmat"
101.Ft int
102.Fn bus_dma_tag_destroy "bus_dma_tag_t dmat"
103.Ft int
104.Fn bus_dmamap_create "bus_dma_tag_t dmat" "int flags" "bus_dmamap_t *mapp"
105.Ft int
106.Fn bus_dmamap_destroy "bus_dma_tag_t dmat" "bus_dmamap_t map"
107.Ft int
108.Fn bus_dmamap_load "bus_dma_tag_t dmat" "bus_dmamap_t map" "void *buf" \
109"bus_size_t buflen" "bus_dmamap_callback_t *callback" "void *callback_arg" \
110"int flags"
111.Ft int
112.Fn bus_dmamap_load_ccb "bus_dma_tag_t dmat" "bus_dmamap_t map" \
113"union ccb *ccb" "bus_dmamap_callback_t *callback" "void *callback_arg" \
114"int flags"
115.Ft int
116.Fn bus_dmamap_load_mbuf "bus_dma_tag_t dmat" "bus_dmamap_t map" \
117"struct mbuf *mbuf" "bus_dmamap_callback2_t *callback" "void *callback_arg" \
118"int flags"
119.Ft int
120.Fn bus_dmamap_load_mbuf_segment "bus_dma_tag_t dmat" "bus_dmamap_t map" \
121"struct mbuf *mbuf" "bus_dma_segment_t *segs" "int maxsegs" "int *nsegs" \
122"int flags"
123.Ft int
124.Fn bus_dmamap_load_mbuf_defrag "bus_dma_tag_t dmat" "bus_dmamap_t map" \
125"struct mbuf **mbuf" "bus_dma_segment_t *segs" "int maxsegs" "int *nsegs" \
126"int flags"
127.Ft int
128.Fn bus_dmamap_load_uio "bus_dma_tag_t dmat" "bus_dmamap_t map" \
129"struct uio *uio" "bus_dmamap_callback2_t *callback" "void *callback_arg" \
130"int flags"
131.Ft int
132.Fn bus_dmamem_alloc "bus_dma_tag_t dmat" "void **vaddr" \
133"int flags" "bus_dmamap_t *mapp"
134.Ft int
135.Fn bus_dmamem_coherent "bus_dma_tag_t parent" "bus_size_t alignment" \
136"bus_size_t boundary" "bus_addr_t lowaddr" "bus_addr_t highaddr" \
137"bus_size_t maxsize" "int flags" "bus_dmamem_t *dmem"
138.Ft void *
139.Fn bus_dmamem_coherent_any "bus_dma_tag_t parent" "bus_size_t alignment" \
140"bus_size_t maxsize" "int flags" "bus_dma_tag_t *dtag" "bus_dmamap_t *dmap" \
141"bus_addr_t *busaddr"
142.Ft void
143.Fn bus_dmamap_unload "bus_dma_tag_t dmat" "bus_dmamap_t map"
144.Ft void
145.Fn bus_dmamap_sync "bus_dma_tag_t dmat" "bus_dmamap_t map" \
146"bus_dmasync_op_t op"
147.Ft void
148.Fn bus_dmamem_free "bus_dma_tag_t dmat" "void *vaddr" \
149"bus_dmamap_t map"
150.Sh DESCRIPTION
151Direct Memory Access (DMA) is a method of transferring data
152without involving the CPU, thus providing higher performance.
153A DMA transaction can be achieved between device to memory,
154device to device, or memory to memory.
155.Pp
156The
157.Nm
158API is a bus, device, and machine-independent (MI) interface to
159DMA mechanisms.
160It provides the client with flexibility and simplicity by
161abstracting machine dependent issues like setting up
162DMA mappings, handling cache issues, bus specific features
163and limitations.
164.Sh STRUCTURES AND TYPES
165.Bl -tag -width compact
166.It Vt bus_dma_tag_t
167A machine-dependent (MD) opaque type that describes the
168characteristics of DMA transactions.
169DMA tags are organized into a hierarchy, with each child
170tag inheriting the restrictions of its parent.
171This allows all devices along the path of DMA transactions
172to contribute to the constraints of those transactions.
173.It Vt bus_dma_segment_t
174A machine-dependent type that describes individual
175DMA segments.
176.Bd -literal
177	bus_addr_t	ds_addr;
178	bus_size_t	ds_len;
179.Ed
180.sp
181The
182.Fa ds_addr
183field contains the device visible address of the DMA segment, and
184.Fa ds_len
185contains the length of the DMA segment.
186Although the DMA segments returned by a mapping call will adhere to
187all restrictions necessary for a successful DMA operation, some conversion
188(e.g. a conversion from host byte order to the device's byte order) is
189almost always required when presenting segment information to the device.
190.It Vt bus_dmamap_t
191A machine-dependent opaque type describing an individual mapping.
192Multiple DMA maps can be associated with one DMA tag.
193.It Vt bus_dmamem_t
194A machine-dependent type that describes DMA memory created by
195.Fn bus_dmamem_coherent .
196.Bd -literal
197	bus_dma_tag_t	dmem_tag;
198	bus_dmamap_t	dmem_map;
199	void		*dmem_addr;
200	bus_addr_t	dmem_busaddr;
201.Ed
202.sp
203The
204.Fa dmem_tag
205field contains the DMA tag of the DMA memory and
206.Fa dmem_map
207field contains the DMA map of the DMA memory.
208The
209.Fa dmem_addr
210field points to the allocated DMA memory in kernel virtual address space.
211The
212.Fa dmem_busaddr
213field contains the device visible address of the DMA memory.
214.It Vt bus_dmamap_callback_t
215Client specified callback for receiving mapping information resulting from
216the load of a
217.Vt bus_dmamap_t
218via
219.Fn bus_dmamap_load
220or
221.Fn bus_dmamap_load_ccb .
222Callbacks are of the format:
223.Bl -tag -width compact
224.It Ft void
225.Fn "client_callback" "void *callback_arg" "bus_dma_segment_t *segs" \
226"int nseg" "int error"
227.El
228.sp
229The
230.Fa callback_arg
231is the callback argument passed to dmamap load functions.
232The
233.Fa segs
234and
235.Fa nseg
236parameters describe an array of
237.Vt bus_dma_segment_t
238structures that represent the mapping.
239This array is only valid within the scope of the callback function.
240The success or failure of the mapping is indicated by the
241.Fa error
242parameter.
243More information on the use of callbacks can be found in the
244description of the individual dmamap load functions.
245.It Vt bus_dmamap_callback2_t
246Client specified callback for receiving mapping information resulting from
247the load of a
248.Vt bus_dmamap_t
249via
250.Fn bus_dmamap_load_uio
251or
252.Fn bus_dmamap_load_mbuf .
253.sp
254Callback2s are of the format:
255.Bl -tag -width compact
256.It Ft void
257.Fn "client_callback2" "void *callback_arg" "bus_dma_segment_t *segs" \
258"int nseg" "bus_size_t mapsize" "int error"
259.El
260.sp
261Callback2's behavior is the same as
262.Vt bus_dmamap_callback_t
263with the addition that the length of the data mapped is provided via
264.Fa mapsize .
265.It Vt bus_dmasync_op_t
266Memory synchronization operation specifier.
267Bus DMA requires explicit synchronization of memory with its device
268visible mapping in order to guarantee memory coherency.
269The
270.Vt bus_dmasync_op_t
271allows the type of DMA operation that will be or has been performed
272to be communicated to the system so that the correct coherency measures
273are taken.
274All operations specified below are performed from the DMA engine's
275point of view:
276.Bl -tag -width BUS_DMASYNC_POSTWRITE
277.It Dv BUS_DMASYNC_PREREAD
278Perform any synchronization required after an update of memory by the CPU
279but prior to DMA read operations.
280.It Dv BUS_DMASYNC_PREWRITE
281Perform any synchronization required after an update of memory by the CPU
282but prior to DMA write operations.
283.It Dv BUS_DMASYNC_POSTREAD
284Perform any synchronization required after DMA read operations, but prior
285to CPU access of the memory.
286.It Dv BUS_DMASYNC_POSTWRITE
287Perform any synchronization required after DMA write operations, but prior
288to CPU access of the memory.
289.El
290.El
291.sp
292.Sh FUNCTIONS
293.Bl -tag -width compact
294.It Fn bus_dma_tag_create "parent" "alignment" "boundary" "lowaddr" \
295"highaddr" "maxsize" "nsegments" "maxsegsz" "flags" "*dmat"
296Allocates a device specific DMA tag, and initializes it according to
297the arguments provided:
298.Bl -tag -width alignment -compact
299.It Fa parent
300Indicates restrictions between the parent bridge, CPU memory, and the
301device.
302May be NULL, if no DMA restrictions are to be inherited.
303.It Fa alignment
304Alignment constraint, in bytes, of any mappings created using this tag.
305The alignment must be a power of 2.
306Hardware that can DMA starting at any address would specify
307.Em 1
308for byte alignment.
309Hardware requiring DMA transfers to start on a multiple of 4K
310would specify
311.Em 4096 .
312.It Fa boundary
313Boundary constraint, in bytes, of the target DMA memory region.
314The boundary indicates the set of addresses, all multiples of the
315boundary argument, that cannot be crossed by a single
316.Vt bus_dma_segment_t .
317The boundary must be either a power of 2 or 0.
318.Ql 0
319indicates that there are no boundary restrictions.
320.It Fa lowaddr
321.It Fa highaddr
322Bounds of the window of bus address space that
323.Em cannot
324be directly accessed by the device.
325The window contains all address greater than lowaddr and
326less than or equal to highaddr.
327For example, a device incapable of DMA above 4GB, would specify
328a highaddr of
329.Dv BUS_SPACE_MAXADDR
330and a lowaddr of
331.Dv BUS_SPACE_MAXADDR_32BIT .
332Similarly a device that can only dma to addresses below 16MB would
333specify a highaddr of
334.Dv BUS_SPACE_MAXADDR
335and a lowaddr of
336.Dv BUS_SPACE_MAXADDR_24BIT .
337Some implementations requires that some region of device visible
338address space, overlapping available host memory, be outside the
339window.
340This area of
341.Ql safe memory
342is used to bounce requests that would otherwise conflict with
343the exclusion window.
344.It Fa maxsize
345Maximum size, in bytes, of the sum of all segment lengths in a given
346DMA mapping associated with this tag.
347.It Fa nsegments
348Number of discontinuities (scatter/gather segments) allowed
349in a DMA mapped region.
350If there is no restriction,
351.Dv BUS_SPACE_UNRESTRICTED
352may be specified for the tag intended to be used as the parent.
353.Dv BUS_SPACE_UNRESTRICTED
354must not be specified for the tags
355which will be used to create maps.
356For tags which will be used to create maps,
357this argument must be less than 16384 on x86_64.
358.It Fa maxsegsz
359Maximum size, in bytes, of a segment in any DMA mapped region associated
360with
361.Fa dmat .
362.It Fa flags
363Are as follows:
364.Bl -tag -width ".Dv BUS_DMA_PRIVBZONE" -compact
365.It Dv BUS_DMA_ALLOCNOW
366Allocate the minimum resources necessary to guarantee that all map load
367operations associated with this tag may not block.
368If sufficient resources are not available,
369.Er ENOMEM
370is returned.
371.It Dv BUS_DMA_WAITOK
372Indicates that it is OK to wait for resources.
373However,
374unlike
375.Xr kmalloc 9 ,
376it is not guaranteed that the resource allocation will succeed.
377This flag is the default one,
378if
379.Dv BUS_DMA_NOWAIT
380is not supplied.
381.It Dv BUS_DMA_NOWAIT
382If the resource allocation request cannot be immediately fulfilled,
383.Er ENOMEM
384is returned.
385.It Dv BUS_DMA_ONEBPAGE
386Allocte one bounce page at most,
387even if the
388.Fa maxsize
389indicates that multiple bounce pages are needed.
390.It Dv BUS_DMA_ALIGNED
391Indicates that all memory to be loaded into the DMA maps associated
392with this DMA tag is properly aligned according to
393.Fa alignment
394constraint.
395No resources,
396e.g. bounce pages,
397will be allocated due to the
398.Fa alignment
399constraint.
400If unaligned memory was loaded into the DMA maps associated with this DMA tag,
401system will panic.
402.It Dv BUS_DMA_PRIVBZONE
403Uses a private bounce zone instead of a shared one.
404A private bounce zone will vanish if the DMA tag is destroyed.
405.It Dv BUS_DMA_ALLOCALL
406Allocate all required resources (mainly the bounce buffer).
407If any allocation fails,
408.Fn bus_dma_tag_create
409fails.
410.It Dv BUS_DMA_PROTECTED
411All of the functions called with the DMA tag are already protected by the
412caller, so the
413.Nm
414code need not protect the internal data structures.
415.El
416.It Fa dmat
417Pointer to a bus_dma_tag_t where the resulting DMA tag will
418be stored.
419.El
420.Pp
421Returns
422.Er ENOMEM
423if sufficient memory is not available for tag creation
424or allocating mapping resources.
425.It Fn bus_dma_tag_destroy "dmat"
426Deallocate the DMA tag
427.Fa dmat
428that was created by
429.Fn bus_dma_tag_create .
430.Pp
431Returns
432.Er EBUSY
433if any DMA maps remain associated with
434.Fa dmat
435or
436.Ql 0
437on success.
438.It Fn bus_dmamap_create "dmat" "flags" "*mapp"
439Allocates and initializes a DMA map.
440Arguments are as follows:
441.Bl -tag -width nsegments -compact
442.It Fa dmat
443DMA tag.
444.It Fa flags
445Are as follows:
446.Bl -tag -width ".Dv BUS_DMA_ONEBPAGE" -compact
447.It Dv BUS_DMA_WAITOK
448Indicates that it is OK to wait for resources.
449However,
450unlike
451.Xr kmalloc 9 ,
452it is not guaranteed that the resource allocation will succeed.
453This flag is the default one,
454if
455.Dv BUS_DMA_NOWAIT
456is not supplied.
457.It Dv BUS_DMA_NOWAIT
458If the resource allocation request cannot be immediately fulfilled,
459.Er ENOMEM
460is returned.
461.It Dv BUS_DMA_ONEBPAGE
462Allocte one bounce page at most,
463even if the
464.Fa maxsize
465used to create the
466.Fa dmat
467indicates that multiple bounce pages are needed.
468.El
469.It Fa mapp
470Pointer to a
471.Vt bus_dmamap_t
472where the resulting DMA map will be stored.
473.El
474.Pp
475Returns
476.Er ENOMEM
477if sufficient memory is not available for creating the
478map or allocating mapping resources.
479.It Fn bus_dmamap_destroy "dmat" "map"
480Frees all resources associated with a given DMA map.
481Arguments are as follows:
482.Bl -tag -width dmat -compact
483.It Fa dmat
484DMA tag used to allocate
485.Fa map .
486.It Fa map
487The DMA map to destroy.
488.El
489.Pp
490Returns
491.Er EBUSY
492if a mapping is still active for
493.Fa map .
494.It Fn bus_dmamap_load "dmat" "map" "buf" "buflen" "*callback" "..."
495Creates a mapping in device visible address space of
496.Fa buflen
497bytes of
498.Fa buf ,
499associated with the DMA map
500.Fa map .
501Arguments are as follows:
502.Bl -tag -width buflen -compact
503.It Fa dmat
504DMA tag used to allocate
505.Fa map .
506.It Fa map
507A DMA map without a currently active mapping.
508.It Fa buf
509A kernel virtual address pointer to a contiguous (in KVA) buffer, to be
510mapped into device visible address space.
511.It Fa buflen
512The size of the buffer.
513.It Fa callback Fa callback_arg
514The callback function, and its argument.
515.It Fa flags
516The value of this argument is currently undefined, and should be
517specified as
518.Ql 0 .
519.El
520.Pp
521Return values to the caller are as follows:
522.Bl -tag -width ".Er EINPROGRESS" -compact
523.It 0
524The callback has been called and completed.
525The status of the mapping has been delivered to the callback.
526.It Er EINPROGRESS
527The mapping has been deferred for lack of resources.
528The callback will be called as soon as resources are available.
529Callbacks are serviced in FIFO order.
530DMA maps created from DMA tags that are allocated with
531the
532.Dv BUS_DMA_ALLOCNOW
533flag will never return this status for a load operation.
534.It Er EINVAL
535The load request was invalid.
536The callback has not, and will not be called.
537This error value may indicate that
538.Fa dmat ,
539.Fa map ,
540.Fa buf ,
541or
542.Fa callback
543were invalid, or
544.Fa buslen
545was larger than the
546.Fa maxsize
547argument used to create the dma tag
548.Fa dmat .
549.El
550.Pp
551When the callback is called, it is presented with an error value
552indicating the disposition of the mapping.
553Error may be one of the following:
554.Bl -tag -width ".Er EINPROGRESS" -compact
555.It 0
556The mapping was successful and the
557.Fa dm_segs
558callback argument contains an array of
559.Vt bus_dma_segment_t
560elements describing the mapping.
561This array is only valid during the scope of the callback function.
562.It Er EFBIG
563A mapping could not be achieved within the segment constraints provided
564in the tag even though the requested allocation size was less than maxsize.
565.El
566.It Fn bus_dmamap_load_ccb "dmat" "map" "ccb" "callback" "callback_arg" "flags"
567This is a variation of
568.Fn bus_dmamap_load
569which maps data pointed to by
570.Fa ccb
571for DMA transfers.
572.It Fn bus_dmamap_load_mbuf "dmat" "map" "mbuf" "callback2" "callback_arg" \
573"flags"
574This is a variation of
575.Fn bus_dmamap_load
576which maps mbuf chains
577for DMA transfers.
578A
579.Vt bus_size_t
580argument is also passed to the callback routine, which
581contains the mbuf chain's packet header length.
582.Pp
583Mbuf chains are assumed to be in kernel virtual address space.
584.Pp
585Returns
586.Er EINVAL
587if the size of the mbuf chain exceeds the maximum limit of the
588DMA tag.
589.It Fn bus_dmamap_load_mbuf_segment "dmat" "map" "mbuf" "*segs" "maxsegs" \
590"*nsegs" "flags"
591It is like
592.Fn bus_dmamap_load_mbuf
593without callback.
594Segmentation information are saved in the
595.Fa segs
596and
597.Fa nsegs
598if the loading is successful.
599The
600.Fa maxsegs ,
601which indicates the number of elements in the
602.Fa segs ,
603must be set by the caller and must be at least 1 and at most equal the
604.Fa nsegments
605used to create the
606.Fa dmat .
607The
608.Fa flags
609must have
610.Dv BUS_DMA_NOWAIT
611turned on.
612.Pp
613This function will not block.
614When system is short of DMA resources,
615this function will return
616.Er ENOMEM ,
617instead of
618.Er EINPROGRESS .
619.It Fn bus_dmamap_load_mbuf_defrag "dmat" "map" "*mbuf" "*segs" "maxsegs" \
620"*nsegs" "flags"
621This function is like
622.Fn bus_dmamap_load_mbuf_segment ,
623but it will call
624.Fn m_defrag
625on the
626.Fa *mbuf
627and try reloading,
628if low level code indicates too many fragments in the
629.Fa *mbuf ;
630the
631.Fa mbuf
632will be updated under this situation.
633However,
634.Fa *mbuf
635would not be freed by this function,
636even if
637.Fn m_defrag
638failed.
639.Pp
640Return
641.Er ENOBUFS ,
642if the calling of
643.Fn m_defrag
644failed.
645.It Fn bus_dmamap_load_uio "dmat" "map" "uio" "callback2" "callback_arg" "flags"
646This is a variation of
647.Fn bus_dmamap_load
648which maps buffers pointed to by
649.Fa uio
650for DMA transfers.
651A
652.Vt bus_size_t
653argument is also passed to the callback routine, which contains the size of
654.Fa uio ,
655i.e.
656.Fa uio->uio_resid .
657.Pp
658If
659.Fa uio->uio_segflg
660is
661.Dv UIO_USERSPACE ,
662then it is assumed that the buffer,
663.Fa uio
664is in
665.Fa "uio->uio_td->td_proc" Ns 's
666address space.
667User space memory must be in-core and wired prior to attempting a map
668load operation.
669.It Fn bus_dmamap_unload "dmat" "map"
670Unloads a DMA map.
671Arguments are as follows:
672.Bl -tag -width dmam -compact
673.It Fa dmat
674DMA tag used to allocate
675.Fa map .
676.It Fa map
677The DMA map that is to be unloaded.
678.El
679.Pp
680.Fn bus_dmamap_unload
681will not perform any implicit synchronization of DMA buffers.
682This must be done explicitly by a call to
683.Fn bus_dmamap_sync
684prior to unloading the map.
685.It Fn bus_dmamap_sync "dmat" "map" "op"
686Performs synchronization of a device visible mapping with the CPU visible
687memory referenced by that mapping.
688Arguments are as follows:
689.Bl -tag -width dmat -compact
690.It Fa dmat
691DMA tag used to allocate
692.Fa map .
693.It Fa map
694The DMA mapping to be synchronized.
695.It Fa op
696Type of synchronization operation to perform.
697See the definition of
698.Vt bus_dmasync_op_t
699for a description of the acceptable values for
700.Fa op .
701.El
702.Pp
703.Fn bus_dmamap_sync
704is the method used to ensure that CPU and device DMA access to shared
705memory is coherent.
706For example, the CPU might be used to setup the contents of a buffer
707that is to be DMA'ed into a device.
708To ensure that the data are visible via the device's mapping of that
709memory, the buffer must be loaded and a dma sync operation of
710.Dv BUS_DMASYNC_PREREAD
711must be performed.
712Additional sync operations must be performed after every CPU write
713to this memory if additional DMA reads are to be performed.
714Conversely, for the DMA write case, the buffer must be loaded,
715and a dma sync operation of
716.Dv BUS_DMASYNC_PREWRITE
717must be performed.
718The CPU will only be able to see the results of this DMA write
719once the DMA has completed and a
720.Dv BUS_DMASYNC_POSTWRITE
721operation has been performed.
722.Pp
723If DMA read and write operations are not preceded and followed by the
724appropriate synchronization operations, behavior is undefined.
725.It Fn bus_dmamem_alloc "dmat" "**vaddr" "flags" "mapp"
726Allocates memory that is mapped into KVA at the address returned
727in
728.Fa vaddr
729that is permanently loaded into the newly created
730.Vt bus_dmamap_t
731returned via
732.Fa mapp .
733Arguments are as follows:
734.Bl -tag -width alignment -compact
735.It Fa dmat
736DMA tag describing the constraints of the DMA mapping.
737.It Fa vaddr
738Pointer to a pointer that will hold the returned KVA mapping of
739the allocated region.
740.It Fa flags
741Flags are defined as follows:
742.Bl -tag -width ".Dv BUS_DMA_COHERENT" -compact
743.It Dv BUS_DMA_WAITOK
744The routine can safely wait (sleep) for resources.
745.It Dv BUS_DMA_NOWAIT
746The routine is not allowed to wait for resources.
747If resources are not available,
748.Er ENOMEM
749is returned.
750.It Dv BUS_DMA_COHERENT
751Attempt to map this memory such that cache sync operations are
752as cheap as possible.
753This flag is typically set on memory that will be accessed by both
754a CPU and a DMA engine, frequently.
755Use of this flag does not remove the requirement of using
756bus_dmamap_sync, but it may reduce the cost of performing
757these operations.
758.It Dv BUS_DMA_ZERO
759Causes the allocated memory to be set to all zeros.
760.It Dv BUS_DMA_NOCACHE
761The allocated memory will not be cached in the processor caches.
762All memory accesses appear on the bus and are executed
763without reordering.
764On x86_64, the
765.Dv BUS_DMA_NOCACHE
766flag results in the
767Strong Uncacheable PAT to be set for the allocated virtual address range.
768.El
769.It Fa mapp
770Pointer to storage for the returned DMA map.
771.El
772.Pp
773The size of memory to be allocated is
774.Fa maxsize
775as specified in
776.Fa dmat .
777.Pp
778The current implementation of
779.Fn bus_dmamem_alloc
780will allocate all requests as a single segment.
781.Pp
782Although no explicit loading is required to access the memory
783referenced by the returned map, the synchronization requirements
784as described in the
785.Fn bus_dmamap_sync
786section still apply.
787.Pp
788Returns
789.Er ENOMEM
790if sufficient memory is not available for completing
791the operation.
792.It Fn bus_dmamem_coherent "parent" "alignment" "boundary" "lowaddr" \
793"highaddr" "maxsize" "flags" "*dmem"
794This is a convenient function to create one segment of DMA memory.
795It combines following
796.Nm
797function calls:
798.Bd -literal
799	bus_dma_tag_create(..., dtag);
800	bus_dmamem_alloc(*dtag, vaddr, ..., dmap);
801	bus_dmamap_load(*dtag, *dmap, *vaddr, ..., \\
802			callback, busaddr, ...);
803.Ed
804.sp
805The final results of the above function calls are:
806DMA tag,
807DMA map,
808DMA memory's kernel virtual address and
809its device visible address.
810.Fn bus_dmamem_coherent
811saves the results in
812.Fa *dmem .
813.Pp
814The
815.Fa parent ,
816.Fa alignment ,
817.Fa boundary ,
818.Fa lowaddr
819and
820.Fa highaddr
821will be passed to
822.Fn bus_dma_tag_create
823as they are.
824The
825.Fa maxsize
826will be passed to
827.Fn bus_dma_tag_create
828as its
829.Fa maxsize
830and
831.Fa maxsegsz
832and
833.Ql 1
834will be passed to
835.Fn bus_dma_tag_create
836as its
837.Fa nsegments .
838When
839.Fn bus_dmamem_alloc
840is called,
841.Fa flags
842will be first or'ed with
843.Dv BUS_DMA_COHERENT
844then passed to it.
845The final results of the above three functions,
846i.e. DMA tag,
847DMA map,
848DMA memory's kernel virtual address and
849its device visible address,
850are saved in
851.Fa *dmem .
852If any of the three functions failed,
853this function will return the error code and the
854.Fa *dmem
855should not be used.
856.It Fn bus_dmamem_coherent_any "parent" "alignment" "maxsize" "flags" \
857"*dtag" "*dmap" "*busaddr"
858This function is a simplified version of
859.Fn bus_dmamem_coherent
860with
861its
862.Fa boundary
863set to
864.Ql 0 ,
865.Fa lowaddr
866set to
867.Dv BUS_SPACE_MAXADDR
868and
869.Fa highaddr
870set to
871.Dv BUS_SPACE_MAXADDR .
872The
873.Fa parent
874usually should not be NULL.
875.Pp
876Return the DMA memory's kernel virtual address.
877The DMA tag, DMA map and device visible address are returned in
878.Fa *dtag ,
879.Fa *dmap ,
880and
881.Fa *busaddr .
882If this function failed,
883NULL will be returned;
884.Fa *dtag ,
885.Fa *dmap ,
886and
887.Fa *busaddr
888are left unchanged.
889.It Fn bus_dmamem_free "dmat" "*vaddr" "map"
890Frees memory previously allocated by
891.Fn bus_dmamem_alloc .
892Any mappings
893will be invalidated.
894Arguments are as follows:
895.Bl -tag -width vaddr -compact
896.It Fa dmat
897DMA tag.
898.It Fa vaddr
899Kernel virtual address of the memory.
900.It Fa map
901DMA map to be invalidated.
902.El
903.El
904.Sh RETURN VALUES
905Behavior is undefined if invalid arguments are passed to
906any of the above functions.
907If sufficient resources cannot be allocated for a given
908transaction,
909.Er ENOMEM
910is returned.
911All
912routines that are not of type,
913.Vt void ,
914will return 0 on success or an error
915code, as discussed above.
916.Pp
917All
918.Vt void
919routines will succeed if provided with valid arguments.
920.Sh SEE ALSO
921.Xr devclass 9 ,
922.Xr device 9 ,
923.Xr driver 9 ,
924.Xr rman 9
925.Rs
926.%A "Jason R. Thorpe"
927.%T "A Machine-Independent DMA Framework for NetBSD"
928.%J "Proceedings of the Summer 1998 USENIX Technical Conference"
929.%Q "USENIX Association"
930.%D "June 1998"
931.Re
932.Sh HISTORY
933The
934.Nm
935interface first appeared in
936.Nx 1.3 .
937.Pp
938The
939.Nm
940API was adopted from
941.Nx
942for use in the CAM SCSI subsystem.
943The alterations to the original API were aimed to remove the need for
944a
945.Vt bus_dma_segment_t
946array stored in each
947.Vt bus_dmamap_t
948while allowing callers to queue up on scarce resources.
949.Sh AUTHORS
950The
951.Nm
952interface was designed and implemented by
953.An Jason R. Thorpe
954of the Numerical Aerospace Simulation Facility, NASA Ames Research Center.
955Additional input on the
956.Nm
957design was provided by
958.An -nosplit
959.An Chris Demetriou ,
960.An Charles Hannum ,
961.An Ross Harvey ,
962.An Matthew Jacob ,
963.An Jonathan Stone ,
964and
965.An Matt Thomas .
966.Pp
967This manual page was written by
968.An Hiten Pandya
969and
970.An Justin T. Gibbs .
971