Signed-off-by: Paolo Bonzini <[email protected]>
---
hw/pci-bridge/pci_bridge_dev.c | 2 ++
hw/pci/shpc.c | 8 +++++++-
include/hw/pci/shpc.h | 1 +
3 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/hw/pci-bridge/pci_bridge_dev.c b/hw/pci-bridge/pci_bridge_dev.c
index 971b432..39deb1f 100644
--- a/hw/pci-bridge/pci_bridge_dev.c
+++ b/hw/pci-bridge/pci_bridge_dev.c
@@ -72,6 +72,7 @@ msi_error:
slotid_cap_cleanup(dev);
slotid_error:
shpc_cleanup(dev, &bridge_dev->bar);
+ shpc_free(dev);
shpc_error:
memory_region_destroy(&bridge_dev->bar);
pci_bridge_exitfn(dev);
@@ -88,6 +89,7 @@ static void pci_bridge_dev_exitfn(PCIDevice *dev)
}
slotid_cap_cleanup(dev);
shpc_cleanup(dev, &bridge_dev->bar);
+ shpc_free(dev);
memory_region_destroy(&bridge_dev->bar);
pci_bridge_exitfn(dev);
}
diff --git a/hw/pci/shpc.c b/hw/pci/shpc.c
index d35c2ee..db88da9 100644
--- a/hw/pci/shpc.c
+++ b/hw/pci/shpc.c
@@ -630,15 +630,21 @@ int shpc_bar_size(PCIDevice *d)
void shpc_cleanup(PCIDevice *d, MemoryRegion *bar)
{
SHPCDevice *shpc = d->shpc;
+ /* TODO: cleanup config space changes? */
d->cap_present &= ~QEMU_PCI_CAP_SHPC;
memory_region_del_subregion(bar, &shpc->mmio);
- /* TODO: cleanup config space changes? */
+}
+
+void shpc_free(PCIDevice *d)
+{
+ SHPCDevice *shpc = d->shpc;
g_free(shpc->config);
g_free(shpc->cmask);
g_free(shpc->wmask);
g_free(shpc->w1cmask);
memory_region_destroy(&shpc->mmio);
g_free(shpc);
+ d->shpc = NULL;
}
void shpc_cap_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int l)
diff --git a/include/hw/pci/shpc.h b/include/hw/pci/shpc.h
index 467911a..5f27431 100644
--- a/include/hw/pci/shpc.h
+++ b/include/hw/pci/shpc.h
@@ -39,6 +39,7 @@ void shpc_reset(PCIDevice *d);
int shpc_bar_size(PCIDevice *dev);
int shpc_init(PCIDevice *dev, PCIBus *sec_bus, MemoryRegion *bar, unsigned
off);
void shpc_cleanup(PCIDevice *dev, MemoryRegion *bar);
+void shpc_free(PCIDevice *d);
void shpc_cap_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int len);
extern VMStateInfo shpc_vmstate_info;
--
1.8.1.4