From 27a7bbcdf9483be3b4c0b816d59676c8715c2af3 Mon Sep 17 00:00:00 2001 From: Ladi Prosek Date: Wed, 30 Mar 2016 15:07:20 +0200 Subject: virtio-input: add missing key mappings KEY_PAUSE is flat out missing. KEY_SYSRQ already has a keycode assigned but it's not what I'm seeing on my system. The mapping doesn't appear to have to be unique so both keycodes now map to KEY_SYSRQ which is what the "Keyboard PrintScreen", HID usage ID 0x46, translates to. Signed-off-by: Ladi Prosek Message-id: 1459343240-19483-1-git-send-email-lprosek@redhat.com Signed-off-by: Gerd Hoffmann --- hw/input/virtio-input-hid.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'hw') diff --git a/hw/input/virtio-input-hid.c b/hw/input/virtio-input-hid.c index 5d12157114..fe6d37fd73 100644 --- a/hw/input/virtio-input-hid.c +++ b/hw/input/virtio-input-hid.c @@ -121,6 +121,8 @@ static const unsigned int keymap_qcode[Q_KEY_CODE__MAX] = { [Q_KEY_CODE_CTRL_R] = KEY_RIGHTCTRL, [Q_KEY_CODE_SYSRQ] = KEY_SYSRQ, + [Q_KEY_CODE_PRINT] = KEY_SYSRQ, + [Q_KEY_CODE_PAUSE] = KEY_PAUSE, [Q_KEY_CODE_ALT_R] = KEY_RIGHTALT, [Q_KEY_CODE_HOME] = KEY_HOME, -- cgit v1.2.3 From 848c4d4480561154ada54851ba411aea3977c771 Mon Sep 17 00:00:00 2001 From: Ladi Prosek Date: Thu, 31 Mar 2016 11:53:48 +0200 Subject: virtio-input: retrieve EV_LED host config bits VIRTIO_INPUT_CFG_EV_BITS with subsel of EV_LED was always returning an empty bitmap for pass-through input devices. Signed-off-by: Ladi Prosek Message-id: 1459418028-7473-1-git-send-email-lprosek@redhat.com Signed-off-by: Gerd Hoffmann --- hw/input/virtio-input-host.c | 1 + 1 file changed, 1 insertion(+) (limited to 'hw') diff --git a/hw/input/virtio-input-host.c b/hw/input/virtio-input-host.c index 9e0f46d88f..97b7dd6b5c 100644 --- a/hw/input/virtio-input-host.c +++ b/hw/input/virtio-input-host.c @@ -125,6 +125,7 @@ static void virtio_input_host_realize(DeviceState *dev, Error **errp) virtio_input_bits_config(vih, EV_ABS, ABS_CNT); virtio_input_bits_config(vih, EV_MSC, MSC_CNT); virtio_input_bits_config(vih, EV_SW, SW_CNT); + virtio_input_bits_config(vih, EV_LED, LED_CNT); qemu_set_fd_handler(vih->fd, virtio_input_host_event, NULL, vih); return; -- cgit v1.2.3 From 1a782629f668875955f4f08ac8f11de752d71298 Mon Sep 17 00:00:00 2001 From: Ladi Prosek Date: Fri, 1 Apr 2016 13:45:46 +0200 Subject: virtio-input: implement pass-through evdev writes The write path for pass-through devices, commonly used for controlling keyboard LEDs via EV_LED, was not implemented. This commit adds the necessary plumbing to connect the status virtio queue to the host evdev file descriptor. Signed-off-by: Ladi Prosek Message-id: 1459511146-12060-1-git-send-email-lprosek@redhat.com Signed-off-by: Gerd Hoffmann --- hw/input/virtio-input-host.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'hw') diff --git a/hw/input/virtio-input-host.c b/hw/input/virtio-input-host.c index 97b7dd6b5c..96124f47c1 100644 --- a/hw/input/virtio-input-host.c +++ b/hw/input/virtio-input-host.c @@ -146,6 +146,28 @@ static void virtio_input_host_unrealize(DeviceState *dev, Error **errp) } } +static void virtio_input_host_handle_status(VirtIOInput *vinput, + virtio_input_event *event) +{ + VirtIOInputHost *vih = VIRTIO_INPUT_HOST(vinput); + struct input_event evdev; + int rc; + + if (gettimeofday(&evdev.time, NULL)) { + perror("virtio_input_host_handle_status: gettimeofday"); + return; + } + + evdev.type = le16_to_cpu(event->type); + evdev.code = le16_to_cpu(event->code); + evdev.value = le32_to_cpu(event->value); + + rc = write(vih->fd, &evdev, sizeof(evdev)); + if (rc == -1) { + perror("virtio_input_host_handle_status: write"); + } +} + static const VMStateDescription vmstate_virtio_input_host = { .name = "virtio-input-host", .unmigratable = 1, @@ -165,6 +187,7 @@ static void virtio_input_host_class_init(ObjectClass *klass, void *data) dc->props = virtio_input_host_properties; vic->realize = virtio_input_host_realize; vic->unrealize = virtio_input_host_unrealize; + vic->handle_status = virtio_input_host_handle_status; } static void virtio_input_host_init(Object *obj) -- cgit v1.2.3 From 2d738374665ede5b7c08545e5b44a411e7c3e943 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Tue, 5 Apr 2016 14:31:41 +0200 Subject: virtio-input: add live migration support virtio-input is simple enough that it doesn't need to xfer any state. Still we have to wire up savevm manually, so the generic pci and virtio are saved correctly. Additionally we need to do some post-load processing to figure whenever the guest uses the device or not, so we can give input routing hints to the qemu input layer using qemu_input_handler_{activate,deactivate}. Signed-off-by: Gerd Hoffmann Message-id: 1459859501-16965-1-git-send-email-kraxel@redhat.com --- hw/input/virtio-input.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) (limited to 'hw') diff --git a/hw/input/virtio-input.c b/hw/input/virtio-input.c index 672c207eb5..ac019c7d23 100644 --- a/hw/input/virtio-input.c +++ b/hw/input/virtio-input.c @@ -14,6 +14,8 @@ #include "standard-headers/linux/input.h" +#define VIRTIO_INPUT_VM_VERSION 1 + /* ----------------------------------------------------------------- */ void virtio_input_send(VirtIOInput *vinput, virtio_input_event *event) @@ -214,6 +216,38 @@ static void virtio_input_reset(VirtIODevice *vdev) } } +static void virtio_input_save(QEMUFile *f, void *opaque) +{ + VirtIOInput *vinput = opaque; + VirtIODevice *vdev = VIRTIO_DEVICE(vinput); + + virtio_save(vdev, f); +} + +static int virtio_input_load(QEMUFile *f, void *opaque, int version_id) +{ + VirtIOInput *vinput = opaque; + VirtIOInputClass *vic = VIRTIO_INPUT_GET_CLASS(vinput); + VirtIODevice *vdev = VIRTIO_DEVICE(vinput); + int ret; + + if (version_id != VIRTIO_INPUT_VM_VERSION) { + return -EINVAL; + } + + ret = virtio_load(vdev, f, version_id); + if (ret) { + return ret; + } + + /* post_load() */ + vinput->active = vdev->status & VIRTIO_CONFIG_S_DRIVER_OK; + if (vic->change_active) { + vic->change_active(vinput); + } + return 0; +} + static void virtio_input_device_realize(DeviceState *dev, Error **errp) { VirtIOInputClass *vic = VIRTIO_INPUT_GET_CLASS(dev); @@ -245,14 +279,20 @@ static void virtio_input_device_realize(DeviceState *dev, Error **errp) vinput->cfg_size); vinput->evt = virtio_add_queue(vdev, 64, virtio_input_handle_evt); vinput->sts = virtio_add_queue(vdev, 64, virtio_input_handle_sts); + + register_savevm(dev, "virtio-input", -1, VIRTIO_INPUT_VM_VERSION, + virtio_input_save, virtio_input_load, vinput); } static void virtio_input_device_unrealize(DeviceState *dev, Error **errp) { VirtIOInputClass *vic = VIRTIO_INPUT_GET_CLASS(dev); VirtIODevice *vdev = VIRTIO_DEVICE(dev); + VirtIOInput *vinput = VIRTIO_INPUT(dev); Error *local_err = NULL; + unregister_savevm(dev, "virtio-input", vinput); + if (vic->unrealize) { vic->unrealize(dev, &local_err); if (local_err) { -- cgit v1.2.3 From 0263b3a72fbd2ac9ba59ecc2449a9bc53ccf6fb3 Mon Sep 17 00:00:00 2001 From: Ladi Prosek Date: Fri, 8 Apr 2016 17:21:33 +0200 Subject: virtio-input: fix emulated tablet axis ranges The reported maximum was wrong. The X and Y coordinates are 0-based so if size is 8000 maximum must be 7FFF. Signed-off-by: Ladi Prosek Message-id: 1460128893-10244-1-git-send-email-lprosek@redhat.com Signed-off-by: Gerd Hoffmann --- hw/input/virtio-input-hid.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'hw') diff --git a/hw/input/virtio-input-hid.c b/hw/input/virtio-input-hid.c index fe6d37fd73..3ee0c1814a 100644 --- a/hw/input/virtio-input-hid.c +++ b/hw/input/virtio-input-hid.c @@ -484,12 +484,12 @@ static struct virtio_input_config virtio_tablet_config[] = { .select = VIRTIO_INPUT_CFG_ABS_INFO, .subsel = ABS_X, .size = sizeof(virtio_input_absinfo), - .u.abs.max = const_le32(INPUT_EVENT_ABS_SIZE), + .u.abs.max = const_le32(INPUT_EVENT_ABS_SIZE - 1), },{ .select = VIRTIO_INPUT_CFG_ABS_INFO, .subsel = ABS_Y, .size = sizeof(virtio_input_absinfo), - .u.abs.max = const_le32(INPUT_EVENT_ABS_SIZE), + .u.abs.max = const_le32(INPUT_EVENT_ABS_SIZE - 1), }, { /* end of list */ }, }; -- cgit v1.2.3 From b065e275a8066c3ec478f326f39c5fc3c9db103c Mon Sep 17 00:00:00 2001 From: Ladi Prosek Date: Wed, 13 Apr 2016 16:43:23 +0200 Subject: virtio-input: support absolute axis config in pass-through VIRTIO_INPUT_CFG_ABS_INFO was not implemented for pass-through input devices. This patch follows the existing design and pre-fetches the config for all absolute axes using EVIOCGABS at realize time. Signed-off-by: Ladi Prosek Message-id: 1460558603-18331-1-git-send-email-lprosek@redhat.com Signed-off-by: Gerd Hoffmann --- hw/input/virtio-input-host.c | 46 ++++++++++++++++++++++++++++++++++++++++++-- hw/input/virtio-input.c | 6 +++--- 2 files changed, 47 insertions(+), 5 deletions(-) (limited to 'hw') diff --git a/hw/input/virtio-input-host.c b/hw/input/virtio-input-host.c index 96124f47c1..cb79e80024 100644 --- a/hw/input/virtio-input-host.c +++ b/hw/input/virtio-input-host.c @@ -70,13 +70,39 @@ static void virtio_input_bits_config(VirtIOInputHost *vih, virtio_input_add_config(VIRTIO_INPUT(vih), &bits); } +static void virtio_input_abs_config(VirtIOInputHost *vih, int axis) +{ + virtio_input_config config; + struct input_absinfo absinfo; + int rc; + + rc = ioctl(vih->fd, EVIOCGABS(axis), &absinfo); + if (rc < 0) { + return; + } + + memset(&config, 0, sizeof(config)); + config.select = VIRTIO_INPUT_CFG_ABS_INFO; + config.subsel = axis; + config.size = sizeof(virtio_input_absinfo); + + config.u.abs.min = cpu_to_le32(absinfo.minimum); + config.u.abs.max = cpu_to_le32(absinfo.maximum); + config.u.abs.fuzz = cpu_to_le32(absinfo.fuzz); + config.u.abs.flat = cpu_to_le32(absinfo.flat); + config.u.abs.res = cpu_to_le32(absinfo.resolution); + + virtio_input_add_config(VIRTIO_INPUT(vih), &config); +} + static void virtio_input_host_realize(DeviceState *dev, Error **errp) { VirtIOInputHost *vih = VIRTIO_INPUT_HOST(dev); VirtIOInput *vinput = VIRTIO_INPUT(dev); - virtio_input_config id; + virtio_input_config id, *abs; struct input_id ids; - int rc, ver; + int rc, ver, i, axis; + uint8_t byte; if (!vih->evdev) { error_setg(errp, "evdev property is required"); @@ -127,6 +153,22 @@ static void virtio_input_host_realize(DeviceState *dev, Error **errp) virtio_input_bits_config(vih, EV_SW, SW_CNT); virtio_input_bits_config(vih, EV_LED, LED_CNT); + abs = virtio_input_find_config(VIRTIO_INPUT(vih), + VIRTIO_INPUT_CFG_EV_BITS, EV_ABS); + if (abs) { + for (i = 0; i < abs->size; i++) { + byte = abs->u.bitmap[i]; + axis = 8 * i; + while (byte) { + if (byte & 1) { + virtio_input_abs_config(vih, axis); + } + axis++; + byte >>= 1; + } + } + } + qemu_set_fd_handler(vih->fd, virtio_input_host_event, NULL, vih); return; diff --git a/hw/input/virtio-input.c b/hw/input/virtio-input.c index ac019c7d23..f59749a943 100644 --- a/hw/input/virtio-input.c +++ b/hw/input/virtio-input.c @@ -99,9 +99,9 @@ static void virtio_input_handle_sts(VirtIODevice *vdev, VirtQueue *vq) virtio_notify(vdev, vinput->sts); } -static virtio_input_config *virtio_input_find_config(VirtIOInput *vinput, - uint8_t select, - uint8_t subsel) +virtio_input_config *virtio_input_find_config(VirtIOInput *vinput, + uint8_t select, + uint8_t subsel) { VirtIOInputConfig *cfg; -- cgit v1.2.3