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