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 */