1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2 /******************************************************************************
4 * Module Name: uteval - Object evaluation
6 * Copyright (C) 2000 - 2020, Intel Corp.
8 *****************************************************************************/
10 #include <acpi/acpi.h>
14 #define _COMPONENT ACPI_UTILITIES
15 ACPI_MODULE_NAME("uteval")
17 /*******************************************************************************
19 * FUNCTION: acpi_ut_evaluate_object
21 * PARAMETERS: prefix_node - Starting node
22 * path - Path to object from starting node
23 * expected_return_types - Bitmap of allowed return types
24 * return_desc - Where a return value is stored
28 * DESCRIPTION: Evaluates a namespace object and verifies the type of the
29 * return object. Common code that simplifies accessing objects
30 * that have required return objects of fixed types.
32 * NOTE: Internal function, no parameter validation
34 ******************************************************************************/
37 acpi_ut_evaluate_object(struct acpi_namespace_node
*prefix_node
,
39 u32 expected_return_btypes
,
40 union acpi_operand_object
**return_desc
)
42 struct acpi_evaluate_info
*info
;
46 ACPI_FUNCTION_TRACE(ut_evaluate_object
);
48 /* Allocate the evaluation information block */
50 info
= ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info
));
52 return_ACPI_STATUS(AE_NO_MEMORY
);
55 info
->prefix_node
= prefix_node
;
56 info
->relative_pathname
= path
;
58 /* Evaluate the object/method */
60 status
= acpi_ns_evaluate(info
);
61 if (ACPI_FAILURE(status
)) {
62 if (status
== AE_NOT_FOUND
) {
63 ACPI_DEBUG_PRINT((ACPI_DB_EXEC
,
64 "[%4.4s.%s] was not found\n",
65 acpi_ut_get_node_name(prefix_node
),
68 ACPI_ERROR_METHOD("Method execution failed",
69 prefix_node
, path
, status
);
75 /* Did we get a return object? */
77 if (!info
->return_object
) {
78 if (expected_return_btypes
) {
79 ACPI_ERROR_METHOD("No object was returned from",
80 prefix_node
, path
, AE_NOT_EXIST
);
82 status
= AE_NOT_EXIST
;
88 /* Map the return object type to the bitmapped type */
90 switch ((info
->return_object
)->common
.type
) {
91 case ACPI_TYPE_INTEGER
:
93 return_btype
= ACPI_BTYPE_INTEGER
;
96 case ACPI_TYPE_BUFFER
:
98 return_btype
= ACPI_BTYPE_BUFFER
;
101 case ACPI_TYPE_STRING
:
103 return_btype
= ACPI_BTYPE_STRING
;
106 case ACPI_TYPE_PACKAGE
:
108 return_btype
= ACPI_BTYPE_PACKAGE
;
117 if ((acpi_gbl_enable_interpreter_slack
) && (!expected_return_btypes
)) {
119 * We received a return object, but one was not expected. This can
120 * happen frequently if the "implicit return" feature is enabled.
121 * Just delete the return object and return AE_OK.
123 acpi_ut_remove_reference(info
->return_object
);
127 /* Is the return object one of the expected types? */
129 if (!(expected_return_btypes
& return_btype
)) {
130 ACPI_ERROR_METHOD("Return object type is incorrect",
131 prefix_node
, path
, AE_TYPE
);
134 "Type returned from %s was incorrect: %s, expected Btypes: 0x%X",
136 acpi_ut_get_object_type_name(info
->return_object
),
137 expected_return_btypes
));
139 /* On error exit, we must delete the return object */
141 acpi_ut_remove_reference(info
->return_object
);
146 /* Object type is OK, return it */
148 *return_desc
= info
->return_object
;
152 return_ACPI_STATUS(status
);
155 /*******************************************************************************
157 * FUNCTION: acpi_ut_evaluate_numeric_object
159 * PARAMETERS: object_name - Object name to be evaluated
160 * device_node - Node for the device
161 * value - Where the value is returned
165 * DESCRIPTION: Evaluates a numeric namespace object for a selected device
166 * and stores result in *Value.
168 * NOTE: Internal function, no parameter validation
170 ******************************************************************************/
173 acpi_ut_evaluate_numeric_object(const char *object_name
,
174 struct acpi_namespace_node
*device_node
,
177 union acpi_operand_object
*obj_desc
;
180 ACPI_FUNCTION_TRACE(ut_evaluate_numeric_object
);
182 status
= acpi_ut_evaluate_object(device_node
, object_name
,
183 ACPI_BTYPE_INTEGER
, &obj_desc
);
184 if (ACPI_FAILURE(status
)) {
185 return_ACPI_STATUS(status
);
188 /* Get the returned Integer */
190 *value
= obj_desc
->integer
.value
;
192 /* On exit, we must delete the return object */
194 acpi_ut_remove_reference(obj_desc
);
195 return_ACPI_STATUS(status
);
198 /*******************************************************************************
200 * FUNCTION: acpi_ut_execute_STA
202 * PARAMETERS: device_node - Node for the device
203 * flags - Where the status flags are returned
207 * DESCRIPTION: Executes _STA for selected device and stores results in
208 * *Flags. If _STA does not exist, then the device is assumed
209 * to be present/functional/enabled (as per the ACPI spec).
211 * NOTE: Internal function, no parameter validation
213 ******************************************************************************/
216 acpi_ut_execute_STA(struct acpi_namespace_node
*device_node
, u32
* flags
)
218 union acpi_operand_object
*obj_desc
;
221 ACPI_FUNCTION_TRACE(ut_execute_STA
);
223 status
= acpi_ut_evaluate_object(device_node
, METHOD_NAME__STA
,
224 ACPI_BTYPE_INTEGER
, &obj_desc
);
225 if (ACPI_FAILURE(status
)) {
226 if (AE_NOT_FOUND
== status
) {
228 * if _STA does not exist, then (as per the ACPI specification),
229 * the returned flags will indicate that the device is present,
230 * functional, and enabled.
232 ACPI_DEBUG_PRINT((ACPI_DB_EXEC
,
233 "_STA on %4.4s was not found, assuming device is present\n",
234 acpi_ut_get_node_name(device_node
)));
236 *flags
= ACPI_UINT32_MAX
;
240 return_ACPI_STATUS(status
);
243 /* Extract the status flags */
245 *flags
= (u32
) obj_desc
->integer
.value
;
247 /* On exit, we must delete the return object */
249 acpi_ut_remove_reference(obj_desc
);
250 return_ACPI_STATUS(status
);
253 /*******************************************************************************
255 * FUNCTION: acpi_ut_execute_power_methods
257 * PARAMETERS: device_node - Node for the device
258 * method_names - Array of power method names
259 * method_count - Number of methods to execute
260 * out_values - Where the power method values are returned
262 * RETURN: Status, out_values
264 * DESCRIPTION: Executes the specified power methods for the device and returns
267 * NOTE: Internal function, no parameter validation
269 ******************************************************************************/
272 acpi_ut_execute_power_methods(struct acpi_namespace_node
*device_node
,
273 const char **method_names
,
274 u8 method_count
, u8
*out_values
)
276 union acpi_operand_object
*obj_desc
;
278 acpi_status final_status
= AE_NOT_FOUND
;
281 ACPI_FUNCTION_TRACE(ut_execute_power_methods
);
283 for (i
= 0; i
< method_count
; i
++) {
285 * Execute the power method (_sx_d or _sx_w). The only allowable
286 * return type is an Integer.
288 status
= acpi_ut_evaluate_object(device_node
,
291 ACPI_BTYPE_INTEGER
, &obj_desc
);
292 if (ACPI_SUCCESS(status
)) {
293 out_values
[i
] = (u8
)obj_desc
->integer
.value
;
295 /* Delete the return object */
297 acpi_ut_remove_reference(obj_desc
);
298 final_status
= AE_OK
; /* At least one value is valid */
302 out_values
[i
] = ACPI_UINT8_MAX
;
303 if (status
== AE_NOT_FOUND
) {
304 continue; /* Ignore if not found */
307 ACPI_DEBUG_PRINT((ACPI_DB_EXEC
,
308 "Failed %s on Device %4.4s, %s\n",
309 ACPI_CAST_PTR(char, method_names
[i
]),
310 acpi_ut_get_node_name(device_node
),
311 acpi_format_exception(status
)));
314 return_ACPI_STATUS(final_status
);