Signed-off-by: Paolo Bonzini <pbonz...@redhat.com> --- hw/pci-bridge/i82801b11.c | 1 + hw/pci-bridge/ioh3420.c | 2 ++ hw/pci-bridge/pci_bridge_dev.c | 2 ++ hw/pci-bridge/xio3130_downstream.c | 2 ++ hw/pci-bridge/xio3130_upstream.c | 2 ++ hw/pci/pci_bridge.c | 5 +++++ include/hw/pci/pci_bridge.h | 1 + 7 files changed, 15 insertions(+)
diff --git a/hw/pci-bridge/i82801b11.c b/hw/pci-bridge/i82801b11.c index 5807a92..f965958 100644 --- a/hw/pci-bridge/i82801b11.c +++ b/hw/pci-bridge/i82801b11.c @@ -74,6 +74,7 @@ static int i82801b11_bridge_initfn(PCIDevice *d) err_bridge: pci_bridge_exitfn(d); + pci_bridge_free(d); return rc; } diff --git a/hw/pci-bridge/ioh3420.c b/hw/pci-bridge/ioh3420.c index bb541eb..74ab7c8 100644 --- a/hw/pci-bridge/ioh3420.c +++ b/hw/pci-bridge/ioh3420.c @@ -143,6 +143,7 @@ err_msi: msi_uninit(d); err_bridge: pci_bridge_exitfn(d); + pci_bridge_free(d); return rc; } @@ -157,6 +158,7 @@ static void ioh3420_exitfn(PCIDevice *d) pcie_cap_exit(d); msi_uninit(d); pci_bridge_exitfn(d); + pci_bridge_free(d); } PCIESlot *ioh3420_init(PCIBus *bus, int devfn, bool multifunction, diff --git a/hw/pci-bridge/pci_bridge_dev.c b/hw/pci-bridge/pci_bridge_dev.c index 39deb1f..c1aab15 100644 --- a/hw/pci-bridge/pci_bridge_dev.c +++ b/hw/pci-bridge/pci_bridge_dev.c @@ -76,6 +76,7 @@ slotid_error: shpc_error: memory_region_destroy(&bridge_dev->bar); pci_bridge_exitfn(dev); + pci_bridge_free(dev); bridge_error: return err; } @@ -92,6 +93,7 @@ static void pci_bridge_dev_exitfn(PCIDevice *dev) shpc_free(dev); memory_region_destroy(&bridge_dev->bar); pci_bridge_exitfn(dev); + pci_bridge_free(dev); } static void pci_bridge_dev_write_config(PCIDevice *d, diff --git a/hw/pci-bridge/xio3130_downstream.c b/hw/pci-bridge/xio3130_downstream.c index 1810dd2..57af725 100644 --- a/hw/pci-bridge/xio3130_downstream.c +++ b/hw/pci-bridge/xio3130_downstream.c @@ -108,6 +108,7 @@ err_msi: msi_uninit(d); err_bridge: pci_bridge_exitfn(d); + pci_bridge_free(d); return rc; } @@ -122,6 +123,7 @@ static void xio3130_downstream_exitfn(PCIDevice *d) pcie_cap_exit(d); msi_uninit(d); pci_bridge_exitfn(d); + pci_bridge_free(d); } PCIESlot *xio3130_downstream_init(PCIBus *bus, int devfn, bool multifunction, diff --git a/hw/pci-bridge/xio3130_upstream.c b/hw/pci-bridge/xio3130_upstream.c index 8e0d97a..58c3d29 100644 --- a/hw/pci-bridge/xio3130_upstream.c +++ b/hw/pci-bridge/xio3130_upstream.c @@ -95,6 +95,7 @@ err_msi: msi_uninit(d); err_bridge: pci_bridge_exitfn(d); + pci_bridge_free(d); return rc; } @@ -104,6 +105,7 @@ static void xio3130_upstream_exitfn(PCIDevice *d) pcie_cap_exit(d); msi_uninit(d); pci_bridge_exitfn(d); + pci_bridge_free(d); } PCIEPort *xio3130_upstream_init(PCIBus *bus, int devfn, bool multifunction, diff --git a/hw/pci/pci_bridge.c b/hw/pci/pci_bridge.c index 24be6c5..4191729 100644 --- a/hw/pci/pci_bridge.c +++ b/hw/pci/pci_bridge.c @@ -383,6 +383,11 @@ void pci_bridge_exitfn(PCIDevice *pci_dev) assert(QLIST_EMPTY(&s->sec_bus.child)); QLIST_REMOVE(&s->sec_bus, sibling); pci_bridge_region_del(s, s->windows); +} + +void pci_bridge_free(PCIDevice *pci_dev) +{ + PCIBridge *s = DO_UPCAST(PCIBridge, dev, pci_dev); pci_bridge_region_cleanup(s, s->windows); memory_region_destroy(&s->address_space_mem); memory_region_destroy(&s->address_space_io); diff --git a/include/hw/pci/pci_bridge.h b/include/hw/pci/pci_bridge.h index 1868f7a..99ba0eb 100644 --- a/include/hw/pci/pci_bridge.h +++ b/include/hw/pci/pci_bridge.h @@ -45,6 +45,7 @@ void pci_bridge_reset(DeviceState *qdev); int pci_bridge_initfn(PCIDevice *pci_dev, const char *typename); void pci_bridge_exitfn(PCIDevice *pci_dev); +void pci_bridge_free(PCIDevice *pci_dev); /* -- 1.8.1.4