Protect against broken hardware. In this particular case, protect against
H/W not de-asserting the interrupt at all. On x86, and because of the
following conditions, this results in a hard hang with interrupts disabled:
- The uart(4) driver uses a spin lock to protect against concurrent access to the H/W. Spin locks disable and restore interrupts.
- Restoring the interrupt on x86 always writes the flags register. Even if we're restoring the interrupt from disabled to disabled.
- The x86 CPU has a short window in which interrupts are enabled when the flags register is written.
- The uart(4) driver registers a fast interrupt by default.
To catch this case, we first try to clear any pending H/W interrupts and in
particular, before setting up the interrupt. This makes sure the interrupt
is masked on the PIC. The interrupt handler now has a limit set on the
number of iterations it'll go through to clear interrupt conditions. If the
limit is hit, the handler will return FILTER_SCHEDULE_THREAD. The attach
function will check for this return code and avoid setting up the interrupt
and foce polling in that case.
Obtained from: Juniper Networks, Inc.