patch-2.1.120 linux/arch/i386/kernel/io_apic.c
Next file: linux/arch/i386/kernel/irq.c
Previous file: linux/arch/i386/kernel/entry.S
Back to the patch index
Back to the overall index
- Lines: 148
- Date:
Mon Aug 31 16:03:17 1998
- Orig file:
v2.1.119/linux/arch/i386/kernel/io_apic.c
- Orig date:
Tue Aug 18 22:02:02 1998
diff -u --recursive --new-file v2.1.119/linux/arch/i386/kernel/io_apic.c linux/arch/i386/kernel/io_apic.c
@@ -921,9 +921,10 @@
static inline void self_IPI(unsigned int irq)
{
irq_desc_t *desc = irq_desc + irq;
+ unsigned int status = desc->status;
- if (desc->events && !desc->ipi) {
- desc->ipi = 1;
+ if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) {
+ desc->status = status | IRQ_REPLAY;
send_IPI(APIC_DEST_SELF, IO_APIC_VECTOR(irq));
}
}
@@ -960,6 +961,7 @@
{
irq_desc_t *desc = irq_desc + irq;
struct irqaction * action;
+ unsigned int status;
spin_lock(&irq_controller_lock);
@@ -968,19 +970,19 @@
* and do not need to be masked.
*/
ack_APIC_irq();
- desc->ipi = 0;
- desc->events = 1;
+ status = desc->status & ~IRQ_REPLAY;
+ status |= IRQ_PENDING;
/*
* If the IRQ is disabled for whatever reason, we cannot
* use the action we have.
*/
action = NULL;
- if (!(desc->status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
+ if (!(status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
action = desc->action;
- desc->status = IRQ_INPROGRESS;
- desc->events = 0;
+ status &= ~IRQ_PENDING;
}
+ desc->status = status | IRQ_INPROGRESS;
spin_unlock(&irq_controller_lock);
/*
@@ -996,18 +998,15 @@
* pending events.
*/
for (;;) {
- int pending;
-
handle_IRQ_event(irq, regs);
spin_lock(&irq_controller_lock);
- pending = desc->events;
- desc->events = 0;
- if (!pending)
+ if (!(desc->status & IRQ_PENDING))
break;
+ desc->status &= ~IRQ_PENDING;
spin_unlock(&irq_controller_lock);
}
- desc->status &= IRQ_DISABLED;
+ desc->status &= ~IRQ_INPROGRESS;
spin_unlock(&irq_controller_lock);
irq_exit(cpu, irq);
@@ -1018,6 +1017,7 @@
{
irq_desc_t *desc = irq_desc + irq;
struct irqaction * action;
+ unsigned int status;
spin_lock(&irq_controller_lock);
/*
@@ -1029,18 +1029,17 @@
* So this all has to be within the spinlock.
*/
mask_IO_APIC_irq(irq);
-
- desc->ipi = 0;
+ status = desc->status & ~IRQ_REPLAY;
/*
* If the IRQ is disabled for whatever reason, we must
* not enter the IRQ action.
*/
action = NULL;
- if (!(desc->status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
+ if (!(status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
action = desc->action;
- desc->status = IRQ_INPROGRESS;
}
+ desc->status = status | IRQ_INPROGRESS;
ack_APIC_irq();
spin_unlock(&irq_controller_lock);
@@ -1055,7 +1054,7 @@
spin_lock(&irq_controller_lock);
desc->status &= ~IRQ_INPROGRESS;
- if (!desc->status)
+ if (!(desc->status & IRQ_DISABLED))
unmask_IO_APIC_irq(irq);
spin_unlock(&irq_controller_lock);
@@ -1160,6 +1159,31 @@
}
}
+/*
+ *
+ * IRQ's that are handled by the old PIC in all cases:
+ * - IRQ2 is the cascade IRQ, and cannot be a io-apic IRQ.
+ * Linux doesn't really care, as it's not actually used
+ * for any interrupt handling anyway.
+ * - IRQ13 is the FPU error IRQ, and may be connected
+ * directly from the FPU to the old PIC. Linux doesn't
+ * really care, because Linux doesn't want to use IRQ13
+ * anyway (exception 16 is the proper FPU error signal)
+ * - IRQ9 is broken on PIIX4 motherboards:
+ *
+ * "IRQ9 cannot be re-assigned"
+ *
+ * IRQ9 is not available to assign to
+ * ISA add-in cards because it is
+ * dedicated to the power
+ * management function of the PIIX4
+ * controller on the motherboard.
+ * This is true for other motherboards
+ * which use the 82371AB PIIX4
+ * component.
+ */
+#define PIC_IRQS ((1<<2)|(1<<9)|(1<<13))
+
void __init setup_IO_APIC(void)
{
init_sym_mode();
@@ -1177,7 +1201,7 @@
pirqs_enabled)
{
printk("ENABLING IO-APIC IRQs\n");
- io_apic_irqs = ~((1<<2)|(1<<9)|(1<<13));
+ io_apic_irqs = ~PIC_IRQS;
} else {
if (ioapic_blacklisted())
printk(" blacklisted board, DISABLING IO-APIC IRQs\n");
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov