Patchwork [26/61] virtio-scsi : add the virtio-scsi device.

login
register
mail settings
Submitter fred.konrad@greensocs.com
Date Jan. 7, 2013, 6:40 p.m.
Message ID <1357584074-10852-27-git-send-email-fred.konrad@greensocs.com>
Download mbox | patch
Permalink /patch/210057/
State New
Headers show

Comments

fred.konrad@greensocs.com - Jan. 7, 2013, 6:40 p.m.
From: KONRAD Frederic <fred.konrad@greensocs.com>

Create virtio-scsi which extends virtio-device, so it can be connected on
virtio-bus.

Signed-off-by: KONRAD Frederic <fred.konrad@greensocs.com>
---
 hw/virtio-pci.c  |  5 ++++
 hw/virtio-scsi.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++----
 hw/virtio-scsi.h |  7 +++++
 3 files changed, 98 insertions(+), 5 deletions(-)

Patch

diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
index 8955b73..be382c0 100644
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@ -1065,6 +1065,11 @@  static void virtio_pci_device_plugged(DeviceState *d)
                                  PCI_DEVICE_ID_VIRTIO_NET);
         pci_config_set_class(proxy->pci_dev.config, PCI_CLASS_NETWORK_ETHERNET);
         break;
+    case VIRTIO_ID_SCSI:
+        pci_config_set_device_id(proxy->pci_dev.config,
+                                 PCI_DEVICE_ID_VIRTIO_SCSI);
+        pci_config_set_class(proxy->pci_dev.config, PCI_CLASS_STORAGE_SCSI);
+        break;
     default:
         error_report("unknown device id\n");
         break;
diff --git a/hw/virtio-scsi.c b/hw/virtio-scsi.c
index 7b922ab..ad07a65 100644
--- a/hw/virtio-scsi.c
+++ b/hw/virtio-scsi.c
@@ -16,6 +16,7 @@ 
 #include "virtio-scsi.h"
 #include <hw/scsi.h>
 #include <hw/scsi-defs.h>
+#include "virtio-bus.h"
 
 #define VIRTIO_SCSI_VQ_SIZE     128
 #define VIRTIO_SCSI_CDB_SIZE    32
@@ -681,15 +682,36 @@  static struct SCSIBusInfo virtio_scsi_scsi_info = {
     .load_request = virtio_scsi_load_request,
 };
 
-VirtIODevice *virtio_scsi_init(DeviceState *dev, VirtIOSCSIConf *proxyconf)
+void virtio_scsi_set_conf(DeviceState *qdev, VirtIOSCSIConf *conf)
 {
-    VirtIOSCSI *s;
+    VirtIOSCSI *s = VIRTIO_SCSI(qdev);
+    memcpy(&(s->conf), conf, sizeof(struct VirtIOSCSIConf));
+}
+
+static VirtIODevice *virtio_scsi_common_init(DeviceState *dev,
+                                             VirtIOSCSIConf *proxyconf,
+                                             VirtIOSCSI **ps)
+{
+    VirtIOSCSI *s = *ps;
     static int virtio_scsi_id;
     int i;
 
-    s = (VirtIOSCSI *)virtio_common_init("virtio-scsi", VIRTIO_ID_SCSI,
-                                         sizeof(VirtIOSCSIConfig),
-                                         sizeof(VirtIOSCSI));
+    /*
+     * We have two cases here : the old virtio-net-pci device, and the
+     * refactored virtio-net.
+     */
+
+    if (s == NULL) {
+        /* virtio-scsi-pci */
+        s = (VirtIOSCSI *)virtio_common_init("virtio-scsi", VIRTIO_ID_SCSI,
+                                             sizeof(VirtIOSCSIConfig),
+                                             sizeof(VirtIOSCSI));
+    } else {
+        /* virtio-scsi */
+        virtio_init(VIRTIO_DEVICE(s), "virtio-scsi", VIRTIO_ID_SCSI,
+                    sizeof(VirtIOSCSIConfig));
+    }
+
     s->cmd_vqs = g_malloc0(proxyconf->num_queues * sizeof(VirtQueue *));
 
     s->qdev = dev;
@@ -721,9 +743,68 @@  VirtIODevice *virtio_scsi_init(DeviceState *dev, VirtIOSCSIConf *proxyconf)
     return &s->vdev;
 }
 
+VirtIODevice *virtio_scsi_init(DeviceState *dev, VirtIOSCSIConf *proxyconf)
+{
+    VirtIOSCSI *s = NULL;
+    return virtio_scsi_common_init(dev, proxyconf, &s);
+}
+
 void virtio_scsi_exit(VirtIODevice *vdev)
 {
     VirtIOSCSI *s = (VirtIOSCSI *)vdev;
     unregister_savevm(s->qdev, "virtio-scsi", s);
     virtio_cleanup(vdev);
 }
+
+static int virtio_scsi_device_init(VirtIODevice *vdev)
+{
+    DeviceState *qdev = DEVICE(vdev);
+    VirtIOSCSI *s = VIRTIO_SCSI(vdev);
+    if (virtio_scsi_common_init(qdev, &(s->conf), &s) == NULL) {
+        return -1;
+    }
+    return 0;
+}
+
+static int virtio_scsi_device_exit(DeviceState *qdev)
+{
+    VirtIOSCSI *s = VIRTIO_SCSI(qdev);
+    VirtIODevice *vdev = VIRTIO_DEVICE(qdev);
+
+    unregister_savevm(qdev, "virtio-scsi", s);
+    g_free(s->cmd_vqs);
+    virtio_common_cleanup(vdev);
+    return 0;
+}
+
+static Property virtio_scsi_properties[] = {
+    DEFINE_VIRTIO_SCSI_PROPERTIES(VirtIOSCSI, conf),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void virtio_scsi_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
+    dc->exit = virtio_scsi_device_exit;
+    dc->props = virtio_scsi_properties;
+    vdc->init = virtio_scsi_device_init;
+    vdc->get_config = virtio_scsi_get_config;
+    vdc->set_config = virtio_scsi_set_config;
+    vdc->get_features = virtio_scsi_get_features;
+    vdc->reset = virtio_scsi_reset;
+}
+
+static const TypeInfo virtio_scsi_info = {
+    .name = TYPE_VIRTIO_SCSI,
+    .parent = TYPE_VIRTIO_DEVICE,
+    .instance_size = sizeof(VirtIOSCSI),
+    .class_init = virtio_scsi_class_init,
+};
+
+static void virtio_register_types(void)
+{
+    type_register_static(&virtio_scsi_info);
+}
+
+type_init(virtio_register_types)
diff --git a/hw/virtio-scsi.h b/hw/virtio-scsi.h
index 197a7b5..67d9067 100644
--- a/hw/virtio-scsi.h
+++ b/hw/virtio-scsi.h
@@ -18,6 +18,11 @@ 
 #include "pci/pci.h"
 #include <hw/scsi.h>
 
+#define TYPE_VIRTIO_SCSI "virtio-scsi"
+#define VIRTIO_SCSI(obj) \
+        OBJECT_CHECK(VirtIOSCSI, (obj), TYPE_VIRTIO_SCSI)
+
+
 /* The ID for virtio_scsi */
 #define VIRTIO_ID_SCSI  8
 
@@ -52,4 +57,6 @@  typedef struct {
     DEFINE_PROP_UINT32("max_sectors", _state, _conf_field.max_sectors, 0xFFFF),\
     DEFINE_PROP_UINT32("cmd_per_lun", _state, _conf_field.cmd_per_lun, 128)
 
+void virtio_scsi_set_conf(DeviceState *qdev, VirtIOSCSIConf *conf);
+
 #endif /* _QEMU_VIRTIO_SCSI_H */