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