From: Marcel Apfelbaum <marce...@redhat.com>

Refactoring it as a method of PCIBusClass will allow
different implementations for subclasses.

Removed the assumption that the root bus does not
have a parent device because is specific only
to the default class implementation.

Signed-off-by: Marcel Apfelbaum <mar...@redhat.com>
---
 hw/pci/pci.c             | 11 ++++-------
 hw/pci/pci_bus.c         |  9 +++++++++
 hw/vfio/pci.c            |  1 +
 include/hw/pci/pci.h     |  1 -
 include/hw/pci/pci_bus.h | 15 +++++++++++++++
 5 files changed, 29 insertions(+), 8 deletions(-)

diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index 933ef65..0b4e138 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -204,7 +204,10 @@ PCIBus *pci_device_root_bus(const PCIDevice *d)
 {
     PCIBus *bus = d->bus;
 
-    while ((d = bus->parent_dev) != NULL) {
+    while (!pci_bus_is_root(bus)) {
+        d = bus->parent_dev;
+        assert(d != NULL);
+
         bus = d->bus;
     }
 
@@ -217,7 +220,6 @@ const char *pci_root_bus_path(PCIDevice *dev)
     PCIHostState *host_bridge = PCI_HOST_BRIDGE(rootbus->qbus.parent);
     PCIHostBridgeClass *hc = PCI_HOST_BRIDGE_GET_CLASS(host_bridge);
 
-    assert(!rootbus->parent_dev);
     assert(host_bridge->bus == rootbus);
 
     if (hc->root_bus_path) {
@@ -249,11 +251,6 @@ bool pci_bus_is_express(PCIBus *bus)
     return object_dynamic_cast(OBJECT(bus), TYPE_PCIE_BUS);
 }
 
-bool pci_bus_is_root(PCIBus *bus)
-{
-    return !bus->parent_dev;
-}
-
 void pci_bus_new_inplace(PCIBus *bus, size_t bus_size, DeviceState *parent,
                          const char *name,
                          MemoryRegion *address_space_mem,
diff --git a/hw/pci/pci_bus.c b/hw/pci/pci_bus.c
index d156194..0922a75 100644
--- a/hw/pci/pci_bus.c
+++ b/hw/pci/pci_bus.c
@@ -464,9 +464,15 @@ static void pcibus_reset(BusState *qbus)
     }
 }
 
+static bool pcibus_is_root(PCIBus *bus)
+{
+    return !bus->parent_dev;
+}
+
 static void pci_bus_class_init(ObjectClass *klass, void *data)
 {
     BusClass *k = BUS_CLASS(klass);
+    PCIBusClass *pbc = PCI_BUS_CLASS(klass);
 
     k->print_dev = pcibus_dev_print;
     k->get_dev_path = pcibus_get_dev_path;
@@ -474,11 +480,14 @@ static void pci_bus_class_init(ObjectClass *klass, void 
*data)
     k->realize = pci_bus_realize;
     k->unrealize = pci_bus_unrealize;
     k->reset = pcibus_reset;
+
+    pbc->is_root = pcibus_is_root;
 }
 
 static const TypeInfo pci_bus_info = {
     .name = TYPE_PCI_BUS,
     .parent = TYPE_BUS,
+    .class_size = sizeof(PCIBusClass),
     .instance_size = sizeof(PCIBus),
     .class_init = pci_bus_class_init,
 };
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index 014a92c..a6f3179 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -32,6 +32,7 @@
 #include "hw/pci/msi.h"
 #include "hw/pci/msix.h"
 #include "hw/pci/pci.h"
+#include "hw/pci/pci_bus.h"
 #include "qemu-common.h"
 #include "qemu/error-report.h"
 #include "qemu/event_notifier.h"
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index 966e9cd..7b2567a 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -338,7 +338,6 @@ typedef PCIINTxRoute (*pci_route_irq_fn)(void *opaque, int 
pin);
 #define TYPE_PCIE_BUS "PCIE"
 
 bool pci_bus_is_express(PCIBus *bus);
-bool pci_bus_is_root(PCIBus *bus);
 void pci_bus_new_inplace(PCIBus *bus, size_t bus_size, DeviceState *parent,
                          const char *name,
                          MemoryRegion *address_space_mem,
diff --git a/include/hw/pci/pci_bus.h b/include/hw/pci/pci_bus.h
index ea427a3..306ef10 100644
--- a/include/hw/pci/pci_bus.h
+++ b/include/hw/pci/pci_bus.h
@@ -15,6 +15,16 @@ PciDeviceInfoList *qmp_query_pci_devices(PCIBus *bus, int 
bus_num);
 
 #define TYPE_PCI_BUS "PCI"
 #define PCI_BUS(obj) OBJECT_CHECK(PCIBus, (obj), TYPE_PCI_BUS)
+#define PCI_BUS_CLASS(klass) OBJECT_CLASS_CHECK(PCIBusClass, (klass), 
TYPE_PCI_BUS)
+#define PCI_BUS_GET_CLASS(obj) OBJECT_GET_CLASS(PCIBusClass, (obj), 
TYPE_PCI_BUS)
+
+typedef struct PCIBusClass {
+    /*< private >*/
+    BusClass parent_class;
+    /*< public >*/
+
+    bool (*is_root)(PCIBus *bus);
+} PCIBusClass;
 
 struct PCIBus {
     BusState qbus;
@@ -39,6 +49,11 @@ struct PCIBus {
     int *irq_count;
 };
 
+static inline bool pci_bus_is_root(PCIBus *bus)
+{
+    return PCI_BUS_GET_CLASS(bus)->is_root(bus);
+}
+
 typedef struct PCIBridgeWindows PCIBridgeWindows;
 
 /*
-- 
2.1.0


Reply via email to