diff options
author | Bob Moore <robert.moore@intel.com> | 2008-04-10 11:06:39 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2008-04-22 14:29:24 -0400 |
commit | 53cf174409a24e8388e1d554d27436275fc81fe7 (patch) | |
tree | 52883d192ba1b4bd978a8ca9d30af1e533679e70 /drivers/acpi/namespace | |
parent | 1c12a7dde1752f2c40fe170cabff463a0b362720 (diff) |
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>
Diffstat (limited to 'drivers/acpi/namespace')
-rw-r--r-- | drivers/acpi/namespace/nsaccess.c | 96 |
1 files changed, 60 insertions, 36 deletions
diff --git a/drivers/acpi/namespace/nsaccess.c b/drivers/acpi/namespace/nsaccess.c index 32a01673cae8..54852fbfc878 100644 --- a/drivers/acpi/namespace/nsaccess.c +++ b/drivers/acpi/namespace/nsaccess.c | |||
@@ -581,44 +581,68 @@ acpi_ns_lookup(union acpi_generic_state *scope_info, | |||
581 | return_ACPI_STATUS(status); | 581 | return_ACPI_STATUS(status); |
582 | } | 582 | } |
583 | 583 | ||
584 | /* | 584 | /* More segments to follow? */ |
585 | * Sanity typecheck of the target object: | 585 | |
586 | * | 586 | if (num_segments > 0) { |
587 | * If 1) This is the last segment (num_segments == 0) | 587 | /* |
588 | * 2) And we are looking for a specific type | 588 | * If we have an alias to an object that opens a scope (such as a |
589 | * (Not checking for TYPE_ANY) | 589 | * device or processor), we need to dereference the alias here so that |
590 | * 3) Which is not an alias | 590 | * we can access any children of the original node (via the remaining |
591 | * 4) Which is not a local type (TYPE_SCOPE) | 591 | * segments). |
592 | * 5) And the type of target object is known (not TYPE_ANY) | 592 | */ |
593 | * 6) And target object does not match what we are looking for | 593 | if (this_node->type == ACPI_TYPE_LOCAL_ALIAS) { |
594 | * | 594 | if (acpi_ns_opens_scope |
595 | * Then we have a type mismatch. Just warn and ignore it. | 595 | (((struct acpi_namespace_node *)this_node-> |
596 | */ | 596 | object)->type)) { |
597 | if ((num_segments == 0) && | 597 | this_node = |
598 | (type_to_check_for != ACPI_TYPE_ANY) && | 598 | (struct acpi_namespace_node *) |
599 | (type_to_check_for != ACPI_TYPE_LOCAL_ALIAS) && | 599 | this_node->object; |
600 | (type_to_check_for != ACPI_TYPE_LOCAL_METHOD_ALIAS) && | 600 | } |
601 | (type_to_check_for != ACPI_TYPE_LOCAL_SCOPE) && | 601 | } |
602 | (this_node->type != ACPI_TYPE_ANY) && | ||
603 | (this_node->type != type_to_check_for)) { | ||
604 | |||
605 | /* Complain about a type mismatch */ | ||
606 | |||
607 | ACPI_WARNING((AE_INFO, | ||
608 | "NsLookup: Type mismatch on %4.4s (%s), searching for (%s)", | ||
609 | ACPI_CAST_PTR(char, &simple_name), | ||
610 | acpi_ut_get_type_name(this_node->type), | ||
611 | acpi_ut_get_type_name | ||
612 | (type_to_check_for))); | ||
613 | } | 602 | } |
614 | 603 | ||
615 | /* | 604 | /* Special handling for the last segment (num_segments == 0) */ |
616 | * If this is the last name segment and we are not looking for a | 605 | |
617 | * specific type, but the type of found object is known, use that type | 606 | else { |
618 | * to see if it opens a scope. | 607 | /* |
619 | */ | 608 | * Sanity typecheck of the target object: |
620 | if ((num_segments == 0) && (type == ACPI_TYPE_ANY)) { | 609 | * |
621 | type = this_node->type; | 610 | * If 1) This is the last segment (num_segments == 0) |
611 | * 2) And we are looking for a specific type | ||
612 | * (Not checking for TYPE_ANY) | ||
613 | * 3) Which is not an alias | ||
614 | * 4) Which is not a local type (TYPE_SCOPE) | ||
615 | * 5) And the type of target object is known (not TYPE_ANY) | ||
616 | * 6) And target object does not match what we are looking for | ||
617 | * | ||
618 | * Then we have a type mismatch. Just warn and ignore it. | ||
619 | */ | ||
620 | if ((type_to_check_for != ACPI_TYPE_ANY) && | ||
621 | (type_to_check_for != ACPI_TYPE_LOCAL_ALIAS) && | ||
622 | (type_to_check_for != ACPI_TYPE_LOCAL_METHOD_ALIAS) | ||
623 | && (type_to_check_for != ACPI_TYPE_LOCAL_SCOPE) | ||
624 | && (this_node->type != ACPI_TYPE_ANY) | ||
625 | && (this_node->type != type_to_check_for)) { | ||
626 | |||
627 | /* Complain about a type mismatch */ | ||
628 | |||
629 | ACPI_WARNING((AE_INFO, | ||
630 | "NsLookup: Type mismatch on %4.4s (%s), searching for (%s)", | ||
631 | ACPI_CAST_PTR(char, &simple_name), | ||
632 | acpi_ut_get_type_name(this_node-> | ||
633 | type), | ||
634 | acpi_ut_get_type_name | ||
635 | (type_to_check_for))); | ||
636 | } | ||
637 | |||
638 | /* | ||
639 | * If this is the last name segment and we are not looking for a | ||
640 | * specific type, but the type of found object is known, use that type | ||
641 | * to (later) see if it opens a scope. | ||
642 | */ | ||
643 | if (type == ACPI_TYPE_ANY) { | ||
644 | type = this_node->type; | ||
645 | } | ||
622 | } | 646 | } |
623 | 647 | ||
624 | /* Point to next name segment and make this node current */ | 648 | /* Point to next name segment and make this node current */ |