Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 27922b4260f65d317aabda37e42bbbff > files > 87

kernel-2.6.18-238.el5.src.rpm

From: peterm@redhat.com <peterm@redhat.com>
Date: Tue, 26 Aug 2008 12:38:28 -0400
Subject: [acpi] error attaching device data
Message-id: 200808261638.m7QGcSXV020706@dhcp-100-18-167.bos.redhat.com
O-Subject: [RHEL 5.3 Patch] ACPI: Error attaching device data
Bugzilla: 459670
RH-Acked-by: John Feeney <jfeeney@redhat.com>
RH-Acked-by: Prarit Bhargava <prarit@redhat.com>

Hello,

Some of the newer Nehalem based systems declare their CPU DSDT entries
as type "Alias".  During boot this will cause RHEL to log an,
"Error attaching device data", error message when trying to add the
duplicate device node for the individual CPU entries.  This patch taken
from upstream resolves the problem by pointing the Alias CPU entries to
the original NS nodes attached object.  Affected systems will have the
problematic, "Alias (P00[n], CPU[n])", entries in their DSDT.dsl files

Problem reported by SEG, and requested for inclusion in R5.3.  Patch
provided in the bug report by Jeremy West.

Testing: A brew built kernel was tested in-house on HP xw6800, xw8800
workstations, and Intel Tylersberg/Nehalem based systems.  Tested by Sun
on the system which showed the original problem.  No problems in
testing to report.

Brew build id: 1436965

Upstream Commit: 53cf174409a24e8388e1d554d27436275fc81fe7

Resolves bug: 459670

https://bugzilla.redhat.com/show_bug.cgi?id=459670

Peter-

diff --git a/drivers/acpi/executer/excreate.c b/drivers/acpi/executer/excreate.c
index 34eec82..13143bf 100644
--- a/drivers/acpi/executer/excreate.c
+++ b/drivers/acpi/executer/excreate.c
@@ -97,6 +97,9 @@ acpi_status acpi_ex_create_alias(struct acpi_walk_state *walk_state)
 	 * to the original Node.
 	 */
 	switch (target_node->type) {
+
+		/* For these types, the sub-object can change dynamically via a Store */
+
 	case ACPI_TYPE_INTEGER:
 	case ACPI_TYPE_STRING:
 	case ACPI_TYPE_BUFFER:
@@ -104,9 +107,18 @@ acpi_status acpi_ex_create_alias(struct acpi_walk_state *walk_state)
 	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
-		 * NS node, not the object itself.  This is because for these
-		 * types, the object can change dynamically via a Store.
+		 * NS node, not the object itself.
 		 */
 		alias_node->type = ACPI_TYPE_LOCAL_ALIAS;
 		alias_node->object =
@@ -116,9 +128,7 @@ acpi_status acpi_ex_create_alias(struct acpi_walk_state *walk_state)
 	case ACPI_TYPE_METHOD:
 
 		/*
-		 * The new alias has the type ALIAS and points to the original
-		 * NS node, not the object itself.  This is because for these
-		 * types, the object can change dynamically via a Store.
+		 * Control method aliases need to be differentiated
 		 */
 		alias_node->type = ACPI_TYPE_LOCAL_METHOD_ALIAS;
 		alias_node->object =
diff --git a/drivers/acpi/namespace/nsaccess.c b/drivers/acpi/namespace/nsaccess.c
index c1c6c23..913da3d 100644
--- a/drivers/acpi/namespace/nsaccess.c
+++ b/drivers/acpi/namespace/nsaccess.c
@@ -586,44 +586,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)) {
-
-			/* 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)));
+		/* 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;
+				}
+			}
 		}
 
-		/*
-		 * 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 */