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