blob: a10120ad698223976185f2cb1ee135021fdbbb7d [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
65 "Linux",
66 "Windows 2000",
67 "Windows 2001",
68 "Windows 2001 SP0",
69 "Windows 2001 SP1",
70 "Windows 2001 SP2",
71 "Windows 2001 SP3",
72 "Windows 2001 SP4",
73 "Windows 2001.1",
74 "Windows 2001.1 SP1", /* Added 03/2006 */
75 "Windows 2006", /* Added 03/2006 */
76
77 /* Feature Group Strings */
78
79 "Extended Address Space Descriptor"
80 /*
81 * All "optional" feature group strings (features that are implemented
82 * by the host) should be implemented in the host version of
83 * acpi_os_validate_interface and should not be added here.
84 */
85};
86
Linus Torvalds1da177e2005-04-16 15:20:36 -070087/*******************************************************************************
88 *
89 * FUNCTION: acpi_ut_osi_implementation
90 *
91 * PARAMETERS: walk_state - Current walk state
92 *
93 * RETURN: Status
94 *
Bob Mooreb229cf92006-04-21 17:15:00 -040095 * DESCRIPTION: Implementation of the _OSI predefined control method
Linus Torvalds1da177e2005-04-16 15:20:36 -070096 *
97 ******************************************************************************/
98
Len Brown4be44fc2005-08-05 00:44:28 -040099acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700100{
Bob Mooreb229cf92006-04-21 17:15:00 -0400101 acpi_status status;
Len Brown4be44fc2005-08-05 00:44:28 -0400102 union acpi_operand_object *string_desc;
103 union acpi_operand_object *return_desc;
104 acpi_native_uint i;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700105
Bob Mooreb229cf92006-04-21 17:15:00 -0400106 ACPI_FUNCTION_TRACE(ut_osi_implementation);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700107
108 /* Validate the string input argument */
109
110 string_desc = walk_state->arguments[0].object;
111 if (!string_desc || (string_desc->common.type != ACPI_TYPE_STRING)) {
Len Brown4be44fc2005-08-05 00:44:28 -0400112 return_ACPI_STATUS(AE_TYPE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700113 }
114
Bob Mooreb229cf92006-04-21 17:15:00 -0400115 /* Create a return object */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700116
Len Brown4be44fc2005-08-05 00:44:28 -0400117 return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700118 if (!return_desc) {
Len Brown4be44fc2005-08-05 00:44:28 -0400119 return_ACPI_STATUS(AE_NO_MEMORY);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700120 }
121
Bob Mooreb229cf92006-04-21 17:15:00 -0400122 /* Default return value is SUPPORTED */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700123
Bob Mooreb229cf92006-04-21 17:15:00 -0400124 return_desc->integer.value = ACPI_UINT32_MAX;
125 walk_state->return_desc = return_desc;
Bob Moore52fc0b02006-10-02 00:00:00 -0400126
Bob Mooreb229cf92006-04-21 17:15:00 -0400127 /* Compare input string to static table of supported interfaces */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700128
Bob Mooreb229cf92006-04-21 17:15:00 -0400129 for (i = 0; i < ACPI_ARRAY_LENGTH(acpi_interfaces_supported); i++) {
130 if (!ACPI_STRCMP
131 (string_desc->string.pointer,
132 acpi_interfaces_supported[i])) {
133
134 /* The interface is supported */
135
136 return_ACPI_STATUS(AE_CTRL_TERMINATE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700137 }
138 }
139
Bob Mooreb229cf92006-04-21 17:15:00 -0400140 /*
141 * Did not match the string in the static table, call the host OSL to
142 * check for a match with one of the optional strings (such as
143 * "Module Device", "3.0 Thermal Model", etc.)
144 */
145 status = acpi_os_validate_interface(string_desc->string.pointer);
146 if (ACPI_SUCCESS(status)) {
147
148 /* The interface is supported */
149
150 return_ACPI_STATUS(AE_CTRL_TERMINATE);
151 }
152
153 /* The interface is not supported */
154
155 return_desc->integer.value = 0;
Len Brown4be44fc2005-08-05 00:44:28 -0400156 return_ACPI_STATUS(AE_CTRL_TERMINATE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700157}
158
Linus Torvalds1da177e2005-04-16 15:20:36 -0700159/*******************************************************************************
160 *
Len Brownae00d812007-05-29 18:43:33 -0400161 * FUNCTION: acpi_osi_invalidate
162 *
163 * PARAMETERS: interface_string
164 *
165 * RETURN: Status
166 *
167 * DESCRIPTION: invalidate string in pre-defiend _OSI string list
168 *
169 ******************************************************************************/
170
171acpi_status acpi_osi_invalidate(char *interface)
172{
173 int i;
174
175 for (i = 0; i < ACPI_ARRAY_LENGTH(acpi_interfaces_supported); i++) {
176 if (!ACPI_STRCMP(interface, acpi_interfaces_supported[i])) {
177 *acpi_interfaces_supported[i] = '\0';
178 return AE_OK;
179 }
180 }
181 return AE_NOT_FOUND;
182}
183
184/*******************************************************************************
185 *
Linus Torvalds1da177e2005-04-16 15:20:36 -0700186 * FUNCTION: acpi_ut_evaluate_object
187 *
188 * PARAMETERS: prefix_node - Starting node
189 * Path - Path to object from starting node
190 * expected_return_types - Bitmap of allowed return types
191 * return_desc - Where a return value is stored
192 *
193 * RETURN: Status
194 *
195 * DESCRIPTION: Evaluates a namespace object and verifies the type of the
196 * return object. Common code that simplifies accessing objects
197 * that have required return objects of fixed types.
198 *
199 * NOTE: Internal function, no parameter validation
200 *
201 ******************************************************************************/
202
203acpi_status
Len Brown4be44fc2005-08-05 00:44:28 -0400204acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node,
205 char *path,
206 u32 expected_return_btypes,
207 union acpi_operand_object **return_desc)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700208{
Bob Moore41195322006-05-26 16:36:00 -0400209 struct acpi_evaluate_info *info;
Len Brown4be44fc2005-08-05 00:44:28 -0400210 acpi_status status;
211 u32 return_btype;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700212
Bob Mooreb229cf92006-04-21 17:15:00 -0400213 ACPI_FUNCTION_TRACE(ut_evaluate_object);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700214
Bob Moore41195322006-05-26 16:36:00 -0400215 /* Allocate the evaluation information block */
216
217 info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
218 if (!info) {
219 return_ACPI_STATUS(AE_NO_MEMORY);
220 }
221
222 info->prefix_node = prefix_node;
223 info->pathname = path;
224 info->parameter_type = ACPI_PARAM_ARGS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700225
226 /* Evaluate the object/method */
227
Bob Moore41195322006-05-26 16:36:00 -0400228 status = acpi_ns_evaluate(info);
Len Brown4be44fc2005-08-05 00:44:28 -0400229 if (ACPI_FAILURE(status)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700230 if (status == AE_NOT_FOUND) {
Len Brown4be44fc2005-08-05 00:44:28 -0400231 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
232 "[%4.4s.%s] was not found\n",
233 acpi_ut_get_node_name(prefix_node),
234 path));
235 } else {
Bob Mooreb8e4d892006-01-27 16:43:00 -0500236 ACPI_ERROR_METHOD("Method execution failed",
237 prefix_node, path, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700238 }
239
Bob Moore41195322006-05-26 16:36:00 -0400240 goto cleanup;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700241 }
242
243 /* Did we get a return object? */
244
Bob Moore41195322006-05-26 16:36:00 -0400245 if (!info->return_object) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700246 if (expected_return_btypes) {
Bob Mooreb8e4d892006-01-27 16:43:00 -0500247 ACPI_ERROR_METHOD("No object was returned from",
248 prefix_node, path, AE_NOT_EXIST);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700249
Bob Moore41195322006-05-26 16:36:00 -0400250 status = AE_NOT_EXIST;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700251 }
252
Bob Moore41195322006-05-26 16:36:00 -0400253 goto cleanup;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700254 }
255
256 /* Map the return object type to the bitmapped type */
257
Bob Moore41195322006-05-26 16:36:00 -0400258 switch (ACPI_GET_OBJECT_TYPE(info->return_object)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700259 case ACPI_TYPE_INTEGER:
260 return_btype = ACPI_BTYPE_INTEGER;
261 break;
262
263 case ACPI_TYPE_BUFFER:
264 return_btype = ACPI_BTYPE_BUFFER;
265 break;
266
267 case ACPI_TYPE_STRING:
268 return_btype = ACPI_BTYPE_STRING;
269 break;
270
271 case ACPI_TYPE_PACKAGE:
272 return_btype = ACPI_BTYPE_PACKAGE;
273 break;
274
275 default:
276 return_btype = 0;
277 break;
278 }
279
Len Brown4be44fc2005-08-05 00:44:28 -0400280 if ((acpi_gbl_enable_interpreter_slack) && (!expected_return_btypes)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700281 /*
282 * We received a return object, but one was not expected. This can
283 * happen frequently if the "implicit return" feature is enabled.
284 * Just delete the return object and return AE_OK.
285 */
Bob Moore41195322006-05-26 16:36:00 -0400286 acpi_ut_remove_reference(info->return_object);
287 goto cleanup;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700288 }
289
290 /* Is the return object one of the expected types? */
291
292 if (!(expected_return_btypes & return_btype)) {
Bob Mooreb8e4d892006-01-27 16:43:00 -0500293 ACPI_ERROR_METHOD("Return object type is incorrect",
294 prefix_node, path, AE_TYPE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700295
Bob Mooreb8e4d892006-01-27 16:43:00 -0500296 ACPI_ERROR((AE_INFO,
297 "Type returned from %s was incorrect: %s, expected Btypes: %X",
298 path,
Bob Moore41195322006-05-26 16:36:00 -0400299 acpi_ut_get_object_type_name(info->return_object),
Bob Mooreb8e4d892006-01-27 16:43:00 -0500300 expected_return_btypes));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700301
302 /* On error exit, we must delete the return object */
303
Bob Moore41195322006-05-26 16:36:00 -0400304 acpi_ut_remove_reference(info->return_object);
305 status = AE_TYPE;
306 goto cleanup;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700307 }
308
309 /* Object type is OK, return it */
310
Bob Moore41195322006-05-26 16:36:00 -0400311 *return_desc = info->return_object;
312
313 cleanup:
314 ACPI_FREE(info);
315 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700316}
317
Linus Torvalds1da177e2005-04-16 15:20:36 -0700318/*******************************************************************************
319 *
320 * FUNCTION: acpi_ut_evaluate_numeric_object
321 *
Robert Moore44f6c012005-04-18 22:49:35 -0400322 * PARAMETERS: object_name - Object name to be evaluated
Linus Torvalds1da177e2005-04-16 15:20:36 -0700323 * device_node - Node for the device
Robert Moore44f6c012005-04-18 22:49:35 -0400324 * Address - Where the value is returned
Linus Torvalds1da177e2005-04-16 15:20:36 -0700325 *
326 * RETURN: Status
327 *
328 * DESCRIPTION: Evaluates a numeric namespace object for a selected device
329 * and stores result in *Address.
330 *
331 * NOTE: Internal function, no parameter validation
332 *
333 ******************************************************************************/
334
335acpi_status
Len Brown4be44fc2005-08-05 00:44:28 -0400336acpi_ut_evaluate_numeric_object(char *object_name,
337 struct acpi_namespace_node *device_node,
338 acpi_integer * address)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700339{
Len Brown4be44fc2005-08-05 00:44:28 -0400340 union acpi_operand_object *obj_desc;
341 acpi_status status;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700342
Bob Mooreb229cf92006-04-21 17:15:00 -0400343 ACPI_FUNCTION_TRACE(ut_evaluate_numeric_object);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700344
Len Brown4be44fc2005-08-05 00:44:28 -0400345 status = acpi_ut_evaluate_object(device_node, object_name,
346 ACPI_BTYPE_INTEGER, &obj_desc);
347 if (ACPI_FAILURE(status)) {
348 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700349 }
350
351 /* Get the returned Integer */
352
353 *address = obj_desc->integer.value;
354
355 /* On exit, we must delete the return object */
356
Len Brown4be44fc2005-08-05 00:44:28 -0400357 acpi_ut_remove_reference(obj_desc);
358 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700359}
360
Linus Torvalds1da177e2005-04-16 15:20:36 -0700361/*******************************************************************************
362 *
363 * FUNCTION: acpi_ut_copy_id_string
364 *
365 * PARAMETERS: Destination - Where to copy the string
366 * Source - Source string
367 * max_length - Length of the destination buffer
368 *
369 * RETURN: None
370 *
371 * DESCRIPTION: Copies an ID string for the _HID, _CID, and _UID methods.
372 * Performs removal of a leading asterisk if present -- workaround
373 * for a known issue on a bunch of machines.
374 *
375 ******************************************************************************/
376
377static void
Len Brown4be44fc2005-08-05 00:44:28 -0400378acpi_ut_copy_id_string(char *destination, char *source, acpi_size max_length)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700379{
380
Linus Torvalds1da177e2005-04-16 15:20:36 -0700381 /*
382 * Workaround for ID strings that have a leading asterisk. This construct
383 * is not allowed by the ACPI specification (ID strings must be
384 * alphanumeric), but enough existing machines have this embedded in their
385 * ID strings that the following code is useful.
386 */
387 if (*source == '*') {
388 source++;
389 }
390
391 /* Do the actual copy */
392
Len Brown4be44fc2005-08-05 00:44:28 -0400393 ACPI_STRNCPY(destination, source, max_length);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700394}
395
Linus Torvalds1da177e2005-04-16 15:20:36 -0700396/*******************************************************************************
397 *
398 * FUNCTION: acpi_ut_execute_HID
399 *
400 * PARAMETERS: device_node - Node for the device
Robert Moore44f6c012005-04-18 22:49:35 -0400401 * Hid - Where the HID is returned
Linus Torvalds1da177e2005-04-16 15:20:36 -0700402 *
403 * RETURN: Status
404 *
405 * DESCRIPTION: Executes the _HID control method that returns the hardware
406 * ID of the device.
407 *
408 * NOTE: Internal function, no parameter validation
409 *
410 ******************************************************************************/
411
412acpi_status
Len Brown4be44fc2005-08-05 00:44:28 -0400413acpi_ut_execute_HID(struct acpi_namespace_node *device_node,
414 struct acpi_device_id *hid)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700415{
Len Brown4be44fc2005-08-05 00:44:28 -0400416 union acpi_operand_object *obj_desc;
417 acpi_status status;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700418
Bob Mooreb229cf92006-04-21 17:15:00 -0400419 ACPI_FUNCTION_TRACE(ut_execute_HID);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700420
Len Brown4be44fc2005-08-05 00:44:28 -0400421 status = acpi_ut_evaluate_object(device_node, METHOD_NAME__HID,
422 ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING,
423 &obj_desc);
424 if (ACPI_FAILURE(status)) {
425 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700426 }
427
Len Brown4be44fc2005-08-05 00:44:28 -0400428 if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {
Bob Moore52fc0b02006-10-02 00:00:00 -0400429
Linus Torvalds1da177e2005-04-16 15:20:36 -0700430 /* Convert the Numeric HID to string */
431
Len Brown4be44fc2005-08-05 00:44:28 -0400432 acpi_ex_eisa_id_to_string((u32) obj_desc->integer.value,
433 hid->value);
434 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700435 /* Copy the String HID from the returned object */
436
Len Brown4be44fc2005-08-05 00:44:28 -0400437 acpi_ut_copy_id_string(hid->value, obj_desc->string.pointer,
438 sizeof(hid->value));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700439 }
440
441 /* On exit, we must delete the return object */
442
Len Brown4be44fc2005-08-05 00:44:28 -0400443 acpi_ut_remove_reference(obj_desc);
444 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700445}
446
Linus Torvalds1da177e2005-04-16 15:20:36 -0700447/*******************************************************************************
448 *
449 * FUNCTION: acpi_ut_translate_one_cid
450 *
451 * PARAMETERS: obj_desc - _CID object, must be integer or string
452 * one_cid - Where the CID string is returned
453 *
454 * RETURN: Status
455 *
456 * DESCRIPTION: Return a numeric or string _CID value as a string.
457 * (Compatible ID)
458 *
459 * NOTE: Assumes a maximum _CID string length of
460 * ACPI_MAX_CID_LENGTH.
461 *
462 ******************************************************************************/
463
464static acpi_status
Len Brown4be44fc2005-08-05 00:44:28 -0400465acpi_ut_translate_one_cid(union acpi_operand_object *obj_desc,
466 struct acpi_compatible_id *one_cid)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700467{
468
Len Brown4be44fc2005-08-05 00:44:28 -0400469 switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700470 case ACPI_TYPE_INTEGER:
471
472 /* Convert the Numeric CID to string */
473
Len Brown4be44fc2005-08-05 00:44:28 -0400474 acpi_ex_eisa_id_to_string((u32) obj_desc->integer.value,
475 one_cid->value);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700476 return (AE_OK);
477
478 case ACPI_TYPE_STRING:
479
480 if (obj_desc->string.length > ACPI_MAX_CID_LENGTH) {
481 return (AE_AML_STRING_LIMIT);
482 }
483
484 /* Copy the String CID from the returned object */
485
Len Brown4be44fc2005-08-05 00:44:28 -0400486 acpi_ut_copy_id_string(one_cid->value, obj_desc->string.pointer,
487 ACPI_MAX_CID_LENGTH);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700488 return (AE_OK);
489
490 default:
491
492 return (AE_TYPE);
493 }
494}
495
Linus Torvalds1da177e2005-04-16 15:20:36 -0700496/*******************************************************************************
497 *
498 * FUNCTION: acpi_ut_execute_CID
499 *
500 * PARAMETERS: device_node - Node for the device
Robert Moore44f6c012005-04-18 22:49:35 -0400501 * return_cid_list - Where the CID list is returned
Linus Torvalds1da177e2005-04-16 15:20:36 -0700502 *
503 * RETURN: Status
504 *
505 * DESCRIPTION: Executes the _CID control method that returns one or more
506 * compatible hardware IDs for the device.
507 *
508 * NOTE: Internal function, no parameter validation
509 *
510 ******************************************************************************/
511
512acpi_status
Len Brown4be44fc2005-08-05 00:44:28 -0400513acpi_ut_execute_CID(struct acpi_namespace_node * device_node,
514 struct acpi_compatible_id_list ** return_cid_list)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700515{
Len Brown4be44fc2005-08-05 00:44:28 -0400516 union acpi_operand_object *obj_desc;
517 acpi_status status;
518 u32 count;
519 u32 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700520 struct acpi_compatible_id_list *cid_list;
Len Brown4be44fc2005-08-05 00:44:28 -0400521 acpi_native_uint i;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700522
Bob Mooreb229cf92006-04-21 17:15:00 -0400523 ACPI_FUNCTION_TRACE(ut_execute_CID);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700524
525 /* Evaluate the _CID method for this device */
526
Len Brown4be44fc2005-08-05 00:44:28 -0400527 status = acpi_ut_evaluate_object(device_node, METHOD_NAME__CID,
528 ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING
529 | ACPI_BTYPE_PACKAGE, &obj_desc);
530 if (ACPI_FAILURE(status)) {
531 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700532 }
533
534 /* Get the number of _CIDs returned */
535
536 count = 1;
Len Brown4be44fc2005-08-05 00:44:28 -0400537 if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_PACKAGE) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700538 count = obj_desc->package.count;
539 }
540
541 /* Allocate a worst-case buffer for the _CIDs */
542
Len Brown4be44fc2005-08-05 00:44:28 -0400543 size = (((count - 1) * sizeof(struct acpi_compatible_id)) +
544 sizeof(struct acpi_compatible_id_list));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700545
Bob Moore83135242006-10-03 00:00:00 -0400546 cid_list = ACPI_ALLOCATE_ZEROED((acpi_size) size);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700547 if (!cid_list) {
Len Brown4be44fc2005-08-05 00:44:28 -0400548 return_ACPI_STATUS(AE_NO_MEMORY);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700549 }
550
551 /* Init CID list */
552
553 cid_list->count = count;
554 cid_list->size = size;
555
556 /*
Robert Moore44f6c012005-04-18 22:49:35 -0400557 * A _CID can return either a single compatible ID or a package of
558 * compatible IDs. Each compatible ID can be one of the following:
559 * 1) Integer (32 bit compressed EISA ID) or
560 * 2) String (PCI ID format, e.g. "PCI\VEN_vvvv&DEV_dddd&SUBSYS_ssssssss")
Linus Torvalds1da177e2005-04-16 15:20:36 -0700561 */
562
563 /* The _CID object can be either a single CID or a package (list) of CIDs */
564
Len Brown4be44fc2005-08-05 00:44:28 -0400565 if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_PACKAGE) {
Bob Moore52fc0b02006-10-02 00:00:00 -0400566
Linus Torvalds1da177e2005-04-16 15:20:36 -0700567 /* Translate each package element */
568
569 for (i = 0; i < count; i++) {
Len Brown4be44fc2005-08-05 00:44:28 -0400570 status =
571 acpi_ut_translate_one_cid(obj_desc->package.
572 elements[i],
573 &cid_list->id[i]);
574 if (ACPI_FAILURE(status)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700575 break;
576 }
577 }
Len Brown4be44fc2005-08-05 00:44:28 -0400578 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700579 /* Only one CID, translate to a string */
580
Len Brown4be44fc2005-08-05 00:44:28 -0400581 status = acpi_ut_translate_one_cid(obj_desc, cid_list->id);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700582 }
583
584 /* Cleanup on error */
585
Len Brown4be44fc2005-08-05 00:44:28 -0400586 if (ACPI_FAILURE(status)) {
Bob Moore83135242006-10-03 00:00:00 -0400587 ACPI_FREE(cid_list);
Len Brown4be44fc2005-08-05 00:44:28 -0400588 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700589 *return_cid_list = cid_list;
590 }
591
592 /* On exit, we must delete the _CID return object */
593
Len Brown4be44fc2005-08-05 00:44:28 -0400594 acpi_ut_remove_reference(obj_desc);
595 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700596}
597
Linus Torvalds1da177e2005-04-16 15:20:36 -0700598/*******************************************************************************
599 *
600 * FUNCTION: acpi_ut_execute_UID
601 *
602 * PARAMETERS: device_node - Node for the device
Robert Moore44f6c012005-04-18 22:49:35 -0400603 * Uid - Where the UID is returned
Linus Torvalds1da177e2005-04-16 15:20:36 -0700604 *
605 * RETURN: Status
606 *
607 * DESCRIPTION: Executes the _UID control method that returns the hardware
608 * ID of the device.
609 *
610 * NOTE: Internal function, no parameter validation
611 *
612 ******************************************************************************/
613
614acpi_status
Len Brown4be44fc2005-08-05 00:44:28 -0400615acpi_ut_execute_UID(struct acpi_namespace_node *device_node,
616 struct acpi_device_id *uid)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700617{
Len Brown4be44fc2005-08-05 00:44:28 -0400618 union acpi_operand_object *obj_desc;
619 acpi_status status;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700620
Bob Mooreb229cf92006-04-21 17:15:00 -0400621 ACPI_FUNCTION_TRACE(ut_execute_UID);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700622
Len Brown4be44fc2005-08-05 00:44:28 -0400623 status = acpi_ut_evaluate_object(device_node, METHOD_NAME__UID,
624 ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING,
625 &obj_desc);
626 if (ACPI_FAILURE(status)) {
627 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700628 }
629
Len Brown4be44fc2005-08-05 00:44:28 -0400630 if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {
Bob Moore52fc0b02006-10-02 00:00:00 -0400631
Linus Torvalds1da177e2005-04-16 15:20:36 -0700632 /* Convert the Numeric UID to string */
633
Len Brown4be44fc2005-08-05 00:44:28 -0400634 acpi_ex_unsigned_integer_to_string(obj_desc->integer.value,
635 uid->value);
636 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700637 /* Copy the String UID from the returned object */
638
Len Brown4be44fc2005-08-05 00:44:28 -0400639 acpi_ut_copy_id_string(uid->value, obj_desc->string.pointer,
640 sizeof(uid->value));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700641 }
642
643 /* On exit, we must delete the return object */
644
Len Brown4be44fc2005-08-05 00:44:28 -0400645 acpi_ut_remove_reference(obj_desc);
646 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700647}
648
Linus Torvalds1da177e2005-04-16 15:20:36 -0700649/*******************************************************************************
650 *
651 * FUNCTION: acpi_ut_execute_STA
652 *
653 * PARAMETERS: device_node - Node for the device
Robert Moore44f6c012005-04-18 22:49:35 -0400654 * Flags - Where the status flags are returned
Linus Torvalds1da177e2005-04-16 15:20:36 -0700655 *
656 * RETURN: Status
657 *
658 * DESCRIPTION: Executes _STA for selected device and stores results in
659 * *Flags.
660 *
661 * NOTE: Internal function, no parameter validation
662 *
663 ******************************************************************************/
664
665acpi_status
Len Brown4be44fc2005-08-05 00:44:28 -0400666acpi_ut_execute_STA(struct acpi_namespace_node *device_node, u32 * flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700667{
Len Brown4be44fc2005-08-05 00:44:28 -0400668 union acpi_operand_object *obj_desc;
669 acpi_status status;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700670
Bob Mooreb229cf92006-04-21 17:15:00 -0400671 ACPI_FUNCTION_TRACE(ut_execute_STA);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700672
Len Brown4be44fc2005-08-05 00:44:28 -0400673 status = acpi_ut_evaluate_object(device_node, METHOD_NAME__STA,
674 ACPI_BTYPE_INTEGER, &obj_desc);
675 if (ACPI_FAILURE(status)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700676 if (AE_NOT_FOUND == status) {
Len Brown4be44fc2005-08-05 00:44:28 -0400677 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
678 "_STA on %4.4s was not found, assuming device is present\n",
679 acpi_ut_get_node_name(device_node)));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700680
Bob Mooredefba1d2005-12-16 17:05:00 -0500681 *flags = ACPI_UINT32_MAX;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700682 status = AE_OK;
683 }
684
Len Brown4be44fc2005-08-05 00:44:28 -0400685 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700686 }
687
688 /* Extract the status flags */
689
690 *flags = (u32) obj_desc->integer.value;
691
692 /* On exit, we must delete the return object */
693
Len Brown4be44fc2005-08-05 00:44:28 -0400694 acpi_ut_remove_reference(obj_desc);
695 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700696}
697
Linus Torvalds1da177e2005-04-16 15:20:36 -0700698/*******************************************************************************
699 *
700 * FUNCTION: acpi_ut_execute_Sxds
701 *
702 * PARAMETERS: device_node - Node for the device
Robert Moore44f6c012005-04-18 22:49:35 -0400703 * Flags - Where the status flags are returned
Linus Torvalds1da177e2005-04-16 15:20:36 -0700704 *
705 * RETURN: Status
706 *
707 * DESCRIPTION: Executes _STA for selected device and stores results in
708 * *Flags.
709 *
710 * NOTE: Internal function, no parameter validation
711 *
712 ******************************************************************************/
713
714acpi_status
Len Brown4be44fc2005-08-05 00:44:28 -0400715acpi_ut_execute_sxds(struct acpi_namespace_node *device_node, u8 * highest)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700716{
Len Brown4be44fc2005-08-05 00:44:28 -0400717 union acpi_operand_object *obj_desc;
718 acpi_status status;
719 u32 i;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700720
Bob Mooreb229cf92006-04-21 17:15:00 -0400721 ACPI_FUNCTION_TRACE(ut_execute_sxds);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700722
723 for (i = 0; i < 4; i++) {
724 highest[i] = 0xFF;
Len Brown4be44fc2005-08-05 00:44:28 -0400725 status = acpi_ut_evaluate_object(device_node,
Bob Mooredefba1d2005-12-16 17:05:00 -0500726 ACPI_CAST_PTR(char,
727 acpi_gbl_highest_dstate_names
728 [i]),
729 ACPI_BTYPE_INTEGER, &obj_desc);
Len Brown4be44fc2005-08-05 00:44:28 -0400730 if (ACPI_FAILURE(status)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700731 if (status != AE_NOT_FOUND) {
Len Brown4be44fc2005-08-05 00:44:28 -0400732 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
733 "%s on Device %4.4s, %s\n",
Bob Mooredefba1d2005-12-16 17:05:00 -0500734 ACPI_CAST_PTR(char,
735 acpi_gbl_highest_dstate_names
736 [i]),
Len Brown4be44fc2005-08-05 00:44:28 -0400737 acpi_ut_get_node_name
738 (device_node),
739 acpi_format_exception
740 (status)));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700741
Len Brown4be44fc2005-08-05 00:44:28 -0400742 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700743 }
Len Brown4be44fc2005-08-05 00:44:28 -0400744 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700745 /* Extract the Dstate value */
746
747 highest[i] = (u8) obj_desc->integer.value;
748
749 /* Delete the return object */
750
Len Brown4be44fc2005-08-05 00:44:28 -0400751 acpi_ut_remove_reference(obj_desc);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700752 }
753 }
754
Len Brown4be44fc2005-08-05 00:44:28 -0400755 return_ACPI_STATUS(AE_OK);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700756}