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