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