ia64/xen-unstable

changeset 13233:d275951acf10

[LINUX] Extend the event-channel interfaces to provide helper methods
for creating interdomain event channels bound to IRQ handlers.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@localhost.localdomain
date Sat Dec 30 18:23:27 2006 +0000 (2006-12-30)
parents 63fb88610e1e
children dbddea768e29
files linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.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/core/evtchn.c linux-2.6-xen-sparse/drivers/xen/fbfront/xenfb.c linux-2.6-xen-sparse/drivers/xen/fbfront/xenkbd.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/pciback/xenbus.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/xenbus/xenbus_client.c linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c linux-2.6-xen-sparse/include/xen/evtchn.h linux-2.6-xen-sparse/include/xen/xenbus.h
line diff
     1.1 --- a/linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c	Sat Dec 30 15:45:13 2006 +0000
     1.2 +++ b/linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c	Sat Dec 30 18:23:27 2006 +0000
     1.3 @@ -54,7 +54,6 @@ struct tpm_private {
     1.4  
     1.5  	tpmif_tx_interface_t *tx;
     1.6  	atomic_t refcnt;
     1.7 -	unsigned int evtchn;
     1.8  	unsigned int irq;
     1.9  	u8 is_connected;
    1.10  	u8 is_suspended;
    1.11 @@ -271,7 +270,7 @@ static void destroy_tpmring(struct tpm_p
    1.12  	if (tp->irq)
    1.13  		unbind_from_irqhandler(tp->irq, tp);
    1.14  
    1.15 -	tp->evtchn = tp->irq = 0;
    1.16 +	tp->irq = 0;
    1.17  }
    1.18  
    1.19  
    1.20 @@ -302,8 +301,8 @@ again:
    1.21  		goto abort_transaction;
    1.22  	}
    1.23  
    1.24 -	err = xenbus_printf(xbt, dev->nodename,
    1.25 -			    "event-channel", "%u", tp->evtchn);
    1.26 +	err = xenbus_printf(xbt, dev->nodename, "event-channel", "%u",
    1.27 +			    irq_to_evtchn_port(tp->irq));
    1.28  	if (err) {
    1.29  		message = "writing event-channel";
    1.30  		goto abort_transaction;
    1.31 @@ -459,19 +458,15 @@ static int tpmif_connect(struct xenbus_d
    1.32  
    1.33  	tp->backend_id = domid;
    1.34  
    1.35 -	err = xenbus_alloc_evtchn(dev, &tp->evtchn);
    1.36 -	if (err)
    1.37 -		return err;
    1.38 -
    1.39 -	err = bind_evtchn_to_irqhandler(tp->evtchn,
    1.40 -					tpmif_int, SA_SAMPLE_RANDOM, "tpmif",
    1.41 -					tp);
    1.42 +	err = bind_listening_port_to_irqhandler(
    1.43 +		domid, tpmif_int, SA_SAMPLE_RANDOM, "tpmif", tp);
    1.44  	if (err <= 0) {
    1.45 -		WPRINTK("bind_evtchn_to_irqhandler failed (err=%d)\n", err);
    1.46 +		WPRINTK("bind_listening_port_to_irqhandler failed "
    1.47 +			"(err=%d)\n", err);
    1.48  		return err;
    1.49  	}
    1.50 +	tp->irq = err;
    1.51  
    1.52 -	tp->irq = err;
    1.53  	return 0;
    1.54  }
    1.55  
    1.56 @@ -656,9 +651,6 @@ static int tpm_xmit(struct tpm_private *
    1.57  
    1.58  	mb();
    1.59  
    1.60 -	DPRINTK("Notifying backend via event channel %d\n",
    1.61 -	        tp->evtchn);
    1.62 -
    1.63  	notify_remote_via_irq(tp->irq);
    1.64  
    1.65  	spin_unlock_irq(&tp->tx_lock);
     2.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/common.h	Sat Dec 30 15:45:13 2006 +0000
     2.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/common.h	Sat Dec 30 18:23:27 2006 +0000
     2.3 @@ -65,7 +65,6 @@ typedef struct blkif_st {
     2.4  	domid_t           domid;
     2.5  	unsigned int      handle;
     2.6  	/* Physical parameters of the comms window. */
     2.7 -	unsigned int      evtchn;
     2.8  	unsigned int      irq;
     2.9  	/* Comms information. */
    2.10  	blkif_back_ring_t blk_ring;
     3.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c	Sat Dec 30 15:45:13 2006 +0000
     3.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c	Sat Dec 30 18:23:27 2006 +0000
     3.3 @@ -97,7 +97,6 @@ int blkif_map(blkif_t *blkif, unsigned l
     3.4  {
     3.5  	blkif_sring_t *sring;
     3.6  	int err;
     3.7 -	struct evtchn_bind_interdomain bind_interdomain;
     3.8  
     3.9  	/* Already connected through? */
    3.10  	if (blkif->irq)
    3.11 @@ -112,24 +111,18 @@ int blkif_map(blkif_t *blkif, unsigned l
    3.12  		return err;
    3.13  	}
    3.14  
    3.15 -	bind_interdomain.remote_dom  = blkif->domid;
    3.16 -	bind_interdomain.remote_port = evtchn;
    3.17 +	sring = (blkif_sring_t *)blkif->blk_ring_area->addr;
    3.18 +	BACK_RING_INIT(&blkif->blk_ring, sring, PAGE_SIZE);
    3.19  
    3.20 -	err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain,
    3.21 -					  &bind_interdomain);
    3.22 -	if (err) {
    3.23 +	err = bind_interdomain_evtchn_to_irqhandler(
    3.24 +		blkif->domid, evtchn, blkif_be_int, 0, "blkif-backend", blkif);
    3.25 +	if (err < 0)
    3.26 +	{
    3.27  		unmap_frontend_page(blkif);
    3.28  		free_vm_area(blkif->blk_ring_area);
    3.29  		return err;
    3.30  	}
    3.31 -
    3.32 -	blkif->evtchn = bind_interdomain.local_port;
    3.33 -
    3.34 -	sring = (blkif_sring_t *)blkif->blk_ring_area->addr;
    3.35 -	BACK_RING_INIT(&blkif->blk_ring, sring, PAGE_SIZE);
    3.36 -
    3.37 -	blkif->irq = bind_evtchn_to_irqhandler(
    3.38 -		blkif->evtchn, blkif_be_int, 0, "blkif-backend", blkif);
    3.39 +	blkif->irq = err;
    3.40  
    3.41  	return 0;
    3.42  }
     4.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c	Sat Dec 30 15:45:13 2006 +0000
     4.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c	Sat Dec 30 18:23:27 2006 +0000
     4.3 @@ -174,8 +174,8 @@ again:
     4.4  		message = "writing ring-ref";
     4.5  		goto abort_transaction;
     4.6  	}
     4.7 -	err = xenbus_printf(xbt, dev->nodename,
     4.8 -			    "event-channel", "%u", info->evtchn);
     4.9 +	err = xenbus_printf(xbt, dev->nodename, "event-channel", "%u",
    4.10 +			    irq_to_evtchn_port(info->irq));
    4.11  	if (err) {
    4.12  		message = "writing event-channel";
    4.13  		goto abort_transaction;
    4.14 @@ -228,15 +228,11 @@ static int setup_blkring(struct xenbus_d
    4.15  	}
    4.16  	info->ring_ref = err;
    4.17  
    4.18 -	err = xenbus_alloc_evtchn(dev, &info->evtchn);
    4.19 -	if (err)
    4.20 -		goto fail;
    4.21 -
    4.22 -	err = bind_evtchn_to_irqhandler(
    4.23 -		info->evtchn, blkif_int, SA_SAMPLE_RANDOM, "blkif", info);
    4.24 +	err = bind_listening_port_to_irqhandler(
    4.25 +		dev->otherend_id, blkif_int, SA_SAMPLE_RANDOM, "blkif", info);
    4.26  	if (err <= 0) {
    4.27  		xenbus_dev_fatal(dev, err,
    4.28 -				 "bind_evtchn_to_irqhandler failed");
    4.29 +				 "bind_listening_port_to_irqhandler");
    4.30  		goto fail;
    4.31  	}
    4.32  	info->irq = err;
    4.33 @@ -775,8 +771,7 @@ static void blkif_free(struct blkfront_i
    4.34  	}
    4.35  	if (info->irq)
    4.36  		unbind_from_irqhandler(info->irq, info);
    4.37 -	info->evtchn = info->irq = 0;
    4.38 -
    4.39 +	info->irq = 0;
    4.40  }
    4.41  
    4.42  static void blkif_completion(struct blk_shadow *s)
     5.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkfront/block.h	Sat Dec 30 15:45:13 2006 +0000
     5.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/block.h	Sat Dec 30 18:23:27 2006 +0000
     5.3 @@ -119,7 +119,7 @@ struct blkfront_info
     5.4  	int connected;
     5.5  	int ring_ref;
     5.6  	blkif_front_ring_t ring;
     5.7 -	unsigned int evtchn, irq;
     5.8 +	unsigned int irq;
     5.9  	struct xlbd_major_info *mi;
    5.10  	request_queue_t *rq;
    5.11  	struct work_struct work;
     6.1 --- a/linux-2.6-xen-sparse/drivers/xen/blktap/common.h	Sat Dec 30 15:45:13 2006 +0000
     6.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blktap/common.h	Sat Dec 30 18:23:27 2006 +0000
     6.3 @@ -56,7 +56,6 @@ typedef struct blkif_st {
     6.4  	domid_t           domid;
     6.5  	unsigned int      handle;
     6.6  	/* Physical parameters of the comms window. */
     6.7 -	unsigned int      evtchn;
     6.8  	unsigned int      irq;
     6.9  	/* Comms information. */
    6.10  	blkif_back_ring_t blk_ring;
     7.1 --- a/linux-2.6-xen-sparse/drivers/xen/blktap/interface.c	Sat Dec 30 15:45:13 2006 +0000
     7.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blktap/interface.c	Sat Dec 30 18:23:27 2006 +0000
     7.3 @@ -98,7 +98,6 @@ int tap_blkif_map(blkif_t *blkif, unsign
     7.4  {
     7.5  	blkif_sring_t *sring;
     7.6  	int err;
     7.7 -	struct evtchn_bind_interdomain bind_interdomain;
     7.8  
     7.9  	/* Already connected through? */
    7.10  	if (blkif->irq)
    7.11 @@ -113,24 +112,18 @@ int tap_blkif_map(blkif_t *blkif, unsign
    7.12  		return err;
    7.13  	}
    7.14  
    7.15 -	bind_interdomain.remote_dom  = blkif->domid;
    7.16 -	bind_interdomain.remote_port = evtchn;
    7.17 +	sring = (blkif_sring_t *)blkif->blk_ring_area->addr;
    7.18 +	BACK_RING_INIT(&blkif->blk_ring, sring, PAGE_SIZE);
    7.19  
    7.20 -	err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain,
    7.21 -					  &bind_interdomain);
    7.22 -	if (err) {
    7.23 +	err = bind_interdomain_evtchn_to_irqhandler(
    7.24 +		blkif->domid, evtchn, tap_blkif_be_int,
    7.25 +		0, "blkif-backend", blkif);
    7.26 +	if (err < 0) {
    7.27  		unmap_frontend_page(blkif);
    7.28  		free_vm_area(blkif->blk_ring_area);
    7.29  		return err;
    7.30  	}
    7.31 -
    7.32 -	blkif->evtchn = bind_interdomain.local_port;
    7.33 -
    7.34 -	sring = (blkif_sring_t *)blkif->blk_ring_area->addr;
    7.35 -	BACK_RING_INIT(&blkif->blk_ring, sring, PAGE_SIZE);
    7.36 -
    7.37 -	blkif->irq = bind_evtchn_to_irqhandler(
    7.38 -		blkif->evtchn, tap_blkif_be_int, 0, "blkif-backend", blkif);
    7.39 +	blkif->irq = err;
    7.40  
    7.41  	return 0;
    7.42  }
     8.1 --- a/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c	Sat Dec 30 15:45:13 2006 +0000
     8.2 +++ b/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c	Sat Dec 30 18:23:27 2006 +0000
     8.3 @@ -121,7 +121,7 @@ int xencons_ring_init(void)
     8.4  	    !xen_start_info->console.domU.evtchn)
     8.5  		return -ENODEV;
     8.6  
     8.7 -	irq = bind_evtchn_to_irqhandler(
     8.8 +	irq = bind_caller_port_to_irqhandler(
     8.9  		xen_start_info->console.domU.evtchn,
    8.10  		handle_input, 0, "xencons", NULL);
    8.11  	if (irq < 0) {
     9.1 --- a/linux-2.6-xen-sparse/drivers/xen/core/evtchn.c	Sat Dec 30 15:45:13 2006 +0000
     9.2 +++ b/linux-2.6-xen-sparse/drivers/xen/core/evtchn.c	Sat Dec 30 18:23:27 2006 +0000
     9.3 @@ -61,7 +61,14 @@ static int evtchn_to_irq[NR_EVENT_CHANNE
     9.4  static u32 irq_info[NR_IRQS];
     9.5  
     9.6  /* Binding types. */
     9.7 -enum { IRQT_UNBOUND, IRQT_PIRQ, IRQT_VIRQ, IRQT_IPI, IRQT_EVTCHN };
     9.8 +enum {
     9.9 +	IRQT_UNBOUND,
    9.10 +	IRQT_PIRQ,
    9.11 +	IRQT_VIRQ,
    9.12 +	IRQT_IPI,
    9.13 +	IRQT_LOCAL_PORT,
    9.14 +	IRQT_CALLER_PORT
    9.15 +};
    9.16  
    9.17  /* Constructor for packed IRQ information. */
    9.18  static inline u32 mk_irq_info(u32 type, u32 index, u32 evtchn)
    9.19 @@ -275,18 +282,18 @@ static int find_unbound_irq(void)
    9.20  	return -ENOSPC;
    9.21  }
    9.22  
    9.23 -static int bind_evtchn_to_irq(unsigned int evtchn)
    9.24 +static int bind_caller_port_to_irq(unsigned int caller_port)
    9.25  {
    9.26  	int irq;
    9.27  
    9.28  	spin_lock(&irq_mapping_update_lock);
    9.29  
    9.30 -	if ((irq = evtchn_to_irq[evtchn]) == -1) {
    9.31 +	if ((irq = evtchn_to_irq[caller_port]) == -1) {
    9.32  		if ((irq = find_unbound_irq()) < 0)
    9.33  			goto out;
    9.34  
    9.35 -		evtchn_to_irq[evtchn] = irq;
    9.36 -		irq_info[irq] = mk_irq_info(IRQT_EVTCHN, 0, evtchn);
    9.37 +		evtchn_to_irq[caller_port] = irq;
    9.38 +		irq_info[irq] = mk_irq_info(IRQT_CALLER_PORT, 0, caller_port);
    9.39  	}
    9.40  
    9.41  	irq_bindcount[irq]++;
    9.42 @@ -296,6 +303,59 @@ static int bind_evtchn_to_irq(unsigned i
    9.43  	return irq;
    9.44  }
    9.45  
    9.46 +static int bind_local_port_to_irq(unsigned int local_port)
    9.47 +{
    9.48 +	int irq;
    9.49 +
    9.50 +	spin_lock(&irq_mapping_update_lock);
    9.51 +
    9.52 +	BUG_ON(evtchn_to_irq[local_port] != -1);
    9.53 +
    9.54 +	if ((irq = find_unbound_irq()) < 0) {
    9.55 +		struct evtchn_close close = { .port = local_port };
    9.56 +		if (HYPERVISOR_event_channel_op(EVTCHNOP_close, &close))
    9.57 +			BUG();
    9.58 +		goto out;
    9.59 +	}
    9.60 +
    9.61 +	evtchn_to_irq[local_port] = irq;
    9.62 +	irq_info[irq] = mk_irq_info(IRQT_LOCAL_PORT, 0, local_port);
    9.63 +	irq_bindcount[irq]++;
    9.64 +
    9.65 + out:
    9.66 +	spin_unlock(&irq_mapping_update_lock);
    9.67 +	return irq;
    9.68 +}
    9.69 +
    9.70 +static int bind_listening_port_to_irq(unsigned int remote_domain)
    9.71 +{
    9.72 +	struct evtchn_alloc_unbound alloc_unbound;
    9.73 +	int err;
    9.74 +
    9.75 +	alloc_unbound.dom        = DOMID_SELF;
    9.76 +	alloc_unbound.remote_dom = remote_domain;
    9.77 +
    9.78 +	err = HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound,
    9.79 +					  &alloc_unbound);
    9.80 +
    9.81 +	return err ? : bind_local_port_to_irq(alloc_unbound.port);
    9.82 +}
    9.83 +
    9.84 +static int bind_interdomain_evtchn_to_irq(unsigned int remote_domain,
    9.85 +					  unsigned int remote_port)
    9.86 +{
    9.87 +	struct evtchn_bind_interdomain bind_interdomain;
    9.88 +	int err;
    9.89 +
    9.90 +	bind_interdomain.remote_dom  = remote_domain;
    9.91 +	bind_interdomain.remote_port = remote_port;
    9.92 +
    9.93 +	err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain,
    9.94 +					  &bind_interdomain);
    9.95 +
    9.96 +	return err ? : bind_local_port_to_irq(bind_interdomain.local_port);
    9.97 +}
    9.98 +
    9.99  static int bind_virq_to_irq(unsigned int virq, unsigned int cpu)
   9.100  {
   9.101  	struct evtchn_bind_virq bind_virq;
   9.102 @@ -370,7 +430,8 @@ static void unbind_from_irq(unsigned int
   9.103  
   9.104  	if ((--irq_bindcount[irq] == 0) && VALID_EVTCHN(evtchn)) {
   9.105  		close.port = evtchn;
   9.106 -		if (HYPERVISOR_event_channel_op(EVTCHNOP_close, &close) != 0)
   9.107 +		if ((type_from_irq(irq) != IRQT_CALLER_PORT) &&
   9.108 +		    HYPERVISOR_event_channel_op(EVTCHNOP_close, &close))
   9.109  			BUG();
   9.110  
   9.111  		switch (type_from_irq(irq)) {
   9.112 @@ -396,17 +457,16 @@ static void unbind_from_irq(unsigned int
   9.113  	spin_unlock(&irq_mapping_update_lock);
   9.114  }
   9.115  
   9.116 -int bind_evtchn_to_irqhandler(
   9.117 -	unsigned int evtchn,
   9.118 +int bind_caller_port_to_irqhandler(
   9.119 +	unsigned int caller_port,
   9.120  	irqreturn_t (*handler)(int, void *, struct pt_regs *),
   9.121  	unsigned long irqflags,
   9.122  	const char *devname,
   9.123  	void *dev_id)
   9.124  {
   9.125 -	unsigned int irq;
   9.126 -	int retval;
   9.127 +	int irq, retval;
   9.128  
   9.129 -	irq = bind_evtchn_to_irq(evtchn);
   9.130 +	irq = bind_caller_port_to_irq(caller_port);
   9.131  	if (irq < 0)
   9.132  		return irq;
   9.133  
   9.134 @@ -418,7 +478,54 @@ int bind_evtchn_to_irqhandler(
   9.135  
   9.136  	return irq;
   9.137  }
   9.138 -EXPORT_SYMBOL_GPL(bind_evtchn_to_irqhandler);
   9.139 +EXPORT_SYMBOL_GPL(bind_caller_port_to_irqhandler);
   9.140 +
   9.141 +int bind_listening_port_to_irqhandler(
   9.142 +	unsigned int remote_domain,
   9.143 +	irqreturn_t (*handler)(int, void *, struct pt_regs *),
   9.144 +	unsigned long irqflags,
   9.145 +	const char *devname,
   9.146 +	void *dev_id)
   9.147 +{
   9.148 +	int irq, retval;
   9.149 +
   9.150 +	irq = bind_listening_port_to_irq(remote_domain);
   9.151 +	if (irq < 0)
   9.152 +		return irq;
   9.153 +
   9.154 +	retval = request_irq(irq, handler, irqflags, devname, dev_id);
   9.155 +	if (retval != 0) {
   9.156 +		unbind_from_irq(irq);
   9.157 +		return retval;
   9.158 +	}
   9.159 +
   9.160 +	return irq;
   9.161 +}
   9.162 +EXPORT_SYMBOL_GPL(bind_listening_port_to_irqhandler);
   9.163 +
   9.164 +int bind_interdomain_evtchn_to_irqhandler(
   9.165 +	unsigned int remote_domain,
   9.166 +	unsigned int remote_port,
   9.167 +	irqreturn_t (*handler)(int, void *, struct pt_regs *),
   9.168 +	unsigned long irqflags,
   9.169 +	const char *devname,
   9.170 +	void *dev_id)
   9.171 +{
   9.172 +	int irq, retval;
   9.173 +
   9.174 +	irq = bind_interdomain_evtchn_to_irq(remote_domain, remote_port);
   9.175 +	if (irq < 0)
   9.176 +		return irq;
   9.177 +
   9.178 +	retval = request_irq(irq, handler, irqflags, devname, dev_id);
   9.179 +	if (retval != 0) {
   9.180 +		unbind_from_irq(irq);
   9.181 +		return retval;
   9.182 +	}
   9.183 +
   9.184 +	return irq;
   9.185 +}
   9.186 +EXPORT_SYMBOL_GPL(bind_interdomain_evtchn_to_irqhandler);
   9.187  
   9.188  int bind_virq_to_irqhandler(
   9.189  	unsigned int virq,
   9.190 @@ -428,8 +535,7 @@ int bind_virq_to_irqhandler(
   9.191  	const char *devname,
   9.192  	void *dev_id)
   9.193  {
   9.194 -	unsigned int irq;
   9.195 -	int retval;
   9.196 +	int irq, retval;
   9.197  
   9.198  	irq = bind_virq_to_irq(virq, cpu);
   9.199  	if (irq < 0)
   9.200 @@ -453,8 +559,7 @@ int bind_ipi_to_irqhandler(
   9.201  	const char *devname,
   9.202  	void *dev_id)
   9.203  {
   9.204 -	unsigned int irq;
   9.205 -	int retval;
   9.206 +	int irq, retval;
   9.207  
   9.208  	irq = bind_ipi_to_irq(ipi, cpu);
   9.209  	if (irq < 0)
   9.210 @@ -729,6 +834,12 @@ void notify_remote_via_irq(int irq)
   9.211  }
   9.212  EXPORT_SYMBOL_GPL(notify_remote_via_irq);
   9.213  
   9.214 +int irq_to_evtchn_port(int irq)
   9.215 +{
   9.216 +	return evtchn_from_irq(irq);
   9.217 +}
   9.218 +EXPORT_SYMBOL_GPL(irq_to_evtchn_port);
   9.219 +
   9.220  void mask_evtchn(int port)
   9.221  {
   9.222  	shared_info_t *s = HYPERVISOR_shared_info;
    10.1 --- a/linux-2.6-xen-sparse/drivers/xen/fbfront/xenfb.c	Sat Dec 30 15:45:13 2006 +0000
    10.2 +++ b/linux-2.6-xen-sparse/drivers/xen/fbfront/xenfb.c	Sat Dec 30 18:23:27 2006 +0000
    10.3 @@ -56,7 +56,6 @@ struct xenfb_info
    10.4  	struct page		**pages;
    10.5  	struct list_head	mappings; /* protected by mm_lock */
    10.6  
    10.7 -	unsigned		evtchn;
    10.8  	int			irq;
    10.9  	struct xenfb_page	*page;
   10.10  	unsigned long 		*mfns;
   10.11 @@ -156,7 +155,7 @@ static void xenfb_do_update(struct xenfb
   10.12  	wmb();			/* ensure ring contents visible */
   10.13  	info->page->out_prod = prod + 1;
   10.14  
   10.15 -	notify_remote_via_evtchn(info->evtchn);
   10.16 +	notify_remote_via_irq(info->irq);
   10.17  }
   10.18  
   10.19  static int xenfb_queue_full(struct xenfb_info *info)
   10.20 @@ -429,7 +428,7 @@ static irqreturn_t xenfb_event_handler(i
   10.21  
   10.22  	if (page->in_cons != page->in_prod) {
   10.23  		info->page->in_cons = info->page->in_prod;
   10.24 -		notify_remote_via_evtchn(info->evtchn);
   10.25 +		notify_remote_via_irq(info->irq);
   10.26  	}
   10.27  	return IRQ_HANDLED;
   10.28  }
   10.29 @@ -618,14 +617,11 @@ static int xenfb_connect_backend(struct 
   10.30  	int ret;
   10.31  	struct xenbus_transaction xbt;
   10.32  
   10.33 -	ret = xenbus_alloc_evtchn(dev, &info->evtchn);
   10.34 -	if (ret)
   10.35 -		return ret;
   10.36 -	ret = bind_evtchn_to_irqhandler(info->evtchn, xenfb_event_handler,
   10.37 -					0, "xenfb", info);
   10.38 +	ret = bind_listening_port_to_irqhandler(
   10.39 +		dev->otherend_id, xenfb_event_handler, 0, "xenfb", info);
   10.40  	if (ret < 0) {
   10.41 -		xenbus_free_evtchn(dev, info->evtchn);
   10.42 -		xenbus_dev_fatal(dev, ret, "bind_evtchn_to_irqhandler");
   10.43 +		xenbus_dev_fatal(dev, ret,
   10.44 +				 "bind_listening_port_to_irqhandler");
   10.45  		return ret;
   10.46  	}
   10.47  	info->irq = ret;
   10.48 @@ -641,7 +637,7 @@ static int xenfb_connect_backend(struct 
   10.49  	if (ret)
   10.50  		goto error_xenbus;
   10.51  	ret = xenbus_printf(xbt, dev->nodename, "event-channel", "%u",
   10.52 -			    info->evtchn);
   10.53 +			    irq_to_evtchn_port(info->irq));
   10.54  	if (ret)
   10.55  		goto error_xenbus;
   10.56  	ret = xenbus_printf(xbt, dev->nodename, "feature-update", "1");
    11.1 --- a/linux-2.6-xen-sparse/drivers/xen/fbfront/xenkbd.c	Sat Dec 30 15:45:13 2006 +0000
    11.2 +++ b/linux-2.6-xen-sparse/drivers/xen/fbfront/xenkbd.c	Sat Dec 30 18:23:27 2006 +0000
    11.3 @@ -31,7 +31,6 @@ struct xenkbd_info
    11.4  {
    11.5  	struct input_dev *dev;
    11.6  	struct xenkbd_page *page;
    11.7 -	unsigned evtchn;
    11.8  	int irq;
    11.9  	struct xenbus_device *xbdev;
   11.10  };
   11.11 @@ -76,7 +75,7 @@ static irqreturn_t input_handler(int rq,
   11.12  	input_sync(info->dev);
   11.13  	mb();			/* ensure we got ring contents */
   11.14  	page->in_cons = cons;
   11.15 -	notify_remote_via_evtchn(info->evtchn);
   11.16 +	notify_remote_via_irq(info->irq);
   11.17  
   11.18  	return IRQ_HANDLED;
   11.19  }
   11.20 @@ -168,14 +167,11 @@ static int xenkbd_connect_backend(struct
   11.21  	int ret;
   11.22  	struct xenbus_transaction xbt;
   11.23  
   11.24 -	ret = xenbus_alloc_evtchn(dev, &info->evtchn);
   11.25 -	if (ret)
   11.26 -		return ret;
   11.27 -	ret = bind_evtchn_to_irqhandler(info->evtchn, input_handler, 0,
   11.28 -					"xenkbd", info);
   11.29 +	ret = bind_listening_port_to_irqhandler(
   11.30 +		dev->otherend_id, input_handler, 0, "xenkbd", info);
   11.31  	if (ret < 0) {
   11.32 -		xenbus_free_evtchn(dev, info->evtchn);
   11.33 -		xenbus_dev_fatal(dev, ret, "bind_evtchn_to_irqhandler");
   11.34 +		xenbus_dev_fatal(dev, ret,
   11.35 +				 "bind_listening_port_to_irqhandler");
   11.36  		return ret;
   11.37  	}
   11.38  	info->irq = ret;
   11.39 @@ -191,7 +187,7 @@ static int xenkbd_connect_backend(struct
   11.40  	if (ret)
   11.41  		goto error_xenbus;
   11.42  	ret = xenbus_printf(xbt, dev->nodename, "event-channel", "%u",
   11.43 -			    info->evtchn);
   11.44 +			    irq_to_evtchn_port(info->irq));
   11.45  	if (ret)
   11.46  		goto error_xenbus;
   11.47  	ret = xenbus_transaction_end(xbt, 0);
    12.1 --- a/linux-2.6-xen-sparse/drivers/xen/netback/common.h	Sat Dec 30 15:45:13 2006 +0000
    12.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/common.h	Sat Dec 30 18:23:27 2006 +0000
    12.3 @@ -67,7 +67,6 @@ typedef struct netif_st {
    12.4  	grant_ref_t      tx_shmem_ref;
    12.5  	grant_handle_t   rx_shmem_handle;
    12.6  	grant_ref_t      rx_shmem_ref;
    12.7 -	unsigned int     evtchn;
    12.8  	unsigned int     irq;
    12.9  
   12.10  	/* The shared rings and indexes. */
    13.1 --- a/linux-2.6-xen-sparse/drivers/xen/netback/interface.c	Sat Dec 30 15:45:13 2006 +0000
    13.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/interface.c	Sat Dec 30 18:23:27 2006 +0000
    13.3 @@ -259,7 +259,6 @@ int netif_map(netif_t *netif, unsigned l
    13.4  	int err = -ENOMEM;
    13.5  	netif_tx_sring_t *txs;
    13.6  	netif_rx_sring_t *rxs;
    13.7 -	struct evtchn_bind_interdomain bind_interdomain;
    13.8  
    13.9  	/* Already connected through? */
   13.10  	if (netif->irq)
   13.11 @@ -276,18 +275,12 @@ int netif_map(netif_t *netif, unsigned l
   13.12  	if (err)
   13.13  		goto err_map;
   13.14  
   13.15 -	bind_interdomain.remote_dom = netif->domid;
   13.16 -	bind_interdomain.remote_port = evtchn;
   13.17 -
   13.18 -	err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain,
   13.19 -					  &bind_interdomain);
   13.20 -	if (err)
   13.21 +	err = bind_interdomain_evtchn_to_irqhandler(
   13.22 +		netif->domid, evtchn, netif_be_int, 0,
   13.23 +		netif->dev->name, netif);
   13.24 +	if (err < 0)
   13.25  		goto err_hypervisor;
   13.26 -
   13.27 -	netif->evtchn = bind_interdomain.local_port;
   13.28 -
   13.29 -	netif->irq = bind_evtchn_to_irqhandler(
   13.30 -		netif->evtchn, netif_be_int, 0, netif->dev->name, netif);
   13.31 +	netif->irq = err;
   13.32  	disable_irq(netif->irq);
   13.33  
   13.34  	txs = (netif_tx_sring_t *)netif->tx_comms_area->addr;
    14.1 --- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c	Sat Dec 30 15:45:13 2006 +0000
    14.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c	Sat Dec 30 18:23:27 2006 +0000
    14.3 @@ -153,7 +153,7 @@ struct netfront_info {
    14.4  	spinlock_t   tx_lock;
    14.5  	spinlock_t   rx_lock;
    14.6  
    14.7 -	unsigned int evtchn, irq;
    14.8 +	unsigned int irq;
    14.9  	unsigned int copying_receiver;
   14.10  
   14.11  	/* Receive-ring batched refills. */
   14.12 @@ -408,7 +408,8 @@ again:
   14.13  		goto abort_transaction;
   14.14  	}
   14.15  	err = xenbus_printf(xbt, dev->nodename,
   14.16 -			    "event-channel", "%u", info->evtchn);
   14.17 +			    "event-channel", "%u",
   14.18 +			    irq_to_evtchn_port(info->irq));
   14.19  	if (err) {
   14.20  		message = "writing event-channel";
   14.21  		goto abort_transaction;
   14.22 @@ -513,17 +514,15 @@ static int setup_device(struct xenbus_de
   14.23  	}
   14.24  	info->rx_ring_ref = err;
   14.25  
   14.26 -	err = xenbus_alloc_evtchn(dev, &info->evtchn);
   14.27 -	if (err)
   14.28 -		goto fail;
   14.29 +	memcpy(netdev->dev_addr, info->mac, ETH_ALEN);
   14.30  
   14.31 -	memcpy(netdev->dev_addr, info->mac, ETH_ALEN);
   14.32 -	err = bind_evtchn_to_irqhandler(info->evtchn, netif_int,
   14.33 -					SA_SAMPLE_RANDOM, netdev->name,
   14.34 -					netdev);
   14.35 +	err = bind_listening_port_to_irqhandler(
   14.36 +		dev->otherend_id, netif_int, SA_SAMPLE_RANDOM, netdev->name,
   14.37 +		netdev);
   14.38  	if (err < 0)
   14.39  		goto fail;
   14.40  	info->irq = err;
   14.41 +
   14.42  	return 0;
   14.43  
   14.44   fail:
   14.45 @@ -2029,7 +2028,7 @@ static void netif_disconnect_backend(str
   14.46  
   14.47  	if (info->irq)
   14.48  		unbind_from_irqhandler(info->irq, info->netdev);
   14.49 -	info->evtchn = info->irq = 0;
   14.50 +	info->irq = 0;
   14.51  
   14.52  	end_access(info->tx_ring_ref, info->tx.sring);
   14.53  	end_access(info->rx_ring_ref, info->rx.sring);
    15.1 --- a/linux-2.6-xen-sparse/drivers/xen/pciback/xenbus.c	Sat Dec 30 15:45:13 2006 +0000
    15.2 +++ b/linux-2.6-xen-sparse/drivers/xen/pciback/xenbus.c	Sat Dec 30 18:23:27 2006 +0000
    15.3 @@ -71,7 +71,6 @@ static int pciback_do_attach(struct pcib
    15.4  			     int remote_evtchn)
    15.5  {
    15.6  	int err = 0;
    15.7 -	int evtchn;
    15.8  	struct vm_struct *area;
    15.9  
   15.10  	dev_dbg(&pdev->xdev->dev,
   15.11 @@ -86,12 +85,9 @@ static int pciback_do_attach(struct pcib
   15.12  	pdev->sh_area = area;
   15.13  	pdev->sh_info = area->addr;
   15.14  
   15.15 -	err = xenbus_bind_evtchn(pdev->xdev, remote_evtchn, &evtchn);
   15.16 -	if (err)
   15.17 -		goto out;
   15.18 -
   15.19 -	err = bind_evtchn_to_irqhandler(evtchn, pciback_handle_event,
   15.20 -					SA_SAMPLE_RANDOM, "pciback", pdev);
   15.21 +	err = bind_interdomain_evtchn_to_irqhandler(
   15.22 +		pdev->xdev->otherend_id, remote_evtchn, pciback_handle_event,
   15.23 +		SA_SAMPLE_RANDOM, "pciback", pdev);
   15.24  	if (err < 0) {
   15.25  		xenbus_dev_fatal(pdev->xdev, err,
   15.26  				 "Error binding event channel to IRQ");
    16.1 --- a/linux-2.6-xen-sparse/drivers/xen/tpmback/common.h	Sat Dec 30 15:45:13 2006 +0000
    16.2 +++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/common.h	Sat Dec 30 18:23:27 2006 +0000
    16.3 @@ -30,7 +30,6 @@ typedef struct tpmif_st {
    16.4  	unsigned int handle;
    16.5  
    16.6  	/* Physical parameters of the comms window. */
    16.7 -	unsigned int evtchn;
    16.8  	unsigned int irq;
    16.9  
   16.10  	/* The shared rings and indexes. */
    17.1 --- a/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c	Sat Dec 30 15:45:13 2006 +0000
    17.2 +++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c	Sat Dec 30 18:23:27 2006 +0000
    17.3 @@ -118,11 +118,9 @@ static void unmap_frontend_page(tpmif_t 
    17.4  int tpmif_map(tpmif_t *tpmif, unsigned long shared_page, unsigned int evtchn)
    17.5  {
    17.6  	int err;
    17.7 -	struct evtchn_bind_interdomain bind_interdomain;
    17.8  
    17.9 -	if (tpmif->irq) {
   17.10 +	if (tpmif->irq)
   17.11  		return 0;
   17.12 -	}
   17.13  
   17.14  	if ((tpmif->tx_area = alloc_vm_area(PAGE_SIZE)) == NULL)
   17.15  		return -ENOMEM;
   17.16 @@ -133,24 +131,17 @@ int tpmif_map(tpmif_t *tpmif, unsigned l
   17.17  		return err;
   17.18  	}
   17.19  
   17.20 +	tpmif->tx = (tpmif_tx_interface_t *)tpmif->tx_area->addr;
   17.21  
   17.22 -	bind_interdomain.remote_dom  = tpmif->domid;
   17.23 -	bind_interdomain.remote_port = evtchn;
   17.24 -
   17.25 -	err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain,
   17.26 -					  &bind_interdomain);
   17.27 -	if (err) {
   17.28 +	err = bind_interdomain_evtchn_to_irqhandler(
   17.29 +		tpmif->domid, evtchn, tpmif_be_int, 0, tpmif->devname, tpmif);
   17.30 +	if (err < 0) {
   17.31  		unmap_frontend_page(tpmif);
   17.32  		free_vm_area(tpmif->tx_area);
   17.33  		return err;
   17.34  	}
   17.35 -
   17.36 -	tpmif->evtchn = bind_interdomain.local_port;
   17.37 +	tpmif->irq = err;
   17.38  
   17.39 -	tpmif->tx = (tpmif_tx_interface_t *)tpmif->tx_area->addr;
   17.40 -
   17.41 -	tpmif->irq = bind_evtchn_to_irqhandler(
   17.42 -		tpmif->evtchn, tpmif_be_int, 0, tpmif->devname, tpmif);
   17.43  	tpmif->shmem_ref = shared_page;
   17.44  	tpmif->active = 1;
   17.45  
    18.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c	Sat Dec 30 15:45:13 2006 +0000
    18.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c	Sat Dec 30 18:23:27 2006 +0000
    18.3 @@ -254,28 +254,6 @@ int xenbus_alloc_evtchn(struct xenbus_de
    18.4  EXPORT_SYMBOL_GPL(xenbus_alloc_evtchn);
    18.5  
    18.6  
    18.7 -int xenbus_bind_evtchn(struct xenbus_device *dev, int remote_port, int *port)
    18.8 -{
    18.9 -	struct evtchn_bind_interdomain bind_interdomain;
   18.10 -	int err;
   18.11 -
   18.12 -	bind_interdomain.remote_dom  = dev->otherend_id;
   18.13 -	bind_interdomain.remote_port = remote_port,
   18.14 -
   18.15 -	err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain,
   18.16 -					  &bind_interdomain);
   18.17 -	if (err)
   18.18 -		xenbus_dev_fatal(dev, err,
   18.19 -				 "binding to event channel %d from domain %d",
   18.20 -				 remote_port, dev->otherend_id);
   18.21 -	else
   18.22 -		*port = bind_interdomain.local_port;
   18.23 -
   18.24 -	return err;
   18.25 -}
   18.26 -EXPORT_SYMBOL_GPL(xenbus_bind_evtchn);
   18.27 -
   18.28 -
   18.29  int xenbus_free_evtchn(struct xenbus_device *dev, int port)
   18.30  {
   18.31  	struct evtchn_close close;
    19.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c	Sat Dec 30 15:45:13 2006 +0000
    19.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c	Sat Dec 30 18:23:27 2006 +0000
    19.3 @@ -196,7 +196,7 @@ int xb_init_comms(void)
    19.4  	if (xenbus_irq)
    19.5  		unbind_from_irqhandler(xenbus_irq, &xb_waitq);
    19.6  
    19.7 -	err = bind_evtchn_to_irqhandler(
    19.8 +	err = bind_caller_port_to_irqhandler(
    19.9  		xen_store_evtchn, wake_waiting,
   19.10  		0, "xenbus", &xb_waitq);
   19.11  	if (err <= 0) {
    20.1 --- a/linux-2.6-xen-sparse/include/xen/evtchn.h	Sat Dec 30 15:45:13 2006 +0000
    20.2 +++ b/linux-2.6-xen-sparse/include/xen/evtchn.h	Sat Dec 30 18:23:27 2006 +0000
    20.3 @@ -52,22 +52,34 @@
    20.4   * The IRQ argument passed to the callback handler is the same as returned
    20.5   * from the bind call. It may not correspond to a Linux IRQ number.
    20.6   * Returns IRQ or negative errno.
    20.7 - * UNBIND: Takes IRQ to unbind from; automatically closes the event channel.
    20.8   */
    20.9 -extern int bind_evtchn_to_irqhandler(
   20.10 -	unsigned int evtchn,
   20.11 +int bind_caller_port_to_irqhandler(
   20.12 +	unsigned int caller_port,
   20.13  	irqreturn_t (*handler)(int, void *, struct pt_regs *),
   20.14  	unsigned long irqflags,
   20.15  	const char *devname,
   20.16  	void *dev_id);
   20.17 -extern int bind_virq_to_irqhandler(
   20.18 +int bind_listening_port_to_irqhandler(
   20.19 +	unsigned int remote_domain,
   20.20 +	irqreturn_t (*handler)(int, void *, struct pt_regs *),
   20.21 +	unsigned long irqflags,
   20.22 +	const char *devname,
   20.23 +	void *dev_id);
   20.24 +int bind_interdomain_evtchn_to_irqhandler(
   20.25 +	unsigned int remote_domain,
   20.26 +	unsigned int remote_port,
   20.27 +	irqreturn_t (*handler)(int, void *, struct pt_regs *),
   20.28 +	unsigned long irqflags,
   20.29 +	const char *devname,
   20.30 +	void *dev_id);
   20.31 +int bind_virq_to_irqhandler(
   20.32  	unsigned int virq,
   20.33  	unsigned int cpu,
   20.34  	irqreturn_t (*handler)(int, void *, struct pt_regs *),
   20.35  	unsigned long irqflags,
   20.36  	const char *devname,
   20.37  	void *dev_id);
   20.38 -extern int bind_ipi_to_irqhandler(
   20.39 +int bind_ipi_to_irqhandler(
   20.40  	unsigned int ipi,
   20.41  	unsigned int cpu,
   20.42  	irqreturn_t (*handler)(int, void *, struct pt_regs *),
   20.43 @@ -77,21 +89,21 @@ extern int bind_ipi_to_irqhandler(
   20.44  
   20.45  /*
   20.46   * Common unbind function for all event sources. Takes IRQ to unbind from.
   20.47 - * Automatically closes the underlying event channel (even for bindings
   20.48 - * made with bind_evtchn_to_irqhandler()).
   20.49 + * Automatically closes the underlying event channel (except for bindings
   20.50 + * made with bind_caller_port_to_irqhandler()).
   20.51   */
   20.52 -extern void unbind_from_irqhandler(unsigned int irq, void *dev_id);
   20.53 +void unbind_from_irqhandler(unsigned int irq, void *dev_id);
   20.54  
   20.55 -extern void irq_resume(void);
   20.56 +void irq_resume(void);
   20.57  
   20.58  /* Entry point for notifications into Linux subsystems. */
   20.59  asmlinkage void evtchn_do_upcall(struct pt_regs *regs);
   20.60  
   20.61  /* Entry point for notifications into the userland character device. */
   20.62 -extern void evtchn_device_upcall(int port);
   20.63 +void evtchn_device_upcall(int port);
   20.64  
   20.65 -extern void mask_evtchn(int port);
   20.66 -extern void unmask_evtchn(int port);
   20.67 +void mask_evtchn(int port);
   20.68 +void unmask_evtchn(int port);
   20.69  
   20.70  static inline void clear_evtchn(int port)
   20.71  {
   20.72 @@ -106,9 +118,10 @@ static inline void notify_remote_via_evt
   20.73  }
   20.74  
   20.75  /*
   20.76 - * Unlike notify_remote_via_evtchn(), this is safe to use across
   20.77 - * save/restore. Notifications on a broken connection are silently dropped.
   20.78 + * Use these to access the event channel underlying the IRQ handle returned
   20.79 + * by bind_*_to_irqhandler().
   20.80   */
   20.81 -extern void notify_remote_via_irq(int irq);
   20.82 +void notify_remote_via_irq(int irq);
   20.83 +int irq_to_evtchn_port(int irq);
   20.84  
   20.85  #endif /* __ASM_EVTCHN_H__ */
    21.1 --- a/linux-2.6-xen-sparse/include/xen/xenbus.h	Sat Dec 30 15:45:13 2006 +0000
    21.2 +++ b/linux-2.6-xen-sparse/include/xen/xenbus.h	Sat Dec 30 18:23:27 2006 +0000
    21.3 @@ -262,14 +262,6 @@ int xenbus_alloc_evtchn(struct xenbus_de
    21.4  
    21.5  
    21.6  /**
    21.7 - * Bind to an existing interdomain event channel in another domain. Returns 0
    21.8 - * on success and stores the local port in *port. On error, returns -errno,
    21.9 - * switches the device to XenbusStateClosing, and saves the error in XenStore.
   21.10 - */
   21.11 -int xenbus_bind_evtchn(struct xenbus_device *dev, int remote_port, int *port);
   21.12 -
   21.13 -
   21.14 -/**
   21.15   * Free an existing event channel. Returns 0 on success or -errno on error.
   21.16   */
   21.17  int xenbus_free_evtchn(struct xenbus_device *dev, int port);