aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/acpica/nsxfeval.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/acpica/nsxfeval.c')
-rw-r--r--drivers/acpi/acpica/nsxfeval.c96
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
460acpi_walk_namespace(acpi_object_type type, 463acpi_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;