This patch detangle Sysbus PCI bridge from PCIBus. The pci host bridge is derived from sysbus device and therefore it is not possible to hotplug a host bridge. This change makes it possible to develop hotplugable devices creating a pci bus on the fly.
Signed-off-by: Frank Blaschka <blasc...@linux.vnet.ibm.com> --- hw/pci/pci.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/hw/pci/pci.c b/hw/pci/pci.c index cc5d946..553a130 100644 --- a/hw/pci/pci.c +++ b/hw/pci/pci.c @@ -253,9 +253,11 @@ static void pcibus_reset(BusState *qbus) static void pci_host_bus_register(PCIBus *bus, DeviceState *parent) { - PCIHostState *host_bridge = PCI_HOST_BRIDGE(parent); - - QLIST_INSERT_HEAD(&pci_host_bridges, host_bridge, next); + PCIHostState *host_bridge = (PCIHostState *)object_dynamic_cast( + OBJECT(parent), TYPE_PCI_HOST_BRIDGE); + if (host_bridge) { + QLIST_INSERT_HEAD(&pci_host_bridges, host_bridge, next); + } } PCIBus *pci_find_primary_bus(void) @@ -288,14 +290,20 @@ PCIBus *pci_device_root_bus(const PCIDevice *d) const char *pci_root_bus_path(PCIDevice *dev) { PCIBus *rootbus = pci_device_root_bus(dev); - PCIHostState *host_bridge = PCI_HOST_BRIDGE(rootbus->qbus.parent); - PCIHostBridgeClass *hc = PCI_HOST_BRIDGE_GET_CLASS(host_bridge); + PCIHostState *host_bridge; + PCIHostBridgeClass *hc; + + host_bridge = (PCIHostState *)object_dynamic_cast( + OBJECT(rootbus->qbus.parent), TYPE_PCI_HOST_BRIDGE); assert(!rootbus->parent_dev); - assert(host_bridge->bus == rootbus); - if (hc->root_bus_path) { - return (*hc->root_bus_path)(host_bridge, rootbus); + if (host_bridge) { + assert(host_bridge->bus == rootbus); + hc = PCI_HOST_BRIDGE_GET_CLASS(host_bridge); + if (hc->root_bus_path) { + return (*hc->root_bus_path)(host_bridge, rootbus); + } } return rootbus->qbus.name; -- 2.1.4