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