- 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:
parent
74720a7e3d
commit
7ea4fab234
@ -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)
|
||||||
|
Loading…
Reference in New Issue
Block a user