patch-2.3.20 linux/arch/i386/kernel/irq.c
Next file: linux/arch/i386/kernel/mtrr.c
Previous file: linux/arch/i386/kernel/io_apic.c
Back to the patch index
Back to the overall index
- Lines: 155
- Date:
Thu Oct 7 10:17:08 1999
- Orig file:
v2.3.19/linux/arch/i386/kernel/irq.c
- Orig date:
Tue Aug 31 17:29:12 1999
diff -u --recursive --new-file v2.3.19/linux/arch/i386/kernel/irq.c linux/arch/i386/kernel/irq.c
@@ -22,7 +22,6 @@
#include <linux/ptrace.h>
#include <linux/errno.h>
-#include <linux/kernel_stat.h>
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/ioport.h>
@@ -30,14 +29,13 @@
#include <linux/timex.h>
#include <linux/malloc.h>
#include <linux/random.h>
-#include <linux/smp.h>
#include <linux/smp_lock.h>
#include <linux/init.h>
+#include <linux/kernel_stat.h>
#include <asm/system.h>
#include <asm/io.h>
#include <asm/bitops.h>
-#include <asm/smp.h>
#include <asm/pgtable.h>
#include <asm/delay.h>
#include <asm/desc.h>
@@ -48,7 +46,7 @@
unsigned int local_bh_count[NR_CPUS];
unsigned int local_irq_count[NR_CPUS];
-atomic_t nmi_counter;
+extern atomic_t nmi_counter[NR_CPUS];
/*
* Linux has a controller-independent x86 interrupt architecture.
@@ -75,7 +73,8 @@
/*
* Controller mappings for all interrupt sources:
*/
-irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned = { [0 ... NR_IRQS-1] = { 0, &no_irq_type, }};
+irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned =
+ { [0 ... NR_IRQS-1] = { 0, &no_irq_type, }};
/*
* Special irq handlers.
@@ -84,6 +83,52 @@
void no_action(int cpl, void *dev_id, struct pt_regs *regs) { }
/*
+ * Generic no controller code
+ */
+
+static void enable_none(unsigned int irq) { }
+static unsigned int startup_none(unsigned int irq) { return 0; }
+static void disable_none(unsigned int irq) { }
+static void ack_none(unsigned int irq)
+{
+/*
+ * 'what should we do if we get a hw irq event on an illegal vector'.
+ * each architecture has to answer this themselves, it doesnt deserve
+ * a generic callback i think.
+ */
+#if CONFIG_X86
+ printk("unexpected IRQ trap at vector %02x\n", irq);
+#ifdef __SMP__
+ /*
+ * Currently unexpected vectors happen only on SMP and APIC.
+ * We _must_ ack these because every local APIC has only N
+ * irq slots per priority level, and a 'hanging, unacked' IRQ
+ * holds up an irq slot - in excessive cases (when multiple
+ * unexpected vectors occur) that might lock up the APIC
+ * completely.
+ */
+ ack_APIC_irq();
+#endif
+#endif
+}
+
+/* startup is the same as "enable", shutdown is same as "disable" */
+#define shutdown_none disable_none
+#define end_none enable_none
+
+struct hw_interrupt_type no_irq_type = {
+ "none",
+ startup_none,
+ shutdown_none,
+ enable_none,
+ disable_none,
+ ack_none,
+ end_none
+};
+
+volatile unsigned long irq_err_count;
+
+/*
* Generic, controller-independent functions:
*/
@@ -106,22 +151,30 @@
#ifndef __SMP__
p += sprintf(p, "%10u ", kstat_irqs(i));
#else
- for (j=0; j<smp_num_cpus; j++)
+ for (j = 0; j < smp_num_cpus; j++)
p += sprintf(p, "%10u ",
kstat.irqs[cpu_logical_map(j)][i]);
#endif
p += sprintf(p, " %14s", irq_desc[i].handler->typename);
p += sprintf(p, " %s", action->name);
- for (action=action->next; action; action = action->next) {
+ for (action=action->next; action; action = action->next)
p += sprintf(p, ", %s", action->name);
- }
*p++ = '\n';
}
- p += sprintf(p, "NMI: %10u\n", atomic_read(&nmi_counter));
-#ifdef __SMP__
- p += sprintf(p, "ERR: %10lu\n", ipi_count);
-#endif
+ p += sprintf(p, "NMI: ");
+ for (j = 0; j < smp_num_cpus; j++)
+ p += sprintf(p, "%10u ",
+ atomic_read(nmi_counter+cpu_logical_map(j)));
+ p += sprintf(p, "\n");
+#if CONFIG_SMP
+ p += sprintf(p, "LOC: ");
+ for (j = 0; j < smp_num_cpus; j++)
+ p += sprintf(p, "%10u ",
+ apic_timer_irqs[cpu_logical_map(j)]);
+ p += sprintf(p, "\n");
+#endif
+ p += sprintf(p, "ERR: %10lu\n", irq_err_count);
return p - buf;
}
@@ -520,7 +573,7 @@
kstat.irqs[cpu][irq]++;
desc = irq_desc + irq;
spin_lock(&irq_controller_lock);
- irq_desc[irq].handler->ack(irq);
+ desc->handler->ack(irq);
/*
REPLAY is when Linux resends an IRQ that was dropped earlier
WAITING is used by probe to mark irqs that are being tested
@@ -570,9 +623,8 @@
spin_unlock(&irq_controller_lock);
}
desc->status &= ~IRQ_INPROGRESS;
- if (!(desc->status & IRQ_DISABLED)){
- irq_desc[irq].handler->end(irq);
- }
+ if (!(desc->status & IRQ_DISABLED))
+ desc->handler->end(irq);
spin_unlock(&irq_controller_lock);
/*
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)