From: Jean Guyader Date: Thu, 12 Mar 2009 17:37:45 +0000 (+0000) Subject: Bug fixes for the dom0_driver and the swithing code: X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=d48832f19ac3f780c7d7d195257876d7c2bd66e5;p=xenclient%2Fioemu.git Bug fixes for the dom0_driver and the swithing code: - 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. --- diff --git a/dom0_driver.c b/dom0_driver.c index 2f593b3a..fa4fc161 100644 --- a/dom0_driver.c +++ b/dom0_driver.c @@ -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) diff --git a/hid-linux.c b/hid-linux.c index f4613a44..6daf5e23 100644 --- a/hid-linux.c +++ b/hid-linux.c @@ -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)