ia64/xen-unstable
changeset 13234:dbddea768e29
[PV-ON-HVM] Update evtchn interface to match new PV Linux interfaces.
Also fix unbind_from_irqhandler() to close event-channel port where
that is appropriate.
Signed-off-by: Keir Fraser <keir@xensource.com>
Also fix unbind_from_irqhandler() to close event-channel port where
that is appropriate.
Signed-off-by: Keir Fraser <keir@xensource.com>
author | kaf24@localhost.localdomain |
---|---|
date | Sun Dec 31 11:59:47 2006 +0000 (2006-12-31) |
parents | d275951acf10 |
children | 4fc6ffff2ac5 |
files | unmodified_drivers/linux-2.6/platform-pci/evtchn.c |
line diff
1.1 --- a/unmodified_drivers/linux-2.6/platform-pci/evtchn.c Sat Dec 30 18:23:27 2006 +0000 1.2 +++ b/unmodified_drivers/linux-2.6/platform-pci/evtchn.c Sun Dec 31 11:59:47 2006 +0000 1.3 @@ -43,10 +43,10 @@ 1.4 void *shared_info_area; 1.5 1.6 #define MAX_EVTCHN 256 1.7 -static struct 1.8 -{ 1.9 +static struct { 1.10 irqreturn_t(*handler) (int, void *, struct pt_regs *); 1.11 void *dev_id; 1.12 + int close; /* close on unbind_from_irqhandler()? */ 1.13 } evtchns[MAX_EVTCHN]; 1.14 1.15 void mask_evtchn(int port) 1.16 @@ -94,22 +94,48 @@ void unmask_evtchn(int port) 1.17 } 1.18 EXPORT_SYMBOL(unmask_evtchn); 1.19 1.20 -int 1.21 -bind_evtchn_to_irqhandler(unsigned int evtchn, 1.22 - irqreturn_t(*handler) (int, void *, 1.23 - struct pt_regs *), 1.24 - unsigned long irqflags, const char *devname, 1.25 - void *dev_id) 1.26 +int bind_listening_port_to_irqhandler( 1.27 + unsigned int remote_domain, 1.28 + irqreturn_t (*handler)(int, void *, struct pt_regs *), 1.29 + unsigned long irqflags, 1.30 + const char *devname, 1.31 + void *dev_id) 1.32 { 1.33 - if (evtchn >= MAX_EVTCHN) 1.34 + struct evtchn_alloc_unbound alloc_unbound; 1.35 + int err; 1.36 + 1.37 + alloc_unbound.dom = DOMID_SELF; 1.38 + alloc_unbound.remote_dom = remote_domain; 1.39 + 1.40 + err = HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound, 1.41 + &alloc_unbound); 1.42 + if (err) 1.43 + return err; 1.44 + 1.45 + evtchns[alloc_unbound.port].handler = handler; 1.46 + evtchns[alloc_unbound.port].dev_id = dev_id; 1.47 + evtchns[alloc_unbound.port].close = 1; 1.48 + unmask_evtchn(alloc_unbound.port); 1.49 + return alloc_unbound.port; 1.50 +} 1.51 +EXPORT_SYMBOL(bind_listening_port_to_irqhandler); 1.52 + 1.53 +int bind_caller_port_to_irqhandler( 1.54 + unsigned int caller_port, 1.55 + irqreturn_t (*handler)(int, void *, struct pt_regs *), 1.56 + unsigned long irqflags, 1.57 + const char *devname, 1.58 + void *dev_id) 1.59 +{ 1.60 + if (caller_port >= MAX_EVTCHN) 1.61 return -EINVAL; 1.62 - evtchns[evtchn].handler = handler; 1.63 - evtchns[evtchn].dev_id = dev_id; 1.64 - unmask_evtchn(evtchn); 1.65 - return evtchn; 1.66 + evtchns[caller_port].handler = handler; 1.67 + evtchns[caller_port].dev_id = dev_id; 1.68 + evtchns[caller_port].close = 0; 1.69 + unmask_evtchn(caller_port); 1.70 + return caller_port; 1.71 } 1.72 - 1.73 -EXPORT_SYMBOL(bind_evtchn_to_irqhandler); 1.74 +EXPORT_SYMBOL(bind_caller_port_to_irqhandler); 1.75 1.76 void unbind_from_irqhandler(unsigned int evtchn, void *dev_id) 1.77 { 1.78 @@ -118,8 +144,12 @@ void unbind_from_irqhandler(unsigned int 1.79 1.80 mask_evtchn(evtchn); 1.81 evtchns[evtchn].handler = NULL; 1.82 + 1.83 + if (evtchns[evtchn].close) { 1.84 + struct evtchn_close close = { .port = evtchn }; 1.85 + HYPERVISOR_event_channel_op(EVTCHNOP_close, &close); 1.86 + } 1.87 } 1.88 - 1.89 EXPORT_SYMBOL(unbind_from_irqhandler); 1.90 1.91 void notify_remote_via_irq(int irq) 1.92 @@ -127,7 +157,6 @@ void notify_remote_via_irq(int irq) 1.93 int evtchn = irq; 1.94 notify_remote_via_evtchn(evtchn); 1.95 } 1.96 - 1.97 EXPORT_SYMBOL(notify_remote_via_irq); 1.98 1.99 irqreturn_t evtchn_interrupt(int irq, void *dev_id, struct pt_regs *regs)