Patchwork [2/7] pseries: Generate device paths for VIO devices

login
register
mail settings
Submitter David Gibson
Date April 8, 2013, 5:08 a.m.
Message ID <1365397702-1515-3-git-send-email-david@gibson.dropbear.id.au>
Download mbox | patch
Permalink /patch/234576/
State New
Headers show

Comments

David Gibson - April 8, 2013, 5:08 a.m.
This patch implements a get_dev_path qdev hook for the pseries paravirtual
VIO bus.  With upcoming savevm support, this will become very important for
scsi disks hanging of VIO virtual SCSI adapters.  scsibus_get_dev_path
uses the get_dev_path of the parent adapter if available, but otherwise
just uses a local channel/target/lun number to identify the device.  So if
two disks are present in the system having the same target and lun on
seperate VIO scsi adapters, savevm cannot distinguish them.  Since the
conventional way of using VSCSI adapters is to have just one disk per
adapter, such a conflict is very likely.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ppc/spapr_vio.c |   37 +++++++++++++++++++++++--------------
 1 file changed, 23 insertions(+), 14 deletions(-)

Patch

diff --git a/hw/ppc/spapr_vio.c b/hw/ppc/spapr_vio.c
index 614b4a8..fc27cdc 100644
--- a/hw/ppc/spapr_vio.c
+++ b/hw/ppc/spapr_vio.c
@@ -53,9 +53,29 @@  static Property spapr_vio_props[] = {
     DEFINE_PROP_END_OF_LIST(),
 };
 
+static char *spapr_vio_get_dev_name(DeviceState *qdev)
+{
+    VIOsPAPRDevice *dev = VIO_SPAPR_DEVICE(qdev);
+    VIOsPAPRDeviceClass *pc = VIO_SPAPR_DEVICE_GET_CLASS(dev);
+    char *name;
+
+    /* Device tree style name device@reg */
+    name = g_strdup_printf("%s@%x", pc->dt_name, dev->reg);
+
+    return name;
+}
+
+static void spapr_vio_bus_class_init(ObjectClass *klass, void *data)
+{
+    BusClass *k = BUS_CLASS(klass);
+
+    k->get_dev_path = spapr_vio_get_dev_name;
+}
+
 static const TypeInfo spapr_vio_bus_info = {
     .name = TYPE_SPAPR_VIO_BUS,
     .parent = TYPE_BUS,
+    .class_init = spapr_vio_bus_class_init,
     .instance_size = sizeof(VIOsPAPRBus),
 };
 
@@ -74,17 +94,6 @@  VIOsPAPRDevice *spapr_vio_find_by_reg(VIOsPAPRBus *bus, uint32_t reg)
     return NULL;
 }
 
-static char *vio_format_dev_name(VIOsPAPRDevice *dev)
-{
-    VIOsPAPRDeviceClass *pc = VIO_SPAPR_DEVICE_GET_CLASS(dev);
-    char *name;
-
-    /* Device tree style name device@reg */
-    name = g_strdup_printf("%s@%x", pc->dt_name, dev->reg);
-
-    return name;
-}
-
 #ifdef CONFIG_FDT
 static int vio_make_devnode(VIOsPAPRDevice *dev,
                             void *fdt)
@@ -98,7 +107,7 @@  static int vio_make_devnode(VIOsPAPRDevice *dev,
         return vdevice_off;
     }
 
-    dt_name = vio_format_dev_name(dev);
+    dt_name = spapr_vio_get_dev_name(DEVICE(dev));
     node_off = fdt_add_subnode(fdt, vdevice_off, dt_name);
     g_free(dt_name);
     if (node_off < 0) {
@@ -437,7 +446,7 @@  static int spapr_vio_busdev_init(DeviceState *qdev)
 
     /* Don't overwrite ids assigned on the command line */
     if (!dev->qdev.id) {
-        id = vio_format_dev_name(dev);
+        id = spapr_vio_get_dev_name(DEVICE(dev));
         dev->qdev.id = id;
     }
 
@@ -636,7 +645,7 @@  int spapr_populate_chosen_stdout(void *fdt, VIOsPAPRBus *bus)
         return offset;
     }
 
-    name = vio_format_dev_name(dev);
+    name = spapr_vio_get_dev_name(DEVICE(dev));
     path = g_strdup_printf("/vdevice/%s", name);
 
     ret = fdt_setprop_string(fdt, offset, "linux,stdout-path", path);