diff options
author | jhb <jhb@FreeBSD.org> | 2004-05-03 14:52:41 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2004-05-03 14:52:41 +0000 |
commit | 7ea4fab234ee89fcd9911a1dc05214f5ec956001 (patch) | |
tree | 4d14a2e620bf8d863dfb66cd5c945c21dbe0f37c /sys/i386/isa | |
parent | 74720a7e3d63b5597281038fcbaf7e705e15ef9b (diff) | |
download | FreeBSD-src-7ea4fab234ee89fcd9911a1dc05214f5ec956001.zip FreeBSD-src-7ea4fab234ee89fcd9911a1dc05214f5ec956001.tar.gz |
- Add an IMEN_MASK macro that returns the 8-bit bitmask of an atpic
interrupt source.
- Only do an outb() to the PIC to clear a bit in imen if the bit is set.
- Add a NUM_ISA_IRQS macro to replace uglier
'sizeof(array) / sizeof(member)' expressions along with a CTASSERT() to
ensure that the macro is correct.
Diffstat (limited to 'sys/i386/isa')
-rw-r--r-- | sys/i386/isa/atpic.c | 24 |
1 files changed, 16 insertions, 8 deletions
diff --git a/sys/i386/isa/atpic.c b/sys/i386/isa/atpic.c index 6344539..0498252 100644 --- a/sys/i386/isa/atpic.c +++ b/sys/i386/isa/atpic.c @@ -93,6 +93,10 @@ __FBSDID("$FreeBSD$"); #define SLAVE_MODE BASE_SLAVE_MODE #endif +#define IMEN_MASK(ai) (1 << (ai)->at_irq) + +#define NUM_ISA_IRQS 16 + static void atpic_init(void *dummy); unsigned int imen; /* XXX */ @@ -166,6 +170,8 @@ static struct atpic_intsrc atintrs[] = { INTSRC(15), }; +CTASSERT(sizeof(atintrs) / sizeof(struct atpic_intsrc) == NUM_ISA_IRQS); + static void atpic_enable_source(struct intsrc *isrc) { @@ -173,8 +179,10 @@ atpic_enable_source(struct intsrc *isrc) struct atpic *ap = (struct atpic *)isrc->is_pic; mtx_lock_spin(&icu_lock); - *ap->at_imen &= ~(1 << ai->at_irq); - outb(ap->at_ioaddr + ICU_IMR_OFFSET, *ap->at_imen); + if (*ap->at_imen & IMEN_MASK(ai)) { + *ap->at_imen &= ~IMEN_MASK(ai); + outb(ap->at_ioaddr + ICU_IMR_OFFSET, *ap->at_imen); + } mtx_unlock_spin(&icu_lock); } @@ -185,7 +193,7 @@ atpic_disable_source(struct intsrc *isrc) struct atpic *ap = (struct atpic *)isrc->is_pic; mtx_lock_spin(&icu_lock); - *ap->at_imen |= (1 << ai->at_irq); + *ap->at_imen |= IMEN_MASK(ai); outb(ap->at_ioaddr + ICU_IMR_OFFSET, *ap->at_imen); mtx_unlock_spin(&icu_lock); } @@ -243,7 +251,7 @@ atpic_source_pending(struct intsrc *isrc) struct atpic_intsrc *ai = (struct atpic_intsrc *)isrc; struct atpic *ap = (struct atpic *)isrc->is_pic; - return (inb(ap->at_ioaddr) & (1 << ai->at_irq)); + return (inb(ap->at_ioaddr) & IMEN_MASK(ai)); } static void @@ -318,10 +326,9 @@ atpic_startup(void) atpic_enable_source((struct intsrc *)&atintrs[ICU_SLAVEID]); /* Install low-level interrupt handlers for all of our IRQs. */ - for (i = 0; i < sizeof(atintrs) / sizeof(struct atpic_intsrc); i++) { + for (i = 0, ai = atintrs; i < NUM_ISA_IRQS; i++, ai++) { if (i == ICU_SLAVEID) continue; - ai = &atintrs[i]; ai->at_intsrc.is_count = &ai->at_count; ai->at_intsrc.is_straycount = &ai->at_straycount; setidt(((struct atpic *)ai->at_intsrc.is_pic)->at_intbase + @@ -333,13 +340,14 @@ atpic_startup(void) static void atpic_init(void *dummy __unused) { + struct atpic_intsrc *ai; int i; /* Loop through all interrupt sources and add them. */ - for (i = 0; i < sizeof(atintrs) / sizeof(struct atpic_intsrc); i++) { + for (i = 0, ai = atintrs; i < NUM_ISA_IRQS; i++, ai++) { if (i == ICU_SLAVEID) continue; - intr_register_source(&atintrs[i].at_intsrc); + intr_register_source(&ai->at_intsrc); } } SYSINIT(atpic_init, SI_SUB_INTR, SI_ORDER_SECOND + 1, atpic_init, NULL) |