1*8f41a3a8SEmanuele Giuseppe Esposito /* 2*8f41a3a8SEmanuele Giuseppe Esposito * libqos driver framework 3*8f41a3a8SEmanuele Giuseppe Esposito * 4*8f41a3a8SEmanuele Giuseppe Esposito * Copyright (c) 2018 Emanuele Giuseppe Esposito <e.emanuelegiuseppe@gmail.com> 5*8f41a3a8SEmanuele Giuseppe Esposito * 6*8f41a3a8SEmanuele Giuseppe Esposito * This library is free software; you can redistribute it and/or 7*8f41a3a8SEmanuele Giuseppe Esposito * modify it under the terms of the GNU Lesser General Public 8*8f41a3a8SEmanuele Giuseppe Esposito * License version 2 as published by the Free Software Foundation. 9*8f41a3a8SEmanuele Giuseppe Esposito * 10*8f41a3a8SEmanuele Giuseppe Esposito * This library is distributed in the hope that it will be useful, 11*8f41a3a8SEmanuele Giuseppe Esposito * but WITHOUT ANY WARRANTY; without even the implied warranty of 12*8f41a3a8SEmanuele Giuseppe Esposito * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13*8f41a3a8SEmanuele Giuseppe Esposito * Lesser General Public License for more details. 14*8f41a3a8SEmanuele Giuseppe Esposito * 15*8f41a3a8SEmanuele Giuseppe Esposito * You should have received a copy of the GNU Lesser General Public 16*8f41a3a8SEmanuele Giuseppe Esposito * License along with this library; if not, see <http://www.gnu.org/licenses/> 17*8f41a3a8SEmanuele Giuseppe Esposito */ 18*8f41a3a8SEmanuele Giuseppe Esposito 19*8f41a3a8SEmanuele Giuseppe Esposito #include "qemu/osdep.h" 20*8f41a3a8SEmanuele Giuseppe Esposito #include "libqtest.h" 21*8f41a3a8SEmanuele Giuseppe Esposito #include "standard-headers/linux/virtio_ids.h" 22*8f41a3a8SEmanuele Giuseppe Esposito #include "libqos/qgraph.h" 23*8f41a3a8SEmanuele Giuseppe Esposito #include "libqos/virtio-scsi.h" 24*8f41a3a8SEmanuele Giuseppe Esposito 25*8f41a3a8SEmanuele Giuseppe Esposito /* virtio-scsi-device */ 26*8f41a3a8SEmanuele Giuseppe Esposito static void *qvirtio_scsi_get_driver(QVirtioSCSI *v_scsi, 27*8f41a3a8SEmanuele Giuseppe Esposito const char *interface) 28*8f41a3a8SEmanuele Giuseppe Esposito { 29*8f41a3a8SEmanuele Giuseppe Esposito if (!g_strcmp0(interface, "virtio-scsi")) { 30*8f41a3a8SEmanuele Giuseppe Esposito return v_scsi; 31*8f41a3a8SEmanuele Giuseppe Esposito } 32*8f41a3a8SEmanuele Giuseppe Esposito if (!g_strcmp0(interface, "virtio")) { 33*8f41a3a8SEmanuele Giuseppe Esposito return v_scsi->vdev; 34*8f41a3a8SEmanuele Giuseppe Esposito } 35*8f41a3a8SEmanuele Giuseppe Esposito 36*8f41a3a8SEmanuele Giuseppe Esposito fprintf(stderr, "%s not present in virtio-scsi-device\n", interface); 37*8f41a3a8SEmanuele Giuseppe Esposito g_assert_not_reached(); 38*8f41a3a8SEmanuele Giuseppe Esposito } 39*8f41a3a8SEmanuele Giuseppe Esposito 40*8f41a3a8SEmanuele Giuseppe Esposito static void *qvirtio_scsi_device_get_driver(void *object, 41*8f41a3a8SEmanuele Giuseppe Esposito const char *interface) 42*8f41a3a8SEmanuele Giuseppe Esposito { 43*8f41a3a8SEmanuele Giuseppe Esposito QVirtioSCSIDevice *v_scsi = object; 44*8f41a3a8SEmanuele Giuseppe Esposito return qvirtio_scsi_get_driver(&v_scsi->scsi, interface); 45*8f41a3a8SEmanuele Giuseppe Esposito } 46*8f41a3a8SEmanuele Giuseppe Esposito 47*8f41a3a8SEmanuele Giuseppe Esposito static void *virtio_scsi_device_create(void *virtio_dev, 48*8f41a3a8SEmanuele Giuseppe Esposito QGuestAllocator *t_alloc, 49*8f41a3a8SEmanuele Giuseppe Esposito void *addr) 50*8f41a3a8SEmanuele Giuseppe Esposito { 51*8f41a3a8SEmanuele Giuseppe Esposito QVirtioSCSIDevice *virtio_bdevice = g_new0(QVirtioSCSIDevice, 1); 52*8f41a3a8SEmanuele Giuseppe Esposito QVirtioSCSI *interface = &virtio_bdevice->scsi; 53*8f41a3a8SEmanuele Giuseppe Esposito 54*8f41a3a8SEmanuele Giuseppe Esposito interface->vdev = virtio_dev; 55*8f41a3a8SEmanuele Giuseppe Esposito 56*8f41a3a8SEmanuele Giuseppe Esposito virtio_bdevice->obj.get_driver = qvirtio_scsi_device_get_driver; 57*8f41a3a8SEmanuele Giuseppe Esposito 58*8f41a3a8SEmanuele Giuseppe Esposito return &virtio_bdevice->obj; 59*8f41a3a8SEmanuele Giuseppe Esposito } 60*8f41a3a8SEmanuele Giuseppe Esposito 61*8f41a3a8SEmanuele Giuseppe Esposito /* virtio-scsi-pci */ 62*8f41a3a8SEmanuele Giuseppe Esposito static void *qvirtio_scsi_pci_get_driver(void *object, 63*8f41a3a8SEmanuele Giuseppe Esposito const char *interface) 64*8f41a3a8SEmanuele Giuseppe Esposito { 65*8f41a3a8SEmanuele Giuseppe Esposito QVirtioSCSIPCI *v_scsi = object; 66*8f41a3a8SEmanuele Giuseppe Esposito if (!g_strcmp0(interface, "pci-device")) { 67*8f41a3a8SEmanuele Giuseppe Esposito return v_scsi->pci_vdev.pdev; 68*8f41a3a8SEmanuele Giuseppe Esposito } 69*8f41a3a8SEmanuele Giuseppe Esposito return qvirtio_scsi_get_driver(&v_scsi->scsi, interface); 70*8f41a3a8SEmanuele Giuseppe Esposito } 71*8f41a3a8SEmanuele Giuseppe Esposito 72*8f41a3a8SEmanuele Giuseppe Esposito static void *virtio_scsi_pci_create(void *pci_bus, 73*8f41a3a8SEmanuele Giuseppe Esposito QGuestAllocator *t_alloc, 74*8f41a3a8SEmanuele Giuseppe Esposito void *addr) 75*8f41a3a8SEmanuele Giuseppe Esposito { 76*8f41a3a8SEmanuele Giuseppe Esposito QVirtioSCSIPCI *virtio_spci = g_new0(QVirtioSCSIPCI, 1); 77*8f41a3a8SEmanuele Giuseppe Esposito QVirtioSCSI *interface = &virtio_spci->scsi; 78*8f41a3a8SEmanuele Giuseppe Esposito QOSGraphObject *obj = &virtio_spci->pci_vdev.obj; 79*8f41a3a8SEmanuele Giuseppe Esposito 80*8f41a3a8SEmanuele Giuseppe Esposito virtio_pci_init(&virtio_spci->pci_vdev, pci_bus, addr); 81*8f41a3a8SEmanuele Giuseppe Esposito interface->vdev = &virtio_spci->pci_vdev.vdev; 82*8f41a3a8SEmanuele Giuseppe Esposito 83*8f41a3a8SEmanuele Giuseppe Esposito g_assert_cmphex(interface->vdev->device_type, ==, VIRTIO_ID_SCSI); 84*8f41a3a8SEmanuele Giuseppe Esposito 85*8f41a3a8SEmanuele Giuseppe Esposito obj->get_driver = qvirtio_scsi_pci_get_driver; 86*8f41a3a8SEmanuele Giuseppe Esposito 87*8f41a3a8SEmanuele Giuseppe Esposito return obj; 88*8f41a3a8SEmanuele Giuseppe Esposito } 89*8f41a3a8SEmanuele Giuseppe Esposito 90*8f41a3a8SEmanuele Giuseppe Esposito static void virtio_scsi_register_nodes(void) 91*8f41a3a8SEmanuele Giuseppe Esposito { 92*8f41a3a8SEmanuele Giuseppe Esposito QPCIAddress addr = { 93*8f41a3a8SEmanuele Giuseppe Esposito .devfn = QPCI_DEVFN(4, 0), 94*8f41a3a8SEmanuele Giuseppe Esposito }; 95*8f41a3a8SEmanuele Giuseppe Esposito 96*8f41a3a8SEmanuele Giuseppe Esposito QOSGraphEdgeOptions opts = { 97*8f41a3a8SEmanuele Giuseppe Esposito .before_cmd_line = "-drive id=drv0,if=none,file=null-co://,format=raw", 98*8f41a3a8SEmanuele Giuseppe Esposito .after_cmd_line = "-device scsi-hd,bus=vs0.0,drive=drv0", 99*8f41a3a8SEmanuele Giuseppe Esposito }; 100*8f41a3a8SEmanuele Giuseppe Esposito 101*8f41a3a8SEmanuele Giuseppe Esposito /* virtio-scsi-device */ 102*8f41a3a8SEmanuele Giuseppe Esposito opts.extra_device_opts = "id=vs0"; 103*8f41a3a8SEmanuele Giuseppe Esposito qos_node_create_driver("virtio-scsi-device", 104*8f41a3a8SEmanuele Giuseppe Esposito virtio_scsi_device_create); 105*8f41a3a8SEmanuele Giuseppe Esposito qos_node_consumes("virtio-scsi-device", "virtio-bus", &opts); 106*8f41a3a8SEmanuele Giuseppe Esposito qos_node_produces("virtio-scsi-device", "virtio-scsi"); 107*8f41a3a8SEmanuele Giuseppe Esposito 108*8f41a3a8SEmanuele Giuseppe Esposito /* virtio-scsi-pci */ 109*8f41a3a8SEmanuele Giuseppe Esposito opts.extra_device_opts = "id=vs0,addr=04.0"; 110*8f41a3a8SEmanuele Giuseppe Esposito add_qpci_address(&opts, &addr); 111*8f41a3a8SEmanuele Giuseppe Esposito qos_node_create_driver("virtio-scsi-pci", virtio_scsi_pci_create); 112*8f41a3a8SEmanuele Giuseppe Esposito qos_node_consumes("virtio-scsi-pci", "pci-bus", &opts); 113*8f41a3a8SEmanuele Giuseppe Esposito qos_node_produces("virtio-scsi-pci", "pci-device"); 114*8f41a3a8SEmanuele Giuseppe Esposito qos_node_produces("virtio-scsi-pci", "virtio-scsi"); 115*8f41a3a8SEmanuele Giuseppe Esposito } 116*8f41a3a8SEmanuele Giuseppe Esposito 117*8f41a3a8SEmanuele Giuseppe Esposito libqos_init(virtio_scsi_register_nodes); 118