Sun Microsystems, Inc.
spacerspacer
spacer www.sun.com docs.sun.com |
spacer
black dot
 
 
  Previous   Contents   Next 
   
 
Chapter 2

Overview of Solaris Device Drivers

This chapter gives an overview of Solaris device drivers. It provides information on the following subjects:

What Is a Device Driver?

A device driver is a kernel module responsible for managing low-level I/O operations for a particular hardware device. Device drivers can also be software-only, emulating a device that exists only in software, such as a RAM disk or a pseudo-terminal.

A device driver contains all the device-specific code necessary to communicate with a device and provides a standard set of interfaces to the rest of the system. This interface protects the kernel from device specifics just as the system call interface protects application programs from platform specifics. Application programs and the rest of the kernel need little (if any) device-specific code to address the device. In this way, device drivers make the system more portable and easier to maintain.

Types of Device Drivers

There are several kinds of device drivers, each handling a different kind of I/O. Block device drivers manage devices with physically addressable storage media, such as disks. All other devices are considered character devices. Two types of character device drivers are standard character device drivers and STREAMS device drivers.

Block Device Drivers

Devices that support a file system are known as block devices. Drivers written for these devices are known as block device drivers. Block device drivers take a file system request, in the form of a buf(9S) structure, and issue the I/O operations to the disk to transfer the specified block. The main interface to the file system is the strategy(9E) routine. See Chapter 11, Drivers for Block Devices for more information.

Block device drivers can also provide a character driver interface that allows utility programs to bypass the file system and access the device directly. This device access is commonly referred to as the raw interface to a block device.

Character Device Drivers

Character device drivers normally perform I/O in a byte stream. Examples of devices using character drivers include tape drives and serial ports. Character device drivers can also provide additional interfaces not present in block drivers, such as I/O control (ioctl) commands, memory mapping, and device polling. See Chapter 10, Drivers for Character Devices for more information.

Byte-Stream I/O

The main task of any device driver is to perform I/O, and many character device drivers do what is called byte-stream or character I/O. The driver transfers data to and from the device without using a specific device address. This is in contrast to block device drivers, where part of the file system request identifies a specific location on the device.

The read(9E) and write(9E) entry points handle byte-stream I/O for standard character drivers. See "I/O Request Handling" for more information.

Memory Mapped Devices

For certain devices, such as frame buffers, application programs having direct access to device memory is more efficient than byte-stream I/O. Applications can map device memory into their address spaces using the mmap(2) system call. To support memory mapping, device drivers implement segmap(9E) and devmap(9E) entry points. For information on devmap(9E), see Chapter 12, Mapping Device and Kernel Memory. For information on segmap(9E), see Chapter 10, Drivers for Character Devices.

Drivers that define the devmap(9E) entry point usually do not define read(9E) and write(9E) entry points, as application programs perform I/O directly to the devices after calling mmap(2).

STREAMS Drivers

STREAMS is a separate programming model for writing a character driver. Devices that receive data asynchronously (such as terminal and network devices) are suited to a STREAMS implementation. STREAMS device drivers must provide the loading and autoconfiguration support described in Chapter 5, Driver Autoconfiguration. See the Streams Programming Guide for additional information on how to write STREAMS drivers.

Driver Module Entry Points

Each device driver defines a standard set of functions called entry points, which are listed in Intro(9E). These entry points are called by the Solaris kernel to load and unload the driver, autoconfigure devices, and provide the character, block, or STREAMS driver I/O services. Drivers for different types of devices have different sets of entry points according to the kinds of operations the devices perform. A driver for a memory-mapped character-oriented device, for example, supports a devmap(9E) entry point, while a block driver does not support this entry.

Figure 2-1 Device Driver Overview

Some operations are common to all drivers, such as the functions that are required for module loading (_init(9E), _info(9E), and _fini(9E)), and the required autoconfiguration entry points attach(9E), detach(9E), and getinfo(9E). Drivers also support the optional autoconfiguration entry point for probe(9E). Most leaf drivers have open(9E) and close(9E) entry points to control access to their devices.

Traditionally, all driver function and variable names have some prefix added to them. Usually this is the name of the driver, such as xxopen() for the open(9E) routine of driver xx. In subsequent examples, xx is used as the driver prefix.


Note - In the Solaris 9 operating environment, only the loadable module routines must be visible outside the driver object module. Other routines can have the storage class static.


Loadable Module Entry Points

All drivers are required to implement the loadable module entry points _init(9E), _fini(9E), and _info(9E) to load, unload, and report information about the driver module.

Drivers should allocate and initialize any global resources in _init(9E) and release their resources in _fini(9E).

Autoconfiguration Entry Points

Drivers are required to implement the attach(9E), detach(9E), and getinfo(9E) entry points for device autoconfiguration. Drivers might need to implement probe(9E) if the driver supports devices that are not self identifying, such as SCSI target devices. See Chapter 5, Driver Autoconfiguration for more information on these routines.

Character and Block Driver Entry Points

Drivers for character and block devices export a cb_ops(9S) structure, which defines the driver entry points for block device access and character device access. Both types of drivers are required to support open(9E) and close(9E). Block drivers are required to support strategy(9E), while character drivers can choose to implement whatever mix of read(9E), write(9E), ioctl(9E), mmap(9E), or devmap(9E) entry points as appropriate for the type of device. Character drivers can also support a polling interface through chpoll(9E), as well as asynchronous I/O through aread(9E) and awrite(9E).

For information on character driver entry points, see Chapter 10, Drivers for Character Devices. For information on block driver entry points, see Chapter 11, Drivers for Block Devices.

Power Management Entry Point

Drivers for hardware devices that provide Power Management functionality can support the optional power(9E) entry point. See Chapter 9, Power Management for details about this entry point.

Device Driver Design Considerations

Device driver must be compatible with the Solaris operating environment, both as a consumer and provider of services. This section discusses the following issues which should be considered in device driver design:

DDI/DKI Facilities

This section discusses design considerations necessary for using the DDI/DKI interfaces.

Device IDs

The Solaris DDI provides interfaces that allow drivers to provide a persistent, unique identifier for a device. The device ID can be used to identify or locate a device and 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.

Device Properties

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.

Interrupt Handling

The Solaris 9 DDI/DKI addresses these 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 IA platform.

 
 
 
  Previous   Contents   Next