summaryrefslogtreecommitdiffstats
path: root/hw/i386
diff options
context:
space:
mode:
authorAni Sinha2020-09-18 10:41:03 +0200
committerMichael S. Tsirkin2020-09-29 09:06:12 +0200
commit15a5b25408538172bd1dafae373c729a82a1e86d (patch)
tree3f926ef1ca1b3b30b0c3f4b31b991c7c2064b507 /hw/i386
parentFix a gap where acpi_pcihp_find_hotplug_bus() returns a non-hotpluggable bus (diff)
downloadqemu-15a5b25408538172bd1dafae373c729a82a1e86d.tar.gz
qemu-15a5b25408538172bd1dafae373c729a82a1e86d.tar.xz
qemu-15a5b25408538172bd1dafae373c729a82a1e86d.zip
i440fx/acpi: do not add hotplug related amls for cold plugged bridges
Cold plugged bridges are not hot unpluggable, even when their hotplug property (acpi-pci-hotplug-with-bridge-support) is turned off. Please see the function acpi_pcihp_pc_no_hotplug(). However, with the current implementaton, Windows would try to hot-unplug a pci bridge when it's hotplug switch is off. This is regardless of whether there are devices attached to the bridge. This is because we add ACPI code like _EJ0 etc for the pci slot where the bridge is cold plugged. In this fix, we identify a cold plugged bridge and for cold plugged bridges, we do not add the appropriate ACPI methods that are used by the OS to identify a hot-pluggable/unpluggable pci device. After this change, Windows does not detect the cold plugged pci bridge as ejectable. As a result of the patch, the following are the changes to the DSDT ACPI table: @@ -858,38 +858,33 @@ Return (Zero) } Method (_S2D, 0, NotSerialized) // _S2D: S2 Device State { Return (Zero) } Method (_S3D, 0, NotSerialized) // _S3D: S3 Device State { Return (Zero) } } Device (S18) { - Name (_SUN, 0x03) // _SUN: Slot User Number Name (_ADR, 0x00030000) // _ADR: Address - Method (_EJ0, 1, NotSerialized) // _EJx: Eject Device - { - PCEJ (BSEL, _SUN) - } } Device (S20) { Name (_SUN, 0x04) // _SUN: Slot User Number Name (_ADR, 0x00040000) // _ADR: Address Method (_EJ0, 1, NotSerialized) // _EJx: Eject Device { PCEJ (BSEL, _SUN) } } Device (S28) { Name (_SUN, 0x05) // _SUN: Slot User Number Name (_ADR, 0x00050000) // _ADR: Address @@ -1148,37 +1143,32 @@ PCEJ (BSEL, _SUN) } } Device (SF8) { Name (_SUN, 0x1F) // _SUN: Slot User Number Name (_ADR, 0x001F0000) // _ADR: Address Method (_EJ0, 1, NotSerialized) // _EJx: Eject Device { PCEJ (BSEL, _SUN) } } Method (DVNT, 2, NotSerialized) { - If ((Arg0 & 0x08)) - { - Notify (S18, Arg1) - } - If ((Arg0 & 0x10)) { Notify (S20, Arg1) } If ((Arg0 & 0x20)) { Notify (S28, Arg1) } If ((Arg0 & 0x40)) { Notify (S30, Arg1) } If ((Arg0 & 0x80)) While at it, I have also updated a stale comment. Signed-off-by: Ani Sinha <ani@anisinha.ca> Suggested-by: Julia Suvorova <jusual@redhat.com> Reviewed-by: Julia Suvorova <jusual@redhat.com> Reviewed-by: Igor Mammedov <imammedo@redhat.com> Message-Id: <20200918084111.15339-6-ani@anisinha.ca> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Diffstat (limited to 'hw/i386')
-rw-r--r--hw/i386/acpi-build.c12
1 files changed, 6 insertions, 6 deletions
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index b49d360ab2..2b17843837 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -365,6 +365,7 @@ static void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus,
int slot = PCI_SLOT(i);
bool hotplug_enabled_dev;
bool bridge_in_acpi;
+ bool cold_plugged_bridge;
if (!pdev) {
if (bsel) { /* add hotplug slots for non present devices */
@@ -386,15 +387,14 @@ static void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus,
pc = PCI_DEVICE_GET_CLASS(pdev);
dc = DEVICE_GET_CLASS(pdev);
- /* When hotplug for bridges is enabled, bridges are
- * described in ACPI separately (see build_pci_bus_end).
- * In this case they aren't themselves hot-pluggable.
+ /*
+ * Cold plugged bridges aren't themselves hot-pluggable.
* Hotplugged bridges *are* hot-pluggable.
*/
- bridge_in_acpi = pc->is_bridge && pcihp_bridge_en &&
- !DEVICE(pdev)->hotplugged;
+ cold_plugged_bridge = pc->is_bridge && !DEVICE(pdev)->hotplugged;
+ bridge_in_acpi = cold_plugged_bridge && pcihp_bridge_en;
- hotplug_enabled_dev = bsel && dc->hotpluggable && !bridge_in_acpi;
+ hotplug_enabled_dev = bsel && dc->hotpluggable && !cold_plugged_bridge;
if (pc->class_id == PCI_CLASS_BRIDGE_ISA) {
continue;