ia64/xen-unstable

changeset 7128:559ad1abb3d5

Change semantics of bind_evtchn_to_xxx and
unbind_evtchn_from_xxx. The bind now returns the IRQ
number on success. The unbind takes this as a parameter
instead of the event-channel port. Also, unbind closes
down the underlying event-channel port if it is still
live.

Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Thu Sep 29 15:14:03 2005 +0100 (2005-09-29)
parents 805ee053e61f
children 8c23b56f3954
files linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c linux-2.6-xen-sparse/arch/xen/kernel/reboot.c linux-2.6-xen-sparse/drivers/xen/blkback/common.h linux-2.6-xen-sparse/drivers/xen/blkback/interface.c linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c linux-2.6-xen-sparse/drivers/xen/blkfront/block.h linux-2.6-xen-sparse/drivers/xen/blktap/common.h linux-2.6-xen-sparse/drivers/xen/blktap/interface.c linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c linux-2.6-xen-sparse/drivers/xen/netback/common.h linux-2.6-xen-sparse/drivers/xen/netback/interface.c linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c linux-2.6-xen-sparse/drivers/xen/tpmback/common.h linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.h linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.h linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c linux-2.6-xen-sparse/include/asm-xen/evtchn.h
line diff
     1.1 --- a/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c	Thu Sep 29 13:05:43 2005 +0100
     1.2 +++ b/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c	Thu Sep 29 15:14:03 2005 +0100
     1.3 @@ -320,13 +320,19 @@ int bind_evtchn_to_irq(unsigned int evtc
     1.4  }
     1.5  EXPORT_SYMBOL(bind_evtchn_to_irq);
     1.6  
     1.7 -void unbind_evtchn_from_irq(unsigned int evtchn)
     1.8 +void unbind_evtchn_from_irq(unsigned int irq)
     1.9  {
    1.10 -	int irq = evtchn_to_irq[evtchn];
    1.11 +	evtchn_op_t op;
    1.12 +	int evtchn = irq_to_evtchn[irq];
    1.13  
    1.14  	spin_lock(&irq_mapping_update_lock);
    1.15  
    1.16 -	if (--irq_bindcount[irq] == 0) {
    1.17 +	if ((--irq_bindcount[irq] == 0) && (evtchn != -1)) {
    1.18 +		op.cmd          = EVTCHNOP_close;
    1.19 +		op.u.close.dom  = DOMID_SELF;
    1.20 +		op.u.close.port = evtchn;
    1.21 +		BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
    1.22 +
    1.23  		evtchn_to_irq[evtchn] = -1;
    1.24  		irq_to_evtchn[irq]    = -1;
    1.25  	}
    1.26 @@ -348,17 +354,16 @@ int bind_evtchn_to_irqhandler(
    1.27  	irq = bind_evtchn_to_irq(evtchn);
    1.28  	retval = request_irq(irq, handler, irqflags, devname, dev_id);
    1.29  	if (retval != 0)
    1.30 -		unbind_evtchn_from_irq(evtchn);
    1.31 +		unbind_evtchn_from_irq(irq);
    1.32  
    1.33 -	return retval;
    1.34 +	return irq;
    1.35  }
    1.36  EXPORT_SYMBOL(bind_evtchn_to_irqhandler);
    1.37  
    1.38 -void unbind_evtchn_from_irqhandler(unsigned int evtchn, void *dev_id)
    1.39 +void unbind_evtchn_from_irqhandler(unsigned int irq, void *dev_id)
    1.40  {
    1.41 -	unsigned int irq = evtchn_to_irq[evtchn];
    1.42  	free_irq(irq, dev_id);
    1.43 -	unbind_evtchn_from_irq(evtchn);
    1.44 +	unbind_evtchn_from_irq(irq);
    1.45  }
    1.46  EXPORT_SYMBOL(unbind_evtchn_from_irqhandler);
    1.47  
    1.48 @@ -425,9 +430,8 @@ static unsigned int startup_dynirq(unsig
    1.49  {
    1.50  	int evtchn = irq_to_evtchn[irq];
    1.51  
    1.52 -	if (!VALID_EVTCHN(evtchn))
    1.53 -		return 0;
    1.54 -	unmask_evtchn(evtchn);
    1.55 +	if (VALID_EVTCHN(evtchn))
    1.56 +		unmask_evtchn(evtchn);
    1.57  	return 0;
    1.58  }
    1.59  
    1.60 @@ -435,38 +439,41 @@ static void shutdown_dynirq(unsigned int
    1.61  {
    1.62  	int evtchn = irq_to_evtchn[irq];
    1.63  
    1.64 -	if (!VALID_EVTCHN(evtchn))
    1.65 -		return;
    1.66 -	mask_evtchn(evtchn);
    1.67 +	if (VALID_EVTCHN(evtchn))
    1.68 +		mask_evtchn(evtchn);
    1.69  }
    1.70  
    1.71  static void enable_dynirq(unsigned int irq)
    1.72  {
    1.73  	int evtchn = irq_to_evtchn[irq];
    1.74  
    1.75 -	unmask_evtchn(evtchn);
    1.76 +	if (VALID_EVTCHN(evtchn))
    1.77 +		unmask_evtchn(evtchn);
    1.78  }
    1.79  
    1.80  static void disable_dynirq(unsigned int irq)
    1.81  {
    1.82  	int evtchn = irq_to_evtchn[irq];
    1.83  
    1.84 -	mask_evtchn(evtchn);
    1.85 +	if (VALID_EVTCHN(evtchn))
    1.86 +		mask_evtchn(evtchn);
    1.87  }
    1.88  
    1.89  static void ack_dynirq(unsigned int irq)
    1.90  {
    1.91  	int evtchn = irq_to_evtchn[irq];
    1.92  
    1.93 -	mask_evtchn(evtchn);
    1.94 -	clear_evtchn(evtchn);
    1.95 +	if (VALID_EVTCHN(evtchn)) {
    1.96 +		mask_evtchn(evtchn);
    1.97 +		clear_evtchn(evtchn);
    1.98 +	}
    1.99  }
   1.100  
   1.101  static void end_dynirq(unsigned int irq)
   1.102  {
   1.103  	int evtchn = irq_to_evtchn[irq];
   1.104  
   1.105 -	if (!(irq_desc[irq].status & IRQ_DISABLED))
   1.106 +	if (VALID_EVTCHN(evtchn) && !(irq_desc[irq].status & IRQ_DISABLED))
   1.107  		unmask_evtchn(evtchn);
   1.108  }
   1.109  
   1.110 @@ -559,35 +566,36 @@ static void shutdown_pirq(unsigned int i
   1.111  static void enable_pirq(unsigned int irq)
   1.112  {
   1.113  	int evtchn = irq_to_evtchn[irq];
   1.114 -	if (!VALID_EVTCHN(evtchn))
   1.115 -		return;
   1.116 -	unmask_evtchn(evtchn);
   1.117 -	pirq_unmask_notify(irq_to_pirq(irq));
   1.118 +
   1.119 +	if (VALID_EVTCHN(evtchn)) {
   1.120 +		unmask_evtchn(evtchn);
   1.121 +		pirq_unmask_notify(irq_to_pirq(irq));
   1.122 +	}
   1.123  }
   1.124  
   1.125  static void disable_pirq(unsigned int irq)
   1.126  {
   1.127  	int evtchn = irq_to_evtchn[irq];
   1.128 -	if (!VALID_EVTCHN(evtchn))
   1.129 -		return;
   1.130 -	mask_evtchn(evtchn);
   1.131 +
   1.132 +	if (VALID_EVTCHN(evtchn))
   1.133 +		mask_evtchn(evtchn);
   1.134  }
   1.135  
   1.136  static void ack_pirq(unsigned int irq)
   1.137  {
   1.138  	int evtchn = irq_to_evtchn[irq];
   1.139 -	if (!VALID_EVTCHN(evtchn))
   1.140 -		return;
   1.141 -	mask_evtchn(evtchn);
   1.142 -	clear_evtchn(evtchn);
   1.143 +
   1.144 +	if (VALID_EVTCHN(evtchn)) {
   1.145 +		mask_evtchn(evtchn);
   1.146 +		clear_evtchn(evtchn);
   1.147 +	}
   1.148  }
   1.149  
   1.150  static void end_pirq(unsigned int irq)
   1.151  {
   1.152  	int evtchn = irq_to_evtchn[irq];
   1.153 -	if (!VALID_EVTCHN(evtchn))
   1.154 -		return;
   1.155 -	if (!(irq_desc[irq].status & IRQ_DISABLED)) {
   1.156 +
   1.157 +	if (VALID_EVTCHN(evtchn) && !(irq_desc[irq].status & IRQ_DISABLED)) {
   1.158  		unmask_evtchn(evtchn);
   1.159  		pirq_unmask_notify(irq_to_pirq(irq));
   1.160  	}
   1.161 @@ -637,6 +645,10 @@ void irq_resume(void)
   1.162  			BUG_ON(per_cpu(ipi_to_evtchn, cpu)[ipi] != -1);
   1.163  	}
   1.164  
   1.165 +	/* No IRQ -> event-channel mappings. */
   1.166 +	for (irq = 0; irq < NR_IRQS; irq++)
   1.167 +		irq_to_evtchn[irq] = -1;
   1.168 +
   1.169  	/* Primary CPU: rebind VIRQs automatically. */
   1.170  	for (virq = 0; virq < NR_VIRQS; virq++) {
   1.171  		if ((irq = per_cpu(virq_to_irq, 0)[virq]) == -1)
   1.172 @@ -676,6 +688,13 @@ void irq_resume(void)
   1.173  		/* Ready for use. */
   1.174  		unmask_evtchn(evtchn);
   1.175  	}
   1.176 +
   1.177 +	/* Remove defunct event-channel -> IRQ mappings. */
   1.178 +	for (evtchn = 0; evtchn < NR_EVENT_CHANNELS; evtchn++) {
   1.179 +		if ((evtchn_to_irq[evtchn] != -1) &&
   1.180 +		    (irq_to_evtchn[evtchn_to_irq[evtchn]] == -1))
   1.181 +			evtchn_to_irq[evtchn] = -1;
   1.182 +	}
   1.183  }
   1.184  
   1.185  void __init init_IRQ(void)
   1.186 @@ -689,11 +708,10 @@ void __init init_IRQ(void)
   1.187  
   1.188  	init_evtchn_cpu_bindings();
   1.189  
   1.190 +	/* No VIRQ or IPI bindings. */
   1.191  	for (cpu = 0; cpu < NR_CPUS; cpu++) {
   1.192 -		/* No VIRQ -> IRQ mappings. */
   1.193  		for (i = 0; i < NR_VIRQS; i++)
   1.194  			per_cpu(virq_to_irq, cpu)[i] = -1;
   1.195 -		/* No VIRQ -> IRQ mappings. */
   1.196  		for (i = 0; i < NR_IPIS; i++)
   1.197  			per_cpu(ipi_to_evtchn, cpu)[i] = -1;
   1.198  	}
     2.1 --- a/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c	Thu Sep 29 13:05:43 2005 +0100
     2.2 +++ b/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c	Thu Sep 29 15:14:03 2005 +0100
     2.3 @@ -65,12 +65,6 @@ static int __do_suspend(void *ignore)
     2.4  {
     2.5  	int i, j, k, fpp;
     2.6  
     2.7 -#ifdef CONFIG_XEN_USB_FRONTEND
     2.8 -	extern void usbif_resume();
     2.9 -#else
    2.10 -#define usbif_resume() do{}while(0)
    2.11 -#endif
    2.12 -
    2.13  	extern int gnttab_suspend(void);
    2.14  	extern int gnttab_resume(void);
    2.15  
    2.16 @@ -87,7 +81,6 @@ static int __do_suspend(void *ignore)
    2.17  	int restore_vcpu_context(int vcpu, vcpu_guest_context_t *ctxt);
    2.18  #endif
    2.19  
    2.20 -	extern void xencons_suspend(void);
    2.21  	extern void xencons_resume(void);
    2.22  
    2.23  	int err = 0;
    2.24 @@ -147,17 +140,15 @@ static int __do_suspend(void *ignore)
    2.25  	}
    2.26  #endif
    2.27  
    2.28 +	xenbus_suspend();
    2.29 +
    2.30 +	gnttab_suspend();
    2.31 +
    2.32  #ifdef __i386__
    2.33  	mm_pin_all();
    2.34  	kmem_cache_shrink(pgd_cache);
    2.35  #endif
    2.36  
    2.37 -	xenbus_suspend();
    2.38 -
    2.39 -	xencons_suspend();
    2.40 -
    2.41 -	gnttab_suspend();
    2.42 -
    2.43  	HYPERVISOR_shared_info = (shared_info_t *)empty_zero_page;
    2.44  	clear_fixmap(FIX_SHARED_INFO);
    2.45  
    2.46 @@ -202,8 +193,6 @@ static int __do_suspend(void *ignore)
    2.47  
    2.48  	time_resume();
    2.49  
    2.50 -	usbif_resume();
    2.51 -
    2.52  #ifdef CONFIG_SMP
    2.53  	for_each_cpu_mask(i, prev_present_cpus)
    2.54  		restore_vcpu_context(i, &suspended_cpu_records[i]);
     3.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/common.h	Thu Sep 29 13:05:43 2005 +0100
     3.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/common.h	Thu Sep 29 15:14:03 2005 +0100
     3.3 @@ -44,7 +44,7 @@ typedef struct blkif_st {
     3.4  	unsigned int      handle;
     3.5  	/* Physical parameters of the comms window. */
     3.6  	unsigned int      evtchn;
     3.7 -	unsigned int      remote_evtchn;
     3.8 +	unsigned int      irq;
     3.9  	/* Comms information. */
    3.10  	blkif_back_ring_t blk_ring;
    3.11  	struct vm_struct *blk_ring_area;
     4.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c	Thu Sep 29 13:05:43 2005 +0100
     4.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c	Thu Sep 29 15:14:03 2005 +0100
     4.3 @@ -71,8 +71,6 @@ int blkif_map(blkif_t *blkif, unsigned l
     4.4  	evtchn_op_t op = { .cmd = EVTCHNOP_bind_interdomain };
     4.5  	int err;
     4.6  
     4.7 -	BUG_ON(blkif->remote_evtchn);
     4.8 -
     4.9  	if ( (blkif->blk_ring_area = alloc_vm_area(PAGE_SIZE)) == NULL )
    4.10  		return -ENOMEM;
    4.11  
    4.12 @@ -94,13 +92,12 @@ int blkif_map(blkif_t *blkif, unsigned l
    4.13  	}
    4.14  
    4.15  	blkif->evtchn = op.u.bind_interdomain.port1;
    4.16 -	blkif->remote_evtchn = evtchn;
    4.17  
    4.18  	sring = (blkif_sring_t *)blkif->blk_ring_area->addr;
    4.19  	SHARED_RING_INIT(sring);
    4.20  	BACK_RING_INIT(&blkif->blk_ring, sring, PAGE_SIZE);
    4.21  
    4.22 -	bind_evtchn_to_irqhandler(
    4.23 +	blkif->irq = bind_evtchn_to_irqhandler(
    4.24  		blkif->evtchn, blkif_be_int, 0, "blkif-backend", blkif);
    4.25  	blkif->status = CONNECTED;
    4.26  
    4.27 @@ -109,21 +106,13 @@ int blkif_map(blkif_t *blkif, unsigned l
    4.28  
    4.29  static void free_blkif(void *arg)
    4.30  {
    4.31 -	evtchn_op_t op = { .cmd = EVTCHNOP_close };
    4.32  	blkif_t *blkif = (blkif_t *)arg;
    4.33  
    4.34 -	op.u.close.port = blkif->evtchn;
    4.35 -	op.u.close.dom = DOMID_SELF;
    4.36 -	HYPERVISOR_event_channel_op(&op);
    4.37 -	op.u.close.port = blkif->remote_evtchn;
    4.38 -	op.u.close.dom = blkif->domid;
    4.39 -	HYPERVISOR_event_channel_op(&op);
    4.40 +	if (blkif->irq)
    4.41 +		unbind_evtchn_from_irqhandler(blkif->irq, blkif);
    4.42  
    4.43  	vbd_free(&blkif->vbd);
    4.44  
    4.45 -	if (blkif->evtchn)
    4.46 -		unbind_evtchn_from_irqhandler(blkif->evtchn, blkif);
    4.47 -
    4.48  	if (blkif->blk_ring.sring) {
    4.49  		unmap_frontend_page(blkif);
    4.50  		free_vm_area(blkif->blk_ring_area);
     5.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c	Thu Sep 29 13:05:43 2005 +0100
     5.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c	Thu Sep 29 15:14:03 2005 +0100
     5.3 @@ -357,8 +357,9 @@ static void blkif_free(struct blkfront_i
     5.4  	if (info->ring_ref != GRANT_INVALID_REF)
     5.5  		gnttab_end_foreign_access(info->ring_ref, 0);
     5.6  	info->ring_ref = GRANT_INVALID_REF;
     5.7 -	unbind_evtchn_from_irqhandler(info->evtchn, info); 
     5.8 -	info->evtchn = 0;
     5.9 +	if (info->irq)
    5.10 +		unbind_evtchn_from_irqhandler(info->irq, info); 
    5.11 +	info->evtchn = info->irq = 0;
    5.12  }
    5.13  
    5.14  static void blkif_recover(struct blkfront_info *info)
    5.15 @@ -429,10 +430,12 @@ static void blkif_connect(struct blkfron
    5.16  
    5.17  	err = bind_evtchn_to_irqhandler(
    5.18  		info->evtchn, blkif_int, SA_SAMPLE_RANDOM, "blkif", info);
    5.19 -	if (err != 0) {
    5.20 +	if (err <= 0) {
    5.21  		WPRINTK("bind_evtchn_to_irqhandler failed (err=%d)\n", err);
    5.22  		return;
    5.23  	}
    5.24 +
    5.25 +	info->irq = err;
    5.26  }
    5.27  
    5.28  
     6.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkfront/block.h	Thu Sep 29 13:05:43 2005 +0100
     6.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/block.h	Thu Sep 29 15:14:03 2005 +0100
     6.3 @@ -123,7 +123,7 @@ struct blkfront_info
     6.4  	int backend_id;
     6.5  	int ring_ref;
     6.6  	blkif_front_ring_t ring;
     6.7 -	unsigned int evtchn;
     6.8 +	unsigned int evtchn, irq;
     6.9  	struct xlbd_major_info *mi;
    6.10  	request_queue_t *rq;
    6.11  	struct work_struct work;
     7.1 --- a/linux-2.6-xen-sparse/drivers/xen/blktap/common.h	Thu Sep 29 13:05:43 2005 +0100
     7.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blktap/common.h	Thu Sep 29 15:14:03 2005 +0100
     7.3 @@ -46,7 +46,7 @@ typedef struct blkif_st {
     7.4  	unsigned int      handle;
     7.5  	/* Physical parameters of the comms window. */
     7.6  	unsigned int      evtchn;
     7.7 -	unsigned int      remote_evtchn;
     7.8 +	unsigned int      irq;
     7.9  	/* Comms information. */
    7.10  	blkif_back_ring_t blk_ring;
    7.11  	struct vm_struct *blk_ring_area;
     8.1 --- a/linux-2.6-xen-sparse/drivers/xen/blktap/interface.c	Thu Sep 29 13:05:43 2005 +0100
     8.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blktap/interface.c	Thu Sep 29 15:14:03 2005 +0100
     8.3 @@ -71,8 +71,6 @@ int blkif_map(blkif_t *blkif, unsigned l
     8.4  	evtchn_op_t op = { .cmd = EVTCHNOP_bind_interdomain };
     8.5  	int err;
     8.6  
     8.7 -	BUG_ON(blkif->remote_evtchn);
     8.8 -
     8.9  	if ((blkif->blk_ring_area = alloc_vm_area(PAGE_SIZE)) == NULL)
    8.10  		return -ENOMEM;
    8.11  
    8.12 @@ -93,35 +91,26 @@ int blkif_map(blkif_t *blkif, unsigned l
    8.13  		return err;
    8.14  	}
    8.15  
    8.16 -
    8.17  	blkif->evtchn = op.u.bind_interdomain.port1;
    8.18 -	blkif->remote_evtchn = evtchn;
    8.19  
    8.20  	sring = (blkif_sring_t *)blkif->blk_ring_area->addr;
    8.21  	SHARED_RING_INIT(sring);
    8.22  	BACK_RING_INIT(&blkif->blk_ring, sring, PAGE_SIZE);
    8.23  
    8.24 -	bind_evtchn_to_irqhandler(
    8.25 +	blkif->irq = bind_evtchn_to_irqhandler(
    8.26  		blkif->evtchn, blkif_be_int, 0, "blkif-backend", blkif);
    8.27 -	blkif->status        = CONNECTED;
    8.28 +
    8.29 +	blkif->status = CONNECTED;
    8.30  
    8.31  	return 0;
    8.32  }
    8.33  
    8.34  static void free_blkif(void *arg)
    8.35  {
    8.36 -	evtchn_op_t op = { .cmd = EVTCHNOP_close };
    8.37  	blkif_t *blkif = (blkif_t *)arg;
    8.38  
    8.39 -	op.u.close.port = blkif->evtchn;
    8.40 -	op.u.close.dom = DOMID_SELF;
    8.41 -	HYPERVISOR_event_channel_op(&op);
    8.42 -	op.u.close.port = blkif->remote_evtchn;
    8.43 -	op.u.close.dom = blkif->domid;
    8.44 -	HYPERVISOR_event_channel_op(&op);
    8.45 -
    8.46 -	if (blkif->evtchn)
    8.47 -		unbind_evtchn_from_irqhandler(blkif->evtchn, blkif);
    8.48 +	if (blkif->irq)
    8.49 +		unbind_evtchn_from_irqhandler(blkif->irq, blkif);
    8.50  
    8.51  	if (blkif->blk_ring.sring) {
    8.52  		unmap_frontend_page(blkif);
     9.1 --- a/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c	Thu Sep 29 13:05:43 2005 +0100
     9.2 +++ b/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c	Thu Sep 29 15:14:03 2005 +0100
     9.3 @@ -21,7 +21,6 @@
     9.4  #include <linux/err.h>
     9.5  #include "xencons_ring.h"
     9.6  
     9.7 -
     9.8  struct ring_head
     9.9  {
    9.10  	u32 cons;
    9.11 @@ -29,6 +28,7 @@ struct ring_head
    9.12  	char buf[0];
    9.13  } __attribute__((packed));
    9.14  
    9.15 +static int xencons_irq;
    9.16  
    9.17  #define XENCONS_RING_SIZE (PAGE_SIZE/2 - sizeof (struct ring_head))
    9.18  #define XENCONS_IDX(cnt) ((cnt) % XENCONS_RING_SIZE)
    9.19 @@ -97,32 +97,28 @@ int xencons_ring_init(void)
    9.20  {
    9.21  	int err;
    9.22  
    9.23 +	if (xencons_irq)
    9.24 +		unbind_evtchn_from_irqhandler(xencons_irq, inring());
    9.25 +	xencons_irq = 0;
    9.26 +
    9.27  	if (!xen_start_info->console_evtchn)
    9.28  		return 0;
    9.29  
    9.30 -	err = bind_evtchn_to_irqhandler(xen_start_info->console_evtchn,
    9.31 -					handle_input, 0, "xencons", inring());
    9.32 -	if (err) {
    9.33 +	err = bind_evtchn_to_irqhandler(
    9.34 +		xen_start_info->console_evtchn,
    9.35 +		handle_input, 0, "xencons", inring());
    9.36 +	if (err <= 0) {
    9.37  		xprintk("XEN console request irq failed %i\n", err);
    9.38  		return err;
    9.39  	}
    9.40  
    9.41 +	xencons_irq = err;
    9.42 +
    9.43  	return 0;
    9.44  }
    9.45  
    9.46 -void xencons_suspend(void)
    9.47 -{
    9.48 -
    9.49 -	if (!xen_start_info->console_evtchn)
    9.50 -		return;
    9.51 -
    9.52 -	unbind_evtchn_from_irqhandler(xen_start_info->console_evtchn,
    9.53 -				      inring());
    9.54 -}
    9.55 -
    9.56  void xencons_resume(void)
    9.57  {
    9.58 -
    9.59  	(void)xencons_ring_init();
    9.60  }
    9.61  
    10.1 --- a/linux-2.6-xen-sparse/drivers/xen/netback/common.h	Thu Sep 29 13:05:43 2005 +0100
    10.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/common.h	Thu Sep 29 15:14:03 2005 +0100
    10.3 @@ -50,7 +50,7 @@ typedef struct netif_st {
    10.4  	u16              rx_shmem_handle;
    10.5  	grant_ref_t      rx_shmem_ref; 
    10.6  	unsigned int     evtchn;
    10.7 -	unsigned int     remote_evtchn;
    10.8 +	unsigned int     irq;
    10.9  
   10.10  	/* The shared rings and indexes. */
   10.11  	netif_tx_interface_t *tx;
    11.1 --- a/linux-2.6-xen-sparse/drivers/xen/netback/interface.c	Thu Sep 29 13:05:43 2005 +0100
    11.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/interface.c	Thu Sep 29 15:14:03 2005 +0100
    11.3 @@ -15,18 +15,17 @@ static void __netif_up(netif_t *netif)
    11.4  	spin_lock_bh(&dev->xmit_lock);
    11.5  	netif->active = 1;
    11.6  	spin_unlock_bh(&dev->xmit_lock);
    11.7 -	(void)bind_evtchn_to_irqhandler(
    11.8 -		netif->evtchn, netif_be_int, 0, dev->name, netif);
    11.9 +	enable_irq(netif->irq);
   11.10  	netif_schedule_work(netif);
   11.11  }
   11.12  
   11.13  static void __netif_down(netif_t *netif)
   11.14  {
   11.15  	struct net_device *dev = netif->dev;
   11.16 +	disable_irq(netif->irq);
   11.17  	spin_lock_bh(&dev->xmit_lock);
   11.18  	netif->active = 0;
   11.19  	spin_unlock_bh(&dev->xmit_lock);
   11.20 -	unbind_evtchn_from_irqhandler(netif->evtchn, netif);
   11.21  	netif_deschedule_work(netif);
   11.22  }
   11.23  
   11.24 @@ -203,7 +202,10 @@ int netif_map(netif_t *netif, unsigned l
   11.25  	}
   11.26  
   11.27  	netif->evtchn = op.u.bind_interdomain.port1;
   11.28 -	netif->remote_evtchn = evtchn;
   11.29 +
   11.30 +	netif->irq = bind_evtchn_to_irqhandler(
   11.31 +		netif->evtchn, netif_be_int, 0, netif->dev->name, netif);
   11.32 +	disable_irq(netif->irq);
   11.33  
   11.34  	netif->tx = (netif_tx_interface_t *)netif->comms_area->addr;
   11.35  	netif->rx = (netif_rx_interface_t *)
   11.36 @@ -224,21 +226,15 @@ int netif_map(netif_t *netif, unsigned l
   11.37  
   11.38  static void free_netif_callback(void *arg)
   11.39  {
   11.40 -	evtchn_op_t op = { .cmd = EVTCHNOP_close };
   11.41  	netif_t *netif = (netif_t *)arg;
   11.42  
   11.43  	/*
   11.44 -	 * These can't be done in netif_disconnect() because at that point
   11.45 +	 * This can't be done in netif_disconnect() because at that point
   11.46  	 * there may be outstanding requests in the network stack whose
   11.47  	 * asynchronous responses must still be notified to the remote driver.
   11.48  	 */
   11.49 -
   11.50 -	op.u.close.port = netif->evtchn;
   11.51 -	op.u.close.dom = DOMID_SELF;
   11.52 -	HYPERVISOR_event_channel_op(&op);
   11.53 -	op.u.close.port = netif->remote_evtchn;
   11.54 -	op.u.close.dom = netif->domid;
   11.55 -	HYPERVISOR_event_channel_op(&op);
   11.56 +	if (netif->irq)
   11.57 +		unbind_evtchn_from_irqhandler(netif->irq, netif);
   11.58  
   11.59  	unregister_netdev(netif->dev);
   11.60  
    12.1 --- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c	Thu Sep 29 13:05:43 2005 +0100
    12.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c	Thu Sep 29 15:14:03 2005 +0100
    12.3 @@ -127,7 +127,7 @@ struct net_private
    12.4  	spinlock_t   rx_lock;
    12.5  
    12.6  	unsigned int handle;
    12.7 -	unsigned int evtchn;
    12.8 +	unsigned int evtchn, irq;
    12.9  
   12.10  	/* What is the status of our connection to the remote backend? */
   12.11  #define BEST_CLOSED       0
   12.12 @@ -815,7 +815,7 @@ connect_device(struct net_private *np, u
   12.13  	memcpy(dev->dev_addr, np->mac, ETH_ALEN);
   12.14  	np->evtchn = evtchn;
   12.15  	network_connect(dev);
   12.16 -	(void)bind_evtchn_to_irqhandler(
   12.17 +	np->irq = bind_evtchn_to_irqhandler(
   12.18  		np->evtchn, netif_int, SA_SAMPLE_RANDOM, dev->name, dev);
   12.19  	(void)send_fake_arp(dev);
   12.20  	show_device(np);
   12.21 @@ -1055,8 +1055,9 @@ static void netif_free(struct netfront_i
   12.22  		gnttab_end_foreign_access(info->rx_ring_ref, 0);
   12.23  	info->rx_ring_ref = GRANT_INVALID_REF;
   12.24  
   12.25 -	unbind_evtchn_from_irqhandler(info->evtchn, info->netdev);
   12.26 -	info->evtchn = 0;
   12.27 +	if (info->irq)
   12.28 +		unbind_evtchn_from_irqhandler(info->irq, info->netdev);
   12.29 +	info->evtchn = info->irq = 0;
   12.30  }
   12.31  
   12.32  /* Stop network device and free tx/rx queues and irq. */
    13.1 --- a/linux-2.6-xen-sparse/drivers/xen/tpmback/common.h	Thu Sep 29 13:05:43 2005 +0100
    13.2 +++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/common.h	Thu Sep 29 15:14:03 2005 +0100
    13.3 @@ -35,7 +35,7 @@ typedef struct tpmif_st {
    13.4  
    13.5  	/* Physical parameters of the comms window. */
    13.6  	unsigned int evtchn;
    13.7 -	unsigned int remote_evtchn;
    13.8 +	unsigned int irq;
    13.9  
   13.10  	/* The shared rings and indexes. */
   13.11  	tpmif_tx_interface_t *tx;
    14.1 --- a/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c	Thu Sep 29 13:05:43 2005 +0100
    14.2 +++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c	Thu Sep 29 15:14:03 2005 +0100
    14.3 @@ -120,8 +120,6 @@ tpmif_map(tpmif_t *tpmif, unsigned long 
    14.4  	evtchn_op_t op = {.cmd = EVTCHNOP_bind_interdomain };
    14.5  	int err;
    14.6  
    14.7 -	BUG_ON(tpmif->remote_evtchn);
    14.8 -
    14.9  	if ((tpmif->tx_area = alloc_vm_area(PAGE_SIZE)) == NULL)
   14.10  		return -ENOMEM;
   14.11  
   14.12 @@ -143,12 +141,11 @@ tpmif_map(tpmif_t *tpmif, unsigned long 
   14.13  	}
   14.14  
   14.15  	tpmif->evtchn = op.u.bind_interdomain.port1;
   14.16 -	tpmif->remote_evtchn = evtchn;
   14.17  
   14.18  	tpmif->tx = (tpmif_tx_interface_t *)tpmif->tx_area->addr;
   14.19  
   14.20 -	bind_evtchn_to_irqhandler(tpmif->evtchn,
   14.21 -				  tpmif_be_int, 0, "tpmif-backend", tpmif);
   14.22 +	tpmif->irq = bind_evtchn_to_irqhandler(
   14.23 +		tpmif->evtchn, tpmif_be_int, 0, "tpmif-backend", tpmif);
   14.24  	tpmif->status = CONNECTED;
   14.25  	tpmif->shmem_ref = shared_page;
   14.26  	tpmif->active = 1;
   14.27 @@ -159,18 +156,10 @@ tpmif_map(tpmif_t *tpmif, unsigned long 
   14.28  static void
   14.29  __tpmif_disconnect_complete(void *arg)
   14.30  {
   14.31 -	evtchn_op_t op = {.cmd = EVTCHNOP_close };
   14.32  	tpmif_t *tpmif = (tpmif_t *) arg;
   14.33  
   14.34 -	op.u.close.port = tpmif->evtchn;
   14.35 -	op.u.close.dom = DOMID_SELF;
   14.36 -	HYPERVISOR_event_channel_op(&op);
   14.37 -	op.u.close.port = tpmif->remote_evtchn;
   14.38 -	op.u.close.dom = tpmif->domid;
   14.39 -	HYPERVISOR_event_channel_op(&op);
   14.40 -
   14.41 -	if (tpmif->evtchn)
   14.42 -		unbind_evtchn_from_irqhandler(tpmif->evtchn, tpmif);
   14.43 +	if (tpmif->irq)
   14.44 +		unbind_evtchn_from_irqhandler(tpmif->irq, tpmif);
   14.45  
   14.46  	if (tpmif->tx) {
   14.47  		unmap_frontend_page(tpmif);
    15.1 --- a/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c	Thu Sep 29 13:05:43 2005 +0100
    15.2 +++ b/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c	Thu Sep 29 15:14:03 2005 +0100
    15.3 @@ -292,8 +292,10 @@ static void destroy_tpmring(struct tpmfr
    15.4  		free_page((unsigned long)tp->tx);
    15.5  		tp->tx = NULL;
    15.6  	}
    15.7 -	unbind_evtchn_from_irqhandler(tp->evtchn, NULL);
    15.8 -	tp->evtchn = 0;
    15.9 +
   15.10 +	if (tpm->irq)
   15.11 +		unbind_evtchn_from_irqhandler(tp->irq, NULL);
   15.12 +	tp->evtchn = tpm->irq = 0;
   15.13  }
   15.14  
   15.15  
   15.16 @@ -501,10 +503,12 @@ static void tpmif_connect(u16 evtchn, do
   15.17  	err = bind_evtchn_to_irqhandler(
   15.18  		tp->evtchn,
   15.19  		tpmif_int, SA_SAMPLE_RANDOM, "tpmif", tp);
   15.20 -	if ( err != 0 ) {
   15.21 +	if ( err <= 0 ) {
   15.22  		WPRINTK("bind_evtchn_to_irqhandler failed (err=%d)\n", err);
   15.23  		return;
   15.24  	}
   15.25 +
   15.26 +	tp->irq = err;
   15.27  }
   15.28  
   15.29  static struct xenbus_device_id tpmfront_ids[] = {
    16.1 --- a/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.h	Thu Sep 29 13:05:43 2005 +0100
    16.2 +++ b/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.h	Thu Sep 29 15:14:03 2005 +0100
    16.3 @@ -5,7 +5,7 @@
    16.4  struct tpm_private
    16.5  {
    16.6  	tpmif_tx_interface_t *tx;
    16.7 -	unsigned int evtchn;
    16.8 +	unsigned int evtchn, irq;
    16.9  	int connected;
   16.10  
   16.11  	spinlock_t tx_lock;
    17.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c	Thu Sep 29 13:05:43 2005 +0100
    17.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c	Thu Sep 29 15:14:03 2005 +0100
    17.3 @@ -44,6 +44,8 @@ struct ringbuf_head
    17.4  	char buf[0];
    17.5  } __attribute__((packed));
    17.6  
    17.7 +static int xenbus_irq;
    17.8 +
    17.9  DECLARE_WAIT_QUEUE_HEAD(xb_waitq);
   17.10  
   17.11  static inline struct ringbuf_head *outbuf(void)
   17.12 @@ -205,33 +207,29 @@ int xb_init_comms(void)
   17.13  {
   17.14  	int err;
   17.15  
   17.16 +	if (xenbus_irq)
   17.17 +		unbind_evtchn_from_irqhandler(xenbus_irq, &xb_waitq);
   17.18 +	xenbus_irq = 0;
   17.19 +
   17.20  	if (!xen_start_info->store_evtchn)
   17.21  		return 0;
   17.22  
   17.23  	err = bind_evtchn_to_irqhandler(
   17.24  		xen_start_info->store_evtchn, wake_waiting,
   17.25  		0, "xenbus", &xb_waitq);
   17.26 -	if (err) {
   17.27 +	if (err <= 0) {
   17.28  		printk(KERN_ERR "XENBUS request irq failed %i\n", err);
   17.29 -		unbind_evtchn_from_irq(xen_start_info->store_evtchn);
   17.30  		return err;
   17.31  	}
   17.32  
   17.33 +	xenbus_irq = err;
   17.34 +
   17.35  	/* FIXME zero out page -- domain builder should probably do this*/
   17.36  	memset(mfn_to_virt(xen_start_info->store_mfn), 0, PAGE_SIZE);
   17.37  
   17.38  	return 0;
   17.39  }
   17.40  
   17.41 -void xb_suspend_comms(void)
   17.42 -{
   17.43 -
   17.44 -	if (!xen_start_info->store_evtchn)
   17.45 -		return;
   17.46 -
   17.47 -	unbind_evtchn_from_irqhandler(xen_start_info->store_evtchn, &xb_waitq);
   17.48 -}
   17.49 -
   17.50  /*
   17.51   * Local variables:
   17.52   *  c-file-style: "linux"
    18.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.h	Thu Sep 29 13:05:43 2005 +0100
    18.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.h	Thu Sep 29 15:14:03 2005 +0100
    18.3 @@ -30,7 +30,6 @@
    18.4  
    18.5  int xs_init(void);
    18.6  int xb_init_comms(void);
    18.7 -void xb_suspend_comms(void);
    18.8  
    18.9  /* Low level routines. */
   18.10  int xb_write(const void *data, unsigned len);
    19.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c	Thu Sep 29 13:05:43 2005 +0100
    19.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c	Thu Sep 29 15:14:03 2005 +0100
    19.3 @@ -607,7 +607,6 @@ void xenbus_suspend(void)
    19.4  	down(&xenbus_lock);
    19.5  	bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, suspend_dev);
    19.6  	bus_for_each_dev(&xenbus_backend.bus, NULL, NULL, suspend_dev);
    19.7 -	xb_suspend_comms();
    19.8  }
    19.9  
   19.10  void xenbus_resume(void)
    20.1 --- a/linux-2.6-xen-sparse/include/asm-xen/evtchn.h	Thu Sep 29 13:05:43 2005 +0100
    20.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/evtchn.h	Thu Sep 29 15:14:03 2005 +0100
    20.3 @@ -51,14 +51,21 @@ extern void unbind_virq_from_irq(int vir
    20.4  extern int  bind_ipi_to_irq(int ipi);
    20.5  extern void unbind_ipi_from_irq(int ipi);
    20.6  
    20.7 -/* Dynamically bind an event-channel port to Linux IRQ space. */
    20.8 +/*
    20.9 + * Dynamically bind an event-channel port to Linux IRQ space.
   20.10 + * BIND:   Returns IRQ or error.
   20.11 + * UNBIND: Takes IRQ to unbind from; automatically closes the event channel.
   20.12 + */
   20.13  extern int  bind_evtchn_to_irq(unsigned int evtchn);
   20.14 -extern void unbind_evtchn_from_irq(unsigned int evtchn);
   20.15 +extern void unbind_evtchn_from_irq(unsigned int irq);
   20.16  
   20.17  /*
   20.18   * Dynamically bind an event-channel port to an IRQ-like callback handler.
   20.19   * On some platforms this may not be implemented via the Linux IRQ subsystem.
   20.20 - * You *cannot* trust the irq argument passed to the callback handler.
   20.21 + * The IRQ argument passed to the callback handler is the same as returned
   20.22 + * from the bind call. It may not correspond to a Linux IRQ number.
   20.23 + * BIND:   Returns IRQ or error.
   20.24 + * UNBIND: Takes IRQ to unbind from; automatically closes the event channel.
   20.25   */
   20.26  extern int  bind_evtchn_to_irqhandler(
   20.27  	unsigned int evtchn,
   20.28 @@ -66,7 +73,7 @@ extern int  bind_evtchn_to_irqhandler(
   20.29  	unsigned long irqflags,
   20.30  	const char *devname,
   20.31  	void *dev_id);
   20.32 -extern void unbind_evtchn_from_irqhandler(unsigned int evtchn, void *dev_id);
   20.33 +extern void unbind_evtchn_from_irqhandler(unsigned int irq, void *dev_id);
   20.34  
   20.35  extern void irq_resume(void);
   20.36