The interrupt handler is called when an interrupt is received which may be from this
particular device. The ISA bus does not support interrupt sharing (except in some special
cases) so in practice if the interrupt handler is called then the interrupt almost for
sure came from its device. Still, the interrupt handler must poll the device registers
and make sure that the interrupt was generated by its device. If not it should just
return.
The old convention for the ISA drivers was getting the device unit number as an
argument. This is obsolete, and the new drivers receive whatever argument was specified
for them in the attach routine when calling bus_setup_intr(). By the new convention it should be the pointer
to the structure softc. So the interrupt handler commonly starts as:
static void
xxx_intr(struct xxx_softc *sc)
{
It runs at the interrupt priority level specified by the interrupt type parameter of
bus_setup_intr(). That means that all the other interrupts
of the same type as well as all the software interrupts are disabled.
To avoid races it is commonly written as a loop:
while(xxx_interrupt_pending(sc)) {
xxx_process_interrupt(sc);
xxx_acknowledge_interrupt(sc);
}
The interrupt handler has to acknowledge interrupt to the device only but not to the
interrupt controller, the system takes care of the latter.