/*
 * Vhost-user vsock PCI Bindings
 *
 * Copyright 2020 Red Hat, Inc.
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or
 * (at your option) any later version.  See the COPYING file in the
 * top-level directory.
 */

#include "qemu/osdep.h"

#include "hw/virtio/virtio-pci.h"
#include "hw/qdev-properties.h"
#include "hw/virtio/vhost-user-vsock.h"
#include "qom/object.h"

typedef struct VHostUserVSockPCI VHostUserVSockPCI;

/*
 * vhost-user-vsock-pci: This extends VirtioPCIProxy.
 */
#define TYPE_VHOST_USER_VSOCK_PCI "vhost-user-vsock-pci-base"
DECLARE_INSTANCE_CHECKER(VHostUserVSockPCI, VHOST_USER_VSOCK_PCI,
                         TYPE_VHOST_USER_VSOCK_PCI)

struct VHostUserVSockPCI {
    VirtIOPCIProxy parent_obj;
    VHostUserVSock vdev;
};

/* vhost-user-vsock-pci */

static const Property vhost_user_vsock_pci_properties[] = {
    DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 3),
};

static void vhost_user_vsock_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
{
    VHostUserVSockPCI *dev = VHOST_USER_VSOCK_PCI(vpci_dev);
    DeviceState *vdev = DEVICE(&dev->vdev);

    /* unlike vhost-vsock, we do not need to care about pre-5.1 compat */
    virtio_pci_force_virtio_1(vpci_dev);

    qdev_realize(vdev, BUS(&vpci_dev->bus), errp);
}

static void vhost_user_vsock_pci_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
    PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
    k->realize = vhost_user_vsock_pci_realize;
    set_bit(DEVICE_CATEGORY_MISC, dc->categories);
    device_class_set_props(dc, vhost_user_vsock_pci_properties);
    pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
    pcidev_k->device_id = PCI_DEVICE_ID_VIRTIO_VSOCK;
    pcidev_k->revision = 0x00;
    pcidev_k->class_id = PCI_CLASS_COMMUNICATION_OTHER;
}

static void vhost_user_vsock_pci_instance_init(Object *obj)
{
    VHostUserVSockPCI *dev = VHOST_USER_VSOCK_PCI(obj);

    virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
                                TYPE_VHOST_USER_VSOCK);
}

static const VirtioPCIDeviceTypeInfo vhost_user_vsock_pci_info = {
    .base_name             = TYPE_VHOST_USER_VSOCK_PCI,
    .generic_name          = "vhost-user-vsock-pci",
    .non_transitional_name = "vhost-user-vsock-pci-non-transitional",
    .instance_size = sizeof(VHostUserVSockPCI),
    .instance_init = vhost_user_vsock_pci_instance_init,
    .class_init    = vhost_user_vsock_pci_class_init,
};

static void virtio_pci_vhost_register(void)
{
    virtio_pci_types_register(&vhost_user_vsock_pci_info);
}

type_init(virtio_pci_vhost_register)
