direct-io.hg

changeset 1498:d81962226803

bitkeeper revision 1.977 (40d1af37oBB1b1SdQkgqOJajb8vT1w)

Merge scramble.cl.cam.ac.uk:/auto/groups/xeno/BK/xeno.bk
into scramble.cl.cam.ac.uk:/local/scratch/kaf24/xeno
author kaf24@scramble.cl.cam.ac.uk
date Thu Jun 17 14:48:23 2004 +0000 (2004-06-17)
parents c2247f632d3f ce351da91680
children 231c7f2a212e
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 13:18:35 2004 +0000
     1.2 +++ b/xen/arch/x86/i8259.c	Thu Jun 17 14:48:23 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 13:18:35 2004 +0000
     2.2 +++ b/xen/arch/x86/irq.c	Thu Jun 17 14:48:23 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, &regs, 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, &regs);
   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 13:18:35 2004 +0000
     3.2 +++ b/xen/arch/x86/pci-irq.c	Thu Jun 17 14:48:23 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 13:18:35 2004 +0000
     4.2 +++ b/xen/arch/x86/setup.c	Thu Jun 17 14:48:23 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 13:18:35 2004 +0000
     5.2 +++ b/xen/arch/x86/time.c	Thu Jun 17 14:48:23 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 13:18:35 2004 +0000
     6.2 +++ b/xen/drivers/char/keyboard.c	Thu Jun 17 14:48:23 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 13:18:35 2004 +0000
     7.2 +++ b/xen/drivers/char/serial.c	Thu Jun 17 14:48:23 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 13:18:35 2004 +0000
     8.2 +++ b/xen/include/asm-x86/irq.h	Thu Jun 17 14:48:23 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 13:18:35 2004 +0000
     9.2 +++ b/xen/include/xen/interrupt.h	Thu Jun 17 14:48:23 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 13:18:35 2004 +0000
    10.2 +++ b/xen/include/xen/irq.h	Thu Jun 17 14:48:23 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 13:18:35 2004 +0000
    11.2 +++ b/xen/include/xen/sched.h	Thu Jun 17 14:48:23 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