ia64/xen-unstable
changeset 1497:ce351da91680
bitkeeper revision 1.974.1.1 (40d1af31iUa7xgOjIcSvMJwh-WxR2g)
Cleanups.
Cleanups.
author | kaf24@scramble.cl.cam.ac.uk |
---|---|
date | Thu Jun 17 14:48:17 2004 +0000 (2004-06-17) |
parents | 4e971c8daf85 |
children | d81962226803 |
files | xen/arch/x86/i8259.c xen/arch/x86/irq.c xen/arch/x86/pci-irq.c xen/arch/x86/setup.c xen/arch/x86/time.c xen/drivers/char/keyboard.c xen/drivers/char/serial.c xen/include/asm-x86/irq.h xen/include/xen/interrupt.h xen/include/xen/irq.h xen/include/xen/sched.h |
line diff
1.1 --- a/xen/arch/x86/i8259.c Thu Jun 17 09:33:04 2004 +0000 1.2 +++ b/xen/arch/x86/i8259.c Thu Jun 17 14:48:17 2004 +0000 1.3 @@ -48,7 +48,7 @@ BUILD_COMMON_IRQ() 1.4 * ISA PIC or low IO-APIC triggered (INTA-cycle or APIC) interrupts: 1.5 * (these are usually mapped to vectors 0x30-0x3f) 1.6 */ 1.7 - BUILD_16_IRQS(0x0) 1.8 +BUILD_16_IRQS(0x0) 1.9 1.10 #ifdef CONFIG_X86_IO_APIC 1.11 /* 1.12 @@ -61,10 +61,10 @@ BUILD_COMMON_IRQ() 1.13 * 1.14 * (these are usually mapped into the 0x30-0xff vector range) 1.15 */ 1.16 - BUILD_16_IRQS(0x1) BUILD_16_IRQS(0x2) BUILD_16_IRQS(0x3) 1.17 - BUILD_16_IRQS(0x4) BUILD_16_IRQS(0x5) BUILD_16_IRQS(0x6) BUILD_16_IRQS(0x7) 1.18 - BUILD_16_IRQS(0x8) BUILD_16_IRQS(0x9) BUILD_16_IRQS(0xa) BUILD_16_IRQS(0xb) 1.19 - BUILD_16_IRQS(0xc) 1.20 +BUILD_16_IRQS(0x1) BUILD_16_IRQS(0x2) BUILD_16_IRQS(0x3) 1.21 +BUILD_16_IRQS(0x4) BUILD_16_IRQS(0x5) BUILD_16_IRQS(0x6) BUILD_16_IRQS(0x7) 1.22 +BUILD_16_IRQS(0x8) BUILD_16_IRQS(0x9) BUILD_16_IRQS(0xa) BUILD_16_IRQS(0xb) 1.23 +BUILD_16_IRQS(0xc) 1.24 #endif 1.25 1.26 #undef BUILD_16_IRQS 1.27 @@ -77,23 +77,21 @@ BUILD_COMMON_IRQ() 1.28 * through the ICC by us (IPIs) 1.29 */ 1.30 #ifdef CONFIG_SMP 1.31 - BUILD_SMP_INTERRUPT(event_check_interrupt,EVENT_CHECK_VECTOR) 1.32 - BUILD_SMP_INTERRUPT(invalidate_interrupt,INVALIDATE_TLB_VECTOR) 1.33 - BUILD_SMP_INTERRUPT(call_function_interrupt,CALL_FUNCTION_VECTOR) 1.34 +BUILD_SMP_INTERRUPT(event_check_interrupt,EVENT_CHECK_VECTOR) 1.35 +BUILD_SMP_INTERRUPT(invalidate_interrupt,INVALIDATE_TLB_VECTOR) 1.36 +BUILD_SMP_INTERRUPT(call_function_interrupt,CALL_FUNCTION_VECTOR) 1.37 #endif 1.38 1.39 /* 1.40 - * every pentium local APIC has two 'local interrupts', with a 1.41 + * Every pentium local APIC has two 'local interrupts', with a 1.42 * soft-definable vector attached to both interrupts, one of 1.43 * which is a timer interrupt, the other one is error counter 1.44 * overflow. Linux uses the local APIC timer interrupt to get 1.45 * a much simpler SMP time architecture: 1.46 */ 1.47 -#ifdef CONFIG_X86_LOCAL_APIC 1.48 - BUILD_SMP_TIMER_INTERRUPT(apic_timer_interrupt,LOCAL_TIMER_VECTOR) 1.49 - BUILD_SMP_INTERRUPT(error_interrupt,ERROR_APIC_VECTOR) 1.50 - BUILD_SMP_INTERRUPT(spurious_interrupt,SPURIOUS_APIC_VECTOR) 1.51 -#endif 1.52 +BUILD_SMP_TIMER_INTERRUPT(apic_timer_interrupt,LOCAL_TIMER_VECTOR) 1.53 +BUILD_SMP_INTERRUPT(error_interrupt,ERROR_APIC_VECTOR) 1.54 +BUILD_SMP_INTERRUPT(spurious_interrupt,SPURIOUS_APIC_VECTOR) 1.55 1.56 #define IRQ(x,y) \ 1.57 IRQ##x##y##_interrupt 1.58 @@ -374,56 +372,24 @@ void __init init_8259A(int auto_eoi) 1.59 spin_unlock_irqrestore(&i8259A_lock, flags); 1.60 } 1.61 1.62 - 1.63 -/* 1.64 - * IRQ2 is cascade interrupt to second interrupt controller 1.65 - */ 1.66 - 1.67 -static struct irqaction irq2 = { no_action, 0, 0, "cascade", NULL, NULL}; 1.68 - 1.69 -void __init init_ISA_irqs (void) 1.70 -{ 1.71 - int i; 1.72 - 1.73 -#ifdef CONFIG_X86_LOCAL_APIC 1.74 - init_bsp_APIC(); 1.75 -#endif 1.76 - init_8259A(0); 1.77 - 1.78 - for (i = 0; i < NR_IRQS; i++) { 1.79 - irq_desc[i].status = IRQ_DISABLED; 1.80 - irq_desc[i].action = 0; 1.81 - irq_desc[i].depth = 1; 1.82 - 1.83 - if (i < 16) { 1.84 - /* 1.85 - * 16 old-style INTA-cycle interrupts: 1.86 - */ 1.87 - irq_desc[i].handler = &i8259A_irq_type; 1.88 - } else { 1.89 - /* 1.90 - * 'high' PCI IRQs filled in on demand 1.91 - */ 1.92 - irq_desc[i].handler = &no_irq_type; 1.93 - } 1.94 - } 1.95 -} 1.96 +static struct irqaction cascade = { no_action, "cascade", NULL}; 1.97 1.98 void __init init_IRQ(void) 1.99 { 1.100 int i; 1.101 1.102 - init_ISA_irqs(); 1.103 + init_bsp_APIC(); 1.104 + 1.105 + init_8259A(0); 1.106 1.107 - /* 1.108 - * Cover the whole vector space, no vector can escape 1.109 - * us. (some of these will be overridden and become 1.110 - * 'special' SMP interrupts) 1.111 - */ 1.112 - for (i = 0; i < NR_IRQS; i++) { 1.113 - int vector = FIRST_EXTERNAL_VECTOR + i; 1.114 - if (vector != HYPERVISOR_CALL_VECTOR) 1.115 - set_intr_gate(vector, interrupt[i]); 1.116 + for ( i = 0; i < NR_IRQS; i++ ) 1.117 + { 1.118 + irq_desc[i].status = IRQ_DISABLED; 1.119 + irq_desc[i].handler = (i<16) ? &i8259A_irq_type : &no_irq_type; 1.120 + irq_desc[i].action = NULL; 1.121 + irq_desc[i].depth = 1; 1.122 + spin_lock_init(&irq_desc[i].lock); 1.123 + set_intr_gate(FIRST_EXTERNAL_VECTOR+i, interrupt[i]); 1.124 } 1.125 1.126 #ifdef CONFIG_SMP 1.127 @@ -433,38 +399,26 @@ void __init init_IRQ(void) 1.128 */ 1.129 set_intr_gate(FIRST_DEVICE_VECTOR, interrupt[0]); 1.130 1.131 - /* 1.132 - * The reschedule interrupt is a CPU-to-CPU reschedule-helper 1.133 - * IPI, driven by wakeup. 1.134 - */ 1.135 + /* Various IPI functions. */ 1.136 set_intr_gate(EVENT_CHECK_VECTOR, event_check_interrupt); 1.137 - 1.138 - /* IPI for invalidation */ 1.139 set_intr_gate(INVALIDATE_TLB_VECTOR, invalidate_interrupt); 1.140 - 1.141 - /* IPI for generic function call */ 1.142 set_intr_gate(CALL_FUNCTION_VECTOR, call_function_interrupt); 1.143 #endif 1.144 1.145 -#ifdef CONFIG_X86_LOCAL_APIC 1.146 - /* self generated IPI for local APIC timer */ 1.147 + /* Self-generated IPI for local APIC timer. */ 1.148 set_intr_gate(LOCAL_TIMER_VECTOR, apic_timer_interrupt); 1.149 1.150 - /* IPI vectors for APIC spurious and error interrupts */ 1.151 + /* IPI vectors for APIC spurious and error interrupts. */ 1.152 set_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt); 1.153 set_intr_gate(ERROR_APIC_VECTOR, error_interrupt); 1.154 -#endif 1.155 1.156 - /* 1.157 - * Set the clock to HZ Hz, we already have a valid 1.158 - * vector now: 1.159 - */ 1.160 + /* Set the clock to HZ Hz */ 1.161 #define CLOCK_TICK_RATE 1193180 /* crystal freq (Hz) */ 1.162 #define LATCH (((CLOCK_TICK_RATE)+(HZ/2))/HZ) 1.163 outb_p(0x34,0x43); /* binary, mode 2, LSB/MSB, ch 0 */ 1.164 outb_p(LATCH & 0xff , 0x40); /* LSB */ 1.165 outb(LATCH >> 8 , 0x40); /* MSB */ 1.166 1.167 - setup_irq(2, &irq2); 1.168 + setup_irq(2, &cascade); 1.169 } 1.170
2.1 --- a/xen/arch/x86/irq.c Thu Jun 17 09:33:04 2004 +0000 2.2 +++ b/xen/arch/x86/irq.c Thu Jun 17 14:48:17 2004 +0000 2.3 @@ -1,106 +1,34 @@ 2.4 -/* 2.5 - * linux/arch/i386/kernel/irq.c 2.6 - * 2.7 - * Copyright (C) 1992, 1998 Linus Torvalds, Ingo Molnar 2.8 - * 2.9 - * This file contains the code used by various IRQ handling routines: 2.10 - * asking for different IRQ's should be done through these routines 2.11 - * instead of just grabbing them. Thus setup_irqs with different IRQ numbers 2.12 - * shouldn't result in any weird surprises, and installing new handlers 2.13 - * should be easier. 2.14 - */ 2.15 - 2.16 -/* 2.17 - * (mostly architecture independent, will move to kernel/irq.c in 2.5.) 2.18 - * 2.19 - * IRQs are in fact implemented a bit like signal handlers for the kernel. 2.20 - * Naturally it's not a 1:1 relation, but there are similarities. 2.21 +/****************************************************************************** 2.22 + * arch/x86/irq.c 2.23 + * 2.24 + * Portions of this file are: 2.25 + * Copyright (C) 1992, 1998 Linus Torvalds, Ingo Molnar 2.26 */ 2.27 2.28 #include <xen/config.h> 2.29 -#include <xen/init.h> 2.30 #include <xen/errno.h> 2.31 -#include <xen/sched.h> 2.32 +#include <xen/event.h> 2.33 #include <xen/interrupt.h> 2.34 #include <xen/irq.h> 2.35 -#include <xen/slab.h> 2.36 -#include <xen/event.h> 2.37 -#include <asm/mpspec.h> 2.38 -#include <asm/io_apic.h> 2.39 -#include <asm/msr.h> 2.40 -#include <asm/hardirq.h> 2.41 -#include <asm/ptrace.h> 2.42 -#include <asm/atomic.h> 2.43 -#include <asm/io.h> 2.44 -#include <asm/smp.h> 2.45 -#include <asm/system.h> 2.46 -#include <asm/bitops.h> 2.47 -#include <asm/flushtlb.h> 2.48 -#include <xen/delay.h> 2.49 #include <xen/perfc.h> 2.50 +#include <xen/sched.h> 2.51 #include <asm/smpboot.h> 2.52 2.53 -/* 2.54 - * Linux has a controller-independent x86 interrupt architecture. 2.55 - * every controller has a 'controller-template', that is used 2.56 - * by the main code to do the right thing. Each driver-visible 2.57 - * interrupt source is transparently wired to the apropriate 2.58 - * controller. Thus drivers need not be aware of the 2.59 - * interrupt-controller. 2.60 - * 2.61 - * Various interrupt controllers we handle: 8259 PIC, SMP IO-APIC, 2.62 - * PIIX4's internal 8259 PIC and SGI's Visual Workstation Cobalt (IO-)APIC. 2.63 - * (IO-APICs assumed to be messaging to Pentium local-APICs) 2.64 - * 2.65 - * the code is designed to be easily extended with new/different 2.66 - * interrupt controllers, without having to do assembly magic. 2.67 - */ 2.68 - 2.69 -/* 2.70 - * Controller mappings for all interrupt sources: 2.71 - */ 2.72 -irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned = 2.73 -{ [0 ... NR_IRQS-1] = { 0, &no_irq_type, NULL, 0, SPIN_LOCK_UNLOCKED}}; 2.74 +irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned; 2.75 2.76 static void __do_IRQ_guest(int irq); 2.77 2.78 -/* 2.79 - * Special irq handlers. 2.80 - */ 2.81 - 2.82 void no_action(int cpl, void *dev_id, struct pt_regs *regs) { } 2.83 2.84 -/* 2.85 - * Generic no controller code 2.86 - */ 2.87 - 2.88 static void enable_none(unsigned int irq) { } 2.89 static unsigned int startup_none(unsigned int irq) { return 0; } 2.90 static void disable_none(unsigned int irq) { } 2.91 static void ack_none(unsigned int irq) 2.92 { 2.93 -/* 2.94 - * 'what should we do if we get a hw irq event on an illegal vector'. 2.95 - * each architecture has to answer this themselves, it doesnt deserve 2.96 - * a generic callback i think. 2.97 - */ 2.98 -#if CONFIG_X86 2.99 - printk("unexpected IRQ trap at vector %02x\n", irq); 2.100 -#ifdef CONFIG_X86_LOCAL_APIC 2.101 - /* 2.102 - * Currently unexpected vectors happen only on SMP and APIC. 2.103 - * We _must_ ack these because every local APIC has only N 2.104 - * irq slots per priority level, and a 'hanging, unacked' IRQ 2.105 - * holds up an irq slot - in excessive cases (when multiple 2.106 - * unexpected vectors occur) that might lock up the APIC 2.107 - * completely. 2.108 - */ 2.109 + printk("Unexpected IRQ trap at vector %02x.\n", irq); 2.110 ack_APIC_irq(); 2.111 -#endif 2.112 -#endif 2.113 } 2.114 2.115 -/* startup is the same as "enable", shutdown is same as "disable" */ 2.116 #define shutdown_none disable_none 2.117 #define end_none enable_none 2.118 2.119 @@ -115,420 +43,132 @@ struct hw_interrupt_type no_irq_type = { 2.120 }; 2.121 2.122 atomic_t irq_err_count; 2.123 -#ifdef CONFIG_X86_IO_APIC 2.124 -#ifdef APIC_MISMATCH_DEBUG 2.125 atomic_t irq_mis_count; 2.126 -#endif 2.127 -#endif 2.128 - 2.129 -/* 2.130 - * Generic, controller-independent functions: 2.131 - */ 2.132 - 2.133 -/* 2.134 - * This should really return information about whether 2.135 - * we should do bottom half handling etc. Right now we 2.136 - * end up _always_ checking the bottom half, which is a 2.137 - * waste of time and is not what some drivers would 2.138 - * prefer. 2.139 - */ 2.140 -static int handle_IRQ_event(unsigned int irq, 2.141 - struct pt_regs * regs, 2.142 - struct irqaction * action) 2.143 -{ 2.144 - int status; 2.145 - int cpu = smp_processor_id(); 2.146 - 2.147 - irq_enter(cpu, irq); 2.148 - 2.149 - status = 1; /* Force the "do bottom halves" bit */ 2.150 - 2.151 - if (!(action->flags & SA_INTERRUPT)) 2.152 - __sti(); 2.153 2.154 - do { 2.155 - status |= action->flags; 2.156 - action->handler(irq, action->dev_id, regs); 2.157 - action = action->next; 2.158 - } while (action); 2.159 - 2.160 - __cli(); 2.161 - 2.162 - irq_exit(cpu, irq); 2.163 - 2.164 - return status; 2.165 -} 2.166 - 2.167 -/* 2.168 - * Generic enable/disable code: this just calls 2.169 - * down into the PIC-specific version for the actual 2.170 - * hardware disable after having gotten the irq 2.171 - * controller lock. 2.172 - */ 2.173 - 2.174 -/** 2.175 - * disable_irq_nosync - disable an irq without waiting 2.176 - * @irq: Interrupt to disable 2.177 - * 2.178 - * Disable the selected interrupt line. Disables and Enables are 2.179 - * nested. 2.180 - * Unlike disable_irq(), this function does not ensure existing 2.181 - * instances of the IRQ handler have completed before returning. 2.182 - * 2.183 - * This function may be called from IRQ context. 2.184 - */ 2.185 - 2.186 inline void disable_irq_nosync(unsigned int irq) 2.187 { 2.188 - irq_desc_t *desc = irq_desc + irq; 2.189 + irq_desc_t *desc = &irq_desc[irq]; 2.190 unsigned long flags; 2.191 2.192 spin_lock_irqsave(&desc->lock, flags); 2.193 - if (!desc->depth++) { 2.194 + 2.195 + if ( desc->depth++ == 0 ) 2.196 + { 2.197 desc->status |= IRQ_DISABLED; 2.198 desc->handler->disable(irq); 2.199 } 2.200 + 2.201 spin_unlock_irqrestore(&desc->lock, flags); 2.202 } 2.203 2.204 -/** 2.205 - * disable_irq - disable an irq and wait for completion 2.206 - * @irq: Interrupt to disable 2.207 - * 2.208 - * Disable the selected interrupt line. Enables and Disables are 2.209 - * nested. 2.210 - * This function waits for any pending IRQ handlers for this interrupt 2.211 - * to complete before returning. If you use this function while 2.212 - * holding a resource the IRQ handler may need you will deadlock. 2.213 - * 2.214 - * This function may be called - with care - from IRQ context. 2.215 - */ 2.216 - 2.217 void disable_irq(unsigned int irq) 2.218 { 2.219 disable_irq_nosync(irq); 2.220 - 2.221 - if (!local_irq_count(smp_processor_id())) { 2.222 - do { 2.223 - barrier(); 2.224 - cpu_relax(); 2.225 - } while (irq_desc[irq].status & IRQ_INPROGRESS); 2.226 - } 2.227 + do { smp_mb(); } while ( irq_desc[irq].status & IRQ_INPROGRESS ); 2.228 } 2.229 2.230 -/** 2.231 - * enable_irq - enable handling of an irq 2.232 - * @irq: Interrupt to enable 2.233 - * 2.234 - * Undoes the effect of one call to disable_irq(). If this 2.235 - * matches the last disable, processing of interrupts on this 2.236 - * IRQ line is re-enabled. 2.237 - * 2.238 - * This function may be called from IRQ context. 2.239 - */ 2.240 - 2.241 void enable_irq(unsigned int irq) 2.242 { 2.243 - irq_desc_t *desc = irq_desc + irq; 2.244 + irq_desc_t *desc = &irq_desc[irq]; 2.245 unsigned long flags; 2.246 2.247 spin_lock_irqsave(&desc->lock, flags); 2.248 - switch (desc->depth) { 2.249 - case 1: { 2.250 - unsigned int status = desc->status & ~IRQ_DISABLED; 2.251 - desc->status = status; 2.252 - if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) { 2.253 - desc->status = status | IRQ_REPLAY; 2.254 + 2.255 + if ( --desc->depth == 0 ) 2.256 + { 2.257 + desc->status &= ~IRQ_DISABLED; 2.258 + if ( (desc->status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING ) 2.259 + { 2.260 + desc->status |= IRQ_REPLAY; 2.261 hw_resend_irq(desc->handler,irq); 2.262 } 2.263 desc->handler->enable(irq); 2.264 - /* fall-through */ 2.265 } 2.266 - default: 2.267 - desc->depth--; 2.268 - break; 2.269 - case 0: 2.270 - printk("enable_irq(%u) unbalanced from %p\n", irq, 2.271 - __builtin_return_address(0)); 2.272 - } 2.273 + 2.274 spin_unlock_irqrestore(&desc->lock, flags); 2.275 } 2.276 2.277 -/* 2.278 - * do_IRQ handles all normal device IRQ's (the special 2.279 - * SMP cross-CPU interrupts have their own specific 2.280 - * handlers). 2.281 - */ 2.282 -asmlinkage unsigned int do_IRQ(struct pt_regs regs) 2.283 +asmlinkage void do_IRQ(struct pt_regs regs) 2.284 { 2.285 - /* 2.286 - * We ack quickly, we don't want the irq controller 2.287 - * thinking we're snobs just because some other CPU has 2.288 - * disabled global interrupts (we have already done the 2.289 - * INT_ACK cycles, it's too late to try to pretend to the 2.290 - * controller that we aren't taking the interrupt). 2.291 - * 2.292 - * 0 return value means that this irq is already being 2.293 - * handled by some other CPU. (or is disabled) 2.294 - */ 2.295 - int irq = regs.orig_eax & 0xff; /* high bits used in ret_from_ code */ 2.296 - irq_desc_t *desc = irq_desc + irq; 2.297 - struct irqaction * action; 2.298 - unsigned int status; 2.299 + unsigned int irq = regs.orig_eax & 0xff; 2.300 + irq_desc_t *desc = &irq_desc[irq]; 2.301 + struct irqaction *action; 2.302 2.303 -#ifdef PERF_COUNTERS 2.304 - int cpu = smp_processor_id(); 2.305 - u32 cc_start, cc_end; 2.306 - 2.307 - perfc_incra(irqs, cpu); 2.308 - rdtscl(cc_start); 2.309 -#endif 2.310 + perfc_incrc(irqs); 2.311 2.312 spin_lock(&desc->lock); 2.313 desc->handler->ack(irq); 2.314 2.315 - /* 2.316 - REPLAY is when Linux resends an IRQ that was dropped earlier 2.317 - WAITING is used by probe to mark irqs that are being tested 2.318 - */ 2.319 - status = desc->status & ~(IRQ_REPLAY | IRQ_WAITING); 2.320 - status |= IRQ_PENDING; /* we _want_ to handle it */ 2.321 - 2.322 - /* We hook off guest-bound IRQs for special handling. */ 2.323 - if ( status & IRQ_GUEST ) 2.324 + if ( likely(desc->status & IRQ_GUEST) ) 2.325 { 2.326 __do_IRQ_guest(irq); 2.327 spin_unlock(&desc->lock); 2.328 - return 1; 2.329 + return; 2.330 } 2.331 2.332 - /* 2.333 - * If the IRQ is disabled for whatever reason, we cannot use the action we 2.334 - * have. 2.335 - */ 2.336 - action = NULL; 2.337 - if (!(status & (IRQ_DISABLED | IRQ_INPROGRESS))) { 2.338 - action = desc->action; 2.339 - status &= ~IRQ_PENDING; /* we commit to handling */ 2.340 - status |= IRQ_INPROGRESS; /* we are handling it */ 2.341 - } 2.342 - desc->status = status; 2.343 - 2.344 - /* 2.345 - * If there is no IRQ handler or it was disabled, exit early. Since we set 2.346 - * PENDING, if another processor is handling a different instance of this 2.347 - * same irq, the other processor will take care of it. 2.348 - */ 2.349 - if (!action) 2.350 - goto out; 2.351 + desc->status &= ~IRQ_REPLAY; 2.352 + desc->status |= IRQ_PENDING; 2.353 2.354 /* 2.355 - * Edge triggered interrupts need to remember pending events. This applies 2.356 - * to any hw interrupts that allow a second instance of the same irq to 2.357 - * arrive while we are in do_IRQ or in the handler. But the code here only 2.358 - * handles the _second_ instance of the irq, not the third or fourth. So 2.359 - * it is mostly useful for irq hardware that does not mask cleanly in an 2.360 - * SMP environment. 2.361 + * Since we set PENDING, if another processor is handling a different 2.362 + * instance of this same irq, the other processor will take care of it. 2.363 */ 2.364 - for (;;) { 2.365 - spin_unlock(&desc->lock); 2.366 - handle_IRQ_event(irq, ®s, action); 2.367 - spin_lock(&desc->lock); 2.368 - 2.369 - if (!(desc->status & IRQ_PENDING)) 2.370 - break; 2.371 + if ( desc->status & (IRQ_DISABLED | IRQ_INPROGRESS) ) 2.372 + goto out; 2.373 + 2.374 + desc->status |= IRQ_INPROGRESS; 2.375 + 2.376 + action = desc->action; 2.377 + while ( desc->status & IRQ_PENDING ) 2.378 + { 2.379 desc->status &= ~IRQ_PENDING; 2.380 + irq_enter(smp_processor_id(), irq); 2.381 + spin_unlock_irq(&desc->lock); 2.382 + action->handler(irq, action->dev_id, ®s); 2.383 + spin_lock_irq(&desc->lock); 2.384 + irq_exit(smp_processor_id(), irq); 2.385 } 2.386 + 2.387 desc->status &= ~IRQ_INPROGRESS; 2.388 + 2.389 out: 2.390 - /* 2.391 - * The ->end() handler has to deal with interrupts which got disabled 2.392 - * while the handler was running. 2.393 - */ 2.394 desc->handler->end(irq); 2.395 spin_unlock(&desc->lock); 2.396 - 2.397 -#ifdef PERF_COUNTERS 2.398 - rdtscl(cc_end); 2.399 - 2.400 - if ( !action || (!(action->flags & SA_NOPROFILE)) ) 2.401 - { 2.402 - perfc_adda(irq_time, cpu, cc_end - cc_start); 2.403 -#ifndef NDEBUG 2.404 - if ( (cc_end - cc_start) > (cpu_khz * 100) ) 2.405 - printk("Long interrupt %08x -> %08x\n", cc_start, cc_end); 2.406 -#endif 2.407 - } 2.408 -#endif 2.409 - 2.410 - return 1; 2.411 } 2.412 2.413 -/** 2.414 - * request_irq - allocate an interrupt line 2.415 - * @irq: Interrupt line to allocate 2.416 - * @handler: Function to be called when the IRQ occurs 2.417 - * @irqflags: Interrupt type flags 2.418 - * @devname: An ascii name for the claiming device 2.419 - * @dev_id: A cookie passed back to the handler function 2.420 - * 2.421 - * This call allocates interrupt resources and enables the 2.422 - * interrupt line and IRQ handling. From the point this 2.423 - * call is made your handler function may be invoked. Since 2.424 - * your handler function must clear any interrupt the board 2.425 - * raises, you must take care both to initialise your hardware 2.426 - * and to set up the interrupt handler in the right order. 2.427 - * 2.428 - * Dev_id must be globally unique. Normally the address of the 2.429 - * device data structure is used as the cookie. Since the handler 2.430 - * receives this value it makes sense to use it. 2.431 - * 2.432 - * If your interrupt is shared you must pass a non NULL dev_id 2.433 - * as this is required when freeing the interrupt. 2.434 - * 2.435 - * Flags: 2.436 - * 2.437 - * SA_SHIRQ Interrupt is shared 2.438 - * 2.439 - * SA_INTERRUPT Disable local interrupts while processing 2.440 - */ 2.441 - 2.442 -int request_irq(unsigned int irq, 2.443 - void (*handler)(int, void *, struct pt_regs *), 2.444 - unsigned long irqflags, 2.445 - const char * devname, 2.446 - void *dev_id) 2.447 +void free_irq(unsigned int irq) 2.448 { 2.449 - int retval; 2.450 - struct irqaction * action; 2.451 - 2.452 - if (irq >= NR_IRQS) 2.453 - return -EINVAL; 2.454 - if (!handler) 2.455 - return -EINVAL; 2.456 - 2.457 - action = (struct irqaction *) 2.458 - kmalloc(sizeof(struct irqaction), GFP_KERNEL); 2.459 - if (!action) 2.460 - return -ENOMEM; 2.461 + irq_desc_t *desc = &irq_desc[irq]; 2.462 + unsigned long flags; 2.463 2.464 - action->handler = handler; 2.465 - action->flags = irqflags; 2.466 - action->mask = 0; 2.467 - action->name = devname; 2.468 - action->next = NULL; 2.469 - action->dev_id = dev_id; 2.470 + spin_lock_irqsave(&desc->lock,flags); 2.471 + desc->action = NULL; 2.472 + desc->depth = 1; 2.473 + desc->status |= IRQ_DISABLED; 2.474 + desc->handler->shutdown(irq); 2.475 + spin_unlock_irqrestore(&desc->lock,flags); 2.476 2.477 - retval = setup_irq(irq, action); 2.478 - if (retval) 2.479 - kfree(action); 2.480 - 2.481 - return retval; 2.482 + /* Wait to make sure it's not being used on another CPU */ 2.483 + do { smp_mb(); } while ( irq_desc[irq].status & IRQ_INPROGRESS ); 2.484 } 2.485 2.486 -/** 2.487 - * free_irq - free an interrupt 2.488 - * @irq: Interrupt line to free 2.489 - * @dev_id: Device identity to free 2.490 - * 2.491 - * Remove an interrupt handler. The handler is removed and if the 2.492 - * interrupt line is no longer in use by any driver it is disabled. 2.493 - * On a shared IRQ the caller must ensure the interrupt is disabled 2.494 - * on the card it drives before calling this function. The function 2.495 - * does not return until any executing interrupts for this IRQ 2.496 - * have completed. 2.497 - * 2.498 - * This function may be called from interrupt context. 2.499 - * 2.500 - * Bugs: Attempting to free an irq in a handler for the same irq hangs 2.501 - * the machine. 2.502 - */ 2.503 - 2.504 -void free_irq(unsigned int irq, void *dev_id) 2.505 +int setup_irq(unsigned int irq, struct irqaction *new) 2.506 { 2.507 - irq_desc_t *desc; 2.508 - struct irqaction **p; 2.509 + irq_desc_t *desc = &irq_desc[irq]; 2.510 unsigned long flags; 2.511 - 2.512 - if (irq >= NR_IRQS) 2.513 - return; 2.514 - 2.515 - desc = irq_desc + irq; 2.516 - spin_lock_irqsave(&desc->lock,flags); 2.517 - p = &desc->action; 2.518 - for (;;) { 2.519 - struct irqaction * action = *p; 2.520 - if (action) { 2.521 - struct irqaction **pp = p; 2.522 - p = &action->next; 2.523 - if (action->dev_id != dev_id) 2.524 - continue; 2.525 - 2.526 - /* Found it - now remove it from the list of entries */ 2.527 - *pp = action->next; 2.528 - if (!desc->action) { 2.529 - desc->status |= IRQ_DISABLED; 2.530 - desc->handler->shutdown(irq); 2.531 - } 2.532 - spin_unlock_irqrestore(&desc->lock,flags); 2.533 - 2.534 -#ifdef CONFIG_SMP 2.535 - /* Wait to make sure it's not being used on another CPU */ 2.536 - while (desc->status & IRQ_INPROGRESS) { 2.537 - barrier(); 2.538 - cpu_relax(); 2.539 - } 2.540 -#endif 2.541 - kfree(action); 2.542 - return; 2.543 - } 2.544 - printk("Trying to free free IRQ%d\n",irq); 2.545 - spin_unlock_irqrestore(&desc->lock,flags); 2.546 - return; 2.547 - } 2.548 -} 2.549 - 2.550 -int setup_irq(unsigned int irq, struct irqaction * new) 2.551 -{ 2.552 - int shared = 0; 2.553 - unsigned long flags; 2.554 - struct irqaction *old, **p; 2.555 - irq_desc_t *desc = irq_desc + irq; 2.556 - 2.557 - /* 2.558 - * The following block of code has to be executed atomically 2.559 - */ 2.560 + 2.561 spin_lock_irqsave(&desc->lock,flags); 2.562 2.563 - if ( desc->status & IRQ_GUEST ) 2.564 + if ( desc->action != NULL ) 2.565 { 2.566 spin_unlock_irqrestore(&desc->lock,flags); 2.567 return -EBUSY; 2.568 } 2.569 2.570 - p = &desc->action; 2.571 - if ((old = *p) != NULL) { 2.572 - /* Can't share interrupts unless both agree to */ 2.573 - if (!(old->flags & new->flags & SA_SHIRQ)) { 2.574 - spin_unlock_irqrestore(&desc->lock,flags); 2.575 - return -EBUSY; 2.576 - } 2.577 - 2.578 - /* add new interrupt at end of irq queue */ 2.579 - do { 2.580 - p = &old->next; 2.581 - old = *p; 2.582 - } while (old); 2.583 - shared = 1; 2.584 - } 2.585 - 2.586 - *p = new; 2.587 - 2.588 - if (!shared) { 2.589 - desc->depth = 0; 2.590 - desc->status &= ~(IRQ_DISABLED | IRQ_AUTODETECT | IRQ_WAITING); 2.591 - desc->handler->startup(irq); 2.592 - } 2.593 + desc->action = new; 2.594 + desc->depth = 0; 2.595 + desc->status &= ~IRQ_DISABLED; 2.596 + desc->handler->startup(irq); 2.597 2.598 spin_unlock_irqrestore(&desc->lock,flags); 2.599 2.600 @@ -536,7 +176,6 @@ int setup_irq(unsigned int irq, struct i 2.601 } 2.602 2.603 2.604 - 2.605 /* 2.606 * HANDLING OF GUEST-BOUND PHYSICAL IRQS 2.607 */ 2.608 @@ -551,10 +190,10 @@ typedef struct { 2.609 2.610 static void __do_IRQ_guest(int irq) 2.611 { 2.612 - irq_desc_t *desc = &irq_desc[irq]; 2.613 + irq_desc_t *desc = &irq_desc[irq]; 2.614 irq_guest_action_t *action = (irq_guest_action_t *)desc->action; 2.615 struct task_struct *p; 2.616 - int i; 2.617 + int i; 2.618 2.619 for ( i = 0; i < action->nr_guests; i++ ) 2.620 { 2.621 @@ -567,9 +206,9 @@ static void __do_IRQ_guest(int irq) 2.622 2.623 int pirq_guest_unmask(struct task_struct *p) 2.624 { 2.625 - irq_desc_t *desc; 2.626 - int i, j, pirq; 2.627 - u32 m; 2.628 + irq_desc_t *desc; 2.629 + int i, j, pirq; 2.630 + u32 m; 2.631 shared_info_t *s = p->shared_info; 2.632 2.633 for ( i = 0; i < 2; i++ ) 2.634 @@ -594,10 +233,10 @@ int pirq_guest_unmask(struct task_struct 2.635 2.636 int pirq_guest_bind(struct task_struct *p, int irq, int will_share) 2.637 { 2.638 - unsigned long flags; 2.639 - irq_desc_t *desc = &irq_desc[irq]; 2.640 + irq_desc_t *desc = &irq_desc[irq]; 2.641 irq_guest_action_t *action; 2.642 - int rc = 0; 2.643 + unsigned long flags; 2.644 + int rc = 0; 2.645 2.646 if ( !IS_CAPABLE_PHYSDEV(p) ) 2.647 return -EPERM; 2.648 @@ -630,7 +269,7 @@ int pirq_guest_bind(struct task_struct * 2.649 2.650 desc->depth = 0; 2.651 desc->status |= IRQ_GUEST; 2.652 - desc->status &= ~(IRQ_DISABLED | IRQ_AUTODETECT | IRQ_WAITING); 2.653 + desc->status &= ~IRQ_DISABLED; 2.654 desc->handler->startup(irq); 2.655 2.656 /* Attempt to bind the interrupt target to the correct CPU. */ 2.657 @@ -662,10 +301,10 @@ int pirq_guest_bind(struct task_struct * 2.658 2.659 int pirq_guest_unbind(struct task_struct *p, int irq) 2.660 { 2.661 - unsigned long flags; 2.662 - irq_desc_t *desc = &irq_desc[irq]; 2.663 + irq_desc_t *desc = &irq_desc[irq]; 2.664 irq_guest_action_t *action; 2.665 - int i; 2.666 + unsigned long flags; 2.667 + int i; 2.668 2.669 spin_lock_irqsave(&desc->lock, flags); 2.670 2.671 @@ -679,6 +318,7 @@ int pirq_guest_unbind(struct task_struct 2.672 { 2.673 desc->action = NULL; 2.674 kfree(action); 2.675 + desc->depth = 1; 2.676 desc->status |= IRQ_DISABLED; 2.677 desc->status &= ~IRQ_GUEST; 2.678 desc->handler->shutdown(irq); 2.679 @@ -695,3 +335,26 @@ int pirq_guest_unbind(struct task_struct 2.680 spin_unlock_irqrestore(&desc->lock, flags); 2.681 return 0; 2.682 } 2.683 + 2.684 +int pirq_guest_bindable(int irq, int will_share) 2.685 +{ 2.686 + irq_desc_t *desc = &irq_desc[irq]; 2.687 + irq_guest_action_t *action; 2.688 + unsigned long flags; 2.689 + int okay; 2.690 + 2.691 + spin_lock_irqsave(&desc->lock, flags); 2.692 + 2.693 + action = (irq_guest_action_t *)desc->action; 2.694 + 2.695 + /* 2.696 + * To be bindable the IRQ must either be not currently bound (1), or 2.697 + * it must be shareable (2) and not at its share limit (3). 2.698 + */ 2.699 + okay = ((!(desc->status & IRQ_GUEST) && (action == NULL)) || /* 1 */ 2.700 + (action->shareable && will_share && /* 2 */ 2.701 + (action->nr_guests != IRQ_MAX_GUESTS))); /* 3 */ 2.702 + 2.703 + spin_unlock_irqrestore(&desc->lock, flags); 2.704 + return okay; 2.705 +}
3.1 --- a/xen/arch/x86/pci-irq.c Thu Jun 17 09:33:04 2004 +0000 3.2 +++ b/xen/arch/x86/pci-irq.c Thu Jun 17 14:48:17 2004 +0000 3.3 @@ -903,10 +903,8 @@ static int pcibios_lookup_irq(struct pci 3.4 if (!(mask & (1 << i))) 3.5 continue; 3.6 if (pirq_penalty[i] < pirq_penalty[newirq] && 3.7 - !request_irq(i, pcibios_test_irq_handler, SA_SHIRQ, "pci-test", dev)) { 3.8 - free_irq(i, dev); 3.9 + pirq_guest_bindable(i,1)) 3.10 newirq = i; 3.11 - } 3.12 } 3.13 } 3.14 DBG(" -> newirq=%d", newirq);
4.1 --- a/xen/arch/x86/setup.c Thu Jun 17 09:33:04 2004 +0000 4.2 +++ b/xen/arch/x86/setup.c Thu Jun 17 14:48:17 2004 +0000 4.3 @@ -300,8 +300,8 @@ unsigned long pci_mem_start = 0x10000000 4.4 4.5 void __init start_of_day(void) 4.6 { 4.7 + extern void init_IRQ(void); 4.8 extern void trap_init(void); 4.9 - extern void init_IRQ(void); 4.10 extern void time_init(void); 4.11 extern void ac_timer_init(void); 4.12 extern void initialize_keytable(); 4.13 @@ -350,8 +350,8 @@ void __init start_of_day(void) 4.14 get_smp_config(); 4.15 #endif 4.16 scheduler_init(); 4.17 + init_IRQ(); /* installs simple interrupt wrappers. Starts HZ clock. */ 4.18 trap_init(); 4.19 - init_IRQ(); /* installs simple interrupt wrappers. Starts HZ clock. */ 4.20 time_init(); /* installs software handler for HZ clock. */ 4.21 softirq_init(); 4.22 init_apic_mappings(); /* make APICs addressable in our pagetables. */
5.1 --- a/xen/arch/x86/time.c Thu Jun 17 09:33:04 2004 +0000 5.2 +++ b/xen/arch/x86/time.c Thu Jun 17 14:48:17 2004 +0000 5.3 @@ -54,7 +54,7 @@ static void timer_interrupt(int irq, voi 5.4 { 5.5 u64 full_tsc; 5.6 5.7 - write_lock(&time_lock); 5.8 + write_lock_irq(&time_lock); 5.9 5.10 #ifdef CONFIG_X86_IO_APIC 5.11 if ( timer_ack ) 5.12 @@ -89,15 +89,14 @@ static void timer_interrupt(int irq, voi 5.13 /* Updates system time (nanoseconds since boot). */ 5.14 stime_irq += MILLISECS(1000/HZ); 5.15 5.16 - write_unlock(&time_lock); 5.17 + write_unlock_irq(&time_lock); 5.18 5.19 /* Rough hack to allow accurate timers to sort-of-work with no APIC. */ 5.20 if ( do_timer_lists_from_pit ) 5.21 __cpu_raise_softirq(smp_processor_id(), AC_TIMER_SOFTIRQ); 5.22 } 5.23 5.24 -static struct irqaction irq0 = { timer_interrupt, SA_INTERRUPT, 0, 5.25 - "timer", NULL, NULL}; 5.26 +static struct irqaction irq0 = { timer_interrupt, "timer", NULL}; 5.27 5.28 /* ------ Calibrate the TSC ------- 5.29 * Return processor ticks per second / CALIBRATE_FRAC.
6.1 --- a/xen/drivers/char/keyboard.c Thu Jun 17 09:33:04 2004 +0000 6.2 +++ b/xen/drivers/char/keyboard.c Thu Jun 17 14:48:17 2004 +0000 6.3 @@ -13,6 +13,7 @@ 6.4 #include <hypervisor-ifs/kbd.h> 6.5 #include <xen/event.h> 6.6 #include <xen/console.h> 6.7 +#include <xen/interrupt.h> 6.8 6.9 /* Hash-defines torn from <xen/pc_keyb.h> and <asm/keyboard.h> */ 6.10 6.11 @@ -241,23 +242,13 @@ static void keyboard_interrupt(int irq, 6.12 } 6.13 6.14 6.15 +static struct irqaction keyb = { keyboard_interrupt, "Keyboard", NULL }; 6.16 +static struct irqaction aux = { keyboard_interrupt, "PS/2 Mouse", NULL }; 6.17 6.18 void initialize_keyboard() 6.19 { 6.20 spin_lock_init(&kbd_lock); 6.21 - 6.22 - if( request_irq(KEYBOARD_IRQ, keyboard_interrupt, 6.23 - SA_NOPROFILE, "keyboard", NULL)) 6.24 - { 6.25 - printk("initialize_keyboard: failed to alloc IRQ %d\n", KEYBOARD_IRQ); 6.26 - return; 6.27 - } 6.28 - 6.29 - if ( request_irq(AUX_IRQ, keyboard_interrupt, 6.30 - SA_NOPROFILE, "PS/2 Mouse", NULL)) 6.31 - { 6.32 - printk("initialize_keyboard: failed to alloc IRQ %d\n", AUX_IRQ); 6.33 - return; 6.34 - } 6.35 + (void)setup_irq(KEYBOARD_IRQ, &keyb); 6.36 + (void)setup_irq(AUX_IRQ, &aux); 6.37 } 6.38
7.1 --- a/xen/drivers/char/serial.c Thu Jun 17 09:33:04 2004 +0000 7.2 +++ b/xen/drivers/char/serial.c Thu Jun 17 14:48:17 2004 +0000 7.3 @@ -12,6 +12,7 @@ 7.4 #include <xen/sched.h> 7.5 #include <xen/keyhandler.h> 7.6 #include <xen/reboot.h> 7.7 +#include <xen/interrupt.h> 7.8 #include <xen/irq.h> 7.9 #include <xen/serial.h> 7.10 #include <asm/pdb.h> 7.11 @@ -73,11 +74,12 @@ 7.12 #define RXBUFSZ 32 7.13 #define MASK_RXBUF_IDX(_i) ((_i)&(RXBUFSZ-1)) 7.14 typedef struct { 7.15 - int baud, data_bits, parity, stop_bits, io_base, irq; 7.16 - serial_rx_fn rx_lo, rx_hi, rx; 7.17 - spinlock_t lock; 7.18 - unsigned char rxbuf[RXBUFSZ]; 7.19 - unsigned int rxbufp, rxbufc; 7.20 + int baud, data_bits, parity, stop_bits, io_base, irq; 7.21 + serial_rx_fn rx_lo, rx_hi, rx; 7.22 + spinlock_t lock; 7.23 + unsigned char rxbuf[RXBUFSZ]; 7.24 + unsigned int rxbufp, rxbufc; 7.25 + struct irqaction irqaction; 7.26 } uart_t; 7.27 7.28 static uart_t com[2] = { 7.29 @@ -249,12 +251,10 @@ static void uart_config_stage2(uart_t *u 7.30 if ( !UART_ENABLED(uart) ) 7.31 return; 7.32 7.33 - rc = request_irq(uart->irq, 7.34 - serial_interrupt, 7.35 - SA_NOPROFILE, 7.36 - "serial", 7.37 - uart); 7.38 - if ( rc != 0 ) 7.39 + uart->irqaction.handler = serial_interrupt; 7.40 + uart->irqaction.name = "serial"; 7.41 + uart->irqaction.dev_id = uart; 7.42 + if ( (rc = setup_irq(uart->irq, &uart->irqaction)) != 0 ) 7.43 printk("ERROR: Failed to allocate serial IRQ %d\n", uart->irq); 7.44 7.45 /* For sanity, clear the receive FIFO. */
8.1 --- a/xen/include/asm-x86/irq.h Thu Jun 17 09:33:04 2004 +0000 8.2 +++ b/xen/include/asm-x86/irq.h Thu Jun 17 14:48:17 2004 +0000 8.3 @@ -6,14 +6,6 @@ 8.4 #include <xen/config.h> 8.5 #include <asm/atomic.h> 8.6 8.7 -#define SA_INTERRUPT 0x20000000 8.8 -#define SA_SHIRQ 0x04000000 8.9 -#define SA_NOPROFILE 0x02000000 8.10 - 8.11 -#define SA_SAMPLE_RANDOM 0 /* Linux driver compatibility */ 8.12 - 8.13 -#define TIMER_IRQ 0 8.14 - 8.15 extern void disable_irq(unsigned int); 8.16 extern void disable_irq_nosync(unsigned int); 8.17 extern void enable_irq(unsigned int); 8.18 @@ -34,12 +26,6 @@ extern void enable_irq(unsigned int); 8.19 8.20 /* 8.21 * Special IRQ vectors used by the SMP architecture, 0xf0-0xff 8.22 - * 8.23 - * some of the following vectors are 'rare', they are merged 8.24 - * into a single vector (CALL_FUNCTION_VECTOR) to save vector space. 8.25 - * TLB, reschedule and local APIC vectors are performance-critical. 8.26 - * 8.27 - * Vectors 0xf0-0xfa are free (reserved for future Linux use). 8.28 */ 8.29 #define SPURIOUS_APIC_VECTOR 0xff 8.30 #define ERROR_APIC_VECTOR 0xfe 8.31 @@ -186,7 +172,7 @@ SYMBOL_NAME_STR(IRQ) #nr "_interrupt:\n\ 8.32 "jmp common_interrupt"); 8.33 8.34 extern unsigned long prof_cpu_mask; 8.35 -extern unsigned int * prof_buffer; 8.36 +extern unsigned int *prof_buffer; 8.37 extern unsigned long prof_len; 8.38 extern unsigned long prof_shift; 8.39
9.1 --- a/xen/include/xen/interrupt.h Thu Jun 17 09:33:04 2004 +0000 9.2 +++ b/xen/include/xen/interrupt.h Thu Jun 17 14:48:17 2004 +0000 9.3 @@ -12,11 +12,8 @@ 9.4 9.5 struct irqaction { 9.6 void (*handler)(int, void *, struct pt_regs *); 9.7 - unsigned long flags; 9.8 - unsigned long mask; 9.9 const char *name; 9.10 void *dev_id; 9.11 - struct irqaction *next; 9.12 }; 9.13 9.14 #include <asm/hardirq.h>
10.1 --- a/xen/include/xen/irq.h Thu Jun 17 09:33:04 2004 +0000 10.2 +++ b/xen/include/xen/irq.h Thu Jun 17 14:48:17 2004 +0000 10.3 @@ -12,9 +12,7 @@ 10.4 #define IRQ_DISABLED 2 /* IRQ disabled - do not enter! */ 10.5 #define IRQ_PENDING 4 /* IRQ pending - replay on enable */ 10.6 #define IRQ_REPLAY 8 /* IRQ has been replayed but not acked yet */ 10.7 -#define IRQ_AUTODETECT 16 /* IRQ is being autodetected */ 10.8 -#define IRQ_WAITING 32 /* IRQ not yet seen - for autodetection */ 10.9 -#define IRQ_GUEST 64 /* IRQ is handled by guest OS(es) */ 10.10 +#define IRQ_GUEST 16 /* IRQ is handled by guest OS(es) */ 10.11 10.12 /* 10.13 * Interrupt controller descriptor. This is all we need 10.14 @@ -53,6 +51,7 @@ typedef struct { 10.15 extern irq_desc_t irq_desc[NR_IRQS]; 10.16 10.17 extern int setup_irq(unsigned int, struct irqaction *); 10.18 +extern void free_irq(unsigned int); 10.19 10.20 extern hw_irq_controller no_irq_type; 10.21 extern void no_action(int cpl, void *dev_id, struct pt_regs *regs); 10.22 @@ -61,5 +60,6 @@ struct task_struct; 10.23 extern int pirq_guest_unmask(struct task_struct *p); 10.24 extern int pirq_guest_bind(struct task_struct *p, int irq, int will_share); 10.25 extern int pirq_guest_unbind(struct task_struct *p, int irq); 10.26 +extern int pirq_guest_bindable(int irq, int will_share); 10.27 10.28 #endif /* __XEN_IRQ_H__ */
11.1 --- a/xen/include/xen/sched.h Thu Jun 17 09:33:04 2004 +0000 11.2 +++ b/xen/include/xen/sched.h Thu Jun 17 14:48:17 2004 +0000 11.3 @@ -242,12 +242,6 @@ void new_thread(struct task_struct *p, 11.4 unsigned long start_stack, 11.5 unsigned long start_info); 11.6 11.7 -/* Linux puts these here for some reason! */ 11.8 -extern int request_irq(unsigned int, 11.9 - void (*handler)(int, void *, struct pt_regs *), 11.10 - unsigned long, const char *, void *); 11.11 -extern void free_irq(unsigned int, void *); 11.12 - 11.13 extern unsigned long wait_init_idle; 11.14 #define init_idle() clear_bit(smp_processor_id(), &wait_init_idle); 11.15