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