diff options
Diffstat (limited to 'linux/dev')
-rw-r--r-- | linux/dev/arch/i386/kernel/irq.c | 93 |
1 files changed, 51 insertions, 42 deletions
diff --git a/linux/dev/arch/i386/kernel/irq.c b/linux/dev/arch/i386/kernel/irq.c index 39f88b6b..a3b34956 100644 --- a/linux/dev/arch/i386/kernel/irq.c +++ b/linux/dev/arch/i386/kernel/irq.c @@ -90,6 +90,49 @@ static struct linux_action *irq_action[16] = }; /* + * Mask an IRQ. + */ +static inline void +mask_irq (unsigned int irq_nr) +{ + int new_pic_mask = curr_pic_mask | 1 << irq_nr; + + if (curr_pic_mask != new_pic_mask) + { + curr_pic_mask = new_pic_mask; + if (irq_nr < 8) + outb (curr_pic_mask & 0xff, PIC_MASTER_OCW); + else + outb (curr_pic_mask >> 8, PIC_SLAVE_OCW); + } +} + +/* + * Unmask an IRQ. + */ +static inline void +unmask_irq (unsigned int irq_nr) +{ + int mask; + int new_pic_mask; + + mask = 1 << irq_nr; + if (irq_nr >= 8) + mask |= 1 << 2; + + new_pic_mask = curr_pic_mask & ~mask; + + if (curr_pic_mask != new_pic_mask) + { + curr_pic_mask = new_pic_mask; + if (irq_nr < 8) + outb (curr_pic_mask & 0xff, PIC_MASTER_OCW); + else + outb (curr_pic_mask >> 8, PIC_SLAVE_OCW); + } +} + +/* * Generic interrupt handler for Linux devices. * Set up a fake `struct pt_regs' then call the real handler. */ @@ -119,6 +162,7 @@ linux_intr (int irq) *prev = action->next; linux_kfree(action); action = *prev; + continue; } } else if (action->handler) @@ -127,52 +171,17 @@ linux_intr (int irq) action = action->next; } - restore_flags (flags); - - intr_count--; -} - -/* - * Mask an IRQ. - */ -static inline void -mask_irq (unsigned int irq_nr) -{ - int new_pic_mask = curr_pic_mask | 1 << irq_nr; - - if (curr_pic_mask != new_pic_mask) + if (!irq_action[irq]) { - curr_pic_mask = new_pic_mask; - if (irq_nr < 8) - outb (curr_pic_mask & 0xff, PIC_MASTER_OCW); - else - outb (curr_pic_mask >> 8, PIC_SLAVE_OCW); + /* No handler any more, disable interrupt */ + mask_irq (irq); + ivect[irq] = intnull; + iunit[irq] = irq; } -} - -/* - * Unmask an IRQ. - */ -static inline void -unmask_irq (unsigned int irq_nr) -{ - int mask; - int new_pic_mask; - - mask = 1 << irq_nr; - if (irq_nr >= 8) - mask |= 1 << 2; - new_pic_mask = curr_pic_mask & ~mask; + restore_flags (flags); - if (curr_pic_mask != new_pic_mask) - { - curr_pic_mask = new_pic_mask; - if (irq_nr < 8) - outb (curr_pic_mask & 0xff, PIC_MASTER_OCW); - else - outb (curr_pic_mask >> 8, PIC_SLAVE_OCW); - } + intr_count--; } /* Count how many subsystems requested to disable each IRQ */ |