x86: pcihp: fix missing PCNT callchain when intermediate root-port has 'hotplug=off' set
Beside BSEL numbers change (due to 2 extra root-ports in q35/miltibridge test), following change is expected: Scope (\_SB.PCI0) { ... + Scope (S50) + { + Scope (S00) + { + Method (PCNT, 0, NotSerialized) + { + BNUM = Zero + DVNT (PCIU, One) + DVNT (PCID, 0x03) + } + } + + Method (PCNT, 0, NotSerialized) + { + ^S00.PCNT + } + } ... Method (PCNT, 0, NotSerialized) { + ^S50.PCNT () ^S13.PCNT () ^S12.PCNT () ^S11.PCNT () I practice [1] hasn't broke anything since on hardware side we unset hotplug_handler on such intermediate port => hotplug behind it has not been properly wired and as result not worked. 1) Fixes: ddab4d3fae4e8 ("pcihp: compose PCNT callchain right before its user _GPE._E01") Signed-off-by: Igor Mammedov <imammedo@redhat.com> Message-Id: <20230302161543.286002-8-imammedo@redhat.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
parent
0c3bf7c431
commit
11215a349e
@ -517,17 +517,25 @@ static bool build_append_notfication_callback(Aml *parent_scope,
|
|||||||
PCIBus *sec;
|
PCIBus *sec;
|
||||||
QObject *bsel;
|
QObject *bsel;
|
||||||
int nr_notifiers = 0;
|
int nr_notifiers = 0;
|
||||||
|
GQueue *pcnt_bus_list = g_queue_new();
|
||||||
|
|
||||||
QLIST_FOREACH(sec, &bus->child, sibling) {
|
QLIST_FOREACH(sec, &bus->child, sibling) {
|
||||||
Aml *br_scope = aml_scope("S%.02X", sec->parent_dev->devfn);
|
Aml *br_scope = aml_scope("S%.02X", sec->parent_dev->devfn);
|
||||||
if (pci_bus_is_root(sec) ||
|
if (pci_bus_is_root(sec)) {
|
||||||
!object_property_find(OBJECT(sec), ACPI_PCIHP_PROP_BSEL)) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
nr_notifiers = nr_notifiers +
|
nr_notifiers = nr_notifiers +
|
||||||
build_append_notfication_callback(br_scope, sec);
|
build_append_notfication_callback(br_scope, sec);
|
||||||
|
/*
|
||||||
|
* add new child scope to parent
|
||||||
|
* and keep track of bus that have PCNT,
|
||||||
|
* bus list is used later to call children PCNTs from this level PCNT
|
||||||
|
*/
|
||||||
|
if (nr_notifiers) {
|
||||||
|
g_queue_push_tail(pcnt_bus_list, sec);
|
||||||
aml_append(parent_scope, br_scope);
|
aml_append(parent_scope, br_scope);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Append PCNT method to notify about events on local and child buses.
|
* Append PCNT method to notify about events on local and child buses.
|
||||||
@ -550,17 +558,13 @@ static bool build_append_notfication_callback(Aml *parent_scope,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Notify about child bus events in any case */
|
/* Notify about child bus events in any case */
|
||||||
QLIST_FOREACH(sec, &bus->child, sibling) {
|
while ((sec = g_queue_pop_head(pcnt_bus_list))) {
|
||||||
if (pci_bus_is_root(sec) ||
|
|
||||||
!object_property_find(OBJECT(sec), ACPI_PCIHP_PROP_BSEL)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
aml_append(method, aml_name("^S%.02X.PCNT", sec->parent_dev->devfn));
|
aml_append(method, aml_name("^S%.02X.PCNT", sec->parent_dev->devfn));
|
||||||
}
|
}
|
||||||
|
|
||||||
aml_append(parent_scope, method);
|
aml_append(parent_scope, method);
|
||||||
qobject_unref(bsel);
|
qobject_unref(bsel);
|
||||||
|
g_queue_free(pcnt_bus_list);
|
||||||
return !!nr_notifiers;
|
return !!nr_notifiers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user