- 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.
This commit is contained in:
jhb 2004-05-03 14:52:41 +00:00
parent 74720a7e3d
commit 7ea4fab234

View File

@ -93,6 +93,10 @@ __FBSDID("$FreeBSD$");
#define SLAVE_MODE BASE_SLAVE_MODE #define SLAVE_MODE BASE_SLAVE_MODE
#endif #endif
#define IMEN_MASK(ai) (1 << (ai)->at_irq)
#define NUM_ISA_IRQS 16
static void atpic_init(void *dummy); static void atpic_init(void *dummy);
unsigned int imen; /* XXX */ unsigned int imen; /* XXX */
@ -166,6 +170,8 @@ static struct atpic_intsrc atintrs[] = {
INTSRC(15), INTSRC(15),
}; };
CTASSERT(sizeof(atintrs) / sizeof(struct atpic_intsrc) == NUM_ISA_IRQS);
static void static void
atpic_enable_source(struct intsrc *isrc) atpic_enable_source(struct intsrc *isrc)
{ {
@ -173,8 +179,10 @@ atpic_enable_source(struct intsrc *isrc)
struct atpic *ap = (struct atpic *)isrc->is_pic; struct atpic *ap = (struct atpic *)isrc->is_pic;
mtx_lock_spin(&icu_lock); mtx_lock_spin(&icu_lock);
*ap->at_imen &= ~(1 << ai->at_irq); if (*ap->at_imen & IMEN_MASK(ai)) {
outb(ap->at_ioaddr + ICU_IMR_OFFSET, *ap->at_imen); *ap->at_imen &= ~IMEN_MASK(ai);
outb(ap->at_ioaddr + ICU_IMR_OFFSET, *ap->at_imen);
}
mtx_unlock_spin(&icu_lock); mtx_unlock_spin(&icu_lock);
} }
@ -185,7 +193,7 @@ atpic_disable_source(struct intsrc *isrc)
struct atpic *ap = (struct atpic *)isrc->is_pic; struct atpic *ap = (struct atpic *)isrc->is_pic;
mtx_lock_spin(&icu_lock); 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); outb(ap->at_ioaddr + ICU_IMR_OFFSET, *ap->at_imen);
mtx_unlock_spin(&icu_lock); 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_intsrc *ai = (struct atpic_intsrc *)isrc;
struct atpic *ap = (struct atpic *)isrc->is_pic; 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 static void
@ -318,10 +326,9 @@ atpic_startup(void)
atpic_enable_source((struct intsrc *)&atintrs[ICU_SLAVEID]); atpic_enable_source((struct intsrc *)&atintrs[ICU_SLAVEID]);
/* Install low-level interrupt handlers for all of our IRQs. */ /* 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) if (i == ICU_SLAVEID)
continue; continue;
ai = &atintrs[i];
ai->at_intsrc.is_count = &ai->at_count; ai->at_intsrc.is_count = &ai->at_count;
ai->at_intsrc.is_straycount = &ai->at_straycount; ai->at_intsrc.is_straycount = &ai->at_straycount;
setidt(((struct atpic *)ai->at_intsrc.is_pic)->at_intbase + setidt(((struct atpic *)ai->at_intsrc.is_pic)->at_intbase +
@ -333,13 +340,14 @@ atpic_startup(void)
static void static void
atpic_init(void *dummy __unused) atpic_init(void *dummy __unused)
{ {
struct atpic_intsrc *ai;
int i; int i;
/* Loop through all interrupt sources and add them. */ /* 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) if (i == ICU_SLAVEID)
continue; 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) SYSINIT(atpic_init, SI_SUB_INTR, SI_ORDER_SECOND + 1, atpic_init, NULL)