Linux-2.6.12-rc2
[linux-flexiantxendom0-natty.git] / drivers / acpi / utilities / uteval.c
1 /******************************************************************************
2  *
3  * Module Name: uteval - Object evaluation
4  *
5  *****************************************************************************/
6
7 /*
8  * Copyright (C) 2000 - 2005, R. Byron Moore
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
45 #include <acpi/acpi.h>
46 #include <acpi/acnamesp.h>
47 #include <acpi/acinterp.h>
48
49
50 #define _COMPONENT          ACPI_UTILITIES
51          ACPI_MODULE_NAME    ("uteval")
52
53
54 /*******************************************************************************
55  *
56  * FUNCTION:    acpi_ut_osi_implementation
57  *
58  * PARAMETERS:  walk_state          - Current walk state
59  *
60  * RETURN:      Status
61  *
62  * DESCRIPTION: Implementation of _OSI predefined control method
63  *              Supported = _OSI (String)
64  *
65  ******************************************************************************/
66
67 acpi_status
68 acpi_ut_osi_implementation (
69         struct acpi_walk_state          *walk_state)
70 {
71         union acpi_operand_object       *string_desc;
72         union acpi_operand_object       *return_desc;
73         acpi_native_uint                i;
74
75
76         ACPI_FUNCTION_TRACE ("ut_osi_implementation");
77
78
79         /* Validate the string input argument */
80
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);
84         }
85
86         /* Create a return object (Default value = 0) */
87
88         return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
89         if (!return_desc) {
90                 return_ACPI_STATUS (AE_NO_MEMORY);
91         }
92
93         /* Compare input string to table of supported strings */
94
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 */
99
100                         return_desc->integer.value = 0xFFFFFFFF;
101                         break;
102                 }
103         }
104
105         walk_state->return_desc = return_desc;
106         return_ACPI_STATUS (AE_CTRL_TERMINATE);
107 }
108
109
110 /*******************************************************************************
111  *
112  * FUNCTION:    acpi_ut_evaluate_object
113  *
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
118  *
119  * RETURN:      Status
120  *
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.
124  *
125  *              NOTE: Internal function, no parameter validation
126  *
127  ******************************************************************************/
128
129 acpi_status
130 acpi_ut_evaluate_object (
131         struct acpi_namespace_node      *prefix_node,
132         char                            *path,
133         u32                             expected_return_btypes,
134         union acpi_operand_object       **return_desc)
135 {
136         struct acpi_parameter_info      info;
137         acpi_status                     status;
138         u32                             return_btype;
139
140
141         ACPI_FUNCTION_TRACE ("ut_evaluate_object");
142
143
144         info.node = prefix_node;
145         info.parameters = NULL;
146         info.parameter_type = ACPI_PARAM_ARGS;
147
148         /* Evaluate the object/method */
149
150         status = acpi_ns_evaluate_relative (path, &info);
151         if (ACPI_FAILURE (status)) {
152                 if (status == AE_NOT_FOUND) {
153                         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s.%s] was not found\n",
154                                 acpi_ut_get_node_name (prefix_node), path));
155                 }
156                 else {
157                         ACPI_REPORT_METHOD_ERROR ("Method execution failed",
158                                 prefix_node, path, status);
159                 }
160
161                 return_ACPI_STATUS (status);
162         }
163
164         /* Did we get a return object? */
165
166         if (!info.return_object) {
167                 if (expected_return_btypes) {
168                         ACPI_REPORT_METHOD_ERROR ("No object was returned from",
169                                 prefix_node, path, AE_NOT_EXIST);
170
171                         return_ACPI_STATUS (AE_NOT_EXIST);
172                 }
173
174                 return_ACPI_STATUS (AE_OK);
175         }
176
177         /* Map the return object type to the bitmapped type */
178
179         switch (ACPI_GET_OBJECT_TYPE (info.return_object)) {
180         case ACPI_TYPE_INTEGER:
181                 return_btype = ACPI_BTYPE_INTEGER;
182                 break;
183
184         case ACPI_TYPE_BUFFER:
185                 return_btype = ACPI_BTYPE_BUFFER;
186                 break;
187
188         case ACPI_TYPE_STRING:
189                 return_btype = ACPI_BTYPE_STRING;
190                 break;
191
192         case ACPI_TYPE_PACKAGE:
193                 return_btype = ACPI_BTYPE_PACKAGE;
194                 break;
195
196         default:
197                 return_btype = 0;
198                 break;
199         }
200
201         if ((acpi_gbl_enable_interpreter_slack) &&
202                 (!expected_return_btypes)) {
203                 /*
204                  * We received a return object, but one was not expected.  This can
205                  * happen frequently if the "implicit return" feature is enabled.
206                  * Just delete the return object and return AE_OK.
207                  */
208                 acpi_ut_remove_reference (info.return_object);
209                 return_ACPI_STATUS (AE_OK);
210         }
211
212         /* Is the return object one of the expected types? */
213
214         if (!(expected_return_btypes & return_btype)) {
215                 ACPI_REPORT_METHOD_ERROR ("Return object type is incorrect",
216                         prefix_node, path, AE_TYPE);
217
218                 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
219                         "Type returned from %s was incorrect: %s, expected Btypes: %X\n",
220                         path, acpi_ut_get_object_type_name (info.return_object),
221                         expected_return_btypes));
222
223                 /* On error exit, we must delete the return object */
224
225                 acpi_ut_remove_reference (info.return_object);
226                 return_ACPI_STATUS (AE_TYPE);
227         }
228
229         /* Object type is OK, return it */
230
231         *return_desc = info.return_object;
232         return_ACPI_STATUS (AE_OK);
233 }
234
235
236 /*******************************************************************************
237  *
238  * FUNCTION:    acpi_ut_evaluate_numeric_object
239  *
240  * PARAMETERS:  *object_name        - Object name to be evaluated
241  *              device_node         - Node for the device
242  *              *Address            - Where the value is returned
243  *
244  * RETURN:      Status
245  *
246  * DESCRIPTION: Evaluates a numeric namespace object for a selected device
247  *              and stores result in *Address.
248  *
249  *              NOTE: Internal function, no parameter validation
250  *
251  ******************************************************************************/
252
253 acpi_status
254 acpi_ut_evaluate_numeric_object (
255         char                            *object_name,
256         struct acpi_namespace_node      *device_node,
257         acpi_integer                    *address)
258 {
259         union acpi_operand_object       *obj_desc;
260         acpi_status                     status;
261
262
263         ACPI_FUNCTION_TRACE ("ut_evaluate_numeric_object");
264
265
266         status = acpi_ut_evaluate_object (device_node, object_name,
267                          ACPI_BTYPE_INTEGER, &obj_desc);
268         if (ACPI_FAILURE (status)) {
269                 return_ACPI_STATUS (status);
270         }
271
272         /* Get the returned Integer */
273
274         *address = obj_desc->integer.value;
275
276         /* On exit, we must delete the return object */
277
278         acpi_ut_remove_reference (obj_desc);
279         return_ACPI_STATUS (status);
280 }
281
282
283 /*******************************************************************************
284  *
285  * FUNCTION:    acpi_ut_copy_id_string
286  *
287  * PARAMETERS:  Destination         - Where to copy the string
288  *              Source              - Source string
289  *              max_length          - Length of the destination buffer
290  *
291  * RETURN:      None
292  *
293  * DESCRIPTION: Copies an ID string for the _HID, _CID, and _UID methods.
294  *              Performs removal of a leading asterisk if present -- workaround
295  *              for a known issue on a bunch of machines.
296  *
297  ******************************************************************************/
298
299 static void
300 acpi_ut_copy_id_string (
301         char                            *destination,
302         char                            *source,
303         acpi_size                       max_length)
304 {
305
306
307         /*
308          * Workaround for ID strings that have a leading asterisk. This construct
309          * is not allowed by the ACPI specification  (ID strings must be
310          * alphanumeric), but enough existing machines have this embedded in their
311          * ID strings that the following code is useful.
312          */
313         if (*source == '*') {
314                 source++;
315         }
316
317         /* Do the actual copy */
318
319         ACPI_STRNCPY (destination, source, max_length);
320 }
321
322
323 /*******************************************************************************
324  *
325  * FUNCTION:    acpi_ut_execute_HID
326  *
327  * PARAMETERS:  device_node         - Node for the device
328  *              *Hid                - Where the HID is returned
329  *
330  * RETURN:      Status
331  *
332  * DESCRIPTION: Executes the _HID control method that returns the hardware
333  *              ID of the device.
334  *
335  *              NOTE: Internal function, no parameter validation
336  *
337  ******************************************************************************/
338
339 acpi_status
340 acpi_ut_execute_HID (
341         struct acpi_namespace_node      *device_node,
342         struct acpi_device_id           *hid)
343 {
344         union acpi_operand_object       *obj_desc;
345         acpi_status                     status;
346
347
348         ACPI_FUNCTION_TRACE ("ut_execute_HID");
349
350
351         status = acpi_ut_evaluate_object (device_node, METHOD_NAME__HID,
352                          ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING, &obj_desc);
353         if (ACPI_FAILURE (status)) {
354                 return_ACPI_STATUS (status);
355         }
356
357         if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) {
358                 /* Convert the Numeric HID to string */
359
360                 acpi_ex_eisa_id_to_string ((u32) obj_desc->integer.value, hid->value);
361         }
362         else {
363                 /* Copy the String HID from the returned object */
364
365                 acpi_ut_copy_id_string (hid->value, obj_desc->string.pointer,
366                                 sizeof (hid->value));
367         }
368
369         /* On exit, we must delete the return object */
370
371         acpi_ut_remove_reference (obj_desc);
372         return_ACPI_STATUS (status);
373 }
374
375
376 /*******************************************************************************
377  *
378  * FUNCTION:    acpi_ut_translate_one_cid
379  *
380  * PARAMETERS:  obj_desc            - _CID object, must be integer or string
381  *              one_cid             - Where the CID string is returned
382  *
383  * RETURN:      Status
384  *
385  * DESCRIPTION: Return a numeric or string _CID value as a string.
386  *              (Compatible ID)
387  *
388  *              NOTE:  Assumes a maximum _CID string length of
389  *                     ACPI_MAX_CID_LENGTH.
390  *
391  ******************************************************************************/
392
393 static acpi_status
394 acpi_ut_translate_one_cid (
395         union acpi_operand_object       *obj_desc,
396         struct acpi_compatible_id       *one_cid)
397 {
398
399
400         switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
401         case ACPI_TYPE_INTEGER:
402
403                 /* Convert the Numeric CID to string */
404
405                 acpi_ex_eisa_id_to_string ((u32) obj_desc->integer.value, one_cid->value);
406                 return (AE_OK);
407
408         case ACPI_TYPE_STRING:
409
410                 if (obj_desc->string.length > ACPI_MAX_CID_LENGTH) {
411                         return (AE_AML_STRING_LIMIT);
412                 }
413
414                 /* Copy the String CID from the returned object */
415
416                 acpi_ut_copy_id_string (one_cid->value, obj_desc->string.pointer,
417                                 ACPI_MAX_CID_LENGTH);
418                 return (AE_OK);
419
420         default:
421
422                 return (AE_TYPE);
423         }
424 }
425
426
427 /*******************************************************************************
428  *
429  * FUNCTION:    acpi_ut_execute_CID
430  *
431  * PARAMETERS:  device_node         - Node for the device
432  *              *Cid                - Where the CID is returned
433  *
434  * RETURN:      Status
435  *
436  * DESCRIPTION: Executes the _CID control method that returns one or more
437  *              compatible hardware IDs for the device.
438  *
439  *              NOTE: Internal function, no parameter validation
440  *
441  ******************************************************************************/
442
443 acpi_status
444 acpi_ut_execute_CID (
445         struct acpi_namespace_node      *device_node,
446         struct acpi_compatible_id_list **return_cid_list)
447 {
448         union acpi_operand_object       *obj_desc;
449         acpi_status                     status;
450         u32                             count;
451         u32                             size;
452         struct acpi_compatible_id_list *cid_list;
453         acpi_native_uint                i;
454
455
456         ACPI_FUNCTION_TRACE ("ut_execute_CID");
457
458
459         /* Evaluate the _CID method for this device */
460
461         status = acpi_ut_evaluate_object (device_node, METHOD_NAME__CID,
462                          ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING | ACPI_BTYPE_PACKAGE,
463                          &obj_desc);
464         if (ACPI_FAILURE (status)) {
465                 return_ACPI_STATUS (status);
466         }
467
468         /* Get the number of _CIDs returned */
469
470         count = 1;
471         if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_PACKAGE) {
472                 count = obj_desc->package.count;
473         }
474
475         /* Allocate a worst-case buffer for the _CIDs */
476
477         size = (((count - 1) * sizeof (struct acpi_compatible_id)) +
478                            sizeof (struct acpi_compatible_id_list));
479
480         cid_list = ACPI_MEM_CALLOCATE ((acpi_size) size);
481         if (!cid_list) {
482                 return_ACPI_STATUS (AE_NO_MEMORY);
483         }
484
485         /* Init CID list */
486
487         cid_list->count = count;
488         cid_list->size = size;
489
490         /*
491          *  A _CID can return either a single compatible ID or a package of compatible
492          *  IDs.  Each compatible ID can be one of the following:
493          *  -- Number (32 bit compressed EISA ID) or
494          *  -- String (PCI ID format, e.g. "PCI\VEN_vvvv&DEV_dddd&SUBSYS_ssssssss").
495          */
496
497         /* The _CID object can be either a single CID or a package (list) of CIDs */
498
499         if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_PACKAGE) {
500                 /* Translate each package element */
501
502                 for (i = 0; i < count; i++) {
503                         status = acpi_ut_translate_one_cid (obj_desc->package.elements[i],
504                                           &cid_list->id[i]);
505                         if (ACPI_FAILURE (status)) {
506                                 break;
507                         }
508                 }
509         }
510         else {
511                 /* Only one CID, translate to a string */
512
513                 status = acpi_ut_translate_one_cid (obj_desc, cid_list->id);
514         }
515
516         /* Cleanup on error */
517
518         if (ACPI_FAILURE (status)) {
519                 ACPI_MEM_FREE (cid_list);
520         }
521         else {
522                 *return_cid_list = cid_list;
523         }
524
525         /* On exit, we must delete the _CID return object */
526
527         acpi_ut_remove_reference (obj_desc);
528         return_ACPI_STATUS (status);
529 }
530
531
532 /*******************************************************************************
533  *
534  * FUNCTION:    acpi_ut_execute_UID
535  *
536  * PARAMETERS:  device_node         - Node for the device
537  *              *Uid                - Where the UID is returned
538  *
539  * RETURN:      Status
540  *
541  * DESCRIPTION: Executes the _UID control method that returns the hardware
542  *              ID of the device.
543  *
544  *              NOTE: Internal function, no parameter validation
545  *
546  ******************************************************************************/
547
548 acpi_status
549 acpi_ut_execute_UID (
550         struct acpi_namespace_node      *device_node,
551         struct acpi_device_id           *uid)
552 {
553         union acpi_operand_object       *obj_desc;
554         acpi_status                     status;
555
556
557         ACPI_FUNCTION_TRACE ("ut_execute_UID");
558
559
560         status = acpi_ut_evaluate_object (device_node, METHOD_NAME__UID,
561                          ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING, &obj_desc);
562         if (ACPI_FAILURE (status)) {
563                 return_ACPI_STATUS (status);
564         }
565
566         if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) {
567                 /* Convert the Numeric UID to string */
568
569                 acpi_ex_unsigned_integer_to_string (obj_desc->integer.value, uid->value);
570         }
571         else {
572                 /* Copy the String UID from the returned object */
573
574                 acpi_ut_copy_id_string (uid->value, obj_desc->string.pointer,
575                                 sizeof (uid->value));
576         }
577
578         /* On exit, we must delete the return object */
579
580         acpi_ut_remove_reference (obj_desc);
581         return_ACPI_STATUS (status);
582 }
583
584
585 /*******************************************************************************
586  *
587  * FUNCTION:    acpi_ut_execute_STA
588  *
589  * PARAMETERS:  device_node         - Node for the device
590  *              *Flags              - Where the status flags are returned
591  *
592  * RETURN:      Status
593  *
594  * DESCRIPTION: Executes _STA for selected device and stores results in
595  *              *Flags.
596  *
597  *              NOTE: Internal function, no parameter validation
598  *
599  ******************************************************************************/
600
601 acpi_status
602 acpi_ut_execute_STA (
603         struct acpi_namespace_node      *device_node,
604         u32                             *flags)
605 {
606         union acpi_operand_object       *obj_desc;
607         acpi_status                     status;
608
609
610         ACPI_FUNCTION_TRACE ("ut_execute_STA");
611
612
613         status = acpi_ut_evaluate_object (device_node, METHOD_NAME__STA,
614                          ACPI_BTYPE_INTEGER, &obj_desc);
615         if (ACPI_FAILURE (status)) {
616                 if (AE_NOT_FOUND == status) {
617                         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
618                                 "_STA on %4.4s was not found, assuming device is present\n",
619                                 acpi_ut_get_node_name (device_node)));
620
621                         *flags = 0x0F;
622                         status = AE_OK;
623                 }
624
625                 return_ACPI_STATUS (status);
626         }
627
628         /* Extract the status flags */
629
630         *flags = (u32) obj_desc->integer.value;
631
632         /* On exit, we must delete the return object */
633
634         acpi_ut_remove_reference (obj_desc);
635         return_ACPI_STATUS (status);
636 }
637
638
639 /*******************************************************************************
640  *
641  * FUNCTION:    acpi_ut_execute_Sxds
642  *
643  * PARAMETERS:  device_node         - Node for the device
644  *              *Flags              - Where the status flags are returned
645  *
646  * RETURN:      Status
647  *
648  * DESCRIPTION: Executes _STA for selected device and stores results in
649  *              *Flags.
650  *
651  *              NOTE: Internal function, no parameter validation
652  *
653  ******************************************************************************/
654
655 acpi_status
656 acpi_ut_execute_sxds (
657         struct acpi_namespace_node      *device_node,
658         u8                              *highest)
659 {
660         union acpi_operand_object       *obj_desc;
661         acpi_status                     status;
662         u32                             i;
663
664
665         ACPI_FUNCTION_TRACE ("ut_execute_Sxds");
666
667
668         for (i = 0; i < 4; i++) {
669                 highest[i] = 0xFF;
670                 status = acpi_ut_evaluate_object (device_node,
671                                  (char *) acpi_gbl_highest_dstate_names[i],
672                                  ACPI_BTYPE_INTEGER, &obj_desc);
673                 if (ACPI_FAILURE (status)) {
674                         if (status != AE_NOT_FOUND) {
675                                 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
676                                         "%s on Device %4.4s, %s\n",
677                                         (char *) acpi_gbl_highest_dstate_names[i],
678                                         acpi_ut_get_node_name (device_node),
679                                         acpi_format_exception (status)));
680
681                                 return_ACPI_STATUS (status);
682                         }
683                 }
684                 else {
685                         /* Extract the Dstate value */
686
687                         highest[i] = (u8) obj_desc->integer.value;
688
689                         /* Delete the return object */
690
691                         acpi_ut_remove_reference (obj_desc);
692                 }
693         }
694
695         return_ACPI_STATUS (AE_OK);
696 }