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

     Solaris DDI specific (Solaris 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;

     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
     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 describes the
     endian  characteristics  of  the  device  as  big-endian  or
     little-endian, respectively. Though most of the devices will
     have  the  same endian characteristics as their buses, exam-
     ples 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  order  in  which
     the   CPU  will reference data. Specify one of the following
     values.

          DDI_STRICTORDER_ACC
                The data references must be issued by  a  CPU  in
                program  order.  Strict  ordering  is the default
                behavior.

          DDI_UNORDERED_OK_ACC
                The  CPU  can re-order the data references.  This
                includes all kinds of re-ordering. For example, a
                load followed by a store may  be  replaced  by  a
                store followed by a load.

          DDI_MERGING_OK_ACC
                The  CPU can merge individual stores to  consecu-
                tive   locations.   For example, the CPU can turn
                two consecutive byte  stores  into  one  halfword
                store.  It  can also batch individual loads.  For
                example, the CPU might turn two consecutive  byte
                loads  into one halfword load. DDI_MERGING_OK_ACC
                also implies re-ordering.

          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
                re-ordering.

          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 re-ordering.

     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.


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()  structure 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"   pro-
     perty  list  for this purpose. The size of the address space
     is 128 Kbyte with each 32 Kbyte range as  a  separate  aper-
     ture.  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_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  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_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);


SEE ALSO

     ddi_getw(9F), ddi_putw(9F), ddi_regs_map_setup(9F)

     Writing Device Drivers


Man(1) output converted with man2html