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