Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 53cf1744 authored by Bob Moore's avatar Bob Moore Committed by Len Brown
Browse files

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: default avatarBob Moore <robert.moore@intel.com>
Signed-off-by: default avatarAlexey Starikovskiy <astarikovskiy@suse.de>
Signed-off-by: default avatarLen Brown <len.brown@intel.com>
parent 1c12a7dd
Loading
Loading
Loading
Loading
+15 −5
Original line number Original line Diff line number Diff line
@@ -96,16 +96,28 @@ acpi_status acpi_ex_create_alias(struct acpi_walk_state *walk_state)
	 * to the original Node.
	 * to the original Node.
	 */
	 */
	switch (target_node->type) {
	switch (target_node->type) {

		/* For these types, the sub-object can change dynamically via a Store */

	case ACPI_TYPE_INTEGER:
	case ACPI_TYPE_INTEGER:
	case ACPI_TYPE_STRING:
	case ACPI_TYPE_STRING:
	case ACPI_TYPE_BUFFER:
	case ACPI_TYPE_BUFFER:
	case ACPI_TYPE_PACKAGE:
	case ACPI_TYPE_PACKAGE:
	case ACPI_TYPE_BUFFER_FIELD:
	case ACPI_TYPE_BUFFER_FIELD:


		/*
		 * These types open a new scope, so we need the NS node in order to access
		 * any children.
		 */
	case ACPI_TYPE_DEVICE:
	case ACPI_TYPE_POWER:
	case ACPI_TYPE_PROCESSOR:
	case ACPI_TYPE_THERMAL:
	case ACPI_TYPE_LOCAL_SCOPE:

		/*
		/*
		 * The new alias has the type ALIAS and points to the original
		 * The new alias has the type ALIAS and points to the original
		 * NS node, not the object itself.  This is because for these
		 * NS node, not the object itself.
		 * types, the object can change dynamically via a Store.
		 */
		 */
		alias_node->type = ACPI_TYPE_LOCAL_ALIAS;
		alias_node->type = ACPI_TYPE_LOCAL_ALIAS;
		alias_node->object =
		alias_node->object =
@@ -115,9 +127,7 @@ acpi_status acpi_ex_create_alias(struct acpi_walk_state *walk_state)
	case ACPI_TYPE_METHOD:
	case ACPI_TYPE_METHOD:


		/*
		/*
		 * The new alias has the type ALIAS and points to the original
		 * Control method aliases need to be differentiated
		 * NS node, not the object itself.  This is because for these
		 * types, the object can change dynamically via a Store.
		 */
		 */
		alias_node->type = ACPI_TYPE_LOCAL_METHOD_ALIAS;
		alias_node->type = ACPI_TYPE_LOCAL_METHOD_ALIAS;
		alias_node->object =
		alias_node->object =
+60 −36
Original line number Original line Diff line number Diff line
@@ -581,6 +581,29 @@ acpi_ns_lookup(union acpi_generic_state *scope_info,
			return_ACPI_STATUS(status);
			return_ACPI_STATUS(status);
		}
		}


		/* More segments to follow? */

		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;
				}
			}
		}

		/* Special handling for the last segment (num_segments == 0) */

		else {
			/*
			/*
			 * Sanity typecheck of the target object:
			 * Sanity typecheck of the target object:
			 *
			 *
@@ -594,20 +617,20 @@ acpi_ns_lookup(union acpi_generic_state *scope_info,
			 *
			 *
			 * Then we have a type mismatch. Just warn and ignore it.
			 * Then we have a type mismatch. Just warn and ignore it.
			 */
			 */
		if ((num_segments == 0) &&
			if ((type_to_check_for != ACPI_TYPE_ANY) &&
		    (type_to_check_for != ACPI_TYPE_ANY) &&
			    (type_to_check_for != ACPI_TYPE_LOCAL_ALIAS) &&
			    (type_to_check_for != ACPI_TYPE_LOCAL_ALIAS) &&
		    (type_to_check_for != ACPI_TYPE_LOCAL_METHOD_ALIAS) &&
			    (type_to_check_for != ACPI_TYPE_LOCAL_METHOD_ALIAS)
		    (type_to_check_for != ACPI_TYPE_LOCAL_SCOPE) &&
			    && (type_to_check_for != ACPI_TYPE_LOCAL_SCOPE)
		    (this_node->type != ACPI_TYPE_ANY) &&
			    && (this_node->type != ACPI_TYPE_ANY)
		    (this_node->type != type_to_check_for)) {
			    && (this_node->type != type_to_check_for)) {


				/* Complain about a type mismatch */
				/* Complain about a type mismatch */


				ACPI_WARNING((AE_INFO,
				ACPI_WARNING((AE_INFO,
					      "NsLookup: Type mismatch on %4.4s (%s), searching for (%s)",
					      "NsLookup: Type mismatch on %4.4s (%s), searching for (%s)",
					      ACPI_CAST_PTR(char, &simple_name),
					      ACPI_CAST_PTR(char, &simple_name),
				      acpi_ut_get_type_name(this_node->type),
					      acpi_ut_get_type_name(this_node->
								    type),
					      acpi_ut_get_type_name
					      acpi_ut_get_type_name
					      (type_to_check_for)));
					      (type_to_check_for)));
			}
			}
@@ -615,11 +638,12 @@ acpi_ns_lookup(union acpi_generic_state *scope_info,
			/*
			/*
			 * If this is the last name segment and we are not looking for a
			 * 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
			 * specific type, but the type of found object is known, use that type
		 * to see if it opens a scope.
			 * to (later) see if it opens a scope.
			 */
			 */
		if ((num_segments == 0) && (type == ACPI_TYPE_ANY)) {
			if (type == ACPI_TYPE_ANY) {
				type = this_node->type;
				type = this_node->type;
			}
			}
		}


		/* Point to next name segment and make this node current */
		/* Point to next name segment and make this node current */