/*
 * Vhost vsock PCI Bindings
 *
 * Copyright 2015 Red Hat, Inc.
 *
 * Authors:
 *  Stefan Hajnoczi <stefanha@redhat.com>
 *
 * 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 "virtio-pci.h"
#include "hw/virtio/vhost-vsock.h"
#include "qemu/module.h"

typedef struct VHostVSockPCI VHostVSockPCI;

/*
 * vhost-vsock-pci: This extends VirtioPCIProxy.
 */
#define TYPE_VHOST_VSOCK_PCI "vhost-vsock-pci-base"
#define VHOST_VSOCK_PCI(obj) \
        OBJECT_CHECK(VHostVSockPCI, (obj), TYPE_VHOST_VSOCK_PCI)

struct VHostVSockPCI {
    VirtIOPCIProxy parent_obj;
    VHostVSock vdev;
};

/* vhost-vsock-pci */

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

static void vhost_vsock_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
{
    VHostVSockPCI *dev = VHOST_VSOCK_PCI(vpci_dev);
    DeviceState *vdev = DEVICE(&dev->vdev);

    qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus));
    object_property_set_bool(OBJECT(vdev), true, "realized", errp);
}

static void vhost_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_vsock_pci_realize;
    set_bit(DEVICE_CATEGORY_MISC, dc->categories);
    dc->props = vhost_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_vsock_pci_instance_init(Object *obj)
{
    VHostVSockPCI *dev = VHOST_VSOCK_PCI(obj);

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

static const VirtioPCIDeviceTypeInfo vhost_vsock_pci_info = {
    .base_name             = TYPE_VHOST_VSOCK_PCI,
    .generic_name          = "vhost-vsock-pci",
    .transitional_name     = "vhost-vsock-pci-transitional",
    .non_transitional_name = "vhost-vsock-pci-non-transitional",
    .instance_size = sizeof(VHostVSockPCI),
    .instance_init = vhost_vsock_pci_instance_init,
    .class_init    = vhost_vsock_pci_class_init,
};

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

type_init(virtio_pci_vhost_register)
