# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxxx
# Date 1167566387 0
# Node ID dbddea768e2933b7379d1f10a410081f4946f33f
# Parent d275951acf103aed23293ddc9313d5af5c3406b8
[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@xxxxxxxxxxxxx>
---
unmodified_drivers/linux-2.6/platform-pci/evtchn.c | 63 +++++++++++++++------
1 files changed, 46 insertions(+), 17 deletions(-)
diff -r d275951acf10 -r dbddea768e29
unmodified_drivers/linux-2.6/platform-pci/evtchn.c
--- a/unmodified_drivers/linux-2.6/platform-pci/evtchn.c Sat Dec 30
18:23:27 2006 +0000
+++ b/unmodified_drivers/linux-2.6/platform-pci/evtchn.c Sun Dec 31
11:59:47 2006 +0000
@@ -43,10 +43,10 @@ void *shared_info_area;
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
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)
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|