diff options
author | Kenneth R Westerback <krw@cvs.openbsd.org> | 2001-02-22 00:54:47 +0000 |
---|---|---|
committer | Kenneth R Westerback <krw@cvs.openbsd.org> | 2001-02-22 00:54:47 +0000 |
commit | b5cd940a0ec734f98f208284a70ffd3952550bf7 (patch) | |
tree | ec6e88101ec4154901bf3676afccdc190a21a096 /share/man/man9/bus_space.9 | |
parent | 4ca1941340e804aa98e951511e1087fe94ae4627 (diff) |
First attempt at bringing in bus_space.9 from NetBSD.
Changes from NetBSD bus_space.9 v1.15:
1) All references to the following functions were '.\"'d out:
bus_space_read_raw_multi_1
bus_space_read_raw_region_1
bus_space_read_stream_1
bus_space_read_stream_2
bus_space_read_stream_4
bus_space_read_stream_8
bus_space_vaddr
bus_space_write_raw_multi_1
bus_space_write_raw_region_1
bus_space_write_stream_1
bus_space_write_stream_2
bus_space_write_stream_4
bus_space_write_stream_8
2) All references to the following defines were '.\"'d out:
BUS_SPACE_MAP_PREFETCHABLE
BUS_SPACE_MAP_LINEAR
3) The entire COMPATIBILITY section with its discussion of of
__BUS_SPACE_COMPAT_OLDDEFS was deleted as __BUS_SPACE_COMPAT_OLDDEFS
does not seem to be used at all anywhere in the tree.
4) Added the already documented bus_space_alloc() to list of functions
at head of page
5) Added bus_space_set_multi_N(t,h,o,v,c) definitions and descriptions
6) Renamed bus_space_copy_region_N to bus_space_copy_N
7) Replaced *_stream_* documentation with *_raw_* documentation
8) Rename the parameter 'flags' in bus_space_map and bus_space_alloc
to 'cacheable' as that's the only flag we provide. Other more
descriptive parameter names were retained rather than change to
terse one/two letter parameter names used in bus.h
9) Eliminated short lines, made all new sentences start
on new line, deleted extraneous .Pp's, removed some excess
parenthesis, trailing white space, etc.
** Issues with bus_space.9 **
vax/bus.h and mac68k/bus.h still define
bus_space_copy_region_N()
instead of
bus_space_copy_N
like other architectures, though some of the comments do refer to
bus_space_copy_N.
powerpc/bus.h still defines
bus_space_read_raw_multi_1()
bus_space_write_raw_multi_1()
vax/bus.h still defines
BUS_SPACE_MAP_PREFETCHABLE
while vax/bus.h and mac68k/bus.h both still define
BUS_SPACE_MAP_LINEAR
Diffstat (limited to 'share/man/man9/bus_space.9')
-rw-r--r-- | share/man/man9/bus_space.9 | 1509 |
1 files changed, 1509 insertions, 0 deletions
diff --git a/share/man/man9/bus_space.9 b/share/man/man9/bus_space.9 new file mode 100644 index 00000000000..ec61b60ca58 --- /dev/null +++ b/share/man/man9/bus_space.9 @@ -0,0 +1,1509 @@ +.\" $OpenBSD: bus_space.9,v 1.3 2001/02/22 00:54:46 krw Exp $ +.\" $NetBSD: bus_space.9,v 1.15 2000/08/09 03:11:00 tv Exp $ +.\" +.\" Copyright (c) 1997 The NetBSD Foundation, Inc. +.\" All rights reserved. +.\" +.\" This code is derived from software contributed to The NetBSD Foundation +.\" by Christopher G. Demetriou. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgment: +.\" This product includes software developed by the NetBSD +.\" Foundation, Inc. and its contributors. +.\" 4. Neither the name of The NetBSD Foundation nor the names of its +.\" contributors may be used to endorse or promote products derived +.\" from this software without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +.\" POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd November 20, 2000 +.Dt BUS_SPACE 9 +.Os +.Sh NAME +.Nm bus_space , +.Nm bus_space_alloc , +.Nm bus_space_barrier , +.Nm bus_space_copy_1 , +.Nm bus_space_copy_2 , +.Nm bus_space_copy_4 , +.Nm bus_space_copy_8 , +.Nm bus_space_free , +.Nm bus_space_map , +.Nm bus_space_read_1 , +.Nm bus_space_read_2 , +.Nm bus_space_read_4 , +.Nm bus_space_read_8 , +.Nm bus_space_read_multi_1 , +.Nm bus_space_read_multi_2 , +.Nm bus_space_read_multi_4 , +.Nm bus_space_read_multi_8 , +.\".Nm bus_space_read_raw_multi_1 , +.Nm bus_space_read_raw_multi_2 , +.Nm bus_space_read_raw_multi_4 , +.Nm bus_space_read_raw_multi_8 , +.Nm bus_space_read_region_1 , +.Nm bus_space_read_region_2 , +.Nm bus_space_read_region_4 , +.Nm bus_space_read_region_8 , +.\".Nm bus_space_read_raw_region_1 , +.Nm bus_space_read_raw_region_2 , +.Nm bus_space_read_raw_region_4 , +.Nm bus_space_read_raw_region_8 , +.\".Nm bus_space_read_stream_1 , +.\".Nm bus_space_read_stream_2 , +.\".Nm bus_space_read_stream_4 , +.\".Nm bus_space_read_stream_8 , +.Nm bus_space_set_multi_1 , +.Nm bus_space_set_multi_2 , +.Nm bus_space_set_multi_4 , +.Nm bus_space_set_multi_8 , +.Nm bus_space_set_region_1 , +.Nm bus_space_set_region_2 , +.Nm bus_space_set_region_4 , +.Nm bus_space_set_region_8 , +.Nm bus_space_subregion , +.Nm bus_space_unmap , +.\".Nm bus_space_vaddr , +.Nm bus_space_write_1 , +.Nm bus_space_write_2 , +.Nm bus_space_write_4 , +.Nm bus_space_write_8 , +.Nm bus_space_write_multi_1 , +.Nm bus_space_write_multi_2 , +.Nm bus_space_write_multi_4 , +.Nm bus_space_write_multi_8 , +.\".Nm bus_space_write_raw_multi_1 , +.Nm bus_space_write_raw_multi_2 , +.Nm bus_space_write_raw_multi_4 , +.Nm bus_space_write_raw_multi_8 , +.Nm bus_space_write_region_1 , +.Nm bus_space_write_region_2 , +.Nm bus_space_write_region_4 , +.Nm bus_space_write_region_8 +.\".Nm bus_space_write_raw_region_1 , +.Nm bus_space_write_raw_region_2 , +.Nm bus_space_write_raw_region_4 , +.Nm bus_space_write_raw_region_8 , +.\".Nm bus_space_write_stream_1 , +.\".Nm bus_space_write_stream_2 , +.\".Nm bus_space_write_stream_4 , +.\".Nm bus_space_write_stream_8 , +.Nd bus space manipulation functions +.Sh SYNOPSIS +.Fd #include <machine/bus.h> +.Ft int +.Fn bus_space_map "bus_space_tag_t space" "bus_addr_t address" \ +"bus_size_t size" "int cacheable" "bus_space_handle_t *handlep" +.Ft void +.Fn bus_space_unmap "bus_space_tag_t space" "bus_space_handle_t handle" \ +"bus_size_t size" +.Ft int +.Fn bus_space_subregion "bus_space_tag_t space" "bus_space_handle_t handle" \ +"bus_size_t offset" "bus_size_t size" "bus_space_handle_t *nhandlep" +.Ft int +.Fo bus_space_alloc +.Fa "bus_space_tag_t space" "bus_addr_t reg_start" "bus_addr_t reg_end" +.Fa "bus_size_t size" "bus_size_t alignment" "bus_size_t boundary" +.Fa "int cacheable" "bus_addr_t *addrp" "bus_space_handle_t *handlep" +.Fc +.Ft void +.Fn bus_space_free "bus_space_tag_t space" "bus_space_handle_t handle" \ +"bus_size_t size" +.\".Ft void * +.\".Fn bus_space_vaddr "bus_space_tag_t space" "bus_space_handle_t handle" +.Ft u_int8_t +.Fn bus_space_read_1 "bus_space_tag_t space" "bus_space_handle_t handle" \ +"bus_size_t offset" +.Ft u_int16_t +.Fn bus_space_read_2 "bus_space_tag_t space" "bus_space_handle_t handle" \ +"bus_size_t offset" +.Ft u_int32_t +.Fn bus_space_read_4 "bus_space_tag_t space" "bus_space_handle_t handle" \ +"bus_size_t offset" +.Ft u_int64_t +.Fn bus_space_read_8 "bus_space_tag_t space" "bus_space_handle_t handle" \ +"bus_size_t offset" +.Ft void +.Fn bus_space_write_1 "bus_space_tag_t space" "bus_space_handle_t handle" \ +"bus_size_t offset" "u_int8_t value" +.Ft void +.Fn bus_space_write_2 "bus_space_tag_t space" "bus_space_handle_t handle" \ +"bus_size_t offset" "u_int16_t value" +.Ft void +.Fn bus_space_write_4 "bus_space_tag_t space" "bus_space_handle_t handle" \ +"bus_size_t offset" "u_int32_t value" +.Ft void +.Fn bus_space_write_8 "bus_space_tag_t space" "bus_space_handle_t handle" \ +"bus_size_t offset" "u_int64_t value" +.Ft void +.Fn bus_space_barrier "bus_space_tag_t space" "bus_space_handle_t handle" \ +"bus_size_t offset" "bus_size_t length" "int flags" +.Ft void +.Fn bus_space_read_region_1 "bus_space_tag_t space" \ +"bus_space_handle_t handle" "bus_size_t offset" "u_int8_t *datap" \ +"bus_size_t count" +.Ft void +.Fn bus_space_read_region_2 "bus_space_tag_t space" \ +"bus_space_handle_t handle" "bus_size_t offset" "u_int16_t *datap" \ +"bus_size_t count" +.Ft void +.Fn bus_space_read_region_4 "bus_space_tag_t space" \ +"bus_space_handle_t handle" "bus_size_t offset" "u_int32_t *datap" \ +"bus_size_t count" +.Ft void +.Fn bus_space_read_region_8 "bus_space_tag_t space" \ +"bus_space_handle_t handle" "bus_size_t offset" "u_int64_t *datap" \ +"bus_size_t count" +.\".Ft void +.\".Fn bus_space_read_raw_region_1 "bus_space_tag_t space" \ +.\""bus_space_handle_t handle" "bus_size_t offset" "u_int8_t *datap" \ +.\""bus_size_t count" +.Ft void +.Fn bus_space_read_raw_region_2 "bus_space_tag_t space" \ +"bus_space_handle_t handle" "bus_size_t offset" "u_int8_t *datap" \ +"bus_size_t count" +.Ft void +.Fn bus_space_read_raw_region_4 "bus_space_tag_t space" \ +"bus_space_handle_t handle" "bus_size_t offset" "u_int8_t *datap" \ +"bus_size_t count" +.Ft void +.Fn bus_space_read_raw_region_8 "bus_space_tag_t space" \ +"bus_space_handle_t handle" "bus_size_t offset" "u_int8_t *datap" \ +"bus_size_t count" +.Ft void +.Fn bus_space_write_region_1 "bus_space_tag_t space" \ +"bus_space_handle_t handle" "bus_size_t offset" "const u_int8_t *datap" \ +"bus_size_t count" +.Ft void +.Fn bus_space_write_region_2 "bus_space_tag_t space" \ +"bus_space_handle_t handle" "bus_size_t offset" "const u_int16_t *datap" \ +"bus_size_t count" +.Ft void +.Fn bus_space_write_region_4 "bus_space_tag_t space" \ +"bus_space_handle_t handle" "bus_size_t offset" "const u_int32_t *datap" \ +"bus_size_t count" +.Ft void +.Fn bus_space_write_region_8 "bus_space_tag_t space" \ +"bus_space_handle_t handle" "bus_size_t offset" "const u_int64_t *datap" \ +"bus_size_t count" +.\".Ft void +.\".Fn bus_space_write_raw_region_1 "bus_space_tag_t space" \ +.\""bus_space_handle_t handle" "bus_size_t offset" "const u_int8_t *datap" \ +.\""bus_size_t count" +.Ft void +.Fn bus_space_write_raw_region_2 "bus_space_tag_t space" \ +"bus_space_handle_t handle" "bus_size_t offset" "const u_int8_t *datap" \ +"bus_size_t count" +.Ft void +.Fn bus_space_write_raw_region_4 "bus_space_tag_t space" \ +"bus_space_handle_t handle" "bus_size_t offset" "const u_int8_t *datap" \ +"bus_size_t count" +.Ft void +.Fn bus_space_write_raw_region_8 "bus_space_tag_t space" \ +"bus_space_handle_t handle" "bus_size_t offset" "const u_int8_t *datap" \ +"bus_size_t count" +.Ft void +.Fn bus_space_copy_1 "bus_space_tag_t space" \ +"bus_space_handle_t srchandle" "bus_size_t srcoffset" \ +"bus_space_handle_t dsthandle" "bus_size_t dstoffset" "bus_size_t count" +.Ft void +.Fn bus_space_copy_2 "bus_space_tag_t space" \ +"bus_space_handle_t srchandle" "bus_size_t srcoffset" \ +"bus_space_handle_t dsthandle" "bus_size_t dstoffset" "bus_size_t count" +.Ft void +.Fn bus_space_copy_4 "bus_space_tag_t space" \ +"bus_space_handle_t srchandle" "bus_size_t srcoffset" \ +"bus_space_handle_t dsthandle" "bus_size_t dstoffset" "bus_size_t count" +.Ft void +.Fn bus_space_copy_8 "bus_space_tag_t space" \ +"bus_space_handle_t srchandle" "bus_size_t srcoffset" \ +"bus_space_handle_t dsthandle" "bus_size_t dstoffset" "bus_size_t count" +.Ft void +.Fn bus_space_set_multi_1 "bus_space_tag_t space" \ +"bus_space_handle_t handle" "bus_size_t offset" "u_int8_t value" \ +"bus_size_t count" +.Ft void +.Fn bus_space_set_multi_2 "bus_space_tag_t space" \ +"bus_space_handle_t handle" "bus_size_t offset" "u_int16_t value" \ +"bus_size_t count" +.Ft void +.Fn bus_space_set_multi_4 "bus_space_tag_t space" \ +"bus_space_handle_t handle" "bus_size_t offset" "u_int32_t value" \ +"bus_size_t count" +.Ft void +.Fn bus_space_set_multi_8 "bus_space_tag_t space" \ +"bus_space_handle_t handle" "bus_size_t offset" "u_int64_t value" \ +"bus_size_t count" +.Ft void +.Fn bus_space_set_region_1 "bus_space_tag_t space" \ +"bus_space_handle_t handle" "bus_size_t offset" "u_int8_t value" \ +"bus_size_t count" +.Ft void +.Fn bus_space_set_region_2 "bus_space_tag_t space" \ +"bus_space_handle_t handle" "bus_size_t offset" "u_int16_t value" \ +"bus_size_t count" +.Ft void +.Fn bus_space_set_region_4 "bus_space_tag_t space" \ +"bus_space_handle_t handle" "bus_size_t offset" "u_int32_t value" \ +"bus_size_t count" +.Ft void +.Fn bus_space_set_region_8 "bus_space_tag_t space" \ +"bus_space_handle_t handle" "bus_size_t offset" "u_int64_t value" \ +"bus_size_t count" +.Ft void +.Fn bus_space_read_multi_1 "bus_space_tag_t space" \ +"bus_space_handle_t handle" "bus_size_t offset" "u_int8_t *datap" \ +"bus_size_t count" +.Ft void +.Fn bus_space_read_multi_2 "bus_space_tag_t space" \ +"bus_space_handle_t handle" "bus_size_t offset" "u_int16_t *datap" \ +"bus_size_t count" +.Ft void +.Fn bus_space_read_multi_4 "bus_space_tag_t space" \ +"bus_space_handle_t handle" "bus_size_t offset" "u_int32_t *datap" \ +"bus_size_t count" +.Ft void +.Fn bus_space_read_multi_8 "bus_space_tag_t space" \ +"bus_space_handle_t handle" "bus_size_t offset" "u_int64_t *datap" \ +"bus_size_t count" +.\".Ft void +.\".Fn bus_space_read_raw_multi_1 "bus_space_tag_t space" \ +.\""bus_space_handle_t handle" "bus_size_t offset" "u_int8_t *datap" \ +.\""bus_size_t count" +.Ft void +.Fn bus_space_read_raw_multi_2 "bus_space_tag_t space" \ +"bus_space_handle_t handle" "bus_size_t offset" "u_int8_t *datap" \ +"bus_size_t count" +.Ft void +.Fn bus_space_read_raw_multi_4 "bus_space_tag_t space" \ +"bus_space_handle_t handle" "bus_size_t offset" "u_int8_t *datap" \ +"bus_size_t count" +.Ft void +.Fn bus_space_read_raw_multi_8 "bus_space_tag_t space" \ +"bus_space_handle_t handle" "bus_size_t offset" "u_int8_t *datap" \ +"bus_size_t count" +.Ft void +.Fn bus_space_write_multi_1 "bus_space_tag_t space" \ +"bus_space_handle_t handle" "bus_size_t offset" "const u_int8_t *datap" \ +"bus_size_t count" +.Ft void +.Fn bus_space_write_multi_2 "bus_space_tag_t space" \ +"bus_space_handle_t handle" "bus_size_t offset" "const u_int16_t *datap" \ +"bus_size_t count" +.Ft void +.Fn bus_space_write_multi_4 "bus_space_tag_t space" \ +"bus_space_handle_t handle" "bus_size_t offset" "const u_int32_t *datap" \ +"bus_size_t count" +.Ft void +.Fn bus_space_write_multi_8 "bus_space_tag_t space" \ +"bus_space_handle_t handle" "bus_size_t offset" "const u_int64_t *datap" \ +"bus_size_t count" +.\".Ft void +.\".Fn bus_space_write_raw_multi_1 "bus_space_tag_t space" \ +.\""bus_space_handle_t handle" "bus_size_t offset" "const u_int8_t *datap" \ +.\""bus_size_t count" +.Ft void +.Fn bus_space_write_raw_multi_2 "bus_space_tag_t space" \ +"bus_space_handle_t handle" "bus_size_t offset" "const u_int8_t *datap" \ +"bus_size_t count" +.Ft void +.Fn bus_space_write_raw_multi_4 "bus_space_tag_t space" \ +"bus_space_handle_t handle" "bus_size_t offset" "const u_int8_t *datap" \ +"bus_size_t count" +.Ft void +.Fn bus_space_write_raw_multi_8 "bus_space_tag_t space" \ +"bus_space_handle_t handle" "bus_size_t offset" "const u_int8_t *datap" \ +"bus_size_t count" +.Sh DESCRIPTION +The +.Nm +functions exist to allow device drivers machine-independent access to +bus memory and register areas. +All of the functions and types described in this document can be used by +including the +.Pa Aq machine/bus.h +header file. +.Pp +Many common devices are used on multiple architectures, but are accessed +differently on each because of architectural constraints. +For instance, a device which is mapped in one systems's I/O space may be +mapped in memory space on a second system. +On a third system, architectural limitations might change the way +registers need to be accessed (e.g. creating a non-linear register +space). +In some cases, a single driver may need to access the same type of +device in multiple ways in a single system or architecture. +The goal of the +.Nm +functions is to allow a single driver source file to manipulate a set of +devices on different system architectures, and to allow a single driver +object file to manipulate a set of devices on multiple bus types on a +single architecture. +.Pp +Not all busses have to implement all functions described in this +document, though that is encouraged if the operations are logically +supported by the bus. +Unimplemented functions should cause compile-time errors if possible. +.Pp +All of the interface definitions described in this document are shown as +function prototypes and discussed as if they were required to be +functions. +Implementations are encouraged to implement prototyped (type-checked) +versions of these interfaces, but may implement them as macros if +appropriate. +Machine-dependent types, variables, and functions should be marked +clearly in +.Pa Aq machine/bus.h +to avoid confusion with the machine-independent types and functions, +and, if possible, should be given names which make the +machine-dependence clear. +.Sh CONCEPTS AND GUIDELINES +Bus spaces are described by bus space tags, which can be created only by +machine-dependent code. +A given machine may have several different types of bus space (e.g. +memory space and I/O space), and thus may provide multiple different bus +space tags. +Individual busses or devices on a machine may use more than one bus +space tag. +For instance, ISA devices are given an ISA memory space tag and an ISA +I/O space tag. +Architectures may have several different tags which represent the same +type of space, for instance because of multiple different host bus +interface chipsets. +.Pp +A range in bus space is described by a bus address and a bus size. +The bus address describes the start of the range in bus space. +The bus size describes the size of the range in bytes. +Busses which are not byte addressable may require use of bus space +ranges with appropriately aligned addresses and properly rounded sizes. +.Pp +Access to regions of bus space is facilitated by use of bus space +handles, which are usually created by mapping a specific range of a bus +space. +Handles may also be created by allocating and mapping a range of bus +space, the actual location of which is picked by the implementation +within bounds specified by the caller of the allocation function. +.Pp +All of the bus space access functions require one bus space tag +argument, at least one handle argument, and at least one offset argument +(a bus size). +The bus space tag specifies the space, each handle specifies a region in +the space, and each offset specifies the offset into the region of the +actual location(s) to be accessed. +Offsets are given in bytes, though busses may impose alignment constraints. +The offset used to access data relative to a given handle must be such +that all of the data being accessed is in the mapped region that the +handle describes. +Trying to access data outside that region is an error. +.Pp +Because some architectures' memory systems use buffering to improve +memory and device access performance, there is a mechanism which can be +used to create +.Dq barriers +in the bus space read and write stream. +There are three types of barriers: read, write, and read/write. +All reads started to the region before a read barrier must complete +before any reads after the read barrier are started. +The analogous requirement is true for write barriers. +Read/write barriers force all reads and writes started before the +barrier to complete before any reads or writes after the barrier are +started. +Correctly-written drivers will include all appropriate barriers, and +assume only the read/write ordering imposed by the barrier operations. +.Pp +People trying to write portable drivers with the +.Nm +functions should try to make minimal assumptions about what the system +allows. +In particular, they should expect that the system requires bus space +addresses being accessed to be naturally aligned (i.e. base address of +handle added to offset is a multiple of the access size), and that the +system does alignment checking on pointers (i.e. pointer to objects +being read and written must point to properly-aligned data). +.Pp +The descriptions of the +.Nm +functions given below all assume that they are called with proper +arguments. +If called with invalid arguments or arguments that are out of range +(e.g. trying to access data outside of the region mapped when a given +handle was created), undefined behaviour results. +In that case, they may cause the system to halt, either intentionally +(via panic) or unintentionally (by causing a fatal trap of by some other +means) or may cause improper operation which is not immediately fatal. +Functions which return void or which return data read from bus space +(i.e., functions which don't obviously return an error code) do not +fail. +They could only fail if given invalid arguments, and in that case their +behaviour is undefined. +Functions which take a count of bytes have undefined results if the +specified +.Fa count +is zero. +.Sh TYPES +Several types are defined in +.Pa Aq machine/bus.h +to facilitate use of the +.Nm +functions by drivers. +.Pp +.Bl -ohang -compact +.It Fa bus_addr_t +.Pp +The +.Fa bus_addr_t +type is used to describe bus addresses. +It must be an unsigned integral type capable of holding the largest bus +address usable by the architecture. +This type is primarily used when mapping and unmapping bus space. +.Pp +.It Fa bus_size_t +.Pp +The +.Fa bus_size_t +type is used to describe sizes of ranges in bus space. +It must be an unsigned integral type capable of holding the size of the +largest bus address range usable on the architecture. +This type is used by virtually all of the +.Nm +functions, describing sizes when mapping regions and offsets into +regions when performing space access operations. +.Pp +.It Fa bus_space_tag_t +.Pp +The +.Fa bus_space_tag_t +type is used to describe a particular bus space on a machine. +Its contents are machine-dependent and should be considered opaque by +machine-independent code. +This type is used by all +.Nm +functions to name the space on which they're operating. +.Pp +.It Fa bus_space_handle_t +.Pp +The +.Fa bus_space_handle_t +type is used to describe a mapping of a range of bus space. +Its contents are machine-dependent and should be considered opaque by +machine-independent code. +This type is used when performing bus space access operations. +.El +.Sh MAPPING AND UNMAPPING BUS SPACE +Bus space must be mapped before it can be used, and should be unmapped +when it is no longer needed. +The +.Fn bus_space_map +and +.Fn bus_space_unmap +functions provide these capabilities. +.Pp +Some drivers need to be able to pass a subregion of already-mapped bus +space to another driver or module within a driver. +The +.Fn bus_space_subregion +function allows such subregions to be created. +.Pp +.Bl -ohang -compact +.It Fn bus_space_map "space" "address" "size" "cacheable" "handlep" +.Pp +The +.Fn bus_space_map +function maps the region of bus space named by the +.Fa space , +.Fa address , +and +.Fa size +arguments. +If successful, it returns zero and fills in the bus space handle pointed +to by +.Fa handlep +with the handle that can be used to access the mapped region. +If unsuccessful, it will return non-zero and leave the bus space handle +pointed to by +.Fa handlep +in an undefined state. +.Pp +The +.Fa cacheable +argument controls how the space is to be mapped. +Supported flags include: +.Bl -tag -width BUS_SPACE_MAP_CACHEABLE -offset indent +.It Dv BUS_SPACE_MAP_CACHEABLE +Try to map the space so that accesses can be cached by the system cache. +If this flag is not specified, the implementation should map the space +so that it will not be cached. +This mapping method will only be useful in very rare occasions. +.Pp +This flag must have a value of 1 on all implementations for backward +compatibility. +.\".It Dv BUS_SPACE_MAP_PREFETCHABLE +.\"Try to map the space so that accesses can be prefetched by the system, +.\"and writes can be buffered. +.\"This means, accesses should be side effect free (idempotent). +.\"The +.\".Fn bus_space_barrier +.\"methods will flush the write buffer or force actual read accesses. +.\"If this flag is not specified, the +.\"implementation should map the space so that it will not be prefetched +.\"or delayed. +.\".It Dv BUS_SPACE_MAP_LINEAR +.\"Try to map the space so that its contents can be accessed linearly via +.\"normal memory access methods (e.g. pointer dereferencing and structure +.\"accesses). The +.\".Fn bus_space_vaddr +.\"method can be used to obtain the kernel virtual address of the mapped range. +.\"This is useful when software wants to do direct access to a memory +.\"device, e.g. a frame buffer. If this flag is specified and linear +.\"mapping is not possible, the +.\".Fn bus_space_map +.\"call should fail. +.\"If this +.\"flag is not specified, the system may map the space in whatever way is +.\"most convenient. +.\"Use of this mapping method is not encouraged for normal device access; +.\"where linear access is not essential, use of the +.\".Fn bus_space_read/write +.\"methods is strongly recommended. +.El +.Pp +.\"Not all combinations of flags make sense or are supported with all +.\"spaces. +.\"For instance, +.Dv BUS_SPACE_MAP_CACHEABLE +may be meaningless when used on many systems' I/O port spaces. +.\"and on some systems +.\".Dv BUS_SPACE_MAP_LINEAR +.\"without +.\".Dv BUS_SPACE_MAP_PREFETCHABLE +.\"may never work. +.\"When the system hardware or firmware provides hints as to how spaces should be +.\"mapped (e.g. the PCI memory mapping registers' "prefetchable" bit), those +.\"hints should be followed for maximum compatibility. +.\"On some systems, +.\"requesting a mapping that cannot be satisfied (e.g. requesting a +.\"non-prefetchable mapping when the system can only provide a prefetchable one) +.\"will cause the request to fail. +.Pp +Some implementations may keep track of use of bus space for some or all +bus spaces and refuse to allow duplicate allocations. +This is encouraged for bus spaces which have no notion of slot-specific +space addressing, such as ISA and VME, and for spaces which coexist with +those spaces (e.g. EISA and PCI memory and I/O spaces co-existing with +ISA memory and I/O spaces). +.Pp +Mapped regions may contain areas for which no there is no device on the +bus. +If space in those areas is accessed, the results are bus-dependent. +.Pp +.It Fn bus_space_unmap "space" "handle" "size" +.Pp +The +.Fn bus_space_unmap +function unmaps a region of bus space mapped with +.Fn bus_space_map . +When unmapping a region, the +.Fa size +specified should be the same as the size given to +.Fn bus_space_map +when mapping that region. +.Pp +After +.Fn bus_space_unmap +is called on a handle, that handle is no longer valid. +If copies were made of the handle they are no longer valid, either. +.Pp +This function will never fail. +If it would fail (e.g. because of an argument error), that indicates a +software bug which should cause a panic. +In that case, +.Fn bus_space_unmap +will never return. +.Pp +.It Fn bus_space_subregion "space" "handle" "offset" "size" "nhandlep" +.Pp +The +.Fn bus_space_subregion +function is a convenience function which makes a new handle to some +subregion of an already-mapped region of bus space. +The subregion described by the new handle starts at byte offset +.Fa offset +into the region described by +.Fa handle , +with the size give by +.Fa size , +and must be wholly contained within the original region. +.Pp +If successful, +.Fn bus_space_subregion +returns zero and fills in the bus space handle pointed to by +.Fa nhandlep . +If unsuccessful, it returns non-zero and leaves the bus space handle +pointed to by +.Fa nhandlep +in an undefined state. +In either case, the handle described by +.Fa handle +remains valid and is unmodified. +.Pp +When done with a handle created by +.Fn bus_space_subregion , +the handle should be thrown away. +Under no circumstances should +.Fn bus_space_unmap +be used on the handle. +Doing so may confuse any resource management being done on the space, +and will result in undefined behaviour. +When +.Fn bus_space_unmap +or +.Fn bus_space_free +is called on a handle, all subregions of that handle become invalid. +.\".Pp +.\".It Fn bus_space_vaddr "tag" "handle" +.\".Pp +.\"This method returns the kernel virtual address of a mapped bus space if and +.\"only if it was mapped with the +.\".Dv BUS_SPACE_MAP_LINEAR +.\"flag. The range can be accessed by normal (volatile) pointer dereferences. +.\"If mapped with the +.\".Dv BUS_SPACE_MAP_PREFETCHABLE +.\"flag, the +.\".Fn bus_space_barrier +.\"method must be used to force a particular access order. +.El +.Sh ALLOCATING AND FREEING BUS SPACE +Some devices require or allow bus space to be allocated by the operating +system for device use. +When the devices no longer need the space, the operating system should +free it for use by other devices. +The +.Fn bus_space_alloc +and +.Fn bus_space_free +functions provide these capabilities. +.Pp +.Bl -ohang -compact +.It Xo +.Fo bus_space_alloc +.Fa "space" "reg_start" "reg_end" "size" +.Fa "alignment" "boundary" "cacheable" "addrp" "handlep" +.Fc +.Xc +.Pp +The +.Fn bus_space_alloc +function allocates and maps a region of bus space with the size given by +.Fa size , +corresponding to the given constraints. +If successful, it returns zero, fills in the bus address pointed to by +.Fa addrp +with the bus space address of the allocated region, and fills in the bus +space handle pointed to by +.Fa handlep +with the handle that can be used to access that region. +If unsuccessful, it returns non-zero and leaves the bus address pointed +to by +.Fa addrp +and the bus space handle pointed to by +.Fa handlep +in an undefined state. +.Pp +Constraints on the allocation are given by the +.Fa reg_start , +.Fa reg_end , +.Fa alignment , +and +.Fa boundary +parameters. +The allocated region will start at or after +.Fa reg_start +and end before or at +.Fa reg_end . +The +.Fa alignment +constraint must be a power of two, and the allocated region will start +at an address that is an even multiple of that power of two. +The +.Fa boundary +constraint, if non-zero, ensures that the region is allocated so that +.Fa "first address in region" +/ +.Fa boundary +has the same value as +.Fa "last address in region" +/ +.Fa boundary . +If the constraints cannot be met, +.Fn bus_space_alloc +will fail. +It is an error to specify a set of constraints that can never be met +.Po +for example, +.Fa size +greater than +.Fa boundary +.Pc . +.Pp +The +.Fa cacheable +parameter is the same as the like-named parameter to +.Fa bus_space_map , +the same flag values should be used, and they have the same meanings. +.Pp +Handles created by +.Fn bus_space_alloc +should only be freed with +.Fn bus_space_free . +Trying to use +.Fn bus_space_unmap +on them causes undefined behaviour. +The +.Fn bus_space_subregion +function can be used on handles created by +.Fn bus_space_alloc . +.Pp +.It Fn bus_space_free "space" "handle" "size" +.Pp +The +.Fn bus_space_free +function unmaps and frees a region of bus space mapped and allocated +with +.Fn bus_space_alloc . +When unmapping a region, the +.Fa size +specified should be the same as the size given to +.Fn bus_space_alloc +when allocating the region. +.Pp +After +.Fn bus_space_free +is called on a handle, that handle is no longer valid. +If copies were made of the handle, they are no longer valid, either. +.Pp +This function will never fail. +If it would fail (e.g. because of an argument error), that indicates a +software bug which should cause a panic. +In that case, +.Fn bus_space_free +will never return. +.El +.Sh READING AND WRITING SINGLE DATA ITEMS +The simplest way to access bus space is to read or write a single data +item. +The +.Fn bus_space_read_N +and +.Fn bus_space_write_N +families of functions provide the ability to read and write 1, 2, 4, and +8 byte data items on busses which support those access sizes. +.Pp +.Bl -ohang -compact +.It Fn bus_space_read_1 "space" "handle" "offset" +.It Fn bus_space_read_2 "space" "handle" "offset" +.It Fn bus_space_read_4 "space" "handle" "offset" +.It Fn bus_space_read_8 "space" "handle" "offset" +.Pp +The +.Fn bus_space_read_N +family of functions reads a 1, 2, 4, or 8 byte data item from +the offset specified by +.Fa offset +into the region specified by +.Fa handle +of the bus space specified by +.Fa space . +The location being read must lie within the bus space region specified +by +.Fa handle . +.Pp +For portability, the starting address of the region specified by +.Fa handle +plus the offset should be a multiple of the size of data item being +read. +On some systems, not obeying this requirement may cause incorrect data +to be read, on others it may cause a system crash. +.Pp +Read operations done by the +.Fn bus_space_read_N +functions may be executed out of order with respect to other pending +read and write operations unless order is enforced by use of the +.Fn bus_space_barrier +function. +.Pp +These functions will never fail. +If they would fail (e.g. because of an argument error), that indicates a +software bug which should cause a panic. +In that case, they will never return. +.Pp +.It Fn bus_space_write_1 "space" "handle" "offset" "value" +.It Fn bus_space_write_2 "space" "handle" "offset" "value" +.It Fn bus_space_write_4 "space" "handle" "offset" "value" +.It Fn bus_space_write_8 "space" "handle" "offset" "value" +.Pp +The +.Fn bus_space_write_N +family of functions writes a 1, 2, 4, or 8 byte data item to the offset +specified by +.Fa offset +into the region specified by +.Fa handle +of the bus space specified by +.Fa space . +The location being written must lie within the bus space region +specified by +.Fa handle . +.Pp +For portability, the starting address of the region specified by +.Fa handle +plus the offset should be a multiple of the size of data item being +written. +On some systems, not obeying this requirement may cause incorrect data +to be written, on others it may cause a system crash. +.Pp +Write operations done by the +.Fn bus_space_write_N +functions may be executed out of order with respect to other pending +read and write operations unless order is enforced by use of the +.Fn bus_space_barrier +function. +.Pp +These functions will never fail. +If they would fail (e.g. because of an argument error), that indicates a +software bug which should cause a panic. +In that case, they will never return. +.El +.Sh BARRIERS +In order to allow high-performance buffering implementations to avoid +bus activity on every operation, read and write ordering should be +specified explicitly by drivers when necessary. +The +.Fn bus_space_barrier +function provides that ability. +.Pp +.Bl -ohang -compact +.It Fn bus_space_barrier "space" "handle" "offset" "length" "flags" +.Pp +The +.Fn bus_space_barrier +function enforces ordering of bus space read and write operations for +the specified subregion (described by the +.Fa offset +and +.Fa length +parameters) of the region named by +.Fa handle +in the space named by +.Fa space . +.Pp +The +.Fa flags +argument controls what types of operations are to be ordered. +Supported flags are: +.Bl -tag -width BUS_SPACE_BARRIER_WRITE -offset indent +.It Dv BUS_SPACE_BARRIER_READ +Synchronize read operations. +.It Dv BUS_SPACE_BARRIER_WRITE +Synchronize write operations. +.El +.Pp +Those flags can be combined (or-ed together) to enforce ordering on both +read and write operations. +.Pp +All of the specified type(s) of operation which are done to the region +before the barrier operation are guaranteed to complete before any of +the specified type(s) of operation done after the barrier. +.Pp +Example: Consider a hypothetical device with two single-byte ports, one +write-only input port (at offset 0) and a read-only output port (at +offset 1). +Operation of the device is as follows: data bytes are written to the +input port, and are placed by the device on a stack, the top of which is +read by reading from the output port. +The sequence to correctly write two data bytes to the device then read +those two data bytes back would be: +.Pp +.Bd -literal +/* + * t and h are the tag and handle for the mapped device's + * space. + */ +bus_space_write_1(t, h, 0, data0); +bus_space_barrier(t, h, 0, 1, BUS_SPACE_BARRIER_WRITE); /* 1 */ +bus_space_write_1(t, h, 0, data1); +bus_space_barrier(t, h, 0, 2, + BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE); /* 2 */ +ndata1 = bus_space_read_1(t, h, 1); +bus_space_barrier(t, h, 1, 1, BUS_SPACE_BARRIER_READ); /* 3 */ +ndata0 = bus_space_read_1(t, h, 1); +/* data0 == ndata0, data1 == ndata1 */ +.Ed +.Pp +The first barrier makes sure that the first write finishes before the +second write is issued, so that two writes to the input port are done in +order and are not collapsed into a single write. +This ensures that the data bytes are written to the device correctly and +in order. +.Pp +The second barrier makes sure that the writes to the output port finish +before any of the reads to the input port are issued, thereby making +sure that all of the writes are finished before data is read. +This ensures that the first byte read from the device really is the last +one that was written. +.Pp +The third barrier makes sure that the first read finishes before the +second read is issued, ensuring that data is read correctly and in order. +.Pp +The barriers in the example above are specified to cover the absolute +minimum number of bus space locations. +It is correct (and often easier) to make barrier operations cover the +device's whole range of bus space, that is, to specify an offset of zero +and the size of the whole region. +.El +.Sh REGION OPERATIONS +Some devices use buffers which are mapped as regions in bus space. +Often, drivers want to copy the contents of those buffers to or from +memory, e.g. into mbufs which can be passed to higher levels of the +system or from mbufs to be output to a network. +In order to allow drivers to do this as efficiently as possible, the +.Fn bus_space_read_region_N +and +.Fn bus_space_write_region_N +families of functions are provided. +.Pp +Drivers occasionally need to copy one region of a bus space to another, +or to set all locations in a region of bus space to contain a single +value. +The +.Fn bus_space_copy_N +family of functions and the +.Fn bus_space_set_region_N +family of functions allow drivers to perform these operations. +.Pp +.Bl -ohang -compact +.It Fn bus_space_read_region_1 "space" "handle" "offset" "datap" "count" +.It Fn bus_space_read_region_2 "space" "handle" "offset" "datap" "count" +.It Fn bus_space_read_region_4 "space" "handle" "offset" "datap" "count" +.It Fn bus_space_read_region_8 "space" "handle" "offset" "datap" "count" +.Pp +The +.Fn bus_space_read_region_N +family of functions reads +.Fa count +1, 2, 4, or 8 byte data items from bus space starting at byte offset +.Fa offset +in the region specified by +.Fa handle +of the bus space specified by +.Fa space +and writes them into the array specified by +.Fa datap . +Each successive data item is read from an offset +1, 2, 4, or 8 bytes after the previous data item (depending on which +function is used). +All locations being read must lie within the bus space region specified +by +.Fa handle . +.Pp +For portability, the starting address of the region specified by +.Fa handle +plus the offset should be a multiple of the size of data items being +read and the data array pointer should be properly aligned. +On some systems, not obeying these requirements may cause incorrect data +to be read, on others it may cause a system crash. +.Pp +Read operations done by the +.Fn bus_space_read_region_N +functions may be executed in any order. +They may also be executed out of order with respect to other pending +read and write operations unless order is enforced by use of the +.Fn bus_space_barrier +function. +There is no way to insert barriers between reads of individual bus space +locations executed by the +.Fn bus_space_read_region_N +functions. +.Pp +These functions will never fail. +If they would fail (e.g. because of an argument error), that indicates a +software bug which should cause a panic. +In that case, they will never return. +.Pp +.It Fn bus_space_write_region_1 "space" "handle" "offset" "datap" "count" +.It Fn bus_space_write_region_2 "space" "handle" "offset" "datap" "count" +.It Fn bus_space_write_region_4 "space" "handle" "offset" "datap" "count" +.It Fn bus_space_write_region_8 "space" "handle" "offset" "datap" "count" +.Pp +The +.Fn bus_space_write_region_N +family of functions reads +.Fa count +1, 2, 4, or 8 byte data items from the array specified by +.Fa datap +and writes them to bus space starting at byte offset +.Fa offset +in the region specified by +.Fa handle +of the bus space specified by +.Fa space . +Each successive data item is written to an offset 1, 2, 4, or 8 bytes +after the previous data item (depending on which function is used). +All locations being written must lie within the bus space region +specified by +.Fa handle . +.Pp +For portability, the starting address of the region specified by +.Fa handle +plus the offset should be a multiple of the size of data items being +written and the data array pointer should be properly aligned. +On some systems, not obeying these requirements may cause incorrect data +to be written, on others it may cause a system crash. +.Pp +Write operations done by the +.Fn bus_space_write_region_N +functions may be executed in any order. +They may also be executed out of order with respect to other pending +read and write operations unless order is enforced by use of the +.Fn bus_space_barrier +function. +There is no way to insert barriers between writes of individual bus +space locations executed by the +.Fn bus_space_write_region_N +functions. +.Pp +These functions will never fail. +If they would fail (e.g. because of an argument error), that indicates a +software bug which should cause a panic. +In that case, they will never return. +.Pp +.It Fn bus_space_copy_1 "space" "srchandle" "srcoffset" "dsthandle" \ +"dstoffset" "count" +.It Fn bus_space_copy_2 "space" "srchandle" "srcoffset" "dsthandle" \ +"dstoffset" "count" +.It Fn bus_space_copy_4 "space" "srchandle" "srcoffset" "dsthandle" \ +"dstoffset" "count" +.It Fn bus_space_copy_8 "space" "srchandle" "srcoffset" "dsthandle" \ +"dstoffset" "count" +.Pp +The +.Fn bus_space_copy_N +family of functions copies +.Fa count +1, 2, 4, or 8 byte data items in bus space from the area starting at +byte offset +.Fa srcoffset +in the region specified by +.Fa srchandle +of the bus space specified by +.Fa space +to the area starting at byte offset +.Fa dstoffset +in the region specified by +.Fa dsthandle +in the same bus space. +Each successive data item read or written has an offset 1, 2, 4, or 8 +bytes after the previous data item (depending on which function is +used). +All locations being read and written must lie within the bus space +region specified by their respective handles. +.Pp +For portability, the starting addresses of the regions specified by the +each handle plus its respective offset should be a multiple of the size +of data items being copied. +On some systems, not obeying this requirement may cause incorrect data +to be copied, on others it may cause a system crash. +.Pp +Read and write operations done by the +.Fn bus_space_copy_N +functions may be executed in any order. +They may also be executed out of order with respect to other pending +read and write operations unless order is enforced by use of the +.Fn bus_space_barrier function . +There is no way to insert barriers between reads or writes of individual +bus space locations executed by the +.Fn bus_space_copy_N +functions. +.Pp +Overlapping copies between different subregions of a single region of +bus space are handled correctly by the +.Fn bus_space_copy_N +functions. +.Pp +These functions will never fail. +If they would fail (e.g. because of an argument error), that indicates a +software bug which should cause a panic. +In that case, they will never return. +.Pp +.It Fn bus_space_set_region_1 "space" "handle" "offset" "value" "count" +.It Fn bus_space_set_region_2 "space" "handle" "offset" "value" "count" +.It Fn bus_space_set_region_4 "space" "handle" "offset" "value" "count" +.It Fn bus_space_set_region_8 "space" "handle" "offset" "value" "count" +.Pp +The +.Fn bus_space_set_region_N +family of functions writes the given +.Fa value +to +.Fa count +1, 2, 4, or 8 byte data items in bus space starting at byte offset +.Fa offset +in the region specified by +.Fa handle +of the bus space specified by +.Fa space . +Each successive data item has an offset 1, 2, 4, or 8 bytes after the +previous data item (depending on which function is used). +All locations being written must lie within the bus space region +specified by +.Fa handle . +.Pp +For portability, the starting address of the region specified by +.Fa handle +plus the offset should be a multiple of the size of data items being +written. +On some systems, not obeying this requirement may cause incorrect data +to be written, on others it may cause a system crash. +.Pp +Write operations done by the +.Fn bus_space_set_region_N +functions may be executed in any order. +They may also be executed out of order with respect to other pending +read and write operations unless order is enforced by use of the +.Fn bus_space_barrier +function. +There is no way to insert barriers between writes of individual bus +space locations executed by the +.Fn bus_space_set_region_N +functions. +.Pp +These functions will never fail. +If they would fail (e.g. because of an argument error), that indicates a +software bug which should cause a panic. +In that case, they will never return. +.El +.Sh READING AND WRITING A SINGLE LOCATION MULTIPLE TIMES +Some devices implement single locations in bus space which are to be +read or written multiple times to communicate data, e.g. some ethernet +devices' packet buffer FIFOs. +In order to allow drivers to manipulate these types of devices as +efficiently as possible, the +.Fn bus_space_read_multi_N , +.Fn bus_space_write_multi_N , +and +.Fn bus_space_set_multi_N +families of functions are provided. +.Pp +.Bl -ohang -compact +.It Fn bus_space_read_multi_1 "space" "handle" "offset" "datap" "count" +.It Fn bus_space_read_multi_2 "space" "handle" "offset" "datap" "count" +.It Fn bus_space_read_multi_4 "space" "handle" "offset" "datap" "count" +.It Fn bus_space_read_multi_8 "space" "handle" "offset" "datap" "count" +.Pp +The +.Fn bus_space_read_multi_N +family of functions reads +.Fa count +1, 2, 4, or 8 byte data items from bus space at byte offset +.Fa offset +in the region specified by +.Fa handle +of the bus space specified by +.Fa space +and writes them into the array specified by +.Fa datap . +Each successive data item is read from the same location in bus space. +The location being read must lie within the bus space region specified +by +.Fa handle . +.Pp +For portability, the starting address of the region specified by +.Fa handle +plus the offset should be a multiple of the size of data items being +read and the data array pointer should be properly aligned. +On some systems, not obeying these requirements may cause incorrect data +to be read, on others it may cause a system crash. +.Pp +Read operations done by the +.Fn bus_space_read_multi_N +functions may be executed out of order with respect to other pending +read and write operations unless order is enforced by use of the +.Fn bus_space_barrier +function. +Because the +.Fn bus_space_read_multi_N +functions read the same bus space location multiple times, they place an +implicit read barrier between each successive read of that bus space +location. +.Pp +These functions will never fail. +If they would fail (e.g. because of an argument error), that indicates a +software bug which should cause a panic. +In that case, they will never return. +.Pp +.It Fn bus_space_write_multi_1 "space" "handle" "offset" "datap" "count" +.It Fn bus_space_write_multi_2 "space" "handle" "offset" "datap" "count" +.It Fn bus_space_write_multi_4 "space" "handle" "offset" "datap" "count" +.It Fn bus_space_write_multi_8 "space" "handle" "offset" "datap" "count" +.Pp +The +.Fn bus_space_write_multi_N +family of functions reads +.Fa count +1, 2, 4, or 8 byte data items from the array specified by +.Fa datap +and writes them into bus space at byte offset +.Fa offset +in the region specified by +.Fa handle +of the bus space specified by +.Fa space . +Each successive data item is written to the same location in bus space. +The location being written must lie within the bus space region +specified by +.Fa handle . +.Pp +For portability, the starting address of the region specified by +.Fa handle +plus the offset should be a multiple of the size of data items being +written and the data array pointer should be properly aligned. +On some systems, not obeying these requirements may cause incorrect data +to be written, on others it may cause a system crash. +.Pp +Write operations done by the +.Fn bus_space_write_multi_N +functions may be executed out of order with respect to other pending +read and write operations unless order is enforced by use of the +.Fn bus_space_barrier +function. +Because the +.Fn bus_space_write_multi_N +functions write the same bus space location multiple times, they place +an implicit write barrier between each successive write of that bus +space location. +.Pp +These functions will never fail. +If they would fail (e.g. because of an argument error), that indicates a +software bug which should cause a panic. +In that case, they will never return. +.Pp +.It Fn bus_space_set_multi_1 "space" "handle" "offset" "value" "count" +.It Fn bus_space_set_multi_2 "space" "handle" "offset" "value" "count" +.It Fn bus_space_set_multi_4 "space" "handle" "offset" "value" "count" +.It Fn bus_space_set_multi_8 "space" "handle" "offset" "value" "count" +.Pp +The +.Fn bus_space_set_multi_N +family of functions writes the 1, 2, 4, or 8 byte value +.Fa value +into bus space +.Fa count +times at byte offset +.Fa offset +in the region specified by +.Fa handle +of the bus space specified by +.Fa space . +The location being written must lie within the bus space region +specified by +.Fa handle . +.Pp +For portability, the address specified by +.Fa handle +plus the offset should be a multiple of the size of the data value being +written. +On some systems, not obeying these requirements may cause +incorrect data to be written, on others it may cause a system crash. +.Pp +Write operations done by the +.Fn bus_space_set_multi_N +functions may be executed out of order with respect to other pending +read and write operations unless order is enforced by use of the +.Fn bus_space_barrier +function. +Because the +.Fn bus_space_set_multi_N +functions write the same bus space location multiple times, they place +an implicit write barrier between each successive write of that bus +space location. +.Pp +These functions will never fail. +If they would fail (e.g. because of an argument error), that indicates a +software bug which should cause a panic. +In that case, they will never return. +.El +.Sh RAW FUNCTIONS +Most of the +.Nm +functions imply a host byte-order and a bus byte-order and take care of +any translation for the caller. +In some cases, however, hardware may map a FIFO or some other memory +region for which the caller may want to use multi-word, yet untranslated +access. +Access to these types of memory regions should be with the +.Fn bus_space_*_raw_*_N +functions. +.Pp +.Bl -ohang -compact +.\".It Fn bus_space_read_stream_1 "space" "handle" "offset" +.\".It Fn bus_space_read_stream_2 "space" "handle" "offset" +.\".It Fn bus_space_read_stream_4 "space" "handle" "offset" +.\".It Fn bus_space_read_stream_8 "space" "handle" "offset" +.\".It Fn bus_space_read_raw_multi_1 "space" "handle" "offset" "datap" "count" +.It Fn bus_space_read_raw_multi_2 "space" "handle" "offset" "datap" "count" +.It Fn bus_space_read_raw_multi_4 "space" "handle" "offset" "datap" "count" +.It Fn bus_space_read_raw_multi_8 "space" "handle" "offset" "datap" "count" +.\".It Fn bus_space_read_raw_region_1 "space" "handle" "offset" "datap" "count" +.It Fn bus_space_read_raw_region_2 "space" "handle" "offset" "datap" "count" +.It Fn bus_space_read_raw_region_4 "space" "handle" "offset" "datap" "count" +.It Fn bus_space_read_raw_region_8 "space" "handle" "offset" "datap" "count" +.\".It Fn bus_space_write_stream_1 "space" "handle" "offset" "value" +.\".It Fn bus_space_write_stream_2 "space" "handle" "offset" "value" +.\".It Fn bus_space_write_stream_4 "space" "handle" "offset" "value" +.\".It Fn bus_space_write_stream_8 "space" "handle" "offset" "value" +.\".It Fn bus_space_write_raw_multi_1 "space" "handle" "offset" "datap" "count" +.It Fn bus_space_write_raw_multi_2 "space" "handle" "offset" "datap" "count" +.It Fn bus_space_write_raw_multi_4 "space" "handle" "offset" "datap" "count" +.It Fn bus_space_write_raw_multi_8 "space" "handle" "offset" "datap" "count" +.\".It Fn bus_space_write_raw_region_1 "space" "handle" "offset" "datap" "count" +.It Fn bus_space_write_raw_region_2 "space" "handle" "offset" "datap" "count" +.It Fn bus_space_write_raw_region_4 "space" "handle" "offset" "datap" "count" +.It Fn bus_space_write_raw_region_8 "space" "handle" "offset" "datap" "count" +.El +.Pp +These functions, unlike their non-raw counterparts, all take a +u_int8_t pointer for the +.Fa datap +argument and a byte count for the +.Fa count +argument regardless of the access width being requested. +.Pp +.Fa datap +must reference a buffer that is correctly aligned for the +access width being requested or the results are undefined. +.Pp +.Fa count +must be a multiple of the access width or the results are undefined. +.Pp +In all other respects these functions are the same as their non-raw +counterparts. +Please consult the documentation for those functions for further +information. +.Sh EXPECTED CHANGES TO THE BUS_SPACE FUNCTIONS +The definition of the +.Nm +functions should not yet be considered finalized. +There are several changes and improvements which should be explored, +including: +.Bl -bullet +.It +Providing a mechanism by which incorrectly-written drivers will be +automatically given barriers and properly-written drivers won't be +forced to use more barriers than they need. +This should probably be done via a +.Li #define +in the incorrectly-written drivers. +Unfortunately, at this time, few drivers actually use barriers correctly +(or at all). +Because of that, +.Nm +implementations on architectures which do buffering must always do the +barriers inside the +.Nm +calls, to be safe. +That has a potentially significant performance impact. +.It +Exporting the +.Nm +functions to user-land so that applications (such as X servers) have +easier, more portable access to device space. +.It +Redefining bus space tags and handles so that machine-independent bus +interface drivers (for example PCI to VME bridges) could define and +implement bus spaces without requiring machine-dependent code. +If this is done, it should be done in such a way that machine-dependent +optimizations should remain possible. +.It +Converting bus spaces (such as PCI configuration space) which currently +use space-specific access methods to use the +.Nm +functions where that is appropriate. +.It +Redefining the way bus space is mapped and allocated, so that mapping +and allocation are done with bus specific functions which return bus +space tags. +This would allow further optimization than is currently possible, and +would also ease translation of the +.Nm +functions into user space (since mapping in user space would look like +it just used a different bus-specific mapping function). +.El +.\".Sh COMPATIBILITY +.\".Pp +.\"The current version of the +.\".Nm +.\"interface specification differs slightly from the original +.\"specification that came into wide use. +.\"A few of the function names and arguments have changed +.\"for consistency and increased functionality. +.\"Drivers that were written to the +.\"old, deprecated specification can be compiled by defining the +.\".Dv __BUS_SPACE_COMPAT_OLDDEFS +.\"preprocessor symbol before including +.\".Pa Aq machine/bus.h . +.Sh HISTORY +The +.Nm +functions were introduced in a different form (memory and I/O spaces +were accessed via different sets of functions) in +.Nx 1.2 . +The functions were merged to work on generic +.Dq spaces +early in the +.Nx 1.3 +development cycle, and many drivers were converted to use them. +This document was written later during the +.Nx 1.3 +development cycle and the specification was updated to fix some +consistency problems and to add some missing functionality. +.Pp +The +.Ox +development team added the *_raw_* API, and discarded the *_stream_* +API. +.Sh AUTHORS +The +.Nm +interfaces were designed and implemented by the +.Nx +developer community. +Primary contributors and implementors were Chris Demetriou, Jason +Thorpe, and Charles Hannum, but the rest of the +.Nx +developers and the user community played a significant role in +development. +.Pp +Chris Demetriou wrote this manual page. +.Pp +Niklas Hallqvist did the *_raw_* API for +.Ox . +.Sh SEE ALSO +.Xr bus_dma 9 |