ia64/xen-unstable

changeset 1240:e2d412f4b445

bitkeeper revision 1.825.4.5 (40644998-owgquq-q989ZcZtyvAP9Q)

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 Fri Mar 26 15:17:44 2004 +0000 (2004-03-26)
parents b651279526f3 ebfb82dc24e2
children 916d919c54b7 328b9b7ee67e
files xen/arch/i386/io_apic.c xen/arch/i386/irq.c xen/common/event_channel.c xen/common/physdev.c xen/drivers/char/console.c xen/include/asm-i386/irq.h xen/include/asm-x86_64/irq.h xen/include/xen/interrupt.h xen/include/xen/irq.h
line diff
     1.1 --- a/xen/arch/i386/io_apic.c	Fri Mar 26 13:20:05 2004 +0000
     1.2 +++ b/xen/arch/i386/io_apic.c	Fri Mar 26 15:17:44 2004 +0000
     1.3 @@ -138,14 +138,10 @@ static void __init replace_pin_at_irq(un
     1.4  	static void name##_IO_APIC_irq (unsigned int irq)		\
     1.5  	__DO_ACTION(R, ACTION, FINAL)
     1.6  
     1.7 -DO_ACTION( __mask,             0, |= 0x00010000, io_apic_sync(entry->apic) )
     1.8 -						/* mask = 1 */
     1.9 -DO_ACTION( __unmask,           0, &= 0xfffeffff, )
    1.10 -						/* mask = 0 */
    1.11 -DO_ACTION( __mask_and_edge,    0, = (reg & 0xffff7fff) | 0x00010000, )
    1.12 -						/* mask = 1, trigger = 0 */
    1.13 -DO_ACTION( __unmask_and_level, 0, = (reg & 0xfffeffff) | 0x00008000, )
    1.14 -						/* mask = 0, trigger = 1 */
    1.15 +DO_ACTION( __mask,    0, |= 0x00010000, io_apic_sync(entry->apic) )
    1.16 +DO_ACTION( __unmask,  0, &= 0xfffeffff, )
    1.17 +DO_ACTION( __edge,    0, &= 0xffff7fff, )
    1.18 +DO_ACTION( __level,   0, |= 0x00008000, )
    1.19  
    1.20  static void mask_IO_APIC_irq (unsigned int irq)
    1.21  {
    1.22 @@ -1365,13 +1361,15 @@ static unsigned int startup_level_ioapic
    1.23  	return 0; /* don't check for pending */
    1.24  }
    1.25  
    1.26 -static void end_level_ioapic_irq (unsigned int irq)
    1.27 +static void mask_and_ack_level_ioapic_irq(unsigned int irq)
    1.28  {
    1.29  	unsigned long v;
    1.30  	int i;
    1.31  
    1.32  	balance_irq(irq);
    1.33  
    1.34 +	mask_IO_APIC_irq(irq);
    1.35 +
    1.36  /*
    1.37   * It appears there is an erratum which affects at least version 0x11
    1.38   * of I/O APIC (that's the 82093AA and cores integrated into various
    1.39 @@ -1405,7 +1403,7 @@ static void end_level_ioapic_irq (unsign
    1.40  		atomic_inc(&irq_mis_count);
    1.41  #endif
    1.42  		spin_lock(&ioapic_lock);
    1.43 -		__mask_and_edge_IO_APIC_irq(irq);
    1.44 +		__edge_IO_APIC_irq(irq);
    1.45  #ifdef APIC_LOCKUP_DEBUG
    1.46  		for (entry = irq_2_pin + irq;;) {
    1.47  			unsigned int reg;
    1.48 @@ -1421,12 +1419,15 @@ static void end_level_ioapic_irq (unsign
    1.49  			entry = irq_2_pin + entry->next;
    1.50  		}
    1.51  #endif
    1.52 -		__unmask_and_level_IO_APIC_irq(irq);
    1.53 +		__level_IO_APIC_irq(irq);
    1.54  		spin_unlock(&ioapic_lock);
    1.55  	}
    1.56  }
    1.57  
    1.58 -static void mask_and_ack_level_ioapic_irq (unsigned int irq) { /* nothing */ }
    1.59 +static void end_level_ioapic_irq(unsigned int irq)
    1.60 +{
    1.61 +	unmask_IO_APIC_irq(irq);
    1.62 +}
    1.63  
    1.64  static inline void init_IO_APIC_traps(void)
    1.65  {
     2.1 --- a/xen/arch/i386/irq.c	Fri Mar 26 13:20:05 2004 +0000
     2.2 +++ b/xen/arch/i386/irq.c	Fri Mar 26 15:17:44 2004 +0000
     2.3 @@ -24,6 +24,7 @@
     2.4  #include <xen/interrupt.h>
     2.5  #include <xen/irq.h>
     2.6  #include <xen/slab.h>
     2.7 +#include <xen/event.h>
     2.8  #include <asm/mpspec.h>
     2.9  #include <asm/io_apic.h>
    2.10  #include <asm/msr.h>
    2.11 @@ -66,6 +67,8 @@ irq_desc_t irq_desc[NR_IRQS] __cacheline
    2.12  unsigned long irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = ~0UL };
    2.13  #endif
    2.14  
    2.15 +static void __do_IRQ_guest(int irq);
    2.16 +
    2.17  /*
    2.18   * Special irq handlers.
    2.19   */
    2.20 @@ -333,7 +336,9 @@ void __global_restore_flags(unsigned lon
    2.21   * waste of time and is not what some drivers would
    2.22   * prefer.
    2.23   */
    2.24 -int handle_IRQ_event(unsigned int irq, struct pt_regs * regs, struct irqaction * action)
    2.25 +static int handle_IRQ_event(unsigned int irq, 
    2.26 +                            struct pt_regs * regs, 
    2.27 +                            struct irqaction * action)
    2.28  {
    2.29      int status;
    2.30      int cpu = smp_processor_id();
    2.31 @@ -483,6 +488,7 @@ asmlinkage unsigned int do_IRQ(struct pt
    2.32  
    2.33      spin_lock(&desc->lock);
    2.34      desc->handler->ack(irq);
    2.35 +
    2.36      /*
    2.37        REPLAY is when Linux resends an IRQ that was dropped earlier
    2.38        WAITING is used by probe to mark irqs that are being tested
    2.39 @@ -490,6 +496,14 @@ asmlinkage unsigned int do_IRQ(struct pt
    2.40      status = desc->status & ~(IRQ_REPLAY | IRQ_WAITING);
    2.41      status |= IRQ_PENDING; /* we _want_ to handle it */
    2.42  
    2.43 +    /* We hook off guest-bound IRQs for special handling. */
    2.44 +    if ( status & IRQ_GUEST )
    2.45 +    {
    2.46 +        __do_IRQ_guest(irq);
    2.47 +        spin_unlock(&desc->lock);
    2.48 +        return 1;
    2.49 +    }
    2.50 +
    2.51      /*
    2.52       * If the IRQ is disabled for whatever reason, we cannot use the action we 
    2.53       * have.
    2.54 @@ -883,6 +897,13 @@ int setup_irq(unsigned int irq, struct i
    2.55       * The following block of code has to be executed atomically
    2.56       */
    2.57      spin_lock_irqsave(&desc->lock,flags);
    2.58 +
    2.59 +    if ( desc->status & IRQ_GUEST )
    2.60 +    {
    2.61 +        spin_unlock_irqrestore(&desc->lock,flags);
    2.62 +        return -EBUSY;
    2.63 +    }
    2.64 +
    2.65      p = &desc->action;
    2.66      if ((old = *p) != NULL) {
    2.67          /* Can't share interrupts unless both agree to */
    2.68 @@ -906,7 +927,110 @@ int setup_irq(unsigned int irq, struct i
    2.69          desc->status &= ~(IRQ_DISABLED | IRQ_AUTODETECT | IRQ_WAITING);
    2.70          desc->handler->startup(irq);
    2.71      }
    2.72 +
    2.73      spin_unlock_irqrestore(&desc->lock,flags);
    2.74  
    2.75      return 0;
    2.76  }
    2.77 +
    2.78 +
    2.79 +
    2.80 +/*
    2.81 + * HANDLING OF GUEST-BOUND PHYSICAL IRQS
    2.82 + */
    2.83 +
    2.84 +#define IRQ_MAX_GUESTS 7
    2.85 +typedef struct {
    2.86 +    unsigned int nr_guests;
    2.87 +    struct task_struct *guest[IRQ_MAX_GUESTS];
    2.88 +} irq_guest_action_t;
    2.89 +
    2.90 +static void __do_IRQ_guest(int irq)
    2.91 +{
    2.92 +    irq_desc_t *desc = &irq_desc[irq];
    2.93 +    irq_guest_action_t *action = (irq_guest_action_t *)desc->action;
    2.94 +    struct task_struct *p;
    2.95 +    int i;
    2.96 +
    2.97 +    for ( i = 0; i < action->nr_guests; i++ )
    2.98 +    {
    2.99 +        p = action->guest[i];
   2.100 +        send_guest_pirq(p, irq);
   2.101 +    }
   2.102 +}
   2.103 +
   2.104 +int pirq_guest_bind(struct task_struct *p, int irq)
   2.105 +{
   2.106 +    unsigned long flags;
   2.107 +    irq_desc_t *desc = &irq_desc[irq];
   2.108 +    irq_guest_action_t *action;
   2.109 +    int rc;
   2.110 +
   2.111 +    if ( !IS_PRIV(p) )
   2.112 +        return -EPERM;
   2.113 +
   2.114 +    spin_lock_irqsave(&desc->lock, flags);
   2.115 +
   2.116 +    if ( !(desc->status & IRQ_GUEST) )
   2.117 +    {
   2.118 +        rc = -EBUSY;
   2.119 +        if ( desc->action != NULL )
   2.120 +            goto out;
   2.121 +
   2.122 +        rc = -ENOMEM;
   2.123 +        action = kmalloc(sizeof(irq_guest_action_t), GFP_KERNEL);
   2.124 +        if ( (desc->action = (struct irqaction *)action) == NULL )
   2.125 +            goto out;
   2.126 +
   2.127 +        action->nr_guests = 0;
   2.128 +
   2.129 +        desc->depth = 0;
   2.130 +        desc->status |= IRQ_GUEST;
   2.131 +        desc->status &= ~(IRQ_DISABLED | IRQ_AUTODETECT | IRQ_WAITING);
   2.132 +        desc->handler->startup(irq);
   2.133 +    }
   2.134 +
   2.135 +    action = (irq_guest_action_t *)desc->action;
   2.136 +
   2.137 +    rc = -EBUSY;
   2.138 +    if ( action->nr_guests == IRQ_MAX_GUESTS )
   2.139 +        goto out;
   2.140 +
   2.141 +    action->guest[action->nr_guests++] = p;
   2.142 +
   2.143 + out:
   2.144 +    spin_unlock_irqrestore(&desc->lock, flags);
   2.145 +    return rc;
   2.146 +}
   2.147 +
   2.148 +int pirq_guest_unbind(struct task_struct *p, int irq)
   2.149 +{
   2.150 +    unsigned long flags;
   2.151 +    irq_desc_t *desc = &irq_desc[irq];
   2.152 +    irq_guest_action_t *action;
   2.153 +    int i;
   2.154 +
   2.155 +    spin_lock_irqsave(&desc->lock, flags);
   2.156 +
   2.157 +    action = (irq_guest_action_t *)desc->action;
   2.158 +
   2.159 +    if ( action->nr_guests == 1 )
   2.160 +    {
   2.161 +        desc->action = NULL;
   2.162 +        kfree(action);
   2.163 +        desc->status |= IRQ_DISABLED;
   2.164 +        desc->status &= ~IRQ_GUEST;
   2.165 +        desc->handler->shutdown(irq);
   2.166 +    }
   2.167 +    else
   2.168 +    {
   2.169 +        i = 0;
   2.170 +        while ( action->guest[i] != p )
   2.171 +            i++;
   2.172 +        memmove(&action->guest[i], &action->guest[i+1], IRQ_MAX_GUESTS-i-1);
   2.173 +        action->nr_guests--;
   2.174 +    }
   2.175 +
   2.176 +    spin_unlock_irqrestore(&desc->lock, flags);    
   2.177 +    return 0;
   2.178 +}
     3.1 --- a/xen/common/event_channel.c	Fri Mar 26 13:20:05 2004 +0000
     3.2 +++ b/xen/common/event_channel.c	Fri Mar 26 15:17:44 2004 +0000
     3.3 @@ -21,6 +21,7 @@
     3.4  #include <xen/errno.h>
     3.5  #include <xen/sched.h>
     3.6  #include <xen/event.h>
     3.7 +#include <xen/irq.h>
     3.8  
     3.9  #include <hypervisor-ifs/hypervisor-if.h>
    3.10  #include <hypervisor-ifs/event_channel.h>
    3.11 @@ -181,27 +182,32 @@ static long evtchn_bind_pirq(evtchn_bind
    3.12  {
    3.13      struct task_struct *p = current;
    3.14      int pirq = bind->pirq;
    3.15 -    int port;
    3.16 +    int port, rc;
    3.17  
    3.18      if ( pirq >= ARRAY_SIZE(p->pirq_to_evtchn) )
    3.19          return -EINVAL;
    3.20  
    3.21      spin_lock(&p->event_channel_lock);
    3.22  
    3.23 -    if ( ((port = p->pirq_to_evtchn[pirq]) != 0) ||
    3.24 -         ((port = get_free_port(p)) < 0) )
    3.25 +    if ( ((rc = port = p->pirq_to_evtchn[pirq]) != 0) ||
    3.26 +         ((rc = port = get_free_port(p)) < 0) )
    3.27          goto out;
    3.28  
    3.29 +    p->pirq_to_evtchn[pirq] = port;
    3.30 +    if ( (rc = pirq_guest_bind(p, pirq)) != 0 )
    3.31 +    {
    3.32 +        p->pirq_to_evtchn[pirq] = 0;
    3.33 +        goto out;
    3.34 +    }
    3.35 +
    3.36      p->event_channel[port].state  = ECS_PIRQ;
    3.37      p->event_channel[port].u.pirq = pirq;
    3.38  
    3.39 -    p->pirq_to_evtchn[pirq] = port;
    3.40 -
    3.41   out:
    3.42      spin_unlock(&p->event_channel_lock);
    3.43  
    3.44 -    if ( port < 0 )
    3.45 -        return port;
    3.46 +    if ( rc < 0 )
    3.47 +        return rc;
    3.48  
    3.49      bind->port = port;
    3.50      return 0;
    3.51 @@ -237,7 +243,8 @@ static long __evtchn_close(struct task_s
    3.52          break;
    3.53  
    3.54      case ECS_PIRQ:
    3.55 -        p1->pirq_to_evtchn[chn1[port1].u.pirq] = 0;
    3.56 +        if ( (rc = pirq_guest_unbind(p1, chn1[port1].u.pirq)) == 0 )
    3.57 +            p1->pirq_to_evtchn[chn1[port1].u.pirq] = 0;
    3.58          break;
    3.59  
    3.60      case ECS_VIRQ:
     4.1 --- a/xen/common/physdev.c	Fri Mar 26 13:20:05 2004 +0000
     4.2 +++ b/xen/common/physdev.c	Fri Mar 26 15:17:44 2004 +0000
     4.3 @@ -65,26 +65,16 @@
     4.4  /* bit offsets into state */
     4.5  #define ST_BASE_ADDRESS  0   /* bits 0-5: are for base address access */
     4.6  #define ST_ROM_ADDRESS   6   /* bit 6: is for rom address access */    
     4.7 -#define ST_IRQ_DELIVERED 7   /* bit 7: waiting for end irq call */    
     4.8  
     4.9 -typedef struct _phys_dev_st
    4.10 -{
    4.11 +typedef struct _phys_dev_st {
    4.12      int flags;                       /* flags for access etc */
    4.13      struct pci_dev *dev;             /* the device */
    4.14      struct list_head node;           /* link to the list */
    4.15      struct task_struct *owner;       /* 'owner of this device' */
    4.16      int state;                       /* state for various checks */
    4.17 -
    4.18 -    hw_irq_controller *new_handler;  /* saved old handler */
    4.19 -    hw_irq_controller *orig_handler; /* saved old handler */
    4.20 -
    4.21  } phys_dev_t;
    4.22  
    4.23  
    4.24 -#define MAX_IRQS 32
    4.25 -/* an array of device descriptors index by IRQ number */
    4.26 -static phys_dev_t *irqs[MAX_IRQS];
    4.27 -
    4.28  /*
    4.29   * 
    4.30   * General functions
    4.31 @@ -573,158 +563,9 @@ static long pci_find_irq(int seg, int bu
    4.32      return 0;
    4.33  }
    4.34  
    4.35 -static void phys_dev_interrupt(int irq, void *dev_id, struct pt_regs *ptregs)
    4.36 -{
    4.37 -    phys_dev_t          *pdev;
    4.38 -
    4.39 -    if ( (pdev = (phys_dev_t *)dev_id) == NULL )
    4.40 -    {
    4.41 -        printk("spurious interrupt, no proper device id, %d\n", irq);
    4.42 -        return;
    4.43 -    }
    4.44 -    
    4.45 -    /* XXX KAF: introduced race here? */
    4.46 -    set_bit(ST_IRQ_DELIVERED, &pdev->state);
    4.47 -    send_guest_pirq(pdev->owner, irq);
    4.48 -}
    4.49 -
    4.50 -/* this is called instead of the PICs original end handler. 
    4.51 - * the real end handler is only called once the guest signalled the handling
    4.52 - * of the event. */
    4.53 -static void end_virt_irq (unsigned int i)
    4.54 -{
    4.55 -    /* nothing */
    4.56 -}
    4.57 -
    4.58 -/*
    4.59 - * a guest request an IRQ from a device to be routed to it
    4.60 - * - shared interrupts are not allowed for now
    4.61 - * - we change the hw_irq handler to something else
    4.62 - */
    4.63 -static long pirq_request(int irq)
    4.64 -{
    4.65 -    int err;
    4.66 -    phys_dev_t *pdev = NULL, *t;
    4.67 -    hw_irq_controller *new, *orig;
    4.68 -    struct list_head *tmp;
    4.69 -
    4.70 -    printk("request irq %d\n", irq);
    4.71 -
    4.72 -    /* find pdev */
    4.73 -
    4.74 -    list_for_each(tmp, &current->pcidev_list)
    4.75 -    {
    4.76 -        t = list_entry(tmp,  phys_dev_t, node);
    4.77 -        if ( t->dev->irq == irq )
    4.78 -        {
    4.79 -            pdev = t;
    4.80 -            break;
    4.81 -        }
    4.82 -    }
    4.83 -
    4.84 -    if ( pdev == NULL )
    4.85 -    {
    4.86 -        printk("no device matching IRQ %d\n", irq);
    4.87 -        return -EINVAL;
    4.88 -    }
    4.89 -
    4.90 -    if ( irq >= MAX_IRQS )
    4.91 -    {
    4.92 -        printk("requested IRQ to big %d\n", irq);
    4.93 -        return -EINVAL;
    4.94 -    }
    4.95 -
    4.96 -    if ( irqs[irq] != NULL )
    4.97 -    {
    4.98 -        printk ("irq already in use %d\n", irq);
    4.99 -        return -EPERM;
   4.100 -    }
   4.101 -
   4.102 -    /* allocate a hw_irq controller and copy the original */
   4.103 -    if ( !(new  = kmalloc(sizeof(hw_irq_controller), GFP_KERNEL)) )
   4.104 -    {
   4.105 -        printf("error allocating new irq controller\n");
   4.106 -        return -ENOMEM;
   4.107 -    }
   4.108 -    orig = irq_desc[irq].handler;
   4.109 -    new->typename = orig->typename;
   4.110 -    new->startup = orig->startup;
   4.111 -    new->shutdown = orig->shutdown;
   4.112 -    new->enable = orig->enable;
   4.113 -    new->disable = orig->disable;
   4.114 -    new->ack = orig->ack;
   4.115 -    new->end = orig->end;
   4.116 -    new->set_affinity = orig->set_affinity;
   4.117 -
   4.118 -    /* swap the end routine */
   4.119 -    new->end = end_virt_irq;
   4.120 -
   4.121 -    /* change the irq controllers */
   4.122 -    pdev->orig_handler = orig;
   4.123 -    pdev->new_handler  = new;
   4.124 -    irq_desc[irq].handler = new;
   4.125 -    irqs[irq] = pdev;
   4.126 -    
   4.127 -    printk ("setup handler %d\n", irq);
   4.128 -
   4.129 -    /* request the IRQ. this is not shared and we use a slow handler! */
   4.130 -    err = request_irq(irq, phys_dev_interrupt, SA_INTERRUPT,
   4.131 -                      "foo", (void *)pdev);
   4.132 -    if ( err )
   4.133 -    {
   4.134 -        printk("error requesting irq\n");
   4.135 -        /* restore original */
   4.136 -        irq_desc[irq].handler = pdev->orig_handler;
   4.137 -        /* free memory */
   4.138 -        kfree(new);
   4.139 -        return err;
   4.140 -    }
   4.141 -
   4.142 -    printk ("done\n");
   4.143 -
   4.144 -    return 0;
   4.145 -}
   4.146 -
   4.147 -long pirq_free(int irq)
   4.148 -{
   4.149 -    phys_dev_t *pdev;
   4.150 -
   4.151 -    if ( irq >= MAX_IRQS )
   4.152 -    {
   4.153 -        printk("requested IRQ to big %d\n", irq);
   4.154 -        return -EINVAL;
   4.155 -    }
   4.156 -
   4.157 -    if ( irqs[irq] == NULL )
   4.158 -    {
   4.159 -        printk ("irq not used %d\n", irq);
   4.160 -        return -EINVAL;
   4.161 -    }
   4.162 -
   4.163 -    pdev = irqs[irq];
   4.164 -
   4.165 -    /* shutdown IRQ */
   4.166 -    free_irq(irq, (void *)pdev);
   4.167 -
   4.168 -    /* restore irq controller  */
   4.169 -    irq_desc[irq].handler = pdev->orig_handler;
   4.170 -
   4.171 -    /* clean up */
   4.172 -    pdev->orig_handler = NULL;
   4.173 -    irqs[irq] = NULL;
   4.174 -    kfree(pdev->new_handler);
   4.175 -    pdev->new_handler = NULL;
   4.176 -
   4.177 -    printk("freed irq %d", irq);
   4.178 -    return 0;
   4.179 -}
   4.180  
   4.181  static long pci_unmask_irq(void)
   4.182  {
   4.183 -#if 0
   4.184 -    clear_bit(ST_IRQ_DELIVERED, &pdev->state);
   4.185 -    pdev->orig_handler->end(irq);
   4.186 -#endif
   4.187      return 0;
   4.188  }
   4.189  
     5.1 --- a/xen/drivers/char/console.c	Fri Mar 26 13:20:05 2004 +0000
     5.2 +++ b/xen/drivers/char/console.c	Fri Mar 26 15:17:44 2004 +0000
     5.3 @@ -227,8 +227,8 @@ long read_console_ring(unsigned long str
     5.4  static char serial_rx_ring[SERIAL_RX_SIZE];
     5.5  static unsigned int serial_rx_cons, serial_rx_prod;
     5.6  
     5.7 -/* CTRL-a switches input direction between Xen and DOM0. */
     5.8 -#define CTRL_A 0x01
     5.9 +/* CTRL-g switches input direction between Xen and DOM0. */
    5.10 +#define CTRL_G 0x07
    5.11  static int xen_rx = 1; /* FALSE => serial input passed to domain 0. */
    5.12  
    5.13  static void switch_serial_input(void)
    5.14 @@ -236,7 +236,7 @@ static void switch_serial_input(void)
    5.15      static char *input_str[2] = { "DOM0", "Xen" };
    5.16      xen_rx = !xen_rx;
    5.17      printk("*** Serial input -> %s "
    5.18 -           "(type 'CTRL-a' three times to switch input to %s).\n",
    5.19 +           "(type 'CTRL-g' three times to switch input to %s).\n",
    5.20             input_str[xen_rx], input_str[!xen_rx]);
    5.21  }
    5.22  
    5.23 @@ -264,22 +264,22 @@ static void __serial_rx(unsigned char c,
    5.24  
    5.25  static void serial_rx(unsigned char c, struct pt_regs *regs)
    5.26  {
    5.27 -    static int ctrl_a_count = 0;
    5.28 +    static int ctrl_g_count = 0;
    5.29  
    5.30 -    if ( c == CTRL_A )
    5.31 +    if ( c == CTRL_G )
    5.32      {
    5.33 -        /* We eat CTRL-a in groups of three to switch console input. */
    5.34 -        if ( ++ctrl_a_count == 3 )
    5.35 +        /* We eat CTRL-g in groups of three to switch console input. */
    5.36 +        if ( ++ctrl_g_count == 3 )
    5.37          {
    5.38              switch_serial_input();
    5.39 -            ctrl_a_count = 0;
    5.40 +            ctrl_g_count = 0;
    5.41          }
    5.42      }
    5.43      else
    5.44      {
    5.45 -        /* Flush any pending CTRL-a's. They weren't for us. */
    5.46 -        for ( ; ctrl_a_count != 0; ctrl_a_count-- )
    5.47 -            __serial_rx(CTRL_A, regs);
    5.48 +        /* Flush any pending CTRL-b's. They weren't for us. */
    5.49 +        for ( ; ctrl_g_count != 0; ctrl_g_count-- )
    5.50 +            __serial_rx(CTRL_G, regs);
    5.51          /* Finally process the just-received character. */
    5.52          __serial_rx(c, regs);
    5.53      }
     6.1 --- a/xen/include/asm-i386/irq.h	Fri Mar 26 13:20:05 2004 +0000
     6.2 +++ b/xen/include/asm-i386/irq.h	Fri Mar 26 15:17:44 2004 +0000
     6.3 @@ -192,10 +192,10 @@ extern unsigned long prof_shift;
     6.4  
     6.5  #include <xen/irq.h>
     6.6  
     6.7 -#ifdef CONFIG_SMP /*more of this file should probably be ifdefed SMP */
     6.8 +#if defined(CONFIG_X86_IO_APIC)
     6.9  static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) {
    6.10 -	if (IO_APIC_IRQ(i))
    6.11 -		send_IPI_self(IO_APIC_VECTOR(i));
    6.12 +        if (IO_APIC_IRQ(i))
    6.13 +                send_IPI_self(IO_APIC_VECTOR(i));
    6.14  }
    6.15  #else
    6.16  static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) {}
     7.1 --- a/xen/include/asm-x86_64/irq.h	Fri Mar 26 13:20:05 2004 +0000
     7.2 +++ b/xen/include/asm-x86_64/irq.h	Fri Mar 26 15:17:44 2004 +0000
     7.3 @@ -124,10 +124,10 @@ extern unsigned long prof_shift;
     7.4  
     7.5  #include <xen/irq.h>
     7.6  
     7.7 -#ifdef CONFIG_SMP /*more of this file should probably be ifdefed SMP */
     7.8 +#if defined(CONFIG_X86_IO_APIC)
     7.9  static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) {
    7.10 -	if (IO_APIC_IRQ(i))
    7.11 -		send_IPI_self(IO_APIC_VECTOR(i));
    7.12 +        if (IO_APIC_IRQ(i))
    7.13 +                send_IPI_self(IO_APIC_VECTOR(i));
    7.14  }
    7.15  #else
    7.16  static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) {}
     8.1 --- a/xen/include/xen/interrupt.h	Fri Mar 26 13:20:05 2004 +0000
     8.2 +++ b/xen/include/xen/interrupt.h	Fri Mar 26 15:17:44 2004 +0000
     8.3 @@ -16,7 +16,7 @@ typedef void irqreturn_t;
     8.4  #define IRQ_NONE
     8.5  #define IRQ_HANDLED
     8.6  #define IRQ_RETVAL(x)
     8.7 -                                                                                
     8.8 +
     8.9  struct irqaction {
    8.10  	void (*handler)(int, void *, struct pt_regs *);
    8.11  	unsigned long flags;
    8.12 @@ -26,7 +26,6 @@ struct irqaction {
    8.13  	struct irqaction *next;
    8.14  };
    8.15  
    8.16 -
    8.17  enum {
    8.18  	TIMER_BH = 0,
    8.19  	SCSI_BH
     9.1 --- a/xen/include/xen/irq.h	Fri Mar 26 13:20:05 2004 +0000
     9.2 +++ b/xen/include/xen/irq.h	Fri Mar 26 15:17:44 2004 +0000
     9.3 @@ -1,5 +1,5 @@
     9.4 -#ifndef __irq_h
     9.5 -#define __irq_h
     9.6 +#ifndef __XEN_IRQ_H__
     9.7 +#define __XEN_IRQ_H__
     9.8  
     9.9  #include <xen/config.h>
    9.10  #include <xen/spinlock.h>
    9.11 @@ -14,26 +14,24 @@
    9.12  #define IRQ_REPLAY	8	/* IRQ has been replayed but not acked yet */
    9.13  #define IRQ_AUTODETECT	16	/* IRQ is being autodetected */
    9.14  #define IRQ_WAITING	32	/* IRQ not yet seen - for autodetection */
    9.15 -#define IRQ_LEVEL	64	/* IRQ level triggered */
    9.16 -#define IRQ_MASKED	128	/* IRQ masked - shouldn't be seen again */
    9.17 -#define IRQ_PER_CPU	256	/* IRQ is per CPU */
    9.18 +#define IRQ_GUEST       64      /* IRQ is handled by guest OS(es) */
    9.19  
    9.20  /*
    9.21   * Interrupt controller descriptor. This is all we need
    9.22   * to describe about the low-level hardware. 
    9.23   */
    9.24  struct hw_interrupt_type {
    9.25 -	const char * typename;
    9.26 -	unsigned int (*startup)(unsigned int irq);
    9.27 -	void (*shutdown)(unsigned int irq);
    9.28 -	void (*enable)(unsigned int irq);
    9.29 -	void (*disable)(unsigned int irq);
    9.30 -	void (*ack)(unsigned int irq);
    9.31 -	void (*end)(unsigned int irq);
    9.32 -	void (*set_affinity)(unsigned int irq, unsigned long mask);
    9.33 +    const char *typename;
    9.34 +    unsigned int (*startup)(unsigned int irq);
    9.35 +    void (*shutdown)(unsigned int irq);
    9.36 +    void (*enable)(unsigned int irq);
    9.37 +    void (*disable)(unsigned int irq);
    9.38 +    void (*ack)(unsigned int irq);
    9.39 +    void (*end)(unsigned int irq);
    9.40 +    void (*set_affinity)(unsigned int irq, unsigned long mask);
    9.41  };
    9.42  
    9.43 -typedef struct hw_interrupt_type  hw_irq_controller;
    9.44 +typedef struct hw_interrupt_type hw_irq_controller;
    9.45  
    9.46  #include <asm/irq.h>
    9.47  
    9.48 @@ -45,19 +43,22 @@ typedef struct hw_interrupt_type  hw_irq
    9.49   * Pad this out to 32 bytes for cache and indexing reasons.
    9.50   */
    9.51  typedef struct {
    9.52 -	unsigned int status;		/* IRQ status */
    9.53 -	hw_irq_controller *handler;
    9.54 -	struct irqaction *action;	/* IRQ action list */
    9.55 -	unsigned int depth;		/* nested irq disables */
    9.56 -	spinlock_t lock;
    9.57 +    unsigned int status;		/* IRQ status */
    9.58 +    hw_irq_controller *handler;
    9.59 +    struct irqaction *action;	/* IRQ action list */
    9.60 +    unsigned int depth;		/* nested irq disables */
    9.61 +    spinlock_t lock;
    9.62  } ____cacheline_aligned irq_desc_t;
    9.63  
    9.64 -extern irq_desc_t irq_desc [NR_IRQS];
    9.65 +extern irq_desc_t irq_desc[NR_IRQS];
    9.66  
    9.67 -extern int handle_IRQ_event(unsigned int, struct pt_regs *, struct irqaction *);
    9.68 -extern int setup_irq(unsigned int , struct irqaction * );
    9.69 +extern int setup_irq(unsigned int, struct irqaction *);
    9.70  
    9.71 -extern hw_irq_controller no_irq_type;  /* needed in every arch ? */
    9.72 +extern hw_irq_controller no_irq_type;
    9.73  extern void no_action(int cpl, void *dev_id, struct pt_regs *regs);
    9.74  
    9.75 -#endif /* __asm_h */
    9.76 +struct task_struct;
    9.77 +extern int pirq_guest_bind(struct task_struct *p, int irq);
    9.78 +extern int pirq_guest_unbind(struct task_struct *p, int irq);
    9.79 +
    9.80 +#endif /* __XEN_IRQ_H__ */