patch-2.1.115 linux/arch/i386/kernel/irq.c
Next file: linux/arch/i386/kernel/irq.h
Previous file: linux/arch/i386/kernel/io_apic.c
Back to the patch index
Back to the overall index
- Lines: 190
- Date:
Tue Aug 4 10:52:50 1998
- Orig file:
v2.1.114/linux/arch/i386/kernel/irq.c
- Orig date:
Tue Jul 21 00:15:30 1998
diff -u --recursive --new-file v2.1.114/linux/arch/i386/kernel/irq.c linux/arch/i386/kernel/irq.c
@@ -48,27 +48,23 @@
/*
* About the IO-APIC, the architecture is 'merged' into our
* current irq architecture, seemlessly. (i hope). It is only
- * visible through 8 more hardware interrupt lines, but otherwise
- * drivers are unaffected. The main code is believed to be
- * NR_IRQS-safe (nothing anymore thinks we have 16
+ * visible through a few more more hardware interrupt lines, but
+ * otherwise drivers are unaffected. The main code is believed
+ * to be NR_IRQS-safe (nothing anymore thinks we have 16
* irq lines only), but there might be some places left ...
*/
/*
* This contains the irq mask for both 8259A irq controllers,
- * and on SMP the extended IO-APIC IRQs 16-23. The IO-APIC
- * uses this mask too, in probe_irq*().
- *
- * (0x0000ffff for NR_IRQS==16, 0x00ffffff for NR_IRQS=24)
*/
-#if NR_IRQS == 64
-unsigned long long cached_irq_mask = -1;
-#else
-unsigned long long cached_irq_mask = (((unsigned long long) 1)<<NR_IRQS)-1;
-#endif
+static unsigned int cached_irq_mask = 0xffff;
+
+#define __byte(x,y) (((unsigned char *)&(y))[x])
+#define __word(x,y) (((unsigned short *)&(y))[x])
+#define __long(x,y) (((unsigned int *)&(y))[x])
-#define cached_21 ((cached_irq_mask | io_apic_irqs) & 0xff)
-#define cached_A1 (((cached_irq_mask | io_apic_irqs) >> 8) & 0xff)
+#define cached_21 (__byte(0,cached_irq_mask))
+#define cached_A1 (__byte(1,cached_irq_mask))
spinlock_t irq_controller_lock;
@@ -81,18 +77,11 @@
* this 'mixed mode' IRQ handling costs us one more branch in do_IRQ,
* but we have _much_ higher compatibility and robustness this way.
*/
-
-/*
- * Default to all normal IRQ's _not_ using the IO APIC.
- *
- * To get IO-APIC interrupts we turn some of them into IO-APIC
- * interrupts during boot.
- */
unsigned long long io_apic_irqs = 0;
static void do_8259A_IRQ (unsigned int irq, int cpu, struct pt_regs * regs);
-static void enable_8259A_irq (unsigned int irq);
-static void disable_8259A_irq (unsigned int irq);
+static void enable_8259A_irq(unsigned int irq);
+void disable_8259A_irq(unsigned int irq);
/*
* Dummy controller type for unused interrupts
@@ -127,10 +116,10 @@
* These have to be protected by the irq controller spinlock
* before being called.
*/
-
-static inline void mask_8259A(unsigned int irq)
+void disable_8259A_irq(unsigned int irq)
{
- cached_irq_mask |= 1 << irq;
+ unsigned int mask = 1 << irq;
+ cached_irq_mask |= mask;
if (irq & 8) {
outb(cached_A1,0xA1);
} else {
@@ -138,9 +127,10 @@
}
}
-static inline void unmask_8259A(unsigned int irq)
+static void enable_8259A_irq(unsigned int irq)
{
- cached_irq_mask &= ~(1 << irq);
+ unsigned int mask = ~(1 << irq);
+ cached_irq_mask &= mask;
if (irq & 8) {
outb(cached_A1,0xA1);
} else {
@@ -148,21 +138,6 @@
}
}
-void set_8259A_irq_mask(unsigned int irq)
-{
- /*
- * (it might happen that we see IRQ>15 on a UP box, with SMP
- * emulation)
- */
- if (irq < 16) {
- if (irq & 8) {
- outb(cached_A1,0xA1);
- } else {
- outb(cached_21,0x21);
- }
- }
-}
-
/*
* This builds up the IRQ handler stubs using some ugly macros in irq.h
*
@@ -638,23 +613,7 @@
return status;
}
-/*
- * disable/enable_irq() wait for all irq contexts to finish
- * executing. Also it's recursive.
- */
-static void disable_8259A_irq(unsigned int irq)
-{
- cached_irq_mask |= 1 << irq;
- set_8259A_irq_mask(irq);
-}
-
-void enable_8259A_irq (unsigned int irq)
-{
- cached_irq_mask &= ~(1 << irq);
- set_8259A_irq_mask(irq);
-}
-
-int i8259A_irq_pending (unsigned int irq)
+int i8259A_irq_pending(unsigned int irq)
{
unsigned int mask = 1<<irq;
@@ -664,9 +623,9 @@
}
-void make_8259A_irq (unsigned int irq)
+void make_8259A_irq(unsigned int irq)
{
- io_apic_irqs &= ~(1<<irq);
+ __long(0,io_apic_irqs) &= ~(1<<irq);
irq_desc[irq].handler = &i8259A_irq_type;
disable_irq(irq);
enable_irq(irq);
@@ -705,7 +664,7 @@
if (handle_IRQ_event(irq, regs)) {
spin_lock(&irq_controller_lock);
if (!(irq_desc[irq].status &= IRQ_DISABLED))
- unmask_8259A(irq);
+ enable_8259A_irq(irq);
spin_unlock(&irq_controller_lock);
}
@@ -757,15 +716,6 @@
* do_IRQ handles all normal device IRQ's (the special
* SMP cross-CPU interrupts have their own specific
* handlers).
- *
- * the biggest change on SMP is the fact that we no more mask
- * interrupts in hardware, please believe me, this is unavoidable,
- * the hardware is largely message-oriented, i tried to force our
- * state-driven irq handling scheme onto the IO-APIC, but no avail.
- *
- * so we soft-disable interrupts via 'event counters', the first 'incl'
- * will do the IRQ handling. This also has the nice side effect of increased
- * overlapping ... i saw no driver problem so far.
*/
asmlinkage void do_IRQ(struct pt_regs regs)
{
@@ -846,15 +796,12 @@
#ifdef __SMP__
if (IO_APIC_IRQ(irq)) {
/*
- * First disable it in the 8259A:
+ * If it was on a 8259, disable it there
+ * and move the "pendingness" onto the
+ * new irq descriptor.
*/
- cached_irq_mask |= 1 << irq;
if (irq < 16) {
- set_8259A_irq_mask(irq);
- /*
- * transport pending ISA IRQs to
- * the new descriptor
- */
+ disable_8259A_irq(irq);
if (i8259A_irq_pending(irq))
irq_desc[irq].events = 1;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov