[Return to Library] [Contents] [Previous Chapter] [Next Section] [Next Chapter] [Index] [Help]


3    Structure of EISA/ISA Bus Device Drivers

The sections that make up a Digital UNIX device driver differ, depending on whether the driver is a block, character, or network driver. Figure 3-1 shows the sections that a character device driver can contain and the possible sections that a block device driver can contain. Device drivers do not have to use all of the sections shown in the figure, and more complex drivers can use additional sections. Both character and block device drivers can contain:

The block device driver can also contain a strategy section, a psize section, and a dump section.

The character device driver contains the following sections not contained in a block device driver:

Writing Device Drivers: Tutorial discusses each of the driver sections. The remainder of this chapter describes the differences in the following driver sections as they relate to EISA/ISA bus device drivers: include file and autoconfiguration support (specifically, the xxprobe and xxslave interfaces).

Figure 3-1: Sections of a Character Device Driver and a Block Device Driver


[Return to Library] [Contents] [Previous Chapter] [Next Section] [Next Chapter] [Index] [Help]


3.1    Include Files Section

Data structures and constant values are defined in header files that you include in the Include Files Section of the driver source code. The number and types of header files you specify in the Include Files Section vary, depending on such things as what structures, constants, and kernel interfaces your device driver references. You need to be familiar with:

Writing Device Drivers: Tutorial describes these files. EISA/ISA bus device drivers use the following file in addition to the previously mentioned files:

#include <io/dec/eisa/eisa.h>

The eisa.h file contains definitions specific to EISA/ISA buses.

You must also be familiar with the following name_data.c files:


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


3.2    Autoconfiguration Support Section

When Digital UNIX boots, the kernel determines what EISA/ISA bus devices are connected to the computer. After finding an EISA/ISA bus device, the EISA/ISA bus configuration code initializes it based on the data supplied in the device's configuration file. The probe interface determines if a particular EISA/ISA bus device is present and the attach interface initializes the device. If the device is a disk controller, the slave interface determines if the device is present.

The Autoconfiguration Support Section of an EISA/ISA bus device driver contains the code that implements these interfaces and the section applies to both character and block device drivers. The section can contain:

Writing Device Drivers: Tutorial discusses each of these interfaces.

The following sections describe the xxprobe and xxslave interfaces as they apply to EISA/ISA bus device drivers. For convenience in referring to the names of the driver interfaces, the chapter uses the prefix xx. For example, xxprobe refers to a probe interface for some XX device.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


3.2.1    Setting Up the probe Interface

An EISA/ISA bus device driver's xxprobe interface performs the tasks necessary to determine if the device exists and is functional on a given system. At system startup time, the EISA bus configuration code reads the configuration information saved by the EISA configuration utility (ECU) and performs checks to determine if the device is present before calling xxprobe for statically configured drivers. The EISA bus configuration code calls the xxprobe interface for each device that is defined according to specific rules discussed in Chapter 6.

The ISA bus configuration code reads the data saved by the console firmware's isacfg utility and attempts to match the data to a configured device driver. The matching occurs by using the ISACFG handle and the strings stored in the function member of the isa_option data table that resides in /usr/sys/data/isa_option_data.c.

EISA bus devices must have an ID register that the EISA bus configuration code can use to ensure that the device is present on the system before calling the driver's probe interface. ISA bus devices have no such requirement. Thus drivers for ISA bus devices, whether on either the EISA or ISA bus, should attempt to determine the actual presence of the device in the probe interface probe routine. The methodology to accomplish this is unique to each device. Some predictable device register manipulation is one such method.

The xxprobe interface typically checks some device control status register (CSR) to determine whether the physical device is present. If the device is not present, the device is not initialized and not available for use. In previous versions of the operating system, you defined the device interrupt handlers for static device drivers in the system configuration file or the stanza.static file fragment. At system configuration time, the config program registered the defined device interrupt handlers. For this version of Digital UNIX, Digital recommends that you register the device interrupt handlers for static device drivers in the same way that you register them for loadable device drivers: by calling the handler_add and handler_enable interfaces.

The xxprobe interface returns a nonzero value if the probe operation is successful. It returns the value zero (0) to indicate that the driver did not complete the probe operation.

The arguments you pass to the probe interface differ according to the bus on which the driver operates. The following code fragment shows you how to set up a probe interface for a driver that operates on an EISA or ISA bus:

xxprobe(bus_io_handle, ctlr)
io_handle_t bus_io_handle; [1]
struct controller *ctlr; [2]
{
/* Variable and structure declarations */

.
.
.

/* Code to perform necessary checks */
.
.
.

  1. Specifies an I/O handle that you can use to reference a device register located in the EISA/ISA bus address space. This I/O handle is for the base of the device's slot-specific I/O address space. The EISA bus configuration code passes this I/O handle to the driver's xxprobe interface during device autoconfiguration. You can perform standard C mathematical operations on the I/O handle. For example, you can add an offset to or subtract an offset from the I/O handle.

    Device drivers pass the I/O handle to the following categories of interfaces, which are discussed in Writing Device Drivers: Tutorial. These interfaces can process the I/O handle to access the bus address space they need.

    Section 7.3 shows how the /dev/envram device driver uses the read_io_port and write_io_port interfaces to construct driver-specific interfaces to accomplish the tasks of reading from and writing to the device registers of an EISA bus nonvolatile random-access memory (NVRAM) expansion board. (The /dev/envram driver does not currently accommodate devices that operate on the ISA bus.)

    The /dev/envram device driver example described in Chapter 7 uses the io_copyin, io_copyout, and io_zero interfaces. [Return to example]

  2. Specifies a pointer to the controller structure associated with this device. The bus configuration code passes this pointer to the driver's xxprobe interface. The device driver can reference hardware resources and other information contained in the controller structure pointer. [Return to example]

Section 7.6.1 shows the probe interface for the /dev/envram device driver.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Chapter] [Index] [Help]


3.2.2    Setting Up the slave Interface

A device driver's xxslave interface is called only for a controller that has slave devices connected to it. This interface is called once for each slave attached to the controller. You (or the system manager) specify the attachments of these slave devices as follows:

The following code fragment shows you how to set up a slave interface for a driver that operates on an EISA or ISA bus:

xxslave(device, bus_io_handle)
struct device *device; [1]
io_handle_t bus_io_handle; [2]
{
/* Variable and structure declarations */

.
.
.
/* Code to check that the device is valid */
.
.
.

  1. Specifies a pointer to a device structure for this device. The bus configuration code passes this pointer to the driver's xxslave interface. The device driver can reference such information as the logical unit number of the device, whether the device is functional, and the bus number the device resides on. [Return to example]

  2. Specifies an I/O handle that you can use to reference a device register located in the EISA/ISA bus address space. This I/O handle is for the base of the device's slot-specific I/O address space. The EISA/ISA bus configuration code passes this I/O handle to the driver's xxslave interface during device autoconfiguration. You can perform standard C mathematical operations on the I/O handle. For example, you can add an offset to or subtract an offset from the I/O handle.

    Device drivers pass the I/O handle to the following categories of interfaces, which are discussed in Writing Device Drivers: Tutorial. These interfaces can process the I/O handle to access the bus address space they need.

    [Return to example]