blob: 8ec6f8e481385d2908f286249903d44db35cf184 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/******************************************************************************
2 *
3 * Module Name: uteval - Object evaluation
4 *
5 *****************************************************************************/
6
7/*
Bob Moore6c9deb72007-02-02 19:48:24 +03008 * Copyright (C) 2000 - 2007, R. Byron Moore
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>
45#include <acpi/acnamesp.h>
46#include <acpi/acinterp.h>
47
Linus Torvalds1da177e2005-04-16 15:20:36 -070048#define _COMPONENT ACPI_UTILITIES
Len Brown4be44fc2005-08-05 00:44:28 -040049ACPI_MODULE_NAME("uteval")
Linus Torvalds1da177e2005-04-16 15:20:36 -070050
Robert Moore44f6c012005-04-18 22:49:35 -040051/* Local prototypes */
Robert Moore44f6c012005-04-18 22:49:35 -040052static void
Len Brown4be44fc2005-08-05 00:44:28 -040053acpi_ut_copy_id_string(char *destination, char *source, acpi_size max_length);
Robert Moore44f6c012005-04-18 22:49:35 -040054
55static acpi_status
Len Brown4be44fc2005-08-05 00:44:28 -040056acpi_ut_translate_one_cid(union acpi_operand_object *obj_desc,
57 struct acpi_compatible_id *one_cid);
Linus Torvalds1da177e2005-04-16 15:20:36 -070058
Bob Mooreb229cf92006-04-21 17:15:00 -040059/*
60 * Strings supported by the _OSI predefined (internal) method.
61 */
Len Brownae00d812007-05-29 18:43:33 -040062static char *acpi_interfaces_supported[] = {
Bob Mooreb229cf92006-04-21 17:15:00 -040063 /* Operating System Vendor Strings */
64
Bob Mooreb229cf92006-04-21 17:15:00 -040065 "Windows 2000",
66 "Windows 2001",
67 "Windows 2001 SP0",
68 "Windows 2001 SP1",
69 "Windows 2001 SP2",
70 "Windows 2001 SP3",
71 "Windows 2001 SP4",
72 "Windows 2001.1",
73 "Windows 2001.1 SP1", /* Added 03/2006 */
74 "Windows 2006", /* Added 03/2006 */
75
76 /* Feature Group Strings */
77
78 "Extended Address Space Descriptor"
79 /*
80 * All "optional" feature group strings (features that are implemented
81 * by the host) should be implemented in the host version of
82 * acpi_os_validate_interface and should not be added here.
83 */
84};
85
Linus Torvalds1da177e2005-04-16 15:20:36 -070086/*******************************************************************************
87 *
88 * FUNCTION: acpi_ut_osi_implementation
89 *
90 * PARAMETERS: walk_state - Current walk state
91 *
92 * RETURN: Status
93 *
Bob Mooreb229cf92006-04-21 17:15:00 -040094 * DESCRIPTION: Implementation of the _OSI predefined control method
Linus Torvalds1da177e2005-04-16 15:20:36 -070095 *
96 ******************************************************************************/
97
Len Brown4be44fc2005-08-05 00:44:28 -040098acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state)
Linus Torvalds1da177e2005-04-16 15:20:36 -070099{
Bob Mooreb229cf92006-04-21 17:15:00 -0400100 acpi_status status;
Len Brown4be44fc2005-08-05 00:44:28 -0400101 union acpi_operand_object *string_desc;
102 union acpi_operand_object *return_desc;
103 acpi_native_uint i;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700104
Bob Mooreb229cf92006-04-21 17:15:00 -0400105 ACPI_FUNCTION_TRACE(ut_osi_implementation);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700106
107 /* Validate the string input argument */
108
109 string_desc = walk_state->arguments[0].object;
110 if (!string_desc || (string_desc->common.type != ACPI_TYPE_STRING)) {
Len Brown4be44fc2005-08-05 00:44:28 -0400111 return_ACPI_STATUS(AE_TYPE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700112 }
113
Bob Mooreb229cf92006-04-21 17:15:00 -0400114 /* Create a return object */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700115
Len Brown4be44fc2005-08-05 00:44:28 -0400116 return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700117 if (!return_desc) {
Len Brown4be44fc2005-08-05 00:44:28 -0400118 return_ACPI_STATUS(AE_NO_MEMORY);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700119 }
120
Bob Mooreb229cf92006-04-21 17:15:00 -0400121 /* Default return value is SUPPORTED */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700122
Bob Mooreb229cf92006-04-21 17:15:00 -0400123 return_desc->integer.value = ACPI_UINT32_MAX;
124 walk_state->return_desc = return_desc;
Bob Moore52fc0b02006-10-02 00:00:00 -0400125
Bob Mooreb229cf92006-04-21 17:15:00 -0400126 /* Compare input string to static table of supported interfaces */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700127
Bob Mooreb229cf92006-04-21 17:15:00 -0400128 for (i = 0; i < ACPI_ARRAY_LENGTH(acpi_interfaces_supported); i++) {
129 if (!ACPI_STRCMP
130 (string_desc->string.pointer,
131 acpi_interfaces_supported[i])) {
132
133 /* The interface is supported */
134
135 return_ACPI_STATUS(AE_CTRL_TERMINATE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700136 }
137 }
138
Bob Mooreb229cf92006-04-21 17:15:00 -0400139 /*
140 * Did not match the string in the static table, call the host OSL to
141 * check for a match with one of the optional strings (such as
142 * "Module Device", "3.0 Thermal Model", etc.)
143 */
144 status = acpi_os_validate_interface(string_desc->string.pointer);
145 if (ACPI_SUCCESS(status)) {
146
147 /* The interface is supported */
148
149 return_ACPI_STATUS(AE_CTRL_TERMINATE);
150 }
151
152 /* The interface is not supported */
153
154 return_desc->integer.value = 0;
Len Brown4be44fc2005-08-05 00:44:28 -0400155 return_ACPI_STATUS(AE_CTRL_TERMINATE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700156}
157
Linus Torvalds1da177e2005-04-16 15:20:36 -0700158/*******************************************************************************
159 *
Len Brownae00d812007-05-29 18:43:33 -0400160 * FUNCTION: acpi_osi_invalidate
161 *
162 * PARAMETERS: interface_string
163 *
164 * RETURN: Status
165 *
166 * DESCRIPTION: invalidate string in pre-defiend _OSI string list
167 *
168 ******************************************************************************/
169
170acpi_status acpi_osi_invalidate(char *interface)
171{
172 int i;
173
174 for (i = 0; i < ACPI_ARRAY_LENGTH(acpi_interfaces_supported); i++) {
175 if (!ACPI_STRCMP(interface, acpi_interfaces_supported[i])) {
176 *acpi_interfaces_supported[i] = '\0';
177 return AE_OK;
178 }
179 }
180 return AE_NOT_FOUND;
181}
182
183/*******************************************************************************
184 *
Linus Torvalds1da177e2005-04-16 15:20:36 -0700185 * FUNCTION: acpi_ut_evaluate_object
186 *
187 * PARAMETERS: prefix_node - Starting node
188 * Path - Path to object from starting node
189 * expected_return_types - Bitmap of allowed return types
190 * return_desc - Where a return value is stored
191 *
192 * RETURN: Status
193 *
194 * DESCRIPTION: Evaluates a namespace object and verifies the type of the
195 * return object. Common code that simplifies accessing objects
196 * that have required return objects of fixed types.
197 *
198 * NOTE: Internal function, no parameter validation
199 *
200 ******************************************************************************/
201
202acpi_status
Len Brown4be44fc2005-08-05 00:44:28 -0400203acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node,
204 char *path,
205 u32 expected_return_btypes,
206 union acpi_operand_object **return_desc)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700207{
Bob Moore41195322006-05-26 16:36:00 -0400208 struct acpi_evaluate_info *info;
Len Brown4be44fc2005-08-05 00:44:28 -0400209 acpi_status status;
210 u32 return_btype;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700211
Bob Mooreb229cf92006-04-21 17:15:00 -0400212 ACPI_FUNCTION_TRACE(ut_evaluate_object);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700213
Bob Moore41195322006-05-26 16:36:00 -0400214 /* Allocate the evaluation information block */
215
216 info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
217 if (!info) {
218 return_ACPI_STATUS(AE_NO_MEMORY);
219 }
220
221 info->prefix_node = prefix_node;
222 info->pathname = path;
223 info->parameter_type = ACPI_PARAM_ARGS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700224
225 /* Evaluate the object/method */
226
Bob Moore41195322006-05-26 16:36:00 -0400227 status = acpi_ns_evaluate(info);
Len Brown4be44fc2005-08-05 00:44:28 -0400228 if (ACPI_FAILURE(status)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700229 if (status == AE_NOT_FOUND) {
Len Brown4be44fc2005-08-05 00:44:28 -0400230 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
231 "[%4.4s.%s] was not found\n",
232 acpi_ut_get_node_name(prefix_node),
233 path));
234 } else {
Bob Mooreb8e4d892006-01-27 16:43:00 -0500235 ACPI_ERROR_METHOD("Method execution failed",
236 prefix_node, path, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700237 }
238
Bob Moore41195322006-05-26 16:36:00 -0400239 goto cleanup;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700240 }
241
242 /* Did we get a return object? */
243
Bob Moore41195322006-05-26 16:36:00 -0400244 if (!info->return_object) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700245 if (expected_return_btypes) {
Bob Mooreb8e4d892006-01-27 16:43:00 -0500246 ACPI_ERROR_METHOD("No object was returned from",
247 prefix_node, path, AE_NOT_EXIST);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700248
Bob Moore41195322006-05-26 16:36:00 -0400249 status = AE_NOT_EXIST;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700250 }
251
Bob Moore41195322006-05-26 16:36:00 -0400252 goto cleanup;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700253 }
254
255 /* Map the return object type to the bitmapped type */
256
Bob Moore41195322006-05-26 16:36:00 -0400257 switch (ACPI_GET_OBJECT_TYPE(info->return_object)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700258 case ACPI_TYPE_INTEGER:
259 return_btype = ACPI_BTYPE_INTEGER;
260 break;
261
262 case ACPI_TYPE_BUFFER:
263 return_btype = ACPI_BTYPE_BUFFER;
264 break;
265
266 case ACPI_TYPE_STRING:
267 return_btype = ACPI_BTYPE_STRING;
268 break;
269
270 case ACPI_TYPE_PACKAGE:
271 return_btype = ACPI_BTYPE_PACKAGE;
272 break;
273
274 default:
275 return_btype = 0;
276 break;
277 }
278
Len Brown4be44fc2005-08-05 00:44:28 -0400279 if ((acpi_gbl_enable_interpreter_slack) && (!expected_return_btypes)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700280 /*
281 * We received a return object, but one was not expected. This can
282 * happen frequently if the "implicit return" feature is enabled.
283 * Just delete the return object and return AE_OK.
284 */
Bob Moore41195322006-05-26 16:36:00 -0400285 acpi_ut_remove_reference(info->return_object);
286 goto cleanup;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700287 }
288
289 /* Is the return object one of the expected types? */
290
291 if (!(expected_return_btypes & return_btype)) {
Bob Mooreb8e4d892006-01-27 16:43:00 -0500292 ACPI_ERROR_METHOD("Return object type is incorrect",
293 prefix_node, path, AE_TYPE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700294
Bob Mooreb8e4d892006-01-27 16:43:00 -0500295 ACPI_ERROR((AE_INFO,
296 "Type returned from %s was incorrect: %s, expected Btypes: %X",
297 path,
Bob Moore41195322006-05-26 16:36:00 -0400298 acpi_ut_get_object_type_name(info->return_object),
Bob Mooreb8e4d892006-01-27 16:43:00 -0500299 expected_return_btypes));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700300
301 /* On error exit, we must delete the return object */
302
Bob Moore41195322006-05-26 16:36:00 -0400303 acpi_ut_remove_reference(info->return_object);
304 status = AE_TYPE;
305 goto cleanup;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700306 }
307
308 /* Object type is OK, return it */
309
Bob Moore41195322006-05-26 16:36:00 -0400310 *return_desc = info->return_object;
311
312 cleanup:
313 ACPI_FREE(info);
314 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700315}
316
Linus Torvalds1da177e2005-04-16 15:20:36 -0700317/*******************************************************************************
318 *
319 * FUNCTION: acpi_ut_evaluate_numeric_object
320 *
Robert Moore44f6c012005-04-18 22:49:35 -0400321 * PARAMETERS: object_name - Object name to be evaluated
Linus Torvalds1da177e2005-04-16 15:20:36 -0700322 * device_node - Node for the device
Robert Moore44f6c012005-04-18 22:49:35 -0400323 * Address - Where the value is returned
Linus Torvalds1da177e2005-04-16 15:20:36 -0700324 *
325 * RETURN: Status
326 *
327 * DESCRIPTION: Evaluates a numeric namespace object for a selected device
328 * and stores result in *Address.
329 *
330 * NOTE: Internal function, no parameter validation
331 *
332 ******************************************************************************/
333
334acpi_status
Len Brown4be44fc2005-08-05 00:44:28 -0400335acpi_ut_evaluate_numeric_object(char *object_name,
336 struct acpi_namespace_node *device_node,
337 acpi_integer * address)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700338{
Len Brown4be44fc2005-08-05 00:44:28 -0400339 union acpi_operand_object *obj_desc;
340 acpi_status status;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700341
Bob Mooreb229cf92006-04-21 17:15:00 -0400342 ACPI_FUNCTION_TRACE(ut_evaluate_numeric_object);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700343
Len Brown4be44fc2005-08-05 00:44:28 -0400344 status = acpi_ut_evaluate_object(device_node, object_name,
345 ACPI_BTYPE_INTEGER, &obj_desc);
346 if (ACPI_FAILURE(status)) {
347 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700348 }
349
350 /* Get the returned Integer */
351
352 *address = obj_desc->integer.value;
353
354 /* On exit, we must delete the return object */
355
Len Brown4be44fc2005-08-05 00:44:28 -0400356 acpi_ut_remove_reference(obj_desc);
357 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700358}
359
Linus Torvalds1da177e2005-04-16 15:20:36 -0700360/*******************************************************************************
361 *
362 * FUNCTION: acpi_ut_copy_id_string
363 *
364 * PARAMETERS: Destination - Where to copy the string
365 * Source - Source string
366 * max_length - Length of the destination buffer
367 *
368 * RETURN: None
369 *
370 * DESCRIPTION: Copies an ID string for the _HID, _CID, and _UID methods.
371 * Performs removal of a leading asterisk if present -- workaround
372 * for a known issue on a bunch of machines.
373 *
374 ******************************************************************************/
375
376static void
Len Brown4be44fc2005-08-05 00:44:28 -0400377acpi_ut_copy_id_string(char *destination, char *source, acpi_size max_length)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700378{
379
Linus Torvalds1da177e2005-04-16 15:20:36 -0700380 /*
381 * Workaround for ID strings that have a leading asterisk. This construct
382 * is not allowed by the ACPI specification (ID strings must be
383 * alphanumeric), but enough existing machines have this embedded in their
384 * ID strings that the following code is useful.
385 */
386 if (*source == '*') {
387 source++;
388 }
389
390 /* Do the actual copy */
391
Len Brown4be44fc2005-08-05 00:44:28 -0400392 ACPI_STRNCPY(destination, source, max_length);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700393}
394
Linus Torvalds1da177e2005-04-16 15:20:36 -0700395/*******************************************************************************
396 *
397 * FUNCTION: acpi_ut_execute_HID
398 *
399 * PARAMETERS: device_node - Node for the device
Robert Moore44f6c012005-04-18 22:49:35 -0400400 * Hid - Where the HID is returned
Linus Torvalds1da177e2005-04-16 15:20:36 -0700401 *
402 * RETURN: Status
403 *
404 * DESCRIPTION: Executes the _HID control method that returns the hardware
405 * ID of the device.
406 *
407 * NOTE: Internal function, no parameter validation
408 *
409 ******************************************************************************/
410
411acpi_status
Len Brown4be44fc2005-08-05 00:44:28 -0400412acpi_ut_execute_HID(struct acpi_namespace_node *device_node,
413 struct acpi_device_id *hid)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700414{
Len Brown4be44fc2005-08-05 00:44:28 -0400415 union acpi_operand_object *obj_desc;
416 acpi_status status;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700417
Bob Mooreb229cf92006-04-21 17:15:00 -0400418 ACPI_FUNCTION_TRACE(ut_execute_HID);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700419
Len Brown4be44fc2005-08-05 00:44:28 -0400420 status = acpi_ut_evaluate_object(device_node, METHOD_NAME__HID,
421 ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING,
422 &obj_desc);
423 if (ACPI_FAILURE(status)) {
424 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700425 }
426
Len Brown4be44fc2005-08-05 00:44:28 -0400427 if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {
Bob Moore52fc0b02006-10-02 00:00:00 -0400428
Linus Torvalds1da177e2005-04-16 15:20:36 -0700429 /* Convert the Numeric HID to string */
430
Len Brown4be44fc2005-08-05 00:44:28 -0400431 acpi_ex_eisa_id_to_string((u32) obj_desc->integer.value,
432 hid->value);
433 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700434 /* Copy the String HID from the returned object */
435
Len Brown4be44fc2005-08-05 00:44:28 -0400436 acpi_ut_copy_id_string(hid->value, obj_desc->string.pointer,
437 sizeof(hid->value));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700438 }
439
440 /* On exit, we must delete the return object */
441
Len Brown4be44fc2005-08-05 00:44:28 -0400442 acpi_ut_remove_reference(obj_desc);
443 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700444}
445
Linus Torvalds1da177e2005-04-16 15:20:36 -0700446/*******************************************************************************
447 *
448 * FUNCTION: acpi_ut_translate_one_cid
449 *
450 * PARAMETERS: obj_desc - _CID object, must be integer or string
451 * one_cid - Where the CID string is returned
452 *
453 * RETURN: Status
454 *
455 * DESCRIPTION: Return a numeric or string _CID value as a string.
456 * (Compatible ID)
457 *
458 * NOTE: Assumes a maximum _CID string length of
459 * ACPI_MAX_CID_LENGTH.
460 *
461 ******************************************************************************/
462
463static acpi_status
Len Brown4be44fc2005-08-05 00:44:28 -0400464acpi_ut_translate_one_cid(union acpi_operand_object *obj_desc,
465 struct acpi_compatible_id *one_cid)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700466{
467
Len Brown4be44fc2005-08-05 00:44:28 -0400468 switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700469 case ACPI_TYPE_INTEGER:
470
471 /* Convert the Numeric CID to string */
472
Len Brown4be44fc2005-08-05 00:44:28 -0400473 acpi_ex_eisa_id_to_string((u32) obj_desc->integer.value,
474 one_cid->value);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700475 return (AE_OK);
476
477 case ACPI_TYPE_STRING:
478
479 if (obj_desc->string.length > ACPI_MAX_CID_LENGTH) {
480 return (AE_AML_STRING_LIMIT);
481 }
482
483 /* Copy the String CID from the returned object */
484
Len Brown4be44fc2005-08-05 00:44:28 -0400485 acpi_ut_copy_id_string(one_cid->value, obj_desc->string.pointer,
486 ACPI_MAX_CID_LENGTH);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700487 return (AE_OK);
488
489 default:
490
491 return (AE_TYPE);
492 }
493}
494
Linus Torvalds1da177e2005-04-16 15:20:36 -0700495/*******************************************************************************
496 *
497 * FUNCTION: acpi_ut_execute_CID
498 *
499 * PARAMETERS: device_node - Node for the device
Robert Moore44f6c012005-04-18 22:49:35 -0400500 * return_cid_list - Where the CID list is returned
Linus Torvalds1da177e2005-04-16 15:20:36 -0700501 *
502 * RETURN: Status
503 *
504 * DESCRIPTION: Executes the _CID control method that returns one or more
505 * compatible hardware IDs for the device.
506 *
507 * NOTE: Internal function, no parameter validation
508 *
509 ******************************************************************************/
510
511acpi_status
Len Brown4be44fc2005-08-05 00:44:28 -0400512acpi_ut_execute_CID(struct acpi_namespace_node * device_node,
513 struct acpi_compatible_id_list ** return_cid_list)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700514{
Len Brown4be44fc2005-08-05 00:44:28 -0400515 union acpi_operand_object *obj_desc;
516 acpi_status status;
517 u32 count;
518 u32 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700519 struct acpi_compatible_id_list *cid_list;
Len Brown4be44fc2005-08-05 00:44:28 -0400520 acpi_native_uint i;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700521
Bob Mooreb229cf92006-04-21 17:15:00 -0400522 ACPI_FUNCTION_TRACE(ut_execute_CID);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700523
524 /* Evaluate the _CID method for this device */
525
Len Brown4be44fc2005-08-05 00:44:28 -0400526 status = acpi_ut_evaluate_object(device_node, METHOD_NAME__CID,
527 ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING
528 | ACPI_BTYPE_PACKAGE, &obj_desc);
529 if (ACPI_FAILURE(status)) {
530 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700531 }
532
533 /* Get the number of _CIDs returned */
534
535 count = 1;
Len Brown4be44fc2005-08-05 00:44:28 -0400536 if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_PACKAGE) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700537 count = obj_desc->package.count;
538 }
539
540 /* Allocate a worst-case buffer for the _CIDs */
541
Len Brown4be44fc2005-08-05 00:44:28 -0400542 size = (((count - 1) * sizeof(struct acpi_compatible_id)) +
543 sizeof(struct acpi_compatible_id_list));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700544
Bob Moore83135242006-10-03 00:00:00 -0400545 cid_list = ACPI_ALLOCATE_ZEROED((acpi_size) size);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700546 if (!cid_list) {
Len Brown4be44fc2005-08-05 00:44:28 -0400547 return_ACPI_STATUS(AE_NO_MEMORY);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700548 }
549
550 /* Init CID list */
551
552 cid_list->count = count;
553 cid_list->size = size;
554
555 /*
Robert Moore44f6c012005-04-18 22:49:35 -0400556 * A _CID can return either a single compatible ID or a package of
557 * compatible IDs. Each compatible ID can be one of the following:
558 * 1) Integer (32 bit compressed EISA ID) or
559 * 2) String (PCI ID format, e.g. "PCI\VEN_vvvv&DEV_dddd&SUBSYS_ssssssss")
Linus Torvalds1da177e2005-04-16 15:20:36 -0700560 */
561
562 /* The _CID object can be either a single CID or a package (list) of CIDs */
563
Len Brown4be44fc2005-08-05 00:44:28 -0400564 if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_PACKAGE) {
Bob Moore52fc0b02006-10-02 00:00:00 -0400565
Linus Torvalds1da177e2005-04-16 15:20:36 -0700566 /* Translate each package element */
567
568 for (i = 0; i < count; i++) {
Len Brown4be44fc2005-08-05 00:44:28 -0400569 status =
570 acpi_ut_translate_one_cid(obj_desc->package.
571 elements[i],
572 &cid_list->id[i]);
573 if (ACPI_FAILURE(status)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700574 break;
575 }
576 }
Len Brown4be44fc2005-08-05 00:44:28 -0400577 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700578 /* Only one CID, translate to a string */
579
Len Brown4be44fc2005-08-05 00:44:28 -0400580 status = acpi_ut_translate_one_cid(obj_desc, cid_list->id);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700581 }
582
583 /* Cleanup on error */
584
Len Brown4be44fc2005-08-05 00:44:28 -0400585 if (ACPI_FAILURE(status)) {
Bob Moore83135242006-10-03 00:00:00 -0400586 ACPI_FREE(cid_list);
Len Brown4be44fc2005-08-05 00:44:28 -0400587 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700588 *return_cid_list = cid_list;
589 }
590
591 /* On exit, we must delete the _CID return object */
592
Len Brown4be44fc2005-08-05 00:44:28 -0400593 acpi_ut_remove_reference(obj_desc);
594 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700595}
596
Linus Torvalds1da177e2005-04-16 15:20:36 -0700597/*******************************************************************************
598 *
599 * FUNCTION: acpi_ut_execute_UID
600 *
601 * PARAMETERS: device_node - Node for the device
Robert Moore44f6c012005-04-18 22:49:35 -0400602 * Uid - Where the UID is returned
Linus Torvalds1da177e2005-04-16 15:20:36 -0700603 *
604 * RETURN: Status
605 *
606 * DESCRIPTION: Executes the _UID control method that returns the hardware
607 * ID of the device.
608 *
609 * NOTE: Internal function, no parameter validation
610 *
611 ******************************************************************************/
612
613acpi_status
Len Brown4be44fc2005-08-05 00:44:28 -0400614acpi_ut_execute_UID(struct acpi_namespace_node *device_node,
615 struct acpi_device_id *uid)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700616{
Len Brown4be44fc2005-08-05 00:44:28 -0400617 union acpi_operand_object *obj_desc;
618 acpi_status status;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700619
Bob Mooreb229cf92006-04-21 17:15:00 -0400620 ACPI_FUNCTION_TRACE(ut_execute_UID);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700621
Len Brown4be44fc2005-08-05 00:44:28 -0400622 status = acpi_ut_evaluate_object(device_node, METHOD_NAME__UID,
623 ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING,
624 &obj_desc);
625 if (ACPI_FAILURE(status)) {
626 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700627 }
628
Len Brown4be44fc2005-08-05 00:44:28 -0400629 if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {
Bob Moore52fc0b02006-10-02 00:00:00 -0400630
Linus Torvalds1da177e2005-04-16 15:20:36 -0700631 /* Convert the Numeric UID to string */
632
Len Brown4be44fc2005-08-05 00:44:28 -0400633 acpi_ex_unsigned_integer_to_string(obj_desc->integer.value,
634 uid->value);
635 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700636 /* Copy the String UID from the returned object */
637
Len Brown4be44fc2005-08-05 00:44:28 -0400638 acpi_ut_copy_id_string(uid->value, obj_desc->string.pointer,
639 sizeof(uid->value));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700640 }
641
642 /* On exit, we must delete the return object */
643
Len Brown4be44fc2005-08-05 00:44:28 -0400644 acpi_ut_remove_reference(obj_desc);
645 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700646}
647
Linus Torvalds1da177e2005-04-16 15:20:36 -0700648/*******************************************************************************
649 *
650 * FUNCTION: acpi_ut_execute_STA
651 *
652 * PARAMETERS: device_node - Node for the device
Robert Moore44f6c012005-04-18 22:49:35 -0400653 * Flags - Where the status flags are returned
Linus Torvalds1da177e2005-04-16 15:20:36 -0700654 *
655 * RETURN: Status
656 *
657 * DESCRIPTION: Executes _STA for selected device and stores results in
658 * *Flags.
659 *
660 * NOTE: Internal function, no parameter validation
661 *
662 ******************************************************************************/
663
664acpi_status
Len Brown4be44fc2005-08-05 00:44:28 -0400665acpi_ut_execute_STA(struct acpi_namespace_node *device_node, u32 * flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700666{
Len Brown4be44fc2005-08-05 00:44:28 -0400667 union acpi_operand_object *obj_desc;
668 acpi_status status;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700669
Bob Mooreb229cf92006-04-21 17:15:00 -0400670 ACPI_FUNCTION_TRACE(ut_execute_STA);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700671
Len Brown4be44fc2005-08-05 00:44:28 -0400672 status = acpi_ut_evaluate_object(device_node, METHOD_NAME__STA,
673 ACPI_BTYPE_INTEGER, &obj_desc);
674 if (ACPI_FAILURE(status)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700675 if (AE_NOT_FOUND == status) {
Len Brown4be44fc2005-08-05 00:44:28 -0400676 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
677 "_STA on %4.4s was not found, assuming device is present\n",
678 acpi_ut_get_node_name(device_node)));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700679
Bob Mooredefba1d2005-12-16 17:05:00 -0500680 *flags = ACPI_UINT32_MAX;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700681 status = AE_OK;
682 }
683
Len Brown4be44fc2005-08-05 00:44:28 -0400684 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700685 }
686
687 /* Extract the status flags */
688
689 *flags = (u32) obj_desc->integer.value;
690
691 /* On exit, we must delete the return object */
692
Len Brown4be44fc2005-08-05 00:44:28 -0400693 acpi_ut_remove_reference(obj_desc);
694 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700695}
696
Linus Torvalds1da177e2005-04-16 15:20:36 -0700697/*******************************************************************************
698 *
699 * FUNCTION: acpi_ut_execute_Sxds
700 *
701 * PARAMETERS: device_node - Node for the device
Robert Moore44f6c012005-04-18 22:49:35 -0400702 * Flags - Where the status flags are returned
Linus Torvalds1da177e2005-04-16 15:20:36 -0700703 *
704 * RETURN: Status
705 *
706 * DESCRIPTION: Executes _STA for selected device and stores results in
707 * *Flags.
708 *
709 * NOTE: Internal function, no parameter validation
710 *
711 ******************************************************************************/
712
713acpi_status
Len Brown4be44fc2005-08-05 00:44:28 -0400714acpi_ut_execute_sxds(struct acpi_namespace_node *device_node, u8 * highest)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700715{
Len Brown4be44fc2005-08-05 00:44:28 -0400716 union acpi_operand_object *obj_desc;
717 acpi_status status;
718 u32 i;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700719
Bob Mooreb229cf92006-04-21 17:15:00 -0400720 ACPI_FUNCTION_TRACE(ut_execute_sxds);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700721
722 for (i = 0; i < 4; i++) {
723 highest[i] = 0xFF;
Len Brown4be44fc2005-08-05 00:44:28 -0400724 status = acpi_ut_evaluate_object(device_node,
Bob Mooredefba1d2005-12-16 17:05:00 -0500725 ACPI_CAST_PTR(char,
726 acpi_gbl_highest_dstate_names
727 [i]),
728 ACPI_BTYPE_INTEGER, &obj_desc);
Len Brown4be44fc2005-08-05 00:44:28 -0400729 if (ACPI_FAILURE(status)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700730 if (status != AE_NOT_FOUND) {
Len Brown4be44fc2005-08-05 00:44:28 -0400731 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
732 "%s on Device %4.4s, %s\n",
Bob Mooredefba1d2005-12-16 17:05:00 -0500733 ACPI_CAST_PTR(char,
734 acpi_gbl_highest_dstate_names
735 [i]),
Len Brown4be44fc2005-08-05 00:44:28 -0400736 acpi_ut_get_node_name
737 (device_node),
738 acpi_format_exception
739 (status)));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700740
Len Brown4be44fc2005-08-05 00:44:28 -0400741 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700742 }
Len Brown4be44fc2005-08-05 00:44:28 -0400743 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700744 /* Extract the Dstate value */
745
746 highest[i] = (u8) obj_desc->integer.value;
747
748 /* Delete the return object */
749
Len Brown4be44fc2005-08-05 00:44:28 -0400750 acpi_ut_remove_reference(obj_desc);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700751 }
752 }
753
Len Brown4be44fc2005-08-05 00:44:28 -0400754 return_ACPI_STATUS(AE_OK);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700755}