blob: d6d7121583c0e96af0bee2f7222d4ab136e5ff28 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/******************************************************************************
2 *
3 * Module Name: uteval - Object evaluation
4 *
5 *****************************************************************************/
6
7/*
Bob Moore4a90c7e2006-01-13 16:22:00 -05008 * Copyright (C) 2000 - 2006, 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 */
62static const char *acpi_interfaces_supported[] = {
63 /* 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 *
161 * FUNCTION: acpi_ut_evaluate_object
162 *
163 * PARAMETERS: prefix_node - Starting node
164 * Path - Path to object from starting node
165 * expected_return_types - Bitmap of allowed return types
166 * return_desc - Where a return value is stored
167 *
168 * RETURN: Status
169 *
170 * DESCRIPTION: Evaluates a namespace object and verifies the type of the
171 * return object. Common code that simplifies accessing objects
172 * that have required return objects of fixed types.
173 *
174 * NOTE: Internal function, no parameter validation
175 *
176 ******************************************************************************/
177
178acpi_status
Len Brown4be44fc2005-08-05 00:44:28 -0400179acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node,
180 char *path,
181 u32 expected_return_btypes,
182 union acpi_operand_object **return_desc)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700183{
Bob Moore41195322006-05-26 16:36:00 -0400184 struct acpi_evaluate_info *info;
Len Brown4be44fc2005-08-05 00:44:28 -0400185 acpi_status status;
186 u32 return_btype;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700187
Bob Mooreb229cf92006-04-21 17:15:00 -0400188 ACPI_FUNCTION_TRACE(ut_evaluate_object);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700189
Bob Moore41195322006-05-26 16:36:00 -0400190 /* Allocate the evaluation information block */
191
192 info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
193 if (!info) {
194 return_ACPI_STATUS(AE_NO_MEMORY);
195 }
196
197 info->prefix_node = prefix_node;
198 info->pathname = path;
199 info->parameter_type = ACPI_PARAM_ARGS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700200
201 /* Evaluate the object/method */
202
Bob Moore41195322006-05-26 16:36:00 -0400203 status = acpi_ns_evaluate(info);
Len Brown4be44fc2005-08-05 00:44:28 -0400204 if (ACPI_FAILURE(status)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700205 if (status == AE_NOT_FOUND) {
Len Brown4be44fc2005-08-05 00:44:28 -0400206 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
207 "[%4.4s.%s] was not found\n",
208 acpi_ut_get_node_name(prefix_node),
209 path));
210 } else {
Bob Mooreb8e4d892006-01-27 16:43:00 -0500211 ACPI_ERROR_METHOD("Method execution failed",
212 prefix_node, path, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700213 }
214
Bob Moore41195322006-05-26 16:36:00 -0400215 goto cleanup;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700216 }
217
218 /* Did we get a return object? */
219
Bob Moore41195322006-05-26 16:36:00 -0400220 if (!info->return_object) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700221 if (expected_return_btypes) {
Bob Mooreb8e4d892006-01-27 16:43:00 -0500222 ACPI_ERROR_METHOD("No object was returned from",
223 prefix_node, path, AE_NOT_EXIST);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700224
Bob Moore41195322006-05-26 16:36:00 -0400225 status = AE_NOT_EXIST;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700226 }
227
Bob Moore41195322006-05-26 16:36:00 -0400228 goto cleanup;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700229 }
230
231 /* Map the return object type to the bitmapped type */
232
Bob Moore41195322006-05-26 16:36:00 -0400233 switch (ACPI_GET_OBJECT_TYPE(info->return_object)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700234 case ACPI_TYPE_INTEGER:
235 return_btype = ACPI_BTYPE_INTEGER;
236 break;
237
238 case ACPI_TYPE_BUFFER:
239 return_btype = ACPI_BTYPE_BUFFER;
240 break;
241
242 case ACPI_TYPE_STRING:
243 return_btype = ACPI_BTYPE_STRING;
244 break;
245
246 case ACPI_TYPE_PACKAGE:
247 return_btype = ACPI_BTYPE_PACKAGE;
248 break;
249
250 default:
251 return_btype = 0;
252 break;
253 }
254
Len Brown4be44fc2005-08-05 00:44:28 -0400255 if ((acpi_gbl_enable_interpreter_slack) && (!expected_return_btypes)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700256 /*
257 * We received a return object, but one was not expected. This can
258 * happen frequently if the "implicit return" feature is enabled.
259 * Just delete the return object and return AE_OK.
260 */
Bob Moore41195322006-05-26 16:36:00 -0400261 acpi_ut_remove_reference(info->return_object);
262 goto cleanup;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700263 }
264
265 /* Is the return object one of the expected types? */
266
267 if (!(expected_return_btypes & return_btype)) {
Bob Mooreb8e4d892006-01-27 16:43:00 -0500268 ACPI_ERROR_METHOD("Return object type is incorrect",
269 prefix_node, path, AE_TYPE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700270
Bob Mooreb8e4d892006-01-27 16:43:00 -0500271 ACPI_ERROR((AE_INFO,
272 "Type returned from %s was incorrect: %s, expected Btypes: %X",
273 path,
Bob Moore41195322006-05-26 16:36:00 -0400274 acpi_ut_get_object_type_name(info->return_object),
Bob Mooreb8e4d892006-01-27 16:43:00 -0500275 expected_return_btypes));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700276
277 /* On error exit, we must delete the return object */
278
Bob Moore41195322006-05-26 16:36:00 -0400279 acpi_ut_remove_reference(info->return_object);
280 status = AE_TYPE;
281 goto cleanup;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700282 }
283
284 /* Object type is OK, return it */
285
Bob Moore41195322006-05-26 16:36:00 -0400286 *return_desc = info->return_object;
287
288 cleanup:
289 ACPI_FREE(info);
290 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700291}
292
Linus Torvalds1da177e2005-04-16 15:20:36 -0700293/*******************************************************************************
294 *
295 * FUNCTION: acpi_ut_evaluate_numeric_object
296 *
Robert Moore44f6c012005-04-18 22:49:35 -0400297 * PARAMETERS: object_name - Object name to be evaluated
Linus Torvalds1da177e2005-04-16 15:20:36 -0700298 * device_node - Node for the device
Robert Moore44f6c012005-04-18 22:49:35 -0400299 * Address - Where the value is returned
Linus Torvalds1da177e2005-04-16 15:20:36 -0700300 *
301 * RETURN: Status
302 *
303 * DESCRIPTION: Evaluates a numeric namespace object for a selected device
304 * and stores result in *Address.
305 *
306 * NOTE: Internal function, no parameter validation
307 *
308 ******************************************************************************/
309
310acpi_status
Len Brown4be44fc2005-08-05 00:44:28 -0400311acpi_ut_evaluate_numeric_object(char *object_name,
312 struct acpi_namespace_node *device_node,
313 acpi_integer * address)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700314{
Len Brown4be44fc2005-08-05 00:44:28 -0400315 union acpi_operand_object *obj_desc;
316 acpi_status status;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700317
Bob Mooreb229cf92006-04-21 17:15:00 -0400318 ACPI_FUNCTION_TRACE(ut_evaluate_numeric_object);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700319
Len Brown4be44fc2005-08-05 00:44:28 -0400320 status = acpi_ut_evaluate_object(device_node, object_name,
321 ACPI_BTYPE_INTEGER, &obj_desc);
322 if (ACPI_FAILURE(status)) {
323 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700324 }
325
326 /* Get the returned Integer */
327
328 *address = obj_desc->integer.value;
329
330 /* On exit, we must delete the return object */
331
Len Brown4be44fc2005-08-05 00:44:28 -0400332 acpi_ut_remove_reference(obj_desc);
333 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700334}
335
Linus Torvalds1da177e2005-04-16 15:20:36 -0700336/*******************************************************************************
337 *
338 * FUNCTION: acpi_ut_copy_id_string
339 *
340 * PARAMETERS: Destination - Where to copy the string
341 * Source - Source string
342 * max_length - Length of the destination buffer
343 *
344 * RETURN: None
345 *
346 * DESCRIPTION: Copies an ID string for the _HID, _CID, and _UID methods.
347 * Performs removal of a leading asterisk if present -- workaround
348 * for a known issue on a bunch of machines.
349 *
350 ******************************************************************************/
351
352static void
Len Brown4be44fc2005-08-05 00:44:28 -0400353acpi_ut_copy_id_string(char *destination, char *source, acpi_size max_length)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700354{
355
Linus Torvalds1da177e2005-04-16 15:20:36 -0700356 /*
357 * Workaround for ID strings that have a leading asterisk. This construct
358 * is not allowed by the ACPI specification (ID strings must be
359 * alphanumeric), but enough existing machines have this embedded in their
360 * ID strings that the following code is useful.
361 */
362 if (*source == '*') {
363 source++;
364 }
365
366 /* Do the actual copy */
367
Len Brown4be44fc2005-08-05 00:44:28 -0400368 ACPI_STRNCPY(destination, source, max_length);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700369}
370
Linus Torvalds1da177e2005-04-16 15:20:36 -0700371/*******************************************************************************
372 *
373 * FUNCTION: acpi_ut_execute_HID
374 *
375 * PARAMETERS: device_node - Node for the device
Robert Moore44f6c012005-04-18 22:49:35 -0400376 * Hid - Where the HID is returned
Linus Torvalds1da177e2005-04-16 15:20:36 -0700377 *
378 * RETURN: Status
379 *
380 * DESCRIPTION: Executes the _HID control method that returns the hardware
381 * ID of the device.
382 *
383 * NOTE: Internal function, no parameter validation
384 *
385 ******************************************************************************/
386
387acpi_status
Len Brown4be44fc2005-08-05 00:44:28 -0400388acpi_ut_execute_HID(struct acpi_namespace_node *device_node,
389 struct acpi_device_id *hid)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700390{
Len Brown4be44fc2005-08-05 00:44:28 -0400391 union acpi_operand_object *obj_desc;
392 acpi_status status;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700393
Bob Mooreb229cf92006-04-21 17:15:00 -0400394 ACPI_FUNCTION_TRACE(ut_execute_HID);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700395
Len Brown4be44fc2005-08-05 00:44:28 -0400396 status = acpi_ut_evaluate_object(device_node, METHOD_NAME__HID,
397 ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING,
398 &obj_desc);
399 if (ACPI_FAILURE(status)) {
400 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700401 }
402
Len Brown4be44fc2005-08-05 00:44:28 -0400403 if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {
Bob Moore52fc0b02006-10-02 00:00:00 -0400404
Linus Torvalds1da177e2005-04-16 15:20:36 -0700405 /* Convert the Numeric HID to string */
406
Len Brown4be44fc2005-08-05 00:44:28 -0400407 acpi_ex_eisa_id_to_string((u32) obj_desc->integer.value,
408 hid->value);
409 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700410 /* Copy the String HID from the returned object */
411
Len Brown4be44fc2005-08-05 00:44:28 -0400412 acpi_ut_copy_id_string(hid->value, obj_desc->string.pointer,
413 sizeof(hid->value));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700414 }
415
416 /* On exit, we must delete the return object */
417
Len Brown4be44fc2005-08-05 00:44:28 -0400418 acpi_ut_remove_reference(obj_desc);
419 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700420}
421
Linus Torvalds1da177e2005-04-16 15:20:36 -0700422/*******************************************************************************
423 *
424 * FUNCTION: acpi_ut_translate_one_cid
425 *
426 * PARAMETERS: obj_desc - _CID object, must be integer or string
427 * one_cid - Where the CID string is returned
428 *
429 * RETURN: Status
430 *
431 * DESCRIPTION: Return a numeric or string _CID value as a string.
432 * (Compatible ID)
433 *
434 * NOTE: Assumes a maximum _CID string length of
435 * ACPI_MAX_CID_LENGTH.
436 *
437 ******************************************************************************/
438
439static acpi_status
Len Brown4be44fc2005-08-05 00:44:28 -0400440acpi_ut_translate_one_cid(union acpi_operand_object *obj_desc,
441 struct acpi_compatible_id *one_cid)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700442{
443
Len Brown4be44fc2005-08-05 00:44:28 -0400444 switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700445 case ACPI_TYPE_INTEGER:
446
447 /* Convert the Numeric CID to string */
448
Len Brown4be44fc2005-08-05 00:44:28 -0400449 acpi_ex_eisa_id_to_string((u32) obj_desc->integer.value,
450 one_cid->value);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700451 return (AE_OK);
452
453 case ACPI_TYPE_STRING:
454
455 if (obj_desc->string.length > ACPI_MAX_CID_LENGTH) {
456 return (AE_AML_STRING_LIMIT);
457 }
458
459 /* Copy the String CID from the returned object */
460
Len Brown4be44fc2005-08-05 00:44:28 -0400461 acpi_ut_copy_id_string(one_cid->value, obj_desc->string.pointer,
462 ACPI_MAX_CID_LENGTH);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700463 return (AE_OK);
464
465 default:
466
467 return (AE_TYPE);
468 }
469}
470
Linus Torvalds1da177e2005-04-16 15:20:36 -0700471/*******************************************************************************
472 *
473 * FUNCTION: acpi_ut_execute_CID
474 *
475 * PARAMETERS: device_node - Node for the device
Robert Moore44f6c012005-04-18 22:49:35 -0400476 * return_cid_list - Where the CID list is returned
Linus Torvalds1da177e2005-04-16 15:20:36 -0700477 *
478 * RETURN: Status
479 *
480 * DESCRIPTION: Executes the _CID control method that returns one or more
481 * compatible hardware IDs for the device.
482 *
483 * NOTE: Internal function, no parameter validation
484 *
485 ******************************************************************************/
486
487acpi_status
Len Brown4be44fc2005-08-05 00:44:28 -0400488acpi_ut_execute_CID(struct acpi_namespace_node * device_node,
489 struct acpi_compatible_id_list ** return_cid_list)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700490{
Len Brown4be44fc2005-08-05 00:44:28 -0400491 union acpi_operand_object *obj_desc;
492 acpi_status status;
493 u32 count;
494 u32 size;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700495 struct acpi_compatible_id_list *cid_list;
Len Brown4be44fc2005-08-05 00:44:28 -0400496 acpi_native_uint i;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700497
Bob Mooreb229cf92006-04-21 17:15:00 -0400498 ACPI_FUNCTION_TRACE(ut_execute_CID);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700499
500 /* Evaluate the _CID method for this device */
501
Len Brown4be44fc2005-08-05 00:44:28 -0400502 status = acpi_ut_evaluate_object(device_node, METHOD_NAME__CID,
503 ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING
504 | ACPI_BTYPE_PACKAGE, &obj_desc);
505 if (ACPI_FAILURE(status)) {
506 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700507 }
508
509 /* Get the number of _CIDs returned */
510
511 count = 1;
Len Brown4be44fc2005-08-05 00:44:28 -0400512 if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_PACKAGE) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700513 count = obj_desc->package.count;
514 }
515
516 /* Allocate a worst-case buffer for the _CIDs */
517
Len Brown4be44fc2005-08-05 00:44:28 -0400518 size = (((count - 1) * sizeof(struct acpi_compatible_id)) +
519 sizeof(struct acpi_compatible_id_list));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700520
Bob Moore83135242006-10-03 00:00:00 -0400521 cid_list = ACPI_ALLOCATE_ZEROED((acpi_size) size);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700522 if (!cid_list) {
Len Brown4be44fc2005-08-05 00:44:28 -0400523 return_ACPI_STATUS(AE_NO_MEMORY);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700524 }
525
526 /* Init CID list */
527
528 cid_list->count = count;
529 cid_list->size = size;
530
531 /*
Robert Moore44f6c012005-04-18 22:49:35 -0400532 * A _CID can return either a single compatible ID or a package of
533 * compatible IDs. Each compatible ID can be one of the following:
534 * 1) Integer (32 bit compressed EISA ID) or
535 * 2) String (PCI ID format, e.g. "PCI\VEN_vvvv&DEV_dddd&SUBSYS_ssssssss")
Linus Torvalds1da177e2005-04-16 15:20:36 -0700536 */
537
538 /* The _CID object can be either a single CID or a package (list) of CIDs */
539
Len Brown4be44fc2005-08-05 00:44:28 -0400540 if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_PACKAGE) {
Bob Moore52fc0b02006-10-02 00:00:00 -0400541
Linus Torvalds1da177e2005-04-16 15:20:36 -0700542 /* Translate each package element */
543
544 for (i = 0; i < count; i++) {
Len Brown4be44fc2005-08-05 00:44:28 -0400545 status =
546 acpi_ut_translate_one_cid(obj_desc->package.
547 elements[i],
548 &cid_list->id[i]);
549 if (ACPI_FAILURE(status)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700550 break;
551 }
552 }
Len Brown4be44fc2005-08-05 00:44:28 -0400553 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700554 /* Only one CID, translate to a string */
555
Len Brown4be44fc2005-08-05 00:44:28 -0400556 status = acpi_ut_translate_one_cid(obj_desc, cid_list->id);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700557 }
558
559 /* Cleanup on error */
560
Len Brown4be44fc2005-08-05 00:44:28 -0400561 if (ACPI_FAILURE(status)) {
Bob Moore83135242006-10-03 00:00:00 -0400562 ACPI_FREE(cid_list);
Len Brown4be44fc2005-08-05 00:44:28 -0400563 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700564 *return_cid_list = cid_list;
565 }
566
567 /* On exit, we must delete the _CID return object */
568
Len Brown4be44fc2005-08-05 00:44:28 -0400569 acpi_ut_remove_reference(obj_desc);
570 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700571}
572
Linus Torvalds1da177e2005-04-16 15:20:36 -0700573/*******************************************************************************
574 *
575 * FUNCTION: acpi_ut_execute_UID
576 *
577 * PARAMETERS: device_node - Node for the device
Robert Moore44f6c012005-04-18 22:49:35 -0400578 * Uid - Where the UID is returned
Linus Torvalds1da177e2005-04-16 15:20:36 -0700579 *
580 * RETURN: Status
581 *
582 * DESCRIPTION: Executes the _UID control method that returns the hardware
583 * ID of the device.
584 *
585 * NOTE: Internal function, no parameter validation
586 *
587 ******************************************************************************/
588
589acpi_status
Len Brown4be44fc2005-08-05 00:44:28 -0400590acpi_ut_execute_UID(struct acpi_namespace_node *device_node,
591 struct acpi_device_id *uid)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700592{
Len Brown4be44fc2005-08-05 00:44:28 -0400593 union acpi_operand_object *obj_desc;
594 acpi_status status;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700595
Bob Mooreb229cf92006-04-21 17:15:00 -0400596 ACPI_FUNCTION_TRACE(ut_execute_UID);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700597
Len Brown4be44fc2005-08-05 00:44:28 -0400598 status = acpi_ut_evaluate_object(device_node, METHOD_NAME__UID,
599 ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING,
600 &obj_desc);
601 if (ACPI_FAILURE(status)) {
602 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700603 }
604
Len Brown4be44fc2005-08-05 00:44:28 -0400605 if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {
Bob Moore52fc0b02006-10-02 00:00:00 -0400606
Linus Torvalds1da177e2005-04-16 15:20:36 -0700607 /* Convert the Numeric UID to string */
608
Len Brown4be44fc2005-08-05 00:44:28 -0400609 acpi_ex_unsigned_integer_to_string(obj_desc->integer.value,
610 uid->value);
611 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700612 /* Copy the String UID from the returned object */
613
Len Brown4be44fc2005-08-05 00:44:28 -0400614 acpi_ut_copy_id_string(uid->value, obj_desc->string.pointer,
615 sizeof(uid->value));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700616 }
617
618 /* On exit, we must delete the return object */
619
Len Brown4be44fc2005-08-05 00:44:28 -0400620 acpi_ut_remove_reference(obj_desc);
621 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700622}
623
Linus Torvalds1da177e2005-04-16 15:20:36 -0700624/*******************************************************************************
625 *
626 * FUNCTION: acpi_ut_execute_STA
627 *
628 * PARAMETERS: device_node - Node for the device
Robert Moore44f6c012005-04-18 22:49:35 -0400629 * Flags - Where the status flags are returned
Linus Torvalds1da177e2005-04-16 15:20:36 -0700630 *
631 * RETURN: Status
632 *
633 * DESCRIPTION: Executes _STA for selected device and stores results in
634 * *Flags.
635 *
636 * NOTE: Internal function, no parameter validation
637 *
638 ******************************************************************************/
639
640acpi_status
Len Brown4be44fc2005-08-05 00:44:28 -0400641acpi_ut_execute_STA(struct acpi_namespace_node *device_node, u32 * flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700642{
Len Brown4be44fc2005-08-05 00:44:28 -0400643 union acpi_operand_object *obj_desc;
644 acpi_status status;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700645
Bob Mooreb229cf92006-04-21 17:15:00 -0400646 ACPI_FUNCTION_TRACE(ut_execute_STA);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700647
Len Brown4be44fc2005-08-05 00:44:28 -0400648 status = acpi_ut_evaluate_object(device_node, METHOD_NAME__STA,
649 ACPI_BTYPE_INTEGER, &obj_desc);
650 if (ACPI_FAILURE(status)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700651 if (AE_NOT_FOUND == status) {
Len Brown4be44fc2005-08-05 00:44:28 -0400652 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
653 "_STA on %4.4s was not found, assuming device is present\n",
654 acpi_ut_get_node_name(device_node)));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700655
Bob Mooredefba1d2005-12-16 17:05:00 -0500656 *flags = ACPI_UINT32_MAX;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700657 status = AE_OK;
658 }
659
Len Brown4be44fc2005-08-05 00:44:28 -0400660 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700661 }
662
663 /* Extract the status flags */
664
665 *flags = (u32) obj_desc->integer.value;
666
667 /* On exit, we must delete the return object */
668
Len Brown4be44fc2005-08-05 00:44:28 -0400669 acpi_ut_remove_reference(obj_desc);
670 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700671}
672
Linus Torvalds1da177e2005-04-16 15:20:36 -0700673/*******************************************************************************
674 *
675 * FUNCTION: acpi_ut_execute_Sxds
676 *
677 * PARAMETERS: device_node - Node for the device
Robert Moore44f6c012005-04-18 22:49:35 -0400678 * Flags - Where the status flags are returned
Linus Torvalds1da177e2005-04-16 15:20:36 -0700679 *
680 * RETURN: Status
681 *
682 * DESCRIPTION: Executes _STA for selected device and stores results in
683 * *Flags.
684 *
685 * NOTE: Internal function, no parameter validation
686 *
687 ******************************************************************************/
688
689acpi_status
Len Brown4be44fc2005-08-05 00:44:28 -0400690acpi_ut_execute_sxds(struct acpi_namespace_node *device_node, u8 * highest)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700691{
Len Brown4be44fc2005-08-05 00:44:28 -0400692 union acpi_operand_object *obj_desc;
693 acpi_status status;
694 u32 i;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700695
Bob Mooreb229cf92006-04-21 17:15:00 -0400696 ACPI_FUNCTION_TRACE(ut_execute_sxds);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700697
698 for (i = 0; i < 4; i++) {
699 highest[i] = 0xFF;
Len Brown4be44fc2005-08-05 00:44:28 -0400700 status = acpi_ut_evaluate_object(device_node,
Bob Mooredefba1d2005-12-16 17:05:00 -0500701 ACPI_CAST_PTR(char,
702 acpi_gbl_highest_dstate_names
703 [i]),
704 ACPI_BTYPE_INTEGER, &obj_desc);
Len Brown4be44fc2005-08-05 00:44:28 -0400705 if (ACPI_FAILURE(status)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700706 if (status != AE_NOT_FOUND) {
Len Brown4be44fc2005-08-05 00:44:28 -0400707 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
708 "%s on Device %4.4s, %s\n",
Bob Mooredefba1d2005-12-16 17:05:00 -0500709 ACPI_CAST_PTR(char,
710 acpi_gbl_highest_dstate_names
711 [i]),
Len Brown4be44fc2005-08-05 00:44:28 -0400712 acpi_ut_get_node_name
713 (device_node),
714 acpi_format_exception
715 (status)));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700716
Len Brown4be44fc2005-08-05 00:44:28 -0400717 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700718 }
Len Brown4be44fc2005-08-05 00:44:28 -0400719 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700720 /* Extract the Dstate value */
721
722 highest[i] = (u8) obj_desc->integer.value;
723
724 /* Delete the return object */
725
Len Brown4be44fc2005-08-05 00:44:28 -0400726 acpi_ut_remove_reference(obj_desc);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700727 }
728 }
729
Len Brown4be44fc2005-08-05 00:44:28 -0400730 return_ACPI_STATUS(AE_OK);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700731}