nseval.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487
  1. /*******************************************************************************
  2. *
  3. * Module Name: nseval - Object evaluation interfaces -- includes control
  4. * method lookup and execution.
  5. *
  6. ******************************************************************************/
  7. /*
  8. * Copyright (C) 2000 - 2005, R. Byron Moore
  9. * All rights reserved.
  10. *
  11. * Redistribution and use in source and binary forms, with or without
  12. * modification, are permitted provided that the following conditions
  13. * are met:
  14. * 1. Redistributions of source code must retain the above copyright
  15. * notice, this list of conditions, and the following disclaimer,
  16. * without modification.
  17. * 2. Redistributions in binary form must reproduce at minimum a disclaimer
  18. * substantially similar to the "NO WARRANTY" disclaimer below
  19. * ("Disclaimer") and any redistribution must be conditioned upon
  20. * including a substantially similar Disclaimer requirement for further
  21. * binary redistribution.
  22. * 3. Neither the names of the above-listed copyright holders nor the names
  23. * of any contributors may be used to endorse or promote products derived
  24. * from this software without specific prior written permission.
  25. *
  26. * Alternatively, this software may be distributed under the terms of the
  27. * GNU General Public License ("GPL") version 2 as published by the Free
  28. * Software Foundation.
  29. *
  30. * NO WARRANTY
  31. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  32. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  33. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
  34. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  35. * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  36. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  37. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  38. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  39. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  40. * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  41. * POSSIBILITY OF SUCH DAMAGES.
  42. */
  43. #include <acpi/acpi.h>
  44. #include <acpi/acparser.h>
  45. #include <acpi/acinterp.h>
  46. #include <acpi/acnamesp.h>
  47. #define _COMPONENT ACPI_NAMESPACE
  48. ACPI_MODULE_NAME ("nseval")
  49. /*******************************************************************************
  50. *
  51. * FUNCTION: acpi_ns_evaluate_relative
  52. *
  53. * PARAMETERS: Pathname - Name of method to execute, If NULL, the
  54. * handle is the object to execute
  55. * Info - Method info block
  56. *
  57. * RETURN: Status
  58. *
  59. * DESCRIPTION: Find and execute the requested method using the handle as a
  60. * scope
  61. *
  62. * MUTEX: Locks Namespace
  63. *
  64. ******************************************************************************/
  65. acpi_status
  66. acpi_ns_evaluate_relative (
  67. char *pathname,
  68. struct acpi_parameter_info *info)
  69. {
  70. acpi_status status;
  71. struct acpi_namespace_node *node = NULL;
  72. union acpi_generic_state *scope_info;
  73. char *internal_path = NULL;
  74. ACPI_FUNCTION_TRACE ("ns_evaluate_relative");
  75. /*
  76. * Must have a valid object handle
  77. */
  78. if (!info || !info->node) {
  79. return_ACPI_STATUS (AE_BAD_PARAMETER);
  80. }
  81. /* Build an internal name string for the method */
  82. status = acpi_ns_internalize_name (pathname, &internal_path);
  83. if (ACPI_FAILURE (status)) {
  84. return_ACPI_STATUS (status);
  85. }
  86. scope_info = acpi_ut_create_generic_state ();
  87. if (!scope_info) {
  88. goto cleanup1;
  89. }
  90. /* Get the prefix handle and Node */
  91. status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
  92. if (ACPI_FAILURE (status)) {
  93. goto cleanup;
  94. }
  95. info->node = acpi_ns_map_handle_to_node (info->node);
  96. if (!info->node) {
  97. (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
  98. status = AE_BAD_PARAMETER;
  99. goto cleanup;
  100. }
  101. /* Lookup the name in the namespace */
  102. scope_info->scope.node = info->node;
  103. status = acpi_ns_lookup (scope_info, internal_path, ACPI_TYPE_ANY,
  104. ACPI_IMODE_EXECUTE, ACPI_NS_NO_UPSEARCH, NULL,
  105. &node);
  106. (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
  107. if (ACPI_FAILURE (status)) {
  108. ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Object [%s] not found [%s]\n",
  109. pathname, acpi_format_exception (status)));
  110. goto cleanup;
  111. }
  112. /*
  113. * Now that we have a handle to the object, we can attempt to evaluate it.
  114. */
  115. ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "%s [%p] Value %p\n",
  116. pathname, node, acpi_ns_get_attached_object (node)));
  117. info->node = node;
  118. status = acpi_ns_evaluate_by_handle (info);
  119. ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "*** Completed eval of object %s ***\n",
  120. pathname));
  121. cleanup:
  122. acpi_ut_delete_generic_state (scope_info);
  123. cleanup1:
  124. ACPI_MEM_FREE (internal_path);
  125. return_ACPI_STATUS (status);
  126. }
  127. /*******************************************************************************
  128. *
  129. * FUNCTION: acpi_ns_evaluate_by_name
  130. *
  131. * PARAMETERS: Pathname - Fully qualified pathname to the object
  132. * Info - Contains:
  133. * return_object - Where to put method's return value (if
  134. * any). If NULL, no value is returned.
  135. * Params - List of parameters to pass to the method,
  136. * terminated by NULL. Params itself may be
  137. * NULL if no parameters are being passed.
  138. *
  139. * RETURN: Status
  140. *
  141. * DESCRIPTION: Find and execute the requested method passing the given
  142. * parameters
  143. *
  144. * MUTEX: Locks Namespace
  145. *
  146. ******************************************************************************/
  147. acpi_status
  148. acpi_ns_evaluate_by_name (
  149. char *pathname,
  150. struct acpi_parameter_info *info)
  151. {
  152. acpi_status status;
  153. char *internal_path = NULL;
  154. ACPI_FUNCTION_TRACE ("ns_evaluate_by_name");
  155. /* Build an internal name string for the method */
  156. status = acpi_ns_internalize_name (pathname, &internal_path);
  157. if (ACPI_FAILURE (status)) {
  158. return_ACPI_STATUS (status);
  159. }
  160. status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
  161. if (ACPI_FAILURE (status)) {
  162. goto cleanup;
  163. }
  164. /* Lookup the name in the namespace */
  165. status = acpi_ns_lookup (NULL, internal_path, ACPI_TYPE_ANY,
  166. ACPI_IMODE_EXECUTE, ACPI_NS_NO_UPSEARCH, NULL,
  167. &info->node);
  168. (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
  169. if (ACPI_FAILURE (status)) {
  170. ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
  171. "Object at [%s] was not found, status=%.4X\n",
  172. pathname, status));
  173. goto cleanup;
  174. }
  175. /*
  176. * Now that we have a handle to the object, we can attempt to evaluate it.
  177. */
  178. ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "%s [%p] Value %p\n",
  179. pathname, info->node, acpi_ns_get_attached_object (info->node)));
  180. status = acpi_ns_evaluate_by_handle (info);
  181. ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "*** Completed eval of object %s ***\n",
  182. pathname));
  183. cleanup:
  184. /* Cleanup */
  185. if (internal_path) {
  186. ACPI_MEM_FREE (internal_path);
  187. }
  188. return_ACPI_STATUS (status);
  189. }
  190. /*******************************************************************************
  191. *
  192. * FUNCTION: acpi_ns_evaluate_by_handle
  193. *
  194. * PARAMETERS: Handle - Method Node to execute
  195. * Params - List of parameters to pass to the method,
  196. * terminated by NULL. Params itself may be
  197. * NULL if no parameters are being passed.
  198. * param_type - Type of Parameter list
  199. * return_object - Where to put method's return value (if
  200. * any). If NULL, no value is returned.
  201. *
  202. * RETURN: Status
  203. *
  204. * DESCRIPTION: Execute the requested method passing the given parameters
  205. *
  206. * MUTEX: Locks Namespace
  207. *
  208. ******************************************************************************/
  209. acpi_status
  210. acpi_ns_evaluate_by_handle (
  211. struct acpi_parameter_info *info)
  212. {
  213. acpi_status status;
  214. ACPI_FUNCTION_TRACE ("ns_evaluate_by_handle");
  215. /* Check if namespace has been initialized */
  216. if (!acpi_gbl_root_node) {
  217. return_ACPI_STATUS (AE_NO_NAMESPACE);
  218. }
  219. /* Parameter Validation */
  220. if (!info) {
  221. return_ACPI_STATUS (AE_BAD_PARAMETER);
  222. }
  223. /* Initialize the return value to an invalid object */
  224. info->return_object = NULL;
  225. /* Get the prefix handle and Node */
  226. status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
  227. if (ACPI_FAILURE (status)) {
  228. return_ACPI_STATUS (status);
  229. }
  230. info->node = acpi_ns_map_handle_to_node (info->node);
  231. if (!info->node) {
  232. (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
  233. return_ACPI_STATUS (AE_BAD_PARAMETER);
  234. }
  235. /*
  236. * For a method alias, we must grab the actual method node so that proper
  237. * scoping context will be established before execution.
  238. */
  239. if (acpi_ns_get_type (info->node) == ACPI_TYPE_LOCAL_METHOD_ALIAS) {
  240. info->node = ACPI_CAST_PTR (struct acpi_namespace_node, info->node->object);
  241. }
  242. /*
  243. * Two major cases here:
  244. * 1) The object is an actual control method -- execute it.
  245. * 2) The object is not a method -- just return it's current value
  246. *
  247. * In both cases, the namespace is unlocked by the acpi_ns* procedure
  248. */
  249. if (acpi_ns_get_type (info->node) == ACPI_TYPE_METHOD) {
  250. /*
  251. * Case 1) We have an actual control method to execute
  252. */
  253. status = acpi_ns_execute_control_method (info);
  254. }
  255. else {
  256. /*
  257. * Case 2) Object is NOT a method, just return its current value
  258. */
  259. status = acpi_ns_get_object_value (info);
  260. }
  261. /*
  262. * Check if there is a return value on the stack that must be dealt with
  263. */
  264. if (status == AE_CTRL_RETURN_VALUE) {
  265. /* Map AE_CTRL_RETURN_VALUE to AE_OK, we are done with it */
  266. status = AE_OK;
  267. }
  268. /*
  269. * Namespace was unlocked by the handling acpi_ns* function, so we
  270. * just return
  271. */
  272. return_ACPI_STATUS (status);
  273. }
  274. /*******************************************************************************
  275. *
  276. * FUNCTION: acpi_ns_execute_control_method
  277. *
  278. * PARAMETERS: Info - Method info block (w/params)
  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. struct acpi_parameter_info *info)
  290. {
  291. acpi_status status;
  292. union acpi_operand_object *obj_desc;
  293. ACPI_FUNCTION_TRACE ("ns_execute_control_method");
  294. /* Verify that there is a method associated with this object */
  295. obj_desc = acpi_ns_get_attached_object (info->node);
  296. if (!obj_desc) {
  297. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No attached method object\n"));
  298. (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
  299. return_ACPI_STATUS (AE_NULL_OBJECT);
  300. }
  301. ACPI_DUMP_PATHNAME (info->node, "Execute Method:",
  302. ACPI_LV_INFO, _COMPONENT);
  303. ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Method at AML address %p Length %X\n",
  304. obj_desc->method.aml_start + 1, obj_desc->method.aml_length - 1));
  305. /*
  306. * Unlock the namespace before execution. This allows namespace access
  307. * via the external Acpi* interfaces while a method is being executed.
  308. * However, any namespace deletion must acquire both the namespace and
  309. * interpreter locks to ensure that no thread is using the portion of the
  310. * namespace that is being deleted.
  311. */
  312. status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
  313. if (ACPI_FAILURE (status)) {
  314. return_ACPI_STATUS (status);
  315. }
  316. /*
  317. * Execute the method via the interpreter. The interpreter is locked
  318. * here before calling into the AML parser
  319. */
  320. status = acpi_ex_enter_interpreter ();
  321. if (ACPI_FAILURE (status)) {
  322. return_ACPI_STATUS (status);
  323. }
  324. status = acpi_psx_execute (info);
  325. acpi_ex_exit_interpreter ();
  326. return_ACPI_STATUS (status);
  327. }
  328. /*******************************************************************************
  329. *
  330. * FUNCTION: acpi_ns_get_object_value
  331. *
  332. * PARAMETERS: Info - Method info block (w/params)
  333. *
  334. * RETURN: Status
  335. *
  336. * DESCRIPTION: Return the current value of the object
  337. *
  338. * MUTEX: Assumes namespace is locked, leaves namespace unlocked
  339. *
  340. ******************************************************************************/
  341. acpi_status
  342. acpi_ns_get_object_value (
  343. struct acpi_parameter_info *info)
  344. {
  345. acpi_status status = AE_OK;
  346. struct acpi_namespace_node *resolved_node = info->node;
  347. ACPI_FUNCTION_TRACE ("ns_get_object_value");
  348. /*
  349. * Objects require additional resolution steps (e.g., the Node may be a
  350. * field that must be read, etc.) -- we can't just grab the object out of
  351. * the node.
  352. */
  353. /*
  354. * Use resolve_node_to_value() to get the associated value. This call always
  355. * deletes obj_desc (allocated above).
  356. *
  357. * NOTE: we can get away with passing in NULL for a walk state because
  358. * obj_desc is guaranteed to not be a reference to either a method local or
  359. * a method argument (because this interface can only be called from the
  360. * acpi_evaluate external interface, never called from a running method.)
  361. *
  362. * Even though we do not directly invoke the interpreter for this, we must
  363. * enter it because we could access an opregion. The opregion access code
  364. * assumes that the interpreter is locked.
  365. *
  366. * We must release the namespace lock before entering the intepreter.
  367. */
  368. status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
  369. if (ACPI_FAILURE (status)) {
  370. return_ACPI_STATUS (status);
  371. }
  372. status = acpi_ex_enter_interpreter ();
  373. if (ACPI_SUCCESS (status)) {
  374. status = acpi_ex_resolve_node_to_value (&resolved_node, NULL);
  375. /*
  376. * If acpi_ex_resolve_node_to_value() succeeded, the return value was placed
  377. * in resolved_node.
  378. */
  379. acpi_ex_exit_interpreter ();
  380. if (ACPI_SUCCESS (status)) {
  381. status = AE_CTRL_RETURN_VALUE;
  382. info->return_object = ACPI_CAST_PTR
  383. (union acpi_operand_object, resolved_node);
  384. ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Returning object %p [%s]\n",
  385. info->return_object,
  386. acpi_ut_get_object_type_name (info->return_object)));
  387. }
  388. }
  389. /* Namespace is unlocked */
  390. return_ACPI_STATUS (status);
  391. }