Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
6595 serge 1
/******************************************************************************
2
 *
3
 * Module Name: uteval - Object evaluation
4
 *
5
 *****************************************************************************/
6
 
7
/*
8
 * Copyright (C) 2000 - 2015, Intel Corp.
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
 
44
#include 
45
#include "accommon.h"
46
#include "acnamesp.h"
47
 
48
#define _COMPONENT          ACPI_UTILITIES
49
ACPI_MODULE_NAME("uteval")
50
 
51
/*******************************************************************************
52
 *
53
 * FUNCTION:    acpi_ut_evaluate_object
54
 *
55
 * PARAMETERS:  prefix_node         - Starting node
56
 *              path                - Path to object from starting node
57
 *              expected_return_types - Bitmap of allowed return types
58
 *              return_desc         - Where a return value is stored
59
 *
60
 * RETURN:      Status
61
 *
62
 * DESCRIPTION: Evaluates a namespace object and verifies the type of the
63
 *              return object. Common code that simplifies accessing objects
64
 *              that have required return objects of fixed types.
65
 *
66
 *              NOTE: Internal function, no parameter validation
67
 *
68
 ******************************************************************************/
69
 
70
acpi_status
71
acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node,
72
			char *path,
73
			u32 expected_return_btypes,
74
			union acpi_operand_object **return_desc)
75
{
76
	struct acpi_evaluate_info *info;
77
	acpi_status status;
78
	u32 return_btype;
79
 
80
	ACPI_FUNCTION_TRACE(ut_evaluate_object);
81
 
82
	/* Allocate the evaluation information block */
83
 
84
	info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
85
	if (!info) {
86
		return_ACPI_STATUS(AE_NO_MEMORY);
87
	}
88
 
89
	info->prefix_node = prefix_node;
90
	info->relative_pathname = path;
91
 
92
	/* Evaluate the object/method */
93
 
94
	status = acpi_ns_evaluate(info);
95
	if (ACPI_FAILURE(status)) {
96
		if (status == AE_NOT_FOUND) {
97
			ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
98
					  "[%4.4s.%s] was not found\n",
99
					  acpi_ut_get_node_name(prefix_node),
100
					  path));
101
		} else {
102
			ACPI_ERROR_METHOD("Method execution failed",
103
					  prefix_node, path, status);
104
		}
105
 
106
		goto cleanup;
107
	}
108
 
109
	/* Did we get a return object? */
110
 
111
	if (!info->return_object) {
112
		if (expected_return_btypes) {
113
			ACPI_ERROR_METHOD("No object was returned from",
114
					  prefix_node, path, AE_NOT_EXIST);
115
 
116
			status = AE_NOT_EXIST;
117
		}
118
 
119
		goto cleanup;
120
	}
121
 
122
	/* Map the return object type to the bitmapped type */
123
 
124
	switch ((info->return_object)->common.type) {
125
	case ACPI_TYPE_INTEGER:
126
 
127
		return_btype = ACPI_BTYPE_INTEGER;
128
		break;
129
 
130
	case ACPI_TYPE_BUFFER:
131
 
132
		return_btype = ACPI_BTYPE_BUFFER;
133
		break;
134
 
135
	case ACPI_TYPE_STRING:
136
 
137
		return_btype = ACPI_BTYPE_STRING;
138
		break;
139
 
140
	case ACPI_TYPE_PACKAGE:
141
 
142
		return_btype = ACPI_BTYPE_PACKAGE;
143
		break;
144
 
145
	default:
146
 
147
		return_btype = 0;
148
		break;
149
	}
150
 
151
	if ((acpi_gbl_enable_interpreter_slack) && (!expected_return_btypes)) {
152
		/*
153
		 * We received a return object, but one was not expected. This can
154
		 * happen frequently if the "implicit return" feature is enabled.
155
		 * Just delete the return object and return AE_OK.
156
		 */
157
		acpi_ut_remove_reference(info->return_object);
158
		goto cleanup;
159
	}
160
 
161
	/* Is the return object one of the expected types? */
162
 
163
	if (!(expected_return_btypes & return_btype)) {
164
		ACPI_ERROR_METHOD("Return object type is incorrect",
165
				  prefix_node, path, AE_TYPE);
166
 
167
		ACPI_ERROR((AE_INFO,
168
			    "Type returned from %s was incorrect: %s, expected Btypes: 0x%X",
169
			    path,
170
			    acpi_ut_get_object_type_name(info->return_object),
171
			    expected_return_btypes));
172
 
173
		/* On error exit, we must delete the return object */
174
 
175
		acpi_ut_remove_reference(info->return_object);
176
		status = AE_TYPE;
177
		goto cleanup;
178
	}
179
 
180
	/* Object type is OK, return it */
181
 
182
	*return_desc = info->return_object;
183
 
184
cleanup:
185
	ACPI_FREE(info);
186
	return_ACPI_STATUS(status);
187
}
188
 
189
/*******************************************************************************
190
 *
191
 * FUNCTION:    acpi_ut_evaluate_numeric_object
192
 *
193
 * PARAMETERS:  object_name         - Object name to be evaluated
194
 *              device_node         - Node for the device
195
 *              value               - Where the value is returned
196
 *
197
 * RETURN:      Status
198
 *
199
 * DESCRIPTION: Evaluates a numeric namespace object for a selected device
200
 *              and stores result in *Value.
201
 *
202
 *              NOTE: Internal function, no parameter validation
203
 *
204
 ******************************************************************************/
205
 
206
acpi_status
207
acpi_ut_evaluate_numeric_object(char *object_name,
208
				struct acpi_namespace_node *device_node,
209
				u64 *value)
210
{
211
	union acpi_operand_object *obj_desc;
212
	acpi_status status;
213
 
214
	ACPI_FUNCTION_TRACE(ut_evaluate_numeric_object);
215
 
216
	status = acpi_ut_evaluate_object(device_node, object_name,
217
					 ACPI_BTYPE_INTEGER, &obj_desc);
218
	if (ACPI_FAILURE(status)) {
219
		return_ACPI_STATUS(status);
220
	}
221
 
222
	/* Get the returned Integer */
223
 
224
	*value = obj_desc->integer.value;
225
 
226
	/* On exit, we must delete the return object */
227
 
228
	acpi_ut_remove_reference(obj_desc);
229
	return_ACPI_STATUS(status);
230
}
231
 
232
/*******************************************************************************
233
 *
234
 * FUNCTION:    acpi_ut_execute_STA
235
 *
236
 * PARAMETERS:  device_node         - Node for the device
237
 *              flags               - Where the status flags are returned
238
 *
239
 * RETURN:      Status
240
 *
241
 * DESCRIPTION: Executes _STA for selected device and stores results in
242
 *              *Flags. If _STA does not exist, then the device is assumed
243
 *              to be present/functional/enabled (as per the ACPI spec).
244
 *
245
 *              NOTE: Internal function, no parameter validation
246
 *
247
 ******************************************************************************/
248
 
249
acpi_status
250
acpi_ut_execute_STA(struct acpi_namespace_node *device_node, u32 * flags)
251
{
252
	union acpi_operand_object *obj_desc;
253
	acpi_status status;
254
 
255
	ACPI_FUNCTION_TRACE(ut_execute_STA);
256
 
257
	status = acpi_ut_evaluate_object(device_node, METHOD_NAME__STA,
258
					 ACPI_BTYPE_INTEGER, &obj_desc);
259
	if (ACPI_FAILURE(status)) {
260
		if (AE_NOT_FOUND == status) {
261
			/*
262
			 * if _STA does not exist, then (as per the ACPI specification),
263
			 * the returned flags will indicate that the device is present,
264
			 * functional, and enabled.
265
			 */
266
			ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
267
					  "_STA on %4.4s was not found, assuming device is present\n",
268
					  acpi_ut_get_node_name(device_node)));
269
 
270
			*flags = ACPI_UINT32_MAX;
271
			status = AE_OK;
272
		}
273
 
274
		return_ACPI_STATUS(status);
275
	}
276
 
277
	/* Extract the status flags */
278
 
279
	*flags = (u32) obj_desc->integer.value;
280
 
281
	/* On exit, we must delete the return object */
282
 
283
	acpi_ut_remove_reference(obj_desc);
284
	return_ACPI_STATUS(status);
285
}
286
 
287
/*******************************************************************************
288
 *
289
 * FUNCTION:    acpi_ut_execute_power_methods
290
 *
291
 * PARAMETERS:  device_node         - Node for the device
292
 *              method_names        - Array of power method names
293
 *              method_count        - Number of methods to execute
294
 *              out_values          - Where the power method values are returned
295
 *
296
 * RETURN:      Status, out_values
297
 *
298
 * DESCRIPTION: Executes the specified power methods for the device and returns
299
 *              the result(s).
300
 *
301
 *              NOTE: Internal function, no parameter validation
302
 *
303
******************************************************************************/
304
 
305
acpi_status
306
acpi_ut_execute_power_methods(struct acpi_namespace_node *device_node,
307
			      const char **method_names,
308
			      u8 method_count, u8 *out_values)
309
{
310
	union acpi_operand_object *obj_desc;
311
	acpi_status status;
312
	acpi_status final_status = AE_NOT_FOUND;
313
	u32 i;
314
 
315
	ACPI_FUNCTION_TRACE(ut_execute_power_methods);
316
 
317
	for (i = 0; i < method_count; i++) {
318
		/*
319
		 * Execute the power method (_sx_d or _sx_w). The only allowable
320
		 * return type is an Integer.
321
		 */
322
		status = acpi_ut_evaluate_object(device_node,
323
						 ACPI_CAST_PTR(char,
324
							       method_names[i]),
325
						 ACPI_BTYPE_INTEGER, &obj_desc);
326
		if (ACPI_SUCCESS(status)) {
327
			out_values[i] = (u8)obj_desc->integer.value;
328
 
329
			/* Delete the return object */
330
 
331
			acpi_ut_remove_reference(obj_desc);
332
			final_status = AE_OK;	/* At least one value is valid */
333
			continue;
334
		}
335
 
336
		out_values[i] = ACPI_UINT8_MAX;
337
		if (status == AE_NOT_FOUND) {
338
			continue;	/* Ignore if not found */
339
		}
340
 
341
		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
342
				  "Failed %s on Device %4.4s, %s\n",
343
				  ACPI_CAST_PTR(char, method_names[i]),
344
				  acpi_ut_get_node_name(device_node),
345
				  acpi_format_exception(status)));
346
	}
347
 
348
	return_ACPI_STATUS(final_status);
349
}