|
@@ -333,6 +333,13 @@ static void pci_host_bus_register(DeviceState *host)
|
|
QLIST_INSERT_HEAD(&pci_host_bridges, host_bridge, next);
|
|
QLIST_INSERT_HEAD(&pci_host_bridges, host_bridge, next);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static void pci_host_bus_unregister(DeviceState *host)
|
|
|
|
+{
|
|
|
|
+ PCIHostState *host_bridge = PCI_HOST_BRIDGE(host);
|
|
|
|
+
|
|
|
|
+ QLIST_REMOVE(host_bridge, next);
|
|
|
|
+}
|
|
|
|
+
|
|
PCIBus *pci_device_root_bus(const PCIDevice *d)
|
|
PCIBus *pci_device_root_bus(const PCIDevice *d)
|
|
{
|
|
{
|
|
PCIBus *bus = pci_get_bus(d);
|
|
PCIBus *bus = pci_get_bus(d);
|
|
@@ -379,6 +386,11 @@ static void pci_root_bus_init(PCIBus *bus, DeviceState *parent,
|
|
pci_host_bus_register(parent);
|
|
pci_host_bus_register(parent);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static void pci_bus_uninit(PCIBus *bus)
|
|
|
|
+{
|
|
|
|
+ pci_host_bus_unregister(BUS(bus)->parent);
|
|
|
|
+}
|
|
|
|
+
|
|
bool pci_bus_is_express(PCIBus *bus)
|
|
bool pci_bus_is_express(PCIBus *bus)
|
|
{
|
|
{
|
|
return object_dynamic_cast(OBJECT(bus), TYPE_PCIE_BUS);
|
|
return object_dynamic_cast(OBJECT(bus), TYPE_PCIE_BUS);
|
|
@@ -413,6 +425,12 @@ PCIBus *pci_root_bus_new(DeviceState *parent, const char *name,
|
|
return bus;
|
|
return bus;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+void pci_root_bus_cleanup(PCIBus *bus)
|
|
|
|
+{
|
|
|
|
+ pci_bus_uninit(bus);
|
|
|
|
+ object_unparent(OBJECT(bus));
|
|
|
|
+}
|
|
|
|
+
|
|
void pci_bus_irqs(PCIBus *bus, pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
|
|
void pci_bus_irqs(PCIBus *bus, pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
|
|
void *irq_opaque, int nirq)
|
|
void *irq_opaque, int nirq)
|
|
{
|
|
{
|
|
@@ -423,6 +441,15 @@ void pci_bus_irqs(PCIBus *bus, pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
|
|
bus->irq_count = g_malloc0(nirq * sizeof(bus->irq_count[0]));
|
|
bus->irq_count = g_malloc0(nirq * sizeof(bus->irq_count[0]));
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+void pci_bus_irqs_cleanup(PCIBus *bus)
|
|
|
|
+{
|
|
|
|
+ bus->set_irq = NULL;
|
|
|
|
+ bus->map_irq = NULL;
|
|
|
|
+ bus->irq_opaque = NULL;
|
|
|
|
+ bus->nirq = 0;
|
|
|
|
+ g_free(bus->irq_count);
|
|
|
|
+}
|
|
|
|
+
|
|
PCIBus *pci_register_root_bus(DeviceState *parent, const char *name,
|
|
PCIBus *pci_register_root_bus(DeviceState *parent, const char *name,
|
|
pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
|
|
pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
|
|
void *irq_opaque,
|
|
void *irq_opaque,
|
|
@@ -439,6 +466,12 @@ PCIBus *pci_register_root_bus(DeviceState *parent, const char *name,
|
|
return bus;
|
|
return bus;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+void pci_unregister_root_bus(PCIBus *bus)
|
|
|
|
+{
|
|
|
|
+ pci_bus_irqs_cleanup(bus);
|
|
|
|
+ pci_root_bus_cleanup(bus);
|
|
|
|
+}
|
|
|
|
+
|
|
int pci_bus_num(PCIBus *s)
|
|
int pci_bus_num(PCIBus *s)
|
|
{
|
|
{
|
|
return PCI_BUS_GET_CLASS(s)->bus_num(s);
|
|
return PCI_BUS_GET_CLASS(s)->bus_num(s);
|