[PATCH] Use delayed disable mode of ioapic edge triggered interrupts
authorEric W. Biederman <ebiederm@xmission.com>
Tue, 14 Nov 2006 17:52:12 +0000 (10:52 -0700)
committerLinus Torvalds <torvalds@woody.osdl.org>
Wed, 15 Nov 2006 17:04:32 +0000 (09:04 -0800)
commit45c99533252ef2297f37c5fdd672a3e0eb566870
tree469e706b7a6be19004015e305bdaf4cba4a89a52
parent134a11f0c37c043d3ea557ea15b95b084e3cc2c8
[PATCH] Use delayed disable mode of ioapic edge triggered interrupts

Komuro reports that ISA interrupts do not work after a disable_irq(),
causing some PCMCIA drivers to not work, with messages like

eth0: Asix AX88190: io 0x300, irq 3, hw_addr xx:xx:xx:xx:xx:xx
eth0: found link beat
eth0: autonegotiation complete: 100baseT-FD selected
eth0: interrupt(s) dropped!
eth0: interrupt(s) dropped!
eth0: interrupt(s) dropped!
...

Linus Torvalds <torvalds@osdl.org> said:

  "Now, edge-triggered interrupts are a _lot_ harder to mask, because the
   Intel APIC is an unbelievable piece of sh*t, and has the edge-detect logic
   _before_ the mask logic, so if a edge happens _while_ the device is
   masked, you'll never ever see the edge ever again (unmasking will not
   cause a new edge, so you simply lost the interrupt).

   So when you "mask" an edge-triggered IRQ, you can't really mask it at all,
   because if you did that, you'd lose it forever if the IRQ comes in while
   you masked it. Instead, we're supposed to leave it active, and set a flag,
   and IF the IRQ comes in, we just remember it, and mask it at that point
   instead, and then on unmasking, we have to replay it by sending a
   self-IPI."

This trivial patch solves the problem.

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
Cc: Ingo Molnar <mingo@redhat.com>
Acked-by: Komuro <komurojun-mbn@nifty.com>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
arch/i386/kernel/io_apic.c
arch/x86_64/kernel/io_apic.c