Bring in acpica-unix-20031203. As with other contrib imports, this import
[dragonfly.git] / sys / contrib / dev / acpica-unix-20031203 / utilities / uteval.c
1 /******************************************************************************
2  *
3  * Module Name: uteval - Object evaluation
4  *              $Revision: 49 $
5  *
6  *****************************************************************************/
7
8 /******************************************************************************
9  *
10  * 1. Copyright Notice
11  *
12  * Some or all of this work - Copyright (c) 1999 - 2003, Intel Corp.
13  * All rights reserved.
14  *
15  * 2. License
16  *
17  * 2.1. This is your license from Intel Corp. under its intellectual property
18  * rights.  You may have additional license terms from the party that provided
19  * you this software, covering your right to use that party's intellectual
20  * property rights.
21  *
22  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
23  * copy of the source code appearing in this file ("Covered Code") an
24  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
25  * base code distributed originally by Intel ("Original Intel Code") to copy,
26  * make derivatives, distribute, use and display any portion of the Covered
27  * Code in any form, with the right to sublicense such rights; and
28  *
29  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
30  * license (with the right to sublicense), under only those claims of Intel
31  * patents that are infringed by the Original Intel Code, to make, use, sell,
32  * offer to sell, and import the Covered Code and derivative works thereof
33  * solely to the minimum extent necessary to exercise the above copyright
34  * license, and in no event shall the patent license extend to any additions
35  * to or modifications of the Original Intel Code.  No other license or right
36  * is granted directly or by implication, estoppel or otherwise;
37  *
38  * The above copyright and patent license is granted only if the following
39  * conditions are met:
40  *
41  * 3. Conditions
42  *
43  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
44  * Redistribution of source code of any substantial portion of the Covered
45  * Code or modification with rights to further distribute source must include
46  * the above Copyright Notice, the above License, this list of Conditions,
47  * and the following Disclaimer and Export Compliance provision.  In addition,
48  * Licensee must cause all Covered Code to which Licensee contributes to
49  * contain a file documenting the changes Licensee made to create that Covered
50  * Code and the date of any change.  Licensee must include in that file the
51  * documentation of any changes made by any predecessor Licensee.  Licensee
52  * must include a prominent statement that the modification is derived,
53  * directly or indirectly, from Original Intel Code.
54  *
55  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
56  * Redistribution of source code of any substantial portion of the Covered
57  * Code or modification without rights to further distribute source must
58  * include the following Disclaimer and Export Compliance provision in the
59  * documentation and/or other materials provided with distribution.  In
60  * addition, Licensee may not authorize further sublicense of source of any
61  * portion of the Covered Code, and must include terms to the effect that the
62  * license from Licensee to its licensee is limited to the intellectual
63  * property embodied in the software Licensee provides to its licensee, and
64  * not to intellectual property embodied in modifications its licensee may
65  * make.
66  *
67  * 3.3. Redistribution of Executable. Redistribution in executable form of any
68  * substantial portion of the Covered Code or modification must reproduce the
69  * above Copyright Notice, and the following Disclaimer and Export Compliance
70  * provision in the documentation and/or other materials provided with the
71  * distribution.
72  *
73  * 3.4. Intel retains all right, title, and interest in and to the Original
74  * Intel Code.
75  *
76  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
77  * Intel shall be used in advertising or otherwise to promote the sale, use or
78  * other dealings in products derived from or relating to the Covered Code
79  * without prior written authorization from Intel.
80  *
81  * 4. Disclaimer and Export Compliance
82  *
83  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
84  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
85  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
86  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
87  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
88  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
89  * PARTICULAR PURPOSE.
90  *
91  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
92  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
93  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
94  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
95  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
96  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
97  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
98  * LIMITED REMEDY.
99  *
100  * 4.3. Licensee shall not export, either directly or indirectly, any of this
101  * software or system incorporating such software without first obtaining any
102  * required license or other approval from the U. S. Department of Commerce or
103  * any other agency or department of the United States Government.  In the
104  * event Licensee exports any such software from the United States or
105  * re-exports any such software from a foreign destination, Licensee shall
106  * ensure that the distribution and export/re-export of the software is in
107  * compliance with all laws, regulations, orders, or other restrictions of the
108  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
109  * any of its subsidiaries will export/re-export any technical data, process,
110  * software, or service, directly or indirectly, to any country for which the
111  * United States government or any agency thereof requires an export license,
112  * other governmental approval, or letter of assurance, without first obtaining
113  * such license, approval or letter.
114  *
115  *****************************************************************************/
116
117 #define __UTEVAL_C__
118
119 #include "acpi.h"
120 #include "acnamesp.h"
121 #include "acinterp.h"
122
123
124 #define _COMPONENT          ACPI_UTILITIES
125         ACPI_MODULE_NAME    ("uteval")
126
127
128 /*******************************************************************************
129  *
130  * FUNCTION:    AcpiUtEvaluateObject
131  *
132  * PARAMETERS:  PrefixNode          - Starting node
133  *              Path                - Path to object from starting node
134  *              ExpectedReturnTypes - Bitmap of allowed return types
135  *              ReturnDesc          - Where a return value is stored
136  *
137  * RETURN:      Status
138  *
139  * DESCRIPTION: Evaluates a namespace object and verifies the type of the
140  *              return object.  Common code that simplifies accessing objects
141  *              that have required return objects of fixed types.
142  *
143  *              NOTE: Internal function, no parameter validation
144  *
145  ******************************************************************************/
146
147 ACPI_STATUS
148 AcpiUtEvaluateObject (
149     ACPI_NAMESPACE_NODE     *PrefixNode,
150     char                    *Path,
151     UINT32                  ExpectedReturnBtypes,
152     ACPI_OPERAND_OBJECT     **ReturnDesc)
153 {
154     ACPI_OPERAND_OBJECT     *ObjDesc;
155     ACPI_STATUS             Status;
156     UINT32                  ReturnBtype;
157
158
159     ACPI_FUNCTION_TRACE ("UtEvaluateObject");
160
161
162     /* Evaluate the object/method */
163
164     Status = AcpiNsEvaluateRelative (PrefixNode, Path, NULL, &ObjDesc);
165     if (ACPI_FAILURE (Status))
166     {
167         if (Status == AE_NOT_FOUND)
168         {
169             ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s.%s] was not found\n",
170                 AcpiUtGetNodeName (PrefixNode), Path));
171         }
172         else
173         {
174             ACPI_REPORT_METHOD_ERROR ("Method execution failed",
175                 PrefixNode, Path, Status);
176         }
177
178         return_ACPI_STATUS (Status);
179     }
180
181     /* Did we get a return object? */
182
183     if (!ObjDesc)
184     {
185         if (ExpectedReturnBtypes)
186         {
187             ACPI_REPORT_METHOD_ERROR ("No object was returned from",
188                 PrefixNode, Path, AE_NOT_EXIST);
189
190             return_ACPI_STATUS (AE_NOT_EXIST);
191         }
192
193         return_ACPI_STATUS (AE_OK);
194     }
195
196     /* Map the return object type to the bitmapped type */
197
198     switch (ACPI_GET_OBJECT_TYPE (ObjDesc))
199     {
200     case ACPI_TYPE_INTEGER:
201         ReturnBtype = ACPI_BTYPE_INTEGER;
202         break;
203
204     case ACPI_TYPE_BUFFER:
205         ReturnBtype = ACPI_BTYPE_BUFFER;
206         break;
207
208     case ACPI_TYPE_STRING:
209         ReturnBtype = ACPI_BTYPE_STRING;
210         break;
211
212     case ACPI_TYPE_PACKAGE:
213         ReturnBtype = ACPI_BTYPE_PACKAGE;
214         break;
215
216     default:
217         ReturnBtype = 0;
218         break;
219     }
220
221     /* Is the return object one of the expected types? */
222
223     if (!(ExpectedReturnBtypes & ReturnBtype))
224     {
225         ACPI_REPORT_METHOD_ERROR ("Return object type is incorrect",
226             PrefixNode, Path, AE_TYPE);
227
228         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
229             "Type returned from %s was incorrect: %X\n",
230             Path, ACPI_GET_OBJECT_TYPE (ObjDesc)));
231
232         /* On error exit, we must delete the return object */
233
234         AcpiUtRemoveReference (ObjDesc);
235         return_ACPI_STATUS (AE_TYPE);
236     }
237
238     /* Object type is OK, return it */
239
240     *ReturnDesc = ObjDesc;
241     return_ACPI_STATUS (AE_OK);
242 }
243
244
245 /*******************************************************************************
246  *
247  * FUNCTION:    AcpiUtEvaluateNumericObject
248  *
249  * PARAMETERS:  *ObjectName         - Object name to be evaluated
250  *              DeviceNode          - Node for the device
251  *              *Address            - Where the value is returned
252  *
253  * RETURN:      Status
254  *
255  * DESCRIPTION: Evaluates a numeric namespace object for a selected device
256  *              and stores result in *Address.
257  *
258  *              NOTE: Internal function, no parameter validation
259  *
260  ******************************************************************************/
261
262 ACPI_STATUS
263 AcpiUtEvaluateNumericObject (
264     char                    *ObjectName,
265     ACPI_NAMESPACE_NODE     *DeviceNode,
266     ACPI_INTEGER            *Address)
267 {
268     ACPI_OPERAND_OBJECT     *ObjDesc;
269     ACPI_STATUS             Status;
270
271
272     ACPI_FUNCTION_TRACE ("UtEvaluateNumericObject");
273
274
275     Status = AcpiUtEvaluateObject (DeviceNode, ObjectName,
276                 ACPI_BTYPE_INTEGER, &ObjDesc);
277     if (ACPI_FAILURE (Status))
278     {
279         return_ACPI_STATUS (Status);
280     }
281
282     /* Get the returned Integer */
283
284     *Address = ObjDesc->Integer.Value;
285
286     /* On exit, we must delete the return object */
287
288     AcpiUtRemoveReference (ObjDesc);
289     return_ACPI_STATUS (Status);
290 }
291
292
293 /*******************************************************************************
294  *
295  * FUNCTION:    AcpiUtCopyIdString
296  *
297  * PARAMETERS:  Destination         - Where to copy the string
298  *              Source              - Source string
299  *              MaxLength           - Length of the destination buffer
300  *
301  * RETURN:      None
302  *
303  * DESCRIPTION: Copies an ID string for the _HID, _CID, and _UID methods.
304  *              Performs removal of a leading asterisk if present -- workaround
305  *              for a known issue on a bunch of machines.
306  *
307  ******************************************************************************/
308
309 static void
310 AcpiUtCopyIdString (
311     char                    *Destination,
312     char                    *Source,
313     ACPI_SIZE               MaxLength)
314 {
315
316
317     /*
318      * Workaround for ID strings that have a leading asterisk. This construct
319      * is not allowed by the ACPI specification  (ID strings must be
320      * alphanumeric), but enough existing machines have this embedded in their
321      * ID strings that the following code is useful.
322      */
323     if (*Source == '*')
324     {
325         Source++;
326     }
327
328     /* Do the actual copy */
329
330     ACPI_STRNCPY (Destination, Source, MaxLength);
331 }
332
333
334 /*******************************************************************************
335  *
336  * FUNCTION:    AcpiUtExecute_HID
337  *
338  * PARAMETERS:  DeviceNode          - Node for the device
339  *              *Hid                - Where the HID is returned
340  *
341  * RETURN:      Status
342  *
343  * DESCRIPTION: Executes the _HID control method that returns the hardware
344  *              ID of the device.
345  *
346  *              NOTE: Internal function, no parameter validation
347  *
348  ******************************************************************************/
349
350 ACPI_STATUS
351 AcpiUtExecute_HID (
352     ACPI_NAMESPACE_NODE     *DeviceNode,
353     ACPI_DEVICE_ID          *Hid)
354 {
355     ACPI_OPERAND_OBJECT     *ObjDesc;
356     ACPI_STATUS             Status;
357
358
359     ACPI_FUNCTION_TRACE ("UtExecute_HID");
360
361
362     Status = AcpiUtEvaluateObject (DeviceNode, METHOD_NAME__HID,
363                 ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING, &ObjDesc);
364     if (ACPI_FAILURE (Status))
365     {
366         return_ACPI_STATUS (Status);
367     }
368
369     if (ACPI_GET_OBJECT_TYPE (ObjDesc) == ACPI_TYPE_INTEGER)
370     {
371         /* Convert the Numeric HID to string */
372
373         AcpiExEisaIdToString ((UINT32) ObjDesc->Integer.Value, Hid->Value);
374     }
375     else
376     {
377         /* Copy the String HID from the returned object */
378
379         AcpiUtCopyIdString (Hid->Value, ObjDesc->String.Pointer,
380                 sizeof (Hid->Value));
381     }
382
383     /* On exit, we must delete the return object */
384
385     AcpiUtRemoveReference (ObjDesc);
386     return_ACPI_STATUS (Status);
387 }
388
389
390 /*******************************************************************************
391  *
392  * FUNCTION:    AcpiUtTranslateOneCid
393  *
394  * PARAMETERS:  ObjDesc             - _CID object, must be integer or string
395  *              OneCid              - Where the CID string is returned
396  *
397  * RETURN:      Status
398  *
399  * DESCRIPTION: Return a numeric or string _CID value as a string.
400  *              (Compatible ID)
401  *
402  *              NOTE:  Assumes a maximum _CID string length of
403  *                     ACPI_MAX_CID_LENGTH.
404  *
405  ******************************************************************************/
406
407 static ACPI_STATUS
408 AcpiUtTranslateOneCid (
409     ACPI_OPERAND_OBJECT     *ObjDesc,
410     ACPI_COMPATIBLE_ID      *OneCid)
411 {
412
413
414     switch (ACPI_GET_OBJECT_TYPE (ObjDesc))
415     {
416     case ACPI_TYPE_INTEGER:
417
418         /* Convert the Numeric CID to string */
419
420         AcpiExEisaIdToString ((UINT32) ObjDesc->Integer.Value, OneCid->Value);
421         return (AE_OK);
422
423     case ACPI_TYPE_STRING:
424
425         if (ObjDesc->String.Length > ACPI_MAX_CID_LENGTH)
426         {
427             return (AE_AML_STRING_LIMIT);
428         }
429
430         /* Copy the String CID from the returned object */
431
432         AcpiUtCopyIdString (OneCid->Value, ObjDesc->String.Pointer,
433                 ACPI_MAX_CID_LENGTH);
434         return (AE_OK);
435
436     default:
437
438         return (AE_TYPE);
439     }
440 }
441
442
443 /*******************************************************************************
444  *
445  * FUNCTION:    AcpiUtExecute_CID
446  *
447  * PARAMETERS:  DeviceNode          - Node for the device
448  *              *Cid                - Where the CID is returned
449  *
450  * RETURN:      Status
451  *
452  * DESCRIPTION: Executes the _CID control method that returns one or more
453  *              compatible hardware IDs for the device.
454  *
455  *              NOTE: Internal function, no parameter validation
456  *
457  ******************************************************************************/
458
459 ACPI_STATUS
460 AcpiUtExecute_CID (
461     ACPI_NAMESPACE_NODE     *DeviceNode,
462     ACPI_COMPATIBLE_ID_LIST **ReturnCidList)
463 {
464     ACPI_OPERAND_OBJECT     *ObjDesc;
465     ACPI_STATUS             Status;
466     UINT32                  Count;
467     UINT32                  Size;
468     ACPI_COMPATIBLE_ID_LIST *CidList;
469     ACPI_NATIVE_UINT        i;
470
471
472     ACPI_FUNCTION_TRACE ("UtExecute_CID");
473
474
475     /* Evaluate the _CID method for this device */
476
477     Status = AcpiUtEvaluateObject (DeviceNode, METHOD_NAME__CID,
478                 ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING | ACPI_BTYPE_PACKAGE,
479                 &ObjDesc);
480     if (ACPI_FAILURE (Status))
481     {
482         return_ACPI_STATUS (Status);
483     }
484
485     /* Get the number of _CIDs returned */
486
487     Count = 1;
488     if (ACPI_GET_OBJECT_TYPE (ObjDesc) == ACPI_TYPE_PACKAGE)
489     {
490         Count = ObjDesc->Package.Count;
491     }
492
493     /* Allocate a worst-case buffer for the _CIDs */
494
495     Size = (((Count - 1) * sizeof (ACPI_COMPATIBLE_ID)) +
496                            sizeof (ACPI_COMPATIBLE_ID_LIST));
497
498     CidList = ACPI_MEM_CALLOCATE ((ACPI_SIZE) Size);
499     if (!CidList)
500     {
501         return_ACPI_STATUS (AE_NO_MEMORY);
502     }
503
504     /* Init CID list */
505
506     CidList->Count = Count;
507     CidList->Size  = Size;
508
509     /*
510      *  A _CID can return either a single compatible ID or a package of compatible
511      *  IDs.  Each compatible ID can be one of the following:
512      *  -- Number (32 bit compressed EISA ID) or
513      *  -- String (PCI ID format, e.g. "PCI\VEN_vvvv&DEV_dddd&SUBSYS_ssssssss").
514      */
515
516     /* The _CID object can be either a single CID or a package (list) of CIDs */
517
518     if (ACPI_GET_OBJECT_TYPE (ObjDesc) == ACPI_TYPE_PACKAGE)
519     {
520         /* Translate each package element */
521
522         for (i = 0; i < Count; i++)
523         {
524             Status = AcpiUtTranslateOneCid (ObjDesc->Package.Elements[i],
525                             &CidList->Id[i]);
526             if (ACPI_FAILURE (Status))
527             {
528                 break;
529             }
530         }
531     }
532     else
533     {
534         /* Only one CID, translate to a string */
535
536         Status = AcpiUtTranslateOneCid (ObjDesc, CidList->Id);
537     }
538
539     /* Cleanup on error */
540
541     if (ACPI_FAILURE (Status))
542     {
543         ACPI_MEM_FREE (CidList);
544     }
545     else
546     {
547         *ReturnCidList = CidList;
548     }
549
550     /* On exit, we must delete the _CID return object */
551
552     AcpiUtRemoveReference (ObjDesc);
553     return_ACPI_STATUS (Status);
554 }
555
556
557 /*******************************************************************************
558  *
559  * FUNCTION:    AcpiUtExecute_UID
560  *
561  * PARAMETERS:  DeviceNode          - Node for the device
562  *              *Uid                - Where the UID is returned
563  *
564  * RETURN:      Status
565  *
566  * DESCRIPTION: Executes the _UID control method that returns the hardware
567  *              ID of the device.
568  *
569  *              NOTE: Internal function, no parameter validation
570  *
571  ******************************************************************************/
572
573 ACPI_STATUS
574 AcpiUtExecute_UID (
575     ACPI_NAMESPACE_NODE     *DeviceNode,
576     ACPI_DEVICE_ID          *Uid)
577 {
578     ACPI_OPERAND_OBJECT     *ObjDesc;
579     ACPI_STATUS             Status;
580
581
582     ACPI_FUNCTION_TRACE ("UtExecute_UID");
583
584
585     Status = AcpiUtEvaluateObject (DeviceNode, METHOD_NAME__UID,
586                 ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING, &ObjDesc);
587     if (ACPI_FAILURE (Status))
588     {
589         return_ACPI_STATUS (Status);
590     }
591
592     if (ACPI_GET_OBJECT_TYPE (ObjDesc) == ACPI_TYPE_INTEGER)
593     {
594         /* Convert the Numeric UID to string */
595
596         AcpiExUnsignedIntegerToString (ObjDesc->Integer.Value, Uid->Value);
597     }
598     else
599     {
600         /* Copy the String UID from the returned object */
601
602         AcpiUtCopyIdString (Uid->Value, ObjDesc->String.Pointer,
603                 sizeof (Uid->Value));
604     }
605
606     /* On exit, we must delete the return object */
607
608     AcpiUtRemoveReference (ObjDesc);
609     return_ACPI_STATUS (Status);
610 }
611
612
613 /*******************************************************************************
614  *
615  * FUNCTION:    AcpiUtExecute_STA
616  *
617  * PARAMETERS:  DeviceNode          - Node for the device
618  *              *Flags              - Where the status flags are returned
619  *
620  * RETURN:      Status
621  *
622  * DESCRIPTION: Executes _STA for selected device and stores results in
623  *              *Flags.
624  *
625  *              NOTE: Internal function, no parameter validation
626  *
627  ******************************************************************************/
628
629 ACPI_STATUS
630 AcpiUtExecute_STA (
631     ACPI_NAMESPACE_NODE     *DeviceNode,
632     UINT32                  *Flags)
633 {
634     ACPI_OPERAND_OBJECT     *ObjDesc;
635     ACPI_STATUS             Status;
636
637
638     ACPI_FUNCTION_TRACE ("UtExecute_STA");
639
640
641     Status = AcpiUtEvaluateObject (DeviceNode, METHOD_NAME__STA,
642                 ACPI_BTYPE_INTEGER, &ObjDesc);
643     if (ACPI_FAILURE (Status))
644     {
645         if (AE_NOT_FOUND == Status)
646         {
647             ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
648                 "_STA on %4.4s was not found, assuming device is present\n",
649                 AcpiUtGetNodeName (DeviceNode)));
650
651             *Flags = 0x0F;
652             Status = AE_OK;
653         }
654
655         return_ACPI_STATUS (Status);
656     }
657
658     /* Extract the status flags */
659
660     *Flags = (UINT32) ObjDesc->Integer.Value;
661
662     /* On exit, we must delete the return object */
663
664     AcpiUtRemoveReference (ObjDesc);
665     return_ACPI_STATUS (Status);
666 }