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