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