1.\" $NetBSD: bus_dma.9,v 1.34 2005/12/20 19:53:14 rpaulo Exp $ 2.\" 3.\" Copyright (c) 1996, 1997, 1998, 2001, 2005 The NetBSD Foundation, Inc. 4.\" All rights reserved. 5.\" 6.\" This code is derived from software contributed to The NetBSD Foundation 7.\" by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 8.\" NASA Ames Research Center. 9.\" 10.\" Redistribution and use in source and binary forms, with or without 11.\" modification, are permitted provided that the following conditions 12.\" are met: 13.\" 1. Redistributions of source code must retain the above copyright 14.\" notice, this list of conditions and the following disclaimer. 15.\" 2. Redistributions in binary form must reproduce the above copyright 16.\" notice, this list of conditions and the following disclaimer in the 17.\" documentation and/or other materials provided with the distribution. 18.\" 3. All advertising materials mentioning features or use of this software 19.\" must display the following acknowledgment: 20.\" This product includes software developed by the NetBSD 21.\" Foundation, Inc. and its contributors. 22.\" 4. Neither the name of The NetBSD Foundation nor the names of its 23.\" contributors may be used to endorse or promote products derived 24.\" from this software without specific prior written permission. 25.\" 26.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36.\" POSSIBILITY OF SUCH DAMAGE. 37.\" 38.Dd December 20, 2005 39.Dt BUS_DMA 9 40.Os 41.Sh NAME 42.Nm bus_dma , 43.Nm bus_dmamap_create , 44.Nm bus_dmamap_destroy , 45.Nm bus_dmamap_load , 46.Nm bus_dmamap_load_mbuf , 47.Nm bus_dmamap_load_uio , 48.Nm bus_dmamap_load_raw , 49.Nm bus_dmamap_unload , 50.Nm bus_dmamap_sync , 51.Nm bus_dmamem_alloc , 52.Nm bus_dmamem_free , 53.Nm bus_dmamem_map , 54.Nm bus_dmamem_unmap , 55.Nm bus_dmamem_mmap 56.Nd Bus and Machine Independent DMA Mapping Interface 57.Sh SYNOPSIS 58.In machine/bus.h 59.Ft int 60.Fn bus_dmamap_create "bus_dma_tag_t tag" "bus_size_t size" "int nsegments" \ 61"bus_size_t maxsegsz" "bus_size_t boundary" "int flags" "bus_dmamap_t *dmamp" 62.Ft void 63.Fn bus_dmamap_destroy "bus_dma_tag_t tag" "bus_dmamap_t dmam" 64.Ft int 65.Fn bus_dmamap_load "bus_dma_tag_t tag" "bus_dmamap_t dmam" "void *buf" \ 66"bus_size_t buflen" "struct lwp *l" "int flags" 67.Ft int 68.Fn bus_dmamap_load_mbuf "bus_dma_tag_t tag" "bus_dmamap_t dmam" \ 69"struct mbuf *chain" "int flags" 70.Ft int 71.Fn bus_dmamap_load_uio "bus_dma_tag_t tag" "bus_dmamap_t dmam" \ 72"struct uio *uio" "int flags" 73.Ft int 74.Fn bus_dmamap_load_raw "bus_dma_tag_t tag" "bus_dmamap_t dmam" \ 75"bus_dma_segment_t *segs" "int nsegs" "bus_size_t size" "int flags" 76.Ft void 77.Fn bus_dmamap_unload "bus_dma_tag_t tag" "bus_dmamap_t dmam" 78.Ft void 79.Fn bus_dmamap_sync "bus_dma_tag_t tag" "bus_dmamap_t dmam" \ 80"bus_addr_t offset" "bus_size_t len" "int ops" 81.Ft int 82.Fn bus_dmamem_alloc "bus_dma_tag_t tag" "bus_size_t size" \ 83"bus_size_t alignment" "bus_size_t boundary" "bus_dma_segment_t *segs" \ 84"int nsegs" "int *rsegs" "int flags" 85.Ft void 86.Fn bus_dmamem_free "bus_dma_tag_t tag" "bus_dma_segment_t *segs" "int nsegs" 87.Ft int 88.Fn bus_dmamem_map "bus_dma_tag_t tag" "bus_dma_segment_t *segs" "int nsegs" \ 89"size_t size" "caddr_t *kvap" "int flags" 90.Ft void 91.Fn bus_dmamem_unmap "bus_dma_tag_t tag" "caddr_t kva" "size_t size" 92.Ft paddr_t 93.Fn bus_dmamem_mmap "bus_dma_tag_t tag" "bus_dma_segment_t *segs" \ 94"int nsegs" "off_t off" "int prot" "int flags" 95.Sh DESCRIPTION 96Provide a bus- and machine-independent "DMA mapping interface." 97.Sh NOTES 98All data structures, function prototypes, and macros will be defined 99by the port-specific header 100.Aq Pa machine/bus.h . 101Note that this document 102assumes the existence of types already defined by the current "bus.h" 103interface. 104.Pp 105Unless otherwise noted, all function calls in this interface may be 106defined as 107.Xr cpp 1 108macros. 109.Sh DATA TYPES 110Individual implementations may name these structures whatever they 111wish, providing that the external representations are: 112.Bl -tag -width compact 113.It Fa bus_dma_tag_t 114A machine-dependent opaque type describing the implementation of 115DMA for a given bus. 116.It Fa bus_dma_segment_t 117A structure with at least the following members: 118.Bd -literal 119 bus_addr_t ds_addr; 120 bus_size_t ds_len; 121.Ed 122.sp 123The structure may have machine-dependent members and arbitrary layout. 124The values in 125.Fa ds_addr 126and 127.Fa ds_len 128are suitable for programming into 129DMA controller address and length registers. 130.It Fa bus_dmamap_t 131A pointer to a structure with at least the following members: 132.Bd -literal 133 bus_size_t dm_maxsegsz; 134 bus_size_t dm_mapsize; 135 int dm_nsegs; 136 bus_dma_segment_t *dm_segs; 137.Ed 138.sp 139The structure may have machine-dependent members and arbitrary layout. 140The 141.Fa dm_maxsegsz 142member indicates the maximum number of bytes that may be transferred by 143any given DMA segment. 144The 145.Fa dm_mapsize 146member indicates the size of the mapping. 147A value of 0 indicates the mapping is invalid. 148The 149.Fa dm_segs 150member may be an array of segments or a pointer to an 151array of segments. 152The 153.Fa dm_nsegs 154member indicates the number of segments in 155.Fa dm_segs . 156.El 157.Sh FUNCTIONS 158.Bl -tag -width compact 159.It Fn bus_dmamap_create "tag" "size" "nsegments" "maxsegsz" "boundary" "flags" "dmamp" 160Allocates a DMA handle and initializes it according to the parameters 161provided. 162Arguments are as follows: 163.Bl -tag -width nsegments -compact 164.It Fa tag 165This is the bus_dma_tag_t passed down from the parent driver via 166.Fa \*[Lt]bus\*[Gt]_attach_args . 167.It Fa size 168This is the maximum DMA transfer that can be mapped by the handle. 169.It Fa nsegments 170Number of segments the device can support in a single DMA transaction. 171This may be the number of scatter-gather descriptors supported by the 172device. 173.It Fa maxsegsz 174The maximum number of bytes that may be transferred by any given DMA 175segment and will be assigned to the 176.Fa dm_maxsegsz 177member. 178.It Fa boundary 179Some DMA controllers are not able to transfer data that crosses a 180particular boundary. 181This argument allows this boundary to be specified. 182The boundary lines begin at 0, and occur every 183.Fa boundary 184bytes. 185Mappings may begin on a boundary line but may not end on or 186cross a boundary line. 187If no boundary condition needs to be observed, a 188.Fa boundary 189argument of 0 should be used. 190.It Fa flags 191Flags are defined as follows: 192.Bl -tag -width BUS_DMA_ALLOCNOW -compact 193.It Dv BUS_DMA_WAITOK 194It is safe to wait (sleep) for resources during this call. 195.It Dv BUS_DMA_NOWAIT 196It is not safe to wait (sleep) for resources during this call. 197.It Dv BUS_DMA_ALLOCNOW 198Perform any resource allocation this handle may need now. 199If this is not specified, the allocation may be deferred to 200.Fn bus_dmamap_load . 201If this flag is specified, 202.Fn bus_dmamap_load 203will not block on resource 204allocation. 205.It Dv BUS_DMA_BUS[1-4] 206These flags are placeholders, and may be used by busses to provide 207bus-dependent functionality. 208.El 209.It Fa dmamp 210This is a pointer to a bus_dmamap_t. 211A DMA map will be allocated and pointed to by 212.Fa dmamp 213upon successful completion of this routine. 214.El 215.Pp 216Behavior is not defined if invalid arguments are passed to 217.Fn bus_dmamap_create . 218.Pp 219Returns 0 on success, or an error code to indicate mode of failure. 220.It Fn bus_dmamap_destroy "tag" "dmam" 221Frees all resources associated with a given DMA handle. 222Arguments are as follows: 223.Bl -tag -width dmam -compact 224.It Fa tag 225This is the bus_dma_tag_t passed down from the parent driver via 226.Fa \*[Lt]bus\*[Gt]_attach_args . 227.It Fa dmam 228The DMA handle to destroy. 229.El 230.Pp 231In the event that the DMA handle contains a valid mapping, 232the mapping will be unloaded via the same mechanism used by 233.Fn bus_dmamap_unload . 234.Pp 235Behavior is not defined if invalid arguments are passed to 236.Fn bus_dmamap_destroy . 237.Pp 238If given valid arguments, 239.Fn bus_dmamap_destroy 240always succeeds. 241.It Fn bus_dmamap_load "tag" "dmam" "buf" "buflen" "p" "flags" 242Loads a DMA handle with mappings for a DMA transfer. 243It assumes that all pages involved in a DMA transfer are wired. 244Arguments are as follows: 245.Bl -tag -width buflen -compact 246.It Fa tag 247This is the bus_dma_tag_t passed down from the parent driver via 248.Fa \*[Lt]bus\*[Gt]_attach_args . 249.It Fa dmam 250The DMA handle with which to map the transfer. 251.It Fa buf 252The buffer to be used for the DMA transfer. 253.It Fa buflen 254The size of the buffer. 255.It Fa p 256Used to indicate the address space in which the buffer is located. 257If 258.Dv NULL , 259the buffer is assumed to be in kernel space. 260Otherwise, the buffer is assumed to be in process 261.Fa p Ns 's 262address space. 263.It Fa flags 264are defined as follows: 265.Bl -tag -width "BUS_DMA_STREAMING" -compact 266.It Dv BUS_DMA_WAITOK 267It is safe to wait (sleep) for resources during this call. 268.It Dv BUS_DMA_NOWAIT 269It is not safe to wait (sleep) for resources during this call. 270.It Dv BUS_DMA_STREAMING 271By default, the 272.Nm 273API assumes that there is coherency between memory and the device 274performing the DMA transaction. 275Some platforms, however, have special hardware, such as an 276.Dq I/O cache , 277which may improve performance 278of some types of DMA transactions, but which break the assumption 279that there is coherency between memory and the device performing 280the DMA transaction. 281This flag allows the use of this special hardware, provided that 282the device is doing sequential, unidirectional transfers which 283conform to certain alignment and size constraints defined by the 284platform. 285If the platform does not support the feature, or if the buffer being 286loaded into the DMA map does not conform to the constraints required 287for use of the feature, then this flag will be silently ignored. 288Also refer to the use of this flag with the 289.Fn bus_dmamem_alloc 290function. 291.It Dv BUS_DMA_READ 292This is a hint to the machine-dependent back-end that indicates the 293mapping will be used only for a 294.Em "device -\*[Gt] memory" 295transaction. 296The back-end may perform optimizations based on this information. 297.It Dv BUS_DMA_WRITE 298This is a hint to the machine-dependent back-end that indicates the 299mapping will be used only for a 300.Em "memory -\*[Gt] device" 301transaction. 302The back-end may perform optimizations based on this information. 303.It Dv BUS_DMA_BUS[1-4] 304These flags are placeholders, and may be used by busses to 305provide bus-dependent functionality. 306.El 307.El 308.Pp 309As noted above, if a DMA handle is created with 310.Dv BUS_DMA_ALLOCNOW , 311.Fn bus_dmamap_load 312will never block. 313.Pp 314If a call to 315.Fn bus_dmamap_load 316fails, the mapping in 317the DMA handle will be invalid. 318It is the responsibility of the caller to clean up any inconsistent 319device state resulting from incomplete iteration through the uio. 320.Pp 321Behavior is not defined if invalid arguments are passed to 322.Fn bus_dmamap_load . 323.Pp 324Returns 0 on success, or an error code to indicate mode of failure. 325.It Fn bus_dmamap_load_mbuf "tag" "dmam" "chain" "flags" 326This is a variation of 327.Fn bus_dmamap_load 328which maps mbuf chains 329for DMA transfers. 330Mbuf chains are assumed to be in kernel virtual address space. 331.It Fn bus_dmamap_load_uio "tag" "dmam" "uio" "flags" 332This is a variation of 333.Fn bus_dmamap_load 334which maps buffers pointed to by 335.Fa uio 336for DMA transfers. 337The value of 338.Fa "uio-\*[Gt]uio_segflg" 339will 340determine if the buffers are in user or kernel virtual address space. 341If the buffers are in user address space, the buffers are assumed to be 342in 343.Fa "uio-\*[Gt]uio_procp" Ns 's 344address space. 345.It Fn bus_dmamap_load_raw "tag" "dmam" "segs" "nsegs" "size" "flags" 346This is a variation of 347.Fn bus_dmamap_load 348which maps buffers 349allocated by 350.Fn bus_dmamem_alloc 351(see below). 352The 353.Fa segs 354argument is an array of bus_dma_segment_t's filled in 355by 356.Fn bus_dmamem_alloc . 357The 358.Fa nsegs 359argument is the number of segments in the array. 360The 361.Fa size 362argument is the size of the DMA transfer. 363.It Fn bus_dmamap_unload "tag" "dmam" 364Deletes the mappings for a given DMA handle. 365Arguments are as follows: 366.Bl -tag -width dmam -compact 367.It Fa tag 368This is the bus_dma_tag_t passed down from the parent driver via 369.Fa \*[Lt]bus\*[Gt]_attach_args . 370.It Fa dmam 371The DMA handle containing the mappings which are to be deleted. 372.El 373.Pp 374If the DMA handle was created with 375.Dv BUS_DMA_ALLOCNOW , 376.Fn bus_dmamap_unload 377will not free the corresponding 378resources which were allocated by 379.Fn bus_dmamap_create . 380This is to ensure that 381.Fn bus_dmamap_load 382will never block 383on resources if the handle was created with 384.Dv BUS_DMA_ALLOCNOW . 385.Pp 386.Fn bus_dmamap_unload 387will not perform any implicit synchronization of DMA buffers. 388This must be done explicitly by 389.Fn bus_dmamap_sync . 390.Pp 391.Fn bus_dmamap_unload 392will restore the 393.Fa dm_maxsegsz 394member to its initial value assigned by 395.Fn bus_dmamap_create . 396.Pp 397Behavior is not defined if invalid arguments are passed to 398.Fn bus_dmamap_unload . 399.Pp 400If given valid arguments, 401.Fn bus_dmamap_unload 402always succeeds. 403.It Fn bus_dmamap_sync "tag" "dmam" "offset" "len" "ops" 404Performs pre- and post-DMA operation cache and/or buffer synchronization. 405Arguments are as follows: 406.Bl -tag -width offset -compact 407.It Fa tag 408This is the bus_dma_tag_t passed down from the parent driver via 409.Fa \*[Lt]bus\*[Gt]_attach_args . 410.It Fa dmam 411The DMA mapping to be synchronized. 412.It Fa offset 413The offset into the DMA mapping to synchronize. 414.It Fa len 415The length of the mapping from 416.Fa offset 417to synchronize. 418.It Fa ops 419One or more synchronization operation to perform. 420The following DMA synchronization operations are defined: 421.Bl -tag -width BUS_DMASYNC_POSTWRITE -compact 422.It Dv BUS_DMASYNC_PREREAD 423Perform any pre-read DMA cache and/or bounce operations. 424.It Dv BUS_DMASYNC_POSTREAD 425Perform any post-read DMA cache and/or bounce operations. 426.It Dv BUS_DMASYNC_PREWRITE 427Perform any pre-write DMA cache and/or bounce operations. 428.It Dv BUS_DMASYNC_POSTWRITE 429Perform any post-write DMA cache and/or bounce operations. 430.El 431.Pp 432More than one operation may performed in a given synchronization call. 433Mixing of 434.Em PRE 435and 436.Em POST 437operations is not allowed, and behavior is undefined if this is attempted. 438.El 439.Pp 440Synchronization operations are expressed from the perspective of 441the host RAM, e.g., a 442.Em "device -\*[Gt] memory" 443operation is a 444.Em READ 445and a 446.Em "memory -\*[Gt] device" 447operation is a 448.Em WRITE . 449.Pp 450.Fn bus_dmamap_sync 451may consult state kept within the DMA map to determine if the memory 452is mapped in a DMA coherent fashion. 453If so, 454.Fn bus_dmamap_sync 455may elect to skip certain expensive operations, such as flushing 456of the data cache. 457See 458.Fn bus_dmamem_map 459for more information on this subject. 460.Pp 461On platforms which implement a weak memory access ordering model, 462.Fn bus_dmamap_sync 463will always cause the appropriate memory barriers to be issued. 464.Pp 465This function exists to ensure that the host and the device have 466a consistent view of a range of DMA memory, before and after 467a DMA operation. 468.Pp 469An example of using 470.Fn bus_dmamap_sync , 471involving multiple read-write use of a single mapping 472might look like this: 473.Bd -literal 474bus_dmamap_load(...); 475 476while (not done) { 477 /* invalidate soon-to-be-stale cache blocks */ 478 bus_dmamap_sync(..., BUS_DMASYNC_PREREAD); 479 480 [ do read DMA ] 481 482 /* copy from bounce */ 483 bus_dmamap_sync(..., BUS_DMASYNC_POSTREAD); 484 485 /* read data now in driver-provided buffer */ 486 487 [ computation ] 488 489 /* data to be written now in driver-provided buffer */ 490 491 /* flush write buffers and writeback, copy to bounce */ 492 bus_dmamap_sync(..., BUS_DMASYNC_PREWRITE); 493 494 [ do write DMA ] 495 496 /* probably a no-op, but provided for consistency */ 497 bus_dmamap_sync(..., BUS_DMASYNC_POSTWRITE); 498} 499 500bus_dmamap_unload(...); 501.Ed 502.Pp 503This function 504.Em must 505be called to synchronize DMA buffers before and after a DMA operation. 506Other 507.Nm 508functions can 509.Em not 510be relied on to do this synchronization implicitly. 511If DMA read and write operations are not preceded and followed by the 512appropriate synchronization operations, behavior is undefined. 513.Pp 514Behavior is not defined if invalid arguments are passed to 515.Fn bus_dmamap_sync . 516.Pp 517If given valid arguments, 518.Fn bus_dmamap_sync 519always succeeds. 520.\" XXX: This does not work with all the arguments. 521.It Fn bus_dmamem_alloc "tag" "size" "alignment" "boundary" "segs" "..." 522Allocates memory that is "DMA safe" for the bus corresponding to the 523given tag. 524.Pp 525The mapping of this memory is machine-dependent (or 526"opaque"); machine-independent code is not to assume that the 527addresses returned are valid in kernel virtual address space, or that 528the addresses returned are system physical addresses. 529The address value returned as part of 530.Fa segs 531can thus not be used to program DMA controller address registers. 532Only the values in the 533.Fa dm_segs 534array of a successfully loaded DMA map (using 535.Fn bus_dmamap_load ) 536can be used for this purpose. 537.Pp 538Allocations will always be rounded to the hardware page size. 539Callers may wish to take advantage of this, and cluster allocation of small 540data structures. 541Arguments are as follows: 542.Bl -tag -width alignment -compact 543.It Fa tag 544This is the bus_dma_tag_t passed down from the parent driver via 545.Fa \*[Lt]bus\*[Gt]_attach_args . 546.It Fa size 547The amount of memory to allocate. 548.It Fa alignment 549Each segment in the allocated memory will be aligned to this value. 550If the alignment is less than a hardware page size, it will be rounded up 551to the hardware page size. 552This value must be a power of two. 553.It Fa boundary 554Each segment in the allocated memory must not cross this boundary 555(relative to zero). 556This value must be a power of two. 557A boundary value less than the size of the allocation is invalid. 558.It Fa segs 559An array of bus_dma_segment_t's, filled in as memory is allocated, 560representing the opaque addresses of the memory chunks. 561.It Fa nsegs 562Specifies the number of segments in 563.Fa segs , 564and this is the maximum number 565of segments that the allocated memory may contain. 566.It Fa rsegs 567Used to return the actual number of segments the memory contains. 568.It Fa flags 569Flags are defined as follows: 570.Bl -tag -width BUS_DMA_STREAMING -compact 571.It Dv BUS_DMA_WAITOK 572It is safe to wait (sleep) for resources during this call. 573.It Dv BUS_DMA_NOWAIT 574It is not safe to wait (sleep) for resources during this call. 575.It Dv BUS_DMA_STREAMING 576Adjusts, if necessary, the size, alignment, and boundary constrains 577to conform to the platform-dependent requirements for the use of the 578.Dv BUS_DMA_STREAMING 579flag with the 580.Fn bus_dmamap_load 581function. 582If the platform does not support the 583.Dv BUS_DMA_STREAMING 584feature, or if the size, alignment, and boundary constraints 585would already satisfy the platform's requirements, this flag 586is silently ignored. 587The 588.Dv BUS_DMA_STREAMING 589flag will never relax the constraints specified in the call. 590.It Dv BUS_DMA_BUS[1-4] 591These flags are placeholders, and may be used by busses to provide 592bus-dependent functionality. 593.El 594.El 595.Pp 596All pages allocated by 597.Fn bus_dmamem_alloc 598will be wired down 599until they are freed by 600.Fn bus_dmamem_free . 601.Pp 602Behavior is undefined if invalid arguments are passed to 603.Fn bus_dmamem_alloc . 604.Pp 605Returns 0 on success, or an error code indicating mode of failure. 606.It Fn bus_dmamem_free "tag" "segs" "nsegs" 607Frees memory previously allocated by 608.Fn bus_dmamem_alloc . 609Any mappings 610will be invalidated. 611Arguments are as follows: 612.Bl -tag -width nsegs -compact 613.It Fa tag 614This is the bus_dma_tag_t passed down from the parent driver via 615.Fa \*[Lt]bus\*[Gt]_attach_args . 616.It Fa segs 617The array of bus_dma_segment_t's filled in by 618.Fn bus_dmamem_alloc . 619.It Fa nsegs 620The number of segments in 621.Fa segs . 622.El 623.Pp 624Behavior is undefined if invalid arguments are passed to 625.Fn bus_dmamem_free . 626.Pp 627If given valid arguments, 628.Fn bus_dmamem_free 629always succeeds. 630.It Fn bus_dmamem_map "tag" "segs" "nsegs" "size" "kvap" "flags" 631Maps memory allocated with 632.Fn bus_dmamem_alloc 633into kernel virtual address space. 634Arguments are as follows: 635.Bl -tag -width flags -compact 636.It Fa tag 637This is the bus_dma_tag_t passed down from the parent driver via 638.Fa \*[Lt]bus\*[Gt]_attach_args . 639.It Fa segs 640The array of bus_dma_segment_t's filled in by 641.Fn bus_dmamem_alloc , 642representing the memory regions to map. 643.It Fa nsegs 644The number of segments in 645.Fa segs . 646.It Fa size 647The size of the mapping. 648.It Fa kvap 649Filled in to specify the kernel virtual address where the memory is mapped. 650.It Fa flags 651Flags are defined as follows: 652.Bl -tag -width BUS_DMA_COHERENT -compact 653.It Dv BUS_DMA_WAITOK 654It is safe to wait (sleep) for resources during this call. 655.It Dv BUS_DMA_NOWAIT 656It is not safe to wait (sleep) for resources during this call. 657.It Dv BUS_DMA_BUS[1-4] 658These flags are placeholders, and may be used by busses to provide 659bus-dependent functionality. 660.It Dv BUS_DMA_COHERENT 661This flag is a 662.Em hint 663to machine-dependent code. 664If possible, map the memory in such a way as it will be DMA coherent. 665This may include mapping the pages into uncached address space or 666setting the cache-inhibit bits in page table entries. 667If DMA coherent mappings are impossible, this flag is silently ignored. 668.Pp 669Later, when this memory is loaded into a DMA map, machine-dependent code 670will take whatever steps are necessary to determine if the memory was 671mapped in a DMA coherent fashion. 672This may include checking if the kernel virtual address lies within 673uncached address space or if the cache-inhibit bits are set in page 674table entries. 675If it is determined that the mapping is DMA coherent, state may be 676placed into the DMA map for use by later calls to 677.Fn bus_dmamap_sync . 678.Pp 679Note that a device driver must not rely on 680.Dv BUS_DMA_COHERENT 681for correct operation. 682All calls to 683.Fn bus_dmamap_sync 684must still be made. 685This flag is provided only as an optimization hint to machine-dependent code. 686.Pp 687Also note that this flag only applies to coherency between the CPU 688and memory. 689Coherency between memory and the device is controlled with a different flag. 690See the description of the 691.Fn bus_dmamap_load 692function. 693.It Dv BUS_DMA_NOCACHE 694This flag is a 695.Em hint 696to machine-dependent code. 697If possible, map the uncached memory. 698This flag may be useful in the case that the memory cache causes unexpected 699behavior of the device. 700.El 701.El 702.Pp 703Behavior is undefined if invalid arguments are passed to 704.Fn bus_dmamem_map . 705.Pp 706Returns 0 on success, or an error code indicating mode of failure. 707.It Fn bus_dmamem_unmap "tag" "kva" "size" 708Unmaps memory previously mapped with 709.Fn bus_dmamem_map , 710freeing the 711kernel virtual address space used by the mapping. 712The arguments are as follows: 713.Bl -tag -width size -compact 714.It Fa tag 715This is the bus_dma_tag_t passed down from the parent driver via 716.Fa \*[Lt]bus\*[Gt]_attach_args . 717.It Fa kva 718The kernel virtual address of the mapped memory. 719.It Fa size 720The size of the mapping. 721.El 722.Pp 723Behavior is undefined if invalid arguments are passed to 724.Fn bus_dmamem_unmap . 725.Pp 726If given valid arguments, 727.Fn bus_dmamem_unmap 728always succeeds. 729.It Fn bus_dmamem_mmap "tag" "segs" "nsegs" "off" "prot" "flags" 730Provides support for user 731.Xr mmap 2 Ns 'ing 732of DMA-safe memory. 733This function is to be called by a device driver's (*d_mmap)() entry 734point, which is called by the device pager for each page to be mapped. 735The arguments are as follows: 736.Bl -tag -width nsegs -compact 737.It Fa tag 738This is the bus_dma_tag_t passed down from the parent driver via 739.Fa \*[Lt]bus\*[Gt]_attach_args . 740.It Fa segs 741The array of bus_dma_segment_t's filled in by 742.Fn bus_dmamem_alloc , 743representing the memory to be 744.Xr mmap 2 Ns 'ed . 745.It Fa nsegs 746The number of elements in the 747.Fa segs 748array. 749.It Fa off 750The offset of the page in DMA memory which is to be mapped. 751.It Fa prot 752The protection codes for the mapping. 753.It Fa flags 754Flags are defined as follows: 755.Bl -tag -width BUS_DMA_COHERENT -compact 756.It Dv BUS_DMA_WAITOK 757It is safe to wait (sleep) for resources during this call. 758.It Dv BUS_DMA_NOWAIT 759It is not safe to wait (sleep) for resources during this call. 760.It Dv BUS_DMA_BUS[1-4] 761These flags are placeholders, and may be used by busses to provide 762bus-dependent functionality. 763.It Dv BUS_DMA_COHERENT 764See 765.Fn bus_dmamem_map 766above for a description of this flag. 767.It Dv BUS_DMA_NOCACHE 768See 769.Fn bus_dmamem_map 770above for a description of this flag. 771.El 772.El 773.Pp 774Behavior is undefined if invalid arguments are passed 775to 776.Fn bus_dmamem_mmap . 777.Pp 778Returns -1 to indicate failure. 779Otherwise, returns an opaque value to be interpreted by the device pager. 780.El 781.Sh SEE ALSO 782.Xr bus_space 9 783.Rs 784.%A Jason Thorpe 785.%T "A Machine-Independent DMA Framework for NetBSD" 786.%J "Proceedings of the FREENIX track: 1998 USENIX Annual Technical Conference" 787.%P pp. 1-12 788.%D 1998 789.Re 790.Sh HISTORY 791The 792.Nm 793interface appeared in 794.Nx 1.3 . 795.Sh AUTHORS 796The 797.Nm 798interface was designed and implemented by Jason R. Thorpe of the 799Numerical Aerospace Simulation Facility, NASA Ames Research Center. 800Additional input on the 801.Nm 802design was provided by Chris Demetriou, Charles Hannum, Ross Harvey, 803Matthew Jacob, Jonathan Stone, and Matt Thomas. 804