1.\" $NetBSD: bus_dma.9,v 1.82 2025/01/04 17:18:08 riastradh Exp $ 2.\" 3.\" Copyright (c) 1996, 1997, 1998, 2001, 2005, 2006 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.\" 19.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29.\" POSSIBILITY OF SUCH DAMAGE. 30.\" 31.Dd December 29, 2024 32.Dt BUS_DMA 9 33.Os 34.Sh NAME 35.Nm bus_dma , 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_free , 46.Nm bus_dmamem_map , 47.Nm bus_dmamem_unmap , 48.Nm bus_dmamem_mmap , 49.Nm bus_dmatag_subregion , 50.Nm bus_dmatag_destroy 51.Nd Bus and Machine Independent DMA Mapping Interface 52. 53.Sh SYNOPSIS 54. 55.In sys/bus.h 56. 57.Ft int 58.Fo bus_dmamap_create 59.Fa "bus_dma_tag_t tag" 60.Fa "bus_size_t size" 61.Fa "int nsegments" 62.Fa "bus_size_t maxsegsz" 63.Fa "bus_size_t boundary" 64.Fa "int flags" 65.Fa "bus_dmamap_t *dmamp" 66.Fc 67. 68.Ft void 69.Fo bus_dmamap_destroy 70.Fa "bus_dma_tag_t tag" 71.Fa "bus_dmamap_t dmam" 72.Fc 73. 74.Ft int 75.Fo bus_dmamap_load 76.Fa "bus_dma_tag_t tag" 77.Fa "bus_dmamap_t dmam" 78.Fa "void *buf" 79.Fa "bus_size_t buflen" 80.Fa "struct proc *p" 81.Fa "int flags" 82.Fc 83. 84.Ft int 85.Fo bus_dmamap_load_mbuf 86.Fa "bus_dma_tag_t tag" 87.Fa "bus_dmamap_t dmam" 88.Fa "struct mbuf *chain" 89.Fa "int flags" 90.Fc 91. 92.Ft int 93.Fo bus_dmamap_load_uio 94.Fa "bus_dma_tag_t tag" 95.Fa "bus_dmamap_t dmam" 96.Fa "struct uio *uio" 97.Fa "int flags" 98.Fc 99. 100.Ft int 101.Fo bus_dmamap_load_raw 102.Fa "bus_dma_tag_t tag" 103.Fa "bus_dmamap_t dmam" 104.Fa "bus_dma_segment_t *segs" 105.Fa "int nsegs" 106.Fa "bus_size_t size" 107.Fa "int flags" 108.Fc 109. 110.Ft void 111.Fo bus_dmamap_unload 112.Fa "bus_dma_tag_t tag" 113.Fa "bus_dmamap_t dmam" 114.Fc 115. 116.Ft void 117.Fo bus_dmamap_sync 118.Fa "bus_dma_tag_t tag" 119.Fa "bus_dmamap_t dmam" 120.Fa "bus_addr_t offset" 121.Fa "bus_size_t len" 122.Fa "int ops" 123.Fc 124. 125.Ft int 126.Fo bus_dmamem_alloc 127.Fa "bus_dma_tag_t tag" 128.Fa "bus_size_t size" 129.Fa "bus_size_t alignment" 130.Fa "bus_size_t boundary" 131.Fa "bus_dma_segment_t *segs" 132.Fa "int nsegs" 133.Fa "int *rsegs" 134.Fa "int flags" 135.Fc 136. 137.Ft void 138.Fo bus_dmamem_free 139.Fa "bus_dma_tag_t tag" 140.Fa "bus_dma_segment_t *segs" 141.Fa "int nsegs" 142.Fc 143. 144.Ft int 145.Fo bus_dmamem_map 146.Fa "bus_dma_tag_t tag" 147.Fa "bus_dma_segment_t *segs" 148.Fa "int nsegs" 149.Fa "size_t size" 150.Fa "void **kvap" 151.Fa "int flags" 152.Fc 153. 154.Ft void 155.Fo bus_dmamem_unmap 156.Fa "bus_dma_tag_t tag" 157.Fa "void *kva" 158.Fa "size_t size" 159.Fc 160. 161.Ft paddr_t 162.Fo bus_dmamem_mmap 163.Fa "bus_dma_tag_t tag" 164.Fa "bus_dma_segment_t *segs" 165.Fa "int nsegs" 166.Fa "off_t off" 167.Fa "int prot" 168.Fa "int flags" 169.Fc 170. 171.Ft int 172.Fo bus_dmatag_subregion 173.Fa "bus_dma_tag_t tag" 174.Fa "bus_addr_t min_addr" 175.Fa "bus_addr_t max_addr" 176.Fa "bus_dma_tag_t *newtag" 177.Fa "int flags" 178.Fc 179. 180.Ft void 181.Fo bus_dmatag_destroy 182.Fa "bus_dma_tag_t tag" 183.Fc 184. 185.Sh DESCRIPTION 186Provide a bus- and machine-independent 187.Dq Tn DMA No mapping interface . 188. 189.Ss Implementation Notes 190All data types and constants will be defined 191by the port-specific header 192.In machine/bus_defs.h . 193All functions will be defined 194by the port-specific header 195.In machine/bus_funcs.h . 196Note that this document 197assumes the existence of types already defined by the current 198.Xr bus_space 9 199interface. 200.Pp 201Unless otherwise noted, all function calls in this interface may be 202defined as 203.Xr cpp 1 204macros. 205.Ss Data Types 206Individual implementations may name these structures whatever they 207wish, providing that the external representations are: 208.Bl -tag -width Vt 209.It Vt bus_dma_tag_t 210A machine-dependent opaque type describing the implementation of 211DMA for a given bus. 212.It Vt bus_dma_segment_t 213A structure with at least the following members: 214.Bd -literal -offset indent 215bus_addr_t ds_addr; 216bus_size_t ds_len; 217.Ed 218.Pp 219The structure may have machine-dependent members and arbitrary layout. 220The values in 221.Fa ds_addr 222and 223.Fa ds_len 224are suitable for programming into 225DMA controller address and length registers. 226.It Vt bus_dmamap_t 227A pointer to a structure with at least the following members: 228.Bd -literal -offset indent 229bus_size_t dm_maxsegsz; 230bus_size_t dm_mapsize; 231int dm_nsegs; 232bus_dma_segment_t *dm_segs; 233.Ed 234.Pp 235The structure may have machine-dependent members and arbitrary layout. 236The 237.Fa dm_maxsegsz 238member indicates the maximum number of bytes that may be transferred by 239any given DMA segment. 240The 241.Fa dm_mapsize 242member indicates the size of the mapping. 243A value of 0 indicates the mapping is invalid. 244The 245.Fa dm_segs 246member may be an array of segments or a pointer to an 247array of segments. 248The 249.Fa dm_nsegs 250member indicates the number of segments in 251.Fa dm_segs . 252.El 253. 254.Ss Functions 255.Bl -tag -width Ds \" Fn 256.It Fn bus_dmamap_create "tag" "size" "nsegments" "maxsegsz" "boundary" "flags" "dmamp" 257Allocates a DMA handle and initializes it according to the parameters 258provided. 259.Bl -tag -width Ds \" Fa 260.It Fa tag 261This is the 262.Vt bus_dma_tag_t 263passed down from the parent driver via 264.Fa <bus>_attach_args . 265.It Fa size 266This is the maximum DMA transfer that can be mapped by the handle. 267.It Fa nsegments 268Number of segments the device can support in a single DMA transaction. 269This may be the number of scatter-gather descriptors supported by the 270device. 271.It Fa maxsegsz 272The maximum number of bytes that may be transferred by any given DMA 273segment and will be assigned to the 274.Fa dm_maxsegsz 275member. 276.It Fa boundary 277Some DMA controllers are not able to transfer data that crosses a 278particular boundary. 279This argument allows this boundary to be specified. 280The boundary lines begin at 0, and occur every 281.Fa boundary 282bytes. 283Mappings may begin on a boundary line but may not end on or 284cross a boundary line. 285If no boundary condition needs to be observed, a 286.Fa boundary 287argument of 0 should be used. 288.It Fa flags 289.Bl -tag -width Ds \" Dv 290.It Dv BUS_DMA_WAITOK 291It is safe to wait (sleep) for resources during this call. 292.It Dv BUS_DMA_NOWAIT 293It is not safe to wait (sleep) for resources during this call. 294.It Dv BUS_DMA_ALLOCNOW 295Perform any resource allocation this handle may need now. 296If this is not specified, the allocation may be deferred to 297.Fn bus_dmamap_load . 298If this flag is specified, 299.Fn bus_dmamap_load 300will not block on resource 301allocation. 302.It Dv BUS_DMA_BUS[1-4] 303These flags are placeholders, and may be used by busses to provide 304bus-dependent functionality. 305.El 306.It Fa dmamp 307This is a pointer to a 308.Vt bus_dmamap_t . 309A DMA map will be allocated and pointed to by 310.Fa dmamp 311upon successful completion of this routine. 312.Fa dmamp 313is undefined if this routine fails. 314.El 315.Pp 316Behavior is not defined if invalid arguments are passed to 317.Fn bus_dmamap_create . 318.Pp 319Returns 0 on success, or an error code to indicate mode of failure. 320.It Fn bus_dmamap_destroy "tag" "dmam" 321Frees all resources associated with a given DMA handle. 322.Bl -tag -width Ds \" Fa 323.It Fa tag 324This is the 325.Vt bus_dma_tag_t 326passed down from the parent driver via 327.Fa <bus>_attach_args . 328.It Fa dmam 329The DMA handle to destroy. 330.El 331.Pp 332In the event that the DMA handle contains a valid mapping, 333the mapping will be unloaded via the same mechanism used by 334.Fn bus_dmamap_unload . 335.Pp 336Behavior is not defined if invalid arguments are passed to 337.Fn bus_dmamap_destroy . 338.Pp 339If given valid arguments, 340.Fn bus_dmamap_destroy 341always succeeds. 342.It Fn bus_dmamap_load "tag" "dmam" "buf" "buflen" "p" "flags" 343Loads a DMA handle with mappings for a DMA transfer. 344It assumes that all pages involved in a DMA transfer are wired. 345.Bl -tag -width Ds \" Fa 346.It Fa tag 347This is the 348.Vt bus_dma_tag_t 349passed down from the parent driver via 350.Fa <bus>_attach_args . 351.It Fa dmam 352The DMA handle with which to map the transfer. 353.It Fa buf 354The buffer to be used for the DMA transfer. 355.It Fa buflen 356The size of the buffer. 357.It Fa p 358Used to indicate the address space in which the buffer is located. 359If 360.Dv NULL , 361the buffer is assumed to be in kernel space. 362Otherwise, the buffer is assumed to be in proc 363.Fa p Ap s 364address space. 365.It Fa flags 366.Bl -tag -width Ds \" Dv 367.It Dv BUS_DMA_WAITOK 368It is safe to wait (sleep) for resources during this call. 369.It Dv BUS_DMA_NOWAIT 370It is not safe to wait (sleep) for resources during this call. 371.It Dv BUS_DMA_STREAMING 372By default, the 373.Nm 374API assumes that there is coherency between memory and the device 375performing the DMA transaction. 376Some platforms, however, have special hardware, such as an 377.Dq I/O cache , 378which may improve performance 379of some types of DMA transactions, but which break the assumption 380that there is coherency between memory and the device performing 381the DMA transaction. 382This flag allows the use of this special hardware, provided that 383the device is doing sequential, unidirectional transfers which 384conform to certain alignment and size constraints defined by the 385platform. 386If the platform does not support the feature, or if the buffer being 387loaded into the DMA map does not conform to the constraints required 388for use of the feature, then this flag will be silently ignored. 389Also refer to the use of this flag with the 390.Fn bus_dmamem_alloc 391function. 392.It Dv BUS_DMA_READ 393This is a hint to the machine-dependent back-end that indicates the 394mapping will be used only for a 395.Em device No \(-> Em memory 396transaction. 397The back-end may perform optimizations based on this information. 398.It Dv BUS_DMA_WRITE 399This is a hint to the machine-dependent back-end that indicates the 400mapping will be used only for a 401.Em memory No \(-> Em device 402transaction. 403The back-end may perform optimizations based on this information. 404.It Dv BUS_DMA_BUS[1-4] 405These flags are placeholders, and may be used by busses to 406provide bus-dependent functionality. 407.El 408.El 409.Pp 410As noted above, if a DMA handle is created with 411.Dv BUS_DMA_ALLOCNOW , 412.Fn bus_dmamap_load 413will never block. 414.Pp 415If a call to 416.Fn bus_dmamap_load 417fails, the mapping in 418the DMA handle will be invalid. 419It is the responsibility of the caller to clean up any inconsistent 420device state resulting from incomplete iteration through the uio. 421.Pp 422Behavior is not defined if invalid arguments are passed to 423.Fn bus_dmamap_load . 424.Pp 425Returns 0 on success, or an error code to indicate mode of failure. 426Possible error codes include the following: 427.Pp 428.Bl -tag -width Er 429.It Er EFBIG 430Too many segments. 431.It Er EINVAL 432.Fa buflen 433is too large for the DMA map. 434.It Er ENOMEM 435Could not allocate memory for, e.g., a bounce buffer. 436.El 437.It Fn bus_dmamap_load_mbuf "tag" "dmam" "chain" "flags" 438This is a variation of 439.Fn bus_dmamap_load 440which maps mbuf chains 441for DMA transfers. 442Mbuf chains are assumed to be in kernel virtual address space. 443.It Fn bus_dmamap_load_uio "tag" "dmam" "uio" "flags" 444This is a variation of 445.Fn bus_dmamap_load 446which maps buffers pointed to by 447.Fa uio 448for DMA transfers. 449Determination if the buffers are in user or kernel virtual address space 450is done internally, according to 451.Fa uio\^ Ns Li -> Ns Fa uio_vmspace . 452See 453.Xr uiomove 9 454for details of the 455.Dv uio 456structure. 457.It Fn bus_dmamap_load_raw "tag" "dmam" "segs" "nsegs" "size" "flags" 458This is a variation of 459.Fn bus_dmamap_load 460which maps buffers 461allocated by 462.Fn bus_dmamem_alloc 463(see below). 464The 465.Fa segs 466argument is an array of bus_dma_segment_t's filled in 467by 468.Fn bus_dmamem_alloc . 469The 470.Fa nsegs 471argument is the number of segments in the array. 472The 473.Fa size 474argument is the size of the DMA transfer. 475.It Fn bus_dmamap_unload "tag" "dmam" 476Deletes the mappings for a given DMA handle. 477.Bl -tag -width Ds \" Fa 478.It Fa tag 479This is the 480.Vt bus_dma_tag_t 481passed down from the parent driver via 482.Fa <bus>_attach_args . 483.It Fa dmam 484The DMA handle containing the mappings which are to be deleted. 485.El 486.Pp 487If the DMA handle was created with 488.Dv BUS_DMA_ALLOCNOW , 489.Fn bus_dmamap_unload 490will not free the corresponding 491resources which were allocated by 492.Fn bus_dmamap_create . 493This is to ensure that 494.Fn bus_dmamap_load 495will never block 496on resources if the handle was created with 497.Dv BUS_DMA_ALLOCNOW . 498.Pp 499.Fn bus_dmamap_unload 500will not perform any implicit synchronization of DMA buffers. 501This must be done explicitly by 502.Fn bus_dmamap_sync . 503.Pp 504.Fn bus_dmamap_unload 505will restore the 506.Fa dm_maxsegsz 507member to its initial value assigned by 508.Fn bus_dmamap_create . 509.Pp 510Behavior is not defined if invalid arguments are passed to 511.Fn bus_dmamap_unload . 512.Pp 513If given valid arguments, 514.Fn bus_dmamap_unload 515always succeeds. 516.It Fn bus_dmamap_sync "tag" "dmam" "offset" "len" "ops" 517Performs pre- and post-DMA operation cache and/or buffer synchronization. 518.Bl -tag -width Ds \" Fa 519.It Fa tag 520This is the 521.Vt bus_dma_tag_t 522passed down from the parent driver via 523.Fa <bus>_attach_args . 524.It Fa dmam 525The DMA mapping to be synchronized. 526.It Fa offset 527The offset into the DMA mapping to synchronize. 528.It Fa len 529The length of the mapping from 530.Fa offset 531to synchronize. 532.It Fa ops 533One or more synchronization operations to perform. 534The following DMA synchronization operations are defined: 535.Bl -tag -width Ds \" Dv 536.It Dv BUS_DMASYNC_PREREAD 537Perform any synchronization required prior to an update of host memory by the 538device. 539.It Dv BUS_DMASYNC_POSTREAD 540Perform any synchronization required after an update of host memory by the 541device and prior to CPU access to host memory. 542.It Dv BUS_DMASYNC_PREWRITE 543Perform any synchronization required after an update of host memory by the CPU 544and prior to device access to host memory. 545.It Dv BUS_DMASYNC_POSTWRITE 546Perform any synchronization required after device access to host memory. 547.El 548.Pp 549where each operation may involve cache flush/invalidation, bounce buffer 550copying, and/or memory barriers. 551.Pp 552More than one operation may be performed in a given synchronization call. 553Mixing of 554.Dv PRE 555and 556.Dv POST 557operations is not allowed, and behavior is undefined if this is attempted. 558.Pp 559Synchronization operations are expressed from the perspective of 560the host RAM, i.e., a 561.Em device No \(-> Em memory 562operation is a 563.Dv READ , 564and a 565.Em memory No \(-> Em device 566operation is a 567.Dv WRITE . 568.El 569.Pp 570.Fn bus_dmamap_sync 571may consult state kept within the DMA map to determine if the memory 572is mapped in a DMA coherent fashion. 573If so, 574.Fn bus_dmamap_sync 575may elect to skip certain expensive operations, such as flushing 576of the data cache. 577See 578.Fn bus_dmamem_map 579for more information on this subject. 580.Pp 581On platforms which implement a weak memory access ordering model, 582.Fn bus_dmamap_sync 583will always cause the appropriate memory barriers to be issued. 584.Pp 585This function exists to ensure that the host and the device have 586a consistent view of a range of DMA memory, before and after 587a DMA operation. 588.Pp 589An example of using 590.Fn bus_dmamap_sync , 591involving multiple read-write use of a single mapping 592might look like this: 593.Bd -literal 594bus_dmamap_load(...); 595 596while (not done) { 597 /* invalidate soon-to-be-stale cache blocks */ 598 bus_dmamap_sync(..., BUS_DMASYNC_PREREAD); 599 600 [ do read DMA ] 601 602 /* copy from bounce */ 603 bus_dmamap_sync(..., BUS_DMASYNC_POSTREAD); 604 605 /* read data now in driver-provided buffer */ 606 607 [ computation ] 608 609 /* data to be written now in driver-provided buffer */ 610 611 /* flush write buffers and writeback, copy to bounce */ 612 bus_dmamap_sync(..., BUS_DMASYNC_PREWRITE); 613 614 [ do write DMA ] 615 616 /* probably a no-op, but provided for consistency */ 617 bus_dmamap_sync(..., BUS_DMASYNC_POSTWRITE); 618} 619 620bus_dmamap_unload(...); 621.Ed 622.Pp 623This function 624.Em must 625be called to synchronize DMA buffers before and after a DMA operation. 626Other 627.Nm 628functions can 629.Em not 630be relied on to do this synchronization implicitly. 631If DMA read and write operations are not preceded and followed by the 632appropriate synchronization operations, behavior is undefined. 633.Pp 634Behavior is not defined if invalid arguments are passed to 635.Fn bus_dmamap_sync . 636.Pp 637If given valid arguments, 638.Fn bus_dmamap_sync 639always succeeds. 640.It Fn bus_dmamem_alloc "tag" "size" "alignment" "boundary" "segs" "nsegs" "rsegs" "flags" 641Allocates memory that is 642.Dq DMA safe 643for the bus corresponding to the 644given tag. 645.Pp 646The mapping of this memory is machine-dependent 647.Pq or Dq opaque ; 648machine-independent code must not assume that the 649addresses returned are valid in kernel virtual address space, or that 650the addresses returned are system physical addresses. 651The address value returned as part of 652.Fa segs 653can thus not be used to program DMA controller address registers. 654Only the values in the 655.Fa dm_segs 656array of a successfully loaded DMA map 657.Pq using Fn bus_dmamap_load 658can be used for this purpose. 659.Pp 660Allocations will always be rounded to the hardware page size. 661Callers may wish to take advantage of this, and cluster allocation of small 662data structures. 663.Bl -tag -width Ds \" Fa 664.It Fa tag 665This is the 666.Vt bus_dma_tag_t 667passed down from the parent driver via 668.Fa <bus>_attach_args . 669.It Fa size 670The amount of memory to allocate. 671.It Fa alignment 672Each segment in the allocated memory will be aligned to this value. 673If the alignment is less than a hardware page size, it will be rounded up 674to the hardware page size. 675This value must be a power of two. 676.It Fa boundary 677Each segment in the allocated memory must not cross this boundary 678(relative to zero). 679This value must be a power of two. 680A boundary value less than the size of the allocation is invalid. 681If no boundary condition needs to be observed, a 682.Fa boundary 683argument of 0 should be used. 684.It Fa segs 685An array of bus_dma_segment_t's, filled in as memory is allocated, 686representing the opaque addresses of the memory chunks. 687.It Fa nsegs 688Specifies the number of segments in 689.Fa segs , 690and this is the maximum number 691of segments that the allocated memory may contain. 692.It Fa rsegs 693Used to return the actual number of segments the memory contains. 694.It Fa flags 695.Bl -tag -width Ds \" Dv 696.It Dv BUS_DMA_WAITOK 697It is safe to wait (sleep) for resources during this call. 698.It Dv BUS_DMA_NOWAIT 699It is not safe to wait (sleep) for resources during this call. 700.It Dv BUS_DMA_STREAMING 701Adjusts, if necessary, the size, alignment, and boundary constraints 702to conform to the platform-dependent requirements for the use of the 703.Dv BUS_DMA_STREAMING 704flag with the 705.Fn bus_dmamap_load 706function. 707If the platform does not support the 708.Dv BUS_DMA_STREAMING 709feature, or if the size, alignment, and boundary constraints 710would already satisfy the platform's requirements, this flag 711is silently ignored. 712The 713.Dv BUS_DMA_STREAMING 714flag will never relax the constraints specified in the call. 715.It Dv BUS_DMA_BUS[1-4] 716These flags are placeholders, and may be used by busses to provide 717bus-dependent functionality. 718.El 719.El 720.Pp 721All pages allocated by 722.Fn bus_dmamem_alloc 723will be wired down 724until they are freed by 725.Fn bus_dmamem_free . 726.Pp 727Behavior is undefined if invalid arguments are passed to 728.Fn bus_dmamem_alloc . 729.Pp 730Returns 0 on success, or an error code indicating mode of failure. 731.It Fn bus_dmamem_free "tag" "segs" "nsegs" 732Frees memory previously allocated by 733.Fn bus_dmamem_alloc . 734Any mappings 735will be invalidated. 736.Bl -tag -width Ds \" Fa 737.It Fa tag 738This is the 739.Vt bus_dma_tag_t 740passed down from the parent driver via 741.Fa <bus>_attach_args . 742.It Fa segs 743The array of bus_dma_segment_t's filled in by 744.Fn bus_dmamem_alloc . 745.It Fa nsegs 746The number of segments in 747.Fa segs . 748.El 749.Pp 750Behavior is undefined if invalid arguments are passed to 751.Fn bus_dmamem_free . 752.Pp 753If given valid arguments, 754.Fn bus_dmamem_free 755always succeeds. 756.It Fn bus_dmamem_map "tag" "segs" "nsegs" "size" "kvap" "flags" 757Maps memory allocated with 758.Fn bus_dmamem_alloc 759into kernel virtual address space. 760.Bl -tag -width Ds \" Fa 761.It Fa tag 762This is the 763.Vt bus_dma_tag_t 764passed down from the parent driver via 765.Fa <bus>_attach_args . 766.It Fa segs 767The array of bus_dma_segment_t's filled in by 768.Fn bus_dmamem_alloc , 769representing the memory regions to map. 770.It Fa nsegs 771The number of segments in 772.Fa segs . 773.It Fa size 774The size of the mapping. 775.It Fa kvap 776Filled in to specify the kernel virtual address where the memory is mapped. 777.It Fa flags 778.Bl -tag -width Ds \" Dv 779.It Dv BUS_DMA_WAITOK 780It is safe to wait (sleep) for resources during this call. 781.It Dv BUS_DMA_NOWAIT 782It is not safe to wait (sleep) for resources during this call. 783.It Dv BUS_DMA_BUS[1-4] 784These flags are placeholders, and may be used by busses to provide 785bus-dependent functionality. 786.It Dv BUS_DMA_COHERENT 787This flag is a 788.Em hint 789to machine-dependent code. 790If possible, map the memory in such a way as it will be DMA coherent. 791This may include mapping the pages into uncached address space or 792setting the cache-inhibit bits in page table entries. 793If DMA coherent mappings are impossible, this flag is silently ignored. 794.Pp 795Later, when this memory is loaded into a DMA map, machine-dependent code 796will take whatever steps are necessary to determine if the memory was 797mapped in a DMA coherent fashion. 798This may include checking if the kernel virtual address lies within 799uncached address space or if the cache-inhibit bits are set in page 800table entries. 801If it is determined that the mapping is DMA coherent, state may be 802placed into the DMA map for use by later calls to 803.Fn bus_dmamap_sync . 804.Pp 805Note that a device driver must not rely on 806.Dv BUS_DMA_COHERENT 807for correct operation. 808All calls to 809.Fn bus_dmamap_sync 810must still be made. 811This flag is provided only as an optimization hint to machine-dependent code. 812.Pp 813Also note that this flag only applies to coherency between the CPU 814and memory. 815Coherency between memory and the device is controlled with a different flag. 816See the description of the 817.Fn bus_dmamap_load 818function. 819.It Dv BUS_DMA_NOCACHE 820This flag is a 821.Em hint 822to machine-dependent code. 823If possible, map the memory uncached. 824This flag may be useful in the case that the memory cache causes unexpected 825behavior of the device. 826.Pp 827Exclusive with 828.Dv BUS_DMA_PREFETCHABLE . 829.It Dv BUS_DMA_PREFETCHABLE 830This flag is a 831.Em hint 832to machine-dependent code. 833If possible, map the memory prefetchable/write-combining. 834.Pp 835Exclusive with 836.Dv BUS_DMA_NOCACHE . 837.El 838.El 839.Pp 840Behavior is undefined if invalid arguments are passed to 841.Fn bus_dmamem_map . 842.Pp 843Returns 0 on success, or an error code indicating mode of failure. 844.It Fn bus_dmamem_unmap "tag" "kva" "size" 845Unmaps memory previously mapped with 846.Fn bus_dmamem_map , 847freeing the 848kernel virtual address space used by the mapping. 849.Bl -tag -width Ds \" Fa 850.It Fa tag 851This is the 852.Vt bus_dma_tag_t 853passed down from the parent driver via 854.Fa <bus>_attach_args . 855.It Fa kva 856The kernel virtual address of the mapped memory. 857.It Fa size 858The size of the mapping. 859.El 860.Pp 861Behavior is undefined if invalid arguments are passed to 862.Fn bus_dmamem_unmap . 863.Pp 864If given valid arguments, 865.Fn bus_dmamem_unmap 866always succeeds. 867.It Fn bus_dmamem_mmap "tag" "segs" "nsegs" "off" "prot" "flags" 868Provides support for user 869.Xr mmap 2 Ap ing 870of DMA-safe memory. 871This function is to be called by a device driver's 872.Li (* Ns Fa d_mmap Ns Li )() 873entry 874point, which is called by the device pager for each page to be mapped. 875.Bl -tag -width Ds \" Fa 876.It Fa tag 877This is the 878.Vt bus_dma_tag_t 879passed down from the parent driver via 880.Fa <bus>_attach_args . 881.It Fa segs 882The array of bus_dma_segment_t's filled in by 883.Fn bus_dmamem_alloc , 884representing the memory to be 885.Xr mmap 2 Ap ed . 886.It Fa nsegs 887The number of elements in the 888.Fa segs 889array. 890.It Fa off 891The offset of the page in DMA memory which is to be mapped. 892.It Fa prot 893The protection codes for the mapping. 894.It Fa flags 895.Bl -tag -width Ds \" Dv 896.It Dv BUS_DMA_WAITOK 897It is safe to wait (sleep) for resources during this call. 898.It Dv BUS_DMA_NOWAIT 899It is not safe to wait (sleep) for resources during this call. 900.It Dv BUS_DMA_BUS[1-4] 901These flags are placeholders, and may be used by busses to provide 902bus-dependent functionality. 903.It Dv BUS_DMA_COHERENT 904See 905.Fn bus_dmamem_map 906above for a description of this flag. 907.It Dv BUS_DMA_NOCACHE 908See 909.Fn bus_dmamem_map 910above for a description of this flag. 911.El 912.El 913.Pp 914Behavior is undefined if invalid arguments are passed 915to 916.Fn bus_dmamem_mmap . 917.Pp 918Returns \-1 to indicate failure. 919Otherwise, returns an opaque value to be interpreted by the device pager. 920.It Fn bus_dmatag_subregion "tag" "min_addr" "max_addr" "newtag" "flags" 921Given a 922.Vt bus_dma_tag_t 923create a new 924.Vt bus_dma_tag_t 925with a limited bus address space. 926This function should not normally be used, but is useful for devices 927that do not support the full address space of the parent bus. 928Not all ports implement this method; on ports where it is unavailable, 929.Er EOPNOTSUPP 930is returned. 931.Bl -tag -width Ds \" Fa 932.It Fa tag 933This is the 934.Vt bus_dma_tag_t 935to subregion. 936.It Fa min_addr 937The smallest address this new tag can address. 938.It Fa max_addr 939The largest address this new tag can address. 940.It Fa newtag 941Pointer filled in with the address of the new 942.Vt bus_dma_tag_t . 943.It Fa flags 944.Bl -tag -width Ds \" Dv 945.It Dv BUS_DMA_WAITOK 946It is safe to wait (sleep) for resources during this call. 947.It Dv BUS_DMA_NOWAIT 948It is not safe to wait (sleep) for resources during this call. 949.El 950.El 951.Pp 952The address range 953.Fa min_addr 954to 955.Fa max_addr 956is inclusive of both addresses. 957.It Fn bus_dmatag_destroy "tag" 958Free a tag created by 959.Fn bus_dmatag_subregion . 960.El 961.Sh SEE ALSO 962.Xr membar_ops 3 , 963.Xr bus_space 9 964.Rs 965.%A Jason Thorpe 966.%T "A Machine-Independent DMA Framework for NetBSD" 967.%I USENIX Association 968.%B Proceedings of the FREENIX Track: 1998 USENIX Annual Technical Conference 969.%P 1-12 970.%D June 15-19, 1998 971.%U http://www.usenix.org/publications/library/proceedings/usenix98/freenix/thorpe_dma.pdf 972.Re 973.Sh HISTORY 974The 975.Nm 976interface appeared in 977.Nx 1.3 . 978.Sh AUTHORS 979.An -nosplit 980The 981.Nm 982interface was designed and implemented by 983.An Jason R. Thorpe 984of the 985Numerical Aerospace Simulation Facility, NASA Ames Research Center. 986Additional input on the 987.Nm 988design was provided by 989.An Chris Demetriou , 990.An Charles Hannum , 991.An Ross Harvey , 992.An Matthew Jacob , 993.An Jonathan Stone , 994and 995.An Matt Thomas . 996