ACPICA: Fix for Alias operator to see target child objects

Fixed a problem with the Alias operator when the target of the
alias is a named ASL operator that opens a new scope -- Scope,
Device, PowerResource, Processor, and ThermalZone. In these cases,
any children of the original operator could not be accessed via
the alias, potentially causing unexpected AE_NOT_FOUND exceptions.

Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Alexey Starikovskiy <astarikovskiy@suse.de>
Signed-off-by: Len Brown <len.brown@intel.com>
这个提交包含在:
Bob Moore
2008-04-10 19:06:39 +04:00
提交者 Len Brown
父节点 1c12a7dde1
当前提交 53cf174409
修改 2 个文件,包含 74 行新增40 行删除

查看文件

@@ -581,44 +581,68 @@ acpi_ns_lookup(union acpi_generic_state *scope_info,
return_ACPI_STATUS(status);
}
/*
* Sanity typecheck of the target object:
*
* If 1) This is the last segment (num_segments == 0)
* 2) And we are looking for a specific type
* (Not checking for TYPE_ANY)
* 3) Which is not an alias
* 4) Which is not a local type (TYPE_SCOPE)
* 5) And the type of target object is known (not TYPE_ANY)
* 6) And target object does not match what we are looking for
*
* Then we have a type mismatch. Just warn and ignore it.
*/
if ((num_segments == 0) &&
(type_to_check_for != ACPI_TYPE_ANY) &&
(type_to_check_for != ACPI_TYPE_LOCAL_ALIAS) &&
(type_to_check_for != ACPI_TYPE_LOCAL_METHOD_ALIAS) &&
(type_to_check_for != ACPI_TYPE_LOCAL_SCOPE) &&
(this_node->type != ACPI_TYPE_ANY) &&
(this_node->type != type_to_check_for)) {
/* More segments to follow? */
/* Complain about a type mismatch */
ACPI_WARNING((AE_INFO,
"NsLookup: Type mismatch on %4.4s (%s), searching for (%s)",
ACPI_CAST_PTR(char, &simple_name),
acpi_ut_get_type_name(this_node->type),
acpi_ut_get_type_name
(type_to_check_for)));
if (num_segments > 0) {
/*
* If we have an alias to an object that opens a scope (such as a
* device or processor), we need to dereference the alias here so that
* we can access any children of the original node (via the remaining
* segments).
*/
if (this_node->type == ACPI_TYPE_LOCAL_ALIAS) {
if (acpi_ns_opens_scope
(((struct acpi_namespace_node *)this_node->
object)->type)) {
this_node =
(struct acpi_namespace_node *)
this_node->object;
}
}
}
/*
* If this is the last name segment and we are not looking for a
* specific type, but the type of found object is known, use that type
* to see if it opens a scope.
*/
if ((num_segments == 0) && (type == ACPI_TYPE_ANY)) {
type = this_node->type;
/* Special handling for the last segment (num_segments == 0) */
else {
/*
* Sanity typecheck of the target object:
*
* If 1) This is the last segment (num_segments == 0)
* 2) And we are looking for a specific type
* (Not checking for TYPE_ANY)
* 3) Which is not an alias
* 4) Which is not a local type (TYPE_SCOPE)
* 5) And the type of target object is known (not TYPE_ANY)
* 6) And target object does not match what we are looking for
*
* Then we have a type mismatch. Just warn and ignore it.
*/
if ((type_to_check_for != ACPI_TYPE_ANY) &&
(type_to_check_for != ACPI_TYPE_LOCAL_ALIAS) &&
(type_to_check_for != ACPI_TYPE_LOCAL_METHOD_ALIAS)
&& (type_to_check_for != ACPI_TYPE_LOCAL_SCOPE)
&& (this_node->type != ACPI_TYPE_ANY)
&& (this_node->type != type_to_check_for)) {
/* Complain about a type mismatch */
ACPI_WARNING((AE_INFO,
"NsLookup: Type mismatch on %4.4s (%s), searching for (%s)",
ACPI_CAST_PTR(char, &simple_name),
acpi_ut_get_type_name(this_node->
type),
acpi_ut_get_type_name
(type_to_check_for)));
}
/*
* If this is the last name segment and we are not looking for a
* specific type, but the type of found object is known, use that type
* to (later) see if it opens a scope.
*/
if (type == ACPI_TYPE_ANY) {
type = this_node->type;
}
}
/* Point to next name segment and make this node current */