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