linux/drivers/acpi/acpica/nsxfeval.c
<<
>>
Prefs
   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)
 983