diff options
Diffstat (limited to 'arch/i386/kernel/irq.c')
-rw-r--r-- | arch/i386/kernel/irq.c | 27 |
1 files changed, 19 insertions, 8 deletions
diff --git a/arch/i386/kernel/irq.c b/arch/i386/kernel/irq.c index 061533e0cb5e..16b491703967 100644 --- a/arch/i386/kernel/irq.c +++ b/arch/i386/kernel/irq.c | |||
@@ -53,13 +53,19 @@ static union irq_ctx *softirq_ctx[NR_CPUS] __read_mostly; | |||
53 | */ | 53 | */ |
54 | fastcall unsigned int do_IRQ(struct pt_regs *regs) | 54 | fastcall unsigned int do_IRQ(struct pt_regs *regs) |
55 | { | 55 | { |
56 | /* high bits used in ret_from_ code */ | 56 | /* high bit used in ret_from_ code */ |
57 | int irq = regs->orig_eax & 0xff; | 57 | int irq = ~regs->orig_eax; |
58 | #ifdef CONFIG_4KSTACKS | 58 | #ifdef CONFIG_4KSTACKS |
59 | union irq_ctx *curctx, *irqctx; | 59 | union irq_ctx *curctx, *irqctx; |
60 | u32 *isp; | 60 | u32 *isp; |
61 | #endif | 61 | #endif |
62 | 62 | ||
63 | if (unlikely((unsigned)irq >= NR_IRQS)) { | ||
64 | printk(KERN_EMERG "%s: cannot handle IRQ %d\n", | ||
65 | __FUNCTION__, irq); | ||
66 | BUG(); | ||
67 | } | ||
68 | |||
63 | irq_enter(); | 69 | irq_enter(); |
64 | #ifdef CONFIG_DEBUG_STACKOVERFLOW | 70 | #ifdef CONFIG_DEBUG_STACKOVERFLOW |
65 | /* Debugging check for stack overflow: is there less than 1KB free? */ | 71 | /* Debugging check for stack overflow: is there less than 1KB free? */ |
@@ -76,6 +82,10 @@ fastcall unsigned int do_IRQ(struct pt_regs *regs) | |||
76 | } | 82 | } |
77 | #endif | 83 | #endif |
78 | 84 | ||
85 | if (!irq_desc[irq].handle_irq) { | ||
86 | __do_IRQ(irq, regs); | ||
87 | goto out_exit; | ||
88 | } | ||
79 | #ifdef CONFIG_4KSTACKS | 89 | #ifdef CONFIG_4KSTACKS |
80 | 90 | ||
81 | curctx = (union irq_ctx *) current_thread_info(); | 91 | curctx = (union irq_ctx *) current_thread_info(); |
@@ -100,8 +110,8 @@ fastcall unsigned int do_IRQ(struct pt_regs *regs) | |||
100 | * softirq checks work in the hardirq context. | 110 | * softirq checks work in the hardirq context. |
101 | */ | 111 | */ |
102 | irqctx->tinfo.preempt_count = | 112 | irqctx->tinfo.preempt_count = |
103 | irqctx->tinfo.preempt_count & ~SOFTIRQ_MASK | | 113 | (irqctx->tinfo.preempt_count & ~SOFTIRQ_MASK) | |
104 | curctx->tinfo.preempt_count & SOFTIRQ_MASK; | 114 | (curctx->tinfo.preempt_count & SOFTIRQ_MASK); |
105 | 115 | ||
106 | asm volatile( | 116 | asm volatile( |
107 | " xchgl %%ebx,%%esp \n" | 117 | " xchgl %%ebx,%%esp \n" |
@@ -115,6 +125,7 @@ fastcall unsigned int do_IRQ(struct pt_regs *regs) | |||
115 | #endif | 125 | #endif |
116 | __do_IRQ(irq, regs); | 126 | __do_IRQ(irq, regs); |
117 | 127 | ||
128 | out_exit: | ||
118 | irq_exit(); | 129 | irq_exit(); |
119 | 130 | ||
120 | return 1; | 131 | return 1; |
@@ -243,7 +254,7 @@ int show_interrupts(struct seq_file *p, void *v) | |||
243 | for_each_online_cpu(j) | 254 | for_each_online_cpu(j) |
244 | seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); | 255 | seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); |
245 | #endif | 256 | #endif |
246 | seq_printf(p, " %14s", irq_desc[i].handler->typename); | 257 | seq_printf(p, " %14s", irq_desc[i].chip->typename); |
247 | seq_printf(p, " %s", action->name); | 258 | seq_printf(p, " %s", action->name); |
248 | 259 | ||
249 | for (action=action->next; action; action = action->next) | 260 | for (action=action->next; action; action = action->next) |
@@ -285,13 +296,13 @@ void fixup_irqs(cpumask_t map) | |||
285 | if (irq == 2) | 296 | if (irq == 2) |
286 | continue; | 297 | continue; |
287 | 298 | ||
288 | cpus_and(mask, irq_affinity[irq], map); | 299 | cpus_and(mask, irq_desc[irq].affinity, map); |
289 | if (any_online_cpu(mask) == NR_CPUS) { | 300 | if (any_online_cpu(mask) == NR_CPUS) { |
290 | printk("Breaking affinity for irq %i\n", irq); | 301 | printk("Breaking affinity for irq %i\n", irq); |
291 | mask = map; | 302 | mask = map; |
292 | } | 303 | } |
293 | if (irq_desc[irq].handler->set_affinity) | 304 | if (irq_desc[irq].chip->set_affinity) |
294 | irq_desc[irq].handler->set_affinity(irq, mask); | 305 | irq_desc[irq].chip->set_affinity(irq, mask); |
295 | else if (irq_desc[irq].action && !(warned++)) | 306 | else if (irq_desc[irq].action && !(warned++)) |
296 | printk("Cannot set affinity for irq %i\n", irq); | 307 | printk("Cannot set affinity for irq %i\n", irq); |
297 | } | 308 | } |