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