1.\" 2.\" Copyright (c) 2002, 2003, 2004 The DragonFly Project. All rights reserved. 3.\" 4.\" This code is derived from software contributed to The DragonFly Project 5.\" by Hiten Pandya <hmp@backplane.com>. 6.\" 7.\" Redistribution and use in source and binary forms, with or without 8.\" modification, are permitted provided that the following conditions 9.\" are met: 10.\" 11.\" 1. Redistributions of source code must retain the above copyright 12.\" notice, this list of conditions and the following disclaimer. 13.\" 2. Redistributions in binary form must reproduce the above copyright 14.\" notice, this list of conditions and the following disclaimer in 15.\" the documentation and/or other materials provided with the 16.\" distribution. 17.\" 3. Neither the name of The DragonFly Project nor the names of its 18.\" contributors may be used to endorse or promote products derived 19.\" from this software without specific, prior written permission. 20.\" 21.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23.\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 24.\" FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 25.\" COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26.\" INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 27.\" BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 29.\" AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 31.\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32.\" SUCH DAMAGE. 33.\" 34.\" Copyright (c) 1996, 1997, 1998, 2001 The NetBSD Foundation, Inc. 35.\" All rights reserved. 36.\" 37.\" This code is derived from software contributed to The NetBSD Foundation 38.\" by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 39.\" NASA Ames Research Center. 40.\" 41.\" Redistribution and use in source and binary forms, with or without 42.\" modification, are permitted provided that the following conditions 43.\" are met: 44.\" 1. Redistributions of source code must retain the above copyright 45.\" notice, this list of conditions and the following disclaimer. 46.\" 2. Redistributions in binary form must reproduce the above copyright 47.\" notice, this list of conditions and the following disclaimer in the 48.\" documentation and/or other materials provided with the distribution. 49.\" 3. All advertising materials mentioning features or use of this software 50.\" must display the following acknowledgment: 51.\" This product includes software developed by the NetBSD 52.\" Foundation, Inc. and its contributors. 53.\" 4. Neither the name of The NetBSD Foundation nor the names of its 54.\" contributors may be used to endorse or promote products derived 55.\" from this software without specific prior written permission. 56.\" 57.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 58.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 59.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 60.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 61.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 62.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 63.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 64.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 65.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 66.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 67.\" POSSIBILITY OF SUCH DAMAGE. 68.\" 69.\" $FreeBSD: /repoman/r/ncvs/src/share/man/man9/bus_dma.9,v 1.7 2003/07/27 14:05:29 mux Exp $ 70.\" $NetBSD: bus_dma.9,v 1.25 2002/10/14 13:43:16 wiz Exp $ 71.\" 72.Dd December 09, 2023 73.Dt BUS_DMA 9 74.Os 75.Sh NAME 76.Nm bus_dma , 77.Nm bus_dma_tag_create , 78.Nm bus_dma_tag_destroy , 79.Nm bus_dmamap_create , 80.Nm bus_dmamap_destroy , 81.Nm bus_dmamap_load , 82.Nm bus_dmamap_load_ccb , 83.Nm bus_dmamap_load_mbuf , 84.Nm bus_dmamap_load_mbuf_segment , 85.Nm bus_dmamap_load_mbuf_defrag , 86.Nm bus_dmamap_load_uio , 87.Nm bus_dmamap_unload , 88.Nm bus_dmamap_sync , 89.Nm bus_dmamem_alloc , 90.Nm bus_dmamem_coherent , 91.Nm bus_dmamem_coherent_any , 92.Nm bus_dmamem_free 93.Nd Bus and Machine Independent DMA Mapping Interface 94.Sh SYNOPSIS 95.In sys/bus.h 96.Ft int 97.Fn bus_dma_tag_create "bus_dma_tag_t parent" "bus_size_t alignment" \ 98"bus_size_t boundary" "bus_addr_t lowaddr" "bus_addr_t highaddr" \ 99"bus_size_t maxsize" "int nsegments" "bus_size_t maxsegsz" \ 100"int flags" "bus_dma_tag_t *dmat" 101.Ft int 102.Fn bus_dma_tag_destroy "bus_dma_tag_t dmat" 103.Ft int 104.Fn bus_dmamap_create "bus_dma_tag_t dmat" "int flags" "bus_dmamap_t *mapp" 105.Ft int 106.Fn bus_dmamap_destroy "bus_dma_tag_t dmat" "bus_dmamap_t map" 107.Ft int 108.Fn bus_dmamap_load "bus_dma_tag_t dmat" "bus_dmamap_t map" "void *buf" \ 109"bus_size_t buflen" "bus_dmamap_callback_t *callback" "void *callback_arg" \ 110"int flags" 111.Ft int 112.Fn bus_dmamap_load_ccb "bus_dma_tag_t dmat" "bus_dmamap_t map" \ 113"union ccb *ccb" "bus_dmamap_callback_t *callback" "void *callback_arg" \ 114"int flags" 115.Ft int 116.Fn bus_dmamap_load_mbuf "bus_dma_tag_t dmat" "bus_dmamap_t map" \ 117"struct mbuf *mbuf" "bus_dmamap_callback2_t *callback" "void *callback_arg" \ 118"int flags" 119.Ft int 120.Fn bus_dmamap_load_mbuf_segment "bus_dma_tag_t dmat" "bus_dmamap_t map" \ 121"struct mbuf *mbuf" "bus_dma_segment_t *segs" "int maxsegs" "int *nsegs" \ 122"int flags" 123.Ft int 124.Fn bus_dmamap_load_mbuf_defrag "bus_dma_tag_t dmat" "bus_dmamap_t map" \ 125"struct mbuf **mbuf" "bus_dma_segment_t *segs" "int maxsegs" "int *nsegs" \ 126"int flags" 127.Ft int 128.Fn bus_dmamap_load_uio "bus_dma_tag_t dmat" "bus_dmamap_t map" \ 129"struct uio *uio" "bus_dmamap_callback2_t *callback" "void *callback_arg" \ 130"int flags" 131.Ft int 132.Fn bus_dmamem_alloc "bus_dma_tag_t dmat" "void **vaddr" \ 133"int flags" "bus_dmamap_t *mapp" 134.Ft int 135.Fn bus_dmamem_coherent "bus_dma_tag_t parent" "bus_size_t alignment" \ 136"bus_size_t boundary" "bus_addr_t lowaddr" "bus_addr_t highaddr" \ 137"bus_size_t maxsize" "int flags" "bus_dmamem_t *dmem" 138.Ft void * 139.Fn bus_dmamem_coherent_any "bus_dma_tag_t parent" "bus_size_t alignment" \ 140"bus_size_t maxsize" "int flags" "bus_dma_tag_t *dtag" "bus_dmamap_t *dmap" \ 141"bus_addr_t *busaddr" 142.Ft void 143.Fn bus_dmamap_unload "bus_dma_tag_t dmat" "bus_dmamap_t map" 144.Ft void 145.Fn bus_dmamap_sync "bus_dma_tag_t dmat" "bus_dmamap_t map" \ 146"bus_dmasync_op_t op" 147.Ft void 148.Fn bus_dmamem_free "bus_dma_tag_t dmat" "void *vaddr" \ 149"bus_dmamap_t map" 150.Sh DESCRIPTION 151Direct Memory Access (DMA) is a method of transferring data 152without involving the CPU, thus providing higher performance. 153A DMA transaction can be achieved between device to memory, 154device to device, or memory to memory. 155.Pp 156The 157.Nm 158API is a bus, device, and machine-independent (MI) interface to 159DMA mechanisms. 160It provides the client with flexibility and simplicity by 161abstracting machine dependent issues like setting up 162DMA mappings, handling cache issues, bus specific features 163and limitations. 164.Sh STRUCTURES AND TYPES 165.Bl -tag -width compact 166.It Vt bus_dma_tag_t 167A machine-dependent (MD) opaque type that describes the 168characteristics of DMA transactions. 169DMA tags are organized into a hierarchy, with each child 170tag inheriting the restrictions of its parent. 171This allows all devices along the path of DMA transactions 172to contribute to the constraints of those transactions. 173.It Vt bus_dma_segment_t 174A machine-dependent type that describes individual 175DMA segments. 176.Bd -literal 177 bus_addr_t ds_addr; 178 bus_size_t ds_len; 179.Ed 180.sp 181The 182.Fa ds_addr 183field contains the device visible address of the DMA segment, and 184.Fa ds_len 185contains the length of the DMA segment. 186Although the DMA segments returned by a mapping call will adhere to 187all restrictions necessary for a successful DMA operation, some conversion 188(e.g. a conversion from host byte order to the device's byte order) is 189almost always required when presenting segment information to the device. 190.It Vt bus_dmamap_t 191A machine-dependent opaque type describing an individual mapping. 192Multiple DMA maps can be associated with one DMA tag. 193.It Vt bus_dmamem_t 194A machine-dependent type that describes DMA memory created by 195.Fn bus_dmamem_coherent . 196.Bd -literal 197 bus_dma_tag_t dmem_tag; 198 bus_dmamap_t dmem_map; 199 void *dmem_addr; 200 bus_addr_t dmem_busaddr; 201.Ed 202.sp 203The 204.Fa dmem_tag 205field contains the DMA tag of the DMA memory and 206.Fa dmem_map 207field contains the DMA map of the DMA memory. 208The 209.Fa dmem_addr 210field points to the allocated DMA memory in kernel virtual address space. 211The 212.Fa dmem_busaddr 213field contains the device visible address of the DMA memory. 214.It Vt bus_dmamap_callback_t 215Client specified callback for receiving mapping information resulting from 216the load of a 217.Vt bus_dmamap_t 218via 219.Fn bus_dmamap_load 220or 221.Fn bus_dmamap_load_ccb . 222Callbacks are of the format: 223.Bl -tag -width compact 224.It Ft void 225.Fn "client_callback" "void *callback_arg" "bus_dma_segment_t *segs" \ 226"int nseg" "int error" 227.El 228.sp 229The 230.Fa callback_arg 231is the callback argument passed to dmamap load functions. 232The 233.Fa segs 234and 235.Fa nseg 236parameters describe an array of 237.Vt bus_dma_segment_t 238structures that represent the mapping. 239This array is only valid within the scope of the callback function. 240The success or failure of the mapping is indicated by the 241.Fa error 242parameter. 243More information on the use of callbacks can be found in the 244description of the individual dmamap load functions. 245.It Vt bus_dmamap_callback2_t 246Client specified callback for receiving mapping information resulting from 247the load of a 248.Vt bus_dmamap_t 249via 250.Fn bus_dmamap_load_uio 251or 252.Fn bus_dmamap_load_mbuf . 253.sp 254Callback2s are of the format: 255.Bl -tag -width compact 256.It Ft void 257.Fn "client_callback2" "void *callback_arg" "bus_dma_segment_t *segs" \ 258"int nseg" "bus_size_t mapsize" "int error" 259.El 260.sp 261Callback2's behavior is the same as 262.Vt bus_dmamap_callback_t 263with the addition that the length of the data mapped is provided via 264.Fa mapsize . 265.It Vt bus_dmasync_op_t 266Memory synchronization operation specifier. 267Bus DMA requires explicit synchronization of memory with its device 268visible mapping in order to guarantee memory coherency. 269The 270.Vt bus_dmasync_op_t 271allows the type of DMA operation that will be or has been performed 272to be communicated to the system so that the correct coherency measures 273are taken. 274All operations specified below are performed from the DMA engine's 275point of view: 276.Bl -tag -width BUS_DMASYNC_POSTWRITE 277.It Dv BUS_DMASYNC_PREREAD 278Perform any synchronization required after an update of memory by the CPU 279but prior to DMA read operations. 280.It Dv BUS_DMASYNC_PREWRITE 281Perform any synchronization required after an update of memory by the CPU 282but prior to DMA write operations. 283.It Dv BUS_DMASYNC_POSTREAD 284Perform any synchronization required after DMA read operations, but prior 285to CPU access of the memory. 286.It Dv BUS_DMASYNC_POSTWRITE 287Perform any synchronization required after DMA write operations, but prior 288to CPU access of the memory. 289.El 290.El 291.sp 292.Sh FUNCTIONS 293.Bl -tag -width compact 294.It Fn bus_dma_tag_create "parent" "alignment" "boundary" "lowaddr" \ 295"highaddr" "maxsize" "nsegments" "maxsegsz" "flags" "*dmat" 296Allocates a device specific DMA tag, and initializes it according to 297the arguments provided: 298.Bl -tag -width alignment -compact 299.It Fa parent 300Indicates restrictions between the parent bridge, CPU memory, and the 301device. 302May be NULL, if no DMA restrictions are to be inherited. 303.It Fa alignment 304Alignment constraint, in bytes, of any mappings created using this tag. 305The alignment must be a power of 2. 306Hardware that can DMA starting at any address would specify 307.Em 1 308for byte alignment. 309Hardware requiring DMA transfers to start on a multiple of 4K 310would specify 311.Em 4096 . 312.It Fa boundary 313Boundary constraint, in bytes, of the target DMA memory region. 314The boundary indicates the set of addresses, all multiples of the 315boundary argument, that cannot be crossed by a single 316.Vt bus_dma_segment_t . 317The boundary must be either a power of 2 or 0. 318.Ql 0 319indicates that there are no boundary restrictions. 320.It Fa lowaddr 321.It Fa highaddr 322Bounds of the window of bus address space that 323.Em cannot 324be directly accessed by the device. 325The window contains all address greater than lowaddr and 326less than or equal to highaddr. 327For example, a device incapable of DMA above 4GB, would specify 328a highaddr of 329.Dv BUS_SPACE_MAXADDR 330and a lowaddr of 331.Dv BUS_SPACE_MAXADDR_32BIT . 332Similarly a device that can only dma to addresses below 16MB would 333specify a highaddr of 334.Dv BUS_SPACE_MAXADDR 335and a lowaddr of 336.Dv BUS_SPACE_MAXADDR_24BIT . 337Some implementations requires that some region of device visible 338address space, overlapping available host memory, be outside the 339window. 340This area of 341.Ql safe memory 342is used to bounce requests that would otherwise conflict with 343the exclusion window. 344.It Fa maxsize 345Maximum size, in bytes, of the sum of all segment lengths in a given 346DMA mapping associated with this tag. 347.It Fa nsegments 348Number of discontinuities (scatter/gather segments) allowed 349in a DMA mapped region. 350If there is no restriction, 351.Dv BUS_SPACE_UNRESTRICTED 352may be specified for the tag intended to be used as the parent. 353.Dv BUS_SPACE_UNRESTRICTED 354must not be specified for the tags 355which will be used to create maps. 356For tags which will be used to create maps, 357this argument must be less than 16384 on x86_64. 358.It Fa maxsegsz 359Maximum size, in bytes, of a segment in any DMA mapped region associated 360with 361.Fa dmat . 362.It Fa flags 363Are as follows: 364.Bl -tag -width ".Dv BUS_DMA_PRIVBZONE" -compact 365.It Dv BUS_DMA_ALLOCNOW 366Allocate the minimum resources necessary to guarantee that all map load 367operations associated with this tag may not block. 368If sufficient resources are not available, 369.Er ENOMEM 370is returned. 371.It Dv BUS_DMA_WAITOK 372Indicates that it is OK to wait for resources. 373However, 374unlike 375.Xr kmalloc 9 , 376it is not guaranteed that the resource allocation will succeed. 377This flag is the default one, 378if 379.Dv BUS_DMA_NOWAIT 380is not supplied. 381.It Dv BUS_DMA_NOWAIT 382If the resource allocation request cannot be immediately fulfilled, 383.Er ENOMEM 384is returned. 385.It Dv BUS_DMA_ONEBPAGE 386Allocte one bounce page at most, 387even if the 388.Fa maxsize 389indicates that multiple bounce pages are needed. 390.It Dv BUS_DMA_ALIGNED 391Indicates that all memory to be loaded into the DMA maps associated 392with this DMA tag is properly aligned according to 393.Fa alignment 394constraint. 395No resources, 396e.g. bounce pages, 397will be allocated due to the 398.Fa alignment 399constraint. 400If unaligned memory was loaded into the DMA maps associated with this DMA tag, 401system will panic. 402.It Dv BUS_DMA_PRIVBZONE 403Uses a private bounce zone instead of a shared one. 404A private bounce zone will vanish if the DMA tag is destroyed. 405.It Dv BUS_DMA_ALLOCALL 406Allocate all required resources (mainly the bounce buffer). 407If any allocation fails, 408.Fn bus_dma_tag_create 409fails. 410.It Dv BUS_DMA_PROTECTED 411All of the functions called with the DMA tag are already protected by the 412caller, so the 413.Nm 414code need not protect the internal data structures. 415.El 416.It Fa dmat 417Pointer to a bus_dma_tag_t where the resulting DMA tag will 418be stored. 419.El 420.Pp 421Returns 422.Er ENOMEM 423if sufficient memory is not available for tag creation 424or allocating mapping resources. 425.It Fn bus_dma_tag_destroy "dmat" 426Deallocate the DMA tag 427.Fa dmat 428that was created by 429.Fn bus_dma_tag_create . 430.Pp 431Returns 432.Er EBUSY 433if any DMA maps remain associated with 434.Fa dmat 435or 436.Ql 0 437on success. 438.It Fn bus_dmamap_create "dmat" "flags" "*mapp" 439Allocates and initializes a DMA map. 440Arguments are as follows: 441.Bl -tag -width nsegments -compact 442.It Fa dmat 443DMA tag. 444.It Fa flags 445Are as follows: 446.Bl -tag -width ".Dv BUS_DMA_ONEBPAGE" -compact 447.It Dv BUS_DMA_WAITOK 448Indicates that it is OK to wait for resources. 449However, 450unlike 451.Xr kmalloc 9 , 452it is not guaranteed that the resource allocation will succeed. 453This flag is the default one, 454if 455.Dv BUS_DMA_NOWAIT 456is not supplied. 457.It Dv BUS_DMA_NOWAIT 458If the resource allocation request cannot be immediately fulfilled, 459.Er ENOMEM 460is returned. 461.It Dv BUS_DMA_ONEBPAGE 462Allocte one bounce page at most, 463even if the 464.Fa maxsize 465used to create the 466.Fa dmat 467indicates that multiple bounce pages are needed. 468.El 469.It Fa mapp 470Pointer to a 471.Vt bus_dmamap_t 472where the resulting DMA map will be stored. 473.El 474.Pp 475Returns 476.Er ENOMEM 477if sufficient memory is not available for creating the 478map or allocating mapping resources. 479.It Fn bus_dmamap_destroy "dmat" "map" 480Frees all resources associated with a given DMA map. 481Arguments are as follows: 482.Bl -tag -width dmat -compact 483.It Fa dmat 484DMA tag used to allocate 485.Fa map . 486.It Fa map 487The DMA map to destroy. 488.El 489.Pp 490Returns 491.Er EBUSY 492if a mapping is still active for 493.Fa map . 494.It Fn bus_dmamap_load "dmat" "map" "buf" "buflen" "*callback" "..." 495Creates a mapping in device visible address space of 496.Fa buflen 497bytes of 498.Fa buf , 499associated with the DMA map 500.Fa map . 501Arguments are as follows: 502.Bl -tag -width buflen -compact 503.It Fa dmat 504DMA tag used to allocate 505.Fa map . 506.It Fa map 507A DMA map without a currently active mapping. 508.It Fa buf 509A kernel virtual address pointer to a contiguous (in KVA) buffer, to be 510mapped into device visible address space. 511.It Fa buflen 512The size of the buffer. 513.It Fa callback Fa callback_arg 514The callback function, and its argument. 515.It Fa flags 516The value of this argument is currently undefined, and should be 517specified as 518.Ql 0 . 519.El 520.Pp 521Return values to the caller are as follows: 522.Bl -tag -width ".Er EINPROGRESS" -compact 523.It 0 524The callback has been called and completed. 525The status of the mapping has been delivered to the callback. 526.It Er EINPROGRESS 527The mapping has been deferred for lack of resources. 528The callback will be called as soon as resources are available. 529Callbacks are serviced in FIFO order. 530DMA maps created from DMA tags that are allocated with 531the 532.Dv BUS_DMA_ALLOCNOW 533flag will never return this status for a load operation. 534.It Er EINVAL 535The load request was invalid. 536The callback has not, and will not be called. 537This error value may indicate that 538.Fa dmat , 539.Fa map , 540.Fa buf , 541or 542.Fa callback 543were invalid, or 544.Fa buslen 545was larger than the 546.Fa maxsize 547argument used to create the dma tag 548.Fa dmat . 549.El 550.Pp 551When the callback is called, it is presented with an error value 552indicating the disposition of the mapping. 553Error may be one of the following: 554.Bl -tag -width ".Er EINPROGRESS" -compact 555.It 0 556The mapping was successful and the 557.Fa dm_segs 558callback argument contains an array of 559.Vt bus_dma_segment_t 560elements describing the mapping. 561This array is only valid during the scope of the callback function. 562.It Er EFBIG 563A mapping could not be achieved within the segment constraints provided 564in the tag even though the requested allocation size was less than maxsize. 565.El 566.It Fn bus_dmamap_load_ccb "dmat" "map" "ccb" "callback" "callback_arg" "flags" 567This is a variation of 568.Fn bus_dmamap_load 569which maps data pointed to by 570.Fa ccb 571for DMA transfers. 572.It Fn bus_dmamap_load_mbuf "dmat" "map" "mbuf" "callback2" "callback_arg" \ 573"flags" 574This is a variation of 575.Fn bus_dmamap_load 576which maps mbuf chains 577for DMA transfers. 578A 579.Vt bus_size_t 580argument is also passed to the callback routine, which 581contains the mbuf chain's packet header length. 582.Pp 583Mbuf chains are assumed to be in kernel virtual address space. 584.Pp 585Returns 586.Er EINVAL 587if the size of the mbuf chain exceeds the maximum limit of the 588DMA tag. 589.It Fn bus_dmamap_load_mbuf_segment "dmat" "map" "mbuf" "*segs" "maxsegs" \ 590"*nsegs" "flags" 591It is like 592.Fn bus_dmamap_load_mbuf 593without callback. 594Segmentation information are saved in the 595.Fa segs 596and 597.Fa nsegs 598if the loading is successful. 599The 600.Fa maxsegs , 601which indicates the number of elements in the 602.Fa segs , 603must be set by the caller and must be at least 1 and at most equal the 604.Fa nsegments 605used to create the 606.Fa dmat . 607The 608.Fa flags 609must have 610.Dv BUS_DMA_NOWAIT 611turned on. 612.Pp 613This function will not block. 614When system is short of DMA resources, 615this function will return 616.Er ENOMEM , 617instead of 618.Er EINPROGRESS . 619.It Fn bus_dmamap_load_mbuf_defrag "dmat" "map" "*mbuf" "*segs" "maxsegs" \ 620"*nsegs" "flags" 621This function is like 622.Fn bus_dmamap_load_mbuf_segment , 623but it will call 624.Fn m_defrag 625on the 626.Fa *mbuf 627and try reloading, 628if low level code indicates too many fragments in the 629.Fa *mbuf ; 630the 631.Fa mbuf 632will be updated under this situation. 633However, 634.Fa *mbuf 635would not be freed by this function, 636even if 637.Fn m_defrag 638failed. 639.Pp 640Return 641.Er ENOBUFS , 642if the calling of 643.Fn m_defrag 644failed. 645.It Fn bus_dmamap_load_uio "dmat" "map" "uio" "callback2" "callback_arg" "flags" 646This is a variation of 647.Fn bus_dmamap_load 648which maps buffers pointed to by 649.Fa uio 650for DMA transfers. 651A 652.Vt bus_size_t 653argument is also passed to the callback routine, which contains the size of 654.Fa uio , 655i.e. 656.Fa uio->uio_resid . 657.Pp 658If 659.Fa uio->uio_segflg 660is 661.Dv UIO_USERSPACE , 662then it is assumed that the buffer, 663.Fa uio 664is in 665.Fa "uio->uio_td->td_proc" Ns 's 666address space. 667User space memory must be in-core and wired prior to attempting a map 668load operation. 669.It Fn bus_dmamap_unload "dmat" "map" 670Unloads a DMA map. 671Arguments are as follows: 672.Bl -tag -width dmam -compact 673.It Fa dmat 674DMA tag used to allocate 675.Fa map . 676.It Fa map 677The DMA map that is to be unloaded. 678.El 679.Pp 680.Fn bus_dmamap_unload 681will not perform any implicit synchronization of DMA buffers. 682This must be done explicitly by a call to 683.Fn bus_dmamap_sync 684prior to unloading the map. 685.It Fn bus_dmamap_sync "dmat" "map" "op" 686Performs synchronization of a device visible mapping with the CPU visible 687memory referenced by that mapping. 688Arguments are as follows: 689.Bl -tag -width dmat -compact 690.It Fa dmat 691DMA tag used to allocate 692.Fa map . 693.It Fa map 694The DMA mapping to be synchronized. 695.It Fa op 696Type of synchronization operation to perform. 697See the definition of 698.Vt bus_dmasync_op_t 699for a description of the acceptable values for 700.Fa op . 701.El 702.Pp 703.Fn bus_dmamap_sync 704is the method used to ensure that CPU and device DMA access to shared 705memory is coherent. 706For example, the CPU might be used to setup the contents of a buffer 707that is to be DMA'ed into a device. 708To ensure that the data are visible via the device's mapping of that 709memory, the buffer must be loaded and a dma sync operation of 710.Dv BUS_DMASYNC_PREREAD 711must be performed. 712Additional sync operations must be performed after every CPU write 713to this memory if additional DMA reads are to be performed. 714Conversely, for the DMA write case, the buffer must be loaded, 715and a dma sync operation of 716.Dv BUS_DMASYNC_PREWRITE 717must be performed. 718The CPU will only be able to see the results of this DMA write 719once the DMA has completed and a 720.Dv BUS_DMASYNC_POSTWRITE 721operation has been performed. 722.Pp 723If DMA read and write operations are not preceded and followed by the 724appropriate synchronization operations, behavior is undefined. 725.It Fn bus_dmamem_alloc "dmat" "**vaddr" "flags" "mapp" 726Allocates memory that is mapped into KVA at the address returned 727in 728.Fa vaddr 729that is permanently loaded into the newly created 730.Vt bus_dmamap_t 731returned via 732.Fa mapp . 733Arguments are as follows: 734.Bl -tag -width alignment -compact 735.It Fa dmat 736DMA tag describing the constraints of the DMA mapping. 737.It Fa vaddr 738Pointer to a pointer that will hold the returned KVA mapping of 739the allocated region. 740.It Fa flags 741Flags are defined as follows: 742.Bl -tag -width ".Dv BUS_DMA_COHERENT" -compact 743.It Dv BUS_DMA_WAITOK 744The routine can safely wait (sleep) for resources. 745.It Dv BUS_DMA_NOWAIT 746The routine is not allowed to wait for resources. 747If resources are not available, 748.Er ENOMEM 749is returned. 750.It Dv BUS_DMA_COHERENT 751Attempt to map this memory such that cache sync operations are 752as cheap as possible. 753This flag is typically set on memory that will be accessed by both 754a CPU and a DMA engine, frequently. 755Use of this flag does not remove the requirement of using 756bus_dmamap_sync, but it may reduce the cost of performing 757these operations. 758.It Dv BUS_DMA_ZERO 759Causes the allocated memory to be set to all zeros. 760.It Dv BUS_DMA_NOCACHE 761The allocated memory will not be cached in the processor caches. 762All memory accesses appear on the bus and are executed 763without reordering. 764On x86_64, the 765.Dv BUS_DMA_NOCACHE 766flag results in the 767Strong Uncacheable PAT to be set for the allocated virtual address range. 768.El 769.It Fa mapp 770Pointer to storage for the returned DMA map. 771.El 772.Pp 773The size of memory to be allocated is 774.Fa maxsize 775as specified in 776.Fa dmat . 777.Pp 778The current implementation of 779.Fn bus_dmamem_alloc 780will allocate all requests as a single segment. 781.Pp 782Although no explicit loading is required to access the memory 783referenced by the returned map, the synchronization requirements 784as described in the 785.Fn bus_dmamap_sync 786section still apply. 787.Pp 788Returns 789.Er ENOMEM 790if sufficient memory is not available for completing 791the operation. 792.It Fn bus_dmamem_coherent "parent" "alignment" "boundary" "lowaddr" \ 793"highaddr" "maxsize" "flags" "*dmem" 794This is a convenient function to create one segment of DMA memory. 795It combines following 796.Nm 797function calls: 798.Bd -literal 799 bus_dma_tag_create(..., dtag); 800 bus_dmamem_alloc(*dtag, vaddr, ..., dmap); 801 bus_dmamap_load(*dtag, *dmap, *vaddr, ..., \\ 802 callback, busaddr, ...); 803.Ed 804.sp 805The final results of the above function calls are: 806DMA tag, 807DMA map, 808DMA memory's kernel virtual address and 809its device visible address. 810.Fn bus_dmamem_coherent 811saves the results in 812.Fa *dmem . 813.Pp 814The 815.Fa parent , 816.Fa alignment , 817.Fa boundary , 818.Fa lowaddr 819and 820.Fa highaddr 821will be passed to 822.Fn bus_dma_tag_create 823as they are. 824The 825.Fa maxsize 826will be passed to 827.Fn bus_dma_tag_create 828as its 829.Fa maxsize 830and 831.Fa maxsegsz 832and 833.Ql 1 834will be passed to 835.Fn bus_dma_tag_create 836as its 837.Fa nsegments . 838When 839.Fn bus_dmamem_alloc 840is called, 841.Fa flags 842will be first or'ed with 843.Dv BUS_DMA_COHERENT 844then passed to it. 845The final results of the above three functions, 846i.e. DMA tag, 847DMA map, 848DMA memory's kernel virtual address and 849its device visible address, 850are saved in 851.Fa *dmem . 852If any of the three functions failed, 853this function will return the error code and the 854.Fa *dmem 855should not be used. 856.It Fn bus_dmamem_coherent_any "parent" "alignment" "maxsize" "flags" \ 857"*dtag" "*dmap" "*busaddr" 858This function is a simplified version of 859.Fn bus_dmamem_coherent 860with 861its 862.Fa boundary 863set to 864.Ql 0 , 865.Fa lowaddr 866set to 867.Dv BUS_SPACE_MAXADDR 868and 869.Fa highaddr 870set to 871.Dv BUS_SPACE_MAXADDR . 872The 873.Fa parent 874usually should not be NULL. 875.Pp 876Return the DMA memory's kernel virtual address. 877The DMA tag, DMA map and device visible address are returned in 878.Fa *dtag , 879.Fa *dmap , 880and 881.Fa *busaddr . 882If this function failed, 883NULL will be returned; 884.Fa *dtag , 885.Fa *dmap , 886and 887.Fa *busaddr 888are left unchanged. 889.It Fn bus_dmamem_free "dmat" "*vaddr" "map" 890Frees memory previously allocated by 891.Fn bus_dmamem_alloc . 892Any mappings 893will be invalidated. 894Arguments are as follows: 895.Bl -tag -width vaddr -compact 896.It Fa dmat 897DMA tag. 898.It Fa vaddr 899Kernel virtual address of the memory. 900.It Fa map 901DMA map to be invalidated. 902.El 903.El 904.Sh RETURN VALUES 905Behavior is undefined if invalid arguments are passed to 906any of the above functions. 907If sufficient resources cannot be allocated for a given 908transaction, 909.Er ENOMEM 910is returned. 911All 912routines that are not of type, 913.Vt void , 914will return 0 on success or an error 915code, as discussed above. 916.Pp 917All 918.Vt void 919routines will succeed if provided with valid arguments. 920.Sh SEE ALSO 921.Xr devclass 9 , 922.Xr device 9 , 923.Xr driver 9 , 924.Xr rman 9 925.Rs 926.%A "Jason R. Thorpe" 927.%T "A Machine-Independent DMA Framework for NetBSD" 928.%J "Proceedings of the Summer 1998 USENIX Technical Conference" 929.%Q "USENIX Association" 930.%D "June 1998" 931.Re 932.Sh HISTORY 933The 934.Nm 935interface first appeared in 936.Nx 1.3 . 937.Pp 938The 939.Nm 940API was adopted from 941.Nx 942for use in the CAM SCSI subsystem. 943The alterations to the original API were aimed to remove the need for 944a 945.Vt bus_dma_segment_t 946array stored in each 947.Vt bus_dmamap_t 948while allowing callers to queue up on scarce resources. 949.Sh AUTHORS 950The 951.Nm 952interface was designed and implemented by 953.An Jason R. Thorpe 954of the Numerical Aerospace Simulation Facility, NASA Ames Research Center. 955Additional input on the 956.Nm 957design was provided by 958.An -nosplit 959.An Chris Demetriou , 960.An Charles Hannum , 961.An Ross Harvey , 962.An Matthew Jacob , 963.An Jonathan Stone , 964and 965.An Matt Thomas . 966.Pp 967This manual page was written by 968.An Hiten Pandya 969and 970.An Justin T. Gibbs . 971