1 /******************************************************************************* 2 * 3 * Module Name: nsxfeval - Public interfaces to the ACPI subsystem 4 * ACPI Object evaluation interfaces 5 * 6 ******************************************************************************/ 7 8 /* 9 * Copyright (C) 2000 - 2017, Intel Corp. 10 * All rights reserved. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions, and the following disclaimer, 17 * without modification. 18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 19 * substantially similar to the "NO WARRANTY" disclaimer below 20 * ("Disclaimer") and any redistribution must be conditioned upon 21 * including a substantially similar Disclaimer requirement for further 22 * binary redistribution. 23 * 3. Neither the names of the above-listed copyright holders nor the names 24 * of any contributors may be used to endorse or promote products derived 25 * from this software without specific prior written permission. 26 * 27 * Alternatively, this software may be distributed under the terms of the 28 * GNU General Public License ("GPL") version 2 as published by the Free 29 * Software Foundation. 30 * 31 * NO WARRANTY 32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 42 * POSSIBILITY OF SUCH DAMAGES. 43 */ 44 45 #define EXPORT_ACPI_INTERFACES 46 47 #include <acpi/acpi.h> 48 #include "accommon.h" 49 #include "acnamesp.h" 50 #include "acinterp.h" 51 52 #define _COMPONENT ACPI_NAMESPACE 53 ACPI_MODULE_NAME("nsxfeval") 54 55 /* Local prototypes */ 56 static void acpi_ns_resolve_references(struct acpi_evaluate_info *info); 57 58 /******************************************************************************* 59 * 60 * FUNCTION: acpi_evaluate_object_typed 61 * 62 * PARAMETERS: handle - Object handle (optional) 63 * pathname - Object pathname (optional) 64 * external_params - List of parameters to pass to method, 65 * terminated by NULL. May be NULL 66 * if no parameters are being passed. 67 * return_buffer - Where to put method's return value (if 68 * any). If NULL, no value is returned. 69 * return_type - Expected type of return object 70 * 71 * RETURN: Status 72 * 73 * DESCRIPTION: Find and evaluate the given object, passing the given 74 * parameters if necessary. One of "Handle" or "Pathname" must 75 * be valid (non-null) 76 * 77 ******************************************************************************/ 78 79 acpi_status 80 acpi_evaluate_object_typed(acpi_handle handle, 81 acpi_string pathname, 82 struct acpi_object_list *external_params, 83 struct acpi_buffer *return_buffer, 84 acpi_object_type return_type) 85 { 86 acpi_status status; 87 u8 free_buffer_on_error = FALSE; 88 acpi_handle target_handle; 89 char *full_pathname; 90 91 ACPI_FUNCTION_TRACE(acpi_evaluate_object_typed); 92 93 /* Return buffer must be valid */ 94 95 if (!return_buffer) { 96 return_ACPI_STATUS(AE_BAD_PARAMETER); 97 } 98 99 if (return_buffer->length == ACPI_ALLOCATE_BUFFER) { 100 free_buffer_on_error = TRUE; 101 } 102 103 if (pathname) { 104 status = acpi_get_handle(handle, pathname, &target_handle); 105 if (ACPI_FAILURE(status)) { 106 return_ACPI_STATUS(status); 107 } 108 } else { 109 target_handle = handle; 110 } 111 112 full_pathname = acpi_ns_get_external_pathname(target_handle); 113 if (!full_pathname) { 114 return_ACPI_STATUS(AE_NO_MEMORY); 115 } 116 117 /* Evaluate the object */ 118 119 status = acpi_evaluate_object(target_handle, NULL, external_params, 120 return_buffer); 121 if (ACPI_FAILURE(status)) { 122 goto exit; 123 } 124 125 /* Type ANY means "don't care about return value type" */ 126 127 if (return_type == ACPI_TYPE_ANY) { 128 goto exit; 129 } 130 131 if (return_buffer->length == 0) { 132 133 /* Error because caller specifically asked for a return value */ 134 135 ACPI_ERROR((AE_INFO, "%s did not return any object", 136 full_pathname)); 137 status = AE_NULL_OBJECT; 138 goto exit; 139 } 140 141 /* Examine the object type returned from evaluate_object */ 142 143 if (((union acpi_object *)return_buffer->pointer)->type == return_type) { 144 goto exit; 145 } 146 147 /* Return object type does not match requested type */ 148 149 ACPI_ERROR((AE_INFO, 150 "Incorrect return type from %s - received [%s], requested [%s]", 151 full_pathname, 152 acpi_ut_get_type_name(((union acpi_object *)return_buffer-> 153 pointer)->type), 154 acpi_ut_get_type_name(return_type))); 155 156 if (free_buffer_on_error) { 157 /* 158 * Free a buffer created via ACPI_ALLOCATE_BUFFER. 159 * Note: We use acpi_os_free here because acpi_os_allocate was used 160 * to allocate the buffer. This purposefully bypasses the 161 * (optionally enabled) allocation tracking mechanism since we 162 * only want to track internal allocations. 163 */ 164 acpi_os_free(return_buffer->pointer); 165 return_buffer->pointer = NULL; 166 } 167 168 return_buffer->length = 0; 169 status = AE_TYPE; 170 171 exit: 172 ACPI_FREE(full_pathname); 173 return_ACPI_STATUS(status); 174 } 175 176 ACPI_EXPORT_SYMBOL(acpi_evaluate_object_typed) 177 178 /******************************************************************************* 179 * 180 * FUNCTION: acpi_evaluate_object 181 * 182 * PARAMETERS: handle - Object handle (optional) 183 * pathname - Object pathname (optional) 184 * external_params - List of parameters to pass to method, 185 * terminated by NULL. May be NULL 186 * if no parameters are being passed. 187 * return_buffer - Where to put method's return value (if 188 * any). If NULL, no value is returned. 189 * 190 * RETURN: Status 191 * 192 * DESCRIPTION: Find and evaluate the given object, passing the given 193 * parameters if necessary. One of "Handle" or "Pathname" must 194 * be valid (non-null) 195 * 196 ******************************************************************************/ 197 acpi_status 198 acpi_evaluate_object(acpi_handle handle, 199 acpi_string pathname, 200 struct acpi_object_list *external_params, 201 struct acpi_buffer *return_buffer) 202 { 203 acpi_status status; 204 struct acpi_evaluate_info *info; 205 acpi_size buffer_space_needed; 206 u32 i; 207 208 ACPI_FUNCTION_TRACE(acpi_evaluate_object); 209 210 /* Allocate and initialize the evaluation information block */ 211 212 info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info)); 213 if (!info) { 214 return_ACPI_STATUS(AE_NO_MEMORY); 215 } 216 217 /* Convert and validate the device handle */ 218 219 info->prefix_node = acpi_ns_validate_handle(handle); 220 if (!info->prefix_node) { 221 status = AE_BAD_PARAMETER; 222 goto cleanup; 223 } 224 225 /* 226 * Get the actual namespace node for the target object. 227 * Handles these cases: 228 * 229 * 1) Null node, valid pathname from root (absolute path) 230 * 2) Node and valid pathname (path relative to Node) 231 * 3) Node, Null pathname 232 */ 233 if ((pathname) && (ACPI_IS_ROOT_PREFIX(pathname[0]))) { 234 235 /* The path is fully qualified, just evaluate by name */ 236 237 info->prefix_node = NULL; 238 } else if (!handle) { 239 /* 240 * A handle is optional iff a fully qualified pathname is specified. 241 * Since we've already handled fully qualified names above, this is 242 * an error. 243 */ 244 if (!pathname) { 245 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 246 "Both Handle and Pathname are NULL")); 247 } else { 248 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 249 "Null Handle with relative pathname [%s]", 250 pathname)); 251 } 252 253 status = AE_BAD_PARAMETER; 254 goto cleanup; 255 } 256 257 info->relative_pathname = pathname; 258 259 /* 260 * Convert all external objects passed as arguments to the 261 * internal version(s). 262 */ 263 if (external_params && external_params->count) { 264 info->param_count = (u16)external_params->count; 265 266 /* Warn on impossible argument count */ 267 268 if (info->param_count > ACPI_METHOD_NUM_ARGS) { 269 ACPI_WARN_PREDEFINED((AE_INFO, pathname, 270 ACPI_WARN_ALWAYS, 271 "Excess arguments (%u) - using only %u", 272 info->param_count, 273 ACPI_METHOD_NUM_ARGS)); 274 275 info->param_count = ACPI_METHOD_NUM_ARGS; 276 } 277 278 /* 279 * Allocate a new parameter block for the internal objects 280 * Add 1 to count to allow for null terminated internal list 281 */ 282 info->parameters = ACPI_ALLOCATE_ZEROED(((acpi_size)info-> 283 param_count + 284 1) * sizeof(void *)); 285 if (!info->parameters) { 286 status = AE_NO_MEMORY; 287 goto cleanup; 288 } 289 290 /* Convert each external object in the list to an internal object */ 291 292 for (i = 0; i < info->param_count; i++) { 293 status = 294 acpi_ut_copy_eobject_to_iobject(&external_params-> 295 pointer[i], 296 &info-> 297 parameters[i]); 298 if (ACPI_FAILURE(status)) { 299 goto cleanup; 300 } 301 } 302 303 info->parameters[info->param_count] = NULL; 304 } 305 306 #ifdef _FUTURE_FEATURE 307 308 /* 309 * Begin incoming argument count analysis. Check for too few args 310 * and too many args. 311 */ 312 switch (acpi_ns_get_type(info->node)) { 313 case ACPI_TYPE_METHOD: 314 315 /* Check incoming argument count against the method definition */ 316 317 if (info->obj_desc->method.param_count > info->param_count) { 318 ACPI_ERROR((AE_INFO, 319 "Insufficient arguments (%u) - %u are required", 320 info->param_count, 321 info->obj_desc->method.param_count)); 322 323 status = AE_MISSING_ARGUMENTS; 324 goto cleanup; 325 } 326 327 else if (info->obj_desc->method.param_count < info->param_count) { 328 ACPI_WARNING((AE_INFO, 329 "Excess arguments (%u) - only %u are required", 330 info->param_count, 331 info->obj_desc->method.param_count)); 332 333 /* Just pass the required number of arguments */ 334 335 info->param_count = info->obj_desc->method.param_count; 336 } 337 338 /* 339 * Any incoming external objects to be passed as arguments to the 340 * method must be converted to internal objects 341 */ 342 if (info->param_count) { 343 /* 344 * Allocate a new parameter block for the internal objects 345 * Add 1 to count to allow for null terminated internal list 346 */ 347 info->parameters = ACPI_ALLOCATE_ZEROED(((acpi_size) 348 info-> 349 param_count + 350 1) * 351 sizeof(void *)); 352 if (!info->parameters) { 353 status = AE_NO_MEMORY; 354 goto cleanup; 355 } 356 357 /* Convert each external object in the list to an internal object */ 358 359 for (i = 0; i < info->param_count; i++) { 360 status = 361 acpi_ut_copy_eobject_to_iobject 362 (&external_params->pointer[i], 363 &info->parameters[i]); 364 if (ACPI_FAILURE(status)) { 365 goto cleanup; 366 } 367 } 368 369 info->parameters[info->param_count] = NULL; 370 } 371 break; 372 373 default: 374 375 /* Warn if arguments passed to an object that is not a method */ 376 377 if (info->param_count) { 378 ACPI_WARNING((AE_INFO, 379 "%u arguments were passed to a non-method ACPI object", 380 info->param_count)); 381 } 382 break; 383 } 384 385 #endif 386 387 /* Now we can evaluate the object */ 388 389 status = acpi_ns_evaluate(info); 390 391 /* 392 * If we are expecting a return value, and all went well above, 393 * copy the return value to an external object. 394 */ 395 if (!return_buffer) { 396 goto cleanup_return_object; 397 } 398 399 if (!info->return_object) { 400 return_buffer->length = 0; 401 goto cleanup; 402 } 403 404 if (ACPI_GET_DESCRIPTOR_TYPE(info->return_object) == 405 ACPI_DESC_TYPE_NAMED) { 406 /* 407 * If we received a NS Node as a return object, this means that 408 * the object we are evaluating has nothing interesting to 409 * return (such as a mutex, etc.) We return an error because 410 * these types are essentially unsupported by this interface. 411 * We don't check up front because this makes it easier to add 412 * support for various types at a later date if necessary. 413 */ 414 status = AE_TYPE; 415 info->return_object = NULL; /* No need to delete a NS Node */ 416 return_buffer->length = 0; 417 } 418 419 if (ACPI_FAILURE(status)) { 420 goto cleanup_return_object; 421 } 422 423 /* Dereference Index and ref_of references */ 424 425 acpi_ns_resolve_references(info); 426 427 /* Get the size of the returned object */ 428 429 status = acpi_ut_get_object_size(info->return_object, 430 &buffer_space_needed); 431 if (ACPI_SUCCESS(status)) { 432 433 /* Validate/Allocate/Clear caller buffer */ 434 435 status = acpi_ut_initialize_buffer(return_buffer, 436 buffer_space_needed); 437 if (ACPI_FAILURE(status)) { 438 /* 439 * Caller's buffer is too small or a new one can't 440 * be allocated 441 */ 442 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 443 "Needed buffer size %X, %s\n", 444 (u32)buffer_space_needed, 445 acpi_format_exception(status))); 446 } else { 447 /* We have enough space for the object, build it */ 448 449 status = 450 acpi_ut_copy_iobject_to_eobject(info->return_object, 451 return_buffer); 452 } 453 } 454 455 cleanup_return_object: 456 457 if (info->return_object) { 458 /* 459 * Delete the internal return object. NOTE: Interpreter must be 460 * locked to avoid race condition. 461 */ 462 acpi_ex_enter_interpreter(); 463 464 /* Remove one reference on the return object (should delete it) */ 465 466 acpi_ut_remove_reference(info->return_object); 467 acpi_ex_exit_interpreter(); 468 } 469 470 cleanup: 471 472 /* Free the input parameter list (if we created one) */ 473 474 if (info->parameters) { 475 476 /* Free the allocated parameter block */ 477 478 acpi_ut_delete_internal_object_list(info->parameters); 479 } 480 481 ACPI_FREE(info); 482 return_ACPI_STATUS(status); 483 } 484 485 ACPI_EXPORT_SYMBOL(acpi_evaluate_object) 486 487 /******************************************************************************* 488 * 489 * FUNCTION: acpi_ns_resolve_references 490 * 491 * PARAMETERS: info - Evaluation info block 492 * 493 * RETURN: Info->return_object is replaced with the dereferenced object 494 * 495 * DESCRIPTION: Dereference certain reference objects. Called before an 496 * internal return object is converted to an external union acpi_object. 497 * 498 * Performs an automatic dereference of Index and ref_of reference objects. 499 * These reference objects are not supported by the union acpi_object, so this is a 500 * last resort effort to return something useful. Also, provides compatibility 501 * with other ACPI implementations. 502 * 503 * NOTE: does not handle references within returned package objects or nested 504 * references, but this support could be added later if found to be necessary. 505 * 506 ******************************************************************************/ 507 static void acpi_ns_resolve_references(struct acpi_evaluate_info *info) 508 { 509 union acpi_operand_object *obj_desc = NULL; 510 struct acpi_namespace_node *node; 511 512 /* We are interested in reference objects only */ 513 514 if ((info->return_object)->common.type != ACPI_TYPE_LOCAL_REFERENCE) { 515 return; 516 } 517 518 /* 519 * Two types of references are supported - those created by Index and 520 * ref_of operators. A name reference (AML_NAMEPATH_OP) can be converted 521 * to a union acpi_object, so it is not dereferenced here. A ddb_handle 522 * (AML_LOAD_OP) cannot be dereferenced, nor can it be converted to 523 * a union acpi_object. 524 */ 525 switch (info->return_object->reference.class) { 526 case ACPI_REFCLASS_INDEX: 527 528 obj_desc = *(info->return_object->reference.where); 529 break; 530 531 case ACPI_REFCLASS_REFOF: 532 533 node = info->return_object->reference.object; 534 if (node) { 535 obj_desc = node->object; 536 } 537 break; 538 539 default: 540 541 return; 542 } 543 544 /* Replace the existing reference object */ 545 546 if (obj_desc) { 547 acpi_ut_add_reference(obj_desc); 548 acpi_ut_remove_reference(info->return_object); 549 info->return_object = obj_desc; 550 } 551 552 return; 553 } 554 555 /******************************************************************************* 556 * 557 * FUNCTION: acpi_walk_namespace 558 * 559 * PARAMETERS: type - acpi_object_type to search for 560 * start_object - Handle in namespace where search begins 561 * max_depth - Depth to which search is to reach 562 * descending_callback - Called during tree descent 563 * when an object of "Type" is found 564 * ascending_callback - Called during tree ascent 565 * when an object of "Type" is found 566 * context - Passed to user function(s) above 567 * return_value - Location where return value of 568 * user_function is put if terminated early 569 * 570 * RETURNS Return value from the user_function if terminated early. 571 * Otherwise, returns NULL. 572 * 573 * DESCRIPTION: Performs a modified depth-first walk of the namespace tree, 574 * starting (and ending) at the object specified by start_handle. 575 * The callback function is called whenever an object that matches 576 * the type parameter is found. If the callback function returns 577 * a non-zero value, the search is terminated immediately and this 578 * value is returned to the caller. 579 * 580 * The point of this procedure is to provide a generic namespace 581 * walk routine that can be called from multiple places to 582 * provide multiple services; the callback function(s) can be 583 * tailored to each task, whether it is a print function, 584 * a compare function, etc. 585 * 586 ******************************************************************************/ 587 588 acpi_status 589 acpi_walk_namespace(acpi_object_type type, 590 acpi_handle start_object, 591 u32 max_depth, 592 acpi_walk_callback descending_callback, 593 acpi_walk_callback ascending_callback, 594 void *context, void **return_value) 595 { 596 acpi_status status; 597 598 ACPI_FUNCTION_TRACE(acpi_walk_namespace); 599 600 /* Parameter validation */ 601 602 if ((type > ACPI_TYPE_LOCAL_MAX) || 603 (!max_depth) || (!descending_callback && !ascending_callback)) { 604 return_ACPI_STATUS(AE_BAD_PARAMETER); 605 } 606 607 /* 608 * Need to acquire the namespace reader lock to prevent interference 609 * with any concurrent table unloads (which causes the deletion of 610 * namespace objects). We cannot allow the deletion of a namespace node 611 * while the user function is using it. The exception to this are the 612 * nodes created and deleted during control method execution -- these 613 * nodes are marked as temporary nodes and are ignored by the namespace 614 * walk. Thus, control methods can be executed while holding the 615 * namespace deletion lock (and the user function can execute control 616 * methods.) 617 */ 618 status = acpi_ut_acquire_read_lock(&acpi_gbl_namespace_rw_lock); 619 if (ACPI_FAILURE(status)) { 620 return_ACPI_STATUS(status); 621 } 622 623 /* 624 * Lock the namespace around the walk. The namespace will be 625 * unlocked/locked around each call to the user function - since the user 626 * function must be allowed to make ACPICA calls itself (for example, it 627 * will typically execute control methods during device enumeration.) 628 */ 629 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); 630 if (ACPI_FAILURE(status)) { 631 goto unlock_and_exit; 632 } 633 634 /* Now we can validate the starting node */ 635 636 if (!acpi_ns_validate_handle(start_object)) { 637 status = AE_BAD_PARAMETER; 638 goto unlock_and_exit2; 639 } 640 641 status = acpi_ns_walk_namespace(type, start_object, max_depth, 642 ACPI_NS_WALK_UNLOCK, 643 descending_callback, ascending_callback, 644 context, return_value); 645 646 unlock_and_exit2: 647 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); 648 649 unlock_and_exit: 650 (void)acpi_ut_release_read_lock(&acpi_gbl_namespace_rw_lock); 651 return_ACPI_STATUS(status); 652 } 653 654 ACPI_EXPORT_SYMBOL(acpi_walk_namespace) 655 656 /******************************************************************************* 657 * 658 * FUNCTION: acpi_ns_get_device_callback 659 * 660 * PARAMETERS: Callback from acpi_get_device 661 * 662 * RETURN: Status 663 * 664 * DESCRIPTION: Takes callbacks from walk_namespace and filters out all non- 665 * present devices, or if they specified a HID, it filters based 666 * on that. 667 * 668 ******************************************************************************/ 669 static acpi_status 670 acpi_ns_get_device_callback(acpi_handle obj_handle, 671 u32 nesting_level, 672 void *context, void **return_value) 673 { 674 struct acpi_get_devices_info *info = context; 675 acpi_status status; 676 struct acpi_namespace_node *node; 677 u32 flags; 678 struct acpi_pnp_device_id *hid; 679 struct acpi_pnp_device_id_list *cid; 680 u32 i; 681 u8 found; 682 int no_match; 683 684 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); 685 if (ACPI_FAILURE(status)) { 686 return (status); 687 } 688 689 node = acpi_ns_validate_handle(obj_handle); 690 status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); 691 if (ACPI_FAILURE(status)) { 692 return (status); 693 } 694 695 if (!node) { 696 return (AE_BAD_PARAMETER); 697 } 698 699 /* 700 * First, filter based on the device HID and CID. 701 * 702 * 01/2010: For this case where a specific HID is requested, we don't 703 * want to run _STA until we have an actual HID match. Thus, we will 704 * not unnecessarily execute _STA on devices for which the caller 705 * doesn't care about. Previously, _STA was executed unconditionally 706 * on all devices found here. 707 * 708 * A side-effect of this change is that now we will continue to search 709 * for a matching HID even under device trees where the parent device 710 * would have returned a _STA that indicates it is not present or 711 * not functioning (thus aborting the search on that branch). 712 */ 713 if (info->hid != NULL) { 714 status = acpi_ut_execute_HID(node, &hid); 715 if (status == AE_NOT_FOUND) { 716 return (AE_OK); 717 } else if (ACPI_FAILURE(status)) { 718 return (AE_CTRL_DEPTH); 719 } 720 721 no_match = strcmp(hid->string, info->hid); 722 ACPI_FREE(hid); 723 724 if (no_match) { 725 /* 726 * HID does not match, attempt match within the 727 * list of Compatible IDs (CIDs) 728 */ 729 status = acpi_ut_execute_CID(node, &cid); 730 if (status == AE_NOT_FOUND) { 731 return (AE_OK); 732 } else if (ACPI_FAILURE(status)) { 733 return (AE_CTRL_DEPTH); 734 } 735 736 /* Walk the CID list */ 737 738 found = FALSE; 739 for (i = 0; i < cid->count; i++) { 740 if (strcmp(cid->ids[i].string, info->hid) == 0) { 741 742 /* Found a matching CID */ 743 744 found = TRUE; 745 break; 746 } 747 } 748 749 ACPI_FREE(cid); 750 if (!found) { 751 return (AE_OK); 752 } 753 } 754 } 755 756 /* Run _STA to determine if device is present */ 757 758 status = acpi_ut_execute_STA(node, &flags); 759 if (ACPI_FAILURE(status)) { 760 return (AE_CTRL_DEPTH); 761 } 762 763 if (!(flags & ACPI_STA_DEVICE_PRESENT) && 764 !(flags & ACPI_STA_DEVICE_FUNCTIONING)) { 765 /* 766 * Don't examine the children of the device only when the 767 * device is neither present nor functional. See ACPI spec, 768 * description of _STA for more information. 769 */ 770 return (AE_CTRL_DEPTH); 771 } 772 773 /* We have a valid device, invoke the user function */ 774 775 status = info->user_function(obj_handle, nesting_level, 776 info->context, return_value); 777 return (status); 778 } 779 780 /******************************************************************************* 781 * 782 * FUNCTION: acpi_get_devices 783 * 784 * PARAMETERS: HID - HID to search for. Can be NULL. 785 * user_function - Called when a matching object is found 786 * context - Passed to user function 787 * return_value - Location where return value of 788 * user_function is put if terminated early 789 * 790 * RETURNS Return value from the user_function if terminated early. 791 * Otherwise, returns NULL. 792 * 793 * DESCRIPTION: Performs a modified depth-first walk of the namespace tree, 794 * starting (and ending) at the object specified by start_handle. 795 * The user_function is called whenever an object of type 796 * Device is found. If the user function returns 797 * a non-zero value, the search is terminated immediately and this 798 * value is returned to the caller. 799 * 800 * This is a wrapper for walk_namespace, but the callback performs 801 * additional filtering. Please see acpi_ns_get_device_callback. 802 * 803 ******************************************************************************/ 804 805 acpi_status 806 acpi_get_devices(const char *HID, 807 acpi_walk_callback user_function, 808 void *context, void **return_value) 809 { 810 acpi_status status; 811 struct acpi_get_devices_info info; 812 813 ACPI_FUNCTION_TRACE(acpi_get_devices); 814 815 /* Parameter validation */ 816 817 if (!user_function) { 818 return_ACPI_STATUS(AE_BAD_PARAMETER); 819 } 820 821 /* 822 * We're going to call their callback from OUR callback, so we need 823 * to know what it is, and their context parameter. 824 */ 825 info.hid = HID; 826 info.context = context; 827 info.user_function = user_function; 828 829 /* 830 * Lock the namespace around the walk. 831 * The namespace will be unlocked/locked around each call 832 * to the user function - since this function 833 * must be allowed to make Acpi calls itself. 834 */ 835 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); 836 if (ACPI_FAILURE(status)) { 837 return_ACPI_STATUS(status); 838 } 839 840 status = acpi_ns_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, 841 ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK, 842 acpi_ns_get_device_callback, NULL, 843 &info, return_value); 844 845 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); 846 return_ACPI_STATUS(status); 847 } 848 849 ACPI_EXPORT_SYMBOL(acpi_get_devices) 850 851 /******************************************************************************* 852 * 853 * FUNCTION: acpi_attach_data 854 * 855 * PARAMETERS: obj_handle - Namespace node 856 * handler - Handler for this attachment 857 * data - Pointer to data to be attached 858 * 859 * RETURN: Status 860 * 861 * DESCRIPTION: Attach arbitrary data and handler to a namespace node. 862 * 863 ******************************************************************************/ 864 acpi_status 865 acpi_attach_data(acpi_handle obj_handle, 866 acpi_object_handler handler, void *data) 867 { 868 struct acpi_namespace_node *node; 869 acpi_status status; 870 871 /* Parameter validation */ 872 873 if (!obj_handle || !handler || !data) { 874 return (AE_BAD_PARAMETER); 875 } 876 877 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); 878 if (ACPI_FAILURE(status)) { 879 return (status); 880 } 881 882 /* Convert and validate the handle */ 883 884 node = acpi_ns_validate_handle(obj_handle); 885 if (!node) { 886 status = AE_BAD_PARAMETER; 887 goto unlock_and_exit; 888 } 889 890 status = acpi_ns_attach_data(node, handler, data); 891 892 unlock_and_exit: 893 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); 894 return (status); 895 } 896 897 ACPI_EXPORT_SYMBOL(acpi_attach_data) 898 899 /******************************************************************************* 900 * 901 * FUNCTION: acpi_detach_data 902 * 903 * PARAMETERS: obj_handle - Namespace node handle 904 * handler - Handler used in call to acpi_attach_data 905 * 906 * RETURN: Status 907 * 908 * DESCRIPTION: Remove data that was previously attached to a node. 909 * 910 ******************************************************************************/ 911 acpi_status 912 acpi_detach_data(acpi_handle obj_handle, acpi_object_handler handler) 913 { 914 struct acpi_namespace_node *node; 915 acpi_status status; 916 917 /* Parameter validation */ 918 919 if (!obj_handle || !handler) { 920 return (AE_BAD_PARAMETER); 921 } 922 923 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); 924 if (ACPI_FAILURE(status)) { 925 return (status); 926 } 927 928 /* Convert and validate the handle */ 929 930 node = acpi_ns_validate_handle(obj_handle); 931 if (!node) { 932 status = AE_BAD_PARAMETER; 933 goto unlock_and_exit; 934 } 935 936 status = acpi_ns_detach_data(node, handler); 937 938 unlock_and_exit: 939 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); 940 return (status); 941 } 942 943 ACPI_EXPORT_SYMBOL(acpi_detach_data) 944 945 /******************************************************************************* 946 * 947 * FUNCTION: acpi_get_data_full 948 * 949 * PARAMETERS: obj_handle - Namespace node 950 * handler - Handler used in call to attach_data 951 * data - Where the data is returned 952 * callback - function to execute before returning 953 * 954 * RETURN: Status 955 * 956 * DESCRIPTION: Retrieve data that was previously attached to a namespace node 957 * and execute a callback before returning. 958 * 959 ******************************************************************************/ 960 acpi_status 961 acpi_get_data_full(acpi_handle obj_handle, acpi_object_handler handler, 962 void **data, void (*callback)(void *)) 963 { 964 struct acpi_namespace_node *node; 965 acpi_status status; 966 967 /* Parameter validation */ 968 969 if (!obj_handle || !handler || !data) { 970 return (AE_BAD_PARAMETER); 971 } 972 973 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); 974 if (ACPI_FAILURE(status)) { 975 return (status); 976 } 977 978 /* Convert and validate the handle */ 979 980 node = acpi_ns_validate_handle(obj_handle); 981 if (!node) { 982 status = AE_BAD_PARAMETER; 983 goto unlock_and_exit; 984 } 985 986 status = acpi_ns_get_attached_data(node, handler, data); 987 if (ACPI_SUCCESS(status) && callback) { 988 callback(*data); 989 } 990 991 unlock_and_exit: 992 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); 993 return (status); 994 } 995 996 ACPI_EXPORT_SYMBOL(acpi_get_data_full) 997 998 /******************************************************************************* 999 * 1000 * FUNCTION: acpi_get_data 1001 * 1002 * PARAMETERS: obj_handle - Namespace node 1003 * handler - Handler used in call to attach_data 1004 * data - Where the data is returned 1005 * 1006 * RETURN: Status 1007 * 1008 * DESCRIPTION: Retrieve data that was previously attached to a namespace node. 1009 * 1010 ******************************************************************************/ 1011 acpi_status 1012 acpi_get_data(acpi_handle obj_handle, acpi_object_handler handler, void **data) 1013 { 1014 return acpi_get_data_full(obj_handle, handler, data, NULL); 1015 } 1016 1017 ACPI_EXPORT_SYMBOL(acpi_get_data) 1018