aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Ellerman <michael@ellerman.id.au>2011-11-15 18:53:13 +0000
committerAlexander Graf <agraf@suse.de>2011-11-18 14:26:30 +0100
commit1e34d859d01a408dc8479b1858bb103aa3b4f9a7 (patch)
tree71a13b9ee37a71b2c4d1a2a03b772bb1c2ad00b8
parent3feef8ad17af7307373b9e88b9d7ecb98eeb99da (diff)
pseries: Fix qdev.id handling in the VIO bus code
When the user creates a device on the command line with -device, they can specify the id, using id=foo. Currently the VIO bus code overwrites this id with it's own value. We should only set qdev.id if it is not already set by the user. The device tree code uses qdev.id for the device tree node name, however we can't rely on the user specifiying the id using proper device tree syntax, ie. device@reg. So separate the device tree node name from the qdev.id, but use the same syntax, so they will match by default. Signed-off-by: Michael Ellerman <michael@ellerman.id.au> Signed-off-by: Alexander Graf <agraf@suse.de>
-rw-r--r--hw/spapr_vio.c36
1 files changed, 29 insertions, 7 deletions
diff --git a/hw/spapr_vio.c b/hw/spapr_vio.c
index b7b3ddd116..2dcc0361ed 100644
--- a/hw/spapr_vio.c
+++ b/hw/spapr_vio.c
@@ -73,20 +73,39 @@ VIOsPAPRDevice *spapr_vio_find_by_reg(VIOsPAPRBus *bus, uint32_t reg)
return NULL;
}
+static char *vio_format_dev_name(VIOsPAPRDevice *dev)
+{
+ VIOsPAPRDeviceInfo *info = (VIOsPAPRDeviceInfo *)dev->qdev.info;
+ char *name;
+
+ /* Device tree style name device@reg */
+ if (asprintf(&name, "%s@%x", info->dt_name, dev->reg) < 0) {
+ return NULL;
+ }
+
+ return name;
+}
+
#ifdef CONFIG_FDT
static int vio_make_devnode(VIOsPAPRDevice *dev,
void *fdt)
{
VIOsPAPRDeviceInfo *info = (VIOsPAPRDeviceInfo *)dev->qdev.info;
- int vdevice_off, node_off;
- int ret;
+ int vdevice_off, node_off, ret;
+ char *dt_name;
vdevice_off = fdt_path_offset(fdt, "/vdevice");
if (vdevice_off < 0) {
return vdevice_off;
}
- node_off = fdt_add_subnode(fdt, vdevice_off, dev->qdev.id);
+ dt_name = vio_format_dev_name(dev);
+ if (!dt_name) {
+ return -ENOMEM;
+ }
+
+ node_off = fdt_add_subnode(fdt, vdevice_off, dt_name);
+ free(dt_name);
if (node_off < 0) {
return node_off;
}
@@ -608,12 +627,15 @@ static int spapr_vio_busdev_init(DeviceState *qdev, DeviceInfo *qinfo)
VIOsPAPRDevice *dev = (VIOsPAPRDevice *)qdev;
char *id;
- if (asprintf(&id, "%s@%x", info->dt_name, dev->reg) < 0) {
- return -1;
+ /* Don't overwrite ids assigned on the command line */
+ if (!dev->qdev.id) {
+ id = vio_format_dev_name(dev);
+ if (!id) {
+ return -1;
+ }
+ dev->qdev.id = id;
}
- dev->qdev.id = id;
-
dev->qirq = spapr_allocate_irq(dev->vio_irq_num, &dev->vio_irq_num);
if (!dev->qirq) {
return -1;