 |
Index for Section 9 |
|
 |
Alphabetical listing for W |
|
 |
Bottom of page |
|
write_io_port(9r)
NAME
write_io_port - General: Writes data to a device register
SYNOPSIS
#include <io/common/devdriver.h>
void write_io_port(
io_handle_t dev_addr,
int width,
int flags,
long data );
ARGUMENTS
dev_addr
Specifies an I/O handle that you can use to reference a device register
or memory located in bus address space (either I/O space or memory
space). This I/O handle references a device register in the bus address
space where the write operation occurs. You can perform standard C
mathematical operations (addition and subtraction only) on the I/O
handle. For example, you can add an offset to or subtract an offset
from the I/O handle.
width
Specifies the width (in bytes) of the data to be written. Valid values
are 1, 2, 3, 4, and 8. Not all CPU platforms or bus adapters support
all of these values.
flags
Specifies flags to indicate special processing requests. Currently, no
flags are used.
data
Specifies the data to be written to the specified device register in
bus address space.
DESCRIPTION
The write_io_port routine writes the data of the specified width to the
specified device register in bus address space. This routine shifts the
data to the appropriate byte lanes before performing the write to bus
address space. The I/O handle you pass to dev_addr identifies where the
write operation occurs.
NOTES
The write_io_port routine is a generic routine that maps to a bus- and
machine-specific routine that actually performs the write operation. Using
this routine to write data to a device register makes the device driver
more portable across different bus architectures, different CPU
architectures, and different CPU types within the same CPU architecture.
You must call the mb routine immediately after calling the write_io_port
routine under certain circumstances. For discussions and examples of these
circumstances, see the Memory Barrier Issues section in Writing Device
Drivers.
CAUTIONS
The I/O handle that you pass to the dev_addr argument of the write_io_port
routine must be an I/O handle that references addresses residing in sparse
space. All Alpha CPUs support sparse space. As a result, all bus
configuration code should supply an I/O handle that references bus address
space.
If you pass an I/O handle to the dev_addr argument that references
addresses residing in some other space (for example, dense space) the
results of the write operation are unpredictable.
Tru64 UNIX provides the following routines that allow device drivers to
perform copy operations and zero blocks of memory on addresses that reside
in dense space:
· bcopy
Copies a series of bytes with a specified limit
· blkclr and bzero
Zeros a block of memory
· copyin
Copies data from a user address space to a kernel address space
· copyinstr
Copies a null-terminated string from a user address space to a kernel
address space
· copyout
Copies data from a kernel address space to a user address space
· copyoutstr
Copies a null-terminated string from a kernel address space to a user
address space
The read_io_port and write_io_port routines (and by extension, the macros
built from these routines) do not support unaligned data accesses that
cross longword boundaries. You can access unaligned data by providing a
macro that checks the lower bits of an I/O address to determine the byte
boundary of the I/O read or write operation to be performed and the width
of the data to be read or written. If an alignment problem exists, you can
break up the read or write operation into separate byte-size reads or
writes.
The WRITE_DEVICECSR_USHORT macro is an example of a support macro that
writes an unsigned word of data to a device register. The
WRITE_DEVICECSR_USHORT macro is called instead of directly calling the
macro WRITE_BUS_D16. The WRITE_DEVICECSR_USHORT macro first masks out the
lower 2 bits of the base address. If the lower 2 bits are both high
(indicating an address on a tribyte boundary), the driver must break up the
write operation into 2-byte write operations. The driver must also perform
appropriate bit-shifting operations to write high and low bytes that are
then ORed together.
#define WRITE_DEVICECSR_USHORT(a, data)
(
(u_short)(
(((u_short)(a)&3) == 3)
/*
(((u_short)(a)&1) == 1) This can be used in drivers with 16-bit
CSRs to check if a word write operation
crosses a 16-bit register boundary
*/
?
( WRITE_BUS_D8( (io_handle_t)sc->regbase + (a), data),
mb(),
WRITE_BUS_D8( (io_handle_t)sc->regbase + (a)+1,
(u_short)(data) >> 8),
mb()
)
:
( WRITE_BUS_D16( (io_handle_t)sc->regbase + (a), data),
mb()
);
)
RETURN VALUES
None
SEE ALSO
Kernel Routines: read_io_port(9r)
 |
Index for Section 9 |
|
 |
Alphabetical listing for W |
|
 |
Top of page |
|