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