qemu/hw/input/vhost-user-input.c
<<
>>
Prefs
   1/*
   2 * This work is licensed under the terms of the GNU GPL, version 2 or
   3 * (at your option) any later version.  See the COPYING file in the
   4 * top-level directory.
   5 */
   6
   7#include "qemu/osdep.h"
   8#include "qemu/error-report.h"
   9#include "qapi/error.h"
  10#include "qemu-common.h"
  11
  12#include "hw/qdev.h"
  13#include "hw/virtio/virtio-input.h"
  14
  15static int vhost_input_config_change(struct vhost_dev *dev)
  16{
  17    error_report("vhost-user-input: unhandled backend config change");
  18    return -1;
  19}
  20
  21static const VhostDevConfigOps config_ops = {
  22    .vhost_dev_config_notifier = vhost_input_config_change,
  23};
  24
  25static void vhost_input_realize(DeviceState *dev, Error **errp)
  26{
  27    VHostUserInput *vhi = VHOST_USER_INPUT(dev);
  28    VirtIOInput *vinput = VIRTIO_INPUT(dev);
  29    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
  30
  31    vhost_dev_set_config_notifier(&vhi->vhost->dev, &config_ops);
  32    vinput->cfg_size = sizeof_field(virtio_input_config, u);
  33    if (vhost_user_backend_dev_init(vhi->vhost, vdev, 2, errp) == -1) {
  34        return;
  35    }
  36}
  37
  38static void vhost_input_change_active(VirtIOInput *vinput)
  39{
  40    VHostUserInput *vhi = VHOST_USER_INPUT(vinput);
  41
  42    if (vinput->active) {
  43        vhost_user_backend_start(vhi->vhost);
  44    } else {
  45        vhost_user_backend_stop(vhi->vhost);
  46    }
  47}
  48
  49static void vhost_input_get_config(VirtIODevice *vdev, uint8_t *config_data)
  50{
  51    VirtIOInput *vinput = VIRTIO_INPUT(vdev);
  52    VHostUserInput *vhi = VHOST_USER_INPUT(vdev);
  53    int ret;
  54
  55    memset(config_data, 0, vinput->cfg_size);
  56
  57    ret = vhost_dev_get_config(&vhi->vhost->dev, config_data, vinput->cfg_size);
  58    if (ret) {
  59        error_report("vhost-user-input: get device config space failed");
  60        return;
  61    }
  62}
  63
  64static void vhost_input_set_config(VirtIODevice *vdev,
  65                                   const uint8_t *config_data)
  66{
  67    VHostUserInput *vhi = VHOST_USER_INPUT(vdev);
  68    int ret;
  69
  70    ret = vhost_dev_set_config(&vhi->vhost->dev, config_data,
  71                               0, sizeof(virtio_input_config),
  72                               VHOST_SET_CONFIG_TYPE_MASTER);
  73    if (ret) {
  74        error_report("vhost-user-input: set device config space failed");
  75        return;
  76    }
  77
  78    virtio_notify_config(vdev);
  79}
  80
  81static const VMStateDescription vmstate_vhost_input = {
  82    .name = "vhost-user-input",
  83    .unmigratable = 1,
  84};
  85
  86static void vhost_input_class_init(ObjectClass *klass, void *data)
  87{
  88    VirtIOInputClass *vic = VIRTIO_INPUT_CLASS(klass);
  89    VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
  90    DeviceClass *dc = DEVICE_CLASS(klass);
  91
  92    dc->vmsd = &vmstate_vhost_input;
  93    vdc->get_config = vhost_input_get_config;
  94    vdc->set_config = vhost_input_set_config;
  95    vic->realize = vhost_input_realize;
  96    vic->change_active = vhost_input_change_active;
  97}
  98
  99static void vhost_input_init(Object *obj)
 100{
 101    VHostUserInput *vhi = VHOST_USER_INPUT(obj);
 102
 103    vhi->vhost = VHOST_USER_BACKEND(object_new(TYPE_VHOST_USER_BACKEND));
 104    object_property_add_alias(obj, "chardev",
 105                              OBJECT(vhi->vhost), "chardev", &error_abort);
 106}
 107
 108static void vhost_input_finalize(Object *obj)
 109{
 110    VHostUserInput *vhi = VHOST_USER_INPUT(obj);
 111
 112    object_unref(OBJECT(vhi->vhost));
 113}
 114
 115static const TypeInfo vhost_input_info = {
 116    .name          = TYPE_VHOST_USER_INPUT,
 117    .parent        = TYPE_VIRTIO_INPUT,
 118    .instance_size = sizeof(VHostUserInput),
 119    .instance_init = vhost_input_init,
 120    .instance_finalize = vhost_input_finalize,
 121    .class_init    = vhost_input_class_init,
 122};
 123
 124static void vhost_input_register_types(void)
 125{
 126    type_register_static(&vhost_input_info);
 127}
 128
 129type_init(vhost_input_register_types)
 130