root/drivers/acpi/acpica/nsxfeval.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ACPI_MODULE_NAME
  2. ACPI_EXPORT_SYMBOL
  3. ACPI_EXPORT_SYMBOL
  4. acpi_walk_namespace
  5. ACPI_EXPORT_SYMBOL
  6. acpi_get_devices
  7. ACPI_EXPORT_SYMBOL
  8. ACPI_EXPORT_SYMBOL
  9. ACPI_EXPORT_SYMBOL
  10. ACPI_EXPORT_SYMBOL

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

/* [<][>][^][v][top][bottom][index][help] */