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 January 27, 2018 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_dma_filter_t *filtfunc" "void *filtfuncarg" "bus_size_t maxsize" \ 100"int nsegments" "bus_size_t maxsegsz" "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_filter_t 174Client specified address filter having the format: 175.Bl -tag -width compact 176.It Ft int 177.Fn "client_filter" "void *filtarg" "bus_addr_t testaddr" 178.El 179.sp 180Address filters can be specified during tag creation to allow 181for devices who's DMA address restrictions cannot be specified 182by a single window. 183The 184.Fa filtarg 185is client specified during tag creation to be passed to all 186invocations of the callback. 187The 188.Fa testaddr 189argument contains a potential starting address of a DMA mapping. 190The filter function operates on the set of addresses from 191.Fa testaddr 192to 193.Ql trunc_page(testaddr) + PAGE_SIZE - 1 , 194inclusive. 195The filter function should return zero for any mapping in this range 196that can be accommodated by the device and non-zero otherwise. 197.It Vt bus_dma_segment_t 198A machine-dependent type that describes individual 199DMA segments. 200.Bd -literal 201 bus_addr_t ds_addr; 202 bus_size_t ds_len; 203.Ed 204.sp 205The 206.Fa ds_addr 207field contains the device visible address of the DMA segment, and 208.Fa ds_len 209contains the length of the DMA segment. 210Although the DMA segments returned by a mapping call will adhere to 211all restrictions necessary for a successful DMA operation, some conversion 212(e.g. a conversion from host byte order to the device's byte order) is 213almost always required when presenting segment information to the device. 214.It Vt bus_dmamap_t 215A machine-dependent opaque type describing an individual mapping. 216Multiple DMA maps can be associated with one DMA tag. 217.It Vt bus_dmamem_t 218A machine-dependent type that describes DMA memory created by 219.Fn bus_dmamem_coherent . 220.Bd -literal 221 bus_dma_tag_t dmem_tag; 222 bus_dmamap_t dmem_map; 223 void *dmem_addr; 224 bus_addr_t dmem_busaddr; 225.Ed 226.sp 227The 228.Fa dmem_tag 229field contains the DMA tag of the DMA memory and 230.Fa dmem_map 231field contains the DMA map of the DMA memory. 232The 233.Fa dmem_addr 234field points to the allocated DMA memory in kernel virtual address space. 235The 236.Fa dmem_busaddr 237field contains the device visible address of the DMA memory. 238.It Vt bus_dmamap_callback_t 239Client specified callback for receiving mapping information resulting from 240the load of a 241.Vt bus_dmamap_t 242via 243.Fn bus_dmamap_load 244or 245.Fn bus_dmamap_load_ccb . 246Callbacks are of the format: 247.Bl -tag -width compact 248.It Ft void 249.Fn "client_callback" "void *callback_arg" "bus_dma_segment_t *segs" \ 250"int nseg" "int error" 251.El 252.sp 253The 254.Fa callback_arg 255is the callback argument passed to dmamap load functions. 256The 257.Fa segs 258and 259.Fa nseg 260parameters describe an array of 261.Vt bus_dma_segment_t 262structures that represent the mapping. 263This array is only valid within the scope of the callback function. 264The success or failure of the mapping is indicated by the 265.Fa error 266parameter. 267More information on the use of callbacks can be found in the 268description of the individual dmamap load functions. 269.It Vt bus_dmamap_callback2_t 270Client specified callback for receiving mapping information resulting from 271the load of a 272.Vt bus_dmamap_t 273via 274.Fn bus_dmamap_load_uio 275or 276.Fn bus_dmamap_load_mbuf . 277.sp 278Callback2s are of the format: 279.Bl -tag -width compact 280.It Ft void 281.Fn "client_callback2" "void *callback_arg" "bus_dma_segment_t *segs" \ 282"int nseg" "bus_size_t mapsize" "int error" 283.El 284.sp 285Callback2's behavior is the same as 286.Vt bus_dmamap_callback_t 287with the addition that the length of the data mapped is provided via 288.Fa mapsize . 289.It Vt bus_dmasync_op_t 290Memory synchronization operation specifier. 291Bus DMA requires explicit synchronization of memory with it's device 292visible mapping in order to guarantee memory coherency. 293The 294.Vt bus_dmasync_op_t 295allows the type of DMA operation that will be or has been performed 296to be communicated to the system so that the correct coherency measures 297are taken. 298All operations specified below are performed from the DMA engine's 299point of view: 300.Bl -tag -width BUS_DMASYNC_POSTWRITE 301.It Dv BUS_DMASYNC_PREREAD 302Perform any synchronization required after an update of memory by the CPU 303but prior to DMA read operations. 304.It Dv BUS_DMASYNC_PREWRITE 305Perform any synchronization required after an update of memory by the CPU 306but prior to DMA write operations. 307.It Dv BUS_DMASYNC_POSTREAD 308Perform any synchronization required after DMA read operations, but prior 309to CPU access of the memory. 310.It Dv BUS_DMASYNC_POSTWRITE 311Perform any synchronization required after DMA write operations, but prior 312to CPU access of the memory. 313.El 314.El 315.sp 316.Sh FUNCTIONS 317.Bl -tag -width compact 318.It Fn bus_dma_tag_create "parent" "alignment" "boundary" "lowaddr" \ 319"highaddr" "*filtfunc" "*filtfuncarg" "maxsize" "nsegments" "maxsegsz" \ 320"flags" "*dmat" 321Allocates a device specific DMA tag, and initializes it according to 322the arguments provided: 323.Bl -tag -width *filtfuncarg -compact 324.It Fa parent 325Indicates restrictions between the parent bridge, CPU memory, and the 326device. 327May be NULL, if no DMA restrictions are to be inherited. 328.It Fa alignment 329Alignment constraint, in bytes, of any mappings created using this tag. 330The alignment must be a power of 2. 331Hardware that can DMA starting at any address would specify 332.Em 1 333for byte alignment. 334Hardware requiring DMA transfers to start on a multiple of 4K 335would specify 336.Em 4096 . 337.It Fa boundary 338Boundary constraint, in bytes, of the target DMA memory region. 339The boundary indicates the set of addresses, all multiples of the 340boundary argument, that cannot be crossed by a single 341.Vt bus_dma_segment_t . 342The boundary must be either a power of 2 or 0. 343.Ql 0 344indicates that there are no boundary restrictions. 345.It Fa lowaddr 346.It Fa highaddr 347Bounds of the window of bus address space that 348.Em cannot 349be directly accessed by the device. 350The window contains all address greater than lowaddr and 351less than or equal to highaddr. 352For example, a device incapable of DMA above 4GB, would specify 353a highaddr of 354.Dv BUS_SPACE_MAXADDR 355and a lowaddr of 356.Dv BUS_SPACE_MAXADDR_32BIT . 357Similarly a device that can only dma to addresses bellow 16MB would 358specify a highaddr of 359.Dv BUS_SPACE_MAXADDR 360and a lowaddr of 361.Dv BUS_SPACE_MAXADDR_24BIT . 362Some implementations requires that some region of device visible 363address space, overlapping available host memory, be outside the 364window. 365This area of 366.Ql safe memory 367is used to bounce requests that would otherwise conflict with 368the exclusion window. 369.It Fa filtfunc 370Optional filter function (may be NULL) to be called for any attempt to 371map memory into the window described by 372.Fa lowaddr 373and 374.Fa highaddr . 375A filter function is only required when the single window described 376by 377.Fa lowaddr 378and 379.Fa highaddr 380cannot adequately describe the constraints of the device. 381The filter function will be called for every machine page 382that overlaps the exclusion window. 383.It Fa filtfuncarg 384Argument passed to all calls to the filter function for this tag. 385May be NULL. 386.It Fa maxsize 387Maximum size, in bytes, of the sum of all segment lengths in a given 388DMA mapping associated with this tag. 389.It Fa nsegments 390Number of discontinuities (scatter/gather segments) allowed 391in a DMA mapped region. 392If there is no restriction, 393.Dv BUS_SPACE_UNRESTRICTED 394may be specified for the tag intended to be used as the parent. 395.Dv BUS_SPACE_UNRESTRICTED 396must not be specified for the tags 397which will be used to create maps. 398For tags which will be used to create maps, 399this argument must be less than 16384 on x86_64. 400.It Fa maxsegsz 401Maximum size, in bytes, of a segment in any DMA mapped region associated 402with 403.Fa dmat . 404.It Fa flags 405Are as follows: 406.Bl -tag -width ".Dv BUS_DMA_PRIVBZONE" -compact 407.It Dv BUS_DMA_ALLOCNOW 408Allocate the minimum resources necessary to guarantee that all map load 409operations associated with this tag may not block. 410If sufficient resources are not available, 411.Er ENOMEM 412is returned. 413.It Dv BUS_DMA_WAITOK 414Indicates that it is OK to wait for resources. 415However, 416unlike 417.Xr kmalloc 9 , 418it is not guaranteed that the resource allocation will succeed. 419This flag is the default one, 420if 421.Dv BUS_DMA_NOWAIT 422is not supplied. 423.It Dv BUS_DMA_NOWAIT 424If the resource allocation request cannot be immediately fulfilled, 425.Er ENOMEM 426is returned. 427.It Dv BUS_DMA_ONEBPAGE 428Allocte one bounce page at most, 429even if the 430.Fa maxsize 431indicates that multiple bounce pages are needed. 432.It Dv BUS_DMA_ALIGNED 433Indicates that all memory to be loaded into the DMA maps associated 434with this DMA tag is properly aligned according to 435.Fa alignment 436constraint. 437No resources, 438e.g. bounce pages, 439will be allocated due to the 440.Fa alignment 441constraint. 442If unaligned memory was loaded into the DMA maps associated with this DMA tag, 443system will panic. 444.It Dv BUS_DMA_PRIVBZONE 445Uses a private bounce zone instead of a shared one. 446A private bounce zone will vanish if the DMA tag is destroyed. 447.It Dv BUS_DMA_ALLOCALL 448Allocate all required resources (mainly the bounce buffer). 449If any allocation fails, 450.Fn bus_dma_tag_create 451fails. 452.It Dv BUS_DMA_PROTECTED 453All of the functions called with the DMA tag are already protected by the 454caller, so the 455.Nm 456code need not protect the internal data structures. 457.El 458.It Fa dmat 459Pointer to a bus_dma_tag_t where the resulting DMA tag will 460be stored. 461.El 462.Pp 463Returns 464.Er ENOMEM 465if sufficient memory is not available for tag creation 466or allocating mapping resources. 467.It Fn bus_dma_tag_destroy "dmat" 468Deallocate the DMA tag 469.Fa dmat 470that was created by 471.Fn bus_dma_tag_create . 472.Pp 473Returns 474.Er EBUSY 475if any DMA maps remain associated with 476.Fa dmat 477or 478.Ql 0 479on success. 480.It Fn bus_dmamap_create "dmat" "flags" "*mapp" 481Allocates and initializes a DMA map. 482Arguments are as follows: 483.Bl -tag -width nsegments -compact 484.It Fa dmat 485DMA tag. 486.It Fa flags 487Are as follows: 488.Bl -tag -width ".Dv BUS_DMA_ONEBPAGE" -compact 489.It Dv BUS_DMA_WAITOK 490Indicates that it is OK to wait for resources. 491However, 492unlike 493.Xr kmalloc 9 , 494it is not guaranteed that the resource allocation will succeed. 495This flag is the default one, 496if 497.Dv BUS_DMA_NOWAIT 498is not supplied. 499.It Dv BUS_DMA_NOWAIT 500If the resource allocation request cannot be immediately fulfilled, 501.Er ENOMEM 502is returned. 503.It Dv BUS_DMA_ONEBPAGE 504Allocte one bounce page at most, 505even if the 506.Fa maxsize 507used to create the 508.Fa dmat 509indicates that multiple bounce pages are needed. 510.El 511.It Fa mapp 512Pointer to a 513.Vt bus_dmamap_t 514where the resulting DMA map will be stored. 515.El 516.Pp 517Returns 518.Er ENOMEM 519if sufficient memory is not available for creating the 520map or allocating mapping resources. 521.It Fn bus_dmamap_destroy "dmat" "map" 522Frees all resources associated with a given DMA map. 523Arguments are as follows: 524.Bl -tag -width dmat -compact 525.It Fa dmat 526DMA tag used to allocate 527.Fa map . 528.It Fa map 529The DMA map to destroy. 530.El 531.Pp 532Returns 533.Er EBUSY 534if a mapping is still active for 535.Fa map . 536.It Fn bus_dmamap_load "dmat" "map" "buf" "buflen" "*callback" "..." 537Creates a mapping in device visible address space of 538.Fa buflen 539bytes of 540.Fa buf , 541associated with the DMA map 542.Fa map . 543Arguments are as follows: 544.Bl -tag -width buflen -compact 545.It Fa dmat 546DMA tag used to allocate 547.Fa map . 548.It Fa map 549A DMA map without a currently active mapping. 550.It Fa buf 551A kernel virtual address pointer to a contiguous (in KVA) buffer, to be 552mapped into device visible address space. 553.It Fa buflen 554The size of the buffer. 555.It Fa callback Fa callback_arg 556The callback function, and its argument. 557.It Fa flags 558The value of this argument is currently undefined, and should be 559specified as 560.Ql 0 . 561.El 562.Pp 563Return values to the caller are as follows: 564.Bl -tag -width ".Er EINPROGRESS" -compact 565.It 0 566The callback has been called and completed. 567The status of the mapping has been delivered to the callback. 568.It Er EINPROGRESS 569The mapping has been deferred for lack of resources. 570The callback will be called as soon as resources are available. 571Callbacks are serviced in FIFO order. 572DMA maps created from DMA tags that are allocated with 573the 574.Dv BUS_DMA_ALLOCNOW 575flag will never return this status for a load operation. 576.It Er EINVAL 577The load request was invalid. 578The callback has not, and will not be called. 579This error value may indicate that 580.Fa dmat , 581.Fa map , 582.Fa buf , 583or 584.Fa callback 585were invalid, or 586.Fa buslen 587was larger than the 588.Fa maxsize 589argument used to create the dma tag 590.Fa dmat . 591.El 592.Pp 593When the callback is called, it is presented with an error value 594indicating the disposition of the mapping. 595Error may be one of the following: 596.Bl -tag -width ".Er EINPROGRESS" -compact 597.It 0 598The mapping was successful and the 599.Fa dm_segs 600callback argument contains an array of 601.Vt bus_dma_segment_t 602elements describing the mapping. 603This array is only valid during the scope of the callback function. 604.It Er EFBIG 605A mapping could not be achieved within the segment constraints provided 606in the tag even though the requested allocation size was less than maxsize. 607.El 608.It Fn bus_dmamap_load_ccb "dmat" "map" "ccb" "callback" "callback_arg" "flags" 609This is a variation of 610.Fn bus_dmamap_load 611which maps data pointed to by 612.Fa ccb 613for DMA transfers. 614.It Fn bus_dmamap_load_mbuf "dmat" "map" "mbuf" "callback2" "callback_arg" \ 615"flags" 616This is a variation of 617.Fn bus_dmamap_load 618which maps mbuf chains 619for DMA transfers. 620A 621.Vt bus_size_t 622argument is also passed to the callback routine, which 623contains the mbuf chain's packet header length. 624.Pp 625Mbuf chains are assumed to be in kernel virtual address space. 626.Pp 627Returns 628.Er EINVAL 629if the size of the mbuf chain exceeds the maximum limit of the 630DMA tag. 631.It Fn bus_dmamap_load_mbuf_segment "dmat" "map" "mbuf" "*segs" "maxsegs" \ 632"*nsegs" "flags" 633It is like 634.Fn bus_dmamap_load_mbuf 635without callback. 636Segmentation information are saved in the 637.Fa segs 638and 639.Fa nsegs 640if the loading is successful. 641The 642.Fa maxsegs , 643which indicates the number of elements in the 644.Fa segs , 645must be set by the caller and must be at least 1 and at most equal the 646.Fa nsegments 647used to create the 648.Fa dmat . 649The 650.Fa flags 651must have 652.Dv BUS_DMA_NOWAIT 653turned on. 654.Pp 655This function will not block. 656When system is short of DMA resources, 657this function will return 658.Er ENOMEM , 659instead of 660.Er EINPROGRESS . 661.It Fn bus_dmamap_load_mbuf_defrag "dmat" "map" "*mbuf" "*segs" "maxsegs" \ 662"*nsegs" "flags" 663This function is like 664.Fn bus_dmamap_load_mbuf_segment , 665but it will call 666.Fn m_defrag 667on the 668.Fa *mbuf 669and try reloading, 670if low level code indicates too many fragments in the 671.Fa *mbuf ; 672the 673.Fa mbuf 674will be updated under this situation. 675However, 676.Fa *mbuf 677would not be freed by this function, 678even if 679.Fn m_defrag 680failed. 681.Pp 682Return 683.Er ENOBUFS , 684if the calling of 685.Fn m_defrag 686failed. 687.It Fn bus_dmamap_load_uio "dmat" "map" "uio" "callback2" "callback_arg" "flags" 688This is a variation of 689.Fn bus_dmamap_load 690which maps buffers pointed to by 691.Fa uio 692for DMA transfers. 693A 694.Vt bus_size_t 695argument is also passed to the callback routine, which contains the size of 696.Fa uio , 697i.e. 698.Fa uio->uio_resid . 699.Pp 700If 701.Fa uio->uio_segflg 702is 703.Dv UIO_USERSPACE , 704then it is assumed that the buffer, 705.Fa uio 706is in 707.Fa "uio->uio_td->td_proc" Ns 's 708address space. 709User space memory must be in-core and wired prior to attempting a map 710load operation. 711.It Fn bus_dmamap_unload "dmat" "map" 712Unloads a DMA map. 713Arguments are as follows: 714.Bl -tag -width dmam -compact 715.It Fa dmat 716DMA tag used to allocate 717.Fa map . 718.It Fa map 719The DMA map that is to be unloaded. 720.El 721.Pp 722.Fn bus_dmamap_unload 723will not perform any implicit synchronization of DMA buffers. 724This must be done explicitly by a call to 725.Fn bus_dmamap_sync 726prior to unloading the map. 727.It Fn bus_dmamap_sync "dmat" "map" "op" 728Performs synchronization of a device visible mapping with the CPU visible 729memory referenced by that mapping. 730Arguments are as follows: 731.Bl -tag -width dmat -compact 732.It Fa dmat 733DMA tag used to allocate 734.Fa map . 735.It Fa map 736The DMA mapping to be synchronized. 737.It Fa op 738Type of synchronization operation to perform. 739See the definition of 740.Vt bus_dmasync_op_t 741for a description of the acceptable values for 742.Fa op . 743.El 744.Pp 745.Fn bus_dmamap_sync 746is the method used to ensure that CPU and device DMA access to shared 747memory is coherent. 748For example, the CPU might be used to setup the contents of a buffer 749that is to be DMA'ed into a device. 750To ensure that the data are visible via the device's mapping of that 751memory, the buffer must be loaded and a dma sync operation of 752.Dv BUS_DMASYNC_PREREAD 753must be performed. 754Additional sync operations must be performed after every CPU write 755to this memory if additional DMA reads are to be performed. 756Conversely, for the DMA write case, the buffer must be loaded, 757and a dma sync operation of 758.Dv BUS_DMASYNC_PREWRITE 759must be performed. 760The CPU will only be able to see the results of this DMA write 761once the DMA has completed and a 762.Dv BUS_DMASYNC_POSTWRITE 763operation has been performed. 764.Pp 765If DMA read and write operations are not preceded and followed by the 766appropriate synchronization operations, behavior is undefined. 767.It Fn bus_dmamem_alloc "dmat" "**vaddr" "flags" "mapp" 768Allocates memory that is mapped into KVA at the address returned 769in 770.Fa vaddr 771that is permanently loaded into the newly created 772.Vt bus_dmamap_t 773returned via 774.Fa mapp . 775Arguments are as follows: 776.Bl -tag -width alignment -compact 777.It Fa dmat 778DMA tag describing the constraints of the DMA mapping. 779.It Fa vaddr 780Pointer to a pointer that will hold the returned KVA mapping of 781the allocated region. 782.It Fa flags 783Flags are defined as follows: 784.Bl -tag -width ".Dv BUS_DMA_COHERENT" -compact 785.It Dv BUS_DMA_WAITOK 786The routine can safely wait (sleep) for resources. 787.It Dv BUS_DMA_NOWAIT 788The routine is not allowed to wait for resources. 789If resources are not available, 790.Er ENOMEM 791is returned. 792.It Dv BUS_DMA_COHERENT 793Attempt to map this memory such that cache sync operations are 794as cheap as possible. 795This flag is typically set on memory that will be accessed by both 796a CPU and a DMA engine, frequently. 797Use of this flag does not remove the requirement of using 798bus_dmamap_sync, but it may reduce the cost of performing 799these operations. 800.It Dv BUS_DMA_ZERO 801Causes the allocated memory to be set to all zeros. 802.It Dv BUS_DMA_NOCACHE 803The allocated memory will not be cached in the processor caches. 804All memory accesses appear on the bus and are executed 805without reordering. 806On x86_64, the 807.Dv BUS_DMA_NOCACHE 808flag results in the 809Strong Uncacheable PAT to be set for the allocated virtual address range. 810.El 811.It Fa mapp 812Pointer to storage for the returned DMA map. 813.El 814.Pp 815The size of memory to be allocated is 816.Fa maxsize 817as specified in 818.Fa dmat . 819.Pp 820The current implementation of 821.Fn bus_dmamem_alloc 822will allocate all requests as a single segment. 823.Pp 824Although no explicit loading is required to access the memory 825referenced by the returned map, the synchronization requirements 826as described in the 827.Fn bus_dmamap_sync 828section still apply. 829.Pp 830Returns 831.Er ENOMEM 832if sufficient memory is not available for completing 833the operation. 834.It Fn bus_dmamem_coherent "parent" "alignment" "boundary" "lowaddr" \ 835"highaddr" "maxsize" "flags" "*dmem" 836This is a convenient function to create one segment of DMA memory. 837It combines following 838.Xr bus_dma 9 839function calls: 840.Bd -literal 841 bus_dma_tag_create(..., dtag); 842 bus_dmamem_alloc(*dtag, vaddr, ..., dmap); 843 bus_dmamap_load(*dtag, *dmap, *vaddr, ..., \\ 844 callback, busaddr, ...); 845.Ed 846.sp 847The final results of the above function calls are: 848DMA tag, 849DMA map, 850DMA memory's kernel virtual address and 851its device visible address. 852.Fn bus_dmamem_coherent 853saves the results in 854.Fa *dmem . 855.Pp 856The 857.Fa parent , 858.Fa alignment , 859.Fa boundary , 860.Fa lowaddr 861and 862.Fa highaddr 863will be passed to 864.Fn bus_dma_tag_create 865as they are. 866The 867.Fa maxsize 868will be passed to 869.Fn bus_dma_tag_create 870as its 871.Fa maxsize 872and 873.Fa maxsegsz 874and 875.Ql 1 876will be passed to 877.Fn bus_dma_tag_create 878as its 879.Fa nsegments . 880When 881.Fn bus_dmamem_alloc 882is called, 883.Fa flags 884will be first or'ed with 885.Dv BUS_DMA_COHERENT 886then passed to it. 887The final results of the above three functions, 888i.e. DMA tag, 889DMA map, 890DMA memory's kernel virtual address and 891its device visible address, 892are saved in 893.Fa *dmem . 894If any of the three functions failed, 895this function will return the error code and the 896.Fa *dmem 897should not be used. 898.It Fn bus_dmamem_coherent_any "parent" "alignment" "maxsize" "flags" \ 899"*dtag" "*dmap" "*busaddr" 900This function is a simplified version of 901.Fn bus_dmamem_coherent 902with 903its 904.Fa boundary 905set to 906.Ql 0 , 907.Fa lowaddr 908set to 909.Dv BUS_SPACE_MAXADDR 910and 911.Fa highaddr 912set to 913.Dv BUS_SPACE_MAXADDR . 914The 915.Fa parent 916usually should not be NULL. 917.Pp 918Return the DMA memory's kernel virtual address. 919The DMA tag, DMA map and device visible address are returned in 920.Fa *dtag , 921.Fa *dmap , 922and 923.Fa *busaddr . 924If this function failed, 925NULL will be returned; 926.Fa *dtag , 927.Fa *dmap , 928and 929.Fa *busaddr 930are left unchanged. 931.It Fn bus_dmamem_free "dmat" "*vaddr" "map" 932Frees memory previously allocated by 933.Fn bus_dmamem_alloc . 934Any mappings 935will be invalidated. 936Arguments are as follows: 937.Bl -tag -width vaddr -compact 938.It Fa dmat 939DMA tag. 940.It Fa vaddr 941Kernel virtual address of the memory. 942.It Fa map 943DMA map to be invalidated. 944.El 945.El 946.Sh RETURN VALUES 947Behavior is undefined if invalid arguments are passed to 948any of the above functions. 949If sufficient resources cannot be allocated for a given 950transaction, 951.Er ENOMEM 952is returned. 953All 954routines that are not of type, 955.Vt void , 956will return 0 on success or an error 957code, as discussed above. 958.Pp 959All 960.Vt void 961routines will succeed if provided with valid arguments. 962.Sh SEE ALSO 963.Xr devclass 9 , 964.Xr device 9 , 965.Xr driver 9 , 966.Xr rman 9 967.Rs 968.%A "Jason R. Thorpe" 969.%T "A Machine-Independent DMA Framework for NetBSD" 970.%J "Proceedings of the Summer 1998 USENIX Technical Conference" 971.%Q "USENIX Association" 972.%D "June 1998" 973.Re 974.Sh HISTORY 975The 976.Nm 977interface first appeared in 978.Nx 1.3 . 979.Pp 980The 981.Nm 982API was adopted from 983.Nx 984for use in the CAM SCSI subsystem. 985The alterations to the original API were aimed to remove the need for 986a 987.Vt bus_dma_segment_t 988array stored in each 989.Vt bus_dmamap_t 990while allowing callers to queue up on scarce resources. 991.Sh AUTHORS 992The 993.Nm 994interface was designed and implemented by 995.An Jason R. Thorpe 996of the Numerical Aerospace Simulation Facility, NASA Ames Research Center. 997Additional input on the 998.Nm 999design was provided by 1000.An -nosplit 1001.An Chris Demetriou , 1002.An Charles Hannum , 1003.An Ross Harvey , 1004.An Matthew Jacob , 1005.An Jonathan Stone , 1006and 1007.An Matt Thomas . 1008.Pp 1009This manual page was written by 1010.An Hiten Pandya 1011and 1012.An Justin T. Gibbs . 1013