mirror of
https://gitlab.com/qemu-project/qemu
synced 2024-11-05 20:35:44 +00:00
pci: split shpc_cleanup and shpc_free
object_unparent should not be called until the parent device is going to be destroyed. Only remove the capability and do memory_region_del_subregion at unrealize time. Freeing the data structures is left in shpc_free, to be called from the instance_finalize callback. Acked-by: Michael S. Tsirkin <mst@redhat.com> Reviewed-by: Matthew Rosato <mjrosato@linux.vnet.ibm.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
3a8f2a9ce5
commit
5cd5e70159
3 changed files with 21 additions and 5 deletions
|
@ -97,6 +97,11 @@ static void pci_bridge_dev_exitfn(PCIDevice *dev)
|
|||
pci_bridge_exitfn(dev);
|
||||
}
|
||||
|
||||
static void pci_bridge_dev_instance_finalize(Object *obj)
|
||||
{
|
||||
shpc_free(PCI_DEVICE(obj));
|
||||
}
|
||||
|
||||
static void pci_bridge_dev_write_config(PCIDevice *d,
|
||||
uint32_t address, uint32_t val, int len)
|
||||
{
|
||||
|
@ -154,10 +159,11 @@ static void pci_bridge_dev_class_init(ObjectClass *klass, void *data)
|
|||
}
|
||||
|
||||
static const TypeInfo pci_bridge_dev_info = {
|
||||
.name = TYPE_PCI_BRIDGE_DEV,
|
||||
.parent = TYPE_PCI_BRIDGE,
|
||||
.instance_size = sizeof(PCIBridgeDev),
|
||||
.class_init = pci_bridge_dev_class_init,
|
||||
.name = TYPE_PCI_BRIDGE_DEV,
|
||||
.parent = TYPE_PCI_BRIDGE,
|
||||
.instance_size = sizeof(PCIBridgeDev),
|
||||
.class_init = pci_bridge_dev_class_init,
|
||||
.instance_finalize = pci_bridge_dev_instance_finalize,
|
||||
.interfaces = (InterfaceInfo[]) {
|
||||
{ TYPE_HOTPLUG_HANDLER },
|
||||
{ }
|
||||
|
|
|
@ -663,13 +663,22 @@ void shpc_cleanup(PCIDevice *d, MemoryRegion *bar)
|
|||
SHPCDevice *shpc = d->shpc;
|
||||
d->cap_present &= ~QEMU_PCI_CAP_SHPC;
|
||||
memory_region_del_subregion(bar, &shpc->mmio);
|
||||
object_unparent(OBJECT(&shpc->mmio));
|
||||
/* TODO: cleanup config space changes? */
|
||||
}
|
||||
|
||||
void shpc_free(PCIDevice *d)
|
||||
{
|
||||
SHPCDevice *shpc = d->shpc;
|
||||
if (!shpc) {
|
||||
return;
|
||||
}
|
||||
object_unparent(OBJECT(&shpc->mmio));
|
||||
g_free(shpc->config);
|
||||
g_free(shpc->cmask);
|
||||
g_free(shpc->wmask);
|
||||
g_free(shpc->w1cmask);
|
||||
g_free(shpc);
|
||||
d->shpc = NULL;
|
||||
}
|
||||
|
||||
void shpc_cap_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int l)
|
||||
|
|
|
@ -41,6 +41,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 *dev);
|
||||
void shpc_cap_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int len);
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue