The following sections review the tasks associated with writing device drivers. Writing Device Drivers: Tutorial discusses these tasks in detail. The chapter concludes with a section that discusses VMEbus porting information. You should read this section if you have written VMEbus device drivers for previous versions of the Digital UNIX operating system.
1.1 Gathering Information
The first task in writing a device driver is to gather pertinent information
about the host system and the device for which you are writing the driver.
For
example, you need to:
1.2 Designing a Device Driver
After
you gather information about the host system and the device, you are ready
to design and develop the device driver. You need to specify the driver type
and whether the driver you are writing will be statically or dynamically configured
into the kernel. During the design of the driver, you also identify device
driver entry points and describe the driver states.
1.3 Allocating Data Structures
Data structures are
the mechanism used to pass information between the kernel and device driver
interfaces. The following table summarizes data structures, which are described
in Writing Device Drivers: Tutorial and Writing Device Drivers: Reference:
| Assign_table | Defines members used in device special file creation. |
| buf | Describes arbitrary I/O. |
| bus | Represents an instance of a bus entity to which other buses or controllers are logically attached. |
| cfg_attr_t | Contains information for managing the loading and unloading of drivers. |
| cfg_subsys_attr_t | Contains attribute information for drivers. |
| controller | Contains members that store information about hardware resources and store data for communication between the kernel and the device driver. |
| controller_config | Contains information needed to create a controller structure. |
| DEVGEOMST | Stores disk device geometry. |
| devget | Contains information about a device. |
| device | Contains information that identifies the device. There is one device data structure for each device connected to the controller. |
| device_config | Contains information needed to create a device structure. |
| device_info_t | Is the top-level union that stores bus- and device-type information. |
| disklabel | Stores disk device label information. |
| driver | Defines driver entry points and other driver-specific information. You initialize this data structure in the device driver. |
| dsent | Defines a device driver's entry points and other information. |
| handler_intr_info | Contains interrupt handler information. |
| ihandler_t | Contains information associated with device driver interrupt handling. |
| item_list | Contains hardware platform-specific information. |
| lock | Contains complex lock-specific information. |
| port | Contains information about a port. |
| pt | Stores disk device partition information. |
| pt_tbl | Stores a disk partition map. |
| sel_queue | Defines a queue of select events. |
| sg_entry | Contains bus address/byte count pairs. |
| slock | Contains simple lock-specific information. |
| task | Contains task-specific information. |
| thread | Contains kernel threads-related information. |
| uio | Describes I/O, either single vector or multiple vectors. |
| v1_bustype_info_t | Stores bus information. |
| v1_device_info_t | Is the top-level union that stores bus- and device-type information. |
| v1_devtype_info_t | Stores device-type information. |
| v1_disk_dev_info_t | Stores disk information. |
| v1_tape_dev_info_t | Stores tape information. |
Chapter 4 reviews the members of the controller and driver structures that are specific to the VMEbus.
When designing a device driver, you must decide
on the technique you will use for allocating data structures. Generally, there
are two techniques you can use: dynamic allocation and static allocation.
Dynamic allocation is the recommended method for all new drivers; some existing
drivers allocate data structures statically. If you know that the maximum
number of devices is greater than five or that the driver uses numerous data
structures, plan to use the dynamic allocation method. You should also use
the dynamic allocation method for allocating data structures in loadable device
drivers.
You need to consider the following issues to make your drivers portable
across bus architectures:
You must consider these issues also if you have an ULTRIX device driver
that you want to port to Digital UNIX. See Writing Device Drivers:
Tutorial for a discussion of the additional tasks you need to
perform to port an ULTRIX device driver to Digital UNIX. Also, see the porting
chapter in Writing Device Drivers: Tutorial for a discussion
of the issues associated with updating device drivers written for a previous
version of Digital UNIX to the current version of the operating system. Although
existing device drivers are binary compatible with the current version of
Digital UNIX, you might want to make the changes suggested in the porting
chapter of the tutorial.
See Writing Device Drivers: Tutorial for information
on the I/O copy operation interfaces io_copyin, io_copyio, io_copyout, and io_zero.
These are generic interfaces that map to bus- and machine-specific interfaces
that actually perform the I/O copy operations. Using these interfaces to perform
copy operations makes the device driver more portable across different CPU
architectures and different CPU types within the same architecture. Each of
these interfaces takes an I/O handle that the bus configuration code passes
to the driver's probe interface.
Writing Device Drivers: Tutorial describes the
device driver kits delivery process and how to statically and dynamically
configure drivers into the kernel. The tutorial discusses how to write device
drivers for computer systems running Digital UNIX.
Section 6.5 provides an example of adding
VMEbus interrupt handlers. As described in the tutorial, VMEbus device
drivers must use the structure vme_handler_info rather
than handler_intr_info when using the interrupt handler
handler interfaces. The structure vme_handler_info
includes handler_intr_info as a member.
Previous versions of the operating system provided VMEbus device driver
writers with numerous VMEbus-specific interfaces. To promote the portability
of device drivers across different bus and CPU architectures, this version
of Digital UNIX eliminates some of the VMEbus-specific interfaces and replaces
them with more generic interfaces. Table 1-2
shows the existing VMEbus interfaces and the associated
generic interfaces that VMEbus device drivers should call. A None in the second
column indicates that the interface is no longer available in this version
of the Digital UNIX operating system.
1.4 Writing Portable Device Drivers
Whenever
possible, design your device driver so that it can accommodate peripheral
devices that operate on different bus architectures, different CPU architectures,
and more than one CPU type within the same architecture. You need to consider
the following issues to make your drivers portable across CPU architectures:
Note
1.5 Reviewing the Device Driver Kits Delivery Process
When you are ready to write your driver, you
may want to study the device driver kits delivery process and create an appropriate
device driver development environment.
1.6 Identifying the Method for Registering Device Interrupt Handlers
For this version
of Digital UNIX, Digital requires that you implement all new VMEbus device
drivers to call the handler interfaces and reference the
handler-specific data structures to register their device interrupt handlers.
(See Writing Device Drivers: Tutorial for more
information.)
1.7 VMEbus Porting Information
One of the goals of an open systems environment is to provide
hardware and software platforms that promote the use of standards. By adhering
to a set of standard interfaces, these platforms make it easier for third-party
application programmers to write applications that can run on a variety of
operating systems and hardware. The Digital UNIX operating system adheres
to this philosophy by providing kernel interfaces that device drivers operating
on any bus can use. Writing Device Drivers: Tutorial
provides examples of how to use many of these interfaces.
The following are VMEbus interfaces that VMEbus device drivers can still call: