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