nseval.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491
  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. /* Local prototypes */
  50. static acpi_status
  51. acpi_ns_execute_control_method(struct acpi_parameter_info *info);
  52. static acpi_status acpi_ns_get_object_value(struct acpi_parameter_info *info);
  53. /*******************************************************************************
  54. *
  55. * FUNCTION: acpi_ns_evaluate_relative
  56. *
  57. * PARAMETERS: Pathname - Name of method to execute, If NULL, the
  58. * handle is the object to execute
  59. * Info - Method info block, contains:
  60. * return_object - Where to put method's return value (if
  61. * any). If NULL, no value is returned.
  62. * Params - List of parameters to pass to the method,
  63. * terminated by NULL. Params itself may be
  64. * NULL if no parameters are being passed.
  65. *
  66. * RETURN: Status
  67. *
  68. * DESCRIPTION: Evaluate the object or find and execute the requested method
  69. *
  70. * MUTEX: Locks Namespace
  71. *
  72. ******************************************************************************/
  73. acpi_status
  74. acpi_ns_evaluate_relative(char *pathname, struct acpi_parameter_info *info)
  75. {
  76. acpi_status status;
  77. struct acpi_namespace_node *node = NULL;
  78. union acpi_generic_state *scope_info;
  79. char *internal_path = NULL;
  80. ACPI_FUNCTION_TRACE("ns_evaluate_relative");
  81. /*
  82. * Must have a valid object handle
  83. */
  84. if (!info || !info->node) {
  85. return_ACPI_STATUS(AE_BAD_PARAMETER);
  86. }
  87. /* Build an internal name string for the method */
  88. status = acpi_ns_internalize_name(pathname, &internal_path);
  89. if (ACPI_FAILURE(status)) {
  90. return_ACPI_STATUS(status);
  91. }
  92. scope_info = acpi_ut_create_generic_state();
  93. if (!scope_info) {
  94. goto cleanup1;
  95. }
  96. /* Get the prefix handle and Node */
  97. status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
  98. if (ACPI_FAILURE(status)) {
  99. goto cleanup;
  100. }
  101. info->node = acpi_ns_map_handle_to_node(info->node);
  102. if (!info->node) {
  103. (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
  104. status = AE_BAD_PARAMETER;
  105. goto cleanup;
  106. }
  107. /* Lookup the name in the namespace */
  108. scope_info->scope.node = info->node;
  109. status = acpi_ns_lookup(scope_info, internal_path, ACPI_TYPE_ANY,
  110. ACPI_IMODE_EXECUTE, ACPI_NS_NO_UPSEARCH, NULL,
  111. &node);
  112. (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
  113. if (ACPI_FAILURE(status)) {
  114. ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "Object [%s] not found [%s]\n",
  115. pathname, acpi_format_exception(status)));
  116. goto cleanup;
  117. }
  118. /*
  119. * Now that we have a handle to the object, we can attempt to evaluate it.
  120. */
  121. ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "%s [%p] Value %p\n",
  122. pathname, node, acpi_ns_get_attached_object(node)));
  123. info->node = node;
  124. status = acpi_ns_evaluate_by_handle(info);
  125. ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
  126. "*** Completed eval of object %s ***\n", pathname));
  127. cleanup:
  128. acpi_ut_delete_generic_state(scope_info);
  129. cleanup1:
  130. ACPI_MEM_FREE(internal_path);
  131. return_ACPI_STATUS(status);
  132. }
  133. /*******************************************************************************
  134. *
  135. * FUNCTION: acpi_ns_evaluate_by_name
  136. *
  137. * PARAMETERS: Pathname - Fully qualified pathname to the object
  138. * Info - Method info block, contains:
  139. * return_object - Where to put method's return value (if
  140. * any). If NULL, no value is returned.
  141. * Params - List of parameters to pass to the method,
  142. * terminated by NULL. Params itself may be
  143. * NULL if no parameters are being passed.
  144. *
  145. * RETURN: Status
  146. *
  147. * DESCRIPTION: Evaluate the object or rind and execute the requested method
  148. * passing the given parameters
  149. *
  150. * MUTEX: Locks Namespace
  151. *
  152. ******************************************************************************/
  153. acpi_status
  154. acpi_ns_evaluate_by_name(char *pathname, struct acpi_parameter_info *info)
  155. {
  156. acpi_status status;
  157. char *internal_path = NULL;
  158. ACPI_FUNCTION_TRACE("ns_evaluate_by_name");
  159. /* Build an internal name string for the method */
  160. status = acpi_ns_internalize_name(pathname, &internal_path);
  161. if (ACPI_FAILURE(status)) {
  162. return_ACPI_STATUS(status);
  163. }
  164. status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
  165. if (ACPI_FAILURE(status)) {
  166. goto cleanup;
  167. }
  168. /* Lookup the name in the namespace */
  169. status = acpi_ns_lookup(NULL, internal_path, ACPI_TYPE_ANY,
  170. ACPI_IMODE_EXECUTE, ACPI_NS_NO_UPSEARCH, NULL,
  171. &info->node);
  172. (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
  173. if (ACPI_FAILURE(status)) {
  174. ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
  175. "Object at [%s] was not found, status=%.4X\n",
  176. pathname, status));
  177. goto cleanup;
  178. }
  179. /*
  180. * Now that we have a handle to the object, we can attempt to evaluate it.
  181. */
  182. ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "%s [%p] Value %p\n",
  183. pathname, info->node,
  184. acpi_ns_get_attached_object(info->node)));
  185. status = acpi_ns_evaluate_by_handle(info);
  186. ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
  187. "*** Completed eval of object %s ***\n", pathname));
  188. cleanup:
  189. /* Cleanup */
  190. if (internal_path) {
  191. ACPI_MEM_FREE(internal_path);
  192. }
  193. return_ACPI_STATUS(status);
  194. }
  195. /*******************************************************************************
  196. *
  197. * FUNCTION: acpi_ns_evaluate_by_handle
  198. *
  199. * PARAMETERS: Info - Method info block, contains:
  200. * Node - Method/Object Node to execute
  201. * Parameters - List of parameters to pass to the method,
  202. * terminated by NULL. Params itself may be
  203. * NULL if no parameters are being passed.
  204. * return_object - Where to put method's return value (if
  205. * any). If NULL, no value is returned.
  206. * parameter_type - Type of Parameter list
  207. * return_object - Where to put method's return value (if
  208. * any). If NULL, no value is returned.
  209. *
  210. * RETURN: Status
  211. *
  212. * DESCRIPTION: Evaluate object or execute the requested method passing the
  213. * given parameters
  214. *
  215. * MUTEX: Locks Namespace
  216. *
  217. ******************************************************************************/
  218. acpi_status acpi_ns_evaluate_by_handle(struct acpi_parameter_info *info)
  219. {
  220. acpi_status status;
  221. ACPI_FUNCTION_TRACE("ns_evaluate_by_handle");
  222. /* Check if namespace has been initialized */
  223. if (!acpi_gbl_root_node) {
  224. return_ACPI_STATUS(AE_NO_NAMESPACE);
  225. }
  226. /* Parameter Validation */
  227. if (!info) {
  228. return_ACPI_STATUS(AE_BAD_PARAMETER);
  229. }
  230. /* Initialize the return value to an invalid object */
  231. info->return_object = NULL;
  232. /* Get the prefix handle and Node */
  233. status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
  234. if (ACPI_FAILURE(status)) {
  235. return_ACPI_STATUS(status);
  236. }
  237. info->node = acpi_ns_map_handle_to_node(info->node);
  238. if (!info->node) {
  239. (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
  240. return_ACPI_STATUS(AE_BAD_PARAMETER);
  241. }
  242. /*
  243. * For a method alias, we must grab the actual method node so that proper
  244. * scoping context will be established before execution.
  245. */
  246. if (acpi_ns_get_type(info->node) == ACPI_TYPE_LOCAL_METHOD_ALIAS) {
  247. info->node =
  248. ACPI_CAST_PTR(struct acpi_namespace_node,
  249. info->node->object);
  250. }
  251. /*
  252. * Two major cases here:
  253. * 1) The object is an actual control method -- execute it.
  254. * 2) The object is not a method -- just return it's current value
  255. *
  256. * In both cases, the namespace is unlocked by the acpi_ns* procedure
  257. */
  258. if (acpi_ns_get_type(info->node) == ACPI_TYPE_METHOD) {
  259. /*
  260. * Case 1) We have an actual control method to execute
  261. */
  262. status = acpi_ns_execute_control_method(info);
  263. } else {
  264. /*
  265. * Case 2) Object is NOT a method, just return its current value
  266. */
  267. status = acpi_ns_get_object_value(info);
  268. }
  269. /*
  270. * Check if there is a return value on the stack that must be dealt with
  271. */
  272. if (status == AE_CTRL_RETURN_VALUE) {
  273. /* Map AE_CTRL_RETURN_VALUE to AE_OK, we are done with it */
  274. status = AE_OK;
  275. }
  276. /*
  277. * Namespace was unlocked by the handling acpi_ns* function, so we
  278. * just return
  279. */
  280. return_ACPI_STATUS(status);
  281. }
  282. /*******************************************************************************
  283. *
  284. * FUNCTION: acpi_ns_execute_control_method
  285. *
  286. * PARAMETERS: Info - Method info block, contains:
  287. * Node - Method Node to execute
  288. * obj_desc - Method object
  289. * Parameters - List of parameters to pass to the method,
  290. * terminated by NULL. Params itself may be
  291. * NULL if no parameters are being passed.
  292. * return_object - Where to put method's return value (if
  293. * any). If NULL, no value is returned.
  294. * parameter_type - Type of Parameter list
  295. * return_object - Where to put method's return value (if
  296. * any). If NULL, no value is returned.
  297. *
  298. * RETURN: Status
  299. *
  300. * DESCRIPTION: Execute the requested method passing the given parameters
  301. *
  302. * MUTEX: Assumes namespace is locked
  303. *
  304. ******************************************************************************/
  305. static acpi_status
  306. acpi_ns_execute_control_method(struct acpi_parameter_info *info)
  307. {
  308. acpi_status status;
  309. ACPI_FUNCTION_TRACE("ns_execute_control_method");
  310. /* Verify that there is a method associated with this object */
  311. info->obj_desc = acpi_ns_get_attached_object(info->node);
  312. if (!info->obj_desc) {
  313. ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
  314. "No attached method object\n"));
  315. (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
  316. return_ACPI_STATUS(AE_NULL_OBJECT);
  317. }
  318. ACPI_DUMP_PATHNAME(info->node, "Execute Method:",
  319. ACPI_LV_INFO, _COMPONENT);
  320. ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Method at AML address %p Length %X\n",
  321. info->obj_desc->method.aml_start + 1,
  322. info->obj_desc->method.aml_length - 1));
  323. /*
  324. * Unlock the namespace before execution. This allows namespace access
  325. * via the external Acpi* interfaces while a method is being executed.
  326. * However, any namespace deletion must acquire both the namespace and
  327. * interpreter locks to ensure that no thread is using the portion of the
  328. * namespace that is being deleted.
  329. */
  330. status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
  331. if (ACPI_FAILURE(status)) {
  332. return_ACPI_STATUS(status);
  333. }
  334. /*
  335. * Execute the method via the interpreter. The interpreter is locked
  336. * here before calling into the AML parser
  337. */
  338. status = acpi_ex_enter_interpreter();
  339. if (ACPI_FAILURE(status)) {
  340. return_ACPI_STATUS(status);
  341. }
  342. status = acpi_ps_execute_method(info);
  343. acpi_ex_exit_interpreter();
  344. return_ACPI_STATUS(status);
  345. }
  346. /*******************************************************************************
  347. *
  348. * FUNCTION: acpi_ns_get_object_value
  349. *
  350. * PARAMETERS: Info - Method info block, contains:
  351. * Node - Object's NS node
  352. * return_object - Where to put object value (if
  353. * any). If NULL, no value is returned.
  354. *
  355. * RETURN: Status
  356. *
  357. * DESCRIPTION: Return the current value of the object
  358. *
  359. * MUTEX: Assumes namespace is locked, leaves namespace unlocked
  360. *
  361. ******************************************************************************/
  362. static acpi_status acpi_ns_get_object_value(struct acpi_parameter_info *info)
  363. {
  364. acpi_status status = AE_OK;
  365. struct acpi_namespace_node *resolved_node = info->node;
  366. ACPI_FUNCTION_TRACE("ns_get_object_value");
  367. /*
  368. * Objects require additional resolution steps (e.g., the Node may be a
  369. * field that must be read, etc.) -- we can't just grab the object out of
  370. * the node.
  371. */
  372. /*
  373. * Use resolve_node_to_value() to get the associated value. This call always
  374. * deletes obj_desc (allocated above).
  375. *
  376. * NOTE: we can get away with passing in NULL for a walk state because
  377. * obj_desc is guaranteed to not be a reference to either a method local or
  378. * a method argument (because this interface can only be called from the
  379. * acpi_evaluate external interface, never called from a running method.)
  380. *
  381. * Even though we do not directly invoke the interpreter for this, we must
  382. * enter it because we could access an opregion. The opregion access code
  383. * assumes that the interpreter is locked.
  384. *
  385. * We must release the namespace lock before entering the intepreter.
  386. */
  387. status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
  388. if (ACPI_FAILURE(status)) {
  389. return_ACPI_STATUS(status);
  390. }
  391. status = acpi_ex_enter_interpreter();
  392. if (ACPI_SUCCESS(status)) {
  393. status = acpi_ex_resolve_node_to_value(&resolved_node, NULL);
  394. /*
  395. * If acpi_ex_resolve_node_to_value() succeeded, the return value was placed
  396. * in resolved_node.
  397. */
  398. acpi_ex_exit_interpreter();
  399. if (ACPI_SUCCESS(status)) {
  400. status = AE_CTRL_RETURN_VALUE;
  401. info->return_object = ACPI_CAST_PTR
  402. (union acpi_operand_object, resolved_node);
  403. ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
  404. "Returning object %p [%s]\n",
  405. info->return_object,
  406. acpi_ut_get_object_type_name(info->
  407. return_object)));
  408. }
  409. }
  410. /* Namespace is unlocked */
  411. return_ACPI_STATUS(status);
  412. }