sync hh.org
[hh.org.git] / drivers / acpi / utilities / uteval.c
blobd6d7121583c0e96af0bee2f7222d4ab136e5ff28
1 /******************************************************************************
3 * Module Name: uteval - Object evaluation
5 *****************************************************************************/
7 /*
8 * Copyright (C) 2000 - 2006, R. Byron Moore
9 * All rights reserved.
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.
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.
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.
44 #include <acpi/acpi.h>
45 #include <acpi/acnamesp.h>
46 #include <acpi/acinterp.h>
48 #define _COMPONENT ACPI_UTILITIES
49 ACPI_MODULE_NAME("uteval")
51 /* Local prototypes */
52 static void
53 acpi_ut_copy_id_string(char *destination, char *source, acpi_size max_length);
55 static acpi_status
56 acpi_ut_translate_one_cid(union acpi_operand_object *obj_desc,
57 struct acpi_compatible_id *one_cid);
60 * Strings supported by the _OSI predefined (internal) method.
62 static const char *acpi_interfaces_supported[] = {
63 /* Operating System Vendor Strings */
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 */
77 /* Feature Group Strings */
79 "Extended Address Space Descriptor"
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.
87 /*******************************************************************************
89 * FUNCTION: acpi_ut_osi_implementation
91 * PARAMETERS: walk_state - Current walk state
93 * RETURN: Status
95 * DESCRIPTION: Implementation of the _OSI predefined control method
97 ******************************************************************************/
99 acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state)
101 acpi_status status;
102 union acpi_operand_object *string_desc;
103 union acpi_operand_object *return_desc;
104 acpi_native_uint i;
106 ACPI_FUNCTION_TRACE(ut_osi_implementation);
108 /* Validate the string input argument */
110 string_desc = walk_state->arguments[0].object;
111 if (!string_desc || (string_desc->common.type != ACPI_TYPE_STRING)) {
112 return_ACPI_STATUS(AE_TYPE);
115 /* Create a return object */
117 return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
118 if (!return_desc) {
119 return_ACPI_STATUS(AE_NO_MEMORY);
122 /* Default return value is SUPPORTED */
124 return_desc->integer.value = ACPI_UINT32_MAX;
125 walk_state->return_desc = return_desc;
127 /* Compare input string to static table of supported interfaces */
129 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])) {
134 /* The interface is supported */
136 return_ACPI_STATUS(AE_CTRL_TERMINATE);
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.)
145 status = acpi_os_validate_interface(string_desc->string.pointer);
146 if (ACPI_SUCCESS(status)) {
148 /* The interface is supported */
150 return_ACPI_STATUS(AE_CTRL_TERMINATE);
153 /* The interface is not supported */
155 return_desc->integer.value = 0;
156 return_ACPI_STATUS(AE_CTRL_TERMINATE);
159 /*******************************************************************************
161 * FUNCTION: acpi_ut_evaluate_object
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
168 * RETURN: Status
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.
174 * NOTE: Internal function, no parameter validation
176 ******************************************************************************/
178 acpi_status
179 acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node,
180 char *path,
181 u32 expected_return_btypes,
182 union acpi_operand_object **return_desc)
184 struct acpi_evaluate_info *info;
185 acpi_status status;
186 u32 return_btype;
188 ACPI_FUNCTION_TRACE(ut_evaluate_object);
190 /* Allocate the evaluation information block */
192 info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
193 if (!info) {
194 return_ACPI_STATUS(AE_NO_MEMORY);
197 info->prefix_node = prefix_node;
198 info->pathname = path;
199 info->parameter_type = ACPI_PARAM_ARGS;
201 /* Evaluate the object/method */
203 status = acpi_ns_evaluate(info);
204 if (ACPI_FAILURE(status)) {
205 if (status == AE_NOT_FOUND) {
206 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 {
211 ACPI_ERROR_METHOD("Method execution failed",
212 prefix_node, path, status);
215 goto cleanup;
218 /* Did we get a return object? */
220 if (!info->return_object) {
221 if (expected_return_btypes) {
222 ACPI_ERROR_METHOD("No object was returned from",
223 prefix_node, path, AE_NOT_EXIST);
225 status = AE_NOT_EXIST;
228 goto cleanup;
231 /* Map the return object type to the bitmapped type */
233 switch (ACPI_GET_OBJECT_TYPE(info->return_object)) {
234 case ACPI_TYPE_INTEGER:
235 return_btype = ACPI_BTYPE_INTEGER;
236 break;
238 case ACPI_TYPE_BUFFER:
239 return_btype = ACPI_BTYPE_BUFFER;
240 break;
242 case ACPI_TYPE_STRING:
243 return_btype = ACPI_BTYPE_STRING;
244 break;
246 case ACPI_TYPE_PACKAGE:
247 return_btype = ACPI_BTYPE_PACKAGE;
248 break;
250 default:
251 return_btype = 0;
252 break;
255 if ((acpi_gbl_enable_interpreter_slack) && (!expected_return_btypes)) {
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.
261 acpi_ut_remove_reference(info->return_object);
262 goto cleanup;
265 /* Is the return object one of the expected types? */
267 if (!(expected_return_btypes & return_btype)) {
268 ACPI_ERROR_METHOD("Return object type is incorrect",
269 prefix_node, path, AE_TYPE);
271 ACPI_ERROR((AE_INFO,
272 "Type returned from %s was incorrect: %s, expected Btypes: %X",
273 path,
274 acpi_ut_get_object_type_name(info->return_object),
275 expected_return_btypes));
277 /* On error exit, we must delete the return object */
279 acpi_ut_remove_reference(info->return_object);
280 status = AE_TYPE;
281 goto cleanup;
284 /* Object type is OK, return it */
286 *return_desc = info->return_object;
288 cleanup:
289 ACPI_FREE(info);
290 return_ACPI_STATUS(status);
293 /*******************************************************************************
295 * FUNCTION: acpi_ut_evaluate_numeric_object
297 * PARAMETERS: object_name - Object name to be evaluated
298 * device_node - Node for the device
299 * Address - Where the value is returned
301 * RETURN: Status
303 * DESCRIPTION: Evaluates a numeric namespace object for a selected device
304 * and stores result in *Address.
306 * NOTE: Internal function, no parameter validation
308 ******************************************************************************/
310 acpi_status
311 acpi_ut_evaluate_numeric_object(char *object_name,
312 struct acpi_namespace_node *device_node,
313 acpi_integer * address)
315 union acpi_operand_object *obj_desc;
316 acpi_status status;
318 ACPI_FUNCTION_TRACE(ut_evaluate_numeric_object);
320 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);
326 /* Get the returned Integer */
328 *address = obj_desc->integer.value;
330 /* On exit, we must delete the return object */
332 acpi_ut_remove_reference(obj_desc);
333 return_ACPI_STATUS(status);
336 /*******************************************************************************
338 * FUNCTION: acpi_ut_copy_id_string
340 * PARAMETERS: Destination - Where to copy the string
341 * Source - Source string
342 * max_length - Length of the destination buffer
344 * RETURN: None
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.
350 ******************************************************************************/
352 static void
353 acpi_ut_copy_id_string(char *destination, char *source, acpi_size max_length)
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.
362 if (*source == '*') {
363 source++;
366 /* Do the actual copy */
368 ACPI_STRNCPY(destination, source, max_length);
371 /*******************************************************************************
373 * FUNCTION: acpi_ut_execute_HID
375 * PARAMETERS: device_node - Node for the device
376 * Hid - Where the HID is returned
378 * RETURN: Status
380 * DESCRIPTION: Executes the _HID control method that returns the hardware
381 * ID of the device.
383 * NOTE: Internal function, no parameter validation
385 ******************************************************************************/
387 acpi_status
388 acpi_ut_execute_HID(struct acpi_namespace_node *device_node,
389 struct acpi_device_id *hid)
391 union acpi_operand_object *obj_desc;
392 acpi_status status;
394 ACPI_FUNCTION_TRACE(ut_execute_HID);
396 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);
403 if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {
405 /* Convert the Numeric HID to string */
407 acpi_ex_eisa_id_to_string((u32) obj_desc->integer.value,
408 hid->value);
409 } else {
410 /* Copy the String HID from the returned object */
412 acpi_ut_copy_id_string(hid->value, obj_desc->string.pointer,
413 sizeof(hid->value));
416 /* On exit, we must delete the return object */
418 acpi_ut_remove_reference(obj_desc);
419 return_ACPI_STATUS(status);
422 /*******************************************************************************
424 * FUNCTION: acpi_ut_translate_one_cid
426 * PARAMETERS: obj_desc - _CID object, must be integer or string
427 * one_cid - Where the CID string is returned
429 * RETURN: Status
431 * DESCRIPTION: Return a numeric or string _CID value as a string.
432 * (Compatible ID)
434 * NOTE: Assumes a maximum _CID string length of
435 * ACPI_MAX_CID_LENGTH.
437 ******************************************************************************/
439 static acpi_status
440 acpi_ut_translate_one_cid(union acpi_operand_object *obj_desc,
441 struct acpi_compatible_id *one_cid)
444 switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
445 case ACPI_TYPE_INTEGER:
447 /* Convert the Numeric CID to string */
449 acpi_ex_eisa_id_to_string((u32) obj_desc->integer.value,
450 one_cid->value);
451 return (AE_OK);
453 case ACPI_TYPE_STRING:
455 if (obj_desc->string.length > ACPI_MAX_CID_LENGTH) {
456 return (AE_AML_STRING_LIMIT);
459 /* Copy the String CID from the returned object */
461 acpi_ut_copy_id_string(one_cid->value, obj_desc->string.pointer,
462 ACPI_MAX_CID_LENGTH);
463 return (AE_OK);
465 default:
467 return (AE_TYPE);
471 /*******************************************************************************
473 * FUNCTION: acpi_ut_execute_CID
475 * PARAMETERS: device_node - Node for the device
476 * return_cid_list - Where the CID list is returned
478 * RETURN: Status
480 * DESCRIPTION: Executes the _CID control method that returns one or more
481 * compatible hardware IDs for the device.
483 * NOTE: Internal function, no parameter validation
485 ******************************************************************************/
487 acpi_status
488 acpi_ut_execute_CID(struct acpi_namespace_node * device_node,
489 struct acpi_compatible_id_list ** return_cid_list)
491 union acpi_operand_object *obj_desc;
492 acpi_status status;
493 u32 count;
494 u32 size;
495 struct acpi_compatible_id_list *cid_list;
496 acpi_native_uint i;
498 ACPI_FUNCTION_TRACE(ut_execute_CID);
500 /* Evaluate the _CID method for this device */
502 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);
509 /* Get the number of _CIDs returned */
511 count = 1;
512 if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_PACKAGE) {
513 count = obj_desc->package.count;
516 /* Allocate a worst-case buffer for the _CIDs */
518 size = (((count - 1) * sizeof(struct acpi_compatible_id)) +
519 sizeof(struct acpi_compatible_id_list));
521 cid_list = ACPI_ALLOCATE_ZEROED((acpi_size) size);
522 if (!cid_list) {
523 return_ACPI_STATUS(AE_NO_MEMORY);
526 /* Init CID list */
528 cid_list->count = count;
529 cid_list->size = size;
532 * 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")
538 /* The _CID object can be either a single CID or a package (list) of CIDs */
540 if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_PACKAGE) {
542 /* Translate each package element */
544 for (i = 0; i < count; i++) {
545 status =
546 acpi_ut_translate_one_cid(obj_desc->package.
547 elements[i],
548 &cid_list->id[i]);
549 if (ACPI_FAILURE(status)) {
550 break;
553 } else {
554 /* Only one CID, translate to a string */
556 status = acpi_ut_translate_one_cid(obj_desc, cid_list->id);
559 /* Cleanup on error */
561 if (ACPI_FAILURE(status)) {
562 ACPI_FREE(cid_list);
563 } else {
564 *return_cid_list = cid_list;
567 /* On exit, we must delete the _CID return object */
569 acpi_ut_remove_reference(obj_desc);
570 return_ACPI_STATUS(status);
573 /*******************************************************************************
575 * FUNCTION: acpi_ut_execute_UID
577 * PARAMETERS: device_node - Node for the device
578 * Uid - Where the UID is returned
580 * RETURN: Status
582 * DESCRIPTION: Executes the _UID control method that returns the hardware
583 * ID of the device.
585 * NOTE: Internal function, no parameter validation
587 ******************************************************************************/
589 acpi_status
590 acpi_ut_execute_UID(struct acpi_namespace_node *device_node,
591 struct acpi_device_id *uid)
593 union acpi_operand_object *obj_desc;
594 acpi_status status;
596 ACPI_FUNCTION_TRACE(ut_execute_UID);
598 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);
605 if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {
607 /* Convert the Numeric UID to string */
609 acpi_ex_unsigned_integer_to_string(obj_desc->integer.value,
610 uid->value);
611 } else {
612 /* Copy the String UID from the returned object */
614 acpi_ut_copy_id_string(uid->value, obj_desc->string.pointer,
615 sizeof(uid->value));
618 /* On exit, we must delete the return object */
620 acpi_ut_remove_reference(obj_desc);
621 return_ACPI_STATUS(status);
624 /*******************************************************************************
626 * FUNCTION: acpi_ut_execute_STA
628 * PARAMETERS: device_node - Node for the device
629 * Flags - Where the status flags are returned
631 * RETURN: Status
633 * DESCRIPTION: Executes _STA for selected device and stores results in
634 * *Flags.
636 * NOTE: Internal function, no parameter validation
638 ******************************************************************************/
640 acpi_status
641 acpi_ut_execute_STA(struct acpi_namespace_node *device_node, u32 * flags)
643 union acpi_operand_object *obj_desc;
644 acpi_status status;
646 ACPI_FUNCTION_TRACE(ut_execute_STA);
648 status = acpi_ut_evaluate_object(device_node, METHOD_NAME__STA,
649 ACPI_BTYPE_INTEGER, &obj_desc);
650 if (ACPI_FAILURE(status)) {
651 if (AE_NOT_FOUND == status) {
652 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)));
656 *flags = ACPI_UINT32_MAX;
657 status = AE_OK;
660 return_ACPI_STATUS(status);
663 /* Extract the status flags */
665 *flags = (u32) obj_desc->integer.value;
667 /* On exit, we must delete the return object */
669 acpi_ut_remove_reference(obj_desc);
670 return_ACPI_STATUS(status);
673 /*******************************************************************************
675 * FUNCTION: acpi_ut_execute_Sxds
677 * PARAMETERS: device_node - Node for the device
678 * Flags - Where the status flags are returned
680 * RETURN: Status
682 * DESCRIPTION: Executes _STA for selected device and stores results in
683 * *Flags.
685 * NOTE: Internal function, no parameter validation
687 ******************************************************************************/
689 acpi_status
690 acpi_ut_execute_sxds(struct acpi_namespace_node *device_node, u8 * highest)
692 union acpi_operand_object *obj_desc;
693 acpi_status status;
694 u32 i;
696 ACPI_FUNCTION_TRACE(ut_execute_sxds);
698 for (i = 0; i < 4; i++) {
699 highest[i] = 0xFF;
700 status = acpi_ut_evaluate_object(device_node,
701 ACPI_CAST_PTR(char,
702 acpi_gbl_highest_dstate_names
703 [i]),
704 ACPI_BTYPE_INTEGER, &obj_desc);
705 if (ACPI_FAILURE(status)) {
706 if (status != AE_NOT_FOUND) {
707 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
708 "%s on Device %4.4s, %s\n",
709 ACPI_CAST_PTR(char,
710 acpi_gbl_highest_dstate_names
711 [i]),
712 acpi_ut_get_node_name
713 (device_node),
714 acpi_format_exception
715 (status)));
717 return_ACPI_STATUS(status);
719 } else {
720 /* Extract the Dstate value */
722 highest[i] = (u8) obj_desc->integer.value;
724 /* Delete the return object */
726 acpi_ut_remove_reference(obj_desc);
730 return_ACPI_STATUS(AE_OK);