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


3    Structure of a TURBOchannel Device Driver

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 TURBOchannel 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. TURBOchannel device drivers use the following header file exclusively:

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


[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 devices are connected to the computer. After finding a device, the kernel initializes it so that the device can be used at a later time. The probe interface determines if a particular 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 a TURBOchannel 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 remainder of this chapter describes the differences in the xxprobe and xxslave interfaces as they apply to TURBOchannel 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

A device driver's xxprobe interface performs tasks necessary to determine if the device exists and is functional on a given system. The xxprobe interface typically registers a driver's interrupt handlers by using the ihandler_t and handler_intr_info structures and by calling the handler_add and handler_enable interfaces.

Other tasks that the xxprobe interface performs vary, depending on whether the device driver is statically or dynamically configured into the kernel:

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 following code fragment shows you how to set up a probe interface for a driver that operates on a TURBOchannel 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 TURBOchannel bus address space. The TURBOchannel bus configuration code passes this I/O handle to the driver's xxprobe interface during device autoconfiguration. You can perform standard C mathematical operations (addition and subtraction only) 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 desired bus address space.

    The /dev/cb device driver example in Chapter 6 uses the read_io_port and write_io_port 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 6.7.1 shows an implementation of a probe interface for a /dev/cb 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. The following code fragment shows you how to set up a slave interface for a driver that operates on a TURBOchannel bus:

xxslave(dev, addr)
struct device *dev; [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 slave 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 TURBOchannel bus address space. The TURBOchannel bus configuration code passes this I/O handle to the driver's xxslave interface during device autoconfiguration. You can perform standard C mathematical operations (addition and subtraction only) 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 desired bus address space.

    [Return to example]