1.\" $NetBSD: bus_dma.9,v 1.22 2002/02/13 08:18:36 ross Exp $ 2.\" 3.\" Copyright (c) 1996, 1997, 1998, 2001 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 February 3, 1998 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.Fd #include \*[Lt]machine/bus.h\*[Gt] 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 proc *p" "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.Pa Aq 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_mapsize; 134 int dm_nsegs; 135 bus_dma_segment_t *dm_segs; 136.Ed 137.sp 138The structure may have machine-dependent members and arbitrary layout. 139The 140.Fa dm_mapsize 141member indicates the size of the mapping. A value of 0 indicates the 142mapping is invalid. 143The 144.Fa dm_segs 145member may be an array of segments or a pointer to an 146array of segments. The 147.Fa dm_nsegs 148member indicates the number of segments in 149.Fa dm_segs . 150.El 151.Sh FUNCTIONS 152.Bl -tag -width compact 153.It Fn bus_dmamap_create "tag" "size" "nsegments" "maxsegsz" "boundary" "flags" "dmamp" 154Allocates a DMA handle and initializes it according to the parameters 155provided. 156Arguments are as follows: 157.Bl -tag -width nsegments -compact 158.It Fa tag 159This is the bus_dma_tag_t passed down from the parent driver via 160.Fa \*[Lt]bus\*[Gt]_attach_args . 161.It Fa size 162This is the maximum DMA transfer that can be mapped by the handle. 163.It Fa nsegments 164Number of segments the device can support in a single DMA transaction. 165This may be the number of scatter-gather descriptors supported by the 166device. 167.It Fa maxsegsz 168The maximum number of bytes that may be transferred by any given DMA 169segment. 170.It Fa boundary 171Some DMA controllers are not able to transfer data that crosses a 172particular boundary. This argument allows this boundary to be 173specified. The boundary lines begin at 0, and occur every 174.Fa boundary 175bytes. Mappings may begin on a boundary line but may not end on or 176cross a boundary line. If no boundary condition needs to be observed, a 177.Fa boundary 178argument of 0 should be used. 179.It Fa flags 180Flags are defined as follows: 181.Bl -tag -width BUS_DMA_ALLOCNOW -compact 182.It Dv BUS_DMA_WAITOK 183It is safe to wait (sleep) for resources during this call. 184.It Dv BUS_DMA_NOWAIT 185It is not safe to wait (sleep) for resources during this call. 186.It Dv BUS_DMA_ALLOCNOW 187Perform any resource allocation this handle may need now. If this is 188not specified, the allocation may be deferred to 189.Fn bus_dmamap_load . 190If this flag is specified, 191.Fn bus_dmamap_load 192will not block on resource 193allocation. 194.It Dv BUS_DMA_BUS[1-4] 195These flags are placeholders, and may be used by busses to provide 196bus-dependent functionality. 197.El 198.It Fa dmamp 199This is a pointer to a bus_dmamap_t. A DMA map will be allocated and 200pointed to by 201.Fa dmamp 202upon successful completion of this routine. 203.El 204.Pp 205Behavior is not defined if invalid arguments are passed to 206.Fn bus_dmamap_create . 207.Pp 208Returns 0 on success, or an error code to indicate mode of failure. 209.It Fn bus_dmamap_destroy "tag" "dmam" 210Frees all resources associated with a given DMA handle. Arguments are 211as follows: 212.Bl -tag -width dmam -compact 213.It Fa tag 214This is the bus_dma_tag_t passed down from the parent driver via 215.Fa \*[Lt]bus\*[Gt]_attach_args . 216.It Fa dmam 217The DMA handle to destroy. 218.El 219.Pp 220In the event that the DMA handle contains a valid mapping, 221the mapping will be unloaded via the same mechanism used by 222.Fn bus_dmamap_unload . 223.Pp 224Behavior is not defined if invalid arguments are passed to 225.Fn bus_dmamap_destroy . 226.Pp 227If given valid arguments, 228.Fn bus_dmamap_destroy 229always succeeds. 230.It Fn bus_dmamap_load "tag" "dmam" "buf" "buflen" "p" "flags" 231Loads a DMA handle with mappings for a DMA transfer. It assumes that 232all pages involved in a DMA transfer are wired. 233Arguments are as follows: 234.Bl -tag -width buflen -compact 235.It Fa tag 236This is the bus_dma_tag_t passed down from the parent driver via 237.Fa \*[Lt]bus\*[Gt]_attach_args . 238.It Fa dmam 239The DMA handle with which to map the transfer. 240.It Fa buf 241The buffer to be used for the DMA transfer. 242.It Fa buflen 243The size of the buffer. 244.It Fa p 245Used to indicate the address space in which the buffer is located. If 246.Dv NULL , 247the buffer is assumed to be in kernel space. Otherwise, the 248buffer is assumed to be in process 249.Fa p Ns 's 250address space. 251.It Fa flags 252are defined as follows: 253.Bl -tag -width "BUS_DMA_STREAMING" -compact 254.It Dv BUS_DMA_WAITOK 255It is safe to wait (sleep) for resources during this call. 256.It Dv BUS_DMA_NOWAIT 257It is not safe to wait (sleep) for resources during this call. 258.It Dv BUS_DMA_STREAMING 259By default, the 260.Nm 261API assumes that there is coherency between memory and the device 262performing the DMA transaction. Some platforms, however, have 263special hardware, such as an 264.Dq I/O cache , 265which may improve performance 266of some types of DMA transactions, but which break the assumption 267that there is coherency between memory and the device performing 268the DMA transaction. 269This flag allows the use of this special hardware, provided that 270the device is doing sequential, unidirectional transfers which 271conform to certain alignment and size constraints defined by the 272platform. If the platform does not support the feature, or if 273the buffer being loaded into the DMA map does not conform to the 274constraints required for use of the feature, then this flag will 275be silently ignored. Also refer to the use of this flag with the 276.Fn bus_dmamem_alloc 277function. 278.It Dv BUS_DMA_READ 279This is a hint to the machine-dependent back-end that indicates the 280mapping will be used only for a 281.Em "device -\*[Gt] memory" 282transaction. The back-end may perform optimizations based on this 283information. 284.It Dv BUS_DMA_WRITE 285This is a hint to the machine-dependent back-end that indicates the 286mapping will be used only for a 287.Em "memory -\*[Gt] device" 288transaction. The back-end may perform optimizations based on this 289information. 290.It Dv BUS_DMA_BUS[1-4] 291These flags are placeholders, and may be used by busses to 292provide bus-dependent functionality. 293.El 294.El 295.Pp 296As noted above, if a DMA handle is created with 297.Dv BUS_DMA_ALLOCNOW , 298.Fn bus_dmamap_load 299will never block. 300.Pp 301If a call to 302.Fn bus_dmamap_load 303fails, the mapping in 304the DMA handle will be invalid. It is the responsibility 305of the caller to clean up any inconsistent device state 306resulting from incomplete iteration through the uio. 307.Pp 308Behavior is not defined if invalid arguments are passed to 309.Fn bus_dmamap_load . 310.Pp 311Returns 0 on success, or an error code to indicate mode of failure. 312.It Fn bus_dmamap_load_mbuf "tag" "dmam" "chain" "flags" 313This is a variation of 314.Fn bus_dmamap_load 315which maps mbuf chains 316for DMA transfers. Mbuf chains are assumed to be in kernel 317virtual address space. 318.It Fn bus_dmamap_load_uio "tag" "dmam" "uio" "flags" 319This is a variation of 320.Fn bus_dmamap_load 321which maps buffers pointed to by 322.Fa uio 323for DMA transfers. The value of 324.Fa "uio-\*[Gt]uio_segflg" 325will 326determine if the buffers are in user or kernel virtual address space. 327If the buffers are in user address space, the buffers are assumed to be 328in 329.Fa "uio-\*[Gt]uio_procp" Ns 's 330address space. 331.It Fn bus_dmamap_load_raw "tag" "dmam" "segs" "nsegs" "size" "flags" 332This is a variation of 333.Fn bus_dmamap_load 334which maps buffers 335allocated by 336.Fn bus_dmamem_alloc 337(see below). The 338.Fa segs 339argument is an array of bus_dma_segment_t's filled in 340by 341.Fn bus_dmamem_alloc . 342The 343.Fa nsegs 344argument is the number of segments in the array. The 345.Fa size 346argument is the size of the DMA transfer. 347.It Fn bus_dmamap_unload "tag" "dmam" 348Deletes the mappings for a given DMA handle. Arguments are as follows: 349.Bl -tag -width dmam -compact 350.It Fa tag 351This is the bus_dma_tag_t passed down from the parent driver via 352.Fa \*[Lt]bus\*[Gt]_attach_args . 353.It Fa dmam 354The DMA handle containing the mappings which are to be deleted. 355.El 356.Pp 357If the DMA handle was created with 358.Dv BUS_DMA_ALLOCNOW , 359.Fn bus_dmamap_unload 360will not free the corresponding 361resources which were allocated by 362.Fn bus_dmamap_create . 363This is to ensure that 364.Fn bus_dmamap_load 365will never block 366on resources if the handle was created with 367.Dv BUS_DMA_ALLOCNOW . 368.Pp 369Behavior is not defined if invalid arguments are passed to 370.Fn bus_dmamap_unload . 371.Pp 372If given valid arguments, 373.Fn bus_dmamap_unload 374always succeeds. 375.It Fn bus_dmamap_sync "tag" "dmam" "offset" "len" "ops" 376Performs pre- and post-DMA operation cache and/or buffer synchronization. 377Arguments are as follows: 378.Bl -tag -width offset -compact 379.It Fa tag 380This is the bus_dma_tag_t passed down from the parent driver via 381.Fa \*[Lt]bus\*[Gt]_attach_args . 382.It Fa dmam 383The DMA mapping to be synchronized. 384.It Fa offset 385The offset into the DMA mapping to synchronize. 386.It Fa len 387The length of the mapping from 388.Fa offset 389to synchronize. 390.It Fa ops 391One or more synchronization operation to perform. The following DMA 392synchronization operations are defined: 393.Bl -tag -width BUS_DMASYNC_POSTWRITE -compact 394.It Dv BUS_DMASYNC_PREREAD 395Perform any pre-read DMA cache and/or bounce operations. 396.It Dv BUS_DMASYNC_POSTREAD 397Perform any post-read DMA cache and/or bounce operations. 398.It Dv BUS_DMASYNC_PREWRITE 399Perform any pre-write DMA cache and/or bounce operations. 400.It Dv BUS_DMASYNC_POSTWRITE 401Perform any post-write DMA cache and/or bounce operations. 402.El 403.Pp 404More than one operation may performed in a given synchronization call. 405Mixing of 406.Em PRE 407and 408.Em POST 409operations is not allowed, and behavior is undefined if this is attempted. 410.El 411.Pp 412Synchronization operations are expressed from the perspective of 413the host RAM, e.g. a 414.Em "device -\*[Gt] memory" 415operation is a 416.Em READ 417and a 418.Em "memory -\*[Gt] device" 419operation is a 420.Em WRITE . 421.Pp 422.Fn bus_dmamap_sync 423may consult state kept within the DMA map to determine if the memory 424is mapped in a DMA coherent fashion. If so, 425.Fn bus_dmamap_sync 426may elect to skip certain expensive operations, such as flushing 427of the data cache. See 428.Fn bus_dmamem_map 429for more information on this subject. 430.Pp 431On platforms which implement reordered stores, 432.Fn bus_dmamap_sync 433will always cause the store buffer to be flushed. 434.Pp 435This function exists so that multiple read and write transfers can be 436performed with the same buffer, and so that drivers can explicitly 437inform the 438.Nm 439code when their data is 'ready' in its DMA buffer. 440.Pp 441An example of multiple read-write use of a single mapping 442might look like: 443.Bd -literal 444bus_dmamap_load(...); 445 446while (not done) { 447 /* invalidate soon-to-be-stale cache blocks */ 448 bus_dmamap_sync(..., BUS_DMASYNC_PREREAD); 449 450 [ do read DMA ] 451 452 /* copy from bounce */ 453 bus_dmamap_sync(..., BUS_DMASYNC_POSTREAD); 454 455 /* read data now in driver-provided buffer */ 456 457 [ computation ] 458 459 /* data to be written now in driver-provided buffer */ 460 461 /* flush write buffers and writeback, copy to bounce */ 462 bus_dmamap_sync(..., BUS_DMASYNC_PREWRITE); 463 464 [ do write DMA ] 465 466 /* probably a no-op, but provided for consistency */ 467 bus_dmamap_sync(..., BUS_DMASYNC_POSTWRITE); 468} 469 470bus_dmamap_unload(...); 471.Ed 472.Pp 473If DMA read and write operations are not preceded and followed by the 474appropriate synchronization operations, behavior is undefined. 475.Pp 476Behavior is not defined if invalid arguments are passed to 477.Fn bus_dmamap_sync . 478.Pp 479If given valid arguments, 480.Fn bus_dmamap_sync 481always succeeds. 482.\" XXX: This does not work with all the arguments. 483.It Fn bus_dmamem_alloc "tag" "size" "alignment" "boundary" "segs" "..." 484Allocates memory that is "DMA safe" for the bus corresponding to the 485given tag. 486.Pp 487The mapping of this memory is machine-dependent (or 488"opaque"); machine-independent code is not to assume that the 489addresses returned are valid in kernel virtual address space, or that 490the addresses returned are system physical addresses. The address value 491returned as part of 492.Fa segs 493can thus not be used to program DMA controller address registers. Only 494the values in the 495.Fa dm_segs 496array of a successfully loaded DMA map (using 497.Fn bus_dmamap_load 498) can be used for this purpose. 499.Pp 500Allocations will always be rounded to the hardware page size. Callers 501may wish to take advantage of this, and cluster allocation of small 502data structures. 503Arguments are as follows: 504.Bl -tag -width alignment -compact 505.It Fa tag 506The is the bus_dma_tag_t passed down from the parent driver via 507.Fa \*[Lt]bus\*[Gt]_attach_args . 508.It Fa size 509The amount of memory to allocate. 510.It Fa alignment 511Each segment in the allocated memory will be aligned to this value. If 512the alignment is less than a hardware page size, it will be rounded up 513to the hardware page size. This value must be a power of two. 514.It Fa boundary 515Each segment in the allocated memory must not cross this boundary 516(relative to zero). This value must be a power of two. A boundary 517value less than the size of the allocation is invalid. 518.It Fa segs 519An array of bus_dma_segment_t's, filled in as memory is allocated, 520representing the opaque addresses of the memory chunks. 521.It Fa nsegs 522Specifies the number of segments in 523.Fa segs , 524and this is the maximum number 525of segments that the allocated memory may contain. 526.It Fa rsegs 527Used to return the actual number of segments the memory contains. 528.It Fa flags 529Flags are defined as follows: 530.Bl -tag -width BUS_DMA_STREAMING -compact 531.It Dv BUS_DMA_WAITOK 532It is safe to wait (sleep) for resources during this call. 533.It Dv BUS_DMA_NOWAIT 534It is not safe to wait (sleep) for resources during this call. 535.It Dv BUS_DMA_STREAMING 536Adjusts, if necessary, the size, alignment, and boundary constrains 537to conform to the platform-dependent requirements for the use of the 538.Dv BUS_DMA_STREAMING 539flag with the 540.Fn bus_dmamap_load 541function. If the platform does not support the 542.Dv BUS_DMA_STREAMING 543feature, or if the size, alignment, and boundary constraints 544would already satisfy the platform's requirements, this flag 545is silently ignored. The 546.Dv BUS_DMA_STREAMING 547flag will never relax the constraints specified in the call. 548.It Dv BUS_DMA_BUS[1-4] 549These flags are placeholders, and may be used by busses to provide 550bus-dependent functionality. 551.El 552.El 553.Pp 554All pages allocated by 555.Fn bus_dmamem_alloc 556will be wired down 557until they are freed by 558.Fn bus_dmamem_free . 559.Pp 560Behavior is undefined if invalid arguments are passed to 561.Fn bus_dmamem_alloc . 562.Pp 563Returns 0 on success, or an error code indicating mode of failure. 564.It Fn bus_dmamem_free "tag" "segs" "nsegs" 565Frees memory previously allocated by 566.Fn bus_dmamem_alloc . 567Any mappings 568will be invalidated. Arguments are as follows: 569.Bl -tag -width nsegs -compact 570.It Fa tag 571This is the bus_dma_tag_t passed down from the parent driver via 572.Fa \*[Lt]bus\*[Gt]_attach_args . 573.It Fa segs 574The array of bus_dma_segment_t's filled in by 575.Fn bus_dmamem_alloc . 576.It Fa nsegs 577The number of segments in 578.Fa segs . 579.El 580.Pp 581Behavior is undefined if invalid arguments are passed to 582.Fn bus_dmamem_free . 583.Pp 584If given valid arguments, 585.Fn bus_dmamem_free 586always succeeds. 587.It Fn bus_dmamem_map "tag" "segs" "nsegs" "size" "kvap" "flags" 588Maps memory allocated with 589.Fn bus_dmamem_alloc 590into kernel virtual address space. Arguments are as follows: 591.Bl -tag -width flags -compact 592.It Fa tag 593This is the bus_dma_tag_t passed down from the parent driver via 594.Fa \*[Lt]bus\*[Gt]_attach_args . 595.It Fa segs 596The array of bus_dma_segment_t's filled in by 597.Fn bus_dmamem_alloc , 598representing the memory regions to map. 599.It Fa nsegs 600The number of segments in 601.Fa segs . 602.It Fa size 603The size of the mapping. 604.It Fa kvap 605Filled in to specify the kernel virtual address where the memory is mapped. 606.It Fa flags 607Flags are defined as follows: 608.Bl -tag -width BUS_DMA_COHERENT -compact 609.It Dv BUS_DMA_WAITOK 610It is safe to wait (sleep) for resources during this call. 611.It Dv BUS_DMA_NOWAIT 612It is not safe to wait (sleep) for resources during this call. 613.It Dv BUS_DMA_BUS[1-4] 614These flags are placeholders, and may be used by busses to provide 615bus-dependent functionality. 616.It Dv BUS_DMA_COHERENT 617This flag is a 618.Em hint 619to machine-dependent code. If possible, map the memory in such a way 620as it will be DMA coherent. This may include mapping the pages into 621uncached address space or setting the cache-inhibit bits in page table 622entries. If DMA coherent mappings are impossible, this flag is 623silently ignored. 624.Pp 625Later, when this memory is loaded into a DMA map, machine-dependent code 626will take whatever steps are necessary to determine if the memory was 627mapped in a DMA coherent fashion. This may include checking if the 628kernel virtual address lies within uncached address space or if the 629cache-inhibit bits are set in page table entries. If it is determined 630that the mapping is DMA coherent, state may be placed into the DMA map 631for use by later calls to 632.Fn bus_dmamap_sync . 633.Pp 634Note that a device driver must not rely on 635.Dv BUS_DMA_COHERENT 636for correct operation. All calls to 637.Fn bus_dmamap_sync 638must still be made. This flag is provided only as an optimization 639hint to machine-dependent code. 640.Pp 641Also note that this flag only applies to coherency between the CPU 642and memory. Coherency between memory and the device is controlled 643with a different flag. See the description of the 644.Fn bus_dmamap_load 645function. 646.El 647.El 648.Pp 649Behavior is undefined if invalid arguments are passed to 650.Fn bus_dmamem_map . 651.Pp 652Returns 0 on success, or an error code indicating mode of failure. 653.It Fn bus_dmamem_unmap "tag" "kva" "size" 654Unmaps memory previously mapped with 655.Fn bus_dmamem_map , 656freeing the 657kernel virtual address space used by the mapping. The arguments are as 658follows: 659.Bl -tag -width size -compact 660.It Fa tag 661This is the bus_dma_tag_t passed down from the parent driver via 662.Fa \*[Lt]bus\*[Gt]_attach_args . 663.It Fa kva 664The kernel virtual address of the mapped memory. 665.It Fa size 666The size of the mapping. 667.El 668.Pp 669Behavior is undefined if invalid arguments are passed to 670.Fn bus_dmamem_unmap . 671.Pp 672If given valid arguments, 673.Fn bus_dmamem_unmap 674always succeeds. 675.It Fn bus_dmamem_mmap "tag" "segs" "nsegs" "off" "prot" "flags" 676Provides support for user 677.Xr mmap 2 Ns 'ing 678of DMA-safe memory. This function is to be called by a device 679driver's (*d_mmap)() entry point, which is called by the 680device pager for each page to be mapped. The arguments are 681as follows: 682.Bl -tag -width nsegs -compact 683.It Fa tag 684This is the bus_dma_tag_t passed down from the parent driver via 685.Fa \*[Lt]bus\*[Gt]_attach_args . 686.It Fa segs 687The array of bus_dma_segment_t's filled in by 688.Fn bus_dmamem_alloc , 689representing the memory to be 690.Xr mmap 2 Ns 'ed . 691.It Fa nsegs 692The number of elements in the 693.Fa segs 694array. 695.It Fa off 696The offset of the page in DMA memory which is to be mapped. 697.It Fa prot 698The protection codes for the mapping. 699.It Fa flags 700Flags are defined as follows: 701.Bl -tag -width BUS_DMA_COHERENT -compact 702.It Dv BUS_DMA_WAITOK 703It is safe to wait (sleep) for resources during this call. 704.It Dv BUS_DMA_NOWAIT 705It is not safe to wait (sleep) for resources during this call. 706.It Dv BUS_DMA_BUS[1-4] 707These flags are placeholders, and may be used by busses to provide 708bus-dependent functionality. 709.It Dv BUS_DMA_COHERENT 710See 711.Fn bus_dmamem_map 712above for a description of this flag. 713.El 714.El 715.Pp 716Behavior is undefined if invalid arguments are passed 717to 718.Fn bus_dmamem_mmap . 719.Pp 720Returns -1 to indicate failure. Otherwise, returns an opaque 721value to be interpreted by the device pager. 722.El 723.Sh SEE ALSO 724.Xr bus_space 9 725.Sh HISTORY 726The 727.Nm 728interface appeared in 729.Nx 1.3 . 730.Sh AUTHORS 731The 732.Nm 733interface was designed and implemented by Jason R. Thorpe of the 734Numerical Aerospace Simulation Facility, NASA Ames Research Center. 735Additional input on the 736.Nm 737design was provided by Chris Demetriou, Charles Hannum, Ross Harvey, 738Matthew Jacob, Jonathan Stone, and Matt Thomas. 739