blob: 3b9152579d040bcdc54646c72784e2653f5f173e [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/******************************************************************************
2 *
3 * Module Name: uteval - Object evaluation
4 *
5 *****************************************************************************/
6
7/*
Len Brown75a44ce2008-04-23 23:00:13 -04008 * Copyright (C) 2000 - 2008, Intel Corp.
Linus Torvalds1da177e2005-04-16 15:20:36 -07009 * 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
Linus Torvalds1da177e2005-04-16 15:20:36 -070044#include <acpi/acpi.h>
Len Browne2f7a772009-01-09 00:30:03 -050045#include "accommon.h"
46#include "acnamesp.h"
47#include "acinterp.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070048
Linus Torvalds1da177e2005-04-16 15:20:36 -070049#define _COMPONENT ACPI_UTILITIES
Len Brown4be44fc2005-08-05 00:44:28 -040050ACPI_MODULE_NAME("uteval")
Linus Torvalds1da177e2005-04-16 15:20:36 -070051
Robert Moore44f6c012005-04-18 22:49:35 -040052/* Local prototypes */
Robert Moore44f6c012005-04-18 22:49:35 -040053static void
Len Brown4be44fc2005-08-05 00:44:28 -040054acpi_ut_copy_id_string(char *destination, char *source, acpi_size max_length);
Robert Moore44f6c012005-04-18 22:49:35 -040055
56static acpi_status
Len Brown4be44fc2005-08-05 00:44:28 -040057acpi_ut_translate_one_cid(union acpi_operand_object *obj_desc,
58 struct acpi_compatible_id *one_cid);
Linus Torvalds1da177e2005-04-16 15:20:36 -070059
Bob Mooreb229cf92006-04-21 17:15:00 -040060/*
61 * Strings supported by the _OSI predefined (internal) method.
62 */
Len Brownae00d812007-05-29 18:43:33 -040063static char *acpi_interfaces_supported[] = {
Bob Mooreb229cf92006-04-21 17:15:00 -040064 /* Operating System Vendor Strings */
65
Bob Moore3c6394c2007-03-26 22:10:34 -040066 "Windows 2000", /* Windows 2000 */
67 "Windows 2001", /* Windows XP */
68 "Windows 2001 SP1", /* Windows XP SP1 */
69 "Windows 2001 SP2", /* Windows XP SP2 */
70 "Windows 2001.1", /* Windows Server 2003 */
71 "Windows 2001.1 SP1", /* Windows Server 2003 SP1 - Added 03/2006 */
72 "Windows 2006", /* Windows Vista - Added 03/2006 */
Bob Mooreb229cf92006-04-21 17:15:00 -040073
74 /* Feature Group Strings */
75
76 "Extended Address Space Descriptor"
77 /*
78 * All "optional" feature group strings (features that are implemented
79 * by the host) should be implemented in the host version of
80 * acpi_os_validate_interface and should not be added here.
81 */
82};
83
Linus Torvalds1da177e2005-04-16 15:20:36 -070084/*******************************************************************************
85 *
86 * FUNCTION: acpi_ut_osi_implementation
87 *
88 * PARAMETERS: walk_state - Current walk state
89 *
90 * RETURN: Status
91 *
Bob Mooreb229cf92006-04-21 17:15:00 -040092 * DESCRIPTION: Implementation of the _OSI predefined control method
Linus Torvalds1da177e2005-04-16 15:20:36 -070093 *
94 ******************************************************************************/
95
Len Brown4be44fc2005-08-05 00:44:28 -040096acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state)
Linus Torvalds1da177e2005-04-16 15:20:36 -070097{
Bob Mooreb229cf92006-04-21 17:15:00 -040098 acpi_status status;
Len Brown4be44fc2005-08-05 00:44:28 -040099 union acpi_operand_object *string_desc;
100 union acpi_operand_object *return_desc;
Bob Moorec114e4b2009-02-23 11:00:00 +0800101 u32 return_value;
Bob Moore67a119f2008-06-10 13:42:13 +0800102 u32 i;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700103
Bob Mooreb229cf92006-04-21 17:15:00 -0400104 ACPI_FUNCTION_TRACE(ut_osi_implementation);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700105
106 /* Validate the string input argument */
107
108 string_desc = walk_state->arguments[0].object;
109 if (!string_desc || (string_desc->common.type != ACPI_TYPE_STRING)) {
Len Brown4be44fc2005-08-05 00:44:28 -0400110 return_ACPI_STATUS(AE_TYPE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700111 }
112
Bob Mooreb229cf92006-04-21 17:15:00 -0400113 /* Create a return object */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700114
Len Brown4be44fc2005-08-05 00:44:28 -0400115 return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700116 if (!return_desc) {
Len Brown4be44fc2005-08-05 00:44:28 -0400117 return_ACPI_STATUS(AE_NO_MEMORY);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700118 }
119
Bob Moorec114e4b2009-02-23 11:00:00 +0800120 /* Default return value is 0, NOT SUPPORTED */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700121
Bob Moorec114e4b2009-02-23 11:00:00 +0800122 return_value = 0;
Bob Moore52fc0b02006-10-02 00:00:00 -0400123
Bob Mooreb229cf92006-04-21 17:15:00 -0400124 /* Compare input string to static table of supported interfaces */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700125
Bob Mooreb229cf92006-04-21 17:15:00 -0400126 for (i = 0; i < ACPI_ARRAY_LENGTH(acpi_interfaces_supported); i++) {
Bob Mooreec41f192009-02-18 15:03:30 +0800127 if (!ACPI_STRCMP(string_desc->string.pointer,
128 acpi_interfaces_supported[i])) {
Bob Moorec114e4b2009-02-23 11:00:00 +0800129
130 /* The interface is supported */
131
132 return_value = ACPI_UINT32_MAX;
133 goto exit;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700134 }
135 }
136
Bob Mooreb229cf92006-04-21 17:15:00 -0400137 /*
138 * Did not match the string in the static table, call the host OSL to
139 * check for a match with one of the optional strings (such as
140 * "Module Device", "3.0 Thermal Model", etc.)
141 */
142 status = acpi_os_validate_interface(string_desc->string.pointer);
143 if (ACPI_SUCCESS(status)) {
Bob Moorec114e4b2009-02-23 11:00:00 +0800144
145 /* The interface is supported */
146
147 return_value = ACPI_UINT32_MAX;
Bob Mooreb229cf92006-04-21 17:15:00 -0400148 }
149
Bob Moorec114e4b2009-02-23 11:00:00 +0800150exit:
151 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO,
152 "ACPI: BIOS _OSI(%s) is %ssupported\n",
153 string_desc->string.pointer, return_value == 0 ? "not " : ""));
Bob Mooreb229cf92006-04-21 17:15:00 -0400154
Bob Moorec114e4b2009-02-23 11:00:00 +0800155 /* Complete the return value */
156
157 return_desc->integer.value = return_value;
158 walk_state->return_desc = return_desc;
159 return_ACPI_STATUS (AE_OK);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700160}
161
Linus Torvalds1da177e2005-04-16 15:20:36 -0700162/*******************************************************************************
163 *
Len Brownae00d812007-05-29 18:43:33 -0400164 * FUNCTION: acpi_osi_invalidate
165 *
166 * PARAMETERS: interface_string
167 *
168 * RETURN: Status
169 *
170 * DESCRIPTION: invalidate string in pre-defiend _OSI string list
171 *
172 ******************************************************************************/
173
174acpi_status acpi_osi_invalidate(char *interface)
175{
176 int i;
177
178 for (i = 0; i < ACPI_ARRAY_LENGTH(acpi_interfaces_supported); i++) {
179 if (!ACPI_STRCMP(interface, acpi_interfaces_supported[i])) {
180 *acpi_interfaces_supported[i] = '\0';
181 return AE_OK;
182 }
183 }
184 return AE_NOT_FOUND;
185}
186
187/*******************************************************************************
188 *
Linus Torvalds1da177e2005-04-16 15:20:36 -0700189 * FUNCTION: acpi_ut_evaluate_object
190 *
191 * PARAMETERS: prefix_node - Starting node
192 * Path - Path to object from starting node
193 * expected_return_types - Bitmap of allowed return types
194 * return_desc - Where a return value is stored
195 *
196 * RETURN: Status
197 *
198 * DESCRIPTION: Evaluates a namespace object and verifies the type of the
199 * return object. Common code that simplifies accessing objects
200 * that have required return objects of fixed types.
201 *
202 * NOTE: Internal function, no parameter validation
203 *
204 ******************************************************************************/
205
206acpi_status
Len Brown4be44fc2005-08-05 00:44:28 -0400207acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node,
208 char *path,
209 u32 expected_return_btypes,
210 union acpi_operand_object **return_desc)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700211{
Bob Moore41195322006-05-26 16:36:00 -0400212 struct acpi_evaluate_info *info;
Len Brown4be44fc2005-08-05 00:44:28 -0400213 acpi_status status;
214 u32 return_btype;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700215
Bob Mooreb229cf92006-04-21 17:15:00 -0400216 ACPI_FUNCTION_TRACE(ut_evaluate_object);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700217
Bob Moore41195322006-05-26 16:36:00 -0400218 /* Allocate the evaluation information block */
219
220 info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
221 if (!info) {
222 return_ACPI_STATUS(AE_NO_MEMORY);
223 }
224
225 info->prefix_node = prefix_node;
226 info->pathname = path;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700227
228 /* Evaluate the object/method */
229
Bob Moore41195322006-05-26 16:36:00 -0400230 status = acpi_ns_evaluate(info);
Len Brown4be44fc2005-08-05 00:44:28 -0400231 if (ACPI_FAILURE(status)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700232 if (status == AE_NOT_FOUND) {
Len Brown4be44fc2005-08-05 00:44:28 -0400233 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
234 "[%4.4s.%s] was not found\n",
235 acpi_ut_get_node_name(prefix_node),
236 path));
237 } else {
Bob Mooreb8e4d892006-01-27 16:43:00 -0500238 ACPI_ERROR_METHOD("Method execution failed",
239 prefix_node, path, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700240 }
241
Bob Moore41195322006-05-26 16:36:00 -0400242 goto cleanup;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700243 }
244
245 /* Did we get a return object? */
246
Bob Moore41195322006-05-26 16:36:00 -0400247 if (!info->return_object) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700248 if (expected_return_btypes) {
Bob Mooreb8e4d892006-01-27 16:43:00 -0500249 ACPI_ERROR_METHOD("No object was returned from",
250 prefix_node, path, AE_NOT_EXIST);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700251
Bob Moore41195322006-05-26 16:36:00 -0400252 status = AE_NOT_EXIST;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700253 }
254
Bob Moore41195322006-05-26 16:36:00 -0400255 goto cleanup;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700256 }
257
258 /* Map the return object type to the bitmapped type */
259
Bob Moore3371c192009-02-18 14:44:03 +0800260 switch ((info->return_object)->common.type) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700261 case ACPI_TYPE_INTEGER:
262 return_btype = ACPI_BTYPE_INTEGER;
263 break;
264
265 case ACPI_TYPE_BUFFER:
266 return_btype = ACPI_BTYPE_BUFFER;
267 break;
268
269 case ACPI_TYPE_STRING:
270 return_btype = ACPI_BTYPE_STRING;
271 break;
272
273 case ACPI_TYPE_PACKAGE:
274 return_btype = ACPI_BTYPE_PACKAGE;
275 break;
276
277 default:
278 return_btype = 0;
279 break;
280 }
281
Len Brown4be44fc2005-08-05 00:44:28 -0400282 if ((acpi_gbl_enable_interpreter_slack) && (!expected_return_btypes)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700283 /*
284 * We received a return object, but one was not expected. This can
285 * happen frequently if the "implicit return" feature is enabled.
286 * Just delete the return object and return AE_OK.
287 */
Bob Moore41195322006-05-26 16:36:00 -0400288 acpi_ut_remove_reference(info->return_object);
289 goto cleanup;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700290 }
291
292 /* Is the return object one of the expected types? */
293
294 if (!(expected_return_btypes & return_btype)) {
Bob Mooreb8e4d892006-01-27 16:43:00 -0500295 ACPI_ERROR_METHOD("Return object type is incorrect",
296 prefix_node, path, AE_TYPE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700297
Bob Mooreb8e4d892006-01-27 16:43:00 -0500298 ACPI_ERROR((AE_INFO,
299 "Type returned from %s was incorrect: %s, expected Btypes: %X",
300 path,
Bob Moore41195322006-05-26 16:36:00 -0400301 acpi_ut_get_object_type_name(info->return_object),
Bob Mooreb8e4d892006-01-27 16:43:00 -0500302 expected_return_btypes));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700303
304 /* On error exit, we must delete the return object */
305
Bob Moore41195322006-05-26 16:36:00 -0400306 acpi_ut_remove_reference(info->return_object);
307 status = AE_TYPE;
308 goto cleanup;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700309 }
310
311 /* Object type is OK, return it */
312
Bob Moore41195322006-05-26 16:36:00 -0400313 *return_desc = info->return_object;
314
315 cleanup:
316 ACPI_FREE(info);
317 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700318}
319
Linus Torvalds1da177e2005-04-16 15:20:36 -0700320/*******************************************************************************
321 *
322 * FUNCTION: acpi_ut_evaluate_numeric_object
323 *
Robert Moore44f6c012005-04-18 22:49:35 -0400324 * PARAMETERS: object_name - Object name to be evaluated
Linus Torvalds1da177e2005-04-16 15:20:36 -0700325 * device_node - Node for the device
Robert Moore44f6c012005-04-18 22:49:35 -0400326 * Address - Where the value is returned
Linus Torvalds1da177e2005-04-16 15:20:36 -0700327 *
328 * RETURN: Status
329 *
330 * DESCRIPTION: Evaluates a numeric namespace object for a selected device
331 * and stores result in *Address.
332 *
333 * NOTE: Internal function, no parameter validation
334 *
335 ******************************************************************************/
336
337acpi_status
Len Brown4be44fc2005-08-05 00:44:28 -0400338acpi_ut_evaluate_numeric_object(char *object_name,
339 struct acpi_namespace_node *device_node,
340 acpi_integer * address)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700341{
Len Brown4be44fc2005-08-05 00:44:28 -0400342 union acpi_operand_object *obj_desc;
343 acpi_status status;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700344
Bob Mooreb229cf92006-04-21 17:15:00 -0400345 ACPI_FUNCTION_TRACE(ut_evaluate_numeric_object);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700346
Len Brown4be44fc2005-08-05 00:44:28 -0400347 status = acpi_ut_evaluate_object(device_node, object_name,
348 ACPI_BTYPE_INTEGER, &obj_desc);
349 if (ACPI_FAILURE(status)) {
350 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700351 }
352
353 /* Get the returned Integer */
354
355 *address = obj_desc->integer.value;
356
357 /* On exit, we must delete the return object */
358
Len Brown4be44fc2005-08-05 00:44:28 -0400359 acpi_ut_remove_reference(obj_desc);
360 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700361}
362
Linus Torvalds1da177e2005-04-16 15:20:36 -0700363/*******************************************************************************
364 *
365 * FUNCTION: acpi_ut_copy_id_string
366 *
367 * PARAMETERS: Destination - Where to copy the string
368 * Source - Source string
369 * max_length - Length of the destination buffer
370 *
371 * RETURN: None
372 *
373 * DESCRIPTION: Copies an ID string for the _HID, _CID, and _UID methods.
374 * Performs removal of a leading asterisk if present -- workaround
375 * for a known issue on a bunch of machines.
376 *
377 ******************************************************************************/
378
379static void
Len Brown4be44fc2005-08-05 00:44:28 -0400380acpi_ut_copy_id_string(char *destination, char *source, acpi_size max_length)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700381{
382
Linus Torvalds1da177e2005-04-16 15:20:36 -0700383 /*
384 * Workaround for ID strings that have a leading asterisk. This construct
385 * is not allowed by the ACPI specification (ID strings must be
386 * alphanumeric), but enough existing machines have this embedded in their
387 * ID strings that the following code is useful.
388 */
389 if (*source == '*') {
390 source++;
391 }
392
393 /* Do the actual copy */
394
Len Brown4be44fc2005-08-05 00:44:28 -0400395 ACPI_STRNCPY(destination, source, max_length);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700396}
397
Linus Torvalds1da177e2005-04-16 15:20:36 -0700398/*******************************************************************************
399 *
400 * FUNCTION: acpi_ut_execute_HID
401 *
402 * PARAMETERS: device_node - Node for the device
Robert Moore44f6c012005-04-18 22:49:35 -0400403 * Hid - Where the HID is returned
Linus Torvalds1da177e2005-04-16 15:20:36 -0700404 *
405 * RETURN: Status
406 *
407 * DESCRIPTION: Executes the _HID control method that returns the hardware
408 * ID of the device.
409 *
410 * NOTE: Internal function, no parameter validation
411 *
412 ******************************************************************************/
413
414acpi_status
Len Brown4be44fc2005-08-05 00:44:28 -0400415acpi_ut_execute_HID(struct acpi_namespace_node *device_node,
Thomas Renninger8c8eb782007-07-23 14:43:32 +0200416 struct acpica_device_id *hid)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700417{
Len Brown4be44fc2005-08-05 00:44:28 -0400418 union acpi_operand_object *obj_desc;
419 acpi_status status;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700420
Bob Mooreb229cf92006-04-21 17:15:00 -0400421 ACPI_FUNCTION_TRACE(ut_execute_HID);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700422
Len Brown4be44fc2005-08-05 00:44:28 -0400423 status = acpi_ut_evaluate_object(device_node, METHOD_NAME__HID,
424 ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING,
425 &obj_desc);
426 if (ACPI_FAILURE(status)) {
427 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700428 }
429
Bob Moore3371c192009-02-18 14:44:03 +0800430 if (obj_desc->common.type == ACPI_TYPE_INTEGER) {
Bob Moore52fc0b02006-10-02 00:00:00 -0400431
Linus Torvalds1da177e2005-04-16 15:20:36 -0700432 /* Convert the Numeric HID to string */
433
Len Brown4be44fc2005-08-05 00:44:28 -0400434 acpi_ex_eisa_id_to_string((u32) obj_desc->integer.value,
435 hid->value);
436 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700437 /* Copy the String HID from the returned object */
438
Len Brown4be44fc2005-08-05 00:44:28 -0400439 acpi_ut_copy_id_string(hid->value, obj_desc->string.pointer,
440 sizeof(hid->value));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700441 }
442
443 /* On exit, we must delete the return object */
444
Len Brown4be44fc2005-08-05 00:44:28 -0400445 acpi_ut_remove_reference(obj_desc);
446 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700447}
448
Linus Torvalds1da177e2005-04-16 15:20:36 -0700449/*******************************************************************************
450 *
451 * FUNCTION: acpi_ut_translate_one_cid
452 *
453 * PARAMETERS: obj_desc - _CID object, must be integer or string
454 * one_cid - Where the CID string is returned
455 *
456 * RETURN: Status
457 *
458 * DESCRIPTION: Return a numeric or string _CID value as a string.
459 * (Compatible ID)
460 *
461 * NOTE: Assumes a maximum _CID string length of
462 * ACPI_MAX_CID_LENGTH.
463 *
464 ******************************************************************************/
465
466static acpi_status
Len Brown4be44fc2005-08-05 00:44:28 -0400467acpi_ut_translate_one_cid(union acpi_operand_object *obj_desc,
468 struct acpi_compatible_id *one_cid)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700469{
470
Bob Moore3371c192009-02-18 14:44:03 +0800471 switch (obj_desc->common.type) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700472 case ACPI_TYPE_INTEGER:
473
474 /* Convert the Numeric CID to string */
475
Len Brown4be44fc2005-08-05 00:44:28 -0400476 acpi_ex_eisa_id_to_string((u32) obj_desc->integer.value,
477 one_cid->value);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700478 return (AE_OK);
479
480 case ACPI_TYPE_STRING:
481
482 if (obj_desc->string.length > ACPI_MAX_CID_LENGTH) {
483 return (AE_AML_STRING_LIMIT);
484 }
485
486 /* Copy the String CID from the returned object */
487
Len Brown4be44fc2005-08-05 00:44:28 -0400488 acpi_ut_copy_id_string(one_cid->value, obj_desc->string.pointer,
489 ACPI_MAX_CID_LENGTH);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700490 return (AE_OK);
491
492 default:
493
494 return (AE_TYPE);
495 }
496}
497
Linus Torvalds1da177e2005-04-16 15:20:36 -0700498/*******************************************************************************
499 *
500 * FUNCTION: acpi_ut_execute_CID
501 *
502 * PARAMETERS: device_node - Node for the device
Robert Moore44f6c012005-04-18 22:49:35 -0400503 * return_cid_list - Where the CID list is returned
Linus Torvalds1da177e2005-04-16 15:20:36 -0700504 *
505 * RETURN: Status
506 *
507 * DESCRIPTION: Executes the _CID control method that returns one or more
508 * compatible hardware IDs for the device.
509 *
510 * NOTE: Internal function, no parameter validation
511 *
512 ******************************************************************************/
513
514acpi_status
Len Brown4be44fc2005-08-05 00:44:28 -0400515acpi_ut_execute_CID(struct acpi_namespace_node * device_node,
516 struct acpi_compatible_id_list ** return_cid_list)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700517{
Len Brown4be44fc2005-08-05 00:44:28 -0400518 union acpi_operand_object *obj_desc;
519 acpi_status status;
520 u32 count;
521 u32 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700522 struct acpi_compatible_id_list *cid_list;
Bob Moore67a119f2008-06-10 13:42:13 +0800523 u32 i;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700524
Bob Mooreb229cf92006-04-21 17:15:00 -0400525 ACPI_FUNCTION_TRACE(ut_execute_CID);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700526
527 /* Evaluate the _CID method for this device */
528
Len Brown4be44fc2005-08-05 00:44:28 -0400529 status = acpi_ut_evaluate_object(device_node, METHOD_NAME__CID,
530 ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING
531 | ACPI_BTYPE_PACKAGE, &obj_desc);
532 if (ACPI_FAILURE(status)) {
533 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700534 }
535
536 /* Get the number of _CIDs returned */
537
538 count = 1;
Bob Moore3371c192009-02-18 14:44:03 +0800539 if (obj_desc->common.type == ACPI_TYPE_PACKAGE) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700540 count = obj_desc->package.count;
541 }
542
543 /* Allocate a worst-case buffer for the _CIDs */
544
Len Brown4be44fc2005-08-05 00:44:28 -0400545 size = (((count - 1) * sizeof(struct acpi_compatible_id)) +
546 sizeof(struct acpi_compatible_id_list));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700547
Bob Moore83135242006-10-03 00:00:00 -0400548 cid_list = ACPI_ALLOCATE_ZEROED((acpi_size) size);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700549 if (!cid_list) {
Len Brown4be44fc2005-08-05 00:44:28 -0400550 return_ACPI_STATUS(AE_NO_MEMORY);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700551 }
552
553 /* Init CID list */
554
555 cid_list->count = count;
556 cid_list->size = size;
557
558 /*
Robert Moore44f6c012005-04-18 22:49:35 -0400559 * A _CID can return either a single compatible ID or a package of
560 * compatible IDs. Each compatible ID can be one of the following:
561 * 1) Integer (32 bit compressed EISA ID) or
562 * 2) String (PCI ID format, e.g. "PCI\VEN_vvvv&DEV_dddd&SUBSYS_ssssssss")
Linus Torvalds1da177e2005-04-16 15:20:36 -0700563 */
564
565 /* The _CID object can be either a single CID or a package (list) of CIDs */
566
Bob Moore3371c192009-02-18 14:44:03 +0800567 if (obj_desc->common.type == ACPI_TYPE_PACKAGE) {
Bob Moore52fc0b02006-10-02 00:00:00 -0400568
Linus Torvalds1da177e2005-04-16 15:20:36 -0700569 /* Translate each package element */
570
571 for (i = 0; i < count; i++) {
Len Brown4be44fc2005-08-05 00:44:28 -0400572 status =
573 acpi_ut_translate_one_cid(obj_desc->package.
574 elements[i],
575 &cid_list->id[i]);
576 if (ACPI_FAILURE(status)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700577 break;
578 }
579 }
Len Brown4be44fc2005-08-05 00:44:28 -0400580 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700581 /* Only one CID, translate to a string */
582
Len Brown4be44fc2005-08-05 00:44:28 -0400583 status = acpi_ut_translate_one_cid(obj_desc, cid_list->id);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700584 }
585
586 /* Cleanup on error */
587
Len Brown4be44fc2005-08-05 00:44:28 -0400588 if (ACPI_FAILURE(status)) {
Bob Moore83135242006-10-03 00:00:00 -0400589 ACPI_FREE(cid_list);
Len Brown4be44fc2005-08-05 00:44:28 -0400590 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700591 *return_cid_list = cid_list;
592 }
593
594 /* On exit, we must delete the _CID return object */
595
Len Brown4be44fc2005-08-05 00:44:28 -0400596 acpi_ut_remove_reference(obj_desc);
597 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700598}
599
Linus Torvalds1da177e2005-04-16 15:20:36 -0700600/*******************************************************************************
601 *
602 * FUNCTION: acpi_ut_execute_UID
603 *
604 * PARAMETERS: device_node - Node for the device
Robert Moore44f6c012005-04-18 22:49:35 -0400605 * Uid - Where the UID is returned
Linus Torvalds1da177e2005-04-16 15:20:36 -0700606 *
607 * RETURN: Status
608 *
609 * DESCRIPTION: Executes the _UID control method that returns the hardware
610 * ID of the device.
611 *
612 * NOTE: Internal function, no parameter validation
613 *
614 ******************************************************************************/
615
616acpi_status
Len Brown4be44fc2005-08-05 00:44:28 -0400617acpi_ut_execute_UID(struct acpi_namespace_node *device_node,
Thomas Renninger8c8eb782007-07-23 14:43:32 +0200618 struct acpica_device_id *uid)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700619{
Len Brown4be44fc2005-08-05 00:44:28 -0400620 union acpi_operand_object *obj_desc;
621 acpi_status status;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700622
Bob Mooreb229cf92006-04-21 17:15:00 -0400623 ACPI_FUNCTION_TRACE(ut_execute_UID);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700624
Len Brown4be44fc2005-08-05 00:44:28 -0400625 status = acpi_ut_evaluate_object(device_node, METHOD_NAME__UID,
626 ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING,
627 &obj_desc);
628 if (ACPI_FAILURE(status)) {
629 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700630 }
631
Bob Moore3371c192009-02-18 14:44:03 +0800632 if (obj_desc->common.type == ACPI_TYPE_INTEGER) {
Bob Moore52fc0b02006-10-02 00:00:00 -0400633
Linus Torvalds1da177e2005-04-16 15:20:36 -0700634 /* Convert the Numeric UID to string */
635
Len Brown4be44fc2005-08-05 00:44:28 -0400636 acpi_ex_unsigned_integer_to_string(obj_desc->integer.value,
637 uid->value);
638 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700639 /* Copy the String UID from the returned object */
640
Len Brown4be44fc2005-08-05 00:44:28 -0400641 acpi_ut_copy_id_string(uid->value, obj_desc->string.pointer,
642 sizeof(uid->value));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700643 }
644
645 /* On exit, we must delete the return object */
646
Len Brown4be44fc2005-08-05 00:44:28 -0400647 acpi_ut_remove_reference(obj_desc);
648 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700649}
650
Linus Torvalds1da177e2005-04-16 15:20:36 -0700651/*******************************************************************************
652 *
653 * FUNCTION: acpi_ut_execute_STA
654 *
655 * PARAMETERS: device_node - Node for the device
Robert Moore44f6c012005-04-18 22:49:35 -0400656 * Flags - Where the status flags are returned
Linus Torvalds1da177e2005-04-16 15:20:36 -0700657 *
658 * RETURN: Status
659 *
660 * DESCRIPTION: Executes _STA for selected device and stores results in
661 * *Flags.
662 *
663 * NOTE: Internal function, no parameter validation
664 *
665 ******************************************************************************/
666
667acpi_status
Len Brown4be44fc2005-08-05 00:44:28 -0400668acpi_ut_execute_STA(struct acpi_namespace_node *device_node, u32 * flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700669{
Len Brown4be44fc2005-08-05 00:44:28 -0400670 union acpi_operand_object *obj_desc;
671 acpi_status status;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700672
Bob Mooreb229cf92006-04-21 17:15:00 -0400673 ACPI_FUNCTION_TRACE(ut_execute_STA);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700674
Len Brown4be44fc2005-08-05 00:44:28 -0400675 status = acpi_ut_evaluate_object(device_node, METHOD_NAME__STA,
676 ACPI_BTYPE_INTEGER, &obj_desc);
677 if (ACPI_FAILURE(status)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700678 if (AE_NOT_FOUND == status) {
Len Brown4be44fc2005-08-05 00:44:28 -0400679 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
680 "_STA on %4.4s was not found, assuming device is present\n",
681 acpi_ut_get_node_name(device_node)));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700682
Bob Mooredefba1d2005-12-16 17:05:00 -0500683 *flags = ACPI_UINT32_MAX;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700684 status = AE_OK;
685 }
686
Len Brown4be44fc2005-08-05 00:44:28 -0400687 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700688 }
689
690 /* Extract the status flags */
691
692 *flags = (u32) obj_desc->integer.value;
693
694 /* On exit, we must delete the return object */
695
Len Brown4be44fc2005-08-05 00:44:28 -0400696 acpi_ut_remove_reference(obj_desc);
697 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700698}
699
Linus Torvalds1da177e2005-04-16 15:20:36 -0700700/*******************************************************************************
701 *
702 * FUNCTION: acpi_ut_execute_Sxds
703 *
704 * PARAMETERS: device_node - Node for the device
Robert Moore44f6c012005-04-18 22:49:35 -0400705 * Flags - Where the status flags are returned
Linus Torvalds1da177e2005-04-16 15:20:36 -0700706 *
707 * RETURN: Status
708 *
709 * DESCRIPTION: Executes _STA for selected device and stores results in
710 * *Flags.
711 *
712 * NOTE: Internal function, no parameter validation
713 *
714 ******************************************************************************/
715
716acpi_status
Len Brown4be44fc2005-08-05 00:44:28 -0400717acpi_ut_execute_sxds(struct acpi_namespace_node *device_node, u8 * highest)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700718{
Len Brown4be44fc2005-08-05 00:44:28 -0400719 union acpi_operand_object *obj_desc;
720 acpi_status status;
721 u32 i;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700722
Bob Mooreb229cf92006-04-21 17:15:00 -0400723 ACPI_FUNCTION_TRACE(ut_execute_sxds);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700724
725 for (i = 0; i < 4; i++) {
726 highest[i] = 0xFF;
Len Brown4be44fc2005-08-05 00:44:28 -0400727 status = acpi_ut_evaluate_object(device_node,
Bob Mooredefba1d2005-12-16 17:05:00 -0500728 ACPI_CAST_PTR(char,
729 acpi_gbl_highest_dstate_names
730 [i]),
731 ACPI_BTYPE_INTEGER, &obj_desc);
Len Brown4be44fc2005-08-05 00:44:28 -0400732 if (ACPI_FAILURE(status)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700733 if (status != AE_NOT_FOUND) {
Len Brown4be44fc2005-08-05 00:44:28 -0400734 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
735 "%s on Device %4.4s, %s\n",
Bob Mooredefba1d2005-12-16 17:05:00 -0500736 ACPI_CAST_PTR(char,
737 acpi_gbl_highest_dstate_names
738 [i]),
Len Brown4be44fc2005-08-05 00:44:28 -0400739 acpi_ut_get_node_name
740 (device_node),
741 acpi_format_exception
742 (status)));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700743
Len Brown4be44fc2005-08-05 00:44:28 -0400744 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700745 }
Len Brown4be44fc2005-08-05 00:44:28 -0400746 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700747 /* Extract the Dstate value */
748
749 highest[i] = (u8) obj_desc->integer.value;
750
751 /* Delete the return object */
752
Len Brown4be44fc2005-08-05 00:44:28 -0400753 acpi_ut_remove_reference(obj_desc);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700754 }
755 }
756
Len Brown4be44fc2005-08-05 00:44:28 -0400757 return_ACPI_STATUS(AE_OK);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700758}