Writing Device Drivers

Interrupt Handler Overview

An interrupt is a hardware signal from a device to the CPU. It tells the CPU that the device needs attention and that the CPU should stop performing what it is doing and respond to the device. If the CPU is available (it is not performing a task with higher priority, such as servicing a higher-priority interrupt), it suspends the current thread and eventually invokes the interrupt handler for that device. The job of the interrupt handler is to service the device and stop it from interrupting. Once the handler returns, the CPU resumes what it was doing before the interrupt occurred.

The Solaris 7 DDI/DKI provides a bus-architecture independent interface for registering and servicing interrupts. Drivers must register their interrupt handlers before they can receive and service interrupts.

Interrupt Specification

The interrupt specification is the information the system needs to link the device interrupt source with a specific device interrupt handler. The specification describes the information provided by the hardware to the system when making an interrupt request. Because an interrupt specification is bus specific, the information it contains varies from bus to bus.

Interrupt specifications typically include a bus-interrupt level. For vectored interrupts the specifications include an interrupt vector. On x86 platforms the interrupt specification defines the relative interrupt priority of the device. Because interrupt specifications are bus specific, see isa(4), eisa(4), mca(4),sbus(4), vme(4), and pci(4) for information on interrupt specifications for these buses.

Interrupt Number

When registering interrupts the driver must provide the system with an interrupt number. This interrupt number identifies the interrupt specification (with bus-specific interrupt information) for which the driver is registering a handler. Most devices have one interrupt--interrupt number equals zero. However, there are devices that have different interrupts for different events. A communications controller may have one interrupt for receive ready and one for transmit ready. The device driver normally knows how many interrupts the device has, but if the driver has to support several variations of a controller, it can call ddi_dev_nintrs(9F) to find out the number of device interrupts. For a device with n interrupts, the interrupt numbers range from 0 to n-1.

Interrupt Block Cookies

The iblock cookie is an opaque data structure that is returned from either ddi_get_iblock_cookie(9F) or ddi_add_intr(9F). These interfaces use an interrupt number to return the iblock cookie associated with a specific interrupt source.

The iblock cookie gives the system information on how to block interrupts. It is passed to mutex_init(9F) when allocating driver mutexes to be used in the interrupt routine. See mutex_init(9F) for more information.

Bus Interrupt Levels

Buses prioritize device interrupts at one of several bus-interrupt levels. These bus interrupt levels are then mapped to different processor-interrupt levels. For example, SBus devices that interrupt at SBus level 7 interrupt at SPARC level 9 on SPARCstation 2 systems.

High-Level Interrupts

A bus interrupt level that maps to a CPU interrupt priority level above the scheduler priority level is called a high-level interrupt. High-level interrupts must be handled without using system services that manipulate threads. In particular, the only kernel routines that high-level interrupt handlers are allowed to call are:

A bus-interrupt level by itself does not determine whether a device interrupts at high level: a given bus-interrupt level may map to a high-level interrupt on one platform, but map to an ordinary interrupt on another platform.

The driver can choose whether to support devices that have high-level interrupts, but it always has to check--it cannot assume that its interrupts are not high level. The function ddi_intr_hilevel(9F), given an interrupt number, returns a value indicating whether the interrupt is high level. For information on checking for high-level interrupts see "Registering Interrupts".