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