diff options
author | kaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk> | 2005-10-07 11:54:38 +0100 |
---|---|---|
committer | kaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk> | 2005-10-07 11:54:38 +0100 |
commit | 5bd7984820b32f2a5c4571255907f9bba0e3a8a5 (patch) | |
tree | 844e6b87302257d79b8d109723eb9ddd2763618f | |
parent | e8c790c70c319ada47554e4e089b896e92186e73 (diff) | |
download | xen-5bd7984820b32f2a5c4571255907f9bba0e3a8a5.tar.gz xen-5bd7984820b32f2a5c4571255907f9bba0e3a8a5.tar.bz2 xen-5bd7984820b32f2a5c4571255907f9bba0e3a8a5.zip |
Remove bind_evtchn_to_irq/unbind_evtchn_from_irq from the
evtchn kernel interface. Fix error path in bind_evtchn_to_irqhandler.
Fix backend drivers to avoid double freeing IRQs.
Signed-off-by: Keir Fraser <keir@xensource.com>
5 files changed, 25 insertions, 28 deletions
diff --git a/linux-2.6-xen-sparse/arch/ia64/xen/drivers/evtchn_ia64.c b/linux-2.6-xen-sparse/arch/ia64/xen/drivers/evtchn_ia64.c index e5c3a50f78..f6e6c9ee72 100644 --- a/linux-2.6-xen-sparse/arch/ia64/xen/drivers/evtchn_ia64.c +++ b/linux-2.6-xen-sparse/arch/ia64/xen/drivers/evtchn_ia64.c @@ -67,12 +67,6 @@ void unbind_evtchn_from_irqhandler(unsigned int evtchn, void *dev_id) evtchns[evtchn].handler = NULL; } -void unbind_evtchn_from_irq(unsigned int evtchn) -{ - printk("unbind_evtchn_from_irq called... FIXME??\n"); - while(1); -} - irqreturn_t evtchn_interrupt(int irq, void *dev_id, struct pt_regs *regs) { u32 l1, l2; diff --git a/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c b/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c index a709dd4198..6a85441f7f 100644 --- a/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c +++ b/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c @@ -296,7 +296,7 @@ void unbind_ipi_from_irq(int ipi) } EXPORT_SYMBOL(unbind_ipi_from_irq); -int bind_evtchn_to_irq(unsigned int evtchn) +static int bind_evtchn_to_irq(unsigned int evtchn) { int irq; @@ -314,9 +314,8 @@ int bind_evtchn_to_irq(unsigned int evtchn) return irq; } -EXPORT_SYMBOL(bind_evtchn_to_irq); -void unbind_evtchn_from_irq(unsigned int irq) +static void unbind_evtchn_from_irq(unsigned int irq) { evtchn_op_t op = { .cmd = EVTCHNOP_close }; int evtchn = irq_to_evtchn[irq]; @@ -333,7 +332,6 @@ void unbind_evtchn_from_irq(unsigned int irq) spin_unlock(&irq_mapping_update_lock); } -EXPORT_SYMBOL(unbind_evtchn_from_irq); int bind_evtchn_to_irqhandler( unsigned int evtchn, @@ -347,8 +345,10 @@ int bind_evtchn_to_irqhandler( irq = bind_evtchn_to_irq(evtchn); retval = request_irq(irq, handler, irqflags, devname, dev_id); - if (retval != 0) + if (retval != 0) { unbind_evtchn_from_irq(irq); + return retval; + } return irq; } diff --git a/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c b/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c index 458d6e9c36..ee1889a09a 100644 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c @@ -74,6 +74,10 @@ int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn) .u.bind_interdomain.remote_dom = blkif->domid, .u.bind_interdomain.remote_port = evtchn }; + /* Already connected through? */ + if (blkif->irq) + return 0; + if ( (blkif->blk_ring_area = alloc_vm_area(PAGE_SIZE)) == NULL ) return -ENOMEM; @@ -107,8 +111,12 @@ static void free_blkif(void *arg) { blkif_t *blkif = (blkif_t *)arg; - if (blkif->irq) - unbind_evtchn_from_irqhandler(blkif->irq, blkif); + /* Already disconnected? */ + if (!blkif->irq) + return; + + unbind_evtchn_from_irqhandler(blkif->irq, blkif); + blkif->irq = 0; vbd_free(&blkif->vbd); diff --git a/linux-2.6-xen-sparse/drivers/xen/netback/interface.c b/linux-2.6-xen-sparse/drivers/xen/netback/interface.c index 3e4537c90f..43f516badf 100644 --- a/linux-2.6-xen-sparse/drivers/xen/netback/interface.c +++ b/linux-2.6-xen-sparse/drivers/xen/netback/interface.c @@ -183,6 +183,10 @@ int netif_map(netif_t *netif, unsigned long tx_ring_ref, .u.bind_interdomain.remote_dom = netif->domid, .u.bind_interdomain.remote_port = evtchn }; + /* Already connected through? */ + if (netif->irq) + return 0; + netif->comms_area = alloc_vm_area(2*PAGE_SIZE); if (netif->comms_area == NULL) return -ENOMEM; @@ -227,13 +231,12 @@ static void free_netif_callback(void *arg) { netif_t *netif = (netif_t *)arg; - /* - * 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. - */ - if (netif->irq) - unbind_evtchn_from_irqhandler(netif->irq, netif); + /* Already disconnected? */ + if (!netif->irq) + return; + + unbind_evtchn_from_irqhandler(netif->irq, netif); + netif->irq = 0; unregister_netdev(netif->dev); diff --git a/linux-2.6-xen-sparse/include/asm-xen/evtchn.h b/linux-2.6-xen-sparse/include/asm-xen/evtchn.h index c9feb34606..a38b8732a1 100644 --- a/linux-2.6-xen-sparse/include/asm-xen/evtchn.h +++ b/linux-2.6-xen-sparse/include/asm-xen/evtchn.h @@ -52,14 +52,6 @@ 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. - * 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 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. * The IRQ argument passed to the callback handler is the same as returned |