aboutsummaryrefslogtreecommitdiffstats
path: root/unmodified_drivers
diff options
context:
space:
mode:
authorkaf24@localhost.localdomain <kaf24@localhost.localdomain>2006-12-31 11:59:47 +0000
committerkaf24@localhost.localdomain <kaf24@localhost.localdomain>2006-12-31 11:59:47 +0000
commit41eabc3d5cc84c6dec54da6d9d6bc127b47fbb52 (patch)
tree9a48b1883f7ad2b80c3d84ced0aa71e84617b53d /unmodified_drivers
parent47fad056d3cc74b40c22d4f6b52452ac2a6963e5 (diff)
downloadxen-41eabc3d5cc84c6dec54da6d9d6bc127b47fbb52.tar.gz
xen-41eabc3d5cc84c6dec54da6d9d6bc127b47fbb52.tar.bz2
xen-41eabc3d5cc84c6dec54da6d9d6bc127b47fbb52.zip
[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>
Diffstat (limited to 'unmodified_drivers')
-rw-r--r--unmodified_drivers/linux-2.6/platform-pci/evtchn.c63
1 files changed, 46 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..7ad340074a 100644
--- a/unmodified_drivers/linux-2.6/platform-pci/evtchn.c
+++ b/unmodified_drivers/linux-2.6/platform-pci/evtchn.c
@@ -43,10 +43,10 @@
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];
void mask_evtchn(int port)
@@ -94,22 +94,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 +144,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 +157,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)