DDI_DEVICE_ACC_ATTR(9S)DDI_DEVICE_ACC_ATTR(9S)NAMEddi_device_acc_attr - data access attributes structure
SYNOPSIS
#include <sys/ddi.h>
#include <sys/sunddi.h>
INTERFACE LEVEL
Solaris DDI specific (Solaris DDI)
DESCRIPTION
The ddi_device_acc_attr structure describes the data access character‐
istics and requirements of the device.
STRUCTURE MEMBERS
ushort_t devacc_attr_version;
uchar_t devacc_attr_endian_flags;
uchar_t devacc_attr_dataorder;
uchar_t devacc_attr_access;
The devacc_attr_version member identifies the version number of this
structure. The current version number is DDI_DEVICE_ATTR_V0.
The devacc_attr_endian_flags member describes the endian characteris‐
tics of the device. Specify one of the following values:
DDI_NEVERSWAP_ACC
Data access with no byte swapping
DDI_STRUCTURE_BE_ACC
Structural data access in big-endian format
DDI_STRUCTURE_LE_ACC
Structural data access in little endian format
DDI_STRUCTURE_BE_ACC and DDI_STRUCTURE_LE_ACC describe the endian char‐
acteristics of the device as big-endian or little-endian, respectively.
Although most of the devices have the same endian characteristics as
their buses, examples of devices that have opposite endian characteris‐
tics of the buses do exist. When DDI_STRUCTURE_BE_ACC or DDI_STRUC‐
TURE_LE_ACC is set, byte swapping is automatically performed by the
system if the host machine and the device data formats have opposite
endian characteristics. The implementation can take advantage of hard‐
ware platform byte swapping capabilities.
When you specify DDI_NEVERSWAP_ACC, byte swapping is not invoked in the
data access functions.
The devacc_attr_dataorder member describes the order in which the CPU
references data. Specify one of the following values.
DDI_STRICTORDER_ACC
Data references must be issued by a CPU in
program order. Strict ordering is the
default behavior.
DDI_UNORDERED_OK_ACC
The CPU can reorder the data references.
This includes all kinds of reordering. For
example, a load followed by a store might be
replaced by a store followed by a load.
DDI_MERGING_OK_ACC
The CPU can merge individual stores to con‐
secutive locations. For example, the CPU can
turn two consecutive byte stores into one
half-word store. It can also batch individ‐
ual loads. For example, the CPU might turn
two consecutive byte loads into one half-
word load. DDI_MERGING_OK_ACC also implies
reordering.
DDI_LOADCACHING_OK_ACC
The CPU can cache the data it fetches and
reuse it until another store occurs. The
default behavior is to fetch new data on
every load. DDI_LOADCACHING_OK_ACC also
implies merging and reordering.
DDI_STORECACHING_OK_ACC
The CPU can keep the data in the cache and
push it to the device, perhaps with other
data, at a later time. The default behavior
is to push the data right away. DDI_STORE‐
CACHING_OK_ACC also implies load caching,
merging, and reordering.
These values are advisory, not mandatory. For example, data can be
ordered without being merged, or cached, even though a driver requests
unordered, merged, and cached together.
The values defined for devacc_attr_access are:
DDI_DEFAULT_ACC
If an I/O fault occurs, the system will take the
default action, which might be to panic.
DDI_FLAGERR_ACC
Using this value indicates that the driver is hard‐
ened: able to cope with the incorrect results of
I/O operations that might result from an I/O fault.
The value also indicates that the driver will use
ddi_fm_acc_err_get(9F) to check access handles for
faults on a regular basis.
If possible, the system should not panic on such an
I/O fault, but should instead mark the I/O handle
through which the access was made as having
faulted.
This value is advisory: it tells the system that
the driver can continue in the face of I/O faults.
The value does not guarantee that the system will
not panic, as that depends on the nature of the
fault and the capabilities of the system. It is
quite legitimate for an implementation to ignore
this flag and panic anyway.
DDI_CAUTIOUS_ACC
This value indicates that an I/O fault is antici‐
pated and should be handled as gracefully as possi‐
ble. For example, the framework should not print a
console message.
This value should be used when it is not certain
that a device is physically present: for example,
when probing. As such, it provides an alternative
within the DDI access framework to the existing
peek/poke functions, which don't use access handles
and cannot be integrated easily into a more general
I/O fault handling framework.
In order to guarantee safe recovery from an I/O
fault, it might be necessary to acquire exclusive
access to the parent bus, for example, or to syn‐
chronize across processors on an MP machine. "Cau‐
tious" access can be quite expensive and is only
recommended for initial probing and possibly for
additional fault-recovery code.
EXAMPLES
The following examples illustrate the use of device register address
mapping setup functions and different data access functions.
Example 1 Using ddi_device_acc_attr() in >ddi_regs_map_setup(9F)
This example demonstrates the use of the ddi_device_acc_attr() struc‐
ture in ddi_regs_map_setup(9F). It also shows the use of ddi_getw(9F)
and ddi_putw(9F) functions in accessing the register contents.
dev_info_t *dip;
uint_t rnumber;
ushort_t *dev_addr;
offset_t offset;
offset_t len;
ushort_t dev_command;
ddi_device_acc_attr_t dev_attr;
ddi_acc_handle_t handle;
...
/*
* setup the device attribute structure for little endian,
* strict ordering and 16-bit word access.
*/
dev_attr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
dev_attr.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC;
dev_attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
/*
* set up the device registers address mapping
*/
ddi_regs_map_setup(dip, rnumber, (caddr_t *)&dev_addr, offset, len,
&dev_attr, &handle);
/* read a 16-bit word command register from the device */
dev_command = ddi_getw(handle, dev_addr);
dev_command |= DEV_INTR_ENABLE;
/* store a new value back to the device command register */
ddi_putw(handle, dev_addr, dev_command);
Example 2 Accessing a Device with Different Apertures
The following example illustrates the steps used to access a device
with different apertures. Several apertures are assumed to be grouped
under one single "reg" entry. For example, the sample device has four
different apertures, each 32 Kbyte in size. The apertures represent
YUV little-endian, YUV big-endian, RGB little-endian, and RGB big-
endian. This sample device uses entry 1 of the "reg" property list for
this purpose. The size of the address space is 128 Kbyte with each 32
Kbyte range as a separate aperture. In the register mapping setup func‐
tion, the sample driver uses the offset and len parameters to specify
one of the apertures.
ulong_t *dev_addr;
ddi_device_acc_attr_t dev_attr;
ddi_acc_handle_t handle;
uchar_t buf[256];
...
/*
* setup the device attribute structure for never swap,
* unordered and 32-bit word access.
*/
dev_attr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
dev_attr.devacc_attr_endian_flags = DDI_NEVERSWAP_ACC;
dev_attr.devacc_attr_dataorder = DDI_UNORDERED_OK_ACC;
/*
* map in the RGB big-endian aperture
* while running in a big endian machine
* - offset 96K and len 32K
*/
ddi_regs_map_setup(dip, 1, (caddr_t *)&dev_addr, 96*1024, 32*1024,
&dev_attr, &handle);
/*
* Write to the screen buffer
* first 1K bytes words, each size 4 bytes
*/
ddi_rep_putl(handle, buf, dev_addr, 256, DDI_DEV_AUTOINCR);
Example 3 Functions That Call Out the Data Word Size
The following example illustrates the use of the functions that explic‐
itly call out the data word size to override the data size in the
device attribute structure.
struct device_blk {
ushort_t d_command; /* command register */
ushort_t d_status; /* status register */
ulong d_data; /* data register */
} *dev_blkp;
dev_info_t *dip;
caddr_t dev_addr;
ddi_device_acc_attr_t dev_attr;
ddi_acc_handle_t handle;
uchar_t buf[256];
...
/*
* setup the device attribute structure for never swap,
* strict ordering and 32-bit word access.
*/
dev_attr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
dev_attr.devacc_attr_endian_flags = DDI_NEVERSWAP_ACC;
dev_attr.devacc_attr_dataorder= DDI_STRICTORDER_ACC;
ddi_regs_map_setup(dip, 1, (caddr_t *)&dev_blkp, 0, 0,
&dev_attr, &handle);
/* write command to the 16-bit command register */
ddi_putw(handle, &dev_blkp->d_command, START_XFER);
/* Read the 16-bit status register */
status = ddi_getw(handle, &dev_blkp->d_status);
if (status & DATA_READY)
/* Read 1K bytes off the 32-bit data register */
ddi_rep_getl(handle, buf, &dev_blkp->d_data,
256, DDI_DEV_NO_AUTOINCR);
ATTRIBUTES
See attributes(5) for descriptions of the following attributes:
┌────────────────────┬─────────────────┐
│ ATTRIBUTE TYPE │ ATTRIBUTE VALUE │
├────────────────────┼─────────────────┤
│Interface Stability │ Committed │
└────────────────────┴─────────────────┘
SEE ALSOattributes(5), ddi_fm_acc_err_get(9F), ddi_getw(9F), ddi_putw(9F),
ddi_regs_map_setup(9F)
Writing Device Drivers
May 13, 2007 DDI_DEVICE_ACC_ATTR(9S)