Writing Device Drivers

Address Mapping Setup

Before a driver can access a device's bus address, the bus address spaces must be set up using ddi_regs_map_setup(9F). The driver can then access the device by passing the data access handle returned from ddi_regs_map_setup(9F) to one of the ddi_get8(9F) or ddi_put8(9F) family of routines.

One of the arguments required by ddi_regs_map_setup(9F) is a pointer to a device access attributes structure, ddi_device_acc_attr(9S). The ddi_device_acc_attr(9S) structure describes the data access characteristics and requirements of the device. The ddi_device_acc_attr(9S) structure contains the following members:

	ushort_t   devacc_attr_version;
 	uchar_t    devacc_attr_endian_flags;
 	uchar_t    devacc_attr_dataorder;

devacc_attr_version member identifies the version number of this structure. The current version number is DDI_DEVICE_ATTR_V0.

devacc_attr_endian_flags member describes the endian characteristics of the device. If DDI_NEVERSWAP_ACC is set, data access with no byte swapping is indicated. This flag should be set when no byte swapping is required. For example, if a device does byte-stream I/O, no byte swapping is required. If DDI_STRUCTURE_BE_ACC is set, the device data format is big endian. If DDI_STRUCTURE_LE_ACC is set, the device data format is little endian.

The framework will do any required byte swapping on behalf of the driver based on the flags indicated in devacc_attr_endian_flags and the host's data format endian characteristics.

devacc_attr_dataorder describes the order in which the CPU will reference data. Certain hosts may load or store data in certain orders to pipeline performance. The data ordering may be programmed to execute in one of the following ways:


Note -

The restriction to the hosts diminishes while moving from strong data ordering to cache storing in terms of data accesses by the driver.


The values assigned to devacc_attr_dataorder 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.

A driver for a big-endian device that requires strict data ordering during data accesses would encode the ddi_device_acc_attr structure as follows:

	static ddi_device_acc_attr_t access_attr = {
 		DDI_DEVICE_ATTR_V0,		/* version number */
 		DDI_STRUCTURE_BE_ACC, 	/* big endian */
 		DDI_STRICTORDER_ACC		/* strict ordering */
 	}

The system will use the information stored in the ddi_device_acc_attr structure and other system-specific information to encode an opaque data handle as one of the returned parameters from ddi_map_regs_setup(9F). The returned data handle is used as a parameter to the data access routines (such as ddi_put8(9F) or ddi_get8(9F)) during subsequent accesses to the mapped registers. The driver must never attempt to interpret the contents of the data handle.

If successful, ddi_regs_map_setup(9F) also returns a kernel virtual address that is mapped to the bus address base. The address base may be used as a base reference address in deriving the effective address of other registers by adding the appropriate offset.


Note -

Drivers should not directly dereference the returned address. A driver must access the device through one of the data access functions.