]> xenbits.xensource.com Git - xenclient/ioemu.git/commitdiff
Bug fixes for the dom0_driver and the swithing code:
authorJean Guyader <jean.guyader@eu.citrix.com>
Thu, 12 Mar 2009 17:37:45 +0000 (17:37 +0000)
committerJean Guyader <jean.guyader@eu.citrix.com>
Thu, 12 Mar 2009 17:37:45 +0000 (17:37 +0000)
- If we try to switch to a crashed qemu, we fall back to the pvm.
- Add a sleep for the blanker, when we blank the screen, 100 ms.
- Support for hotplug HID device in dom0.

dom0_driver.c
hid-linux.c

index 2f593b3ae3875464973d69c2659ba90902e6b051..fa4fc161c24bd475cbb43b5133257be24cc2520c 100644 (file)
@@ -49,8 +49,9 @@ static void dom0_driver_state_change(const char *path, void *opaque);
 static void dom0_driver_command(const char *path, void *opaque);
 static void dom0_driver_leave_done(void);
 
-#define DEBUG_DOM0_DRIVER       1
-#define XS_REFRESH_INTERVAL     5000
+#define DEBUG_DOM0_DRIVER              1
+#define XS_REFRESH_INTERVAL            1000
+#define DOM0_DRIVER_SWITCH_TIMEOUT     2
 
 #define DOM0_MOUSE              1
 #define DOM0_KEYBOARD           2
@@ -58,8 +59,9 @@ static void dom0_driver_leave_done(void);
 #if DEBUG_DOM0_DRIVER
 # define DEBUG(_format_, args...)    \
     do { \
-       char *str = get_time(); \
-    fprintf(stderr, "[%s] dom0_driver(%d):%d: " _format_, str, domid, __LINE__, ## args);\
+       char *__str = get_time();       \
+    fprintf(stderr, "[%s] dom0_driver(%d):%d: " _format_, __str, domid, __LINE__, ## args);\
+       free(__str); \
     } while (false)
 #else
 # define DEBUG(_format_, args...) (void)0
@@ -192,7 +194,10 @@ static void dom0_driver_blank_changed(void)
     blank = strtol(str, NULL, 10);
     free(str);
     if (blank == 2)
+    {
+       usleep(100 * 1000); /* 100 ms */
        dom0_driver_leave_done();
+    }
 }
 static int dom0_driver_blank(void)
 {
@@ -310,17 +315,11 @@ static void dom0_gr_devices(int grab, int controller)
 
 static int dom0_dom_alive(int id)
 {
-    int *domids;
-    int len, i;
+    xc_dominfo_t info;
+    int rc;
 
-    domids = xenstore_get_domids(&len);
-    if (domids == NULL)
-       return 0;
-    for (i = 0; i < len; i++)
-       if (domids[i] == id)
-           break;
-    free(domids);
-    return (i < len);
+    rc = xc_domain_getinfo(xc_handle, id, 1, &info);
+    return rc == 1 && info.domid == id;
 }
 
 
@@ -330,18 +329,17 @@ static int dom0_driver_failover_switch(void *opaque)
     uint32_t                   t = time(NULL);
     struct dom0_driver_xs_info mouse, keyboard;
 
-    if (!vga_passthrough)
-       return 0;
-
     dom0_driver_read_xs_info(&mouse, DOM0_MOUSE);
     dom0_driver_read_xs_info(&keyboard, DOM0_KEYBOARD);
-
     if (mouse.domid == domid)
        dom0_driver_handler->probe(1);
     else
        dom0_driver_handler->probe(0);
 
-    if (mouse.state == -1)
+    if (!vga_passthrough)
+       return 0;
+
+        if (mouse.state == -1)
     {
        DEBUG("No state grab the device\n");
        dom0_gr_devices(1, DOM0_KEYBOARD);
@@ -360,6 +358,23 @@ static int dom0_driver_failover_switch(void *opaque)
        goto out;
     }
 
+    if ( keyboard.state == 2 &&
+           (t - keyboard.timestamp) > DOM0_DRIVER_SWITCH_TIMEOUT)
+    {
+       DEBUG("Keyboard in state 2 for to long, take it back\n");
+       dom0_gr_devices(1, DOM0_KEYBOARD);
+    }
+
+    if (mouse.state == 2 &&
+           (t - mouse.timestamp) > DOM0_DRIVER_SWITCH_TIMEOUT)
+    {
+       DEBUG("Mouse in state 2 for to long, take it back\n");
+       dom0_gr_devices(1, DOM0_MOUSE);
+       DEBUG("Get the focus now !\n");
+       driver.enter();
+       goto out;
+    }
+
     ret = 0;
 out:
     qemu_mod_timer(driver.xs_timer, qemu_get_clock(rt_clock) + XS_REFRESH_INTERVAL);
@@ -493,6 +508,8 @@ static void dom0_driver_switch_controller(int slot, int controller)
     int        positions[NB_SLOTS];
     char *str;
     int len;
+    int ready;
+    struct dom0_driver_xs_info info;
 
     dom0_get_positions(positions);
     if (positions[slot] == 0)
@@ -502,13 +519,24 @@ static void dom0_driver_switch_controller(int slot, int controller)
     }
 
     str = xenstore_dom_read(positions[slot], "dom0_input/ready", &len);
-    if (strcmp(str, "1") == 0)
+    ready = strtol(str, NULL, 10);
+    free(str);
+    if (ready != 1)
     {
-       dom0_driver_xs_write("new-slot", slot, controller);
-       dom0_driver_xs_write("timestamp", time(NULL), controller);
-       dom0_driver_xs_write("state", 0, controller);
+       DEBUG("Cannot switch controller %d to %d slot not ready\n", controller, slot);
+       return;
     }
-    free(str);
+
+    dom0_driver_read_xs_info(&info, controller);
+    if (info.state != 1)
+    {
+       DEBUG("Cannot switch controller %d to %d, unstable state\n", controller, slot);
+       return;
+    }
+
+    dom0_driver_xs_write("new-slot", slot, controller);
+    dom0_driver_xs_write("timestamp", time(NULL), controller);
+    dom0_driver_xs_write("state", 0, controller);
 }
 
 void dom0_driver_command(const char *path, void *opaque)
index f4613a442d6e582861f307c91c3a175e8c1c5c83..6daf5e23222776bf1049f1001940aa26519f85c9 100644 (file)
@@ -45,7 +45,8 @@
 
 #define HID_LINUX_XS_PATH              "/local/domain/0/hid_linux"
 #define ABS(x)                         ((x) > 0 ? (x) : -(x))
-#define EVENT_PATH                     "/dev/input/event"
+#define EVENT_PATH                             "/dev/input/event"
+#define HID_LINUX_MAX_DEV              16
 
 #define DEBUG_HID_LINUX
 
@@ -53,9 +54,9 @@
 # define DEBUG(_format_, args...)      \
     do \
 { \
-    char *str = get_time(); \
-    fprintf(stderr, "[%s] hid-linux(%d):%d: " _format_, str, domid, __LINE__, ## args);\
-    free(str);\
+    char *__str = get_time(); \
+    fprintf(stderr, "[%s] hid-linux(%d):%d: " _format_, (__str), domid, __LINE__, ## args);\
+    free(__str);\
 } \
 while (0);
 #else
@@ -64,9 +65,9 @@ while (0);
 
 static struct hid_linux_driver
 {
-    int                keyboard_fds[4];
-    int                mouse_fds[4];
-    char       *controller_paths[8];
+    int                keyboard_fds[HID_LINUX_MAX_DEV / 2];
+    int                mouse_fds[HID_LINUX_MAX_DEV / 2];
+    char       *controller_paths[HID_LINUX_MAX_DEV];
     int                mouse_button_state;
     int                key_status[256];
 } hid_linux_driver;
@@ -139,7 +140,6 @@ void hid_linux_add_binding(const int *tab, void (*cb)(void*), void *payload)
     hid_linux_binding[i + 1].cb = NULL;
     hid_linux_binding[i].cb = cb;
     hid_linux_binding[i].payload = payload;
-    printf("binding payload %d\n", (int)(payload));
     hid_linux_binding[i].binding = NULL;
 
     j = 0;
@@ -333,12 +333,21 @@ static void hid_linux_read(void *opaque)
 }
 
 static int hid_linux_grab_devices(int grab, int *fd)
-{      
-    assert(fd != NULL);
+{
+    int rc = 0;
+
+    assert(fd != NULL && *fd != -1);
     for (; *fd != -1; fd++)
     {
-       if (ioctl(*fd, EVIOCGRAB, grab) == -1)
+       if ((rc = ioctl(*fd, EVIOCGRAB, grab)) == -1)
+       {
+           char *er;
+           er = strerror(errno);
+           DEBUG("ioctl(%d, EVOCGRAB) failed, %s\n", *fd, er);
            return 0;
+       }
+
+       DEBUG("ioctl(%d, EVOCGRAB) succed\n", *fd);
 
        if (grab)
            qemu_set_fd_handler(*fd, hid_linux_read, NULL, fd);
@@ -395,16 +404,19 @@ void hid_linux_probe(int grab)
     {
        sprintf(path, "%s%i", EVENT_PATH, i++);
 
-       if ((fd = open(path, O_RDONLY)) == -1)
+       if (stat(path, &st) == -1)
            break;
 
-       for ( c = 0; c < 8 && hid_linux_driver.controller_paths[c]; c++)
+       for ( c = 0; c < HID_LINUX_MAX_DEV && hid_linux_driver.controller_paths[c]; c++)
            if (!strcmp(hid_linux_driver.controller_paths[c], path))
                break;
-       assert(c != 8);
+       assert(c != HID_LINUX_MAX_DEV);
        if (hid_linux_driver.controller_paths[c])
            continue;
-       
+
+       if ((fd = open(path, O_RDONLY)) == -1)
+           break;
+
        if (ioctl(fd, EVIOCGNAME(128), name) == -1)
        {
            DEBUG("Input get name failed on %s\n", path);
@@ -413,32 +425,39 @@ void hid_linux_probe(int grab)
 
        if (strcasestr(name, "keyboard"))
        {
-           DEBUG("Add %s as a keyboard\n", name);
+           DEBUG("Add %s %s as a keyboard, fd=%d\n", path, name, fd);
            controllers = hid_linux_driver.keyboard_fds;
        }
        else
        {
-           DEBUG("Add %s as a mouse\n", name);
+           DEBUG("Add %s %s as a mouse, fd=%d\n", path, name, fd);
            controllers = hid_linux_driver.mouse_fds;
        }
 
-       for ( j = 0; j < 4 && controllers[j] != -1; j++)
+       for ( j = 0; j < (HID_LINUX_MAX_DEV / 2) && controllers[j] != -1; j++)
            ;
-       assert(j != 4);
-           
+       assert(j != (HID_LINUX_MAX_DEV / 2));
+
        controllers[j] = fd;
        controllers[j + 1] = -1;
-       hid_linux_driver.controller_paths[c] = strdup(path);
-       hid_linux_driver.controller_paths[c + 1] = NULL; 
 
        if (grab)
        {
-           DEBUG("Grab device %s\n", name);
-           hid_linux_grab_devices(0, controllers);
+           if (!hid_linux_grab_devices(1, controllers + j))
+           {
+               DEBUG("Grabing failed, try next time...\n");
+               controllers[j] = -1;
+               break;
+           }
        }
+
+       hid_linux_driver.controller_paths[c] = strdup(path);
+       hid_linux_driver.controller_paths[c + 1] = NULL;
+
        fd = -1;
     }
-    close(fd);
+    if (fd != -1)
+       close(fd);
 }
 
 void hid_linux_init(void)