ia64/xen-unstable

changeset 7670:214bd6a0ed27

Adapt to new evtchn interfaces.
Signed-off-by Kevin Tian <kevin.tian@intel.com>
author djm@kirby.fc.hp.com
date Thu Nov 10 08:18:25 2005 -0600 (2005-11-10)
parents 5b2d9807725d
children b12a48d9e841 4aeb53ba2890
files linux-2.6-xen-sparse/arch/ia64/xen/drivers/evtchn_ia64.c
line diff
     1.1 --- a/linux-2.6-xen-sparse/arch/ia64/xen/drivers/evtchn_ia64.c	Thu Nov 10 08:10:18 2005 -0600
     1.2 +++ b/linux-2.6-xen-sparse/arch/ia64/xen/drivers/evtchn_ia64.c	Thu Nov 10 08:18:25 2005 -0600
     1.3 @@ -6,86 +6,147 @@
     1.4  #include <asm/hw_irq.h>
     1.5  #include <asm-xen/evtchn.h>
     1.6  
     1.7 -#define MAX_EVTCHN 256
     1.8 +#define MAX_EVTCHN 1024
     1.9 +
    1.10 +/* Xen will never allocate port zero for any purpose. */
    1.11 +#define VALID_EVTCHN(_chn) (((_chn) != 0) && ((_chn) < MAX_EVTCHN))
    1.12 +
    1.13 +/* Binding types. Hey, only IRQT_VIRQ and IRQT_EVTCHN are supported now
    1.14 + * for XEN/IA64 - ktian1
    1.15 + */
    1.16 +enum { IRQT_UNBOUND, IRQT_PIRQ, IRQT_VIRQ, IRQT_IPI, IRQT_EVTCHN };
    1.17  
    1.18 -#define VALID_EVTCHN(_chn) ((_chn) >= 0)
    1.19 +/* Constructor for packed IRQ information. */
    1.20 +#define mk_irq_info(type, index, evtchn)				\
    1.21 +	(((u32)(type) << 24) | ((u32)(index) << 16) | (u32)(evtchn))
    1.22 +/* Convenient shorthand for packed representation of an unbound IRQ. */
    1.23 +#define IRQ_UNBOUND	mk_irq_info(IRQT_UNBOUND, 0, 0)
    1.24 +/* Accessor macros for packed IRQ information. */
    1.25 +#define evtchn_from_irq(irq) ((u16)(irq_info[irq]))
    1.26 +#define index_from_irq(irq)  ((u8)(irq_info[irq] >> 16))
    1.27 +#define type_from_irq(irq)   ((u8)(irq_info[irq] >> 24))
    1.28  
    1.29 +/* Packed IRQ information: binding type, sub-type index, and event channel. */
    1.30 +static u32 irq_info[NR_IRQS];
    1.31 +
    1.32 +/* One note for XEN/IA64 is that we have all event channels bound to one
    1.33 + * physical irq vector. So we always mean evtchn vector identical to 'irq'
    1.34 + * vector in this context. - ktian1
    1.35 + */
    1.36  static struct {
    1.37  	irqreturn_t (*handler)(int, void *, struct pt_regs *);
    1.38  	void *dev_id;
    1.39 +	char opened;	/* Whether allocated */
    1.40  } evtchns[MAX_EVTCHN];
    1.41  
    1.42 -int virq_to_evtchn[NR_VIRQS] = {-1};
    1.43 -unsigned int bind_virq_to_evtchn(int virq)
    1.44 +/*
    1.45 + * This lock protects updates to the following mapping and reference-count
    1.46 + * arrays. The lock does not need to be acquired to read the mapping tables.
    1.47 + */
    1.48 +static spinlock_t irq_mapping_update_lock;
    1.49 +
    1.50 +#define unbound_irq(e) (VALID_EVTCHN(e) && (!evtchns[(e)].opened))
    1.51 +int bind_virq_to_irqhandler(
    1.52 +	unsigned int virq,
    1.53 +	unsigned int cpu,
    1.54 +	irqreturn_t (*handler)(int, void *, struct pt_regs *),
    1.55 +	unsigned long irqflags,
    1.56 +	const char *devname,
    1.57 +	void *dev_id)
    1.58  {
    1.59      evtchn_op_t op;
    1.60 +    int evtchn;
    1.61 +
    1.62 +    spin_lock(&irq_mapping_update_lock);
    1.63  
    1.64      op.cmd = EVTCHNOP_bind_virq;
    1.65      op.u.bind_virq.virq = virq;
    1.66 -    op.u.bind_virq.vcpu = 0;
    1.67 -    if ( HYPERVISOR_event_channel_op(&op) != 0 )
    1.68 -        BUG();
    1.69 +    op.u.bind_virq.vcpu = cpu;
    1.70 +    BUG_ON(HYPERVISOR_event_channel_op(&op) != 0 );
    1.71 +    evtchn = op.u.bind_virq.port;
    1.72  
    1.73 -    virq_to_evtchn[virq] = op.u.bind_virq.port;
    1.74 -    return op.u.bind_virq.port;
    1.75 -}
    1.76 +    if (!unbound_irq(evtchn))
    1.77 +	return -EINVAL;
    1.78  
    1.79 -int bind_virq_to_irq(int virq, int cpu)
    1.80 -{
    1.81 -	printk("bind_virq_to_irq called... FIXME??\n");
    1.82 -	while(1);
    1.83 -}
    1.84 +    evtchns[evtchn].handler = handler;
    1.85 +    evtchns[evtchn].dev_id = dev_id;
    1.86 +    evtchns[evtchn].opened = 1;
    1.87 +    irq_info[evtchn] = mk_irq_info(IRQT_VIRQ, virq, evtchn);
    1.88  
    1.89 -void unbind_virq_from_evtchn(int virq)
    1.90 -{
    1.91 -    evtchn_op_t op;
    1.92 -
    1.93 -    op.cmd = EVTCHNOP_close;
    1.94 -//    op.u.close.dom = DOMID_SELF;
    1.95 -    op.u.close.port = virq_to_evtchn[virq];
    1.96 -    if ( HYPERVISOR_event_channel_op(&op) != 0 )
    1.97 -	BUG();
    1.98 -
    1.99 -    virq_to_evtchn[virq] = -1;
   1.100 +    unmask_evtchn(evtchn);
   1.101 +    spin_unlock(&irq_mapping_update_lock);
   1.102 +    return evtchn;
   1.103  }
   1.104  
   1.105  int bind_evtchn_to_irqhandler(unsigned int evtchn,
   1.106                     irqreturn_t (*handler)(int, void *, struct pt_regs *),
   1.107                     unsigned long irqflags, const char * devname, void *dev_id)
   1.108  {
   1.109 -    if (evtchn >= MAX_EVTCHN)
   1.110 -        return -EINVAL;
   1.111 +    spin_lock(&irq_mapping_update_lock);
   1.112 +
   1.113 +    if (!unbound_irq(evtchn))
   1.114 +	return -EINVAL;
   1.115  
   1.116      evtchns[evtchn].handler = handler;
   1.117      evtchns[evtchn].dev_id = dev_id;
   1.118 +    evtchns[evtchn].opened = 1;
   1.119 +    irq_info[evtchn] = mk_irq_info(IRQT_EVTCHN, 0, evtchn);
   1.120 +
   1.121      unmask_evtchn(evtchn);
   1.122 -    //return 0;
   1.123 -    /* On ia64, there's only one irq vector allocated for all event channels,
   1.124 -     * so let's just return evtchn as handle for later communication
   1.125 -     */
   1.126 +    spin_unlock(&irq_mapping_update_lock);
   1.127      return evtchn;
   1.128  }
   1.129  
   1.130 -void unbind_evtchn_from_irqhandler(unsigned int evtchn, void *dev_id)
   1.131 +int bind_ipi_to_irqhandler(
   1.132 +	unsigned int ipi,
   1.133 +	unsigned int cpu,
   1.134 +	irqreturn_t (*handler)(int, void *, struct pt_regs *),
   1.135 +	unsigned long irqflags,
   1.136 +	const char *devname,
   1.137 +	void *dev_id)
   1.138 +{
   1.139 +    printk("%s is called which has not been supported now...?\n", __FUNTION__);
   1.140 +    while(1);
   1.141 +}
   1.142 +
   1.143 +void unbind_from_irqhandler(unsigned int irq, void *dev_id)
   1.144  {
   1.145 -    if (evtchn >= MAX_EVTCHN)
   1.146 +    evtchn_op_t op;
   1.147 +    int evtchn = evtchn_from_irq(irq);
   1.148 +
   1.149 +    spin_lock(&irq_mapping_update_lock);
   1.150 +
   1.151 +    if (unbound_irq(irq))
   1.152          return;
   1.153  
   1.154 +    op.cmd = EVTCHNOP_close;
   1.155 +    op.u.close.port = evtchn;
   1.156 +    BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
   1.157 +
   1.158 +    switch (type_from_irq(irq)) {
   1.159 +	case IRQT_VIRQ:
   1.160 +	    /* Add smp stuff later... */
   1.161 +	    break;
   1.162 +	case IRQT_IPI:
   1.163 +	    /* Add smp stuff later... */
   1.164 +	    break;
   1.165 +	default:
   1.166 +	    break;
   1.167 +    }
   1.168 +
   1.169      mask_evtchn(evtchn);
   1.170      evtchns[evtchn].handler = NULL;
   1.171 -}
   1.172 +    evtchns[evtchn].opened = 0;
   1.173  
   1.174 -void unbind_evtchn_from_irq(unsigned int evtchn)
   1.175 -{
   1.176 -	printk("unbind_evtchn_from_irq called... FIXME??\n");
   1.177 -	while(1);
   1.178 +    spin_unlock(&irq_mapping_update_lock);
   1.179  }
   1.180  
   1.181  void notify_remote_via_irq(int irq)
   1.182  {
   1.183 -	/* IA64 has same irq value as event channel vector */
   1.184 -	if (VALID_EVTCHN(irq))
   1.185 -		notify_remote_via_evtchn(irq);
   1.186 +	int evtchn = evtchn_from_irq(irq);
   1.187 +
   1.188 +	if (!unbound_irq(evtchn))
   1.189 +		notify_remote_via_evtchn(evtchn);
   1.190  }
   1.191  
   1.192  irqreturn_t evtchn_interrupt(int irq, void *dev_id, struct pt_regs *regs)
   1.193 @@ -158,9 +219,7 @@ void __init evtchn_init(void)
   1.194  
   1.195      vcpu_info->arch.evtchn_vector = evtchn_irq;
   1.196      printk("xen-event-channel using irq %d\n", evtchn_irq);
   1.197 +
   1.198 +    spin_lock_init(&irq_mapping_update_lock);
   1.199 +    memset(evtchns, 0, sizeof(evtchns));
   1.200  }
   1.201 -
   1.202 -/* Following are set of interfaces unused on IA64/XEN, just keep it here */
   1.203 -
   1.204 -void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu) {}
   1.205 -int teardown_irq(unsigned int irq, struct irqaction * old) {return 0;}