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 EVENT_PATH "/dev/input/event"
#define XS_REFRESH_INTERVAL 5000
#define DOM0_MOUSE 1
#if DEBUG_DOM0_DRIVER
# define DEBUG(_format_, args...) \
- fprintf(stderr, "dom0_driver(%d):%d: " _format_, domid, __LINE__, ## args)
+ do { \
+ char *str = get_time(); \
+ fprintf(stderr, "[%s] dom0_driver(%d):%d: " _format_, str, domid, __LINE__, ## args);\
+ } while (false)
#else
# define DEBUG(_format_, args...) (void)0
#endif
#define NB_SLOTS 10
-#define ABS(x) ((x) > 0 ? (x) : -(x))
-
static void dom0_read(void *opaque);
static void dom0_driver_reset_keyboard(void);
static void dom0_read_secure(void *opaque);
-
struct dom0_driver
{
- int keyboard_fds[4];
- int mouse_fds[4];
- int mouse_button_state;
QEMUTimer *xs_timer;
- uint8_t scroll_lock_count;
- int key_status[256];
int secure_fd;
+ int (*enter)(void);
+ int (*leave)(void);
+};
+
+struct dom0_driver_handler
+{
+ void (*init)(void);
+ void (*probe)(int);
+ int (*grab_keyboard)(int);
+ int (*grab_mouse)(int);
+ void (*secure_keyboard)(void (*)(int));
+ void (*reset_keyboard)(void);
+ void (*add_binding)(const int *, void (*)(void *), void *);
};
struct dom0_driver_xs_info
{
- int state;
- int domid;
- int leaving_dir;
- int new_slot;
- int timestamp;
+ int state;
+ int domid;
+ int new_slot;
+ int timestamp;
+ int pre;
+};
+
+static struct dom0_driver_handler dom0_driver_hid_linux =
+{
+ .init = hid_linux_init,
+ .probe = hid_linux_probe,
+ .grab_keyboard = hid_linux_grab_keyboard,
+ .grab_mouse = hid_linux_grab_mouse,
+ .secure_keyboard = hid_linux_secure_keyboard,
+ .reset_keyboard = hid_linux_reset_keyboard,
+ .add_binding = hid_linux_add_binding,
};
static struct dom0_driver driver;
+static struct dom0_driver_handler *dom0_driver_handler = NULL;
static int dom0_driver_xs_read_dom0(const char *key)
{
if (!(str = xenstore_read_dom0_driver(key)))
{
- fprintf(stderr, "dom0_driver: the node %s don't exits\n", key);
- exit(2);
+ fprintf(stderr, "dom0_driver: fatal the node %s don't exits\n", key);
+ exit(2);
}
return strtol(str, NULL, 10);
}
-static void dom0_driver_redirect_fds(IOHandler *callback)
-{
- int *fd = 0;
-
- DEBUG("Redirect fds\n");
-
- fd = driver.keyboard_fds;
- while (*fd != -1)
- {
- qemu_set_fd_handler(*fd, callback, NULL, fd);
- fd++;
- }
- fd = driver.mouse_fds;
- while (*fd != -1)
- {
- qemu_set_fd_handler(*fd, callback, NULL, fd);
- fd++;
- }
- if (callback == dom0_read)
- {
- DEBUG("End of the secure mode\n");
- close(driver.secure_fd);
- }
-}
-
static void dom0_driver_read_xs_info(struct dom0_driver_xs_info *info,
- int controller)
+ int controller)
{
char *str = NULL;
char path[128];
int val[10];
- const char *key[] = {"state", "domid", "new-slot", "timestamp"};
+ const char *key[] = {"state", "domid", "new-slot", "timestamp", "pre"};
memset(info, -1, sizeof (struct dom0_driver_xs_info));
for (int i = 0; i < sizeof (key) / sizeof (key[0]); i++)
{
- if (controller == DOM0_MOUSE)
- sprintf(path, "mouse/%s", key[i]);
- else if (controller == DOM0_KEYBOARD)
- sprintf(path, "keyboard/%s", key[i]);
- else
- {
- fprintf(stderr, "dom0_driver unknown controller type\n");
- exit(2);
- }
-
- val[i] = -1;
- if ((str = xenstore_read_dom0_driver(path)))
- {
- val[i] = strtol(str, NULL, 10);
- free(str);
- }
+ if (controller == DOM0_MOUSE)
+ sprintf(path, "mouse/%s", key[i]);
+ else if (controller == DOM0_KEYBOARD)
+ sprintf(path, "keyboard/%s", key[i]);
+ else
+ {
+ fprintf(stderr, "dom0_driver unknown controller type\n");
+ exit(2);
+ }
+
+ val[i] = -1;
+ if ((str = xenstore_read_dom0_driver(path)))
+ {
+ val[i] = strtol(str, NULL, 10);
+ free(str);
+ }
}
info->state = val[0];
info->domid = val[1];
info->new_slot = val[2];
info->timestamp = val[3];
+ info->pre = val[4];
}
static void dom0_driver_xs_write(const char *key, int val, int controller)
char path[256], str[20];
if (controller == DOM0_MOUSE)
- sprintf(path, "mouse/%s", key);
+ sprintf(path, "mouse/%s", key);
else if (controller == DOM0_KEYBOARD)
- sprintf(path, "keyboard/%s", key);
+ sprintf(path, "keyboard/%s", key);
else
{
- DEBUG("unknown controller type\n");
- exit(2);
+ DEBUG("unknown controller type\n");
+ exit(2);
}
sprintf(str, "%d", val);
- xenstore_write_dom0_driver(path, str);
DEBUG("write %s=%d\n", path, val);
+ xenstore_write_dom0_driver(path, str);
+}
+
+/*
+** Blanker fonctions
+*/
+static void dom0_driver_blank_changed(void)
+{
+ char *str;
+ int blank;
+
+ if (!(str = xenstore_read_dom0_driver("blank")))
+ return;
+ blank = strtol(str, NULL, 10);
+ free(str);
+ if (blank == 2)
+ dom0_driver_leave_done();
+}
+static int dom0_driver_blank(void)
+{
+ xenstore_write_dom0_driver("blank", "1");
+ return 0;
+}
+static int dom0_driver_unblank(void)
+{
+ xenstore_write_dom0_driver("blank", "0");
+ return 0;
}
-static int dom0_windows_key_switch(int code, int keycode)
+static void dom0_driver_key_switch(int new_slot)
{
- int new_slot = 0;
struct dom0_driver_xs_info info;
char buff[128];
dom0_driver_read_xs_info(&info, DOM0_MOUSE);
- if (info.state == 0)
- return 0;
+ assert(info.state == 1);
- if (driver.key_status[KEY_LEFTCTRL] && keycode != KEY_LEFTCTRL)
- {
- switch (keycode)
- {
- case KEY_1:
- DEBUG("1 pressed switch to new-slot 1\n");
- new_slot = 1;
- break;
- case KEY_2:
- DEBUG("2 pressed switch to new-slot 2\n");
- new_slot = 2;
- break;
- case KEY_3:
- DEBUG("3 pressed switch to new-slot 3\n");
- new_slot = 3;
- break;
- case KEY_4:
- DEBUG("4 pressed switch to new-slot 4\n");
- new_slot = 4;
- break;
- default:
- return 0;
- }
- sprintf(buff, "switch %d", new_slot);
-
- DEBUG("Write \"%s\" into xenstore\n", buff);
- xenstore_write_dom0_driver("command", buff);
-
- return 1;
- }
+ sprintf(buff, "switch %d", new_slot);
- return 0;
+ DEBUG("Write \"%s\" into xenstore\n", buff);
+ xenstore_write_dom0_driver("command", buff);
}
-static void dom0_key_inject(int code, uint32_t keycode)
+static void dom0_driver_key_switch_1(void)
{
- int first = 0;
-
- driver.key_status[keycode] = code;
-
- switch (keycode)
- {
- case KEY_F11: keycode = 0X57; break; /* F11 */
- case KEY_F12: keycode = 0X58; break; /* F12 */
- case KEY_INSERT: keycode = 0X52; break;
- case KEY_HOME: keycode = 0X47; break;
- case KEY_PAGEUP: keycode = 0X49; break;
- case KEY_DELETE: keycode = 0X53; break;
- case KEY_END: keycode = 0X4F; break;
- case KEY_PAGEDOWN: keycode = 0x51; break;
- case KEY_UP: keycode = 0X48; break;
- case KEY_LEFT: keycode = 0X4B; break;
- case KEY_DOWN: keycode = 0X50; break;
- case KEY_RIGHT: keycode = 0X4D; break;
- case KEY_RIGHTALT: keycode = 0x38; first = 0xe0; break;
- case KEY_LEFTMETA: keycode = 0x5B; first = 0xe0; break;
- case KEY_RIGHTMETA: keycode = 0x5C; first = 0xe0; break;
- }
-
- if (first)
- kbd_put_keycode(first);
-
- if (code == 0)
- kbd_put_keycode(keycode | 0x80);
- else
- kbd_put_keycode(keycode & 0x7f);
+ dom0_driver_key_switch(1);
}
-static void dom0_driver_detect_secure_auth(int keycode)
+static void dom0_driver_read_secure(int ascii)
{
- if ((driver.key_status[KEY_LEFTCTRL] || driver.key_status[KEY_RIGHTCTRL]) &&
- (driver.key_status[KEY_LEFTALT] || driver.key_status[KEY_RIGHTALT]) &&
- (driver.key_status[KEY_BACKSPACE]))
+ int write_sz;
+
+ if (ascii)
{
- struct stat s;
- int sas_ascii = 1, ret = 0;;
-
- DEBUG("Received SAS keystroke\n");
- if ((driver.secure_fd = open("/var/lib/xenmgr/keys", O_WRONLY)) > 0)
- {
- DEBUG("write SAS ascii code\n");
- if ((ret = write(driver.secure_fd, &sas_ascii, 1)) == 1)
- {
- DEBUG("Redirect fds to secure callback\n");
- dom0_driver_redirect_fds(dom0_read_secure);
- }
- DEBUG("writing SAS ret %d\n", ret);
-
- }
- else
- DEBUG("xenmgr file is not there\n");
+ DEBUG("Send %d to xenmgr\n", ascii);
+ write_sz = write(driver.secure_fd, &ascii, 1);
+ if (ascii == -1 || ascii == 27 || write_sz != 1)
+ {
+ dom0_driver_handler->reset_keyboard();
+ dom0_driver_handler->secure_keyboard(NULL);
+ return;
+ }
}
}
-static void dom0_key_event(int code, uint32_t keycode)
+static void dom0_driver_detect_secure_auth(void)
{
- int shift_keys = 0;
- uint8_t esc = 0;
- struct dom0_driver_xs_info keyboard;
+ struct stat s;
+ int sas_ascii = 1, ret = 0;;
- if (code != 2)
+ DEBUG("Received SAS keystroke\n");
+ if ((driver.secure_fd = open("/var/lib/xenmgr/keys", O_WRONLY)) > 0)
{
- if (dom0_windows_key_switch(code, keycode))
- return;
- if (vga_passthrough)
- dom0_driver_detect_secure_auth(keycode);
- }
+ DEBUG("write SAS ascii code\n");
+ if ((ret = write(driver.secure_fd, &sas_ascii, 1)) == 1)
+ {
+ DEBUG("Redirect fds to secure callback\n");
+ dom0_driver_handler->secure_keyboard(dom0_driver_read_secure);
+ }
+ DEBUG("writing SAS ret %d\n", ret);
- dom0_driver_read_xs_info(&keyboard, DOM0_KEYBOARD);
- if (keyboard.state == 0)
- {
- dom0_driver_xs_write("state", 1, DOM0_KEYBOARD);
- dom0_driver_xs_write("domid", domid, DOM0_KEYBOARD);
}
-
-
- dom0_key_inject(code, keycode);
-}
-
-static void dom0_driver_reset_keyboard(void)
-{
- int i = 0;
-
- for (i = 0; i < 256; i++)
- if (driver.key_status[i])
- dom0_key_inject(0, i);
+ else
+ DEBUG("xenmgr file is not there\n");
}
static void dom0_get_positions(int *positions)
int pos = 0;
for (int i = 0; i < NB_SLOTS; i++)
- positions[i] = 0;
+ positions[i] = 0;
/* Get all the positions */
domids = xenstore_get_domids(&num);
for (int i = 0; i < num; i++)
- if (domids[i])
- {
- if (!(tmp = xenstore_dom_read(domids[i], "dom0_input/pos", &len)))
- continue;
- pos = strtol(tmp, NULL, 10);
- free(tmp);
-
- positions[pos] = domids[i];
- }
- free(domids);
-}
-
-static const int ascii2keycode_table[] =
-{
- KEY_A, KEY_B, KEY_C, KEY_D, KEY_E, KEY_F, KEY_G, KEY_H, KEY_I, KEY_J, KEY_K,
- KEY_L, KEY_M, KEY_N, KEY_O, KEY_P, KEY_Q, KEY_R, KEY_S, KEY_T, KEY_U,
- KEY_V, KEY_W, KEY_X, KEY_Y, KEY_Z
-};
-
-static char keycode2ascii(int keycode)
-{
- int i = 0;
-
- for (i = 0; i < sizeof (ascii2keycode_table) / sizeof (int); i++)
- if (ascii2keycode_table[i] == keycode)
- return i + 'a';
- return 0;
-}
-
-static int ascii2keycode(char ascii)
-{
- return ascii2keycode_table[ascii - 'a'];
-}
-
-static void dom0_read_secure(void *opaque)
-{
- int fd = *(int *)opaque;
- struct input_event event[5];
- int read_sz, write_sz = 1, i;
- char ascii = 0;
-
- read_sz = read(fd, event, sizeof (event));
- for (i = 0; i < read_sz / sizeof (struct input_event); i++)
- if (event[i].type == EV_KEY && event[i].value)
- {
- switch (event[i].code)
- {
- case KEY_ESC: ascii = 27; break;
- case KEY_BACKSPACE: ascii = 8; break;
- case KEY_ENTER: ascii = 10; break;
- case KEY_LEFT: ascii = 17; break;
- case KEY_RIGHT: ascii = 18; break;
- case KEY_DELETE: ascii = 127; break;
- case KEY_HOME: ascii = 2; break;
- case KEY_END: ascii = 3; break;
- case KEY_INSERT: ascii = 19; break;
- case KEY_SPACE: ascii = 20; break;
- default:
- ascii = keycode2ascii(event[i].code);
- }
- if (ascii)
- {
- DEBUG("Send %d to xenmgr (keycode was %d)\n", ascii, event[i].code);
- write_sz = write(driver.secure_fd, &ascii, 1);
- if (event[i].code == KEY_ESC || write_sz != 1)
- break;
- }
- }
- if (read_sz <= 0 || event[i].code == KEY_ESC || write_sz != 1)
- {
- dom0_driver_reset_keyboard();
- dom0_driver_redirect_fds(dom0_read);
- return;
- }
-}
-
-static void dom0_read(void *opaque)
-{
- struct input_event event[5];
- int i = 0;
- int read_sz = 0;
- int fd = *(int *)opaque;
+ if (domids[i])
+ {
+ if (!(tmp = xenstore_dom_read(domids[i], "dom0_input/pos", &len)))
+ continue;
+ pos = strtol(tmp, NULL, 10);
+ free(tmp);
- read_sz = read(fd, event, sizeof (event));
- for (i = 0; i < read_sz / (sizeof (struct input_event)); i++)
- {
- if (event[i].type == EV_KEY)
- {
- if (event[i].code >= BTN_MOUSE)
- {
- /* Mouse Key */
- int type = 0;
- struct dom0_driver_xs_info mouse;
-
- dom0_driver_read_xs_info(&mouse, DOM0_MOUSE);
- if (mouse.state == 0)
- {
- dom0_driver_xs_write("state", 1, DOM0_MOUSE);
- dom0_driver_xs_write("domid", domid, DOM0_MOUSE);
- }
-
-
- switch(event[i].code)
- {
- case BTN_LEFT: type = MOUSE_EVENT_LBUTTON; break;
- case BTN_RIGHT: type = MOUSE_EVENT_RBUTTON; break;
- case BTN_MIDDLE: type = MOUSE_EVENT_MBUTTON; break;
- }
-
- if (event[i].value)
- driver.mouse_button_state |= type;
- else
- driver.mouse_button_state &= ~type;
- kbd_mouse_event(0, 0, 0, driver.mouse_button_state);
- }
- else
- dom0_key_event(event[i].value, event[i].code);
- }
-
- if (event[i].type == EV_REL || event[i].type == EV_ABS)
- {
- /* Mouse motion */
- int x = 0, y = 0, z = 0;
-
- if (event[i].type == EV_REL)
- switch (event[i].code)
- {
- case REL_X : x = event[i].value; break;
- case REL_Y : y = event[i].value; break;
- case REL_WHEEL : z = -event[i].value; break;
- }
- if (event[i].type == EV_ABS)
- {
- static int last_x = 1, last_y = 1;
- int px = 0, py = 0, l = 50;
- double div = 1;
- char *str = NULL;
-
- str = xenstore_read_dom0_driver("touchpad-limit");
- if (str)
- l = strtol(str, NULL, 10);
- str = xenstore_read_dom0_driver("touchpad-div");
- if (str)
- div = strtol(str, NULL, 10) / 1000.;
-
- switch (event[i].code)
- {
- case ABS_X : x = event[i].value; break;
- case ABS_Y : y = event[i].value; break;
- }
-
- if (x)
- {
- px = x - last_x;
- last_x = x;
- }
- if (y)
- {
- py = y - last_y;
- last_y = y;
- }
-
- x = (ABS(px) < l ? px : 0) / div;
- y = (ABS(py) < l ? py : 0) / div;
- }
-
- kbd_mouse_event(x, y, z, driver.mouse_button_state);
- }
- }
+ positions[pos] = domids[i];
+ }
+ free(domids);
}
-int pt_i8042_grab(int aux, int grab);
-int kbd_host_grab(int aux, int grab);
static void dom0_gr_devices(int grab, int controller)
{
- int st = 0;
- int *fd = 0;
-
if (controller == DOM0_MOUSE)
- fd = driver.mouse_fds;
- if (controller == DOM0_KEYBOARD)
- fd = driver.keyboard_fds;
- assert(fd != NULL);
-
- while (*fd != -1)
{
- if (ioctl(*fd, EVIOCGRAB, grab) == -1)
- {
- DEBUG("Try to %s on %d\n", 1 ? "grab" : "release", *fd);
- return;
- }
- DEBUG("%s succed %d\n", grab ? "grab" : "release", *fd);
-
- if (grab)
- qemu_set_fd_handler(*fd, dom0_read, NULL, fd);
- else
- qemu_set_fd_handler(*fd, NULL, NULL, fd);
- fd++;
+ DEBUG("%s mouse\n", grab ? "Grab" : "Release");
+ assert(dom0_driver_handler->grab_mouse(grab));
}
-
- if (controller == DOM0_MOUSE && !vga_passthrough)
+ if (controller == DOM0_KEYBOARD)
{
- struct dom0_driver_xs_info info;
-
- dom0_driver_read_xs_info(&info, DOM0_MOUSE);
- if (!vga_passthrough &&
- dom0_driver_xs_read_dom0("natif") != info.domid)
- intel_focus(!grab);
+ DEBUG("%s keyboard\n", grab ? "Grab" : "Release");
+ assert(dom0_driver_handler->grab_keyboard(grab));
}
- dom0_driver_reset_keyboard();
- dom0_driver_xs_write("state", grab ? 1 : 2, controller);
+ dom0_driver_handler->reset_keyboard();
+ if (!grab)
+ dom0_driver_xs_write("pre", domid, controller);
dom0_driver_xs_write("domid", domid, controller);
+ dom0_driver_xs_write("state", grab ? 1 : 2, controller);
}
static int dom0_dom_alive(int id)
domids = xenstore_get_domids(&len);
if (domids == NULL)
- return 0;
+ return 0;
for (i = 0; i < len; i++)
- if (domids[i] == id)
- break;
+ if (domids[i] == id)
+ break;
free(domids);
return (i < len);
}
static int dom0_driver_failover_switch(void *opaque)
{
- struct dom0_driver_xs_info mouse, keyboard;
int ret = 1;
+ uint32_t t = time(NULL);
+ struct dom0_driver_xs_info mouse, keyboard;
if (!vga_passthrough)
- return 0;
+ 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)
{
- DEBUG("No state grab the device\n");
- dom0_gr_devices(1, DOM0_KEYBOARD);
- dom0_gr_devices(1, DOM0_MOUSE);
- goto out;
+ DEBUG("No state grab the device\n");
+ dom0_gr_devices(1, DOM0_KEYBOARD);
+ dom0_gr_devices(1, DOM0_MOUSE);
+ driver.enter();
+ goto out;
}
/* The domain which has the focus crash */
if (!dom0_dom_alive(mouse.domid))
{
- DEBUG("steal the focus from %d\n", mouse.domid);
- dom0_gr_devices(1, DOM0_KEYBOARD);
- dom0_gr_devices(1, DOM0_MOUSE);
- xenstore_write_dom0_driver("blank", "0");
- goto out;
+ DEBUG("steal the focus from %d\n", mouse.domid);
+ dom0_gr_devices(1, DOM0_KEYBOARD);
+ dom0_gr_devices(1, DOM0_MOUSE);
+ driver.enter();
+ goto out;
}
ret = 0;
return ret;
}
-
-static void dom0_driver_dev_init(void)
+static void dom0_driver_dom_command(const char *path, void *opaque)
{
- int i = 0;
- int fd = 0;
- int keyboard = 0, mouse = 0;
- char path[strlen(EVENT_PATH) + 3];
- char name[128];
-
- driver.keyboard_fds[0] = -1;
- driver.mouse_fds[0] = -1;
- while (1)
- {
- sprintf(path, "%s%i", EVENT_PATH, i++);
- if (!(fd = open(path, O_RDONLY)))
- break;
- if (ioctl(fd, EVIOCGNAME(128), name) == -1)
- break;
-
- if (strcasestr(name, "keyboard"))
- {
- driver.keyboard_fds[keyboard] = fd;
- driver.keyboard_fds[keyboard + 1] = -1;
- keyboard++;
- DEBUG("Use \"%s\" as a keyboard %d\n", name, fd);
- }
- else
- {
- driver.mouse_fds[mouse] = fd;
- driver.mouse_fds[mouse + 1] = -1;
- mouse++;
- DEBUG("Use \"%s\" as a mouse %d\n", name, fd);
- }
- }
- assert(driver.keyboard_fds[0] != -1);
- assert(driver.mouse_fds[0] != -1);
-}
+ unsigned int len;
+ char *str;
+ char buff[256];
+ int positions[NB_SLOTS];
+ int natif_domid;
+ int i;
+ struct dom0_driver_xs_info mouse;
-static void dom0_driver_dom_command(char *path, void *opaque)
-{
- unsigned int len;
- char *str;
- char buff[256];
- int positions[NB_SLOTS];
- int natif_domid;
- int i;
-
- if (!(str = xenstore_read(path)) || !*str)
- return;
+ if (!(str = xenstore_read(path)) || !*str)
+ return;
- DEBUG("Received private command %s\n", path);
- dom0_get_positions(positions);
- natif_domid = dom0_driver_xs_read_dom0("natif");
+ DEBUG("Received private command %s\n", path);
+ dom0_get_positions(positions);
+ natif_domid = dom0_driver_xs_read_dom0("natif");
- for (i = 0; i < NB_SLOTS; ++i)
- {
- if (!strcmp("take", str) && positions[i] == domid)
- break;
- if (!strcmp("release", str) && positions[i] == natif_domid)
- break;
- }
- if (i == NB_SLOTS)
- {
- DEBUG("Try to %s on a bad slot\n", str);
- free(str);
- return;
- }
+ dom0_driver_read_xs_info(&mouse, DOM0_MOUSE);
+ if (mouse.domid != natif_domid)
+ {
+ DEBUG("Natif should have the focus for that.\n");
+ return;
+ }
- sprintf(buff, "keyboard %d", i);
- DEBUG("Write \"%s\" into xenstore\n", buff);
- xenstore_write_dom0_driver("command", buff);
+ for (i = 0; i < NB_SLOTS; ++i)
+ {
+ if (!strcmp("take", str) && positions[i] == domid)
+ break;
+ if (!strcmp("release", str) && positions[i] == natif_domid)
+ break;
+ }
+ if (i == NB_SLOTS)
+ {
+ DEBUG("Try to %s on a bad slot\n", str);
free(str);
+ return;
+ }
+
+ sprintf(buff, "keyboard %d", i);
+ DEBUG("Write \"%s\" into xenstore\n", buff);
+ xenstore_write_dom0_driver("command", buff);
+ free(str);
}
static void dom0_driver_event_init(const char *str_arg)
int pos = 0;
int i = 0;
- dom0_driver_dev_init();
-
pos = strtol(str_arg, NULL, 10);
dom0_get_positions(positions);
if (positions[pos])
{
- DEBUG("There is already a vm at this slot\n");
- exit(1);
+ DEBUG("There is already a vm at this slot\n");
+ exit(1);
}
else
{
- snprintf(str, 9, "%d", pos);
- xenstore_dom_write(domid, "dom0_input/pos", str);
+ snprintf(str, 9, "%d", pos);
+ xenstore_dom_write(domid, "dom0_input/pos", str);
}
if (vga_passthrough)
{
- sprintf(str, "%d", domid);
- xenstore_write_dom0_driver("natif", str);
+ sprintf(str, "%d", domid);
+ xenstore_write_dom0_driver("natif", str);
+ xenstore_watch_dom0_driver("command", dom0_driver_command, NULL);
+ }
+ else
+ {
+ xenstore_dom_write(domid, "dom0_input/command", "");
+ sprintf(str, "w%d", domid);
+ xenstore_dom_chmod(domid, "dom0_input/command", str);
+ xenstore_dom_watch(domid, "dom0_input/command", dom0_driver_dom_command, NULL);
}
- else
- {
- xenstore_dom_write(domid, "dom0_input/command", "");
- sprintf(str, "w%d", domid);
- xenstore_dom_chmod(domid, "dom0_input/command", str);
- }
xenstore_watch_dom0_driver("mouse/state", dom0_driver_state_change, NULL);
xenstore_watch_dom0_driver("keyboard/state", dom0_driver_state_change, NULL);
-
- if (vga_passthrough)
- {
- xenstore_write_dom0_driver("blank", "0");
- xenstore_watch_dom0_driver("command", dom0_driver_command, NULL);
- }
- else
- xenstore_dom_watch(domid, "dom0_input/command", dom0_driver_dom_command, NULL);
-
+ xenstore_watch_dom0_driver("leave", dom0_driver_state_change, NULL);
xenstore_watch_dom0_driver("blank", dom0_driver_state_change, NULL);
/* Register the failover switch */
- driver.xs_timer = qemu_new_timer(rt_clock, dom0_driver_failover_switch, NULL);
+ driver.xs_timer = qemu_new_timer(rt_clock,
+ (void (*)(void *))dom0_driver_failover_switch,
+ NULL);
qemu_mod_timer(driver.xs_timer, qemu_get_clock(rt_clock) + XS_REFRESH_INTERVAL);
}
int positions[NB_SLOTS];
if (dom0_driver_failover_switch(NULL))
- return;
+ return;
dom0_driver_read_xs_info(&info, controller);
if (info.new_slot != -1)
{
- dom0_get_positions(positions);
- if (positions[info.new_slot] != 0)
- {
- if (info.state == 0 && info.domid == domid)
- {
- DEBUG("release devices\n");
- dom0_gr_devices(0, controller);
- return;
- }
-
- if (info.state == 2 && positions[info.new_slot] == domid)
- {
- DEBUG("grab devices\n");
- dom0_gr_devices(1, controller);
- return;
- }
-
- }
+ dom0_get_positions(positions);
+ if (positions[info.new_slot] != 0)
+ {
+ if (info.state == 0 && info.domid == domid)
+ {
+ dom0_gr_devices(0, controller);
+ return;
+ }
+
+ if (info.state == 2 && positions[info.new_slot] == domid)
+ {
+ dom0_gr_devices(1, controller);
+ return;
+ }
+
+ }
}
}
static void dom0_driver_switch_controller(int slot, int controller)
{
- dom0_driver_xs_write("new-slot", slot, controller);
- dom0_driver_xs_write("timestamp", time(NULL), controller);
- dom0_driver_xs_write("state", 0, controller);
+ int positions[NB_SLOTS];
+ char *str;
+ int len;
+
+ dom0_get_positions(positions);
+ if (positions[slot] == 0)
+ {
+ DEBUG("Cannot switch controller %d to %d slot empty\n", controller, slot);
+ return;
+ }
+
+ str = xenstore_dom_read(positions[slot], "dom0_input/ready", &len);
+ if (strcmp(str, "1") == 0)
+ {
+ dom0_driver_xs_write("new-slot", slot, controller);
+ dom0_driver_xs_write("timestamp", time(NULL), controller);
+ dom0_driver_xs_write("state", 0, controller);
+ }
+ free(str);
}
void dom0_driver_command(const char *path, void *opaque)
val = xenstore_read(path);
if (val == NULL)
- return;
+ return;
if (!strncmp(val, "switch ", 7))
{
- int slot = strtol(val + 7, NULL, 10);
+ int slot = strtol(val + 7, NULL, 10);
- if (errno == EINVAL)
- goto out;
+ if (errno == EINVAL)
+ goto out;
- DEBUG("switch the keyboard/mouse to slot %d\n", slot);
- dom0_driver_switch_controller(slot, DOM0_KEYBOARD);
- dom0_driver_switch_controller(slot, DOM0_MOUSE);
- xenstore_write(path, "done");
+ DEBUG("switch the keyboard/mouse to slot %d\n", slot);
+ dom0_driver_switch_controller(slot, DOM0_KEYBOARD);
+ dom0_driver_switch_controller(slot, DOM0_MOUSE);
+ xenstore_write(path, "done");
}
else if (!strncmp(val, "keyboard ", 9))
{
- int slot = strtol(val + 9, NULL, 10);
+ int slot = strtol(val + 9, NULL, 10);
- if (errno == EINVAL)
- goto out;
+ if (errno == EINVAL)
+ goto out;
- DEBUG("switch the keyboard to slot %d\n", slot);
- dom0_driver_switch_controller(slot, DOM0_KEYBOARD);
- xenstore_write(path, "done");
+ DEBUG("switch the keyboard to slot %d\n", slot);
+ dom0_driver_switch_controller(slot, DOM0_KEYBOARD);
+ xenstore_write(path, "done");
}
out:
free(val);
}
-static void dom0_driver_blank_done(void)
+static void dom0_driver_leave_done(void)
{
- struct dom0_driver_xs_info info;
- int blank;
-
- dom0_driver_read_xs_info(&info, DOM0_MOUSE);
- blank = dom0_driver_xs_read_dom0("blank");
+ char *str;
+ int id;
+
+ if (!(str = xenstore_read_dom0_driver("leave")))
+ return;
+ id = strtol(str, NULL, 10);
+ free(str);
+ if (id == 1)
+ xenstore_write_dom0_driver("leave", "2");
+}
- if (info.state == 1 && blank == 2)
+static void dom0_driver_leave_changed(void)
+{
+ char *str;
+ int id;
+ struct dom0_driver_xs_info mouse;
+
+ if (!(str = xenstore_read_dom0_driver("leave")))
+ return;
+ id = strtol(str, NULL, 10);
+ free(str);
+ dom0_driver_read_xs_info(&mouse, DOM0_MOUSE);
+ if (id == 2 && mouse.domid == domid)
{
- if (!vga_passthrough)
- intel_focus(info.domid == domid);
+ xenstore_write_dom0_driver("leave", "0");
+ driver.enter();
}
}
{
if (strstr(path, "/keyboard/state"))
- dom0_driver_slots(DOM0_KEYBOARD);
+ dom0_driver_slots(DOM0_KEYBOARD);
if (strstr(path, "/mouse/state"))
- dom0_driver_slots(DOM0_MOUSE);
- if (strstr(path, "/blank"))
- dom0_driver_blank_done();
+ dom0_driver_slots(DOM0_MOUSE);
+ if (strstr(path, "/leave"))
+ dom0_driver_leave_changed();
+ else if (strstr(path, "/blank"))
+ dom0_driver_blank_changed();
else
{
- struct dom0_driver_xs_info mouse, keyboard;
-
- dom0_driver_read_xs_info(&mouse, DOM0_MOUSE);
- dom0_driver_read_xs_info(&keyboard, DOM0_KEYBOARD);
-
- if (mouse.state == 1 && keyboard.state == 1)
- {
- char str[20];
-
- if (!vga_passthrough && intel_getfocus()) {
- intel_focus(0);
- sprintf(str, "%d", !(mouse.domid == dom0_driver_xs_read_dom0("natif")));
- xenstore_write_dom0_driver("blank", str);
- } else if (vga_passthrough && mouse.domid != dom0_driver_xs_read_dom0("natif")) {
- sprintf(str, "%d", !(mouse.domid == domid));
- xenstore_write_dom0_driver("blank", str);
- }
- }
+ struct dom0_driver_xs_info mouse, keyboard;
+
+ dom0_driver_read_xs_info(&mouse, DOM0_MOUSE);
+ dom0_driver_read_xs_info(&keyboard, DOM0_KEYBOARD);
+
+ if (mouse.state == 1 && keyboard.state == 1)
+ if (mouse.pre != -1 && mouse.pre == domid)
+ {
+ xenstore_write_dom0_driver("leave", "1");
+ if (driver.leave())
+ dom0_driver_leave_done();
+ }
+ }
+}
+
+void dom0_driver_switch(void *slot_arg)
+{
+ int slot = (int)slot_arg;
+ char buff[64];
+
+ DEBUG("%d pressed switch to slot %d\n", slot, slot);
+ sprintf(buff, "switch %d", slot);
+ xenstore_write_dom0_driver("command", buff);
+}
+
+void dom0_driver_switch_bind(void)
+{
+ int i = 0;
+ int binds[4];
+
+ for (i = 0; i < 4; i++)
+ binds[i] = -1;
+
+ for (i = 0; i < 9; i++)
+ {
+ binds[0] = KEY_LEFTCTRL;
+ binds[1] = KEY_1 + i;
+ dom0_driver_handler->add_binding(binds, dom0_driver_switch, (void*)(i + 1));
}
}
void dom0_driver_init(const char *position)
{
memset(&driver, 0, sizeof (driver));
+
+ dom0_driver_handler = &dom0_driver_hid_linux;
+ dom0_driver_handler->init();
+
+ if (vga_passthrough)
+ {
+ driver.enter = dom0_driver_unblank;
+ driver.leave = dom0_driver_blank;
+ }
+ else
+ {
+ driver.enter = intel_enter;
+ driver.leave = intel_leave;
+ }
+
+ dom0_driver_switch_bind();
dom0_driver_event_init(position);
dom0_driver_failover_switch(NULL);
+
DEBUG("done\n");
+ xenstore_dom_write(domid, "dom0_input/ready", "1");
}
--- /dev/null
+/*
+ * QEMU hid-linux /dev/input driver
+ *
+ * Copyright (c) 2008 Citrix Systems
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu-common.h"
+#include "console.h"
+#include "qemu-timer.h"
+#include "qemu-xen.h"
+
+#include <sys/types.h>
+#include <linux/input.h>
+#include <linux/kd.h>
+#include <dirent.h>
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <assert.h>
+#include <time.h>
+#include <sys/time.h>
+
+#define HID_LINUX_XS_PATH "/local/domain/0/hid-linux"
+#define ABS(x) ((x) > 0 ? (x) : -(x))
+#define EVENT_PATH "/dev/input/event"
+
+#define DEBUG_HID_LINUX
+
+#ifdef DEBUG_HID_LINUX
+# define DEBUG(_format_, args...) \
+ do \
+{ \
+ char *str = get_time(); \
+ fprintf(stderr, "[%s] hid-linux(%d):%d: " _format_, str, domid, __LINE__, ## args);\
+ free(str);\
+} \
+while (0);
+#else
+# define DEBUG(_format_, args...) (void)0
+#endif
+
+static struct hid_linux_driver
+{
+ int keyboard_fds[4];
+ int mouse_fds[4];
+ char *controller_paths[8];
+ int mouse_button_state;
+ int key_status[256];
+} hid_linux_driver;
+
+struct hid_linux_binding
+{
+ int *binding;
+ void (*cb)(void *);
+ void *payload;
+};
+
+static struct hid_linux_binding *hid_linux_binding = NULL;
+
+static const int ascii2keycode_table[] =
+{
+ KEY_A, KEY_B, KEY_C, KEY_D, KEY_E, KEY_F, KEY_G, KEY_H, KEY_I, KEY_J, KEY_K,
+ KEY_L, KEY_M, KEY_N, KEY_O, KEY_P, KEY_Q, KEY_R, KEY_S, KEY_T, KEY_U,
+ KEY_V, KEY_W, KEY_X, KEY_Y, KEY_Z
+};
+
+static char keycode2ascii(int keycode)
+{
+ int i = 0;
+
+ switch (keycode)
+ {
+ case KEY_ESC: return 27;
+ case KEY_BACKSPACE: return 8;
+ case KEY_ENTER: return 10;
+ case KEY_LEFT: return 17;
+ case KEY_RIGHT: return 18;
+ case KEY_DELETE: return 127;
+ case KEY_HOME: return 2;
+ case KEY_END: return 3;
+ case KEY_INSERT: return 19;
+ case KEY_SPACE: return 20;
+ default:
+ for (i = 0; i < sizeof (ascii2keycode_table) / sizeof (int); i++)
+ if (ascii2keycode_table[i] == keycode)
+ return i + 'a';
+ }
+ return 0;
+}
+
+static int ascii2keycode(char ascii)
+{
+ return ascii2keycode_table[ascii - 'a'];
+}
+
+static char *hid_linux_xs_read(const char *key)
+{
+ char *path = NULL;
+ char *ret;
+
+ if (asprintf(&path, HID_LINUX_XS_PATH"/%s", key) == -1)
+ return NULL;
+ ret = xenstore_read(path);
+ free(path);
+ return ret;
+}
+
+void hid_linux_add_binding(const int *tab, void (*cb)(void*), void *payload)
+{
+ int i = 0, j = 0;
+
+ for (i = 0; hid_linux_binding && hid_linux_binding[i].cb; i++)
+ ;
+ hid_linux_binding = realloc(hid_linux_binding,
+ (i + 2) * sizeof (struct hid_linux_binding));
+ 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;
+ do
+ {
+ hid_linux_binding[i].binding = realloc(hid_linux_binding[i].binding,
+ (j + 1) * sizeof (int));
+ hid_linux_binding[i].binding[j] = tab[j];
+ }
+ while (tab[j++] != -1);
+}
+
+static int hid_linux_detect_binding(void)
+{
+ int i, j;
+
+ for (i = 0; hid_linux_binding && hid_linux_binding[i].cb; i++)
+ {
+ int *tab = hid_linux_binding[i].binding;
+
+ for (j = 0; tab[j] != -1; j++)
+ if (hid_linux_driver.key_status[tab[j]] == 0)
+ break;
+ if (tab[j] != -1)
+ continue;
+ else /* We match a binding */
+ {
+ DEBUG("binding payload %d\n", (int)(hid_linux_binding[i].payload));
+ hid_linux_binding[i].cb(hid_linux_binding[i].payload);
+ hid_linux_reset_keyboard();
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static void hid_linux_key_inject(int code, uint32_t keycode)
+{
+ int first = 0;
+
+ switch (keycode)
+ {
+ case KEY_F11: keycode = 0X57; break; /* F11 */
+ case KEY_F12: keycode = 0X58; break; /* F12 */
+ case KEY_INSERT: keycode = 0X52; break;
+ case KEY_HOME: keycode = 0X47; break;
+ case KEY_PAGEUP: keycode = 0X49; break;
+ case KEY_DELETE: keycode = 0X53; break;
+ case KEY_END: keycode = 0X4F; break;
+ case KEY_PAGEDOWN: keycode = 0x51; break;
+ case KEY_UP: keycode = 0X48; break;
+ case KEY_LEFT: keycode = 0X4B; break;
+ case KEY_DOWN: keycode = 0X50; break;
+ case KEY_RIGHT: keycode = 0X4D; break;
+ case KEY_RIGHTALT: keycode = 0x38; first = 0xe0; break;
+ case KEY_LEFTMETA: keycode = 0x5B; first = 0xe0; break;
+ case KEY_RIGHTMETA: keycode = 0x5C; first = 0xe0; break;
+ }
+
+ if (first)
+ kbd_put_keycode(first);
+
+ if (code == 0)
+ kbd_put_keycode(keycode | 0x80);
+ else
+ kbd_put_keycode(keycode & 0x7f);
+}
+
+void hid_linux_reset_keyboard(void)
+{
+ int i = 0;
+
+ for (i = 0; i < 256; i++)
+ if (hid_linux_driver.key_status[i])
+ {
+ hid_linux_key_inject(0, i);
+ hid_linux_driver.key_status[i] = 0;
+ }
+}
+
+static void hid_linux_key_event(int code, uint32_t keycode)
+{
+ if (code == 1)
+ if (hid_linux_detect_binding())
+ return;
+ hid_linux_key_inject(code, keycode);
+}
+
+void hid_linux_secure_keyboard(void (*cb)(int ascii))
+{
+}
+
+static void hid_linux_redirect_fds(int *fd, IOHandler *cb)
+{
+ assert(fd != NULL);
+
+ while (*fd != -1)
+ {
+ qemu_set_fd_handler(*fd, cb, NULL, fd);
+ fd++;
+ }
+}
+
+static void hid_linux_read(void *opaque)
+{
+ struct input_event event[5];
+ int i = 0;
+ int read_sz = 0;
+ int fd = *(int *)opaque;
+
+ read_sz = read(fd, event, sizeof (event));
+ for (i = 0; i < read_sz / (sizeof (struct input_event)); i++)
+ {
+ if (event[i].type == EV_KEY)
+ {
+ if (event[i].code >= BTN_MOUSE)
+ {
+ /* Mouse Key */
+ int type = 0;
+
+ switch(event[i].code)
+ {
+ case BTN_LEFT: type = MOUSE_EVENT_LBUTTON; break;
+ case BTN_RIGHT: type = MOUSE_EVENT_RBUTTON; break;
+ case BTN_MIDDLE: type = MOUSE_EVENT_MBUTTON; break;
+ }
+
+ if (event[i].value)
+ hid_linux_driver.mouse_button_state |= type;
+ else
+ hid_linux_driver.mouse_button_state &= ~type;
+ kbd_mouse_event(0, 0, 0, hid_linux_driver.mouse_button_state);
+ }
+ else
+ {
+ hid_linux_driver.key_status[event[i].code] = event[i].value;
+ hid_linux_key_event(event[i].value, event[i].code);
+ }
+ }
+
+ if (event[i].type == EV_REL || event[i].type == EV_ABS)
+ {
+ /* Mouse motion */
+ int x = 0, y = 0, z = 0;
+
+ if (event[i].type == EV_REL)
+ switch (event[i].code)
+ {
+ case REL_X : x = event[i].value; break;
+ case REL_Y : y = event[i].value; break;
+ case REL_WHEEL : z = -event[i].value; break;
+ }
+ if (event[i].type == EV_ABS)
+ {
+ static int last_x = 1, last_y = 1;
+ int px = 0, py = 0, l = 50;
+ double div = 1;
+ char *str = NULL;
+
+ str = hid_linux_xs_read("touchpad-limit");
+ if (str)
+ l = strtol(str, NULL, 10);
+ str = hid_linux_xs_read("touchpad-div");
+ if (str)
+ div = strtol(str, NULL, 10) / 1000.;
+
+ switch (event[i].code)
+ {
+ case ABS_X : x = event[i].value; break;
+ case ABS_Y : y = event[i].value; break;
+ }
+
+ if (x)
+ {
+ px = x - last_x;
+ last_x = x;
+ }
+ if (y)
+ {
+ py = y - last_y;
+ last_y = y;
+ }
+
+ x = (ABS(px) < l ? px : 0) / div;
+ y = (ABS(py) < l ? py : 0) / div;
+ }
+
+ kbd_mouse_event(x, y, z, hid_linux_driver.mouse_button_state);
+ }
+ }
+}
+
+static int hid_linux_grab_devices(int grab, int *fd)
+{
+ assert(fd != NULL);
+ for (; *fd != -1; fd++)
+ {
+ if (ioctl(*fd, EVIOCGRAB, grab) == -1)
+ return 0;
+
+ if (grab)
+ qemu_set_fd_handler(*fd, hid_linux_read, NULL, fd);
+ else
+ qemu_set_fd_handler(*fd, NULL, NULL, fd);
+ }
+ return 1;
+}
+
+int hid_linux_grab_keyboard(int grab)
+{
+ return hid_linux_grab_devices(grab, hid_linux_driver.keyboard_fds);
+}
+
+int hid_linux_grab_mouse(int grab)
+{
+ return hid_linux_grab_devices(grab, hid_linux_driver.mouse_fds);
+}
+
+static int hid_linux_open_timeout(const char *path, int flags)
+{
+ int try = 10;
+ int fd = 0;
+
+ while (try-- && ((fd = open(path, flags)) == -1))
+ usleep(100000); /* 10 ms */
+ if (try == 0)
+ return 0;
+ return fd == -1 ? 0 : fd;
+}
+
+static int hid_linux_ioctl_timeout(int fd, int arg1, void *arg2)
+{
+ int try = 10;
+
+ while (try-- && ioctl(fd, arg1, arg2) == -1)
+ usleep(100000); /* 10 ms */
+ if (try == 0)
+ return 0;
+ return 1;
+}
+
+void hid_linux_probe(int grab)
+{
+ int i = 0, j = 0, c = 0;
+ int fd = -1;
+ int keyboard = 0, mouse = 0;
+ char path[strlen(EVENT_PATH) + 3];
+ char name[128];
+ int *controllers;
+ struct stat st;
+
+ while (1)
+ {
+ sprintf(path, "%s%i", EVENT_PATH, i++);
+
+ if ((fd = open(path, O_RDONLY)) == -1)
+ break;
+
+ for ( c = 0; c < 8 && hid_linux_driver.controller_paths[c]; c++)
+ if (!strcmp(hid_linux_driver.controller_paths[c], path))
+ break;
+ assert(c != 8);
+ if (hid_linux_driver.controller_paths[c])
+ continue;
+
+ if (ioctl(fd, EVIOCGNAME(128), name) == -1)
+ {
+ DEBUG("Input get name failed on %s\n", path);
+ break;
+ }
+
+ if (strcasestr(name, "keyboard"))
+ {
+ DEBUG("Add %s as a keyboard\n", name);
+ controllers = hid_linux_driver.keyboard_fds;
+ }
+ else
+ {
+ DEBUG("Add %s as a mouse\n", name);
+ controllers = hid_linux_driver.mouse_fds;
+ }
+
+ for ( j = 0; j < 4 && controllers[j] != -1; j++)
+ ;
+ assert(j != 4);
+
+ 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);
+ }
+ fd = -1;
+ }
+ close(fd);
+}
+
+void hid_linux_init(void)
+{
+ hid_linux_driver.keyboard_fds[0] = -1;
+ hid_linux_driver.mouse_fds[0] = -1;
+ hid_linux_driver.controller_paths[0] = NULL;
+
+ while (hid_linux_driver.keyboard_fds[0] == -1)
+ {
+ hid_linux_probe(0);
+ usleep(100000); /* 10 ms */
+ }
+}
}
while (xenstore_watch_callbacks[i].path)
+ {
+ if (!strcmp(xenstore_watch_callbacks[i].path, path))
+ {
+ xenstore_watch_callbacks[i].cb = fptr;
+ xenstore_watch_callbacks[i].opaque = opaque;
+ return ret;
+ }
i++;
+ }
xenstore_watch_callbacks = realloc(xenstore_watch_callbacks,
(i + 2) * sizeof (struct xenstore_watch_cb_t));
}
static void waitForDevice(char *fn)
-{
+{
struct stat sbuf;
int status;
int uwait = UWAIT_MAX;
out->bus = ch / per_bus;
out->unit = ch % per_bus;
-
+
return 0;
-}
+}
static int drive_name_to_index(const char *name) {
DriveInfo tmp;
backend_dompath = xs_get_domain_path(xsh, domid_backend);
if (!backend_dompath) goto out;
-
+
const char *expected_devtypes[3];
const char **expected_devtype = expected_devtypes;
for (expected_devtype = expected_devtypes;
*expected_devtype;
expected_devtype++) {
-
+
if (pasprintf(&expected_backend, "%s/backend/%s/%lu/%s",
backend_dompath, *expected_devtype,
frontend_domid, inst_danger)
out:
if (xch != -1)
close(xch);
-
+
return 0;
#endif
}
xenstore_get_backend_path(&bpath, "vbd", danger_path, hvm_domid,
e_danger[i]);
if (bpath == NULL)
- continue;
+ continue;
/* read the name of the device */
if (pasprintf(&buf, "%s/dev", bpath) == -1)
continue;
break;
}
}
-
+
for (i = 0; i < num; i++) {
format = NULL; /* don't know what the format is yet */
/* read the backend path */
* Hopefully if they are really needed for something
* someone will shout and then we will find out what for.
*/
- /*
+ /*
* check if device has a phantom vbd; the phantom is hooked
- * to the frontend device (for ease of cleanup), so lookup
+ * to the frontend device (for ease of cleanup), so lookup
* the frontend device, and see if there is a phantom_vbd
* if there is, we will use resolution as the filename
*/
DANGER DANGER params is supposedly trustworthy but here
we read it from untrusted part of xenstore
if (params) {
- /*
- * wait for device, on timeout silently fail because we will
+ /*
+ * wait for device, on timeout silently fail because we will
* fail to open below
*/
waitForDevice(params);
}
/* Set a watch for suspend requests from the migration tools */
- if (pasprintf(&buf,
+ if (pasprintf(&buf,
"/local/domain/0/device-model/%u/command", domid) != -1) {
xs_watch(xsh, buf, "dm-command");
fprintf(logfile, "Watching %s\n", buf);
int shmid;
/* Find and map the shared memory segment for log-dirty bitmaps */
- if (pasprintf(&path,
- "/local/domain/0/device-model/%u/logdirty/key",
+ if (pasprintf(&path,
+ "/local/domain/0/device-model/%u/logdirty/key",
domid) == -1) {
fprintf(logfile, "Log-dirty: out of memory\n");
exit(1);
}
-
+
key_ascii = xs_read(xsh, XBT_NULL, path, &len);
free(path);
- if (!key_ascii)
+ if (!key_ascii)
/* No key yet: wait for the next watch */
return;
key = (key_t) strtoull(key_terminated, NULL, 16);
/* Figure out how bit the log-dirty bitmaps are */
- logdirty_bitmap_size = xc_memory_op(xc_handle,
+ logdirty_bitmap_size = xc_memory_op(xc_handle,
XENMEM_maximum_gpfn, &domid) + 1;
logdirty_bitmap_size = ((logdirty_bitmap_size + HOST_LONG_BITS - 1)
/ HOST_LONG_BITS); /* longs */
/* Double-check that the bitmaps are the size we expect */
if (logdirty_bitmap_size != *(uint32_t *)seg) {
- fprintf(logfile, "Log-dirty: got %u, calc %lu\n",
+ fprintf(logfile, "Log-dirty: got %u, calc %lu\n",
*(uint32_t *)seg, logdirty_bitmap_size);
/* Stale key: wait for next watch */
shmdt(seg);
}
/* Remember the paths for the next-active and active entries */
- if (pasprintf(&active_path,
+ if (pasprintf(&active_path,
"/local/domain/0/device-model/%u/logdirty/active",
domid) == -1) {
fprintf(logfile, "Log-dirty: out of memory\n");
exit(1);
}
- if (pasprintf(&next_active_path,
+ if (pasprintf(&next_active_path,
"/local/domain/0/device-model/%u/logdirty/next-active",
domid) == -1) {
fprintf(logfile, "Log-dirty: out of memory\n");
}
fprintf(logfile, "Triggered log-dirty buffer switch\n");
-
+
/* Read the required active buffer from the store */
act = xs_read(xsh, XBT_NULL, next_active_path, &len);
if (!act) {
char *path = NULL, *command = NULL, *par = NULL;
unsigned int len;
- if (pasprintf(&path,
+ if (pasprintf(&path,
"/local/domain/0/device-model/%u/command", domid) == -1) {
fprintf(logfile, "out of memory reading dm command\n");
goto out;
command = xs_read(xsh, XBT_NULL, path, &len);
if (!command)
goto out;
-
+
if (!strncmp(command, "save", len)) {
fprintf(logfile, "dm-command: pause and save state\n");
xen_pause_requested = 1;
} else if (!strncmp(command, "pci-rem", len)) {
fprintf(logfile, "dm-command: hot remove pass-through pci dev \n");
- if (pasprintf(&path,
+ if (pasprintf(&path,
"/local/domain/0/device-model/%u/parameter", domid) == -1) {
fprintf(logfile, "out of memory reading dm command parameter\n");
goto out;
} else if (!strncmp(command, "pci-ins", len)) {
fprintf(logfile, "dm-command: hot insert pass-through pci dev \n");
- if (pasprintf(&path,
+ if (pasprintf(&path,
"/local/domain/0/device-model/%u/parameter", domid) == -1) {
fprintf(logfile, "out of memory reading dm command parameter\n");
goto out;
{
char *path = NULL;
- if (pasprintf(&path,
+ if (pasprintf(&path,
"/local/domain/0/device-model/%u/%s", domid, subpath) == -1) {
fprintf(logfile, "out of memory recording dm \n");
goto out;
return;
for (i = 0; xenstore_watch_callbacks && xenstore_watch_callbacks[i].path; i++)
- if (!strcmp(vec[XS_WATCH_TOKEN], xenstore_watch_callbacks[i].path))
+ if (xenstore_watch_callbacks[i].cb &&
+ !strcmp(vec[XS_WATCH_TOKEN], xenstore_watch_callbacks[i].path))
xenstore_watch_callbacks[i].cb(vec[XS_WATCH_TOKEN],
xenstore_watch_callbacks[i].opaque);
xenstore_process_dm_command_event();
goto out;
}
-
+
if (!strcmp(vec[XS_WATCH_TOKEN], "acadapterstatechangeevt")) {
acpi_ac_adapter_state_changed();
goto out;
char *path = NULL;
int pci_devid = 0;
- if (pasprintf(&path,
+ if (pasprintf(&path,
"/local/domain/0/backend/pci/%u/%u/vslots", domid, pci_devid) == -1) {
fprintf(logfile, "out of memory when updating vslots.\n");
goto out;
static char *xenstore_vm_key_path(int domid, char *key) {
const char *uuid;
char *buf = NULL;
-
+
if (xsh == NULL)
return NULL;
char *xenstore_extended_power_mgmt_read(char *key, unsigned int *len)
{
char *path = NULL, *value = NULL;
-
+
if (pasprintf(&path, "/pm/%s", key) == -1)
return NULL;
{
int ret;
char *path = NULL;
-
+
if (pasprintf(&path, "/pm/%s", key) == -1)
return -1;
{
int ret;
char *path = NULL;
-
+
if (pasprintf(&path, "events/%s", key) == -1)
return -1;
/*
* Xen power management daemon stores battery generic information
- * like model, make, design volt, capacity etc. under /pm/bif and
+ * like model, make, design volt, capacity etc. under /pm/bif and
* battery status information like charging/discharging rate
* under /pm/bst in xenstore.
*/
* We set /pm/events/refreshbatterystatus xenstore entry
* to refresh battert status info stored under /pm/bst
* Xen power management daemon watches for changes to this
- * entry and triggers a refresh.
+ * entry and triggers a refresh.
*/
int xenstore_refresh_battery_status(void)
{
char *buf = NULL;
int len = 0;
char *val = NULL;
-
+
if (pasprintf(&buf, "%s/%s", path, key) == -1)
return NULL;
val = xs_read(xsh, XBT_NULL, buf, &len);
const char *path = "/local/domain/0/dom0_driver";
char *buf = NULL;
int ret = 0;
-
+
if (pasprintf(&buf, "%s/%s", path, key) == -1)
return 0;
xenstore_watch_new_callback(buf, fptr, opaque);
char *buf = NULL;
int len = 0;
int ret = 0;
-
+
if (pasprintf(&buf, "%s/%s", path, key) == -1)
return 0;
ret = xs_write(xsh, XBT_NULL, buf, str, strlen(str));
free(buf);
}
-
int xenstore_dom_write(int domid, char *key, char *value)
{
char *buf = NULL, *path = NULL;