1f170c5efSJuan Quintela /* 2f170c5efSJuan Quintela * Vhost user blk PCI Bindings 3f170c5efSJuan Quintela * 4f170c5efSJuan Quintela * Copyright(C) 2017 Intel Corporation. 5f170c5efSJuan Quintela * 6f170c5efSJuan Quintela * Authors: 7f170c5efSJuan Quintela * Changpeng Liu <changpeng.liu@intel.com> 8f170c5efSJuan Quintela * 9f170c5efSJuan Quintela * Largely based on the "vhost-user-scsi.c" and "vhost-scsi.c" implemented by: 10f170c5efSJuan Quintela * Felipe Franciosi <felipe@nutanix.com> 11f170c5efSJuan Quintela * Stefan Hajnoczi <stefanha@linux.vnet.ibm.com> 12f170c5efSJuan Quintela * Nicholas Bellinger <nab@risingtidesystems.com> 13f170c5efSJuan Quintela * 14f170c5efSJuan Quintela * This work is licensed under the terms of the GNU LGPL, version 2 or later. 15f170c5efSJuan Quintela * See the COPYING.LIB file in the top-level directory. 16f170c5efSJuan Quintela * 17f170c5efSJuan Quintela */ 18f170c5efSJuan Quintela 19f170c5efSJuan Quintela #include "qemu/osdep.h" 20f170c5efSJuan Quintela 21f170c5efSJuan Quintela #include "standard-headers/linux/virtio_pci.h" 22f170c5efSJuan Quintela #include "hw/virtio/virtio.h" 23f170c5efSJuan Quintela #include "hw/virtio/vhost-user-blk.h" 24f170c5efSJuan Quintela #include "hw/pci/pci.h" 25a27bd6c7SMarkus Armbruster #include "hw/qdev-properties.h" 26f170c5efSJuan Quintela #include "qapi/error.h" 27f170c5efSJuan Quintela #include "qemu/error-report.h" 280b8fa32fSMarkus Armbruster #include "qemu/module.h" 29f170c5efSJuan Quintela #include "virtio-pci.h" 30f170c5efSJuan Quintela 31f170c5efSJuan Quintela typedef struct VHostUserBlkPCI VHostUserBlkPCI; 32f170c5efSJuan Quintela 33f170c5efSJuan Quintela /* 34f170c5efSJuan Quintela * vhost-user-blk-pci: This extends VirtioPCIProxy. 35f170c5efSJuan Quintela */ 36f170c5efSJuan Quintela #define TYPE_VHOST_USER_BLK_PCI "vhost-user-blk-pci-base" 37f170c5efSJuan Quintela #define VHOST_USER_BLK_PCI(obj) \ 38f170c5efSJuan Quintela OBJECT_CHECK(VHostUserBlkPCI, (obj), TYPE_VHOST_USER_BLK_PCI) 39f170c5efSJuan Quintela 40f170c5efSJuan Quintela struct VHostUserBlkPCI { 41f170c5efSJuan Quintela VirtIOPCIProxy parent_obj; 42f170c5efSJuan Quintela VHostUserBlk vdev; 43f170c5efSJuan Quintela }; 44f170c5efSJuan Quintela 45f170c5efSJuan Quintela static Property vhost_user_blk_pci_properties[] = { 46f170c5efSJuan Quintela DEFINE_PROP_UINT32("class", VirtIOPCIProxy, class_code, 0), 47f170c5efSJuan Quintela DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 48f170c5efSJuan Quintela DEV_NVECTORS_UNSPECIFIED), 49f170c5efSJuan Quintela DEFINE_PROP_END_OF_LIST(), 50f170c5efSJuan Quintela }; 51f170c5efSJuan Quintela 52f170c5efSJuan Quintela static void vhost_user_blk_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp) 53f170c5efSJuan Quintela { 54f170c5efSJuan Quintela VHostUserBlkPCI *dev = VHOST_USER_BLK_PCI(vpci_dev); 55f170c5efSJuan Quintela DeviceState *vdev = DEVICE(&dev->vdev); 56f170c5efSJuan Quintela 57*a4eef071SStefan Hajnoczi if (dev->vdev.num_queues == VHOST_USER_BLK_AUTO_NUM_QUEUES) { 58*a4eef071SStefan Hajnoczi dev->vdev.num_queues = virtio_pci_optimal_num_queues(0); 59*a4eef071SStefan Hajnoczi } 60*a4eef071SStefan Hajnoczi 61f170c5efSJuan Quintela if (vpci_dev->nvectors == DEV_NVECTORS_UNSPECIFIED) { 62f170c5efSJuan Quintela vpci_dev->nvectors = dev->vdev.num_queues + 1; 63f170c5efSJuan Quintela } 64f170c5efSJuan Quintela 6599ba777eSMarkus Armbruster qdev_realize(vdev, BUS(&vpci_dev->bus), errp); 66f170c5efSJuan Quintela } 67f170c5efSJuan Quintela 68f170c5efSJuan Quintela static void vhost_user_blk_pci_class_init(ObjectClass *klass, void *data) 69f170c5efSJuan Quintela { 70f170c5efSJuan Quintela DeviceClass *dc = DEVICE_CLASS(klass); 71f170c5efSJuan Quintela VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass); 72f170c5efSJuan Quintela PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass); 73f170c5efSJuan Quintela 74f170c5efSJuan Quintela set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); 754f67d30bSMarc-André Lureau device_class_set_props(dc, vhost_user_blk_pci_properties); 76f170c5efSJuan Quintela k->realize = vhost_user_blk_pci_realize; 77f170c5efSJuan Quintela pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET; 78f170c5efSJuan Quintela pcidev_k->device_id = PCI_DEVICE_ID_VIRTIO_BLOCK; 79f170c5efSJuan Quintela pcidev_k->revision = VIRTIO_PCI_ABI_VERSION; 80f170c5efSJuan Quintela pcidev_k->class_id = PCI_CLASS_STORAGE_SCSI; 81f170c5efSJuan Quintela } 82f170c5efSJuan Quintela 83f170c5efSJuan Quintela static void vhost_user_blk_pci_instance_init(Object *obj) 84f170c5efSJuan Quintela { 85f170c5efSJuan Quintela VHostUserBlkPCI *dev = VHOST_USER_BLK_PCI(obj); 86f170c5efSJuan Quintela 87f170c5efSJuan Quintela virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev), 88f170c5efSJuan Quintela TYPE_VHOST_USER_BLK); 89f170c5efSJuan Quintela object_property_add_alias(obj, "bootindex", OBJECT(&dev->vdev), 90d2623129SMarkus Armbruster "bootindex"); 91f170c5efSJuan Quintela } 92f170c5efSJuan Quintela 93f170c5efSJuan Quintela static const VirtioPCIDeviceTypeInfo vhost_user_blk_pci_info = { 94f170c5efSJuan Quintela .base_name = TYPE_VHOST_USER_BLK_PCI, 95f170c5efSJuan Quintela .generic_name = "vhost-user-blk-pci", 96f170c5efSJuan Quintela .transitional_name = "vhost-user-blk-pci-transitional", 97f170c5efSJuan Quintela .non_transitional_name = "vhost-user-blk-pci-non-transitional", 98f170c5efSJuan Quintela .instance_size = sizeof(VHostUserBlkPCI), 99f170c5efSJuan Quintela .instance_init = vhost_user_blk_pci_instance_init, 100f170c5efSJuan Quintela .class_init = vhost_user_blk_pci_class_init, 101f170c5efSJuan Quintela }; 102f170c5efSJuan Quintela 103f170c5efSJuan Quintela static void vhost_user_blk_pci_register(void) 104f170c5efSJuan Quintela { 105f170c5efSJuan Quintela virtio_pci_types_register(&vhost_user_blk_pci_info); 106f170c5efSJuan Quintela } 107f170c5efSJuan Quintela 108f170c5efSJuan Quintela type_init(vhost_user_blk_pci_register) 109