1.\" Copyright (c) 2002, 2003 Hiten M. Pandya. 2.\" All rights reserved. 3.\" 4.\" Redistribution and use in source and binary forms, with or without 5.\" modification, are permitted provided that the following conditions 6.\" are met: 7.\" 1. Redistributions of source code must retain the above copyright 8.\" notice, this list of conditions, and the following disclaimer, 9.\" without modification, immediately at the beginning of the file. 10.\" 2. The name of the author may not be used to endorse or promote products 11.\" derived from this software without specific prior written permission. 12.\" 13.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 14.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR, CONTRIBUTORS OR THE 17.\" VOICES IN HITEN PANDYA'S HEAD BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 18.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 19.\" TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20.\" PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 21.\" LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 22.\" NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 23.\" SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24.\" 25.\" Copyright (c) 1996, 1997, 1998, 2001 The NetBSD Foundation, Inc. 26.\" All rights reserved. 27.\" 28.\" This code is derived from software contributed to The NetBSD Foundation 29.\" by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 30.\" NASA Ames Research Center. 31.\" 32.\" Redistribution and use in source and binary forms, with or without 33.\" modification, are permitted provided that the following conditions 34.\" are met: 35.\" 1. Redistributions of source code must retain the above copyright 36.\" notice, this list of conditions and the following disclaimer. 37.\" 2. Redistributions in binary form must reproduce the above copyright 38.\" notice, this list of conditions and the following disclaimer in the 39.\" documentation and/or other materials provided with the distribution. 40.\" 41.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 42.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 43.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 44.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 45.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 46.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 47.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 48.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 49.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 50.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 51.\" POSSIBILITY OF SUCH DAMAGE. 52.\" 53.\" $FreeBSD$ 54.\" $NetBSD: bus_dma.9,v 1.25 2002/10/14 13:43:16 wiz Exp $ 55.\" 56.Dd May 25, 2020 57.Dt BUS_DMA 9 58.Os 59.Sh NAME 60.Nm bus_dma , 61.Nm bus_dma_tag_create , 62.Nm bus_dma_tag_destroy , 63.Nm bus_dma_template_init , 64.Nm bus_dma_template_tag , 65.Nm bus_dma_template_clone , 66.Nm bus_dmamap_create , 67.Nm bus_dmamap_destroy , 68.Nm bus_dmamap_load , 69.Nm bus_dmamap_load_bio , 70.Nm bus_dmamap_load_ccb , 71.Nm bus_dmamap_load_crp , 72.Nm bus_dmamap_load_crp_buffer , 73.Nm bus_dmamap_load_mbuf , 74.Nm bus_dmamap_load_mbuf_sg , 75.Nm bus_dmamap_load_uio , 76.Nm bus_dmamap_unload , 77.Nm bus_dmamap_sync , 78.Nm bus_dmamem_alloc , 79.Nm bus_dmamem_free 80.Nd Bus and Machine Independent DMA Mapping Interface 81.Sh SYNOPSIS 82.In machine/bus.h 83.Ft int 84.Fn bus_dma_tag_create "bus_dma_tag_t parent" "bus_size_t alignment" \ 85"bus_addr_t boundary" "bus_addr_t lowaddr" "bus_addr_t highaddr" \ 86"bus_dma_filter_t *filtfunc" "void *filtfuncarg" "bus_size_t maxsize" \ 87"int nsegments" "bus_size_t maxsegsz" "int flags" "bus_dma_lock_t *lockfunc" \ 88"void *lockfuncarg" "bus_dma_tag_t *dmat" 89.Ft int 90.Fn bus_dma_tag_destroy "bus_dma_tag_t dmat" 91.Ft void 92.Fo bus_dma_template_init 93.Fa "bus_dma_template_t template" 94.Fa "bus_dma_tag_t parent" 95.Fc 96.Ft int 97.Fo bus_dma_template_tag 98.Fa "bus_dma_template_t template" 99.Fa "bus_dma_tag_t *dmat" 100.Fc 101.Ft void 102.Fo bus_dma_template_clone 103.Fa "bus_dma_template_t template" 104.Fa "bus_dma_tag_t dmat" 105.Fc 106.Ft int 107.Fn bus_dmamap_create "bus_dma_tag_t dmat" "int flags" "bus_dmamap_t *mapp" 108.Ft int 109.Fn bus_dmamap_destroy "bus_dma_tag_t dmat" "bus_dmamap_t map" 110.Ft int 111.Fn bus_dmamap_load "bus_dma_tag_t dmat" "bus_dmamap_t map" "void *buf" \ 112"bus_size_t buflen" "bus_dmamap_callback_t *callback" "void *callback_arg" \ 113"int flags" 114.Ft int 115.Fn bus_dmamap_load_bio "bus_dma_tag_t dmat" "bus_dmamap_t map" \ 116"struct bio *bio" "bus_dmamap_callback_t *callback" "void *callback_arg" \ 117"int flags" 118.Ft int 119.Fn bus_dmamap_load_ccb "bus_dma_tag_t dmat" "bus_dmamap_t map" \ 120"union ccb *ccb" "bus_dmamap_callback_t *callback" "void *callback_arg" \ 121"int flags" 122.Ft int 123.Fn bus_dmamap_load_crp "bus_dma_tag_t dmat" "bus_dmamap_t map" \ 124"struct crypto *crp" "bus_dmamap_callback_t *callback" "void *callback_arg" \ 125"int flags" 126.Ft int 127.Fn bus_dmamap_load_crp_buffer "bus_dma_tag_t dmat" "bus_dmamap_t map" \ 128"struct crypto_buffer *cb" "bus_dmamap_callback_t *callback" \ 129"void *callback_arg" "int flags" 130.Ft int 131.Fn bus_dmamap_load_mbuf "bus_dma_tag_t dmat" "bus_dmamap_t map" \ 132"struct mbuf *mbuf" "bus_dmamap_callback2_t *callback" "void *callback_arg" \ 133"int flags" 134.Ft int 135.Fn bus_dmamap_load_mbuf_sg "bus_dma_tag_t dmat" "bus_dmamap_t map" \ 136"struct mbuf *mbuf" "bus_dma_segment_t *segs" "int *nsegs" "int flags" 137.Ft int 138.Fn bus_dmamap_load_uio "bus_dma_tag_t dmat" "bus_dmamap_t map" \ 139"struct uio *uio" "bus_dmamap_callback2_t *callback" "void *callback_arg" \ 140"int flags" 141.Ft void 142.Fn bus_dmamap_unload "bus_dma_tag_t dmat" "bus_dmamap_t map" 143.Ft void 144.Fn bus_dmamap_sync "bus_dma_tag_t dmat" "bus_dmamap_t map" \ 145"op" 146.Ft int 147.Fn bus_dmamem_alloc "bus_dma_tag_t dmat" "void **vaddr" \ 148"int flags" "bus_dmamap_t *mapp" 149.Ft void 150.Fn bus_dmamem_free "bus_dma_tag_t dmat" "void *vaddr" \ 151"bus_dmamap_t map" 152.Sh DESCRIPTION 153Direct Memory Access (DMA) is a method of transferring data 154without involving the CPU, thus providing higher performance. 155A DMA transaction can be achieved between device to memory, 156device to device, or memory to memory. 157.Pp 158The 159.Nm 160API is a bus, device, and machine-independent (MI) interface to 161DMA mechanisms. 162It provides the client with flexibility and simplicity by 163abstracting machine dependent issues like setting up 164DMA mappings, handling cache issues, bus specific features 165and limitations. 166.Sh OVERVIEW 167A tag structure 168.Vt ( bus_dma_tag_t ) 169is used to describe the properties of a group of related DMA 170transactions. 171One way to view this is that a tag describes the limitations of a DMA engine. 172For example, if a DMA engine in a device is limited to 32-bit addresses, 173that limitation is specified by a parameter when creating the tag 174for that device. 175Similarly, a tag can be marked as requiring buffers whose addresses are 176aligned to a specific boundary. 177.Pp 178Some devices may require multiple tags to describe DMA 179transactions with differing properties. 180For example, a device might require 16-byte alignment of its descriptor ring 181while permitting arbitrary alignment of I/O buffers. 182In this case, 183the driver must create one tag for the descriptor ring and a separate tag for 184I/O buffers. 185If a device has restrictions that are common to all DMA transactions 186in addition to restrictions that differ between unrelated groups of 187transactions, 188the driver can first create a 189.Dq parent 190tag that decribes the common restrictions. 191The per-group tags can then inherit these restrictions from this 192.Dq parent 193tag rather than having to list them explicitly when creating the per-group tags. 194.Pp 195A mapping structure 196.Vt ( bus_dmamap_t ) 197represents a mapping of a memory region for DMA. 198On systems with I/O MMUs, 199the mapping structure tracks any I/O MMU entries used by a request. 200For DMA requests that require bounce pages, 201the mapping tracks the bounce pages used. 202.Pp 203To prepare for one or more DMA transactions, 204a mapping must be bound to a memory region by calling one of the 205.Fn bus_dmamap_load 206functions. 207These functions configure the mapping which can include programming entries 208in an I/O MMU and/or allocating bounce pages. 209An output of these functions 210(either directly or indirectly by invoking a callback routine) 211is the list of scatter/gather address ranges a consumer can pass to a DMA 212engine to access the memory region. 213When a mapping is no longer needed, 214the mapping must be unloaded via 215.Fn bus_dmamap_unload . 216.Pp 217Before and after each DMA transaction, 218.Fn bus_dmamap_sync 219must be used to ensure that the correct data is used by the DMA engine and 220the CPU. 221If a mapping uses bounce pages, 222the sync operations copy data between the bounce pages and the memory region 223bound to the mapping. 224Sync operations also handle architecture-specific details such as CPU cache 225flushing and CPU memory operation ordering. 226.Sh STATIC VS DYNAMIC 227.Nm 228handles two types of DMA transactions: static and dynamic. 229Static transactions are used with a long-lived memory region that is reused 230for many transactions such as a descriptor ring. 231Dynamic transactions are used for transfers to or from transient buffers 232such as I/O buffers holding a network packet or disk block. 233Each transaction type uses a different subset of the 234.Nm 235API. 236.Ss Static Transactions 237Static transactions use memory regions allocated by 238.Nm . 239Each static memory region is allocated by calling 240.Fn bus_dmamem_alloc . 241This function requires a valid tag describing the properties of the 242DMA transactions to this region such as alignment or address restrictions. 243Multiple regions can share a single tag if they share the same restrictions. 244.Pp 245.Fn bus_dmamem_alloc 246allocates a memory region along with a mapping object. 247The associated tag, memory region, and mapping object must then be passed to 248.Fn bus_dmamap_load 249to bind the mapping to the allocated region and obtain the 250scatter/gather list. 251.Pp 252It is expected that 253.Fn bus_dmamem_alloc 254will attempt to allocate memory requiring less expensive sync operations 255(for example, implementations should not allocate regions requiring bounce 256pages), 257but sync operations should still be used. 258For example, a driver should use 259.Fn bus_dmamap_sync 260in an interrupt handler before reading descriptor ring entries written by the 261device prior to the interrupt. 262.Pp 263When a consumer is finished with a memory region, 264it should unload the mapping via 265.Fn bus_dmamap_unload 266and then release the memory region and mapping object via 267.Fn bus_dmamem_free . 268.Ss Dynamic Transactions 269Dynamic transactions map memory regions provided by other parts of the system. 270A tag must be created via 271.Fn bus_dma_tag_create 272to describe the DMA transactions to and from these memory regions, 273and a pool of mapping objects must be allocated via 274.Fn bus_dmamap_create 275to track the mappings of any in-flight transactions. 276.Pp 277When a consumer wishes to schedule a transaction for a memory region, 278the consumer must first obtain an unused mapping object from its pool 279of mapping objects. 280The memory region must be bound to the mapping object via one of the 281.Fn bus_dmamap_load 282functions. 283Before scheduling the transaction, 284the consumer should sync the memory region via 285.Fn bus_dmamap_sync 286with one or more of the 287.Dq PRE 288flags. 289After the transaction has completed, 290the consumer should sync the memory region via 291.Fn bus_dmamap_sync 292with one or more of the 293.Dq POST 294flags. 295The mapping can then be unloaded via 296.Fn bus_dmamap_unload , 297and the mapping object can be returned to the pool of unused mapping objects. 298.Pp 299When a consumer is no longer scheduling DMA transactions, 300the mapping objects should be freed via 301.Fn bus_dmamap_destroy , 302and the tag should be freed via 303.Fn bus_dma_tag_destroy . 304.Sh STRUCTURES AND TYPES 305.Bl -tag -width indent 306.It Vt bus_dma_tag_t 307A machine-dependent (MD) opaque type that describes the 308characteristics of a group of DMA transactions. 309DMA tags are organized into a hierarchy, with each child 310tag inheriting the restrictions of its parent. 311This allows all devices along the path of DMA transactions 312to contribute to the constraints of those transactions. 313.It Vt bus_dma_template_t 314A template structure for creating a 315.Fa bus_dma_tag_t 316from a set of defaults. 317Once initialized with 318.Fn bus_dma_template_init , 319a driver can over-ride individual fields to suit its needs. 320The following fields have the indicated values: 321.Bd -literal 322 alignment 1 323 boundary 0 324 lowaddr BUS_SPACE_MAXADDR 325 highaddr BUS_SPACE_MAXADDR 326 maxsize BUS_SPACE_MAXSIZE 327 nsegments BUS_SPACE_UNRESTRICTED 328 maxsegsize BUS_SPACE_MAXSIZE 329 flags 0 330 lockfunc NULL 331 lockfuncarg NULL 332.Ed 333.Pp 334Descriptions of each field are documented with 335.Fn bus_dma_tag_create . 336Note that the 337.Fa filtfunc 338and 339.Fa filtfuncarg 340attributes of the DMA tag are not supported with templates. 341.It Vt bus_dma_filter_t 342Client specified address filter having the format: 343.Bl -tag -width indent 344.It Ft int 345.Fn "client_filter" "void *filtarg" "bus_addr_t testaddr" 346.El 347.Pp 348Address filters can be specified during tag creation to allow 349for devices whose DMA address restrictions cannot be specified 350by a single window. 351The 352.Fa filtarg 353argument is specified by the client during tag creation to be passed to all 354invocations of the callback. 355The 356.Fa testaddr 357argument contains a potential starting address of a DMA mapping. 358The filter function operates on the set of addresses from 359.Fa testaddr 360to 361.Ql trunc_page(testaddr) + PAGE_SIZE - 1 , 362inclusive. 363The filter function should return zero if any mapping in this range 364can be accommodated by the device and non-zero otherwise. 365.It Vt bus_dma_segment_t 366A machine-dependent type that describes individual 367DMA segments. 368It contains the following fields: 369.Bd -literal 370 bus_addr_t ds_addr; 371 bus_size_t ds_len; 372.Ed 373.Pp 374The 375.Fa ds_addr 376field contains the device visible address of the DMA segment, and 377.Fa ds_len 378contains the length of the DMA segment. 379Although the DMA segments returned by a mapping call will adhere to 380all restrictions necessary for a successful DMA operation, some conversion 381(e.g.\& a conversion from host byte order to the device's byte order) is 382almost always required when presenting segment information to the device. 383.It Vt bus_dmamap_t 384A machine-dependent opaque type describing an individual mapping. 385One map is used for each memory allocation that will be loaded. 386Maps can be reused once they have been unloaded. 387Multiple maps can be associated with one DMA tag. 388While the value of the map may evaluate to 389.Dv NULL 390on some platforms under certain conditions, 391it should never be assumed that it will be 392.Dv NULL 393in all cases. 394.It Vt bus_dmamap_callback_t 395Client specified callback for receiving mapping information resulting from 396the load of a 397.Vt bus_dmamap_t 398via 399.Fn bus_dmamap_load , 400.Fn bus_dmamap_load_bio , 401.Fn bus_dmamap_load_ccb , 402.Fn bus_dmamap_load_crp , 403or 404.Fn bus_dmamap_load_crp_buffer . 405Callbacks are of the format: 406.Bl -tag -width indent 407.It Ft void 408.Fn "client_callback" "void *callback_arg" "bus_dma_segment_t *segs" \ 409"int nseg" "int error" 410.El 411.Pp 412The 413.Fa callback_arg 414is the callback argument passed to dmamap load functions. 415The 416.Fa segs 417and 418.Fa nseg 419arguments describe an array of 420.Vt bus_dma_segment_t 421structures that represent the mapping. 422This array is only valid within the scope of the callback function. 423The success or failure of the mapping is indicated by the 424.Fa error 425argument. 426More information on the use of callbacks can be found in the 427description of the individual dmamap load functions. 428.It Vt bus_dmamap_callback2_t 429Client specified callback for receiving mapping information resulting from 430the load of a 431.Vt bus_dmamap_t 432via 433.Fn bus_dmamap_load_uio 434or 435.Fn bus_dmamap_load_mbuf . 436.Pp 437Callback2s are of the format: 438.Bl -tag -width indent 439.It Ft void 440.Fn "client_callback2" "void *callback_arg" "bus_dma_segment_t *segs" \ 441"int nseg" "bus_size_t mapsize" "int error" 442.El 443.Pp 444Callback2's behavior is the same as 445.Vt bus_dmamap_callback_t 446with the addition that the length of the data mapped is provided via 447.Fa mapsize . 448.It Vt bus_dmasync_op_t 449Memory synchronization operation specifier. 450Bus DMA requires explicit synchronization of memory with its device 451visible mapping in order to guarantee memory coherency. 452The 453.Vt bus_dmasync_op_t 454allows the type of DMA operation that will be or has been performed 455to be communicated to the system so that the correct coherency measures 456are taken. 457The operations are represented as bitfield flags that can be combined together, 458though it only makes sense to combine PRE flags or POST flags, not both. 459See the 460.Fn bus_dmamap_sync 461description below for more details on how to use these operations. 462.Pp 463All operations specified below are performed from the host memory point of view, 464where a read implies data coming from the device to the host memory, and a write 465implies data going from the host memory to the device. 466Alternatively, the operations can be thought of in terms of driver operations, 467where reading a network packet or storage sector corresponds to a read operation 468in 469.Nm . 470.Bl -tag -width ".Dv BUS_DMASYNC_POSTWRITE" 471.It Dv BUS_DMASYNC_PREREAD 472Perform any synchronization required prior to an update of host memory by the 473device. 474.It Dv BUS_DMASYNC_PREWRITE 475Perform any synchronization required after an update of host memory by the CPU 476and prior to device access to host memory. 477.It Dv BUS_DMASYNC_POSTREAD 478Perform any synchronization required after an update of host memory by the 479device and prior to CPU access to host memory. 480.It Dv BUS_DMASYNC_POSTWRITE 481Perform any synchronization required after device access to host memory. 482.El 483.It Vt bus_dma_lock_t 484Client specified lock/mutex manipulation method. 485This will be called from 486within busdma whenever a client lock needs to be manipulated. 487In its current form, the function will be called immediately before 488the callback for a DMA load operation that has been deferred with 489.Dv BUS_DMA_LOCK 490and immediately after with 491.Dv BUS_DMA_UNLOCK . 492If the load operation does not need to be deferred, then it 493will not be called since the function loading the map should 494be holding the appropriate locks. 495This method is of the format: 496.Bl -tag -width indent 497.It Ft void 498.Fn "lockfunc" "void *lockfunc_arg" "bus_dma_lock_op_t op" 499.El 500.Pp 501The 502.Fa lockfuncarg 503argument is specified by the client during tag creation to be passed to all 504invocations of the callback. 505The 506.Fa op 507argument specifies the lock operation to perform. 508.Pp 509Two 510.Vt lockfunc 511implementations are provided for convenience. 512.Fn busdma_lock_mutex 513performs standard mutex operations on the sleep mutex provided via 514.Fa lockfuncarg . 515.Fn dflt_lock 516will generate a system panic if it is called. 517It is substituted into the tag when 518.Fa lockfunc 519is passed as 520.Dv NULL 521to 522.Fn bus_dma_tag_create 523and is useful for tags that should not be used with deferred load operations. 524.It Vt bus_dma_lock_op_t 525Operations to be performed by the client-specified 526.Fn lockfunc . 527.Bl -tag -width ".Dv BUS_DMA_UNLOCK" 528.It Dv BUS_DMA_LOCK 529Acquires and/or locks the client locking primitive. 530.It Dv BUS_DMA_UNLOCK 531Releases and/or unlocks the client locking primitive. 532.El 533.El 534.Sh FUNCTIONS 535.Bl -tag -width indent 536.It Fn bus_dma_tag_create "parent" "alignment" "boundary" "lowaddr" \ 537"highaddr" "*filtfunc" "*filtfuncarg" "maxsize" "nsegments" "maxsegsz" \ 538"flags" "lockfunc" "lockfuncarg" "*dmat" 539Allocates a DMA tag, and initializes it according to 540the arguments provided: 541.Bl -tag -width ".Fa filtfuncarg" 542.It Fa parent 543A parent tag from which to inherit restrictions. 544The restrictions passed in other arguments can only further tighten the 545restrictions inherited from the parent tag. 546.Pp 547All tags created by a device driver must inherit from the tag returned by 548.Fn bus_get_dma_tag 549to honor restrictions between the parent bridge, CPU memory, and the 550device. 551.It Fa alignment 552Alignment constraint, in bytes, of any mappings created using this tag. 553The alignment must be a power of 2. 554Hardware that can DMA starting at any address would specify 555.Em 1 556for byte alignment. 557Hardware requiring DMA transfers to start on a multiple of 4K 558would specify 559.Em 4096 . 560.It Fa boundary 561Boundary constraint, in bytes, of the target DMA memory region. 562The boundary indicates the set of addresses, all multiples of the 563boundary argument, that cannot be crossed by a single 564.Vt bus_dma_segment_t . 565The boundary must be a power of 2 and must be no smaller than the 566maximum segment size. 567.Ql 0 568indicates that there are no boundary restrictions. 569.It Fa lowaddr , highaddr 570Bounds of the window of bus address space that 571.Em cannot 572be directly accessed by the device. 573The window contains all addresses greater than 574.Fa lowaddr 575and less than or equal to 576.Fa highaddr . 577For example, a device incapable of DMA above 4GB, would specify a 578.Fa highaddr 579of 580.Dv BUS_SPACE_MAXADDR 581and a 582.Fa lowaddr 583of 584.Dv BUS_SPACE_MAXADDR_32BIT . 585Similarly a device that can only perform DMA to addresses below 58616MB would specify a 587.Fa highaddr 588of 589.Dv BUS_SPACE_MAXADDR 590and a 591.Fa lowaddr 592of 593.Dv BUS_SPACE_MAXADDR_24BIT . 594Some implementations require that some region of device visible 595address space, overlapping available host memory, be outside the 596window. 597This area of 598.Ql safe memory 599is used to bounce requests that would otherwise conflict with 600the exclusion window. 601.It Fa filtfunc 602Optional filter function (may be 603.Dv NULL ) 604to be called for any attempt to 605map memory into the window described by 606.Fa lowaddr 607and 608.Fa highaddr . 609A filter function is only required when the single window described 610by 611.Fa lowaddr 612and 613.Fa highaddr 614cannot adequately describe the constraints of the device. 615The filter function will be called for every machine page 616that overlaps the exclusion window. 617.It Fa filtfuncarg 618Argument passed to all calls to the filter function for this tag. 619May be 620.Dv NULL . 621.It Fa maxsize 622Maximum size, in bytes, of the sum of all segment lengths in a given 623DMA mapping associated with this tag. 624.It Fa nsegments 625Number of discontinuities (scatter/gather segments) allowed 626in a DMA mapped region. 627.It Fa maxsegsz 628Maximum size, in bytes, of a segment in any DMA mapped region associated 629with 630.Fa dmat . 631.It Fa flags 632Are as follows: 633.Bl -tag -width ".Dv BUS_DMA_ALLOCNOW" 634.It Dv BUS_DMA_ALLOCNOW 635Pre-allocate enough resources to handle at least one map load operation on 636this tag. 637If sufficient resources are not available, 638.Er ENOMEM 639is returned. 640This should not be used for tags that only describe buffers that will be 641allocated with 642.Fn bus_dmamem_alloc . 643Also, due to resource sharing with other tags, this flag does not guarantee 644that resources will be allocated or reserved exclusively for this tag. 645It should be treated only as a minor optimization. 646.It Dv BUS_DMA_COHERENT 647Indicate that the DMA engine and CPU are cache-coherent. 648Cached memory may be used to back allocations created by 649.Fn bus_dmamem_alloc . 650For 651.Fn bus_dma_tag_create , 652the 653.Dv BUS_DMA_COHERENT 654flag is currently implemented on arm64. 655.El 656.It Fa lockfunc 657Optional lock manipulation function (may be 658.Dv NULL ) 659to be called when busdma 660needs to manipulate a lock on behalf of the client. 661If 662.Dv NULL 663is specified, 664.Fn dflt_lock 665is used. 666.It Fa lockfuncarg 667Optional argument to be passed to the function specified by 668.Fa lockfunc . 669.It Fa dmat 670Pointer to a bus_dma_tag_t where the resulting DMA tag will 671be stored. 672.El 673.Pp 674Returns 675.Er ENOMEM 676if sufficient memory is not available for tag creation 677or allocating mapping resources. 678.It Fn bus_dma_tag_destroy "dmat" 679Deallocate the DMA tag 680.Fa dmat 681that was created by 682.Fn bus_dma_tag_create . 683.Pp 684Returns 685.Er EBUSY 686if any DMA maps remain associated with 687.Fa dmat 688or 689.Ql 0 690on success. 691.It Fn bus_dma_template_init "*template" "parent" 692Initializes a 693.Fa bus_dma_template_t 694structure and associates it with an optional 695.Fa parent . 696The 697.Fa parent 698argument may be NULL. 699.It Fn bus_dma_template_tag "*template" "*dmat" 700Unpacks a template into a tag, and returns the tag via the 701.Fa dmat . 702All return values are identical to 703.Fn bus_dma_tag_create . 704.It Fn bus_dma_template_clone "*template" "dmat" 705Clones the fields from a tag to a template. 706This is useful for cloning tags when paired with 707.Fn bus_dma_template_tag . 708A template that is filled in as a clone does not need to be initialized 709first. 710.It Fn bus_dmamap_create "dmat" "flags" "*mapp" 711Allocates and initializes a DMA map. 712Arguments are as follows: 713.Bl -tag -width ".Fa nsegments" 714.It Fa dmat 715DMA tag. 716.It Fa flags 717Are as follows: 718.Bl -tag -width ".Dv BUS_DMA_COHERENT" 719.It Dv BUS_DMA_COHERENT 720Attempt to map the memory loaded with this map such that cache sync 721operations are as cheap as possible. 722This flag is typically set on maps when the memory loaded with these will 723be accessed by both a CPU and a DMA engine, frequently such as control data 724and as opposed to streamable data such as receive and transmit buffers. 725Use of this flag does not remove the requirement of using 726.Fn bus_dmamap_sync , 727but it may reduce the cost of performing these operations. 728.El 729.It Fa mapp 730Pointer to a 731.Vt bus_dmamap_t 732where the resulting DMA map will be stored. 733.El 734.Pp 735Returns 736.Er ENOMEM 737if sufficient memory is not available for creating the 738map or allocating mapping resources. 739.It Fn bus_dmamap_destroy "dmat" "map" 740Frees all resources associated with a given DMA map. 741Arguments are as follows: 742.Bl -tag -width ".Fa dmat" 743.It Fa dmat 744DMA tag used to allocate 745.Fa map . 746.It Fa map 747The DMA map to destroy. 748.El 749.Pp 750Returns 751.Er EBUSY 752if a mapping is still active for 753.Fa map . 754.It Fn bus_dmamap_load "dmat" "map" "buf" "buflen" "*callback" \ 755"callback_arg" "flags" 756Creates a mapping in device visible address space of 757.Fa buflen 758bytes of 759.Fa buf , 760associated with the DMA map 761.Fa map . 762This call will always return immediately and will not block for any reason. 763Arguments are as follows: 764.Bl -tag -width ".Fa buflen" 765.It Fa dmat 766DMA tag used to allocate 767.Fa map . 768.It Fa map 769A DMA map without a currently active mapping. 770.It Fa buf 771A kernel virtual address pointer to a contiguous (in KVA) buffer, to be 772mapped into device visible address space. 773.It Fa buflen 774The size of the buffer. 775.It Fa callback Fa callback_arg 776The callback function, and its argument. 777This function is called once sufficient mapping resources are available for 778the DMA operation. 779If resources are temporarily unavailable, this function will be deferred until 780later, but the load operation will still return immediately to the caller. 781Thus, callers should not assume that the callback will be called before the 782load returns, and code should be structured appropriately to handle this. 783See below for specific flags and error codes that control this behavior. 784.It Fa flags 785Are as follows: 786.Bl -tag -width ".Dv BUS_DMA_NOWAIT" 787.It Dv BUS_DMA_NOWAIT 788The load should not be deferred in case of insufficient mapping resources, 789and instead should return immediately with an appropriate error. 790.It Dv BUS_DMA_NOCACHE 791The generated transactions to and from the virtual page are non-cacheable. 792.El 793.El 794.Pp 795Return values to the caller are as follows: 796.Bl -tag -width ".Er EINPROGRESS" 797.It 0 798The callback has been called and completed. 799The status of the mapping has been delivered to the callback. 800.It Er EINPROGRESS 801The mapping has been deferred for lack of resources. 802The callback will be called as soon as resources are available. 803Callbacks are serviced in FIFO order. 804.Pp 805Note that subsequent load operations for the same tag that do not require 806extra resources will still succeed. 807This may result in out-of-order processing of requests. 808If the caller requires the order of requests to be preserved, 809then the caller is required to stall subsequent requests until a pending 810request's callback is invoked. 811.It Er ENOMEM 812The load request has failed due to insufficient resources, and the caller 813specifically used the 814.Dv BUS_DMA_NOWAIT 815flag. 816.It Er EINVAL 817The load request was invalid. 818The callback has been called and has been provided the same error. 819This error value may indicate that 820.Fa dmat , 821.Fa map , 822.Fa buf , 823or 824.Fa callback 825were invalid, or 826.Fa buflen 827was larger than the 828.Fa maxsize 829argument used to create the dma tag 830.Fa dmat . 831.El 832.Pp 833When the callback is called, it is presented with an error value 834indicating the disposition of the mapping. 835Error may be one of the following: 836.Bl -tag -width ".Er EINPROGRESS" 837.It 0 838The mapping was successful and the 839.Fa dm_segs 840callback argument contains an array of 841.Vt bus_dma_segment_t 842elements describing the mapping. 843This array is only valid during the scope of the callback function. 844.It Er EFBIG 845A mapping could not be achieved within the segment constraints provided 846in the tag even though the requested allocation size was less than maxsize. 847.El 848.It Fn bus_dmamap_load_bio "dmat" "map" "bio" "callback" "callback_arg" "flags" 849This is a variation of 850.Fn bus_dmamap_load 851which maps buffers pointed to by 852.Fa bio 853for DMA transfers. 854.Fa bio 855may point to either a mapped or unmapped buffer. 856.It Fn bus_dmamap_load_ccb "dmat" "map" "ccb" "callback" "callback_arg" "flags" 857This is a variation of 858.Fn bus_dmamap_load 859which maps data pointed to by 860.Fa ccb 861for DMA transfers. 862The data for 863.Fa ccb 864may be any of the following types: 865.Bl -tag -width ".Er CAM_DATA_SG_PADDR" 866.It CAM_DATA_VADDR 867The data is a single KVA buffer. 868.It CAM_DATA_PADDR 869The data is a single bus address range. 870.It CAM_DATA_SG 871The data is a scatter/gather list of KVA buffers. 872.It CAM_DATA_SG_PADDR 873The data is a scatter/gather list of bus address ranges. 874.It CAM_DATA_BIO 875The data is contained in a 876.Vt struct bio 877attached to the CCB. 878.El 879.Pp 880.Fn bus_dmamap_load_ccb 881supports the following CCB XPT function codes: 882.Pp 883.Bl -item -offset indent -compact 884.It 885XPT_ATA_IO 886.It 887XPT_CONT_TARGET_IO 888.It 889XPT_SCSI_IO 890.El 891.It Fn bus_dmamap_load_crp "dmat" "map" "crp" "callback" "callback_arg" "flags" 892This is a variation of 893.Fn bus_dmamap_load 894which maps the input buffer pointed to by 895.Fa crp 896for DMA transfers. 897The 898.Dv BUS_DMA_NOWAIT 899flag is implied, thus no callback deferral will happen. 900.It Fn bus_dmamap_load_crp_buffer "dmat" "map" "cb" "callback" "callback_arg" \ 901"flags" 902This is a variation of 903.Fn bus_dmamap_load 904which maps the crypto data buffer pointed to by 905.Fa cb 906for DMA transfers. 907The 908.Dv BUS_DMA_NOWAIT 909flag is implied, thus no callback deferral will happen. 910.It Fn bus_dmamap_load_mbuf "dmat" "map" "mbuf" "callback2" "callback_arg" \ 911"flags" 912This is a variation of 913.Fn bus_dmamap_load 914which maps mbuf chains 915for DMA transfers. 916A 917.Vt bus_size_t 918argument is also passed to the callback routine, which 919contains the mbuf chain's packet header length. 920The 921.Dv BUS_DMA_NOWAIT 922flag is implied, thus no callback deferral will happen. 923.Pp 924Mbuf chains are assumed to be in kernel virtual address space. 925.Pp 926Beside the error values listed for 927.Fn bus_dmamap_load , 928.Er EINVAL 929will be returned if the size of the mbuf chain exceeds the maximum limit of the 930DMA tag. 931.It Fn bus_dmamap_load_mbuf_sg "dmat" "map" "mbuf" "segs" "nsegs" "flags" 932This is just like 933.Fn bus_dmamap_load_mbuf 934except that it returns immediately without calling a callback function. 935It is provided for efficiency. 936The scatter/gather segment array 937.Va segs 938is provided by the caller and filled in directly by the function. 939The 940.Va nsegs 941argument is returned with the number of segments filled in. 942Returns the same errors as 943.Fn bus_dmamap_load_mbuf . 944.It Fn bus_dmamap_load_uio "dmat" "map" "uio" "callback2" "callback_arg" "flags" 945This is a variation of 946.Fn bus_dmamap_load 947which maps buffers pointed to by 948.Fa uio 949for DMA transfers. 950A 951.Vt bus_size_t 952argument is also passed to the callback routine, which contains the size of 953.Fa uio , 954i.e. 955.Fa uio->uio_resid . 956The 957.Dv BUS_DMA_NOWAIT 958flag is implied, thus no callback deferral will happen. 959Returns the same errors as 960.Fn bus_dmamap_load . 961.Pp 962If 963.Fa uio->uio_segflg 964is 965.Dv UIO_USERSPACE , 966then it is assumed that the buffer, 967.Fa uio 968is in 969.Fa "uio->uio_td->td_proc" Ns 's 970address space. 971User space memory must be in-core and wired prior to attempting a map 972load operation. 973Pages may be locked using 974.Xr vslock 9 . 975.It Fn bus_dmamap_unload "dmat" "map" 976Unloads a DMA map. 977Arguments are as follows: 978.Bl -tag -width ".Fa dmam" 979.It Fa dmat 980DMA tag used to allocate 981.Fa map . 982.It Fa map 983The DMA map that is to be unloaded. 984.El 985.Pp 986.Fn bus_dmamap_unload 987will not perform any implicit synchronization of DMA buffers. 988This must be done explicitly by a call to 989.Fn bus_dmamap_sync 990prior to unloading the map. 991.It Fn bus_dmamap_sync "dmat" "map" "op" 992Performs synchronization of a device visible mapping with the CPU visible 993memory referenced by that mapping. 994Arguments are as follows: 995.Bl -tag -width ".Fa dmat" 996.It Fa dmat 997DMA tag used to allocate 998.Fa map . 999.It Fa map 1000The DMA mapping to be synchronized. 1001.It Fa op 1002Type of synchronization operation to perform. 1003See the definition of 1004.Vt bus_dmasync_op_t 1005for a description of the acceptable values for 1006.Fa op . 1007.El 1008.Pp 1009The 1010.Fn bus_dmamap_sync 1011function 1012is the method used to ensure that CPU's and device's direct 1013memory access (DMA) to shared 1014memory is coherent. 1015For example, the CPU might be used to set up the contents of a buffer 1016that is to be made available to a device. 1017To ensure that the data are visible via the device's mapping of that 1018memory, the buffer must be loaded and a DMA sync operation of 1019.Dv BUS_DMASYNC_PREWRITE 1020must be performed after the CPU has updated the buffer and before the device 1021access is initiated. 1022If the CPU modifies this buffer again later, another 1023.Dv BUS_DMASYNC_PREWRITE 1024sync operation must be performed before an additional device 1025access. 1026Conversely, suppose a device updates memory that is to be read by a CPU. 1027In this case, the buffer must be loaded, and a DMA sync operation of 1028.Dv BUS_DMASYNC_PREREAD 1029must be performed before the device access is initiated. 1030The CPU will only be able to see the results of this memory update 1031once the DMA operation has completed and a 1032.Dv BUS_DMASYNC_POSTREAD 1033sync operation has been performed. 1034.Pp 1035If read and write operations are not preceded and followed by the 1036appropriate synchronization operations, behavior is undefined. 1037.It Fn bus_dmamem_alloc "dmat" "**vaddr" "flags" "*mapp" 1038Allocates memory that is mapped into KVA at the address returned 1039in 1040.Fa vaddr 1041and that is permanently loaded into the newly created 1042.Vt bus_dmamap_t 1043returned via 1044.Fa mapp . 1045Arguments are as follows: 1046.Bl -tag -width ".Fa alignment" 1047.It Fa dmat 1048DMA tag describing the constraints of the DMA mapping. 1049.It Fa vaddr 1050Pointer to a pointer that will hold the returned KVA mapping of 1051the allocated region. 1052.It Fa flags 1053Flags are defined as follows: 1054.Bl -tag -width ".Dv BUS_DMA_NOWAIT" 1055.It Dv BUS_DMA_WAITOK 1056The routine can safely wait (sleep) for resources. 1057.It Dv BUS_DMA_NOWAIT 1058The routine is not allowed to wait for resources. 1059If resources are not available, 1060.Dv ENOMEM 1061is returned. 1062.It Dv BUS_DMA_COHERENT 1063Attempt to map this memory in a coherent fashion. 1064See 1065.Fn bus_dmamap_create 1066above for a description of this flag. 1067For 1068.Fn bus_dmamem_alloc , 1069the 1070.Dv BUS_DMA_COHERENT 1071flag is currently implemented on arm and arm64. 1072.It Dv BUS_DMA_ZERO 1073Causes the allocated memory to be set to all zeros. 1074.It Dv BUS_DMA_NOCACHE 1075The allocated memory will not be cached in the processor caches. 1076All memory accesses appear on the bus and are executed 1077without reordering. 1078For 1079.Fn bus_dmamem_alloc , 1080the 1081.Dv BUS_DMA_NOCACHE 1082flag is currently implemented on amd64 and i386 where it results in the 1083Strong Uncacheable PAT to be set for the allocated virtual address range. 1084.El 1085.It Fa mapp 1086Pointer to a 1087.Vt bus_dmamap_t 1088where the resulting DMA map will be stored. 1089.El 1090.Pp 1091The size of memory to be allocated is 1092.Fa maxsize 1093as specified in the call to 1094.Fn bus_dma_tag_create 1095for 1096.Fa dmat . 1097.Pp 1098The current implementation of 1099.Fn bus_dmamem_alloc 1100will allocate all requests as a single segment. 1101.Pp 1102An initial load operation is required to obtain the bus address of the allocated 1103memory, and an unload operation is required before freeing the memory, as 1104described below in 1105.Fn bus_dmamem_free . 1106Maps are automatically handled by this function and should not be explicitly 1107allocated or destroyed. 1108.Pp 1109Although an explicit load is not required for each access to the memory 1110referenced by the returned map, the synchronization requirements 1111as described in the 1112.Fn bus_dmamap_sync 1113section still apply and should be used to achieve portability on architectures 1114without coherent buses. 1115.Pp 1116Returns 1117.Er ENOMEM 1118if sufficient memory is not available for completing 1119the operation. 1120.It Fn bus_dmamem_free "dmat" "*vaddr" "map" 1121Frees memory previously allocated by 1122.Fn bus_dmamem_alloc . 1123Any mappings 1124will be invalidated. 1125Arguments are as follows: 1126.Bl -tag -width ".Fa vaddr" 1127.It Fa dmat 1128DMA tag. 1129.It Fa vaddr 1130Kernel virtual address of the memory. 1131.It Fa map 1132DMA map to be invalidated. 1133.El 1134.El 1135.Sh RETURN VALUES 1136Behavior is undefined if invalid arguments are passed to 1137any of the above functions. 1138If sufficient resources cannot be allocated for a given 1139transaction, 1140.Er ENOMEM 1141is returned. 1142All 1143routines that are not of type 1144.Vt void 1145will return 0 on success or an error 1146code on failure as discussed above. 1147.Pp 1148All 1149.Vt void 1150routines will succeed if provided with valid arguments. 1151.Sh LOCKING 1152Two locking protocols are used by 1153.Nm . 1154The first is a private global lock that is used to synchronize access to the 1155bounce buffer pool on the architectures that make use of them. 1156This lock is strictly a leaf lock that is only used internally to 1157.Nm 1158and is not exposed to clients of the API. 1159.Pp 1160The second protocol involves protecting various resources stored in the tag. 1161Since almost all 1162.Nm 1163operations are done through requests from the driver that created the tag, 1164the most efficient way to protect the tag resources is through the lock that 1165the driver uses. 1166In cases where 1167.Nm 1168acts on its own without being called by the driver, the lock primitive 1169specified in the tag is acquired and released automatically. 1170An example of this is when the 1171.Fn bus_dmamap_load 1172callback function is called from a deferred context instead of the driver 1173context. 1174This means that certain 1175.Nm 1176functions must always be called with the same lock held that is specified in the 1177tag. 1178These functions include: 1179.Pp 1180.Bl -item -offset indent -compact 1181.It 1182.Fn bus_dmamap_load 1183.It 1184.Fn bus_dmamap_load_bio 1185.It 1186.Fn bus_dmamap_load_ccb 1187.It 1188.Fn bus_dmamap_load_mbuf 1189.It 1190.Fn bus_dmamap_load_mbuf_sg 1191.It 1192.Fn bus_dmamap_load_uio 1193.It 1194.Fn bus_dmamap_unload 1195.It 1196.Fn bus_dmamap_sync 1197.El 1198.Pp 1199There is one exception to this rule. 1200It is common practice to call some of these functions during driver start-up 1201without any locks held. 1202So long as there is a guarantee of no possible concurrent use of the tag by 1203different threads during this operation, it is safe to not hold a lock for 1204these functions. 1205.Pp 1206Certain 1207.Nm 1208operations should not be called with the driver lock held, either because 1209they are already protected by an internal lock, or because they might sleep 1210due to memory or resource allocation. 1211The following functions must not be 1212called with any non-sleepable locks held: 1213.Pp 1214.Bl -item -offset indent -compact 1215.It 1216.Fn bus_dma_tag_create 1217.It 1218.Fn bus_dmamap_create 1219.It 1220.Fn bus_dmamem_alloc 1221.El 1222.Pp 1223All other functions do not have a locking protocol and can thus be 1224called with or without any system or driver locks held. 1225.Sh SEE ALSO 1226.Xr devclass 9 , 1227.Xr device 9 , 1228.Xr driver 9 , 1229.Xr rman 9 , 1230.Xr vslock 9 1231.Pp 1232.Rs 1233.%A "Jason R. Thorpe" 1234.%T "A Machine-Independent DMA Framework for NetBSD" 1235.%J "Proceedings of the Summer 1998 USENIX Technical Conference" 1236.%Q "USENIX Association" 1237.%D "June 1998" 1238.Re 1239.Sh HISTORY 1240The 1241.Nm 1242interface first appeared in 1243.Nx 1.3 . 1244.Pp 1245The 1246.Nm 1247API was adopted from 1248.Nx 1249for use in the CAM SCSI subsystem. 1250The alterations to the original API were aimed to remove the need for 1251a 1252.Vt bus_dma_segment_t 1253array stored in each 1254.Vt bus_dmamap_t 1255while allowing callers to queue up on scarce resources. 1256.Sh AUTHORS 1257The 1258.Nm 1259interface was designed and implemented by 1260.An Jason R. Thorpe 1261of the Numerical Aerospace Simulation Facility, NASA Ames Research Center. 1262Additional input on the 1263.Nm 1264design was provided by 1265.An -nosplit 1266.An Chris Demetriou , 1267.An Charles Hannum , 1268.An Ross Harvey , 1269.An Matthew Jacob , 1270.An Jonathan Stone , 1271and 1272.An Matt Thomas . 1273.Pp 1274The 1275.Nm 1276interface in 1277.Fx 1278benefits from the contributions of 1279.An Justin T. Gibbs , 1280.An Peter Wemm , 1281.An Doug Rabson , 1282.An Matthew N. Dodd , 1283.An Sam Leffler , 1284.An Maxime Henrion , 1285.An Jake Burkholder , 1286.An Takahashi Yoshihiro , 1287.An Scott Long 1288and many others. 1289.Pp 1290This manual page was written by 1291.An Hiten M. Pandya 1292and 1293.An Justin T. Gibbs . 1294