diff options
author | 2016-06-03 03:33:22 +0000 | |
---|---|---|
committer | 2016-06-03 03:33:23 +0000 | |
commit | da27230f80795d0028333713f036d44c53cb0e68 (patch) | |
tree | b3d379eaf000adf72b36cb01cdf4d79c3e3f064c /qemu/hw/input/virtio-input.c | |
parent | 0e68cb048bb8aadb14675f5d4286d8ab2fc35449 (diff) | |
parent | 437fd90c0250dee670290f9b714253671a990160 (diff) |
Merge "These changes are the raw update to qemu-2.6."
Diffstat (limited to 'qemu/hw/input/virtio-input.c')
-rw-r--r-- | qemu/hw/input/virtio-input.c | 76 |
1 files changed, 65 insertions, 11 deletions
diff --git a/qemu/hw/input/virtio-input.c b/qemu/hw/input/virtio-input.c index 7b25d2769..f59749a94 100644 --- a/qemu/hw/input/virtio-input.c +++ b/qemu/hw/input/virtio-input.c @@ -4,6 +4,8 @@ * top-level directory. */ +#include "qemu/osdep.h" +#include "qapi/error.h" #include "qemu/iov.h" #include "hw/qdev.h" @@ -12,14 +14,20 @@ #include "standard-headers/linux/input.h" +#define VIRTIO_INPUT_VM_VERSION 1 + /* ----------------------------------------------------------------- */ void virtio_input_send(VirtIOInput *vinput, virtio_input_event *event) { - VirtQueueElement elem; + VirtQueueElement *elem; unsigned have, need; int i, len; + if (!vinput->active) { + return; + } + /* queue up events ... */ if (vinput->qindex == vinput->qsize) { vinput->qsize++; @@ -45,14 +53,16 @@ void virtio_input_send(VirtIOInput *vinput, virtio_input_event *event) /* ... and finally pass them to the guest */ for (i = 0; i < vinput->qindex; i++) { - if (!virtqueue_pop(vinput->evt, &elem)) { + elem = virtqueue_pop(vinput->evt, sizeof(VirtQueueElement)); + if (!elem) { /* should not happen, we've checked for space beforehand */ fprintf(stderr, "%s: Huh? No vq elem available ...\n", __func__); return; } - len = iov_from_buf(elem.in_sg, elem.in_num, + len = iov_from_buf(elem->in_sg, elem->in_num, 0, vinput->queue+i, sizeof(virtio_input_event)); - virtqueue_push(vinput->evt, &elem, len); + virtqueue_push(vinput->evt, elem, len); + g_free(elem); } virtio_notify(VIRTIO_DEVICE(vinput), vinput->evt); vinput->qindex = 0; @@ -68,24 +78,30 @@ static void virtio_input_handle_sts(VirtIODevice *vdev, VirtQueue *vq) VirtIOInputClass *vic = VIRTIO_INPUT_GET_CLASS(vdev); VirtIOInput *vinput = VIRTIO_INPUT(vdev); virtio_input_event event; - VirtQueueElement elem; + VirtQueueElement *elem; int len; - while (virtqueue_pop(vinput->sts, &elem)) { + for (;;) { + elem = virtqueue_pop(vinput->sts, sizeof(VirtQueueElement)); + if (!elem) { + break; + } + memset(&event, 0, sizeof(event)); - len = iov_to_buf(elem.out_sg, elem.out_num, + len = iov_to_buf(elem->out_sg, elem->out_num, 0, &event, sizeof(event)); if (vic->handle_status) { vic->handle_status(vinput, &event); } - virtqueue_push(vinput->sts, &elem, len); + virtqueue_push(vinput->sts, elem, len); + g_free(elem); } 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; @@ -200,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); @@ -231,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) { |