[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] [MINIOS]Events handling cleaned up. The interface extended to provide



# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Node ID 43474e663b3d34ad2ad7de728ff25f96200aab3b
# Parent  09378a9ca8ad33fbae906100f728f81bb57dcc71
[MINIOS]Events handling cleaned up. The interface extended to provide
void* pointer to handlers.
Signed-off-by: Steven Smith <sos22@xxxxxxxxx>
Signed-off-by: Grzegorz Milos <gm281@xxxxxxxxx>
---
 extras/mini-os/console/xencons_ring.c |    5 +-
 extras/mini-os/events.c               |   84 +++++++++++++++++++++-------------
 extras/mini-os/include/events.h       |   24 ++-------
 extras/mini-os/include/lib.h          |   13 +++++
 extras/mini-os/lib/string.c           |   10 ++++
 extras/mini-os/time.c                 |    6 +-
 extras/mini-os/xenbus/xenbus.c        |    5 +-
 7 files changed, 93 insertions(+), 54 deletions(-)

diff -r 09378a9ca8ad -r 43474e663b3d extras/mini-os/console/xencons_ring.c
--- a/extras/mini-os/console/xencons_ring.c     Wed Jul 05 11:27:25 2006 +0100
+++ b/extras/mini-os/console/xencons_ring.c     Wed Jul 05 11:27:58 2006 +0100
@@ -53,7 +53,7 @@ int xencons_ring_send(const char *data, 
 
 
 
-static void handle_input(int port, struct pt_regs *regs)
+static void handle_input(int port, struct pt_regs *regs, void *ign)
 {
        struct xencons_interface *intf = xencons_interface();
        XENCONS_RING_IDX cons, prod;
@@ -83,7 +83,8 @@ int xencons_ring_init(void)
        if (!start_info.console_evtchn)
                return 0;
 
-       err = bind_evtchn(start_info.console_evtchn, handle_input);
+       err = bind_evtchn(start_info.console_evtchn, handle_input,
+                         NULL);
        if (err <= 0) {
                printk("XEN console request chn bind failed %i\n", err);
                return err;
diff -r 09378a9ca8ad -r 43474e663b3d extras/mini-os/events.c
--- a/extras/mini-os/events.c   Wed Jul 05 11:27:25 2006 +0100
+++ b/extras/mini-os/events.c   Wed Jul 05 11:27:58 2006 +0100
@@ -22,9 +22,18 @@
 #include <events.h>
 #include <lib.h>
 
+#define NR_EVS 1024
+
+/* this represents a event handler. Chaining or sharing is not allowed */
+typedef struct _ev_action_t {
+       void (*handler)(int, struct pt_regs *, void *);
+       void *data;
+    u32 count;
+} ev_action_t;
+
 
 static ev_action_t ev_actions[NR_EVS];
-void default_handler(int port, struct pt_regs *regs);
+void default_handler(int port, struct pt_regs *regs, void *data);
 
 
 /*
@@ -35,42 +44,33 @@ int do_event(u32 port, struct pt_regs *r
     ev_action_t  *action;
     if (port >= NR_EVS) {
         printk("Port number too large: %d\n", port);
-        goto out;
+               goto out;
     }
 
     action = &ev_actions[port];
     action->count++;
 
-    if (!action->handler)
-    {
-        printk("Spurious event on port %d\n", port);
-        goto out;
-    }
-    
-    if (action->status & EVS_DISABLED)
-    {
-        printk("Event on port %d disabled\n", port);
-        goto out;
-    }
-    
     /* call the handler */
-    action->handler(port, regs);
-    
+       action->handler(port, regs, action->data);
+
  out:
        clear_evtchn(port);
+
     return 1;
 
 }
 
-int bind_evtchn( u32 port, void (*handler)(int, struct pt_regs *) )
+int bind_evtchn( u32 port, void (*handler)(int, struct pt_regs *, void *),
+                                void *data )
 {
        if(ev_actions[port].handler != default_handler)
         printk("WARN: Handler for port %d already registered, replacing\n",
                                port);
 
+       ev_actions[port].data = data;
+       wmb();
        ev_actions[port].handler = handler;
-       ev_actions[port].status &= ~EVS_DISABLED;         
- 
+
        /* Finally unmask the port */
        unmask_evtchn(port);
 
@@ -82,13 +82,14 @@ void unbind_evtchn( u32 port )
        if (ev_actions[port].handler == default_handler)
                printk("WARN: No handler for port %d when unbinding\n", port);
        ev_actions[port].handler = default_handler;
-       ev_actions[port].status |= EVS_DISABLED;
+       wmb();
+       ev_actions[port].data = NULL;
 }
 
-int bind_virq( u32 virq, void (*handler)(int, struct pt_regs *) )
+int bind_virq( u32 virq, void (*handler)(int, struct pt_regs *, void *data),
+                          void *data)
 {
        evtchn_op_t op;
-       int ret = 0;
 
        /* Try to bind the virq to a port */
        op.cmd = EVTCHNOP_bind_virq;
@@ -97,13 +98,11 @@ int bind_virq( u32 virq, void (*handler)
 
        if ( HYPERVISOR_event_channel_op(&op) != 0 )
        {
-               ret = 1;
                printk("Failed to bind virtual IRQ %d\n", virq);
-               goto out;
+               return 1;
     }
-    bind_evtchn(op.u.bind_virq.port, handler); 
-out:
-       return ret;
+    bind_evtchn(op.u.bind_virq.port, handler, data);
+       return 0;
 }
 
 void unbind_virq( u32 port )
@@ -137,13 +136,38 @@ void init_events(void)
 #endif
     /* inintialise event handler */
     for ( i = 0; i < NR_EVS; i++ )
-    {
-        ev_actions[i].status  = EVS_DISABLED;
+       {
         ev_actions[i].handler = default_handler;
         mask_evtchn(i);
     }
 }
 
-void default_handler(int port, struct pt_regs *regs) {
+void default_handler(int port, struct pt_regs *regs, void *ignore)
+{
     printk("[Port %d] - event received\n", port);
 }
+
+/* Unfortunate confusion of terminology: the port is unbound as far
+   as Xen is concerned, but we automatically bind a handler to it
+   from inside mini-os. */
+int evtchn_alloc_unbound(void (*handler)(int, struct pt_regs *regs,
+                                                                               
 void *data),
+                                                void *data)
+{
+       u32 port;
+       evtchn_op_t op;
+       int err;
+
+       op.cmd = EVTCHNOP_alloc_unbound;
+       op.u.alloc_unbound.dom = DOMID_SELF;
+       op.u.alloc_unbound.remote_dom = 0;
+
+       err = HYPERVISOR_event_channel_op(&op);
+       if (err) {
+               printk("Failed to alloc unbound evtchn: %d.\n", err);
+               return -1;
+       }
+       port = op.u.alloc_unbound.port;
+       bind_evtchn(port, handler, data);
+       return port;
+}
diff -r 09378a9ca8ad -r 43474e663b3d extras/mini-os/include/events.h
--- a/extras/mini-os/include/events.h   Wed Jul 05 11:27:25 2006 +0100
+++ b/extras/mini-os/include/events.h   Wed Jul 05 11:27:58 2006 +0100
@@ -22,28 +22,18 @@
 #include<traps.h>
 #include <xen/event_channel.h>
 
-#define NR_EVS 1024
-
-/* ev handler status */
-#define EVS_INPROGRESS 1       /* Event handler active - do not enter! */
-#define EVS_DISABLED   2       /* Event disabled - do not enter! */
-#define EVS_PENDING        4   /* Event pending - replay on enable */
-#define EVS_REPLAY         8   /* Event has been replayed but not acked yet */
-
-/* this represents a event handler. Chaining or sharing is not allowed */
-typedef struct _ev_action_t {
-       void (*handler)(int, struct pt_regs *);
-    unsigned int status;               /* IRQ status */
-    u32 count;
-} ev_action_t;
-
 /* prototypes */
 int do_event(u32 port, struct pt_regs *regs);
-int bind_virq( u32 virq, void (*handler)(int, struct pt_regs *) );
-int bind_evtchn( u32 virq, void (*handler)(int, struct pt_regs *) );
+int bind_virq( u32 virq, void (*handler)(int, struct pt_regs *, void *data),
+                          void *data);
+int bind_evtchn( u32 virq, void (*handler)(int, struct pt_regs *, void *data),
+                                void *data );
 void unbind_evtchn( u32 port );
 void init_events(void);
 void unbind_virq( u32 port );
+int evtchn_alloc_unbound(void (*handler)(int, struct pt_regs *regs,
+                                                                               
 void *data),
+                                                void *data);
 
 static inline int notify_remote_via_evtchn(int port)
 {
diff -r 09378a9ca8ad -r 43474e663b3d extras/mini-os/include/lib.h
--- a/extras/mini-os/include/lib.h      Wed Jul 05 11:27:25 2006 +0100
+++ b/extras/mini-os/include/lib.h      Wed Jul 05 11:27:58 2006 +0100
@@ -89,6 +89,7 @@ char  *strchr(const char *s, int c);
 char  *strchr(const char *s, int c);
 char  *strstr(const char *s1, const char *s2);
 char * strcat(char * dest, const char * src);
+char  *strdup(const char *s);
 
 
 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
@@ -98,6 +99,18 @@ struct kvec {
     size_t iov_len;
 };
 
+#define ASSERT(x)                                              \
+do {                                                           \
+       if (!(x)) {                                                \
+               printk("ASSERTION FAILED: %s at %s:%d.\n",             \
+                          # x ,                                           \
+                          __FILE__,                                       \
+                          __LINE__);                                      \
+        BUG();                                                 \
+       }                                                          \
+} while(0)
 
+/* Consistency check as much as possible. */
+void sanity_check(void);
 
 #endif /* _LIB_H_ */
diff -r 09378a9ca8ad -r 43474e663b3d extras/mini-os/lib/string.c
--- a/extras/mini-os/lib/string.c       Wed Jul 05 11:27:25 2006 +0100
+++ b/extras/mini-os/lib/string.c       Wed Jul 05 11:27:58 2006 +0100
@@ -23,6 +23,7 @@
 #include <os.h>
 #include <types.h>
 #include <lib.h>
+#include <xmalloc.h>
 
 int memcmp(const void * cs,const void * ct,size_t count)
 {
@@ -156,4 +157,13 @@ char * strstr(const char * s1,const char
         return NULL;
 }
 
+char *strdup(const char *x)
+{
+    int l = strlen(x);
+    char *res = malloc(l + 1);
+       if (!res) return NULL;
+    memcpy(res, x, l + 1);
+    return res;
+}
+
 #endif
diff -r 09378a9ca8ad -r 43474e663b3d extras/mini-os/time.c
--- a/extras/mini-os/time.c     Wed Jul 05 11:27:25 2006 +0100
+++ b/extras/mini-os/time.c     Wed Jul 05 11:27:58 2006 +0100
@@ -215,7 +215,7 @@ void block_domain(u32 millisecs)
 /*
  * Just a dummy 
  */
-static void timer_handler(int ev, struct pt_regs *regs)
+static void timer_handler(int ev, struct pt_regs *regs, void *ign)
 {
     static int i;
 
@@ -233,5 +233,5 @@ void init_time(void)
 void init_time(void)
 {
     printk("Initialising timer interface\n");
-    bind_virq(VIRQ_TIMER, &timer_handler);
-}
+    bind_virq(VIRQ_TIMER, &timer_handler, NULL);
+}
diff -r 09378a9ca8ad -r 43474e663b3d extras/mini-os/xenbus/xenbus.c
--- a/extras/mini-os/xenbus/xenbus.c    Wed Jul 05 11:27:25 2006 +0100
+++ b/extras/mini-os/xenbus/xenbus.c    Wed Jul 05 11:27:58 2006 +0100
@@ -112,7 +112,7 @@ static void xenbus_thread_func(void *ign
     }
 }
 
-static void xenbus_evtchn_handler(int port, struct pt_regs *regs)
+static void xenbus_evtchn_handler(int port, struct pt_regs *regs, void *ign)
 {
     wake_up(&xb_waitq);
 }
@@ -174,7 +174,8 @@ void init_xenbus(void)
     create_thread("xenstore", xenbus_thread_func, NULL);
     DEBUG("buf at %p.\n", xenstore_buf);
     err = bind_evtchn(start_info.store_evtchn,
-                     xenbus_evtchn_handler);
+                     xenbus_evtchn_handler,
+              NULL);
     DEBUG("xenbus on irq %d\n", err);
 }
 

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.