mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-04 00:03:54 -06:00
qdev: add "check if address free" callback for buses
Check if an address is free on the bus before plugging in the device. This makes it possible to do the check without any side effects, and to detect the problem early without having to do it in the realize callback. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Message-Id: <20201006123904.610658-5-mlevitsk@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
d8a18da56d
commit
bb755ba47f
4 changed files with 30 additions and 5 deletions
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue