Merge branch 'topic/hda' into for-linus
[linux-2.6] / drivers / acpi / acpica / uteval.c
1 /******************************************************************************
2  *
3  * Module Name: uteval - Object evaluation
4  *
5  *****************************************************************************/
6
7 /*
8  * Copyright (C) 2000 - 2008, Intel Corp.
9  * 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
44 #include <acpi/acpi.h>
45 #include "accommon.h"
46 #include "acnamesp.h"
47 #include "acinterp.h"
48
49 #define _COMPONENT          ACPI_UTILITIES
50 ACPI_MODULE_NAME("uteval")
51
52 /* Local prototypes */
53 static void
54 acpi_ut_copy_id_string(char *destination, char *source, acpi_size max_length);
55
56 static acpi_status
57 acpi_ut_translate_one_cid(union acpi_operand_object *obj_desc,
58                           struct acpi_compatible_id *one_cid);
59
60 /*
61  * Strings supported by the _OSI predefined (internal) method.
62  *
63  * March 2009: Removed "Linux" as this host no longer wants to respond true
64  * for this string. Basically, the only safe OS strings are windows-related
65  * and in many or most cases represent the only test path within the
66  * BIOS-provided ASL code.
67  *
68  * The second element of each entry is used to track the newest version of
69  * Windows that the BIOS has requested.
70  */
71 static struct acpi_interface_info acpi_interfaces_supported[] = {
72         /* Operating System Vendor Strings */
73
74         {"Windows 2000", ACPI_OSI_WIN_2000},    /* Windows 2000 */
75         {"Windows 2001", ACPI_OSI_WIN_XP},      /* Windows XP */
76         {"Windows 2001 SP1", ACPI_OSI_WIN_XP_SP1},      /* Windows XP SP1 */
77         {"Windows 2001.1", ACPI_OSI_WINSRV_2003},       /* Windows Server 2003 */
78         {"Windows 2001 SP2", ACPI_OSI_WIN_XP_SP2},      /* Windows XP SP2 */
79         {"Windows 2001.1 SP1", ACPI_OSI_WINSRV_2003_SP1},       /* Windows Server 2003 SP1 - Added 03/2006 */
80         {"Windows 2006", ACPI_OSI_WIN_VISTA},   /* Windows Vista - Added 03/2006 */
81
82         /* Feature Group Strings */
83
84         {"Extended Address Space Descriptor", 0}
85
86         /*
87          * All "optional" feature group strings (features that are implemented
88          * by the host) should be implemented in the host version of
89          * acpi_os_validate_interface and should not be added here.
90          */
91 };
92
93 /*******************************************************************************
94  *
95  * FUNCTION:    acpi_ut_osi_implementation
96  *
97  * PARAMETERS:  walk_state          - Current walk state
98  *
99  * RETURN:      Status
100  *
101  * DESCRIPTION: Implementation of the _OSI predefined control method
102  *
103  ******************************************************************************/
104
105 acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state)
106 {
107         acpi_status status;
108         union acpi_operand_object *string_desc;
109         union acpi_operand_object *return_desc;
110         u32 return_value;
111         u32 i;
112
113         ACPI_FUNCTION_TRACE(ut_osi_implementation);
114
115         /* Validate the string input argument */
116
117         string_desc = walk_state->arguments[0].object;
118         if (!string_desc || (string_desc->common.type != ACPI_TYPE_STRING)) {
119                 return_ACPI_STATUS(AE_TYPE);
120         }
121
122         /* Create a return object */
123
124         return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
125         if (!return_desc) {
126                 return_ACPI_STATUS(AE_NO_MEMORY);
127         }
128
129         /* Default return value is 0, NOT SUPPORTED */
130
131         return_value = 0;
132
133         /* Compare input string to static table of supported interfaces */
134
135         for (i = 0; i < ACPI_ARRAY_LENGTH(acpi_interfaces_supported); i++) {
136                 if (!ACPI_STRCMP(string_desc->string.pointer,
137                                  acpi_interfaces_supported[i].name)) {
138                         /*
139                          * The interface is supported.
140                          * Update the osi_data if necessary. We keep track of the latest
141                          * version of Windows that has been requested by the BIOS.
142                          */
143                         if (acpi_interfaces_supported[i].value >
144                             acpi_gbl_osi_data) {
145                                 acpi_gbl_osi_data =
146                                     acpi_interfaces_supported[i].value;
147                         }
148
149                         return_value = ACPI_UINT32_MAX;
150                         goto exit;
151                 }
152         }
153
154         /*
155          * Did not match the string in the static table, call the host OSL to
156          * check for a match with one of the optional strings (such as
157          * "Module Device", "3.0 Thermal Model", etc.)
158          */
159         status = acpi_os_validate_interface(string_desc->string.pointer);
160         if (ACPI_SUCCESS(status)) {
161
162                 /* The interface is supported */
163
164                 return_value = ACPI_UINT32_MAX;
165         }
166
167 exit:
168         ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO,
169                 "ACPI: BIOS _OSI(%s) is %ssupported\n",
170                 string_desc->string.pointer, return_value == 0 ? "not " : ""));
171
172         /* Complete the return value */
173
174         return_desc->integer.value = return_value;
175         walk_state->return_desc = return_desc;
176         return_ACPI_STATUS (AE_OK);
177 }
178
179 /*******************************************************************************
180  *
181  * FUNCTION:    acpi_osi_invalidate
182  *
183  * PARAMETERS:  interface_string
184  *
185  * RETURN:      Status
186  *
187  * DESCRIPTION: invalidate string in pre-defiend _OSI string list
188  *
189  ******************************************************************************/
190
191 acpi_status acpi_osi_invalidate(char *interface)
192 {
193         int i;
194
195         for (i = 0; i < ACPI_ARRAY_LENGTH(acpi_interfaces_supported); i++) {
196                 if (!ACPI_STRCMP(interface, acpi_interfaces_supported[i].name)) {
197                         *acpi_interfaces_supported[i].name = '\0';
198                         return AE_OK;
199                 }
200         }
201         return AE_NOT_FOUND;
202 }
203
204 /*******************************************************************************
205  *
206  * FUNCTION:    acpi_ut_evaluate_object
207  *
208  * PARAMETERS:  prefix_node         - Starting node
209  *              Path                - Path to object from starting node
210  *              expected_return_types - Bitmap of allowed return types
211  *              return_desc         - Where a return value is stored
212  *
213  * RETURN:      Status
214  *
215  * DESCRIPTION: Evaluates a namespace object and verifies the type of the
216  *              return object.  Common code that simplifies accessing objects
217  *              that have required return objects of fixed types.
218  *
219  *              NOTE: Internal function, no parameter validation
220  *
221  ******************************************************************************/
222
223 acpi_status
224 acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node,
225                         char *path,
226                         u32 expected_return_btypes,
227                         union acpi_operand_object **return_desc)
228 {
229         struct acpi_evaluate_info *info;
230         acpi_status status;
231         u32 return_btype;
232
233         ACPI_FUNCTION_TRACE(ut_evaluate_object);
234
235         /* Allocate the evaluation information block */
236
237         info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
238         if (!info) {
239                 return_ACPI_STATUS(AE_NO_MEMORY);
240         }
241
242         info->prefix_node = prefix_node;
243         info->pathname = path;
244
245         /* Evaluate the object/method */
246
247         status = acpi_ns_evaluate(info);
248         if (ACPI_FAILURE(status)) {
249                 if (status == AE_NOT_FOUND) {
250                         ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
251                                           "[%4.4s.%s] was not found\n",
252                                           acpi_ut_get_node_name(prefix_node),
253                                           path));
254                 } else {
255                         ACPI_ERROR_METHOD("Method execution failed",
256                                           prefix_node, path, status);
257                 }
258
259                 goto cleanup;
260         }
261
262         /* Did we get a return object? */
263
264         if (!info->return_object) {
265                 if (expected_return_btypes) {
266                         ACPI_ERROR_METHOD("No object was returned from",
267                                           prefix_node, path, AE_NOT_EXIST);
268
269                         status = AE_NOT_EXIST;
270                 }
271
272                 goto cleanup;
273         }
274
275         /* Map the return object type to the bitmapped type */
276
277         switch ((info->return_object)->common.type) {
278         case ACPI_TYPE_INTEGER:
279                 return_btype = ACPI_BTYPE_INTEGER;
280                 break;
281
282         case ACPI_TYPE_BUFFER:
283                 return_btype = ACPI_BTYPE_BUFFER;
284                 break;
285
286         case ACPI_TYPE_STRING:
287                 return_btype = ACPI_BTYPE_STRING;
288                 break;
289
290         case ACPI_TYPE_PACKAGE:
291                 return_btype = ACPI_BTYPE_PACKAGE;
292                 break;
293
294         default:
295                 return_btype = 0;
296                 break;
297         }
298
299         if ((acpi_gbl_enable_interpreter_slack) && (!expected_return_btypes)) {
300                 /*
301                  * We received a return object, but one was not expected.  This can
302                  * happen frequently if the "implicit return" feature is enabled.
303                  * Just delete the return object and return AE_OK.
304                  */
305                 acpi_ut_remove_reference(info->return_object);
306                 goto cleanup;
307         }
308
309         /* Is the return object one of the expected types? */
310
311         if (!(expected_return_btypes & return_btype)) {
312                 ACPI_ERROR_METHOD("Return object type is incorrect",
313                                   prefix_node, path, AE_TYPE);
314
315                 ACPI_ERROR((AE_INFO,
316                             "Type returned from %s was incorrect: %s, expected Btypes: %X",
317                             path,
318                             acpi_ut_get_object_type_name(info->return_object),
319                             expected_return_btypes));
320
321                 /* On error exit, we must delete the return object */
322
323                 acpi_ut_remove_reference(info->return_object);
324                 status = AE_TYPE;
325                 goto cleanup;
326         }
327
328         /* Object type is OK, return it */
329
330         *return_desc = info->return_object;
331
332       cleanup:
333         ACPI_FREE(info);
334         return_ACPI_STATUS(status);
335 }
336
337 /*******************************************************************************
338  *
339  * FUNCTION:    acpi_ut_evaluate_numeric_object
340  *
341  * PARAMETERS:  object_name         - Object name to be evaluated
342  *              device_node         - Node for the device
343  *              Address             - Where the value is returned
344  *
345  * RETURN:      Status
346  *
347  * DESCRIPTION: Evaluates a numeric namespace object for a selected device
348  *              and stores result in *Address.
349  *
350  *              NOTE: Internal function, no parameter validation
351  *
352  ******************************************************************************/
353
354 acpi_status
355 acpi_ut_evaluate_numeric_object(char *object_name,
356                                 struct acpi_namespace_node *device_node,
357                                 acpi_integer * address)
358 {
359         union acpi_operand_object *obj_desc;
360         acpi_status status;
361
362         ACPI_FUNCTION_TRACE(ut_evaluate_numeric_object);
363
364         status = acpi_ut_evaluate_object(device_node, object_name,
365                                          ACPI_BTYPE_INTEGER, &obj_desc);
366         if (ACPI_FAILURE(status)) {
367                 return_ACPI_STATUS(status);
368         }
369
370         /* Get the returned Integer */
371
372         *address = obj_desc->integer.value;
373
374         /* On exit, we must delete the return object */
375
376         acpi_ut_remove_reference(obj_desc);
377         return_ACPI_STATUS(status);
378 }
379
380 /*******************************************************************************
381  *
382  * FUNCTION:    acpi_ut_copy_id_string
383  *
384  * PARAMETERS:  Destination         - Where to copy the string
385  *              Source              - Source string
386  *              max_length          - Length of the destination buffer
387  *
388  * RETURN:      None
389  *
390  * DESCRIPTION: Copies an ID string for the _HID, _CID, and _UID methods.
391  *              Performs removal of a leading asterisk if present -- workaround
392  *              for a known issue on a bunch of machines.
393  *
394  ******************************************************************************/
395
396 static void
397 acpi_ut_copy_id_string(char *destination, char *source, acpi_size max_length)
398 {
399
400         /*
401          * Workaround for ID strings that have a leading asterisk. This construct
402          * is not allowed by the ACPI specification  (ID strings must be
403          * alphanumeric), but enough existing machines have this embedded in their
404          * ID strings that the following code is useful.
405          */
406         if (*source == '*') {
407                 source++;
408         }
409
410         /* Do the actual copy */
411
412         ACPI_STRNCPY(destination, source, max_length);
413 }
414
415 /*******************************************************************************
416  *
417  * FUNCTION:    acpi_ut_execute_HID
418  *
419  * PARAMETERS:  device_node         - Node for the device
420  *              Hid                 - Where the HID is returned
421  *
422  * RETURN:      Status
423  *
424  * DESCRIPTION: Executes the _HID control method that returns the hardware
425  *              ID of the device.
426  *
427  *              NOTE: Internal function, no parameter validation
428  *
429  ******************************************************************************/
430
431 acpi_status
432 acpi_ut_execute_HID(struct acpi_namespace_node *device_node,
433                     struct acpica_device_id *hid)
434 {
435         union acpi_operand_object *obj_desc;
436         acpi_status status;
437
438         ACPI_FUNCTION_TRACE(ut_execute_HID);
439
440         status = acpi_ut_evaluate_object(device_node, METHOD_NAME__HID,
441                                          ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING,
442                                          &obj_desc);
443         if (ACPI_FAILURE(status)) {
444                 return_ACPI_STATUS(status);
445         }
446
447         if (obj_desc->common.type == ACPI_TYPE_INTEGER) {
448
449                 /* Convert the Numeric HID to string */
450
451                 acpi_ex_eisa_id_to_string((u32) obj_desc->integer.value,
452                                           hid->value);
453         } else {
454                 /* Copy the String HID from the returned object */
455
456                 acpi_ut_copy_id_string(hid->value, obj_desc->string.pointer,
457                                        sizeof(hid->value));
458         }
459
460         /* On exit, we must delete the return object */
461
462         acpi_ut_remove_reference(obj_desc);
463         return_ACPI_STATUS(status);
464 }
465
466 /*******************************************************************************
467  *
468  * FUNCTION:    acpi_ut_translate_one_cid
469  *
470  * PARAMETERS:  obj_desc            - _CID object, must be integer or string
471  *              one_cid             - Where the CID string is returned
472  *
473  * RETURN:      Status
474  *
475  * DESCRIPTION: Return a numeric or string _CID value as a string.
476  *              (Compatible ID)
477  *
478  *              NOTE:  Assumes a maximum _CID string length of
479  *                     ACPI_MAX_CID_LENGTH.
480  *
481  ******************************************************************************/
482
483 static acpi_status
484 acpi_ut_translate_one_cid(union acpi_operand_object *obj_desc,
485                           struct acpi_compatible_id *one_cid)
486 {
487
488         switch (obj_desc->common.type) {
489         case ACPI_TYPE_INTEGER:
490
491                 /* Convert the Numeric CID to string */
492
493                 acpi_ex_eisa_id_to_string((u32) obj_desc->integer.value,
494                                           one_cid->value);
495                 return (AE_OK);
496
497         case ACPI_TYPE_STRING:
498
499                 if (obj_desc->string.length > ACPI_MAX_CID_LENGTH) {
500                         return (AE_AML_STRING_LIMIT);
501                 }
502
503                 /* Copy the String CID from the returned object */
504
505                 acpi_ut_copy_id_string(one_cid->value, obj_desc->string.pointer,
506                                        ACPI_MAX_CID_LENGTH);
507                 return (AE_OK);
508
509         default:
510
511                 return (AE_TYPE);
512         }
513 }
514
515 /*******************************************************************************
516  *
517  * FUNCTION:    acpi_ut_execute_CID
518  *
519  * PARAMETERS:  device_node         - Node for the device
520  *              return_cid_list     - Where the CID list is returned
521  *
522  * RETURN:      Status
523  *
524  * DESCRIPTION: Executes the _CID control method that returns one or more
525  *              compatible hardware IDs for the device.
526  *
527  *              NOTE: Internal function, no parameter validation
528  *
529  ******************************************************************************/
530
531 acpi_status
532 acpi_ut_execute_CID(struct acpi_namespace_node * device_node,
533                     struct acpi_compatible_id_list ** return_cid_list)
534 {
535         union acpi_operand_object *obj_desc;
536         acpi_status status;
537         u32 count;
538         u32 size;
539         struct acpi_compatible_id_list *cid_list;
540         u32 i;
541
542         ACPI_FUNCTION_TRACE(ut_execute_CID);
543
544         /* Evaluate the _CID method for this device */
545
546         status = acpi_ut_evaluate_object(device_node, METHOD_NAME__CID,
547                                          ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING
548                                          | ACPI_BTYPE_PACKAGE, &obj_desc);
549         if (ACPI_FAILURE(status)) {
550                 return_ACPI_STATUS(status);
551         }
552
553         /* Get the number of _CIDs returned */
554
555         count = 1;
556         if (obj_desc->common.type == ACPI_TYPE_PACKAGE) {
557                 count = obj_desc->package.count;
558         }
559
560         /* Allocate a worst-case buffer for the _CIDs */
561
562         size = (((count - 1) * sizeof(struct acpi_compatible_id)) +
563                 sizeof(struct acpi_compatible_id_list));
564
565         cid_list = ACPI_ALLOCATE_ZEROED((acpi_size) size);
566         if (!cid_list) {
567                 return_ACPI_STATUS(AE_NO_MEMORY);
568         }
569
570         /* Init CID list */
571
572         cid_list->count = count;
573         cid_list->size = size;
574
575         /*
576          *  A _CID can return either a single compatible ID or a package of
577          *  compatible IDs.  Each compatible ID can be one of the following:
578          *  1) Integer (32 bit compressed EISA ID) or
579          *  2) String (PCI ID format, e.g. "PCI\VEN_vvvv&DEV_dddd&SUBSYS_ssssssss")
580          */
581
582         /* The _CID object can be either a single CID or a package (list) of CIDs */
583
584         if (obj_desc->common.type == ACPI_TYPE_PACKAGE) {
585
586                 /* Translate each package element */
587
588                 for (i = 0; i < count; i++) {
589                         status =
590                             acpi_ut_translate_one_cid(obj_desc->package.
591                                                       elements[i],
592                                                       &cid_list->id[i]);
593                         if (ACPI_FAILURE(status)) {
594                                 break;
595                         }
596                 }
597         } else {
598                 /* Only one CID, translate to a string */
599
600                 status = acpi_ut_translate_one_cid(obj_desc, cid_list->id);
601         }
602
603         /* Cleanup on error */
604
605         if (ACPI_FAILURE(status)) {
606                 ACPI_FREE(cid_list);
607         } else {
608                 *return_cid_list = cid_list;
609         }
610
611         /* On exit, we must delete the _CID return object */
612
613         acpi_ut_remove_reference(obj_desc);
614         return_ACPI_STATUS(status);
615 }
616
617 /*******************************************************************************
618  *
619  * FUNCTION:    acpi_ut_execute_UID
620  *
621  * PARAMETERS:  device_node         - Node for the device
622  *              Uid                 - Where the UID is returned
623  *
624  * RETURN:      Status
625  *
626  * DESCRIPTION: Executes the _UID control method that returns the hardware
627  *              ID of the device.
628  *
629  *              NOTE: Internal function, no parameter validation
630  *
631  ******************************************************************************/
632
633 acpi_status
634 acpi_ut_execute_UID(struct acpi_namespace_node *device_node,
635                     struct acpica_device_id *uid)
636 {
637         union acpi_operand_object *obj_desc;
638         acpi_status status;
639
640         ACPI_FUNCTION_TRACE(ut_execute_UID);
641
642         status = acpi_ut_evaluate_object(device_node, METHOD_NAME__UID,
643                                          ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING,
644                                          &obj_desc);
645         if (ACPI_FAILURE(status)) {
646                 return_ACPI_STATUS(status);
647         }
648
649         if (obj_desc->common.type == ACPI_TYPE_INTEGER) {
650
651                 /* Convert the Numeric UID to string */
652
653                 acpi_ex_unsigned_integer_to_string(obj_desc->integer.value,
654                                                    uid->value);
655         } else {
656                 /* Copy the String UID from the returned object */
657
658                 acpi_ut_copy_id_string(uid->value, obj_desc->string.pointer,
659                                        sizeof(uid->value));
660         }
661
662         /* On exit, we must delete the return object */
663
664         acpi_ut_remove_reference(obj_desc);
665         return_ACPI_STATUS(status);
666 }
667
668 /*******************************************************************************
669  *
670  * FUNCTION:    acpi_ut_execute_STA
671  *
672  * PARAMETERS:  device_node         - Node for the device
673  *              Flags               - Where the status flags are returned
674  *
675  * RETURN:      Status
676  *
677  * DESCRIPTION: Executes _STA for selected device and stores results in
678  *              *Flags.
679  *
680  *              NOTE: Internal function, no parameter validation
681  *
682  ******************************************************************************/
683
684 acpi_status
685 acpi_ut_execute_STA(struct acpi_namespace_node *device_node, u32 * flags)
686 {
687         union acpi_operand_object *obj_desc;
688         acpi_status status;
689
690         ACPI_FUNCTION_TRACE(ut_execute_STA);
691
692         status = acpi_ut_evaluate_object(device_node, METHOD_NAME__STA,
693                                          ACPI_BTYPE_INTEGER, &obj_desc);
694         if (ACPI_FAILURE(status)) {
695                 if (AE_NOT_FOUND == status) {
696                         ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
697                                           "_STA on %4.4s was not found, assuming device is present\n",
698                                           acpi_ut_get_node_name(device_node)));
699
700                         *flags = ACPI_UINT32_MAX;
701                         status = AE_OK;
702                 }
703
704                 return_ACPI_STATUS(status);
705         }
706
707         /* Extract the status flags */
708
709         *flags = (u32) obj_desc->integer.value;
710
711         /* On exit, we must delete the return object */
712
713         acpi_ut_remove_reference(obj_desc);
714         return_ACPI_STATUS(status);
715 }
716
717 /*******************************************************************************
718  *
719  * FUNCTION:    acpi_ut_execute_Sxds
720  *
721  * PARAMETERS:  device_node         - Node for the device
722  *              Flags               - Where the status flags are returned
723  *
724  * RETURN:      Status
725  *
726  * DESCRIPTION: Executes _STA for selected device and stores results in
727  *              *Flags.
728  *
729  *              NOTE: Internal function, no parameter validation
730  *
731  ******************************************************************************/
732
733 acpi_status
734 acpi_ut_execute_sxds(struct acpi_namespace_node *device_node, u8 * highest)
735 {
736         union acpi_operand_object *obj_desc;
737         acpi_status status;
738         u32 i;
739
740         ACPI_FUNCTION_TRACE(ut_execute_sxds);
741
742         for (i = 0; i < 4; i++) {
743                 highest[i] = 0xFF;
744                 status = acpi_ut_evaluate_object(device_node,
745                                                  ACPI_CAST_PTR(char,
746                                                                acpi_gbl_highest_dstate_names
747                                                                [i]),
748                                                  ACPI_BTYPE_INTEGER, &obj_desc);
749                 if (ACPI_FAILURE(status)) {
750                         if (status != AE_NOT_FOUND) {
751                                 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
752                                                   "%s on Device %4.4s, %s\n",
753                                                   ACPI_CAST_PTR(char,
754                                                                 acpi_gbl_highest_dstate_names
755                                                                 [i]),
756                                                   acpi_ut_get_node_name
757                                                   (device_node),
758                                                   acpi_format_exception
759                                                   (status)));
760
761                                 return_ACPI_STATUS(status);
762                         }
763                 } else {
764                         /* Extract the Dstate value */
765
766                         highest[i] = (u8) obj_desc->integer.value;
767
768                         /* Delete the return object */
769
770                         acpi_ut_remove_reference(obj_desc);
771                 }
772         }
773
774         return_ACPI_STATUS(AE_OK);
775 }