aboutsummaryrefslogtreecommitdiff
path: root/hw/core/qdev.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/core/qdev.c')
-rw-r--r--hw/core/qdev.c17
1 files changed, 15 insertions, 2 deletions
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index 96772a1..74db78d 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -94,13 +94,23 @@ static void bus_add_child(BusState *bus, DeviceState *child)
0);
}
-void qdev_set_parent_bus(DeviceState *dev, BusState *bus)
+static bool bus_check_address(BusState *bus, DeviceState *child, Error **errp)
+{
+ BusClass *bc = BUS_GET_CLASS(bus);
+ return !bc->check_address || bc->check_address(bus, child, errp);
+}
+
+bool qdev_set_parent_bus(DeviceState *dev, BusState *bus, Error **errp)
{
BusState *old_parent_bus = dev->parent_bus;
DeviceClass *dc = DEVICE_GET_CLASS(dev);
assert(dc->bus_type && object_dynamic_cast(OBJECT(bus), dc->bus_type));
+ if (!bus_check_address(bus, dev, errp)) {
+ return false;
+ }
+
if (old_parent_bus) {
trace_qdev_update_parent_bus(dev, object_get_typename(OBJECT(dev)),
old_parent_bus, object_get_typename(OBJECT(old_parent_bus)),
@@ -126,6 +136,7 @@ void qdev_set_parent_bus(DeviceState *dev, BusState *bus)
object_unref(OBJECT(old_parent_bus));
object_unref(OBJECT(dev));
}
+ return true;
}
DeviceState *qdev_new(const char *name)
@@ -371,7 +382,9 @@ bool qdev_realize(DeviceState *dev, BusState *bus, Error **errp)
assert(!dev->realized && !dev->parent_bus);
if (bus) {
- qdev_set_parent_bus(dev, bus);
+ if (!qdev_set_parent_bus(dev, bus, errp)) {
+ return false;
+ }
} else {
assert(!DEVICE_GET_CLASS(dev)->bus_type);
}