Writing an Interrupt Service Routine (ISR)

< BACK  NEXT >
[oR]

Once the device operation begins, the actual data transfer is driven by the arrival of hardware interrupts. When an interrupt arrives, the driver's Interrupt Service routine acknowledges the request and either transfers the next piece of data or invokes a DPC routine.

Execution Context

When the kernel receives a device interrupt, it uses its collection of interrupt objects to locate an ISR willing to service the event. It does this by running through all the interrupt objects attached to the DIRQL of the interrupt and calling ISRs until one of them claims the interrupt.

The kernel interrupt dispatcher calls an ISR at the synchronization IRQL specified in the call to IoConnectInterrupt. Usually this is the DIRQL level of the device. The kernel dispatcher also acquires and releases the device spin lock.

Running at such a high IRQL, there are several things an ISR isn't allowed to do. In addition to the usual warning about page faults, an ISR shouldn't try to allocate or free various system resources (like memory). If system support routines must be called from an ISR, check for restrictions on the level of which they can be run. Such calls might require delegation to a DPC routine.

As shown in Table 8.5, the kernel passes a pointer to whatever context information was identified in the original call to IoConnectInterrupt. Most often, this is a pointer to the Device or Controller Extension.

What the Interrupt Service Routine Does

The Interrupt Service routine is the real workhorse in a programmed I/O driver. In general, one of these routines does the following:

  1. Determine if the interrupt belongs to this driver. If not, immediately return a value of FALSE.

  2. Perform any operations needed by the device to acknowledge the interrupt.

  3. Determine if any more data remains to be transferred. If so, start the next device operation. This eventually results in another interrupt.

  4. If all the data has been transferred (or if a device error occurred), queue up a DPC request by calling IoRequestDpc.

  5. Return a value of TRUE.

Always code an ISR for speed. Any work that isn't absolutely essential should go in a DPC routine. It is especially important that an ISR determine whether or not it will handle an interrupt immediately. There may be a number of other ISRs waiting in line for a given interrupt, and nonessential preprocessing blocks their proper operation.

Table 8.5. Function Prototype for an Interrupt Service Routine
BOOLEAN ISR IRQL == DIRQL
Parameter Description
IN PKINTERRUPT pInterruptObj Interrupt object generating interrupt
IN PVOID pServiceContext Context area passed to IoConnectInterrupt
Return value TRUE-interrupt was serviced by ISR
FALSE-interrupt not serviced

< BACK  NEXT >


The Windows 2000 Device Driver Book(c) A Guide for Programmers
The Windows 2000 Device Driver Book: A Guide for Programmers (2nd Edition)
ISBN: 0130204315
EAN: 2147483647
Year: 2000
Pages: 156

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net