Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

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