@@ -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);
}
@@ -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)
@@ -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;
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- 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(-)