1 /******************************************************************************
3 * Module Name: uteval - Object evaluation
5 *****************************************************************************/
8 * Copyright (C) 2000 - 2004, R. Byron Moore
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
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.
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.
45 #include <acpi/acpi.h>
46 #include <acpi/acnamesp.h>
47 #include <acpi/acinterp.h>
50 #define _COMPONENT ACPI_UTILITIES
51 ACPI_MODULE_NAME ("uteval")
54 /*******************************************************************************
56 * FUNCTION: acpi_ut_osi_implementation
58 * PARAMETERS: walk_state - Current walk state
62 * DESCRIPTION: Implementation of _OSI predefined control method
63 * Supported = _OSI (String)
65 ******************************************************************************/
68 acpi_ut_osi_implementation (
69 struct acpi_walk_state *walk_state)
71 union acpi_operand_object *string_desc;
72 union acpi_operand_object *return_desc;
76 ACPI_FUNCTION_TRACE ("ut_osi_implementation");
79 /* Validate the string input argument */
81 string_desc = walk_state->arguments[0].object;
82 if (!string_desc || (string_desc->common.type != ACPI_TYPE_STRING)) {
83 return_ACPI_STATUS (AE_TYPE);
86 /* Create a return object (Default value = 0) */
88 return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
90 return_ACPI_STATUS (AE_NO_MEMORY);
93 /* Compare input string to table of supported strings */
95 for (i = 0; i < ACPI_NUM_OSI_STRINGS; i++) {
96 if (!ACPI_STRCMP (string_desc->string.pointer,
97 (char *) acpi_gbl_valid_osi_strings[i])) {
98 /* This string is supported */
100 return_desc->integer.value = 0xFFFFFFFF;
105 walk_state->return_desc = return_desc;
106 return_ACPI_STATUS (AE_CTRL_TERMINATE);
110 /*******************************************************************************
112 * FUNCTION: acpi_ut_evaluate_object
114 * PARAMETERS: prefix_node - Starting node
115 * Path - Path to object from starting node
116 * expected_return_types - Bitmap of allowed return types
117 * return_desc - Where a return value is stored
121 * DESCRIPTION: Evaluates a namespace object and verifies the type of the
122 * return object. Common code that simplifies accessing objects
123 * that have required return objects of fixed types.
125 * NOTE: Internal function, no parameter validation
127 ******************************************************************************/
130 acpi_ut_evaluate_object (
131 struct acpi_namespace_node *prefix_node,
133 u32 expected_return_btypes,
134 union acpi_operand_object **return_desc)
136 union acpi_operand_object *obj_desc;
141 ACPI_FUNCTION_TRACE ("ut_evaluate_object");
144 /* Evaluate the object/method */
146 status = acpi_ns_evaluate_relative (prefix_node, path, NULL, &obj_desc);
147 if (ACPI_FAILURE (status)) {
148 if (status == AE_NOT_FOUND) {
149 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s.%s] was not found\n",
150 acpi_ut_get_node_name (prefix_node), path));
153 ACPI_REPORT_METHOD_ERROR ("Method execution failed",
154 prefix_node, path, status);
157 return_ACPI_STATUS (status);
160 /* Did we get a return object? */
163 if (expected_return_btypes) {
164 ACPI_REPORT_METHOD_ERROR ("No object was returned from",
165 prefix_node, path, AE_NOT_EXIST);
167 return_ACPI_STATUS (AE_NOT_EXIST);
170 return_ACPI_STATUS (AE_OK);
173 /* Map the return object type to the bitmapped type */
175 switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
176 case ACPI_TYPE_INTEGER:
177 return_btype = ACPI_BTYPE_INTEGER;
180 case ACPI_TYPE_BUFFER:
181 return_btype = ACPI_BTYPE_BUFFER;
184 case ACPI_TYPE_STRING:
185 return_btype = ACPI_BTYPE_STRING;
188 case ACPI_TYPE_PACKAGE:
189 return_btype = ACPI_BTYPE_PACKAGE;
197 /* Is the return object one of the expected types? */
199 if (!(expected_return_btypes & return_btype)) {
200 ACPI_REPORT_METHOD_ERROR ("Return object type is incorrect",
201 prefix_node, path, AE_TYPE);
203 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
204 "Type returned from %s was incorrect: %X\n",
205 path, ACPI_GET_OBJECT_TYPE (obj_desc)));
207 /* On error exit, we must delete the return object */
209 acpi_ut_remove_reference (obj_desc);
210 return_ACPI_STATUS (AE_TYPE);
213 /* Object type is OK, return it */
215 *return_desc = obj_desc;
216 return_ACPI_STATUS (AE_OK);
220 /*******************************************************************************
222 * FUNCTION: acpi_ut_evaluate_numeric_object
224 * PARAMETERS: *object_name - Object name to be evaluated
225 * device_node - Node for the device
226 * *Address - Where the value is returned
230 * DESCRIPTION: Evaluates a numeric namespace object for a selected device
231 * and stores result in *Address.
233 * NOTE: Internal function, no parameter validation
235 ******************************************************************************/
238 acpi_ut_evaluate_numeric_object (
240 struct acpi_namespace_node *device_node,
241 acpi_integer *address)
243 union acpi_operand_object *obj_desc;
247 ACPI_FUNCTION_TRACE ("ut_evaluate_numeric_object");
250 status = acpi_ut_evaluate_object (device_node, object_name,
251 ACPI_BTYPE_INTEGER, &obj_desc);
252 if (ACPI_FAILURE (status)) {
253 return_ACPI_STATUS (status);
256 /* Get the returned Integer */
258 *address = obj_desc->integer.value;
260 /* On exit, we must delete the return object */
262 acpi_ut_remove_reference (obj_desc);
263 return_ACPI_STATUS (status);
267 /*******************************************************************************
269 * FUNCTION: acpi_ut_copy_id_string
271 * PARAMETERS: Destination - Where to copy the string
272 * Source - Source string
273 * max_length - Length of the destination buffer
277 * DESCRIPTION: Copies an ID string for the _HID, _CID, and _UID methods.
278 * Performs removal of a leading asterisk if present -- workaround
279 * for a known issue on a bunch of machines.
281 ******************************************************************************/
284 acpi_ut_copy_id_string (
287 acpi_size max_length)
292 * Workaround for ID strings that have a leading asterisk. This construct
293 * is not allowed by the ACPI specification (ID strings must be
294 * alphanumeric), but enough existing machines have this embedded in their
295 * ID strings that the following code is useful.
297 if (*source == '*') {
301 /* Do the actual copy */
303 ACPI_STRNCPY (destination, source, max_length);
307 /*******************************************************************************
309 * FUNCTION: acpi_ut_execute_HID
311 * PARAMETERS: device_node - Node for the device
312 * *Hid - Where the HID is returned
316 * DESCRIPTION: Executes the _HID control method that returns the hardware
319 * NOTE: Internal function, no parameter validation
321 ******************************************************************************/
324 acpi_ut_execute_HID (
325 struct acpi_namespace_node *device_node,
326 struct acpi_device_id *hid)
328 union acpi_operand_object *obj_desc;
332 ACPI_FUNCTION_TRACE ("ut_execute_HID");
335 status = acpi_ut_evaluate_object (device_node, METHOD_NAME__HID,
336 ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING, &obj_desc);
337 if (ACPI_FAILURE (status)) {
338 return_ACPI_STATUS (status);
341 if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) {
342 /* Convert the Numeric HID to string */
344 acpi_ex_eisa_id_to_string ((u32) obj_desc->integer.value, hid->value);
347 /* Copy the String HID from the returned object */
349 acpi_ut_copy_id_string (hid->value, obj_desc->string.pointer,
350 sizeof (hid->value));
353 /* On exit, we must delete the return object */
355 acpi_ut_remove_reference (obj_desc);
356 return_ACPI_STATUS (status);
360 /*******************************************************************************
362 * FUNCTION: acpi_ut_translate_one_cid
364 * PARAMETERS: obj_desc - _CID object, must be integer or string
365 * one_cid - Where the CID string is returned
369 * DESCRIPTION: Return a numeric or string _CID value as a string.
372 * NOTE: Assumes a maximum _CID string length of
373 * ACPI_MAX_CID_LENGTH.
375 ******************************************************************************/
378 acpi_ut_translate_one_cid (
379 union acpi_operand_object *obj_desc,
380 struct acpi_compatible_id *one_cid)
384 switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
385 case ACPI_TYPE_INTEGER:
387 /* Convert the Numeric CID to string */
389 acpi_ex_eisa_id_to_string ((u32) obj_desc->integer.value, one_cid->value);
392 case ACPI_TYPE_STRING:
394 if (obj_desc->string.length > ACPI_MAX_CID_LENGTH) {
395 return (AE_AML_STRING_LIMIT);
398 /* Copy the String CID from the returned object */
400 acpi_ut_copy_id_string (one_cid->value, obj_desc->string.pointer,
401 ACPI_MAX_CID_LENGTH);
411 /*******************************************************************************
413 * FUNCTION: acpi_ut_execute_CID
415 * PARAMETERS: device_node - Node for the device
416 * *Cid - Where the CID is returned
420 * DESCRIPTION: Executes the _CID control method that returns one or more
421 * compatible hardware IDs for the device.
423 * NOTE: Internal function, no parameter validation
425 ******************************************************************************/
428 acpi_ut_execute_CID (
429 struct acpi_namespace_node *device_node,
430 struct acpi_compatible_id_list **return_cid_list)
432 union acpi_operand_object *obj_desc;
436 struct acpi_compatible_id_list *cid_list;
440 ACPI_FUNCTION_TRACE ("ut_execute_CID");
443 /* Evaluate the _CID method for this device */
445 status = acpi_ut_evaluate_object (device_node, METHOD_NAME__CID,
446 ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING | ACPI_BTYPE_PACKAGE,
448 if (ACPI_FAILURE (status)) {
449 return_ACPI_STATUS (status);
452 /* Get the number of _CIDs returned */
455 if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_PACKAGE) {
456 count = obj_desc->package.count;
459 /* Allocate a worst-case buffer for the _CIDs */
461 size = (((count - 1) * sizeof (struct acpi_compatible_id)) +
462 sizeof (struct acpi_compatible_id_list));
464 cid_list = ACPI_MEM_CALLOCATE ((acpi_size) size);
466 return_ACPI_STATUS (AE_NO_MEMORY);
471 cid_list->count = count;
472 cid_list->size = size;
475 * A _CID can return either a single compatible ID or a package of compatible
476 * IDs. Each compatible ID can be one of the following:
477 * -- Number (32 bit compressed EISA ID) or
478 * -- String (PCI ID format, e.g. "PCI\VEN_vvvv&DEV_dddd&SUBSYS_ssssssss").
481 /* The _CID object can be either a single CID or a package (list) of CIDs */
483 if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_PACKAGE) {
484 /* Translate each package element */
486 for (i = 0; i < count; i++) {
487 status = acpi_ut_translate_one_cid (obj_desc->package.elements[i],
489 if (ACPI_FAILURE (status)) {
495 /* Only one CID, translate to a string */
497 status = acpi_ut_translate_one_cid (obj_desc, cid_list->id);
500 /* Cleanup on error */
502 if (ACPI_FAILURE (status)) {
503 ACPI_MEM_FREE (cid_list);
506 *return_cid_list = cid_list;
509 /* On exit, we must delete the _CID return object */
511 acpi_ut_remove_reference (obj_desc);
512 return_ACPI_STATUS (status);
516 /*******************************************************************************
518 * FUNCTION: acpi_ut_execute_UID
520 * PARAMETERS: device_node - Node for the device
521 * *Uid - Where the UID is returned
525 * DESCRIPTION: Executes the _UID control method that returns the hardware
528 * NOTE: Internal function, no parameter validation
530 ******************************************************************************/
533 acpi_ut_execute_UID (
534 struct acpi_namespace_node *device_node,
535 struct acpi_device_id *uid)
537 union acpi_operand_object *obj_desc;
541 ACPI_FUNCTION_TRACE ("ut_execute_UID");
544 status = acpi_ut_evaluate_object (device_node, METHOD_NAME__UID,
545 ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING, &obj_desc);
546 if (ACPI_FAILURE (status)) {
547 return_ACPI_STATUS (status);
550 if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) {
551 /* Convert the Numeric UID to string */
553 acpi_ex_unsigned_integer_to_string (obj_desc->integer.value, uid->value);
556 /* Copy the String UID from the returned object */
558 acpi_ut_copy_id_string (uid->value, obj_desc->string.pointer,
559 sizeof (uid->value));
562 /* On exit, we must delete the return object */
564 acpi_ut_remove_reference (obj_desc);
565 return_ACPI_STATUS (status);
569 /*******************************************************************************
571 * FUNCTION: acpi_ut_execute_STA
573 * PARAMETERS: device_node - Node for the device
574 * *Flags - Where the status flags are returned
578 * DESCRIPTION: Executes _STA for selected device and stores results in
581 * NOTE: Internal function, no parameter validation
583 ******************************************************************************/
586 acpi_ut_execute_STA (
587 struct acpi_namespace_node *device_node,
590 union acpi_operand_object *obj_desc;
594 ACPI_FUNCTION_TRACE ("ut_execute_STA");
597 status = acpi_ut_evaluate_object (device_node, METHOD_NAME__STA,
598 ACPI_BTYPE_INTEGER, &obj_desc);
599 if (ACPI_FAILURE (status)) {
600 if (AE_NOT_FOUND == status) {
601 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
602 "_STA on %4.4s was not found, assuming device is present\n",
603 acpi_ut_get_node_name (device_node)));
609 return_ACPI_STATUS (status);
612 /* Extract the status flags */
614 *flags = (u32) obj_desc->integer.value;
616 /* On exit, we must delete the return object */
618 acpi_ut_remove_reference (obj_desc);
619 return_ACPI_STATUS (status);
623 /*******************************************************************************
625 * FUNCTION: acpi_ut_execute_Sxds
627 * PARAMETERS: device_node - Node for the device
628 * *Flags - Where the status flags are returned
632 * DESCRIPTION: Executes _STA for selected device and stores results in
635 * NOTE: Internal function, no parameter validation
637 ******************************************************************************/
640 acpi_ut_execute_sxds (
641 struct acpi_namespace_node *device_node,
644 union acpi_operand_object *obj_desc;
649 ACPI_FUNCTION_TRACE ("ut_execute_Sxds");
652 for (i = 0; i < 4; i++) {
654 status = acpi_ut_evaluate_object (device_node,
655 (char *) acpi_gbl_highest_dstate_names[i],
656 ACPI_BTYPE_INTEGER, &obj_desc);
657 if (ACPI_FAILURE (status)) {
658 if (status != AE_NOT_FOUND) {
659 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
660 "%s on Device %4.4s, %s\n",
661 (char *) acpi_gbl_highest_dstate_names[i],
662 acpi_ut_get_node_name (device_node),
663 acpi_format_exception (status)));
665 return_ACPI_STATUS (status);
669 /* Extract the Dstate value */
671 highest[i] = (u8) obj_desc->integer.value;
673 /* Delete the return object */
675 acpi_ut_remove_reference (obj_desc);
679 return_ACPI_STATUS (AE_OK);