Specifications

Writing a User-Level Device Drive
r
17-11
Overview of Interrupt-Handling Issues 17
A user-level driver can be written to support only polling and provide no interrupt support.
If you write a user-level driver of this type, you can use two methods to allow I/O requests
to be sent to the driver:
1. Permit the application using the driver to send only one I/O request to the
driver at a time.
2. Permit the application using the driver to send multiple I/O requests to the
driver, and require the application to issue an acheck call until acheck
returns an I/O completion status.
When the driver cannot immediately process an I/O request, it adds the
request to a queue. When acheck returns a status indicating that the
current I/O request is complete, it frees the queue entry for the completed
request, checks the queue of pending requests, and issues the next I/O
request.
With either of these methods, the throughput to the device is less than the throughput
obtained with an interrupt-driven user-level driver. A user-level driver that supports only
polling requires the application to issue the next request--either directly (as with the first
method) or indirectly (as with the second method).
A user-level device driver can also be interrupt-driven. In this case, polling can still be
supported via the acheck call. A user-level driver that is interrupt-driven can provide
better throughput to the device than a driver that supports only polling. The reason is that
the interrupt can be used to drive servicing of the next device request. When a user-level
driver that is designed to allow a user to send multiple I/O requests to the driver cannot
immediately process an I/O request, it adds the request to a queue. When the current
device request completes, an interrupt is sent. The interrupt routine checks the queue and
initiates the next device request.
Interrupt support is also required if a user-level driver allows the application to block
waiting for the completion of an I/O request (await). In this case, the interrupt routine
must wake any processes that are waiting for completion of the I/O request.
Using interrupts to drive a user-level device driver adds complexity to the driver because
accesses to shared data that are accessed at both program level and interrupt level must be
synchronized. To handle interrupts, a user-level driver can use the operating system’s
support for user-level interrupt routines. This support allows a user-level process to
connect a routine to an interrupt vector for the interrupt generated by a device. The
connected interrupt routine is run at user-level and has full access to the shared memory
structures of the user-level driver.
An overview of the operating system support for user-level interrupt routines is provided
in “The User-Level Interrupt Library Routines and Utility” on page 17-22. Procedures for
developing the user-level driver’s interrupt routine are explained in “Developing the
Driver’s Interrupt Service Routine” on page 17-34.