nseval.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:15k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*******************************************************************************
  2.  *
  3.  * Module Name: nseval - Object evaluation interfaces -- includes control
  4.  *                       method lookup and execution.
  5.  *              $Revision: 102 $
  6.  *
  7.  ******************************************************************************/
  8. /*
  9.  *  Copyright (C) 2000, 2001 R. Byron Moore
  10.  *
  11.  *  This program is free software; you can redistribute it and/or modify
  12.  *  it under the terms of the GNU General Public License as published by
  13.  *  the Free Software Foundation; either version 2 of the License, or
  14.  *  (at your option) any later version.
  15.  *
  16.  *  This program is distributed in the hope that it will be useful,
  17.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  18.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19.  *  GNU General Public License for more details.
  20.  *
  21.  *  You should have received a copy of the GNU General Public License
  22.  *  along with this program; if not, write to the Free Software
  23.  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  24.  */
  25. #include "acpi.h"
  26. #include "amlcode.h"
  27. #include "acparser.h"
  28. #include "acinterp.h"
  29. #include "acnamesp.h"
  30. #define _COMPONENT          ACPI_NAMESPACE
  31.  MODULE_NAME         ("nseval")
  32. /*******************************************************************************
  33.  *
  34.  * FUNCTION:    Acpi_ns_evaluate_relative
  35.  *
  36.  * PARAMETERS:  Handle              - The relative containing object
  37.  *              *Pathname           - Name of method to execute, If NULL, the
  38.  *                                    handle is the object to execute
  39.  *              **Params            - List of parameters to pass to the method,
  40.  *                                    terminated by NULL.  Params itself may be
  41.  *                                    NULL if no parameters are being passed.
  42.  *              *Return_object      - Where to put method's return value (if
  43.  *                                    any).  If NULL, no value is returned.
  44.  *
  45.  * RETURN:      Status
  46.  *
  47.  * DESCRIPTION: Find and execute the requested method using the handle as a
  48.  *              scope
  49.  *
  50.  * MUTEX:       Locks Namespace
  51.  *
  52.  ******************************************************************************/
  53. acpi_status
  54. acpi_ns_evaluate_relative (
  55. acpi_namespace_node     *handle,
  56. NATIVE_CHAR             *pathname,
  57. acpi_operand_object     **params,
  58. acpi_operand_object     **return_object)
  59. {
  60. acpi_namespace_node     *prefix_node;
  61. acpi_status             status;
  62. acpi_namespace_node     *node = NULL;
  63. NATIVE_CHAR             *internal_path = NULL;
  64. acpi_generic_state      scope_info;
  65. FUNCTION_TRACE ("Ns_evaluate_relative");
  66. /*
  67.  * Must have a valid object handle
  68.  */
  69. if (!handle) {
  70. return_ACPI_STATUS (AE_BAD_PARAMETER);
  71. }
  72. /* Build an internal name string for the method */
  73. status = acpi_ns_internalize_name (pathname, &internal_path);
  74. if (ACPI_FAILURE (status)) {
  75. return_ACPI_STATUS (status);
  76. }
  77. /* Get the prefix handle and Node */
  78. acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
  79. prefix_node = acpi_ns_map_handle_to_node (handle);
  80. if (!prefix_node) {
  81. acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
  82. status = AE_BAD_PARAMETER;
  83. goto cleanup;
  84. }
  85. /* Lookup the name in the namespace */
  86. scope_info.scope.node = prefix_node;
  87. status = acpi_ns_lookup (&scope_info, internal_path, ACPI_TYPE_ANY,
  88.  IMODE_EXECUTE, NS_NO_UPSEARCH, NULL,
  89.  &node);
  90. acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
  91. if (ACPI_FAILURE (status)) {
  92. ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Object [%s] not found [%s]n",
  93. pathname, acpi_format_exception (status)));
  94. goto cleanup;
  95. }
  96. /*
  97.  * Now that we have a handle to the object, we can attempt
  98.  * to evaluate it.
  99.  */
  100. ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "%s [%p] Value %pn",
  101. pathname, node, node->object));
  102. status = acpi_ns_evaluate_by_handle (node, params, return_object);
  103. ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "*** Completed eval of object %s ***n",
  104. pathname));
  105. cleanup:
  106. ACPI_MEM_FREE (internal_path);
  107. return_ACPI_STATUS (status);
  108. }
  109. /*******************************************************************************
  110.  *
  111.  * FUNCTION:    Acpi_ns_evaluate_by_name
  112.  *
  113.  * PARAMETERS:  Pathname            - Fully qualified pathname to the object
  114.  *              *Return_object      - Where to put method's return value (if
  115.  *                                    any).  If NULL, no value is returned.
  116.  *              **Params            - List of parameters to pass to the method,
  117.  *                                    terminated by NULL.  Params itself may be
  118.  *                                    NULL if no parameters are being passed.
  119.  *
  120.  * RETURN:      Status
  121.  *
  122.  * DESCRIPTION: Find and execute the requested method passing the given
  123.  *              parameters
  124.  *
  125.  * MUTEX:       Locks Namespace
  126.  *
  127.  ******************************************************************************/
  128. acpi_status
  129. acpi_ns_evaluate_by_name (
  130. NATIVE_CHAR             *pathname,
  131. acpi_operand_object     **params,
  132. acpi_operand_object     **return_object)
  133. {
  134. acpi_status             status;
  135. acpi_namespace_node     *node = NULL;
  136. NATIVE_CHAR             *internal_path = NULL;
  137. FUNCTION_TRACE ("Ns_evaluate_by_name");
  138. /* Build an internal name string for the method */
  139. status = acpi_ns_internalize_name (pathname, &internal_path);
  140. if (ACPI_FAILURE (status)) {
  141. return_ACPI_STATUS (status);
  142. }
  143. acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
  144. /* Lookup the name in the namespace */
  145. status = acpi_ns_lookup (NULL, internal_path, ACPI_TYPE_ANY,
  146.  IMODE_EXECUTE, NS_NO_UPSEARCH, NULL,
  147.  &node);
  148. acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
  149. if (ACPI_FAILURE (status)) {
  150. ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Object at [%s] was not found, status=%.4Xn",
  151. pathname, status));
  152. goto cleanup;
  153. }
  154. /*
  155.  * Now that we have a handle to the object, we can attempt
  156.  * to evaluate it.
  157.  */
  158. ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "%s [%p] Value %pn",
  159. pathname, node, node->object));
  160. status = acpi_ns_evaluate_by_handle (node, params, return_object);
  161. ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "*** Completed eval of object %s ***n",
  162. pathname));
  163. cleanup:
  164. /* Cleanup */
  165. if (internal_path) {
  166. ACPI_MEM_FREE (internal_path);
  167. }
  168. return_ACPI_STATUS (status);
  169. }
  170. /*******************************************************************************
  171.  *
  172.  * FUNCTION:    Acpi_ns_evaluate_by_handle
  173.  *
  174.  * PARAMETERS:  Handle              - Method Node to execute
  175.  *              **Params            - List of parameters to pass to the method,
  176.  *                                    terminated by NULL.  Params itself may be
  177.  *                                    NULL if no parameters are being passed.
  178.  *              *Return_object      - Where to put method's return value (if
  179.  *                                    any).  If NULL, no value is returned.
  180.  *
  181.  * RETURN:      Status
  182.  *
  183.  * DESCRIPTION: Execute the requested method passing the given parameters
  184.  *
  185.  * MUTEX:       Locks Namespace
  186.  *
  187.  ******************************************************************************/
  188. acpi_status
  189. acpi_ns_evaluate_by_handle (
  190. acpi_namespace_node     *handle,
  191. acpi_operand_object     **params,
  192. acpi_operand_object     **return_object)
  193. {
  194. acpi_namespace_node     *node;
  195. acpi_status             status;
  196. acpi_operand_object     *local_return_object;
  197. FUNCTION_TRACE ("Ns_evaluate_by_handle");
  198. /* Check if namespace has been initialized */
  199. if (!acpi_gbl_root_node) {
  200. return_ACPI_STATUS (AE_NO_NAMESPACE);
  201. }
  202. /* Parameter Validation */
  203. if (!handle) {
  204. return_ACPI_STATUS (AE_BAD_PARAMETER);
  205. }
  206. if (return_object) {
  207. /* Initialize the return value to an invalid object */
  208. *return_object = NULL;
  209. }
  210. /* Get the prefix handle and Node */
  211. acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
  212. node = acpi_ns_map_handle_to_node (handle);
  213. if (!node) {
  214. acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
  215. return_ACPI_STATUS (AE_BAD_PARAMETER);
  216. }
  217. /*
  218.  * Two major cases here:
  219.  * 1) The object is an actual control method -- execute it.
  220.  * 2) The object is not a method -- just return it's current
  221.  *      value
  222.  *
  223.  * In both cases, the namespace is unlocked by the
  224.  *  Acpi_ns* procedure
  225.  */
  226. if (acpi_ns_get_type (node) == ACPI_TYPE_METHOD) {
  227. /*
  228.  * Case 1) We have an actual control method to execute
  229.  */
  230. status = acpi_ns_execute_control_method (node, params,
  231.  &local_return_object);
  232. }
  233. else {
  234. /*
  235.  * Case 2) Object is NOT a method, just return its
  236.  * current value
  237.  */
  238. status = acpi_ns_get_object_value (node, &local_return_object);
  239. }
  240. /*
  241.  * Check if there is a return value on the stack that must
  242.  * be dealt with
  243.  */
  244. if (status == AE_CTRL_RETURN_VALUE) {
  245. /*
  246.  * If the Method returned a value and the caller
  247.  * provided a place to store a returned value, Copy
  248.  * the returned value to the object descriptor provided
  249.  * by the caller.
  250.  */
  251. if (return_object) {
  252. /*
  253.  * Valid return object, copy the pointer to
  254.  * the returned object
  255.  */
  256. *return_object = local_return_object;
  257. }
  258. /* Map AE_RETURN_VALUE to AE_OK, we are done with it */
  259. if (status == AE_CTRL_RETURN_VALUE) {
  260. status = AE_OK;
  261. }
  262. }
  263. /*
  264.  * Namespace was unlocked by the handling Acpi_ns* function,
  265.  * so we just return
  266.  */
  267. return_ACPI_STATUS (status);
  268. }
  269. /*******************************************************************************
  270.  *
  271.  * FUNCTION:    Acpi_ns_execute_control_method
  272.  *
  273.  * PARAMETERS:  Method_node     - The object/method
  274.  *              **Params            - List of parameters to pass to the method,
  275.  *                                    terminated by NULL.  Params itself may be
  276.  *                                    NULL if no parameters are being passed.
  277.  *              **Return_obj_desc   - List of result objects to be returned
  278.  *                                    from the method.
  279.  *
  280.  * RETURN:      Status
  281.  *
  282.  * DESCRIPTION: Execute the requested method passing the given parameters
  283.  *
  284.  * MUTEX:       Assumes namespace is locked
  285.  *
  286.  ******************************************************************************/
  287. acpi_status
  288. acpi_ns_execute_control_method (
  289. acpi_namespace_node     *method_node,
  290. acpi_operand_object     **params,
  291. acpi_operand_object     **return_obj_desc)
  292. {
  293. acpi_status             status;
  294. acpi_operand_object     *obj_desc;
  295. FUNCTION_TRACE ("Ns_execute_control_method");
  296. /* Verify that there is a method associated with this object */
  297. obj_desc = acpi_ns_get_attached_object (method_node);
  298. if (!obj_desc) {
  299. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No attached method objectn"));
  300. acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
  301. return_ACPI_STATUS (AE_NULL_OBJECT);
  302. }
  303. ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Control method at Offset %p Length %x]n",
  304. obj_desc->method.aml_start + 1, obj_desc->method.aml_length - 1));
  305. DUMP_PATHNAME (method_node, "Ns_execute_control_method: Executing",
  306. ACPI_LV_NAMES, _COMPONENT);
  307. ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "At offset %pn",
  308. obj_desc->method.aml_start + 1));
  309. /*
  310.  * Unlock the namespace before execution.  This allows namespace access
  311.  * via the external Acpi* interfaces while a method is being executed.
  312.  * However, any namespace deletion must acquire both the namespace and
  313.  * interpreter locks to ensure that no thread is using the portion of the
  314.  * namespace that is being deleted.
  315.  */
  316. acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
  317. /*
  318.  * Execute the method via the interpreter.  The interpreter is locked
  319.  * here before calling into the AML parser
  320.  */
  321. status = acpi_ex_enter_interpreter ();
  322. if (ACPI_FAILURE (status)) {
  323. return_ACPI_STATUS (status);
  324. }
  325. status = acpi_psx_execute (method_node, params, return_obj_desc);
  326. acpi_ex_exit_interpreter ();
  327. return_ACPI_STATUS (status);
  328. }
  329. /*******************************************************************************
  330.  *
  331.  * FUNCTION:    Acpi_ns_get_object_value
  332.  *
  333.  * PARAMETERS:  Node         - The object
  334.  *
  335.  * RETURN:      Status
  336.  *
  337.  * DESCRIPTION: Return the current value of the object
  338.  *
  339.  * MUTEX:       Assumes namespace is locked
  340.  *
  341.  ******************************************************************************/
  342. acpi_status
  343. acpi_ns_get_object_value (
  344. acpi_namespace_node     *node,
  345. acpi_operand_object     **return_obj_desc)
  346. {
  347. acpi_status             status = AE_OK;
  348. acpi_operand_object     *obj_desc;
  349. acpi_operand_object     *source_desc;
  350. FUNCTION_TRACE ("Ns_get_object_value");
  351. /*
  352.  *  We take the value from certain objects directly
  353.  */
  354. if ((node->type == ACPI_TYPE_PROCESSOR) ||
  355. (node->type == ACPI_TYPE_POWER)) {
  356. /*
  357.  *  Create a Reference object to contain the object
  358.  */
  359. obj_desc = acpi_ut_create_internal_object (node->type);
  360. if (!obj_desc) {
  361.    status = AE_NO_MEMORY;
  362.    goto unlock_and_exit;
  363. }
  364. /*
  365.  *  Get the attached object
  366.  */
  367. source_desc = acpi_ns_get_attached_object (node);
  368. if (!source_desc) {
  369. status = AE_NULL_OBJECT;
  370. goto unlock_and_exit;
  371. }
  372. /*
  373.  * Just copy from the original to the return object
  374.  *
  375.  * TBD: [Future] - need a low-level object copy that handles
  376.  * the reference count automatically.  (Don't want to copy it)
  377.  */
  378. MEMCPY (obj_desc, source_desc, sizeof (acpi_operand_object));
  379. obj_desc->common.reference_count = 1;
  380. acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
  381. }
  382. /*
  383.  * Other objects require a reference object wrapper which we
  384.  * then attempt to resolve.
  385.  */
  386. else {
  387. /* Create an Reference object to contain the object */
  388. obj_desc = acpi_ut_create_internal_object (INTERNAL_TYPE_REFERENCE);
  389. if (!obj_desc) {
  390.    status = AE_NO_MEMORY;
  391.    goto unlock_and_exit;
  392. }
  393. /* Construct a descriptor pointing to the name */
  394. obj_desc->reference.opcode = (u8) AML_NAME_OP;
  395. obj_desc->reference.object = (void *) node;
  396. /*
  397.  * Use Resolve_to_value() to get the associated value. This call
  398.  * always deletes Obj_desc (allocated above).
  399.  *
  400.  * NOTE: we can get away with passing in NULL for a walk state
  401.  * because Obj_desc is guaranteed to not be a reference to either
  402.  * a method local or a method argument
  403.  *
  404.  * Even though we do not directly invoke the interpreter
  405.  * for this, we must enter it because we could access an opregion.
  406.  * The opregion access code assumes that the interpreter
  407.  * is locked.
  408.  *
  409.  * We must release the namespace lock before entering the
  410.  * intepreter.
  411.  */
  412. acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
  413. status = acpi_ex_enter_interpreter ();
  414. if (ACPI_SUCCESS (status)) {
  415. status = acpi_ex_resolve_to_value (&obj_desc, NULL);
  416. acpi_ex_exit_interpreter ();
  417. }
  418. }
  419. /*
  420.  * If Acpi_ex_resolve_to_value() succeeded, the return value was
  421.  * placed in Obj_desc.
  422.  */
  423. if (ACPI_SUCCESS (status)) {
  424. status = AE_CTRL_RETURN_VALUE;
  425. *return_obj_desc = obj_desc;
  426. ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Returning obj %pn", *return_obj_desc));
  427. }
  428. /* Namespace is unlocked */
  429. return_ACPI_STATUS (status);
  430. unlock_and_exit:
  431. /* Unlock the namespace */
  432. acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
  433. return_ACPI_STATUS (status);
  434. }