Index Index for
Section 9
Index Alphabetical
listing for R
Bottom of page Bottom of
page

read_io_port(9r)

NAME

read_io_port - General: Reads data from a device register

SYNOPSIS

#include <io/common/devdriver.h> long read_io_port( io_handle_t dev_addr, int width, int flags );

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 read operation originates. 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 read. 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.

DESCRIPTION

The read_io_port routine reads data of the specified width from a device register located in bus address space. The I/O handle you pass to dev_addr identifies where the read operation originates.

NOTES

The read_io_port routine is a generic routine that maps to a bus- and machine-specific routine that actually performs the read operation. Using this routine to read data from 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 read_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 read_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 read 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 an 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 READ_DEVICECSR_USHORT example macro reads an unsigned word of data from a device register. The READ_DEVICECSR_USHORT macro is called instead of directly calling the READ_BUS_D16 macro. The READ_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 read operation into 2-byte read operations. The driver must also perform appropriate bit-shifting operations to read high and low bytes that are then ORed together. #define READ_DEVICECSR_USHORT(a) ( (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 read operation crosses a 16-bit register boundary. */ ? ( (READ_BUS_D8( (io_handle_t)sc->regbase + (a)+1) <<< 8) | READ_BUS_D8( (io_handle_t)sc->regbase + (a) ) ) : ( READ_BUS_D16((io_handle_t)sc->regbase + (a)) ); )

RETURN VALUES

Upon successful completion, read_io_port returns the requested data from the device register located in the bus address space: a byte (8 bits), a word (16 bits), a longword (32 bits), or a quadword (64 bits). This routine returns data justified to the low-order byte lane. For example, a byte (8 bits) is always returned in byte lane 0 and a word (16 bits) is always returned in byte lanes 0 and 1.

SEE ALSO

Kernel Routines: write_io_port(9r)

Index Index for
Section 9
Index Alphabetical
listing for R
Top of page Top of
page