diff options
Diffstat (limited to 'drivers/acpi/acpica/nsxfeval.c')
-rw-r--r-- | drivers/acpi/acpica/nsxfeval.c | 96 |
1 files changed, 58 insertions, 38 deletions
diff --git a/drivers/acpi/acpica/nsxfeval.c b/drivers/acpi/acpica/nsxfeval.c index 4929dbdbc8f0..ebef8a7fd707 100644 --- a/drivers/acpi/acpica/nsxfeval.c +++ b/drivers/acpi/acpica/nsxfeval.c | |||
@@ -6,7 +6,7 @@ | |||
6 | ******************************************************************************/ | 6 | ******************************************************************************/ |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * Copyright (C) 2000 - 2008, Intel Corp. | 9 | * Copyright (C) 2000 - 2010, Intel Corp. |
10 | * All rights reserved. | 10 | * All rights reserved. |
11 | * | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
@@ -190,7 +190,7 @@ acpi_evaluate_object(acpi_handle handle, | |||
190 | 190 | ||
191 | /* Convert and validate the device handle */ | 191 | /* Convert and validate the device handle */ |
192 | 192 | ||
193 | info->prefix_node = acpi_ns_map_handle_to_node(handle); | 193 | info->prefix_node = acpi_ns_validate_handle(handle); |
194 | if (!info->prefix_node) { | 194 | if (!info->prefix_node) { |
195 | status = AE_BAD_PARAMETER; | 195 | status = AE_BAD_PARAMETER; |
196 | goto cleanup; | 196 | goto cleanup; |
@@ -433,8 +433,11 @@ static void acpi_ns_resolve_references(struct acpi_evaluate_info *info) | |||
433 | * PARAMETERS: Type - acpi_object_type to search for | 433 | * PARAMETERS: Type - acpi_object_type to search for |
434 | * start_object - Handle in namespace where search begins | 434 | * start_object - Handle in namespace where search begins |
435 | * max_depth - Depth to which search is to reach | 435 | * max_depth - Depth to which search is to reach |
436 | * user_function - Called when an object of "Type" is found | 436 | * pre_order_visit - Called during tree pre-order visit |
437 | * Context - Passed to user function | 437 | * when an object of "Type" is found |
438 | * post_order_visit - Called during tree post-order visit | ||
439 | * when an object of "Type" is found | ||
440 | * Context - Passed to user function(s) above | ||
438 | * return_value - Location where return value of | 441 | * return_value - Location where return value of |
439 | * user_function is put if terminated early | 442 | * user_function is put if terminated early |
440 | * | 443 | * |
@@ -443,16 +446,16 @@ static void acpi_ns_resolve_references(struct acpi_evaluate_info *info) | |||
443 | * | 446 | * |
444 | * DESCRIPTION: Performs a modified depth-first walk of the namespace tree, | 447 | * DESCRIPTION: Performs a modified depth-first walk of the namespace tree, |
445 | * starting (and ending) at the object specified by start_handle. | 448 | * starting (and ending) at the object specified by start_handle. |
446 | * The user_function is called whenever an object that matches | 449 | * The callback function is called whenever an object that matches |
447 | * the type parameter is found. If the user function returns | 450 | * the type parameter is found. If the callback function returns |
448 | * a non-zero value, the search is terminated immediately and this | 451 | * a non-zero value, the search is terminated immediately and this |
449 | * value is returned to the caller. | 452 | * value is returned to the caller. |
450 | * | 453 | * |
451 | * The point of this procedure is to provide a generic namespace | 454 | * The point of this procedure is to provide a generic namespace |
452 | * walk routine that can be called from multiple places to | 455 | * walk routine that can be called from multiple places to |
453 | * provide multiple services; the User Function can be tailored | 456 | * provide multiple services; the callback function(s) can be |
454 | * to each task, whether it is a print function, a compare | 457 | * tailored to each task, whether it is a print function, |
455 | * function, etc. | 458 | * a compare function, etc. |
456 | * | 459 | * |
457 | ******************************************************************************/ | 460 | ******************************************************************************/ |
458 | 461 | ||
@@ -460,7 +463,8 @@ acpi_status | |||
460 | acpi_walk_namespace(acpi_object_type type, | 463 | acpi_walk_namespace(acpi_object_type type, |
461 | acpi_handle start_object, | 464 | acpi_handle start_object, |
462 | u32 max_depth, | 465 | u32 max_depth, |
463 | acpi_walk_callback user_function, | 466 | acpi_walk_callback pre_order_visit, |
467 | acpi_walk_callback post_order_visit, | ||
464 | void *context, void **return_value) | 468 | void *context, void **return_value) |
465 | { | 469 | { |
466 | acpi_status status; | 470 | acpi_status status; |
@@ -469,7 +473,8 @@ acpi_walk_namespace(acpi_object_type type, | |||
469 | 473 | ||
470 | /* Parameter validation */ | 474 | /* Parameter validation */ |
471 | 475 | ||
472 | if ((type > ACPI_TYPE_LOCAL_MAX) || (!max_depth) || (!user_function)) { | 476 | if ((type > ACPI_TYPE_LOCAL_MAX) || |
477 | (!max_depth) || (!pre_order_visit && !post_order_visit)) { | ||
473 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 478 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
474 | } | 479 | } |
475 | 480 | ||
@@ -501,8 +506,9 @@ acpi_walk_namespace(acpi_object_type type, | |||
501 | } | 506 | } |
502 | 507 | ||
503 | status = acpi_ns_walk_namespace(type, start_object, max_depth, | 508 | status = acpi_ns_walk_namespace(type, start_object, max_depth, |
504 | ACPI_NS_WALK_UNLOCK, user_function, | 509 | ACPI_NS_WALK_UNLOCK, pre_order_visit, |
505 | context, return_value); | 510 | post_order_visit, context, |
511 | return_value); | ||
506 | 512 | ||
507 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | 513 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); |
508 | 514 | ||
@@ -546,7 +552,7 @@ acpi_ns_get_device_callback(acpi_handle obj_handle, | |||
546 | return (status); | 552 | return (status); |
547 | } | 553 | } |
548 | 554 | ||
549 | node = acpi_ns_map_handle_to_node(obj_handle); | 555 | node = acpi_ns_validate_handle(obj_handle); |
550 | status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | 556 | status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); |
551 | if (ACPI_FAILURE(status)) { | 557 | if (ACPI_FAILURE(status)) { |
552 | return (status); | 558 | return (status); |
@@ -556,25 +562,20 @@ acpi_ns_get_device_callback(acpi_handle obj_handle, | |||
556 | return (AE_BAD_PARAMETER); | 562 | return (AE_BAD_PARAMETER); |
557 | } | 563 | } |
558 | 564 | ||
559 | /* Run _STA to determine if device is present */ | 565 | /* |
560 | 566 | * First, filter based on the device HID and CID. | |
561 | status = acpi_ut_execute_STA(node, &flags); | 567 | * |
562 | if (ACPI_FAILURE(status)) { | 568 | * 01/2010: For this case where a specific HID is requested, we don't |
563 | return (AE_CTRL_DEPTH); | 569 | * want to run _STA until we have an actual HID match. Thus, we will |
564 | } | 570 | * not unnecessarily execute _STA on devices for which the caller |
565 | 571 | * doesn't care about. Previously, _STA was executed unconditionally | |
566 | if (!(flags & ACPI_STA_DEVICE_PRESENT) && | 572 | * on all devices found here. |
567 | !(flags & ACPI_STA_DEVICE_FUNCTIONING)) { | 573 | * |
568 | /* | 574 | * A side-effect of this change is that now we will continue to search |
569 | * Don't examine the children of the device only when the | 575 | * for a matching HID even under device trees where the parent device |
570 | * device is neither present nor functional. See ACPI spec, | 576 | * would have returned a _STA that indicates it is not present or |
571 | * description of _STA for more information. | 577 | * not functioning (thus aborting the search on that branch). |
572 | */ | 578 | */ |
573 | return (AE_CTRL_DEPTH); | ||
574 | } | ||
575 | |||
576 | /* Filter based on device HID & CID */ | ||
577 | |||
578 | if (info->hid != NULL) { | 579 | if (info->hid != NULL) { |
579 | status = acpi_ut_execute_HID(node, &hid); | 580 | status = acpi_ut_execute_HID(node, &hid); |
580 | if (status == AE_NOT_FOUND) { | 581 | if (status == AE_NOT_FOUND) { |
@@ -614,6 +615,25 @@ acpi_ns_get_device_callback(acpi_handle obj_handle, | |||
614 | } | 615 | } |
615 | } | 616 | } |
616 | 617 | ||
618 | /* Run _STA to determine if device is present */ | ||
619 | |||
620 | status = acpi_ut_execute_STA(node, &flags); | ||
621 | if (ACPI_FAILURE(status)) { | ||
622 | return (AE_CTRL_DEPTH); | ||
623 | } | ||
624 | |||
625 | if (!(flags & ACPI_STA_DEVICE_PRESENT) && | ||
626 | !(flags & ACPI_STA_DEVICE_FUNCTIONING)) { | ||
627 | /* | ||
628 | * Don't examine the children of the device only when the | ||
629 | * device is neither present nor functional. See ACPI spec, | ||
630 | * description of _STA for more information. | ||
631 | */ | ||
632 | return (AE_CTRL_DEPTH); | ||
633 | } | ||
634 | |||
635 | /* We have a valid device, invoke the user function */ | ||
636 | |||
617 | status = info->user_function(obj_handle, nesting_level, info->context, | 637 | status = info->user_function(obj_handle, nesting_level, info->context, |
618 | return_value); | 638 | return_value); |
619 | return (status); | 639 | return (status); |
@@ -681,8 +701,8 @@ acpi_get_devices(const char *HID, | |||
681 | 701 | ||
682 | status = acpi_ns_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, | 702 | status = acpi_ns_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, |
683 | ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK, | 703 | ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK, |
684 | acpi_ns_get_device_callback, &info, | 704 | acpi_ns_get_device_callback, NULL, |
685 | return_value); | 705 | &info, return_value); |
686 | 706 | ||
687 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | 707 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); |
688 | return_ACPI_STATUS(status); | 708 | return_ACPI_STATUS(status); |
@@ -723,7 +743,7 @@ acpi_attach_data(acpi_handle obj_handle, | |||
723 | 743 | ||
724 | /* Convert and validate the handle */ | 744 | /* Convert and validate the handle */ |
725 | 745 | ||
726 | node = acpi_ns_map_handle_to_node(obj_handle); | 746 | node = acpi_ns_validate_handle(obj_handle); |
727 | if (!node) { | 747 | if (!node) { |
728 | status = AE_BAD_PARAMETER; | 748 | status = AE_BAD_PARAMETER; |
729 | goto unlock_and_exit; | 749 | goto unlock_and_exit; |
@@ -769,7 +789,7 @@ acpi_detach_data(acpi_handle obj_handle, acpi_object_handler handler) | |||
769 | 789 | ||
770 | /* Convert and validate the handle */ | 790 | /* Convert and validate the handle */ |
771 | 791 | ||
772 | node = acpi_ns_map_handle_to_node(obj_handle); | 792 | node = acpi_ns_validate_handle(obj_handle); |
773 | if (!node) { | 793 | if (!node) { |
774 | status = AE_BAD_PARAMETER; | 794 | status = AE_BAD_PARAMETER; |
775 | goto unlock_and_exit; | 795 | goto unlock_and_exit; |
@@ -816,7 +836,7 @@ acpi_get_data(acpi_handle obj_handle, acpi_object_handler handler, void **data) | |||
816 | 836 | ||
817 | /* Convert and validate the handle */ | 837 | /* Convert and validate the handle */ |
818 | 838 | ||
819 | node = acpi_ns_map_handle_to_node(obj_handle); | 839 | node = acpi_ns_validate_handle(obj_handle); |
820 | if (!node) { | 840 | if (!node) { |
821 | status = AE_BAD_PARAMETER; | 841 | status = AE_BAD_PARAMETER; |
822 | goto unlock_and_exit; | 842 | goto unlock_and_exit; |