diff options
author | awilliam@xenbuild2.aw <awilliam@xenbuild2.aw> | 2007-01-10 08:40:47 -0700 |
---|---|---|
committer | awilliam@xenbuild2.aw <awilliam@xenbuild2.aw> | 2007-01-10 08:40:47 -0700 |
commit | a77c31c882ce9be75f2c4b8e09405bd1c9fd1cb9 (patch) | |
tree | 6765cb9b976e23af888506ec7a2456528ca56fff /unmodified_drivers/linux-2.6/platform-pci | |
parent | 6ed3af384fe8be0982eaf8ab841b41ed578761a7 (diff) | |
parent | 5fc32d22f2975d14e23fdbdab6db2e6297a47869 (diff) | |
download | xen-a77c31c882ce9be75f2c4b8e09405bd1c9fd1cb9.tar.gz xen-a77c31c882ce9be75f2c4b8e09405bd1c9fd1cb9.tar.bz2 xen-a77c31c882ce9be75f2c4b8e09405bd1c9fd1cb9.zip |
merge with xen-unstable.hg
Diffstat (limited to 'unmodified_drivers/linux-2.6/platform-pci')
-rw-r--r-- | unmodified_drivers/linux-2.6/platform-pci/evtchn.c | 69 |
1 files changed, 52 insertions, 17 deletions
diff --git a/unmodified_drivers/linux-2.6/platform-pci/evtchn.c b/unmodified_drivers/linux-2.6/platform-pci/evtchn.c index e328cf9663..9cf5972f0d 100644 --- a/unmodified_drivers/linux-2.6/platform-pci/evtchn.c +++ b/unmodified_drivers/linux-2.6/platform-pci/evtchn.c @@ -43,12 +43,18 @@ void *shared_info_area; #define MAX_EVTCHN 256 -static struct -{ +static struct { irqreturn_t(*handler) (int, void *, struct pt_regs *); void *dev_id; + int close; /* close on unbind_from_irqhandler()? */ } evtchns[MAX_EVTCHN]; +int irq_to_evtchn_port(int irq) +{ + return irq; +} +EXPORT_SYMBOL(irq_to_evtchn_port); + void mask_evtchn(int port) { shared_info_t *s = shared_info_area; @@ -94,22 +100,48 @@ void unmask_evtchn(int port) } EXPORT_SYMBOL(unmask_evtchn); -int -bind_evtchn_to_irqhandler(unsigned int evtchn, - irqreturn_t(*handler) (int, void *, - struct pt_regs *), - unsigned long irqflags, const char *devname, - void *dev_id) +int bind_listening_port_to_irqhandler( + unsigned int remote_domain, + irqreturn_t (*handler)(int, void *, struct pt_regs *), + unsigned long irqflags, + const char *devname, + void *dev_id) { - if (evtchn >= MAX_EVTCHN) + struct evtchn_alloc_unbound alloc_unbound; + int err; + + alloc_unbound.dom = DOMID_SELF; + alloc_unbound.remote_dom = remote_domain; + + err = HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound, + &alloc_unbound); + if (err) + return err; + + evtchns[alloc_unbound.port].handler = handler; + evtchns[alloc_unbound.port].dev_id = dev_id; + evtchns[alloc_unbound.port].close = 1; + unmask_evtchn(alloc_unbound.port); + return alloc_unbound.port; +} +EXPORT_SYMBOL(bind_listening_port_to_irqhandler); + +int bind_caller_port_to_irqhandler( + unsigned int caller_port, + irqreturn_t (*handler)(int, void *, struct pt_regs *), + unsigned long irqflags, + const char *devname, + void *dev_id) +{ + if (caller_port >= MAX_EVTCHN) return -EINVAL; - evtchns[evtchn].handler = handler; - evtchns[evtchn].dev_id = dev_id; - unmask_evtchn(evtchn); - return evtchn; + evtchns[caller_port].handler = handler; + evtchns[caller_port].dev_id = dev_id; + evtchns[caller_port].close = 0; + unmask_evtchn(caller_port); + return caller_port; } - -EXPORT_SYMBOL(bind_evtchn_to_irqhandler); +EXPORT_SYMBOL(bind_caller_port_to_irqhandler); void unbind_from_irqhandler(unsigned int evtchn, void *dev_id) { @@ -118,8 +150,12 @@ void unbind_from_irqhandler(unsigned int evtchn, void *dev_id) mask_evtchn(evtchn); evtchns[evtchn].handler = NULL; -} + if (evtchns[evtchn].close) { + struct evtchn_close close = { .port = evtchn }; + HYPERVISOR_event_channel_op(EVTCHNOP_close, &close); + } +} EXPORT_SYMBOL(unbind_from_irqhandler); void notify_remote_via_irq(int irq) @@ -127,7 +163,6 @@ void notify_remote_via_irq(int irq) int evtchn = irq; notify_remote_via_evtchn(evtchn); } - EXPORT_SYMBOL(notify_remote_via_irq); irqreturn_t evtchn_interrupt(int irq, void *dev_id, struct pt_regs *regs) |