xref: /freebsd/share/man/man9/bus_dma.9 (revision ca9ac06c99bfd0150b85d4d83c396ce6237c0e05)
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 May 28, 2003
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.
187Multiple DMA maps can be associated with one DMA tag.
188.It Vt bus_dmamap_callback_t
189Client specified callback for receiving mapping information resulting from
190the load of a
191.Vt bus_dmamap_t
192via
193.Fn bus_dmamap_load .
194Callbacks are of the format:
195.Bl -tag -width compact
196.It Ft void
197.Fn "client_callback" "void *callback_arg" "bus_dma_segment_t *segs" \
198"int nseg" "int error"
199.El
200.sp
201The
202.Fa callback_arg
203is the callback argument passed to dmamap load functions.
204The
205.Fa segs
206and
207.Fa nseg
208parameters describe an array of
209.Vt bus_dma_segment_t
210structures that represent the mapping.
211This array is only valid within the scope of the callback function.
212The success or failure of the mapping is indicated by the
213.Fa error
214parameter.
215More information on the use of callbacks can be found in the
216description of the individual dmamap load functions.
217.It Vt bus_dmamap_callback2_t
218Client specified callback for receiving mapping information resulting from
219the load of a
220.Vt bus_dmamap_t
221via
222.Fn bus_dmamap_load_uio
223or
224.Fn bus_dmamap_load_mbuf .
225.sp
226Callback2s are of the format:
227.Bl -tag -width compact
228.It Ft void
229.Fn "client_callback2" "void *callback_arg" "bus_dma_segment_t *segs" \
230"int nseg" "bus_size_t mapsize" "int error"
231.El
232.sp
233Callback2's behavior is the same as
234.Vt bus_dmamap_callback_t
235with the addition that the length of the data mapped is provided via
236.Fa mapsize .
237.It Vt bus_dmasync_op_t
238Memory synchronization operation specifier.
239Bus DMA requires explicit synchronization of memory with its device
240visible mapping in order to guarantee memory coherency.
241The
242.Vt bus_dmasync_op_t
243allows the type of DMA operation that will be or has been performed
244to be communicated to the system so that the correct coherency measures
245are taken.
246All operations specified below are performed from the CPU's
247point of view (for a complete description, see the
248.Fn bus_dmamap_sync
249description below):
250.Bl -tag -width BUS_DMASYNC_POSTWRITE
251.It Dv BUS_DMASYNC_PREREAD
252Perform any synchronization required after an update of memory by the CPU
253but prior to DMA read operations.
254.It Dv BUS_DMASYNC_PREWRITE
255Perform any synchronization required after an update of memory by the CPU
256but prior to DMA write operations.
257.It Dv BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE
258Perform any synchronization required prior to a combination of DMA read
259and write operations.
260.It Dv BUS_DMASYNC_POSTREAD
261Perform any synchronization required after DMA read operations, but prior
262to CPU access of the memory.
263.It Dv BUS_DMASYNC_POSTWRITE
264Perform any synchronization required after DMA write operations, but prior
265to CPU access of the memory.
266.It Dv BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE
267Perform any synchronization required after a combination of DMA read
268and write operations.
269.El
270.It Vt bus_dma_lock_t
271Client specified lock/mutex manipulation method.
272This will be called from
273within busdma whenever a client lock needs to be manipulated.
274In its current form, the function will be called immediately before
275the callback for a dma load operation that has been deferred with
276.Dv BUS_DMA_LOCK
277and immediately after with
278.Dv BUS_DMA_UNLOCK .
279If the load operation does not need to be deferred, then it
280will not be called since the function loading the map should
281be holding the appropriate locks.
282This method is of the format:
283.Bl -tag -width compact
284.It Ft void
285.Fn "lockfunc" "void *lockfunc_arg" "bus_dma_lock_op_t op"
286.El
287.sp
288Two
289.Vt lockfunc
290implementations are provided for convenience.
291.Fn busdma_lock_mutex
292performs standard mutex operations on the sleep mutex provided via the
293.Fa lockfuncarg .
294passed into
295.Fn bus_dma_tag_create .
296.Fn dflt_lock
297will generate a system panic if it is called.
298It is substituted into the tag when
299.Fa lockfunc
300is passed as NULL to
301.Fn bus_dma_tag_create .
302.It Vt bus_dma_lock_op_t
303Operations to be performed by the client-specified
304.Fn lockfunc .
305.Bl -tag -width BUS_DMA_UNLOCK
306.It Dv BUS_DMA_LOCK
307Acquires and/or locks the client locking primitive.
308.It Dv BUS_DMA_UNLOCK
309Releases and/or unlocks the client locking primitive.
310.El
311.El
312.sp
313.Sh FUNCTIONS
314.Bl -tag -width compact
315.It Fn bus_dma_tag_create "parent" "alignment" "boundary" "lowaddr" \
316"highaddr" "*filtfunc" "*filtfuncarg" "maxsize" "nsegments" "maxsegsz" \
317"flags" "lockfunc" "lockfuncarg" "*dmat"
318Allocates a device specific DMA tag, and initializes it according to
319the arguments provided:
320.Bl -tag -width *filtfuncarg -compact
321.It Fa parent
322Indicates restrictions between the parent bridge, CPU memory, and the
323device.
324May be NULL, if no DMA restrictions are to be inherited.
325.It Fa alignment
326Alignment constraint, in bytes, of any mappings created using this tag.
327The alignment must be a power of 2.
328Hardware that can DMA starting at any address would specify
329.Em 1
330for byte alignment.
331Hardware requiring DMA transfers to start on a multiple of 4K
332would specify
333.Em 4096.
334.It Fa boundary
335Boundary constraint, in bytes, of the target DMA memory region.
336The boundary indicates the set of addresses, all multiples of the
337boundary argument, that cannot be crossed by a single
338.Vt bus_dma_segment_t .
339The boundary must be a power of 2 and must be no smaller than the
340maximum segment size.
341.Ql 0
342indicates that there are no boundary restrictions.
343.It Fa lowaddr
344.It Fa highaddr
345Bounds of the window of bus address space that
346.Em cannot
347be directly accessed by the device.
348The window contains all addresses greater than lowaddr and
349less than or equal to highaddr.
350For example, a device incapable of DMA above 4GB, would specify
351a highaddr of
352.Dv BUS_SPACE_MAXADDR
353and a lowaddr of
354.Dv BUS_SPACE_MAXADDR_32BIT .
355Similarly a device that can only dma to addresses bellow 16MB would
356specify a highaddr of
357.Dv BUS_SPACE_MAXADDR
358and a lowaddr of
359.Dv BUS_SPACE_MAXADDR_24BIT .
360Some implementations requires that some region of device visible
361address space, overlapping available host memory, be outside the
362window.
363This area of
364.Ql safe memory
365is used to bounce requests that would otherwise conflict with
366the exclusion window.
367.It Fa filtfunc
368Optional filter function (may be NULL) to be called for any attempt to
369map memory into the window described by
370.Fa lowaddr
371and
372.Fa highaddr.
373A filter function is only required when the single window described
374by
375.Fa lowaddr
376and
377.Fa highaddr
378cannot adequately describe the constraints of the device.
379The filter function will be called for every machine page
380that overlaps the exclusion window.
381.It Fa filtfuncarg
382Argument passed to all calls to the filter function for this tag.
383May be NULL.
384.It Fa maxsize
385Maximum size, in bytes, of the sum of all segment lengths in a given
386DMA mapping associated with this tag.
387.It Fa nsegments
388Number of discontinuities (scatter/gather segments) allowed
389in a DMA mapped region.
390If there is no restriction,
391.Dv BUS_SPACE_UNRESTRICTED
392may be specified.
393.It Fa maxsegsz
394Maximum size, in bytes, of a segment in any DMA mapped region associated
395with
396.Fa dmat .
397.It Fa flags
398Are as follows:
399.Bl -tag -width "BUS_DMA_ALLOCNOW" -compact
400.It Dv BUS_DMA_ALLOCNOW
401Pre-allocate enough resources to handle at least one map load operation on
402this tag without blocking.
403If sufficient resources are not available,
404.Er ENOMEM
405is returned.
406This should not be used for tags that will not be directly associated with
407a map.
408.El
409.It Fa lockfunc
410Optional lock manipulation function (may be NULL) to be called when busdma
411needs to manipulate a lock on behalf of the client.
412If NULL is specified,
413.Fn dflt_lock
414is used.
415.It Fa lockfuncarg
416Optional argument to be passed to the function specified by
417.Fa lockfunc .
418.It Fa dmat
419Pointer to a bus_dma_tag_t where the resulting DMA tag will
420be stored.
421.El
422.Pp
423Returns
424.Er ENOMEM
425if sufficient memory is not available for tag creation
426or allocating mapping resources.
427.It Fn bus_dma_tag_destroy "dmat"
428Deallocate the DMA tag
429.Fa dmat
430that was created by
431.Fn bus_dma_tag_create .
432.Pp
433Returns
434.Er EBUSY
435if any DMA maps remain associated with
436.Fa dmat
437or
438.Ql 0
439on success.
440.It Fn bus_dmamap_create "dmat" "flags" "*mapp"
441Allocates and initializes a DMA map.
442Arguments are as follows:
443.Bl -tag -width nsegments -compact
444.It Fa dmat
445DMA tag.
446.It Fa flags
447The value of this argument is currently undefined and should be
448specified as
449.Ql 0 .
450.It Fa mapp
451Pointer to a
452.Vt bus_dmamap_t
453where the resulting DMA map will be stored.
454.El
455.Pp
456Returns
457.Er ENOMEM
458if sufficient memory is not available for creating the
459map or allocating mapping resources.
460.It Fn bus_dmamap_destroy "dmat" "map"
461Frees all resources associated with a given DMA map.
462Arguments are as follows:
463.Bl -tag -width dmat -compact
464.It Fa dmat
465DMA tag used to allocate
466.Fa map .
467.It Fa map
468The DMA map to destroy.
469.El
470.Pp
471Returns
472.Er EBUSY
473if a mapping is still active for
474.Fa map .
475.It Fn bus_dmamap_load "dmat" "map" "buf" "buflen" "*callback" \
476"callback_arg" "flags"
477Creates a mapping in device visible address space of
478.Fa buflen
479bytes of
480.Fa buf ,
481associated with the DMA map
482.Fa map.
483Arguments are as follows:
484.Bl -tag -width buflen -compact
485.It Fa dmat
486DMA tag used to allocate
487.Fa map.
488.It Fa map
489A DMA map without a currently active mapping.
490.It Fa buf
491A kernel virtual address pointer to a contiguous (in KVA) buffer, to be
492mapped into device visible address space.
493.It Fa buflen
494The size of the buffer.
495.It Fa callback Fa callback_arg
496The callback function, and its argument.
497.It Fa flags
498The value of this argument is currently undefined, and should be
499specified as
500.Ql 0 .
501.El
502.Pp
503Return values to the caller are as follows:
504.Bl -tag -width EINPROGRESS -compact
505.It 0
506The callback has been called and completed.
507The status of the mapping has been delivered to the callback.
508.It Er EINPROGRESS
509The mapping has been deferred for lack of resources.
510The callback will be called as soon as resources are available.
511Callbacks are serviced in FIFO order.
512To ensure that ordering is guaranteed, all subsequent load requests will also
513be deferred until all callbacks have been processed.
514.It Er EINVAL
515The load request was invalid.
516The callback has not, and will not be called.
517This error value may indicate that
518.Fa dmat ,
519.Fa map ,
520.Fa buf ,
521or
522.Fa callback
523were invalid, or
524.Fa buslen
525was larger than the
526.Fa maxsize
527argument used to create the dma tag
528.Fa dmat .
529.El
530.Pp
531When the callback is called, it is presented with an error value
532indicating the disposition of the mapping.
533Error may be one of the following:
534.Bl -tag -width EINPROGRESS -compact
535.It 0
536The mapping was successful and the
537.Fa dm_segs
538callback argument contains an array of
539.Vt bus_dma_segment_t
540elements describing the mapping.
541This array is only valid during the scope of the callback function.
542.It Er EFBIG
543A mapping could not be achieved within the segment constraints provided
544in the tag even though the requested allocation size was less than maxsize.
545.El
546.It Fn bus_dmamap_load_mbuf "dmat" "map" "mbuf" "callback2" "callback_arg" \
547"flags"
548This is a variation of
549.Fn bus_dmamap_load
550which maps mbuf chains
551for DMA transfers.
552A
553.Vt bus_size_t
554argument is also passed to the callback routine, which
555contains the mbuf chain's packet header length.
556.Pp
557Mbuf chains are assumed to be in kernel virtual address space.
558.Pp
559Returns
560.Er EINVAL
561if the size of the mbuf chain exceeds the maximum limit of the
562DMA tag.
563.It Fn bus_dmamap_load_mbuf_sg "dmat" "map" "mbuf" "segs" "nsegs" "flags"
564This is just like
565.Fn bus_dmamap_load_mbuf
566except that it returns immediately without calling a callback function.  It is
567provided for efficiency.
568The scatter/gather segment array
569.Va segs
570is provided by the caller and filled in directly by the function.
571The
572.Va nsegs
573argument is returned with the number of segments filled in.
574Returns the same errors as
575.Fn bus_dmamap_load_mbuf .
576.It Fn bus_dmamap_load_uio "dmat" "map" "uio" "callback2" "callback_arg" "flags"
577This is a variation of
578.Fn bus_dmamap_load
579which maps buffers pointed to by
580.Fa uio
581for DMA transfers.
582A
583.Vt bus_size_t
584argument is also passed to the callback routine, which contains the size of
585.Fa uio ,
586i.e.
587.Fa uio->uio_resid .
588.Pp
589If
590.Fa uio->uio_segflg
591is
592.Dv UIO_USERSPACE ,
593then it is assumed that the buffer,
594.Fa uio
595is in
596.Fa "uio->uio_td->td_proc" Ns 's
597address space.
598User space memory must be in-core and wired prior to attempting a map
599load operation.
600Pages may be locked using
601.Xr vslock 9 .
602.It Fn bus_dmamap_unload "dmat" "map"
603Unloads a DMA map.
604Arguments are as follows:
605.Bl -tag -width dmam -compact
606.It Fa dmat
607DMA tag used to allocate
608.Fa map .
609.It Fa map
610The DMA map that is to be unloaded.
611.El
612.Pp
613.Fn bus_dmamap_unload
614will not perform any implicit synchronization of DMA buffers.
615This must be done explicitly by a call to
616.Fn bus_dmamap_sync
617prior to unloading the map.
618.It Fn bus_dmamap_sync "dmat" "map" "op"
619Performs synchronization of a device visible mapping with the CPU visible
620memory referenced by that mapping.
621Arguments are as follows:
622.Bl -tag -width dmat -compact
623.It Fa dmat
624DMA tag used to allocate
625.Fa map .
626.It Fa map
627The DMA mapping to be synchronized.
628.It Fa op
629Type of synchronization operation to perform.
630See the definition of
631.Vt bus_dmasync_op_t
632for a description of the acceptable values for
633.Fa op .
634.El
635.Pp
636.Fn bus_dmamap_sync
637is the method used to ensure that CPU and device DMA access to shared
638memory is coherent.
639For example, the CPU might be used to setup the contents of a buffer
640that is to be DMA'ed into a device.
641To ensure that the data are visible via the device's mapping of that
642memory, the buffer must be loaded and a dma sync operation of
643.Dv BUS_DMASYNC_PREREAD
644must be performed.
645Additional sync operations must be performed after every CPU write
646to this memory if additional DMA reads are to be performed.
647Conversely, for the DMA write case, the buffer must be loaded,
648and a dma sync operation of
649.Dv BUS_DMASYNC_PREWRITE
650must be performed.
651The CPU will only be able to see the results of this DMA write
652once the DMA has completed and a
653.Dv BUS_DMASYNC_POSTWRITE
654operation has been performed.
655.Pp
656If DMA read and write operations are not preceded and followed by the
657appropriate synchronization operations, behavior is undefined.
658.It Fn bus_dmamem_alloc "dmat" "**vaddr" "flags" "mapp"
659Allocates memory that is mapped into KVA at the address returned
660in
661.Fa vaddr
662that is permanently loaded into the newly created
663.Vt bus_dmamap_t
664returned via
665.Fa mapp .
666Arguments are as follows:
667.Bl -tag -width alignment -compact
668.It Fa dmat
669DMA tag describing the constraints of the DMA mapping.
670.It Fa vaddr
671Pointer to a pointer that will hold the returned KVA mapping of
672the allocated region.
673.It Fa flags
674Flags are defined as follows:
675.Bl -tag -width BUS_DMA_NOWAIT -compact
676.It Dv BUS_DMA_WAITOK
677The routine can safely wait (sleep) for resources.
678.It Dv BUS_DMA_NOWAIT
679The routine is not allowed to wait for resources.
680If resources are not available,
681.Dv ENOMEM
682is returned.
683.It Dv BUS_DMA_COHERENT
684Attempt to map this memory such that cache sync operations are
685as cheap as possible.
686This flag is typically set on memory that will be accessed by both
687a CPU and a DMA engine, frequently.
688Use of this flag does not remove the requirement of using
689bus_dmamap_sync, but it may reduce the cost of performing
690these operations.
691.It Dv BUS_DMA_ZERO
692Causes the allocated memory to be set to all zeros.
693.El
694.It Fa mapp
695Pointer to storage for the returned DMA map.
696.El
697.Pp
698The size of memory to be allocated is
699.Fa maxsize
700as specified in
701.Fa dmat .
702.Pp
703The current implementation of
704.Fn bus_dmamem_alloc
705will allocate all requests as a single segment.
706.Pp
707Although no explicit loading is required to access the memory
708referenced by the returned map, the synchronization requirements
709as described in the
710.Fn bus_dmamap_sync
711section still apply.
712.Pp
713Returns
714.Er ENOMEM
715if sufficient memory is not available for completing
716the operation.
717.It Fn bus_dmamem_free "dmat" "*vaddr" "map"
718Frees memory previously allocated by
719.Fn bus_dmamem_alloc .
720Any mappings
721will be invalidated.
722Arguments are as follows:
723.Bl -tag -width vaddr -compact
724.It Fa dmat
725DMA tag.
726.It Fa vaddr
727Kernel virtual address of the memory.
728.It Fa map
729DMA map to be invalidated.
730.El
731.El
732.Sh RETURN VALUES
733Behavior is undefined if invalid arguments are passed to
734any of the above functions.
735If sufficient resources cannot be allocated for a given
736transaction,
737.Er ENOMEM
738is returned.
739All
740routines that are not of type,
741.Vt void ,
742will return 0 on success or an error
743code, as discussed above.
744.Pp
745All
746.Vt void
747routines will succeed if provided with valid arguments.
748.Sh SEE ALSO
749.Xr devclass 9 ,
750.Xr device 9 ,
751.Xr driver 9 ,
752.Xr rman 9 ,
753.Xr vslock 9
754.Pp
755.Rs
756.%A "Jason R. Thorpe"
757.%T "A Machine-Independent DMA Framework for NetBSD"
758.%J "Proceedings of the Summer 1998 USENIX Technical Conference"
759.%Q "USENIX Association"
760.%D "June 1998"
761.Re
762.Sh HISTORY
763The
764.Nm
765interface first appeared in
766.Nx 1.3 .
767.Pp
768The
769.Nm
770API was adopted from
771.Nx
772for use in the CAM SCSI subsystem.
773The alterations to the original API were aimed to remove the need for
774a
775.Vt bus_dma_segment_t
776array stored in each
777.Vt bus_dmamap_t
778while allowing callers to queue up on scarce resources.
779.Sh AUTHORS
780The
781.Nm
782interface was designed and implemented by
783.An Jason R. Thorpe
784of the Numerical Aerospace Simulation Facility, NASA Ames Research Center.
785Additional input on the
786.Nm
787design was provided by
788.An -nosplit
789.An Chris Demetriou ,
790.An Charles Hannum ,
791.An Ross Harvey ,
792.An Matthew Jacob ,
793.An Jonathan Stone ,
794and
795.An Matt Thomas .
796.Pp
797The
798.Nm
799interface in
800.Fx
801benefits from the contributions of
802.An Justin T. Gibbs ,
803.An Peter Wemm ,
804.An Doug Rabson ,
805.An Matthew N. Dodd ,
806.An Sam Leffler ,
807.An Maxime Henrion ,
808.An Jake Burkholder ,
809.An Takahashi Yoshihiro ,
810.An Scott Long
811and many others.
812.Pp
813This manual page was written by
814.An Hiten M. Pandya
815and
816.An Justin T. Gibbs .
817