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