1.\" $NetBSD: bus_dma.9,v 1.7 1997/11/11 10:06:50 mrg Exp $ 2.\" 3.\" Copyright (c) 1996, 1997 The NetBSD Foundation, Inc. 4.\" All rights reserved. 5.\" 6.\" This code is derived from software contributed to The NetBSD Foundation 7.\" by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 8.\" NASA Ames Research Center. 9.\" 10.\" Redistribution and use in source and binary forms, with or without 11.\" modification, are permitted provided that the following conditions 12.\" are met: 13.\" 1. Redistributions of source code must retain the above copyright 14.\" notice, this list of conditions and the following disclaimer. 15.\" 2. Redistributions in binary form must reproduce the above copyright 16.\" notice, this list of conditions and the following disclaimer in the 17.\" documentation and/or other materials provided with the distribution. 18.\" 3. All advertising materials mentioning features or use of this software 19.\" must display the following acknowledgment: 20.\" This product includes software developed by the NetBSD 21.\" Foundation, Inc. and its contributors. 22.\" 4. Neither the name of The NetBSD Foundation nor the names of its 23.\" contributors may be used to endorse or promote products derived 24.\" from this software without specific prior written permission. 25.\" 26.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36.\" POSSIBILITY OF SUCH DAMAGE. 37.\" 38.Dd Aug 11, 1997 39.Dt BUS_DMA 9 40.Os NetBSD 41.Sh NAME 42.Nm bus_dma , 43.Nm bus_dmamap_create , 44.Nm bus_dmamap_destroy , 45.Nm bus_dmamap_load , 46.Nm bus_dmamap_load_mbuf , 47.Nm bus_dmamap_load_uio , 48.Nm bus_dmamap_load_raw , 49.Nm bus_dmamap_unload , 50.Nm bus_dmamap_sync , 51.Nm bus_dmamem_alloc , 52.Nm bus_dmamem_free , 53.Nm bus_dmamem_map , 54.Nm bus_dmamem_unmap , 55.Nm bus_dmamem_mmap 56.Nd Bus and Machine Independent DMA Mapping Interface 57.Sh SYNOPSIS 58.Fd #include <machine/bus.h> 59.Ft int 60.Fn bus_dmamap_create "bus_dma_tag_t tag" "bus_size_t size" "int nsegments" \ 61"bus_size_t maxsegsz" "bus_size_t boundary" "int flags" "bus_dmamap_t *dmamp" 62.Ft void 63.Fn bus_dmamap_destroy "bus_dma_tag_t tag" "bus_dmamap_t dmam" 64.Ft int 65.Fn bus_dmamap_load "bus_dma_tag_t tag" "bus_dmamap_t dmam" "void *buf" \ 66"bus_size_t buflen" "struct proc *p" "int flags" 67.Ft int 68.Fn bus_dmamap_load_mbuf "bus_dma_tag_t tag" "bus_dmamap_t dmam" \ 69"struct mbuf *chain" "int flags" 70.Ft int 71.Fn bus_dmamap_load_uio "bus_dma_tag_t tag" "bus_dmamap_t dmam" \ 72"struct uio *uio" "int flags" 73.Ft int 74.Fn bus_dmamap_load_raw "bus_dma_tag_t tag" "bus_dmamap_t dmam" \ 75"bus_dma_segment_t *segs" "int nsegs" "bus_size_t size" "int flags" 76.Ft void 77.Fn bus_dmamap_unload "bus_dma_tag_t tag" "bus_dmamap_t dmam" 78.Ft void 79.Fn bus_dmamap_sync "bus_dma_tag_t tag" "bus_dmamap_t dmam" \ 80"bus_dmasync_op_t op" 81.Ft int 82.Fn bus_dmamem_alloc "bus_dma_tag_t tag" "bus_size_t size" \ 83"bus_size_t alignment" "bus_size_t boundary" "bus_dma_segment_t *segs" \ 84"int nsegs" "int *rsegs" "int flags" 85.Ft void 86.Fn bus_dmamem_free "bus_dma_tag_t tag" "bus_dma_segment_t *segs" "int nsegs" 87.Ft int 88.Fn bus_dmamem_map "bus_dma_tag_t tag" "bus_dma_segment_t *segs" "int nsegs" \ 89"size_t size" "caddr_t *kvap" "int flags" 90.Ft void 91.Fn bus_dmamem_unmap "bus_dma_tag_t tag" "caddr_t kva" "size_t size" 92.Ft int 93.Fn bus_dmamem_mmap "bus_dma_tag_t tag" "bus_dma_segment_t *segs" \ 94"int nsegs" "int off" "int prot" "int flags" 95.Sh DESCRIPTION 96Provide a bus- and machine-independent "DMA mapping interface." 97.Sh NOTES 98.Pp 99All data structures, function prototypes, and macros will be defined 100by the port-specific header 101.Pa Aq machine/bus.h . 102Note that this document 103assumes the existence of types already defined by the current "bus.h" 104interface. 105.Pp 106Unless otherwise noted, all function calls in this interface may be 107defined as 108.Xr cpp 1 109macros. 110.Sh DATA TYPES 111.Pp 112Individual implementations may name these structures whatever they 113wish, providing that the external representations are: 114.Bl -tag -width compact 115.It Fa bus_dma_tag_t 116A machine-dependent opaque type describing the implementation of 117DMA for a given bus. 118.It Fa bus_dma_segment_t 119A structure with at least the following members: 120.Bd -literal 121 bus_addr_t ds_addr; 122 bus_size_t ds_len; 123.Ed 124.sp 125The structure may have machine-dependent members and arbitrary layout. 126The values in 127.Fa ds_addr 128and 129.Fa ds_len 130are suitable for programming into 131DMA controller address and length registers. 132.It Fa bus_dmamap_t 133A pointer to a structure with at least the following members: 134.Bd -literal 135 bus_dma_segment_t *dm_segs; 136 int dm_nsegs; 137.Ed 138.sp 139The structure may have machine-dependent members and arbitrary layout. 140The 141.Fa dm_segs 142member may be an array of segments or a pointer to an 143array of segments. The 144.Fa dm_nsegs 145member indicates the number of segments in 146.Fa dm_segs . 147A value of 0 indicates the mapping is invalid. 148.It Fa bus_dmasync_op_t 149An enumerated type providing the following unique values: 150.Bd -literal 151 BUS_DMASYNC_PREREAD 152 BUS_DMASYNC_POSTREAD 153 BUS_DMASYNC_PREWRITE 154 BUS_DMASYNC_POSTWRITE 155.Ed 156.sp 157See 158.Fn bus_dmamap_sync 159for more details. 160.El 161.Sh FUNCTIONS 162.Bl -tag -width compact 163.It Fn bus_dmamap_create "tag" "size" "nsegments" "maxsegsz" "boundary" "flags" "dmamp" 164Allocates a DMA handle and initializes it according to the parameters 165provided. Arguments are as follows: 166.Bl -tag -width nsegments -compact 167.It Fa tag 168This is the bus_dma_tag_t passed down from the parent driver via 169.Fa <bus>_attach_args . 170.It Fa size 171This is the maximum DMA transfer that can be mapped by the handle. 172.It Fa nsegments 173Number of segments the device can support in a single DMA transaction. 174This may be the number of scatter-gather descriptors supported by the 175device. 176.It Fa maxsegsz 177The maximum number of bytes that may be transferred by any given DMA 178segment. 179.It Fa boundary 180Some DMA controllers are not able to transfer data that crosses a 181particular boundary. This argument allows this boundary to be 182specified. The boundary lines begin at 0, and occur every 183.Fa boundary 184bytes. Mappings may begin on a boundary line but may not end on or 185cross a boundary line. If no boundary condition needs to be observed, a 186.Fa boundary 187argument of 0 should be used. 188.It Fa flags 189Flags are defined as follows: 190.Bl -tag -width BUS_DMA_ALLOCNOW -compact 191.It Dv BUS_DMA_WAITOK 192It is safe to wait (sleep) for resources during this call. 193.It Dv BUS_DMA_NOWAIT 194It is not safe to wait (sleep) for resources during this call. 195.It Dv BUS_DMA_ALLOCNOW 196Perform any resource allocation this handle may need now. If this is 197not specified, the allocation may be deferred to 198.Fn bus_dmamap_load . 199If this flag is specified, 200.Fn bus_dmamap_load 201will not block on resource 202allocation. 203.It Dv BUS_DMA_BUS[1-4] 204These flags are placeholders, and may be used by busses to provide 205bus-dependent functionality. 206.El 207.It Fa dmamp 208This is a pointer to a bus_dmamap_t. A DMA map will be allocated and 209pointed to by 210.Fa dmamp 211upon successful completion of this routine. 212.El 213.Pp 214Behavior is not defined if invalid arguments are passed to 215.Fn bus_dmamap_create . 216.Pp 217Returns 0 on success, or an error code to indicate mode of failure. 218.It Fn bus_dmamap_destroy "tag" "dmam" 219Frees all resources associated with a given DMA handle. Arguments are 220as follows: 221.Bl -tag -width dmam -compact 222.It Fa tag 223This is the bus_dma_tag_t passed down from the parent driver via 224.Fa <bus>_attach_args . 225.It Fa dmam 226The DMA handle to destroy. 227.El 228.Pp 229In the event that the DMA handle contains a valid mapping, 230the mapping will be unloaded via the same mechanism used by 231.Fn bus_dmamap_unload . 232.Pp 233Behavior is not defined if invalid arguments are passed to 234.Fn bus_dmamap_destroy . 235.Pp 236If given valid arguments, 237.Fn bus_dmamap_destroy 238always succeeds. 239.It Fn bus_dmamap_load "tag" "dmam" "buf" "buflen" "p" "flags" 240Loads a DMA handle with mappings for a DMA transfer. It assumes that 241all pages involved in a DMA transfer are wired. Arguments are as follows: 242.Bl -tag -width buflen -compact 243.It Fa tag 244This is the bus_dma_tag_t passed down from the parent driver via 245.Fa <bus>_attach_args . 246.It Fa dmam 247The DMA handle with which to map the transfer. 248.It Fa buf 249The buffer to be used for the DMA transfer. 250.It Fa buflen 251The size of the buffer. 252.It Fa p 253Used to indicate the address space in which the buffer is located. If 254.Dv NULL , 255the buffer is assumed to be in kernel space. Otherwise, the 256buffer is assumed to be in process 257.Fa p Ns 's 258address space. 259.It Fa flags 260are defined as follows: 261.Bl -tag -width "BUS_DMA_BUS[1-4]" -compact 262.It Dv BUS_DMA_WAITOK 263It is safe to wait (sleep) for resources during this call. 264.It Dv BUS_DMA_NOWAIT 265It is not safe to wait (sleep) for resources during this call. 266.It Dv BUS_DMA_BUS[1-4] 267These flags are placeholders, and may be used by busses to 268provide bus-dependent functionality. 269.El 270.El 271.Pp 272As noted above, if a DMA handle is created with 273.Dv BUS_DMA_ALLOCNOW , 274.Fn bus_dmamap_load 275will never block. 276.Pp 277If a call to 278.Fn bus_dmamap_load 279fails, the mapping in 280the DMA handle will be invalid. It is the responsibility 281of the caller to clean up any inconsistent device state 282resulting from incomplete iteration through the uio. 283.Pp 284Behavior is not defined if invalid arguments are passed to 285.Fn bus_dmamap_load . 286.Pp 287Returns 0 on success, or an error code to indicate mode of failure. 288.It Fn bus_dmamap_load_mbuf "tag" "dmam" "chain" "flags" 289This is a variation of 290.Fn bus_dmamap_load 291which maps mbuf chains 292for DMA transfers. Mbuf chains are assumed to be in kernel 293virtual address space. 294.It Fn bus_dmamap_load_uio "tag" "dmam" "uio" "flags" 295This is a variation of 296.Fn bus_dmamap_load 297which maps buffers pointed to by 298.Fa uio 299for DMA transfers. The value of 300.Fa "uio->uio_segflg" 301will 302determine if the buffers are in user or kernel virtual address space. 303If the buffers are in user address space, the buffers are assumed to be 304in 305.Fa "uio->uio_procp" Ns 's 306address space. 307.It Fn bus_dmamap_load_raw "tag" "dmam" "segs" "nsegs" "size" "flags" 308This is a variation of 309.Fn bus_dmamap_load 310which maps buffers 311allocated by 312.Fn bus_dmamem_alloc 313(see below). The 314.Fa segs 315argument is an array of bus_dma_segment_t's filled in 316by 317.Fn bus_dmamem_alloc . 318The 319.Fa nsegs 320argument is the number of segments in the array. The 321.Fa size 322argument is the size of the DMA transfer. 323.It Fn bus_dmamap_unload "tag" "dmam" 324Deletes the mappings for a given DMA handle. Arguments are as follows: 325.Bl -tag -width dmam -compact 326.It Fa tag 327This is the bus_dma_tag_t passed down from the parent driver via 328.Fa <bus>_attach_args . 329.It Fa dmam 330The DMA handle containing the mappings which are to be deleted. 331.El 332.Pp 333If the DMA handle was created with 334.Dv BUS_DMA_ALLOCNOW , 335.Fn bus_dmamap_unload 336will not free the corresponding 337resources which were allocated by 338.Fn bus_dmamap_create . 339This is to ensure that 340.Fn bus_dmamap_load 341will never block 342on resources if the handle was created with 343.Dv BUS_DMA_ALLOCNOW . 344.Pp 345Behavior is not defined if invalid arguments are passed to 346.Fn bus_dmamap_unload . 347.Pp 348If given valid arguments, 349.Fn bus_dmamap_unload 350always succeeds. 351.It Fn bus_dmamap_sync "tag" "dmam" "op" 352Performs pre- and post-DMA operation cache and/or buffer synchronization. 353Arguments are as follows: 354.Bl -tag -width dmam -compact 355.It Fa tag 356This is the bus_dma_tag_t passed down from the parent driver via 357.Fa <bus>_attach_args . 358.It Fa dmam 359The DMA mapping to be synchronized. 360.It Fa op 361The synchronization operation to perform. The following DMA synchronization 362operations are defined: 363.Bl -tag -width BUS_DMASYNC_POSTWRITE -compact 364.It Dv BUS_DMASYNC_PREREAD 365Perform any pre-read DMA cache and/or bounce operations. 366.It Dv BUS_DMASYNC_POSTREAD 367Perform any post-read DMA cache and/or bounce operations. 368.It Dv BUS_DMASYNC_PREWRITE 369Perform any pre-write DMA cache and/or bounce operations. 370.It Dv BUS_DMASYNC_POSTWRITE 371Perform any post-write DMA cache and/or bounce operations. 372.El 373.El 374.Pp 375This function exists so that multiple read and write transfers can be 376performed with the same buffer, and so that drivers can explicitly 377inform the 378.Nm 379code when their data is 'ready' in its DMA buffer. 380.Pp 381An example of multiple read-write use of a single mapping 382might look like: 383.Bd -literal 384bus_dmamap_load(...); 385 386while (not done) { 387 /* invalidate soon-to-be-stale cache blocks */ 388 bus_dmamap_sync(..., BUS_DMASYNC_PREREAD); 389 390 [ do read DMA ] 391 392 /* copy from bounce */ 393 bus_dmamap_sync(..., BUS_DMASYNC_POSTREAD); 394 395 /* read data now in driver-provided buffer */ 396 397 [ computation ] 398 399 /* data to be written now in driver-provided buffer */ 400 401 /* flush write buffers and writeback, copy to bounce */ 402 bus_dmamap_sync(..., BUS_DMASYNC_PREWRITE); 403 404 [ do write DMA ] 405 406 /* probably a no-op, but provided for consistency */ 407 bus_dmamap_sync(..., BUS_DMASYNC_POSTWRITE); 408} 409 410bus_dmamap_unload(...); 411.Ed 412.Pp 413If DMA read and write operations are not preceded and followed by the 414appropriate synchronization operations, behavior is undefined. 415.Pp 416Behavior is not defined if invalid arguments are passed to 417.Fn bus_dmamap_sync . 418.Pp 419If given valid arguments, 420.Fn bus_dmamap_sync 421always succeeds. 422.\" XXX: This does not work with all the arguments. 423.It Fn bus_dmamem_alloc "tag" "size" "alignment" "boundary" "segs" "..." 424Allocates memory that is "DMA safe" for the bus corresponding to the 425given tag. The mapping of this memory is machine-dependent (or 426"opaque"); machine-independent code is not to assume that the 427addresses returned are valid in kernel virtual address space, or that 428the addresses returned are system physical addresses. 429.Pp 430Allocations will always be rounded to the hardware page size. Callers 431may wish to take advantage of this, and cluster allocation of small 432data structures. Arguments are as follows: 433.Bl -tag -width alignment -compact 434.It Fa tag 435The is the bus_dma_tag_t passed down from the parent driver via 436.Fa <bus>_attach_args . 437.It Fa size 438The amount of memory to allocate. 439.It Fa alignment 440Each segment in the allocated memory will be aligned to this value. If 441the alignment is less than a hardware page size, it will be rounded up 442to the hardware page size. This value must be a power of two. 443.It Fa boundary 444Each segment in the allocated memory must not cross this boundary 445(relative to zero). This value must be a power of two. A boundary 446value less than the size of the allocation is invalid. 447.It Fa segs 448An array of bus_dma_segment_t's, filled in as memory is allocated, 449representing the opaque addresses of the memory chunks. 450.It Fa nsegs 451Specifies the number of segments in 452.Fa segs , 453and this is the maximum number 454of segments that the allocated memory may contain. 455.It Fa rsegs 456Used to return the actual number of segments the memory contains. 457.It Fa flags 458Flags are defined as follows: 459.Bl -tag -width BUS_DMA_BUS[1-4] -compact 460.It Dv BUS_DMA_WAITOK 461It is safe to wait (sleep) for resources during this call. 462.It Dv BUS_DMA_NOWAIT 463It is not safe to wait (sleep) for resources during this call. 464.It Dv BUS_DMA_BUS[1-4] 465These flags are placeholders, and may be used by busses to provide 466bus-dependent functionality. 467.El 468.El 469.Pp 470All pages allocated by 471.Fn bus_dmamem_alloc 472will be wired down 473until they are freed by 474.Fn bus_dmamem_free . 475.Pp 476Behavior is undefined if invalid arguments are passed to 477.Fn bus_dmamem_alloc . 478.Pp 479Returns 0 on success, or an error code indicating mode of failure. 480.It Fn bus_dmamem_free "tag" "segs" "nsegs" 481Frees memory previously allocated by 482.Fn bus_dmamem_alloc . 483Any mappings 484will be invalidated. Arguments are as follows: 485.Bl -tag -width nsegs -compact 486.It Fa tag 487This is the bus_dma_tag_t passed down from the parent driver via 488.Fa <bus>_attach_args . 489.It Fa segs 490The array of bus_dma_segment_t's filled in by 491.Fn bus_dmamem_alloc . 492.It Fa nsegs 493The number of segments in 494.Fa segs . 495.El 496.Pp 497Behavior is undefined if invalid arguments are passed to 498.Fn bus_dmamem_free . 499.Pp 500If given valid arguments, 501.Fn bus_dmamem_free 502always succeeds. 503.It Fn bus_dmamem_map "tag" "segs" "nsegs" "size" "kvap" "flags" 504Maps memory allocated with 505.Fn bus_dmamem_alloc 506into kernel virtual address space. Arguments are as follows: 507.Bl -tag -width flags -compact 508.It Fa tag 509This is the bus_dma_tag_t passed down from the parent driver via 510.Fa <bus>_attach_args . 511.It Fa segs 512The array of bus_dma_segment_t's filled in by 513.Fn bus_dmamem_alloc , 514representing the memory regions to map. 515.It Fa nsegs 516The number of segments in 517.Fa segs . 518.It Fa size 519The size of the mapping. 520.It Fa kvap 521Filled in to specify the kernel virtual address where the memory is mapped. 522.It Fa flags 523Flags are defined as follows: 524.Bl -tag -width BUS_DMAMEM_NOSYNC -compact 525.It Dv BUS_DMA_WAITOK 526It is safe to wait (sleep) for resources during this call. 527.It Dv BUS_DMA_NOWAIT 528It is not safe to wait (sleep) for resources during this call. 529.It Dv BUS_DMA_BUS[1-4] 530These flags are placeholders, and may be used by busses to provide 531bus-dependent functionality. 532.It Dv BUS_DMAMEM_NOSYNC 533Map the memory in such a way that synchronization of the map with 534.Fn bus_dmamap_sync 535will not be required. This is especially useful in 536the case of descriptor blocks which are occasionally read/written by 537the device and host as a means of command/status communications, for 538which map synchronization would be unnecessarily expensive. This flag 539should be used with care. 540.El 541.El 542.Pp 543Behavior is undefined if invalid arguments are passed to 544.Fn bus_dmamem_map . 545.Pp 546Returns 0 on success, or an error code indicating mode of failure. 547.It Fn bus_dmamem_unmap "tag" "kva" "size" 548Unmaps memory previously mapped with 549.Fn bus_dmamem_map , 550freeing the 551kernel virtual address space used by the mapping. The arguments are as 552follows: 553.Bl -tag -width size -compact 554.It Fa tag 555This is the bus_dma_tag_t passed down from the parent driver via 556.Fa <bus>_attach_args . 557.It Fa kva 558The kernel virtual address of the mapped memory. 559.It Fa size 560The size of the mapping. 561.El 562.Pp 563Behavior is undefined if invalid arguments are passed to 564.Fn bus_dmamem_unmap . 565.Pp 566If given valid arguments, 567.Fn bus_dmamem_unmap 568always succeeds. 569.It Fn bus_dmamem_mmap "tag" "segs" "nsegs" "off" "prot" "flags" 570Provides support for user 571.Xr mmap 2 Ns 'ing 572of DMA-safe memory. This function is to be called by a device 573driver's (*d_mmap)() entry point, which is called by the 574device pager for each page to be mapped. The arguments are 575as follows: 576.Bl -tag -width nsegs -compact 577.It Fa tag 578This is the bus_dma_tag_t passed down from the parent driver via 579.Fa <bus>_attach_args . 580.It Fa segs 581The array of bus_dma_segment_t's filled in by 582.Fn bus_dmamem_alloc , 583representing the memory to be 584.Xr mmap 2 Ns 'ed. 585.It Fa nsegs 586The number of elements in the 587.Fa segs 588array. 589.It Fa off 590The offset of the page in DMA memory which is to be mapped. 591.It Fa prot 592The protection codes for the mapping. 593.It Fa flags 594Flags are defined as follows: 595.Bl -tag -width BUS_DMAMEM_NOSYNC -compact 596.It Dv BUS_DMA_WAITOK 597It is safe to wait (sleep) for resources during this call. 598.It Dv BUS_DMA_NOWAIT 599It is not safe to wait (sleep) for resources during this call. 600.It Dv BUS_DMA_BUS[1-4] 601These flags are placeholders, and may be used by busses to provide 602bus-dependent functionality. 603.It Dv BUS_DMAMEM_NOSYNC 604Map the memory in such a way that synchronization of the map with 605.Fn bus_dmamap_sync 606will not 607be required. This is especially useful in the case of descriptor 608blocks which are occasionally read/written by the device and host as a 609means of command/status communications, for which map synchronization 610would be unnecessarily expensive. This flag should be used with care. 611.El 612.El 613.Pp 614Behavior is undefined if invalid arguments are passed 615to 616.Fn bus_dmamem_mmap . 617.Pp 618Returns -1 to indicate failure. Otherwise, returns an opaque 619value to be interpreted by the device pager. 620.Sh SEE ALSO 621.Xr bus_space 9 622.Sh HISTORY 623A 624.Nm 625manual page appeared in 626.Nx 1.3 . 627