diff options
author | John Baldwin <jhb@FreeBSD.org> | 2003-11-19 15:40:23 +0000 |
---|---|---|
committer | John Baldwin <jhb@FreeBSD.org> | 2003-11-19 15:40:23 +0000 |
commit | 6006b8f4c672a699a8d884d52b1797a59aac9307 (patch) | |
tree | d8fc498a1b88d2f241a0e1ea4cc5377de04f98ec /sys/i386 | |
parent | 8c770ed57140328c27168f9d9a0b10ff7650a53e (diff) | |
download | src-6006b8f4c672a699a8d884d52b1797a59aac9307.tar.gz src-6006b8f4c672a699a8d884d52b1797a59aac9307.zip |
Add a special check for a stray IRQ 7 or IRQ 15 to see if it is actually
a spurious interrupt from one of the 8259As. If so, don't log it as a
stray IRQ, but just silently ignore it.
Approved by: re (rwatson)
Notes
Notes:
svn path=/head/; revision=122898
Diffstat (limited to 'sys/i386')
-rw-r--r-- | sys/i386/isa/atpic.c | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/sys/i386/isa/atpic.c b/sys/i386/isa/atpic.c index 2f8c78c2b1bd..7252cbf87a10 100644 --- a/sys/i386/isa/atpic.c +++ b/sys/i386/isa/atpic.c @@ -343,6 +343,28 @@ atpic_handle_intr(struct intrframe iframe) KASSERT((uint)iframe.if_vec < ICU_LEN, ("unknown int %d\n", iframe.if_vec)); isrc = &atintrs[iframe.if_vec].at_intsrc; + + /* + * If we don't have an ithread, see if this is a spurious + * interrupt. + */ + if (isrc->is_ithread == NULL && + (iframe.if_vec == 7 || iframe.if_vec == 15)) { + int port, isr; + + /* + * Read the ISR register to see if IRQ 7/15 is really + * pending. Reset read register back to IRR when done. + */ + port = ((struct atpic *)isrc->is_pic)->at_ioaddr; + mtx_lock_spin(&icu_lock); + outb(port, OCW3_SEL | OCW3_RR | OCW3_RIS); + isr = inb(port); + outb(port, OCW3_SEL | OCW3_RR); + mtx_unlock_spin(&icu_lock); + if ((isr & IRQ7) == 0) + return; + } intr_execute_handlers(isrc, &iframe); } |