DDI_DEVICE_ACC_ATTR(9S)  Data Structures for Drivers DDI_DEVICE_ACC_ATTR(9S)
NAME
       ddi_device_acc_attr - data access attributes structure
SYNOPSIS
       #include <sys/ddi.h>
       #include <sys/sunddi.h>
INTERFACE LEVEL
       illumos DDI specific (illumos DDI)
DESCRIPTION
       The 
ddi_device_acc_attr structure describes the data access
       characteristics 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_V1.
       The 
devacc_attr_endian_flags member describes the endian
       characteristics 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
       characteristics 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 characteristics of the buses do exist. When       
DDI_STRUCTURE_BE_ACC or 
DDI_STRUCTURE_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 hardware 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
                                  consecutive locations. For example, the                                  
CPU can turn two consecutive byte stores
                                  into one half-word store. It can also
                                  batch individual 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_STORECACHING_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
                           hardened: 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
                           anticipated and should be handled as gracefully
                           as possible. 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
                           synchronize across processors on an 
MP machine.
                           "Cautious" 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.
       This example demonstrates the use of the 
ddi_device_acc_attr()       structure in  
ddi_regs_map_setup(9F). It also shows the use of       
ddi_get16(9F) and  
ddi_put16(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_V1;
         dev_attr.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC;
         dev_attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
         dev_attr.devacc_attr_access = DDI_DEFAULT_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_get16(handle, dev_addr);
         dev_command |= DEV_INTR_ENABLE;
         /* store a new value back to the device command register    */
         ddi_put16(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 function, 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_V1;
         dev_attr.devacc_attr_endian_flags = DDI_NEVERSWAP_ACC;
         dev_attr.devacc_attr_dataorder = DDI_UNORDERED_OK_ACC;
         dev_attr.devacc_attr_access = DDI_DEFAULT_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_put32(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
       explicitly 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_V1;
         dev_attr.devacc_attr_endian_flags = DDI_NEVERSWAP_ACC;
         dev_attr.devacc_attr_dataorder= DDI_STRICTORDER_ACC;
         dev_attr.devacc_attr_access = DDI_DEFAULT_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_put16(handle, &dev_blkp->d_command, START_XFER);
         /* Read the 16-bit status register */
         status = ddi_get16(handle, &dev_blkp->d_status);
         if (status & DATA_READY)
                 /* Read 1K bytes off the 32-bit data register */
                 ddi_rep_get32(handle, buf, &dev_blkp->d_data,
                         256, DDI_DEV_NO_AUTOINCR);
ATTRIBUTES
       See 
attributes(7) for descriptions of the following attributes:
       +--------------------+-----------------+
       |  ATTRIBUTE TYPE    | ATTRIBUTE VALUE |
       +--------------------+-----------------+
       |Interface Stability | Committed       |
       +--------------------+-----------------+
SEE ALSO
       attributes(7), 
ddi_fm_acc_err_get(9F), 
ddi_get16(9F), 
ddi_put16(9F),       
ddi_regs_map_setup(9F)       Writing Device Drivers                               August 18, 2019       DDI_DEVICE_ACC_ATTR(9S)