/drivers/acpi/acpica/uteval.c

http://github.com/mirrors/linux · C · 315 lines · 152 code · 62 blank · 101 comment · 19 complexity · f3f4c640336791b1ebe78ca9a3862597 MD5 · raw file

  1. // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
  2. /******************************************************************************
  3. *
  4. * Module Name: uteval - Object evaluation
  5. *
  6. * Copyright (C) 2000 - 2020, Intel Corp.
  7. *
  8. *****************************************************************************/
  9. #include <acpi/acpi.h>
  10. #include "accommon.h"
  11. #include "acnamesp.h"
  12. #define _COMPONENT ACPI_UTILITIES
  13. ACPI_MODULE_NAME("uteval")
  14. /*******************************************************************************
  15. *
  16. * FUNCTION: acpi_ut_evaluate_object
  17. *
  18. * PARAMETERS: prefix_node - Starting node
  19. * path - Path to object from starting node
  20. * expected_return_types - Bitmap of allowed return types
  21. * return_desc - Where a return value is stored
  22. *
  23. * RETURN: Status
  24. *
  25. * DESCRIPTION: Evaluates a namespace object and verifies the type of the
  26. * return object. Common code that simplifies accessing objects
  27. * that have required return objects of fixed types.
  28. *
  29. * NOTE: Internal function, no parameter validation
  30. *
  31. ******************************************************************************/
  32. acpi_status
  33. acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node,
  34. const char *path,
  35. u32 expected_return_btypes,
  36. union acpi_operand_object **return_desc)
  37. {
  38. struct acpi_evaluate_info *info;
  39. acpi_status status;
  40. u32 return_btype;
  41. ACPI_FUNCTION_TRACE(ut_evaluate_object);
  42. /* Allocate the evaluation information block */
  43. info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
  44. if (!info) {
  45. return_ACPI_STATUS(AE_NO_MEMORY);
  46. }
  47. info->prefix_node = prefix_node;
  48. info->relative_pathname = path;
  49. /* Evaluate the object/method */
  50. status = acpi_ns_evaluate(info);
  51. if (ACPI_FAILURE(status)) {
  52. if (status == AE_NOT_FOUND) {
  53. ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
  54. "[%4.4s.%s] was not found\n",
  55. acpi_ut_get_node_name(prefix_node),
  56. path));
  57. } else {
  58. ACPI_ERROR_METHOD("Method execution failed",
  59. prefix_node, path, status);
  60. }
  61. goto cleanup;
  62. }
  63. /* Did we get a return object? */
  64. if (!info->return_object) {
  65. if (expected_return_btypes) {
  66. ACPI_ERROR_METHOD("No object was returned from",
  67. prefix_node, path, AE_NOT_EXIST);
  68. status = AE_NOT_EXIST;
  69. }
  70. goto cleanup;
  71. }
  72. /* Map the return object type to the bitmapped type */
  73. switch ((info->return_object)->common.type) {
  74. case ACPI_TYPE_INTEGER:
  75. return_btype = ACPI_BTYPE_INTEGER;
  76. break;
  77. case ACPI_TYPE_BUFFER:
  78. return_btype = ACPI_BTYPE_BUFFER;
  79. break;
  80. case ACPI_TYPE_STRING:
  81. return_btype = ACPI_BTYPE_STRING;
  82. break;
  83. case ACPI_TYPE_PACKAGE:
  84. return_btype = ACPI_BTYPE_PACKAGE;
  85. break;
  86. default:
  87. return_btype = 0;
  88. break;
  89. }
  90. if ((acpi_gbl_enable_interpreter_slack) && (!expected_return_btypes)) {
  91. /*
  92. * We received a return object, but one was not expected. This can
  93. * happen frequently if the "implicit return" feature is enabled.
  94. * Just delete the return object and return AE_OK.
  95. */
  96. acpi_ut_remove_reference(info->return_object);
  97. goto cleanup;
  98. }
  99. /* Is the return object one of the expected types? */
  100. if (!(expected_return_btypes & return_btype)) {
  101. ACPI_ERROR_METHOD("Return object type is incorrect",
  102. prefix_node, path, AE_TYPE);
  103. ACPI_ERROR((AE_INFO,
  104. "Type returned from %s was incorrect: %s, expected Btypes: 0x%X",
  105. path,
  106. acpi_ut_get_object_type_name(info->return_object),
  107. expected_return_btypes));
  108. /* On error exit, we must delete the return object */
  109. acpi_ut_remove_reference(info->return_object);
  110. status = AE_TYPE;
  111. goto cleanup;
  112. }
  113. /* Object type is OK, return it */
  114. *return_desc = info->return_object;
  115. cleanup:
  116. ACPI_FREE(info);
  117. return_ACPI_STATUS(status);
  118. }
  119. /*******************************************************************************
  120. *
  121. * FUNCTION: acpi_ut_evaluate_numeric_object
  122. *
  123. * PARAMETERS: object_name - Object name to be evaluated
  124. * device_node - Node for the device
  125. * value - Where the value is returned
  126. *
  127. * RETURN: Status
  128. *
  129. * DESCRIPTION: Evaluates a numeric namespace object for a selected device
  130. * and stores result in *Value.
  131. *
  132. * NOTE: Internal function, no parameter validation
  133. *
  134. ******************************************************************************/
  135. acpi_status
  136. acpi_ut_evaluate_numeric_object(const char *object_name,
  137. struct acpi_namespace_node *device_node,
  138. u64 *value)
  139. {
  140. union acpi_operand_object *obj_desc;
  141. acpi_status status;
  142. ACPI_FUNCTION_TRACE(ut_evaluate_numeric_object);
  143. status = acpi_ut_evaluate_object(device_node, object_name,
  144. ACPI_BTYPE_INTEGER, &obj_desc);
  145. if (ACPI_FAILURE(status)) {
  146. return_ACPI_STATUS(status);
  147. }
  148. /* Get the returned Integer */
  149. *value = obj_desc->integer.value;
  150. /* On exit, we must delete the return object */
  151. acpi_ut_remove_reference(obj_desc);
  152. return_ACPI_STATUS(status);
  153. }
  154. /*******************************************************************************
  155. *
  156. * FUNCTION: acpi_ut_execute_STA
  157. *
  158. * PARAMETERS: device_node - Node for the device
  159. * flags - Where the status flags are returned
  160. *
  161. * RETURN: Status
  162. *
  163. * DESCRIPTION: Executes _STA for selected device and stores results in
  164. * *Flags. If _STA does not exist, then the device is assumed
  165. * to be present/functional/enabled (as per the ACPI spec).
  166. *
  167. * NOTE: Internal function, no parameter validation
  168. *
  169. ******************************************************************************/
  170. acpi_status
  171. acpi_ut_execute_STA(struct acpi_namespace_node *device_node, u32 * flags)
  172. {
  173. union acpi_operand_object *obj_desc;
  174. acpi_status status;
  175. ACPI_FUNCTION_TRACE(ut_execute_STA);
  176. status = acpi_ut_evaluate_object(device_node, METHOD_NAME__STA,
  177. ACPI_BTYPE_INTEGER, &obj_desc);
  178. if (ACPI_FAILURE(status)) {
  179. if (AE_NOT_FOUND == status) {
  180. /*
  181. * if _STA does not exist, then (as per the ACPI specification),
  182. * the returned flags will indicate that the device is present,
  183. * functional, and enabled.
  184. */
  185. ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
  186. "_STA on %4.4s was not found, assuming device is present\n",
  187. acpi_ut_get_node_name(device_node)));
  188. *flags = ACPI_UINT32_MAX;
  189. status = AE_OK;
  190. }
  191. return_ACPI_STATUS(status);
  192. }
  193. /* Extract the status flags */
  194. *flags = (u32) obj_desc->integer.value;
  195. /* On exit, we must delete the return object */
  196. acpi_ut_remove_reference(obj_desc);
  197. return_ACPI_STATUS(status);
  198. }
  199. /*******************************************************************************
  200. *
  201. * FUNCTION: acpi_ut_execute_power_methods
  202. *
  203. * PARAMETERS: device_node - Node for the device
  204. * method_names - Array of power method names
  205. * method_count - Number of methods to execute
  206. * out_values - Where the power method values are returned
  207. *
  208. * RETURN: Status, out_values
  209. *
  210. * DESCRIPTION: Executes the specified power methods for the device and returns
  211. * the result(s).
  212. *
  213. * NOTE: Internal function, no parameter validation
  214. *
  215. ******************************************************************************/
  216. acpi_status
  217. acpi_ut_execute_power_methods(struct acpi_namespace_node *device_node,
  218. const char **method_names,
  219. u8 method_count, u8 *out_values)
  220. {
  221. union acpi_operand_object *obj_desc;
  222. acpi_status status;
  223. acpi_status final_status = AE_NOT_FOUND;
  224. u32 i;
  225. ACPI_FUNCTION_TRACE(ut_execute_power_methods);
  226. for (i = 0; i < method_count; i++) {
  227. /*
  228. * Execute the power method (_sx_d or _sx_w). The only allowable
  229. * return type is an Integer.
  230. */
  231. status = acpi_ut_evaluate_object(device_node,
  232. ACPI_CAST_PTR(char,
  233. method_names[i]),
  234. ACPI_BTYPE_INTEGER, &obj_desc);
  235. if (ACPI_SUCCESS(status)) {
  236. out_values[i] = (u8)obj_desc->integer.value;
  237. /* Delete the return object */
  238. acpi_ut_remove_reference(obj_desc);
  239. final_status = AE_OK; /* At least one value is valid */
  240. continue;
  241. }
  242. out_values[i] = ACPI_UINT8_MAX;
  243. if (status == AE_NOT_FOUND) {
  244. continue; /* Ignore if not found */
  245. }
  246. ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
  247. "Failed %s on Device %4.4s, %s\n",
  248. ACPI_CAST_PTR(char, method_names[i]),
  249. acpi_ut_get_node_name(device_node),
  250. acpi_format_exception(status)));
  251. }
  252. return_ACPI_STATUS(final_status);
  253. }