Polling and Interrupts
Each time the device is given a command, for example "move the read head to
sector 42 of the floppy disk" the device driver has a choice as to how it finds
out that the command has completed. The device drivers can either
poll the device or they can use interrupts.
Polling the device usually means reading its status register every so often
until the device's status changes to indicate that it has completed the request.
As a device driver is part of the kernel it would be disasterous if a
driver were to poll, since nothing else in the kernel would run until the device had completed
the request. Instead polling device drivers use system timers to have
the kernel call a routine within the device driver at some later time.
This timer routine would check the status of the command and this is exactly how
Linux's floppy driver works.
Polling by means of timers is at best approximate, a much more efficient method
is to use interrupts.
An interrupt driven device driver is one where the hardware device
being controlled will raise a hardware interrupt whenever it needs to be serviced.
For example, an ethernet
device driver would interrupt whenever it receives an ethernet packet
from the network.
The Linux kernel needs to be able to deliver the interrupt from the hardware
device to the correct device driver.
This is achieved by the device driver registering its usage of the interrupt
with the kernel.
It registers the address of an interrupt handling routine and the interrupt
number that it wishes to own.
You can see which interrupts are being used by the device drivers, as well
as how many of each type of interrupts there have been, by looking at
0: 727432 timer
1: 20534 keyboard
2: 0 cascade
3: 79691 + serial
4: 28258 + serial
5: 1 sound blaster
11: 20868 + aic7xxx
13: 1 math error
14: 247 + ide0
15: 170 + ide1
This requesting of interrupt resources is done at driver initialization time.
Some of the interrupts in the system are fixed, this is a legacy of the IBM PC's
So, for example, the floppy disk controller always uses interrupt 6.
Other interrupts, for example the interrupts from PCI devices are dynamically
allocated at boot time.
In this case the device driver must first discover the interrupt number (IRQ) of
the device that it is controlling before it requests ownership of that
interrupt. For PCI interrupts Linux supports standard PCI BIOS callbacks to determine
information about the devices in the system, including their IRQ numbers.
How an interrupt is delivered to the CPU itself is architecture
dependent but on most architectures the interrupt is delivered in
a special mode that stops other interrupts from happening in the system. A
device driver should do as little as possible in its interrupt
handling routine so that the Linux kernel can dismiss the interrupt and
return to what it was doing before it was interrupted.
Device drivers that need to do a lot of work as a result of receiving an interrupt
can use the kernel's bottom half handlers or task queues to queue
routines to be called later on. Details of bottom half handlers can be found
Interrupts are not the only way the executing of a program can be stopped. This can aslo
occur as the result of exceptions and traps. Details can be found here.