The Solaris DDI/DKI interfaces are provided for driver portability. With DDI/DKI, developers can write driver code in a standard fashion without having to worry about hardware or platform differences. This section describes aspects of the DDI/DKI interfaces.
The DDI interfaces enable drivers to provide a persistent, unique identifier for a device. The device ID can be used to identify or locate a device. The ID is independent of the device's name or number (dev_t). Applications can use the functions defined in libdevid(3LIB) to read and manipulate the device IDs registered by the drivers.
The attributes of a device or device driver are specified by properties. A property is a name-value pair. The name is a string that identifies the property with an associated value. Properties can be defined by the FCode of a self-identifying device, by a hardware configuration file (see the driver.conf(4) man page), or by the driver itself using the ddi_prop_update(9F) family of routines.
The DDI/DKI addresses the following aspects of device interrupt handling:
Registering device interrupts with the system
Removing device interrupts
Dispatching interrupts to interrupt handlers
Device interrupt sources are contained in a property called interrupt, which is either provided by the PROM of a self-identifying device, in a hardware configuration file, or by the booting system on the x86 platform.
Certain DDI mechanisms provide a callback mechanism. DDI functions provide a mechanism for scheduling a callback when a condition is met. Callback functions can be used for the following typical conditions:
A transfer has completed
A resource has become available
A time-out period has expired
Callback functions are somewhat similar to entry points, for example, interrupt handlers. DDI functions that allow callbacks expect the callback function to perform certain tasks. In the case of DMA routines, a callback function must return a value indicating whether the callback function needs to be rescheduled in case of a failure.
Callback functions execute as a separate interrupt thread. Callbacks must handle all the usual multithreading issues.
A driver must cancel all scheduled callback functions before detaching a device.
To assist device driver writers in allocating state structures, the DDI/DKI provides a set of memory management routines called the software state management routines, also known as the soft-state routines. These routines dynamically allocate, retrieve, and destroy memory items of a specified size, and hide the details of list management. An instance number is used to identify the desired memory item. This number is typically the instance number assigned by the system.
Routines are provided for the following tasks:
Initialize a driver's soft-state list
Allocate space for an instance of a driver's soft state
Retrieve a pointer to an instance of a driver's soft state
Free the memory for an instance of a driver's soft state
Finish using a driver's soft-state list
See Loadable Driver Interfaces for an example of how to use these routines.
Programmed I/O device access is the act of reading and writing of device registers or device memory by the host CPU. The Solaris DDI provides interfaces for mapping a device's registers or memory by the kernel as well as interfaces for reading and writing to device memory from the driver. These interfaces enable drivers to be developed that are platform and bus independent, by automatically managing any difference in device and host endianness as well as by enforcing any memory-store sequence requirements imposed by the device.
The Solaris platform defines a high-level, architecture-independent model for supporting DMA-capable devices. The Solaris DDI shields drivers from platform-specific details. This concept enables a common driver to run on multiple platforms and architectures.
The DDI/DKI provides a group of interfaces referred to as layered device interfaces (LDI). These interfaces enable a device to be accessed from within the Solaris kernel. This capability enables developers to write applications that observe kernel device usage. For example, both the prtconf(1M) and fuser(1M) commands use LDI to enable system administrators to track aspects of device usage. The LDI is covered in more detail in Chapter 14, Layered Driver Interface (LDI).