ia64/xen-unstable

changeset 10142:5be25952b50d

[IA64] Clean up pirq bind code

This patch clears some pirq related logic as a last prep step
for the final evtchn to be effective. Same, this patch doesn't
break existing logic.

Signed-off-by Kevin Tian <kevin.tian@intel.com>
author awilliam@xenbuild.aw
date Tue May 23 08:56:13 2006 -0600 (2006-05-23)
parents 2f2f500c26da
children f0f88d9c4c9e
files xen/arch/ia64/xen/irq.c
line diff
     1.1 --- a/xen/arch/ia64/xen/irq.c	Tue May 23 08:34:48 2006 -0600
     1.2 +++ b/xen/arch/ia64/xen/irq.c	Tue May 23 08:56:13 2006 -0600
     1.3 @@ -392,6 +392,9 @@ typedef struct {
     1.4      u8 nr_guests;
     1.5      u8 in_flight;
     1.6      u8 shareable;
     1.7 +    u8 ack_type;
     1.8 +#define ACKTYPE_NONE   0     /* No final acknowledgement is required */
     1.9 +#define ACKTYPE_UNMASK 1     /* Unmask notification is required */
    1.10      struct domain *guest[IRQ_MAX_GUESTS];
    1.11  } irq_guest_action_t;
    1.12  
    1.13 @@ -405,12 +408,26 @@ void __do_IRQ_guest(int irq)
    1.14      for ( i = 0; i < action->nr_guests; i++ )
    1.15      {
    1.16          d = action->guest[i];
    1.17 -        if ( !test_and_set_bit(irq, &d->pirq_mask) )
    1.18 +        if ( (action->ack_type != ACKTYPE_NONE) &&
    1.19 +             !test_and_set_bit(irq, &d->pirq_mask) )
    1.20              action->in_flight++;
    1.21          send_guest_pirq(d, irq);
    1.22      }
    1.23  }
    1.24  
    1.25 +int pirq_acktype(int irq)
    1.26 +{
    1.27 +    irq_desc_t *desc = &irq_desc[irq];
    1.28 +
    1.29 +    if (!strcmp(desc->handler->typename, "IO-SAPIC-level"))
    1.30 +        return ACKTYPE_UNMASK;
    1.31 +
    1.32 +    if (!strcmp(desc->handler->typename, "IO-SAPIC-edge"))
    1.33 +        return ACKTYPE_NONE;
    1.34 +
    1.35 +    return ACKTYPE_NONE;
    1.36 +}
    1.37 +
    1.38  int pirq_guest_eoi(struct domain *d, int irq)
    1.39  {
    1.40      irq_desc_t *desc;
    1.41 @@ -422,7 +439,10 @@ int pirq_guest_eoi(struct domain *d, int
    1.42      spin_lock_irq(&desc->lock);
    1.43      if ( test_and_clear_bit(irq, &d->pirq_mask) &&
    1.44           (--((irq_guest_action_t *)desc->action)->in_flight == 0) )
    1.45 +    {
    1.46 +        ASSERT(action->ack_type == ACKTYPE_UNMASK);
    1.47          desc->handler->end(irq);
    1.48 +    }
    1.49      spin_unlock_irq(&desc->lock);
    1.50  
    1.51      return 0;
    1.52 @@ -431,7 +451,6 @@ int pirq_guest_eoi(struct domain *d, int
    1.53  
    1.54  int pirq_guest_unmask(struct domain *d)
    1.55  {
    1.56 -    irq_desc_t    *desc;
    1.57      int            irq;
    1.58      shared_info_t *s = d->shared_info;
    1.59  
    1.60 @@ -439,13 +458,9 @@ int pirq_guest_unmask(struct domain *d)
    1.61            irq < NR_IRQS;
    1.62            irq = find_next_bit(d->pirq_mask, NR_IRQS, irq+1) )
    1.63      {
    1.64 -        desc = &irq_desc[irq];
    1.65 -        spin_lock_irq(&desc->lock);
    1.66 -        if ( !test_bit(d->pirq_to_evtchn[irq], &s->evtchn_mask[0]) &&
    1.67 -             test_and_clear_bit(irq, &d->pirq_mask) &&
    1.68 -             (--((irq_guest_action_t *)desc->action)->in_flight == 0) )
    1.69 -            desc->handler->end(irq);
    1.70 -        spin_unlock_irq(&desc->lock);
    1.71 +        if ( !test_bit(d->pirq_to_evtchn[irq], &s->evtchn_mask[0]) )
    1.72 +            pirq_guest_eoi(d, irq);
    1.73 +
    1.74      }
    1.75  
    1.76      return 0;
    1.77 @@ -460,6 +475,11 @@ int pirq_guest_bind(struct vcpu *v, int 
    1.78  
    1.79      spin_lock_irqsave(&desc->lock, flags);
    1.80  
    1.81 +    if (desc->handler == &no_irq_type) {
    1.82 +        spin_unlock_irqrestore(&desc->lock, flags);
    1.83 +        return -ENOSYS;
    1.84 +    }
    1.85 +
    1.86      action = (irq_guest_action_t *)desc->action;
    1.87  
    1.88      if ( !(desc->status & IRQ_GUEST) )
    1.89 @@ -483,6 +503,7 @@ int pirq_guest_bind(struct vcpu *v, int 
    1.90          action->nr_guests = 0;
    1.91          action->in_flight = 0;
    1.92          action->shareable = will_share;
    1.93 +        action->ack_type  = pirq_acktype(irq);
    1.94          
    1.95          desc->depth = 0;
    1.96          desc->status |= IRQ_GUEST;
    1.97 @@ -529,12 +550,20 @@ int pirq_guest_unbind(struct domain *d, 
    1.98  
    1.99      action = (irq_guest_action_t *)desc->action;
   1.100  
   1.101 -    if ( test_and_clear_bit(irq, &d->pirq_mask) &&
   1.102 -         (--action->in_flight == 0) )
   1.103 -        desc->handler->end(irq);
   1.104 +    i = 0;
   1.105 +    while ( action->guest[i] && (action->guest[i] != d) )
   1.106 +        i++;
   1.107 +    memmove(&action->guest[i], &action->guest[i+1], IRQ_MAX_GUESTS-i-1);
   1.108 +    action->nr_guests--;
   1.109  
   1.110 -    if ( action->nr_guests == 1 )
   1.111 +    if ( action->ack_type == ACKTYPE_UNMASK )
   1.112 +        if ( test_and_clear_bit(irq, &d->pirq_mask) &&
   1.113 +             (--action->in_flight == 0) )
   1.114 +            desc->handler->end(irq);
   1.115 +
   1.116 +    if ( !action->nr_guests )
   1.117      {
   1.118 +        BUG_ON(action->in_flight != 0);
   1.119          desc->action = NULL;
   1.120          xfree(action);
   1.121          desc->depth   = 1;
   1.122 @@ -542,14 +571,6 @@ int pirq_guest_unbind(struct domain *d, 
   1.123          desc->status &= ~IRQ_GUEST;
   1.124          desc->handler->shutdown(irq);
   1.125      }
   1.126 -    else
   1.127 -    {
   1.128 -        i = 0;
   1.129 -        while ( action->guest[i] != d )
   1.130 -            i++;
   1.131 -        memmove(&action->guest[i], &action->guest[i+1], IRQ_MAX_GUESTS-i-1);
   1.132 -        action->nr_guests--;
   1.133 -    }
   1.134  
   1.135      spin_unlock_irqrestore(&desc->lock, flags);    
   1.136      return 0;