qdev-ify virtio-blk.
authorGerd Hoffmann <kraxel@redhat.com>
Fri, 31 Jul 2009 10:25:41 +0000 (12:25 +0200)
committerAnthony Liguori <aliguori@us.ibm.com>
Mon, 10 Aug 2009 18:05:28 +0000 (13:05 -0500)
First user of the new drive property.  With this patch applied host
and guest config can be specified separately, like this:

  -drive if=none,id=disk1,file=/path/to/disk.img
  -device virtio-blk-pci,drive=disk1

You can set any property for virtio-blk-pci now.  You can set the pci
address via addr=.  You can switch the device into 0.10 compat mode
using class=0x0180.  As this is per device you can have one 0.10 and one
0.11 virtio block device in a single virtual machine.

Old syntax continues to work.  Internally it does the same as the two
lines above though.  One side effect this has is a different
initialization order, which might result in a different pci address
being assigned by default.

Long term plan here is to have this working for all block devices, i.e.
once all scsi is properly qdev-ified you will be able to do something
like this:

  -drive if=none,id=sda,file=/path/to/disk.img
  -device lsi,id=lsi,addr=<pciaddr>
  -device scsi-disk,drive=sda,bus=lsi.0,lun=<n>

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Message-Id:

hw/pc.c
hw/pci-hotplug.c
hw/ppc440_bamboo.c
hw/ppce500_mpc8544ds.c
hw/virtio-blk.c
hw/virtio-pci.c
hw/virtio.h
vl.c

diff --git a/hw/pc.c b/hw/pc.c
index bc9e646..6e5669c 100644 (file)
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -1409,18 +1409,6 @@ static void pc_init1(ram_addr_t ram_size,
         }
     }
 
-    /* Add virtio block devices */
-    if (pci_enabled) {
-        int unit_id = 0;
-
-        while ((dinfo = drive_get(IF_VIRTIO, 0, unit_id)) != NULL) {
-            pci_dev = pci_create("virtio-blk-pci",
-                                 dinfo->devaddr);
-            qdev_init(&pci_dev->qdev);
-            unit_id++;
-        }
-    }
-
     /* Add virtio balloon device */
     if (pci_enabled && virtio_balloon) {
         pci_dev = pci_create("virtio-balloon-pci", virtio_balloon_devaddr);
index 43675e2..4da916c 100644 (file)
@@ -136,6 +136,7 @@ static PCIDevice *qemu_pci_hot_add_storage(Monitor *mon,
         break;
     case IF_VIRTIO:
         dev = pci_create("virtio-blk-pci", devaddr);
+        qdev_prop_set_drive(&dev->qdev, "drive", dinfo);
         break;
     default:
         dev = NULL;
index 5011679..3c59f33 100644 (file)
@@ -90,7 +90,6 @@ static void bamboo_init(ram_addr_t ram_size,
 {
     unsigned int pci_irq_nrs[4] = { 28, 27, 26, 25 };
     PCIBus *pcibus;
-    PCIDevice *pci_dev;
     CPUState *env;
     uint64_t elf_entry;
     uint64_t elf_lowaddr;
@@ -102,21 +101,11 @@ static void bamboo_init(ram_addr_t ram_size,
     target_ulong dt_base = 0;
     void *fdt;
     int i;
-    DriveInfo *dinfo;
 
     /* Setup CPU. */
     env = ppc440ep_init(&ram_size, &pcibus, pci_irq_nrs, 1, cpu_model);
 
     if (pcibus) {
-        int unit_id = 0;
-
-        /* Add virtio block devices. */
-        while ((dinfo = drive_get(IF_VIRTIO, 0, unit_id)) != NULL) {
-            pci_dev = pci_create("virtio-blk-pci", dinfo->devaddr);
-            qdev_init(&pci_dev->qdev);
-            unit_id++;
-        }
-
         /* Add virtio console devices */
         for(i = 0; i < MAX_VIRTIO_CONSOLES; i++) {
             if (virtcon_hds[i]) {
index d154c7f..5120821 100644 (file)
@@ -157,7 +157,6 @@ static void mpc8544ds_init(ram_addr_t ram_size,
                          const char *cpu_model)
 {
     PCIBus *pci_bus;
-    PCIDevice *pci_dev;
     CPUState *env;
     uint64_t elf_entry;
     uint64_t elf_lowaddr;
@@ -172,7 +171,6 @@ static void mpc8544ds_init(ram_addr_t ram_size,
     unsigned int pci_irq_nrs[4] = {1, 2, 3, 4};
     qemu_irq *irqs, *mpic, *pci_irqs;
     SerialState * serial[2];
-    DriveInfo *dinfo;
 
     /* Setup CPU */
     env = cpu_ppc_init("e500v2_v30");
@@ -217,15 +215,6 @@ static void mpc8544ds_init(ram_addr_t ram_size,
     isa_mmio_init(MPC8544_PCI_IO, MPC8544_PCI_IOLEN);
 
     if (pci_bus) {
-        int unit_id = 0;
-
-        /* Add virtio block devices. */
-        while ((dinfo = drive_get(IF_VIRTIO, 0, unit_id)) != NULL) {
-            pci_dev = pci_create("virtio-blk-pci", dinfo->devaddr);
-            qdev_init(&pci_dev->qdev);
-            unit_id++;
-        }
-
         /* Register network interfaces. */
         for (i = 0; i < nb_nics; i++) {
             pci_nic_init(&nd_table[i], "virtio", NULL);
index 5036b5b..c278d2e 100644 (file)
@@ -414,29 +414,27 @@ static int virtio_blk_load(QEMUFile *f, void *opaque, int version_id)
     return 0;
 }
 
-VirtIODevice *virtio_blk_init(DeviceState *dev)
+VirtIODevice *virtio_blk_init(DeviceState *dev, DriveInfo *dinfo)
 {
     VirtIOBlock *s;
     int cylinders, heads, secs;
     static int virtio_blk_id;
-    BlockDriverState *bs;
     char *ps;
 
     s = (VirtIOBlock *)virtio_common_init("virtio-blk", VIRTIO_ID_BLOCK,
                                           sizeof(struct virtio_blk_config),
                                           sizeof(VirtIOBlock));
 
-    bs = qdev_init_bdrv(dev, IF_VIRTIO);
     s->vdev.get_config = virtio_blk_update_config;
     s->vdev.get_features = virtio_blk_get_features;
     s->vdev.reset = virtio_blk_reset;
-    s->bs = bs;
+    s->bs = dinfo->bdrv;
     s->rq = NULL;
-    if (strlen(ps = (char *)drive_get_serial(bs)))
+    if (strlen(ps = (char *)drive_get_serial(s->bs)))
         strncpy(s->serial_str, ps, sizeof(s->serial_str));
     else
         snprintf(s->serial_str, sizeof(s->serial_str), "0");
-    bs->private = dev;
+    s->bs->private = dev;
     bdrv_guess_geometry(s->bs, &cylinders, &heads, &secs);
     bdrv_set_geometry_hint(s->bs, cylinders, heads, secs);
 
index 703f4fe..8cf4b57 100644 (file)
@@ -17,7 +17,7 @@
 
 #include "virtio.h"
 #include "pci.h"
-//#include "sysemu.h"
+#include "sysemu.h"
 #include "msix.h"
 #include "net.h"
 
@@ -89,6 +89,7 @@ typedef struct {
     uint32_t addr;
     uint32_t class_code;
     uint32_t nvectors;
+    DriveInfo *dinfo;
 } VirtIOPCIProxy;
 
 /* virtio device */
@@ -432,7 +433,10 @@ static void virtio_blk_init_pci(PCIDevice *pci_dev)
         proxy->class_code != PCI_CLASS_STORAGE_OTHER)
         proxy->class_code = PCI_CLASS_STORAGE_SCSI;
 
-    vdev = virtio_blk_init(&pci_dev->qdev);
+    if (!proxy->dinfo) {
+        fprintf(stderr, "drive property not set\n");
+    }
+    vdev = virtio_blk_init(&pci_dev->qdev, proxy->dinfo);
     virtio_init_pci(proxy, vdev,
                     PCI_VENDOR_ID_REDHAT_QUMRANET,
                     PCI_DEVICE_ID_VIRTIO_BLOCK,
@@ -502,6 +506,10 @@ static PCIDeviceInfo virtio_info[] = {
                 .name   = "class",
                 .info   = &qdev_prop_hex32,
                 .offset = offsetof(VirtIOPCIProxy, class_code),
+            },{
+                .name   = "drive",
+                .info   = &qdev_prop_drive,
+                .offset = offsetof(VirtIOPCIProxy, dinfo),
             },
             {/* end of list */}
         },
index aa55677..c441a93 100644 (file)
@@ -16,6 +16,7 @@
 
 #include "hw.h"
 #include "qdev.h"
+#include "sysemu.h"
 
 /* from Linux's linux/virtio_config.h */
 
@@ -161,7 +162,7 @@ void virtio_bind_device(VirtIODevice *vdev, const VirtIOBindings *binding,
                         void *opaque);
 
 /* Base devices.  */
-VirtIODevice *virtio_blk_init(DeviceState *dev);
+VirtIODevice *virtio_blk_init(DeviceState *dev, DriveInfo *dinfo);
 VirtIODevice *virtio_net_init(DeviceState *dev);
 VirtIODevice *virtio_console_init(DeviceState *dev);
 VirtIODevice *virtio_balloon_init(DeviceState *dev);
diff --git a/vl.c b/vl.c
index 5bf3051..9b390e7 100644 (file)
--- a/vl.c
+++ b/vl.c
@@ -2197,9 +2197,16 @@ DriveInfo *drive_init(QemuOpts *opts, void *opaque,
         break;
     case IF_PFLASH:
     case IF_MTD:
-    case IF_VIRTIO:
     case IF_NONE:
         break;
+    case IF_VIRTIO:
+        /* add virtio block device */
+        opts = qemu_opts_create(&qemu_device_opts, NULL, 0);
+        qemu_opt_set(opts, "driver", "virtio-blk-pci");
+        qemu_opt_set(opts, "drive", dinfo->id);
+        if (devaddr)
+            qemu_opt_set(opts, "addr", devaddr);
+        break;
     case IF_COUNT:
         abort();
     }