aboutsummaryrefslogtreecommitdiff
path: root/hw/acpi/pcihp.c
diff options
context:
space:
mode:
authorDavid Hildenbrand <david@redhat.com>2018-12-12 10:16:18 +0100
committerMichael S. Tsirkin <mst@redhat.com>2018-12-20 11:19:12 -0500
commit3e5209265798af396b9f20bac58f203a743cc3f4 (patch)
tree1ce76635d74e8dfca50897b86a27b940fb4437c6 /hw/acpi/pcihp.c
parentec266f408882fd38475f72c4e864ed576228643b (diff)
pci/pcihp: overwrite hotplug handler recursively from the start
For now, the hotplug handler is not called for devices that are being cold plugged. The hotplug handler is setup when the machine initialization is fully done. Only bridges that were cold plugged are considered. Set the hotplug handler for the root piix bus directly when realizing. Overwrite the hotplug handler of bridges when coldplugging them. This will now make sure that the ACPI PCI hotplug handler is also called for cold plugged devices (also on bridges) but not for bridges that were hotplugged (keeping the current behavior). Reviewed-by: Igor Mammedov <imammedo@redhat.com> Signed-off-by: David Hildenbrand <david@redhat.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Diffstat (limited to 'hw/acpi/pcihp.c')
-rw-r--r--hw/acpi/pcihp.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c
index 5e7cef173c..05e3f8d11e 100644
--- a/hw/acpi/pcihp.c
+++ b/hw/acpi/pcihp.c
@@ -30,6 +30,7 @@
#include "hw/hw.h"
#include "hw/i386/pc.h"
#include "hw/pci/pci.h"
+#include "hw/pci/pci_bridge.h"
#include "hw/acpi/acpi.h"
#include "sysemu/sysemu.h"
#include "exec/address-spaces.h"
@@ -240,6 +241,20 @@ void acpi_pcihp_device_plug_cb(HotplugHandler *hotplug_dev, AcpiPciHpState *s,
* it is present on boot, no hotplug event is necessary. We do send an
* event when the device is disabled later. */
if (!dev->hotplugged) {
+ /*
+ * Overwrite the default hotplug handler with the ACPI PCI one
+ * for cold plugged bridges only.
+ */
+ if (!s->legacy_piix &&
+ object_dynamic_cast(OBJECT(dev), TYPE_PCI_BRIDGE)) {
+ PCIBus *sec = pci_bridge_get_sec_bus(PCI_BRIDGE(pdev));
+
+ qbus_set_hotplug_handler(BUS(sec), DEVICE(hotplug_dev),
+ &error_abort);
+ /* We don't have to overwrite any other hotplug handler yet */
+ assert(QLIST_EMPTY(&sec->child));
+ }
+
return;
}