# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID 559ad1abb3d502079ff5bbd39e2979f0a637549e
# Parent 805ee053e61f4c25e642ff3bb9e657966a15bc33
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@xxxxxxxxxxxxx>
diff -r 805ee053e61f -r 559ad1abb3d5
linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c
--- a/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c Thu Sep 29 12:05:43 2005
+++ b/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c Thu Sep 29 14:14:03 2005
@@ -320,13 +320,19 @@
}
EXPORT_SYMBOL(bind_evtchn_to_irq);
-void unbind_evtchn_from_irq(unsigned int evtchn)
-{
- int irq = evtchn_to_irq[evtchn];
+void unbind_evtchn_from_irq(unsigned int irq)
+{
+ evtchn_op_t op;
+ int evtchn = irq_to_evtchn[irq];
spin_lock(&irq_mapping_update_lock);
- if (--irq_bindcount[irq] == 0) {
+ if ((--irq_bindcount[irq] == 0) && (evtchn != -1)) {
+ op.cmd = EVTCHNOP_close;
+ op.u.close.dom = DOMID_SELF;
+ op.u.close.port = evtchn;
+ BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
+
evtchn_to_irq[evtchn] = -1;
irq_to_evtchn[irq] = -1;
}
@@ -348,17 +354,16 @@
irq = bind_evtchn_to_irq(evtchn);
retval = request_irq(irq, handler, irqflags, devname, dev_id);
if (retval != 0)
- unbind_evtchn_from_irq(evtchn);
-
- return retval;
+ unbind_evtchn_from_irq(irq);
+
+ return irq;
}
EXPORT_SYMBOL(bind_evtchn_to_irqhandler);
-void unbind_evtchn_from_irqhandler(unsigned int evtchn, void *dev_id)
-{
- unsigned int irq = evtchn_to_irq[evtchn];
+void unbind_evtchn_from_irqhandler(unsigned int irq, void *dev_id)
+{
free_irq(irq, dev_id);
- unbind_evtchn_from_irq(evtchn);
+ unbind_evtchn_from_irq(irq);
}
EXPORT_SYMBOL(unbind_evtchn_from_irqhandler);
@@ -425,9 +430,8 @@
{
int evtchn = irq_to_evtchn[irq];
- if (!VALID_EVTCHN(evtchn))
- return 0;
- unmask_evtchn(evtchn);
+ if (VALID_EVTCHN(evtchn))
+ unmask_evtchn(evtchn);
return 0;
}
@@ -435,38 +439,41 @@
{
int evtchn = irq_to_evtchn[irq];
- if (!VALID_EVTCHN(evtchn))
- return;
- mask_evtchn(evtchn);
+ if (VALID_EVTCHN(evtchn))
+ mask_evtchn(evtchn);
}
static void enable_dynirq(unsigned int irq)
{
int evtchn = irq_to_evtchn[irq];
- unmask_evtchn(evtchn);
+ if (VALID_EVTCHN(evtchn))
+ unmask_evtchn(evtchn);
}
static void disable_dynirq(unsigned int irq)
{
int evtchn = irq_to_evtchn[irq];
- mask_evtchn(evtchn);
+ if (VALID_EVTCHN(evtchn))
+ mask_evtchn(evtchn);
}
static void ack_dynirq(unsigned int irq)
{
int evtchn = irq_to_evtchn[irq];
- mask_evtchn(evtchn);
- clear_evtchn(evtchn);
+ if (VALID_EVTCHN(evtchn)) {
+ mask_evtchn(evtchn);
+ clear_evtchn(evtchn);
+ }
}
static void end_dynirq(unsigned int irq)
{
int evtchn = irq_to_evtchn[irq];
- if (!(irq_desc[irq].status & IRQ_DISABLED))
+ if (VALID_EVTCHN(evtchn) && !(irq_desc[irq].status & IRQ_DISABLED))
unmask_evtchn(evtchn);
}
@@ -559,35 +566,36 @@
static void enable_pirq(unsigned int irq)
{
int evtchn = irq_to_evtchn[irq];
- if (!VALID_EVTCHN(evtchn))
- return;
- unmask_evtchn(evtchn);
- pirq_unmask_notify(irq_to_pirq(irq));
+
+ if (VALID_EVTCHN(evtchn)) {
+ unmask_evtchn(evtchn);
+ pirq_unmask_notify(irq_to_pirq(irq));
+ }
}
static void disable_pirq(unsigned int irq)
{
int evtchn = irq_to_evtchn[irq];
- if (!VALID_EVTCHN(evtchn))
- return;
- mask_evtchn(evtchn);
+
+ if (VALID_EVTCHN(evtchn))
+ mask_evtchn(evtchn);
}
static void ack_pirq(unsigned int irq)
{
int evtchn = irq_to_evtchn[irq];
- if (!VALID_EVTCHN(evtchn))
- return;
- mask_evtchn(evtchn);
- clear_evtchn(evtchn);
+
+ if (VALID_EVTCHN(evtchn)) {
+ mask_evtchn(evtchn);
+ clear_evtchn(evtchn);
+ }
}
static void end_pirq(unsigned int irq)
{
int evtchn = irq_to_evtchn[irq];
- if (!VALID_EVTCHN(evtchn))
- return;
- if (!(irq_desc[irq].status & IRQ_DISABLED)) {
+
+ if (VALID_EVTCHN(evtchn) && !(irq_desc[irq].status & IRQ_DISABLED)) {
unmask_evtchn(evtchn);
pirq_unmask_notify(irq_to_pirq(irq));
}
@@ -637,6 +645,10 @@
BUG_ON(per_cpu(ipi_to_evtchn, cpu)[ipi] != -1);
}
+ /* No IRQ -> event-channel mappings. */
+ for (irq = 0; irq < NR_IRQS; irq++)
+ irq_to_evtchn[irq] = -1;
+
/* Primary CPU: rebind VIRQs automatically. */
for (virq = 0; virq < NR_VIRQS; virq++) {
if ((irq = per_cpu(virq_to_irq, 0)[virq]) == -1)
@@ -676,6 +688,13 @@
/* Ready for use. */
unmask_evtchn(evtchn);
}
+
+ /* Remove defunct event-channel -> IRQ mappings. */
+ for (evtchn = 0; evtchn < NR_EVENT_CHANNELS; evtchn++) {
+ if ((evtchn_to_irq[evtchn] != -1) &&
+ (irq_to_evtchn[evtchn_to_irq[evtchn]] == -1))
+ evtchn_to_irq[evtchn] = -1;
+ }
}
void __init init_IRQ(void)
@@ -689,11 +708,10 @@
init_evtchn_cpu_bindings();
+ /* No VIRQ or IPI bindings. */
for (cpu = 0; cpu < NR_CPUS; cpu++) {
- /* No VIRQ -> IRQ mappings. */
for (i = 0; i < NR_VIRQS; i++)
per_cpu(virq_to_irq, cpu)[i] = -1;
- /* No VIRQ -> IRQ mappings. */
for (i = 0; i < NR_IPIS; i++)
per_cpu(ipi_to_evtchn, cpu)[i] = -1;
}
diff -r 805ee053e61f -r 559ad1abb3d5
linux-2.6-xen-sparse/arch/xen/kernel/reboot.c
--- a/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c Thu Sep 29 12:05:43 2005
+++ b/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c Thu Sep 29 14:14:03 2005
@@ -65,12 +65,6 @@
{
int i, j, k, fpp;
-#ifdef CONFIG_XEN_USB_FRONTEND
- extern void usbif_resume();
-#else
-#define usbif_resume() do{}while(0)
-#endif
-
extern int gnttab_suspend(void);
extern int gnttab_resume(void);
@@ -87,7 +81,6 @@
int restore_vcpu_context(int vcpu, vcpu_guest_context_t *ctxt);
#endif
- extern void xencons_suspend(void);
extern void xencons_resume(void);
int err = 0;
@@ -147,16 +140,14 @@
}
#endif
+ xenbus_suspend();
+
+ gnttab_suspend();
+
#ifdef __i386__
mm_pin_all();
kmem_cache_shrink(pgd_cache);
#endif
-
- xenbus_suspend();
-
- xencons_suspend();
-
- gnttab_suspend();
HYPERVISOR_shared_info = (shared_info_t *)empty_zero_page;
clear_fixmap(FIX_SHARED_INFO);
@@ -202,8 +193,6 @@
time_resume();
- usbif_resume();
-
#ifdef CONFIG_SMP
for_each_cpu_mask(i, prev_present_cpus)
restore_vcpu_context(i, &suspended_cpu_records[i]);
diff -r 805ee053e61f -r 559ad1abb3d5
linux-2.6-xen-sparse/drivers/xen/blkback/common.h
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/common.h Thu Sep 29 12:05:43 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/common.h Thu Sep 29 14:14:03 2005
@@ -44,7 +44,7 @@
unsigned int handle;
/* Physical parameters of the comms window. */
unsigned int evtchn;
- unsigned int remote_evtchn;
+ unsigned int irq;
/* Comms information. */
blkif_back_ring_t blk_ring;
struct vm_struct *blk_ring_area;
diff -r 805ee053e61f -r 559ad1abb3d5
linux-2.6-xen-sparse/drivers/xen/blkback/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c Thu Sep 29
12:05:43 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c Thu Sep 29
14:14:03 2005
@@ -71,8 +71,6 @@
evtchn_op_t op = { .cmd = EVTCHNOP_bind_interdomain };
int err;
- BUG_ON(blkif->remote_evtchn);
-
if ( (blkif->blk_ring_area = alloc_vm_area(PAGE_SIZE)) == NULL )
return -ENOMEM;
@@ -94,13 +92,12 @@
}
blkif->evtchn = op.u.bind_interdomain.port1;
- blkif->remote_evtchn = evtchn;
sring = (blkif_sring_t *)blkif->blk_ring_area->addr;
SHARED_RING_INIT(sring);
BACK_RING_INIT(&blkif->blk_ring, sring, PAGE_SIZE);
- bind_evtchn_to_irqhandler(
+ blkif->irq = bind_evtchn_to_irqhandler(
blkif->evtchn, blkif_be_int, 0, "blkif-backend", blkif);
blkif->status = CONNECTED;
@@ -109,20 +106,12 @@
static void free_blkif(void *arg)
{
- evtchn_op_t op = { .cmd = EVTCHNOP_close };
blkif_t *blkif = (blkif_t *)arg;
- op.u.close.port = blkif->evtchn;
- op.u.close.dom = DOMID_SELF;
- HYPERVISOR_event_channel_op(&op);
- op.u.close.port = blkif->remote_evtchn;
- op.u.close.dom = blkif->domid;
- HYPERVISOR_event_channel_op(&op);
+ if (blkif->irq)
+ unbind_evtchn_from_irqhandler(blkif->irq, blkif);
vbd_free(&blkif->vbd);
-
- if (blkif->evtchn)
- unbind_evtchn_from_irqhandler(blkif->evtchn, blkif);
if (blkif->blk_ring.sring) {
unmap_frontend_page(blkif);
diff -r 805ee053e61f -r 559ad1abb3d5
linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c Thu Sep 29
12:05:43 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c Thu Sep 29
14:14:03 2005
@@ -357,8 +357,9 @@
if (info->ring_ref != GRANT_INVALID_REF)
gnttab_end_foreign_access(info->ring_ref, 0);
info->ring_ref = GRANT_INVALID_REF;
- unbind_evtchn_from_irqhandler(info->evtchn, info);
- info->evtchn = 0;
+ if (info->irq)
+ unbind_evtchn_from_irqhandler(info->irq, info);
+ info->evtchn = info->irq = 0;
}
static void blkif_recover(struct blkfront_info *info)
@@ -429,10 +430,12 @@
err = bind_evtchn_to_irqhandler(
info->evtchn, blkif_int, SA_SAMPLE_RANDOM, "blkif", info);
- if (err != 0) {
+ if (err <= 0) {
WPRINTK("bind_evtchn_to_irqhandler failed (err=%d)\n", err);
return;
}
+
+ info->irq = err;
}
diff -r 805ee053e61f -r 559ad1abb3d5
linux-2.6-xen-sparse/drivers/xen/blkfront/block.h
--- a/linux-2.6-xen-sparse/drivers/xen/blkfront/block.h Thu Sep 29 12:05:43 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/block.h Thu Sep 29 14:14:03 2005
@@ -123,7 +123,7 @@
int backend_id;
int ring_ref;
blkif_front_ring_t ring;
- unsigned int evtchn;
+ unsigned int evtchn, irq;
struct xlbd_major_info *mi;
request_queue_t *rq;
struct work_struct work;
diff -r 805ee053e61f -r 559ad1abb3d5
linux-2.6-xen-sparse/drivers/xen/blktap/common.h
--- a/linux-2.6-xen-sparse/drivers/xen/blktap/common.h Thu Sep 29 12:05:43 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blktap/common.h Thu Sep 29 14:14:03 2005
@@ -46,7 +46,7 @@
unsigned int handle;
/* Physical parameters of the comms window. */
unsigned int evtchn;
- unsigned int remote_evtchn;
+ unsigned int irq;
/* Comms information. */
blkif_back_ring_t blk_ring;
struct vm_struct *blk_ring_area;
diff -r 805ee053e61f -r 559ad1abb3d5
linux-2.6-xen-sparse/drivers/xen/blktap/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/blktap/interface.c Thu Sep 29
12:05:43 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blktap/interface.c Thu Sep 29
14:14:03 2005
@@ -71,8 +71,6 @@
evtchn_op_t op = { .cmd = EVTCHNOP_bind_interdomain };
int err;
- BUG_ON(blkif->remote_evtchn);
-
if ((blkif->blk_ring_area = alloc_vm_area(PAGE_SIZE)) == NULL)
return -ENOMEM;
@@ -93,35 +91,26 @@
return err;
}
-
blkif->evtchn = op.u.bind_interdomain.port1;
- blkif->remote_evtchn = evtchn;
sring = (blkif_sring_t *)blkif->blk_ring_area->addr;
SHARED_RING_INIT(sring);
BACK_RING_INIT(&blkif->blk_ring, sring, PAGE_SIZE);
- bind_evtchn_to_irqhandler(
+ blkif->irq = bind_evtchn_to_irqhandler(
blkif->evtchn, blkif_be_int, 0, "blkif-backend", blkif);
- blkif->status = CONNECTED;
+
+ blkif->status = CONNECTED;
return 0;
}
static void free_blkif(void *arg)
{
- evtchn_op_t op = { .cmd = EVTCHNOP_close };
blkif_t *blkif = (blkif_t *)arg;
- op.u.close.port = blkif->evtchn;
- op.u.close.dom = DOMID_SELF;
- HYPERVISOR_event_channel_op(&op);
- op.u.close.port = blkif->remote_evtchn;
- op.u.close.dom = blkif->domid;
- HYPERVISOR_event_channel_op(&op);
-
- if (blkif->evtchn)
- unbind_evtchn_from_irqhandler(blkif->evtchn, blkif);
+ if (blkif->irq)
+ unbind_evtchn_from_irqhandler(blkif->irq, blkif);
if (blkif->blk_ring.sring) {
unmap_frontend_page(blkif);
diff -r 805ee053e61f -r 559ad1abb3d5
linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c
--- a/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c Thu Sep 29
12:05:43 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c Thu Sep 29
14:14:03 2005
@@ -21,7 +21,6 @@
#include <linux/err.h>
#include "xencons_ring.h"
-
struct ring_head
{
u32 cons;
@@ -29,6 +28,7 @@
char buf[0];
} __attribute__((packed));
+static int xencons_irq;
#define XENCONS_RING_SIZE (PAGE_SIZE/2 - sizeof (struct ring_head))
#define XENCONS_IDX(cnt) ((cnt) % XENCONS_RING_SIZE)
@@ -97,32 +97,28 @@
{
int err;
+ if (xencons_irq)
+ unbind_evtchn_from_irqhandler(xencons_irq, inring());
+ xencons_irq = 0;
+
if (!xen_start_info->console_evtchn)
return 0;
- err = bind_evtchn_to_irqhandler(xen_start_info->console_evtchn,
- handle_input, 0, "xencons", inring());
- if (err) {
+ err = bind_evtchn_to_irqhandler(
+ xen_start_info->console_evtchn,
+ handle_input, 0, "xencons", inring());
+ if (err <= 0) {
xprintk("XEN console request irq failed %i\n", err);
return err;
}
+ xencons_irq = err;
+
return 0;
-}
-
-void xencons_suspend(void)
-{
-
- if (!xen_start_info->console_evtchn)
- return;
-
- unbind_evtchn_from_irqhandler(xen_start_info->console_evtchn,
- inring());
}
void xencons_resume(void)
{
-
(void)xencons_ring_init();
}
diff -r 805ee053e61f -r 559ad1abb3d5
linux-2.6-xen-sparse/drivers/xen/netback/common.h
--- a/linux-2.6-xen-sparse/drivers/xen/netback/common.h Thu Sep 29 12:05:43 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/common.h Thu Sep 29 14:14:03 2005
@@ -50,7 +50,7 @@
u16 rx_shmem_handle;
grant_ref_t rx_shmem_ref;
unsigned int evtchn;
- unsigned int remote_evtchn;
+ unsigned int irq;
/* The shared rings and indexes. */
netif_tx_interface_t *tx;
diff -r 805ee053e61f -r 559ad1abb3d5
linux-2.6-xen-sparse/drivers/xen/netback/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/interface.c Thu Sep 29
12:05:43 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/interface.c Thu Sep 29
14:14:03 2005
@@ -15,18 +15,17 @@
spin_lock_bh(&dev->xmit_lock);
netif->active = 1;
spin_unlock_bh(&dev->xmit_lock);
- (void)bind_evtchn_to_irqhandler(
- netif->evtchn, netif_be_int, 0, dev->name, netif);
+ enable_irq(netif->irq);
netif_schedule_work(netif);
}
static void __netif_down(netif_t *netif)
{
struct net_device *dev = netif->dev;
+ disable_irq(netif->irq);
spin_lock_bh(&dev->xmit_lock);
netif->active = 0;
spin_unlock_bh(&dev->xmit_lock);
- unbind_evtchn_from_irqhandler(netif->evtchn, netif);
netif_deschedule_work(netif);
}
@@ -203,7 +202,10 @@
}
netif->evtchn = op.u.bind_interdomain.port1;
- netif->remote_evtchn = evtchn;
+
+ netif->irq = bind_evtchn_to_irqhandler(
+ netif->evtchn, netif_be_int, 0, netif->dev->name, netif);
+ disable_irq(netif->irq);
netif->tx = (netif_tx_interface_t *)netif->comms_area->addr;
netif->rx = (netif_rx_interface_t *)
@@ -224,21 +226,15 @@
static void free_netif_callback(void *arg)
{
- evtchn_op_t op = { .cmd = EVTCHNOP_close };
netif_t *netif = (netif_t *)arg;
/*
- * These can't be done in netif_disconnect() because at that point
+ * This can't be done in netif_disconnect() because at that point
* there may be outstanding requests in the network stack whose
* asynchronous responses must still be notified to the remote driver.
*/
-
- op.u.close.port = netif->evtchn;
- op.u.close.dom = DOMID_SELF;
- HYPERVISOR_event_channel_op(&op);
- op.u.close.port = netif->remote_evtchn;
- op.u.close.dom = netif->domid;
- HYPERVISOR_event_channel_op(&op);
+ if (netif->irq)
+ unbind_evtchn_from_irqhandler(netif->irq, netif);
unregister_netdev(netif->dev);
diff -r 805ee053e61f -r 559ad1abb3d5
linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c Thu Sep 29
12:05:43 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c Thu Sep 29
14:14:03 2005
@@ -127,7 +127,7 @@
spinlock_t rx_lock;
unsigned int handle;
- unsigned int evtchn;
+ unsigned int evtchn, irq;
/* What is the status of our connection to the remote backend? */
#define BEST_CLOSED 0
@@ -815,7 +815,7 @@
memcpy(dev->dev_addr, np->mac, ETH_ALEN);
np->evtchn = evtchn;
network_connect(dev);
- (void)bind_evtchn_to_irqhandler(
+ np->irq = bind_evtchn_to_irqhandler(
np->evtchn, netif_int, SA_SAMPLE_RANDOM, dev->name, dev);
(void)send_fake_arp(dev);
show_device(np);
@@ -1055,8 +1055,9 @@
gnttab_end_foreign_access(info->rx_ring_ref, 0);
info->rx_ring_ref = GRANT_INVALID_REF;
- unbind_evtchn_from_irqhandler(info->evtchn, info->netdev);
- info->evtchn = 0;
+ if (info->irq)
+ unbind_evtchn_from_irqhandler(info->irq, info->netdev);
+ info->evtchn = info->irq = 0;
}
/* Stop network device and free tx/rx queues and irq. */
diff -r 805ee053e61f -r 559ad1abb3d5
linux-2.6-xen-sparse/drivers/xen/tpmback/common.h
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/common.h Thu Sep 29 12:05:43 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/common.h Thu Sep 29 14:14:03 2005
@@ -35,7 +35,7 @@
/* Physical parameters of the comms window. */
unsigned int evtchn;
- unsigned int remote_evtchn;
+ unsigned int irq;
/* The shared rings and indexes. */
tpmif_tx_interface_t *tx;
diff -r 805ee053e61f -r 559ad1abb3d5
linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c Thu Sep 29
12:05:43 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c Thu Sep 29
14:14:03 2005
@@ -120,8 +120,6 @@
evtchn_op_t op = {.cmd = EVTCHNOP_bind_interdomain };
int err;
- BUG_ON(tpmif->remote_evtchn);
-
if ((tpmif->tx_area = alloc_vm_area(PAGE_SIZE)) == NULL)
return -ENOMEM;
@@ -143,12 +141,11 @@
}
tpmif->evtchn = op.u.bind_interdomain.port1;
- tpmif->remote_evtchn = evtchn;
tpmif->tx = (tpmif_tx_interface_t *)tpmif->tx_area->addr;
- bind_evtchn_to_irqhandler(tpmif->evtchn,
- tpmif_be_int, 0, "tpmif-backend", tpmif);
+ tpmif->irq = bind_evtchn_to_irqhandler(
+ tpmif->evtchn, tpmif_be_int, 0, "tpmif-backend", tpmif);
tpmif->status = CONNECTED;
tpmif->shmem_ref = shared_page;
tpmif->active = 1;
@@ -159,18 +156,10 @@
static void
__tpmif_disconnect_complete(void *arg)
{
- evtchn_op_t op = {.cmd = EVTCHNOP_close };
tpmif_t *tpmif = (tpmif_t *) arg;
- op.u.close.port = tpmif->evtchn;
- op.u.close.dom = DOMID_SELF;
- HYPERVISOR_event_channel_op(&op);
- op.u.close.port = tpmif->remote_evtchn;
- op.u.close.dom = tpmif->domid;
- HYPERVISOR_event_channel_op(&op);
-
- if (tpmif->evtchn)
- unbind_evtchn_from_irqhandler(tpmif->evtchn, tpmif);
+ if (tpmif->irq)
+ unbind_evtchn_from_irqhandler(tpmif->irq, tpmif);
if (tpmif->tx) {
unmap_frontend_page(tpmif);
diff -r 805ee053e61f -r 559ad1abb3d5
linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c Thu Sep 29
12:05:43 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c Thu Sep 29
14:14:03 2005
@@ -292,8 +292,10 @@
free_page((unsigned long)tp->tx);
tp->tx = NULL;
}
- unbind_evtchn_from_irqhandler(tp->evtchn, NULL);
- tp->evtchn = 0;
+
+ if (tpm->irq)
+ unbind_evtchn_from_irqhandler(tp->irq, NULL);
+ tp->evtchn = tpm->irq = 0;
}
@@ -501,10 +503,12 @@
err = bind_evtchn_to_irqhandler(
tp->evtchn,
tpmif_int, SA_SAMPLE_RANDOM, "tpmif", tp);
- if ( err != 0 ) {
+ if ( err <= 0 ) {
WPRINTK("bind_evtchn_to_irqhandler failed (err=%d)\n", err);
return;
}
+
+ tp->irq = err;
}
static struct xenbus_device_id tpmfront_ids[] = {
diff -r 805ee053e61f -r 559ad1abb3d5
linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.h
--- a/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.h Thu Sep 29
12:05:43 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.h Thu Sep 29
14:14:03 2005
@@ -5,7 +5,7 @@
struct tpm_private
{
tpmif_tx_interface_t *tx;
- unsigned int evtchn;
+ unsigned int evtchn, irq;
int connected;
spinlock_t tx_lock;
diff -r 805ee053e61f -r 559ad1abb3d5
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c Thu Sep 29
12:05:43 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c Thu Sep 29
14:14:03 2005
@@ -43,6 +43,8 @@
u8 flags;
char buf[0];
} __attribute__((packed));
+
+static int xenbus_irq;
DECLARE_WAIT_QUEUE_HEAD(xb_waitq);
@@ -205,31 +207,27 @@
{
int err;
+ if (xenbus_irq)
+ unbind_evtchn_from_irqhandler(xenbus_irq, &xb_waitq);
+ xenbus_irq = 0;
+
if (!xen_start_info->store_evtchn)
return 0;
err = bind_evtchn_to_irqhandler(
xen_start_info->store_evtchn, wake_waiting,
0, "xenbus", &xb_waitq);
- if (err) {
+ if (err <= 0) {
printk(KERN_ERR "XENBUS request irq failed %i\n", err);
- unbind_evtchn_from_irq(xen_start_info->store_evtchn);
return err;
}
+ xenbus_irq = err;
+
/* FIXME zero out page -- domain builder should probably do this*/
memset(mfn_to_virt(xen_start_info->store_mfn), 0, PAGE_SIZE);
return 0;
-}
-
-void xb_suspend_comms(void)
-{
-
- if (!xen_start_info->store_evtchn)
- return;
-
- unbind_evtchn_from_irqhandler(xen_start_info->store_evtchn, &xb_waitq);
}
/*
diff -r 805ee053e61f -r 559ad1abb3d5
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.h
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.h Thu Sep 29
12:05:43 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.h Thu Sep 29
14:14:03 2005
@@ -30,7 +30,6 @@
int xs_init(void);
int xb_init_comms(void);
-void xb_suspend_comms(void);
/* Low level routines. */
int xb_write(const void *data, unsigned len);
diff -r 805ee053e61f -r 559ad1abb3d5
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c Thu Sep 29
12:05:43 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c Thu Sep 29
14:14:03 2005
@@ -607,7 +607,6 @@
down(&xenbus_lock);
bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, suspend_dev);
bus_for_each_dev(&xenbus_backend.bus, NULL, NULL, suspend_dev);
- xb_suspend_comms();
}
void xenbus_resume(void)
diff -r 805ee053e61f -r 559ad1abb3d5
linux-2.6-xen-sparse/include/asm-xen/evtchn.h
--- a/linux-2.6-xen-sparse/include/asm-xen/evtchn.h Thu Sep 29 12:05:43 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/evtchn.h Thu Sep 29 14:14:03 2005
@@ -51,14 +51,21 @@
extern int bind_ipi_to_irq(int ipi);
extern void unbind_ipi_from_irq(int ipi);
-/* Dynamically bind an event-channel port to Linux IRQ space. */
+/*
+ * Dynamically bind an event-channel port to Linux IRQ space.
+ * BIND: Returns IRQ or error.
+ * UNBIND: Takes IRQ to unbind from; automatically closes the event channel.
+ */
extern int bind_evtchn_to_irq(unsigned int evtchn);
-extern void unbind_evtchn_from_irq(unsigned int evtchn);
+extern void unbind_evtchn_from_irq(unsigned int irq);
/*
* Dynamically bind an event-channel port to an IRQ-like callback handler.
* On some platforms this may not be implemented via the Linux IRQ subsystem.
- * You *cannot* trust the irq argument passed to the callback handler.
+ * The IRQ argument passed to the callback handler is the same as returned
+ * from the bind call. It may not correspond to a Linux IRQ number.
+ * BIND: Returns IRQ or error.
+ * UNBIND: Takes IRQ to unbind from; automatically closes the event channel.
*/
extern int bind_evtchn_to_irqhandler(
unsigned int evtchn,
@@ -66,7 +73,7 @@
unsigned long irqflags,
const char *devname,
void *dev_id);
-extern void unbind_evtchn_from_irqhandler(unsigned int evtchn, void *dev_id);
+extern void unbind_evtchn_from_irqhandler(unsigned int irq, void *dev_id);
extern void irq_resume(void);
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|