]> CyberLeo.Net >> Repos - FreeBSD/releng/8.0.git/blob - sys/contrib/dev/acpica/compiler/aslanalyze.c
Adjust to reflect 8.0-RELEASE.
[FreeBSD/releng/8.0.git] / sys / contrib / dev / acpica / compiler / aslanalyze.c
1
2 /******************************************************************************
3  *
4  * Module Name: aslanalyze.c - check for semantic errors
5  *
6  *****************************************************************************/
7
8 /******************************************************************************
9  *
10  * 1. Copyright Notice
11  *
12  * Some or all of this work - Copyright (c) 1999 - 2009, 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
118 #include <contrib/dev/acpica/compiler/aslcompiler.h>
119 #include "aslcompiler.y.h"
120 #include <contrib/dev/acpica/include/acparser.h>
121 #include <contrib/dev/acpica/include/amlcode.h>
122
123 #define _COMPONENT          ACPI_COMPILER
124         ACPI_MODULE_NAME    ("aslanalyze")
125
126 /* Local prototypes */
127
128 static UINT32
129 AnMapArgTypeToBtype (
130     UINT32                  ArgType);
131
132 static UINT32
133 AnMapEtypeToBtype (
134     UINT32                  Etype);
135
136 static void
137 AnFormatBtype (
138     char                    *Buffer,
139     UINT32                  Btype);
140
141 static UINT32
142 AnGetBtype (
143     ACPI_PARSE_OBJECT       *Op);
144
145 static UINT32
146 AnCheckForReservedName (
147     ACPI_PARSE_OBJECT       *Op,
148     char                    *Name);
149
150 static void
151 AnCheckForReservedMethod (
152     ACPI_PARSE_OBJECT       *Op,
153     ASL_METHOD_INFO         *MethodInfo);
154
155 static UINT32
156 AnMapObjTypeToBtype (
157     ACPI_PARSE_OBJECT       *Op);
158
159 static BOOLEAN
160 AnLastStatementIsReturn (
161     ACPI_PARSE_OBJECT       *Op);
162
163 static void
164 AnCheckMethodReturnValue (
165     ACPI_PARSE_OBJECT       *Op,
166     const ACPI_OPCODE_INFO  *OpInfo,
167     ACPI_PARSE_OBJECT       *ArgOp,
168     UINT32                  RequiredBtypes,
169     UINT32                  ThisNodeBtype);
170
171 static BOOLEAN
172 AnIsInternalMethod (
173     ACPI_PARSE_OBJECT       *Op);
174
175 static UINT32
176 AnGetInternalMethodReturnType (
177     ACPI_PARSE_OBJECT       *Op);
178
179 BOOLEAN
180 AnIsResultUsed (
181     ACPI_PARSE_OBJECT       *Op);
182
183
184 /*******************************************************************************
185  *
186  * FUNCTION:    AnIsInternalMethod
187  *
188  * PARAMETERS:  Op              - Current op
189  *
190  * RETURN:      Boolean
191  *
192  * DESCRIPTION: Check for an internal control method.
193  *
194  ******************************************************************************/
195
196 static BOOLEAN
197 AnIsInternalMethod (
198     ACPI_PARSE_OBJECT       *Op)
199 {
200
201     if ((!ACPI_STRCMP (Op->Asl.ExternalName, "\\_OSI")) ||
202         (!ACPI_STRCMP (Op->Asl.ExternalName, "_OSI")))
203     {
204         return (TRUE);
205     }
206
207     return (FALSE);
208 }
209
210
211 /*******************************************************************************
212  *
213  * FUNCTION:    AnGetInternalMethodReturnType
214  *
215  * PARAMETERS:  Op              - Current op
216  *
217  * RETURN:      Btype
218  *
219  * DESCRIPTION: Get the return type of an internal method
220  *
221  ******************************************************************************/
222
223 static UINT32
224 AnGetInternalMethodReturnType (
225     ACPI_PARSE_OBJECT       *Op)
226 {
227
228     if ((!ACPI_STRCMP (Op->Asl.ExternalName, "\\_OSI")) ||
229         (!ACPI_STRCMP (Op->Asl.ExternalName, "_OSI")))
230     {
231         return (ACPI_BTYPE_STRING);
232     }
233
234     return (0);
235 }
236
237
238 /*******************************************************************************
239  *
240  * FUNCTION:    AnMapArgTypeToBtype
241  *
242  * PARAMETERS:  ArgType      - The ARGI required type(s) for this argument,
243  *                             from the opcode info table
244  *
245  * RETURN:      The corresponding Bit-encoded types
246  *
247  * DESCRIPTION: Convert an encoded ARGI required argument type code into a
248  *              bitfield type code. Implements the implicit source conversion
249  *              rules.
250  *
251  ******************************************************************************/
252
253 static UINT32
254 AnMapArgTypeToBtype (
255     UINT32                  ArgType)
256 {
257
258     switch (ArgType)
259     {
260
261     /* Simple types */
262
263     case ARGI_ANYTYPE:
264         return (ACPI_BTYPE_OBJECTS_AND_REFS);
265
266     case ARGI_PACKAGE:
267         return (ACPI_BTYPE_PACKAGE);
268
269     case ARGI_EVENT:
270         return (ACPI_BTYPE_EVENT);
271
272     case ARGI_MUTEX:
273         return (ACPI_BTYPE_MUTEX);
274
275     case ARGI_DDBHANDLE:
276         /*
277          * DDBHandleObject := SuperName
278          * ACPI_BTYPE_REFERENCE: Index reference as parameter of Load/Unload
279          */
280         return (ACPI_BTYPE_DDB_HANDLE | ACPI_BTYPE_REFERENCE);
281
282     /* Interchangeable types */
283     /*
284      * Source conversion rules:
285      * Integer, String, and Buffer are all interchangeable
286      */
287     case ARGI_INTEGER:
288     case ARGI_STRING:
289     case ARGI_BUFFER:
290     case ARGI_BUFFER_OR_STRING:
291     case ARGI_COMPUTEDATA:
292         return (ACPI_BTYPE_COMPUTE_DATA);
293
294     /* References */
295
296     case ARGI_INTEGER_REF:
297         return (ACPI_BTYPE_INTEGER);
298
299     case ARGI_OBJECT_REF:
300         return (ACPI_BTYPE_ALL_OBJECTS);
301
302     case ARGI_DEVICE_REF:
303         return (ACPI_BTYPE_DEVICE_OBJECTS);
304
305     case ARGI_REFERENCE:
306         return (ACPI_BTYPE_REFERENCE);
307
308     case ARGI_TARGETREF:
309     case ARGI_FIXED_TARGET:
310     case ARGI_SIMPLE_TARGET:
311         return (ACPI_BTYPE_OBJECTS_AND_REFS);
312
313     /* Complex types */
314
315     case ARGI_DATAOBJECT:
316
317         /*
318          * Buffer, string, package or reference to a Op -
319          * Used only by SizeOf operator
320          */
321         return (ACPI_BTYPE_STRING | ACPI_BTYPE_BUFFER |
322             ACPI_BTYPE_PACKAGE | ACPI_BTYPE_REFERENCE);
323
324     case ARGI_COMPLEXOBJ:
325
326         /* Buffer, String, or package */
327
328         return (ACPI_BTYPE_STRING | ACPI_BTYPE_BUFFER | ACPI_BTYPE_PACKAGE);
329
330     case ARGI_REF_OR_STRING:
331         return (ACPI_BTYPE_STRING | ACPI_BTYPE_REFERENCE);
332
333     case ARGI_REGION_OR_BUFFER:
334
335         /* Used by Load() only. Allow buffers in addition to regions/fields */
336
337         return (ACPI_BTYPE_REGION | ACPI_BTYPE_BUFFER | ACPI_BTYPE_FIELD_UNIT);
338
339     case ARGI_DATAREFOBJ:
340         return (ACPI_BTYPE_INTEGER |ACPI_BTYPE_STRING | ACPI_BTYPE_BUFFER |
341             ACPI_BTYPE_PACKAGE | ACPI_BTYPE_REFERENCE | ACPI_BTYPE_DDB_HANDLE);
342
343     default:
344         break;
345     }
346
347     return (ACPI_BTYPE_OBJECTS_AND_REFS);
348 }
349
350
351 /*******************************************************************************
352  *
353  * FUNCTION:    AnMapEtypeToBtype
354  *
355  * PARAMETERS:  Etype           - Encoded ACPI Type
356  *
357  * RETURN:      Btype corresponding to the Etype
358  *
359  * DESCRIPTION: Convert an encoded ACPI type to a bitfield type applying the
360  *              operand conversion rules. In other words, returns the type(s)
361  *              this Etype is implicitly converted to during interpretation.
362  *
363  ******************************************************************************/
364
365 static UINT32
366 AnMapEtypeToBtype (
367     UINT32                  Etype)
368 {
369
370
371     if (Etype == ACPI_TYPE_ANY)
372     {
373         return ACPI_BTYPE_OBJECTS_AND_REFS;
374     }
375
376     /* Try the standard ACPI data types */
377
378     if (Etype <= ACPI_TYPE_EXTERNAL_MAX)
379     {
380         /*
381          * This switch statement implements the allowed operand conversion
382          * rules as per the "ASL Data Types" section of the ACPI
383          * specification.
384          */
385         switch (Etype)
386         {
387         case ACPI_TYPE_INTEGER:
388             return (ACPI_BTYPE_COMPUTE_DATA | ACPI_BTYPE_DDB_HANDLE);
389
390         case ACPI_TYPE_STRING:
391         case ACPI_TYPE_BUFFER:
392             return (ACPI_BTYPE_COMPUTE_DATA);
393
394         case ACPI_TYPE_PACKAGE:
395             return (ACPI_BTYPE_PACKAGE);
396
397         case ACPI_TYPE_FIELD_UNIT:
398             return (ACPI_BTYPE_COMPUTE_DATA | ACPI_BTYPE_FIELD_UNIT);
399
400         case ACPI_TYPE_BUFFER_FIELD:
401             return (ACPI_BTYPE_COMPUTE_DATA | ACPI_BTYPE_BUFFER_FIELD);
402
403         case ACPI_TYPE_DDB_HANDLE:
404             return (ACPI_BTYPE_INTEGER | ACPI_BTYPE_DDB_HANDLE);
405
406         case ACPI_BTYPE_DEBUG_OBJECT:
407
408             /* Cannot be used as a source operand */
409
410             return (0);
411
412         default:
413             return (1 << (Etype - 1));
414         }
415     }
416
417     /* Try the internal data types */
418
419     switch (Etype)
420     {
421     case ACPI_TYPE_LOCAL_REGION_FIELD:
422     case ACPI_TYPE_LOCAL_BANK_FIELD:
423     case ACPI_TYPE_LOCAL_INDEX_FIELD:
424
425         /* Named fields can be either Integer/Buffer/String */
426
427         return (ACPI_BTYPE_COMPUTE_DATA | ACPI_BTYPE_FIELD_UNIT);
428
429     case ACPI_TYPE_LOCAL_ALIAS:
430
431         return (ACPI_BTYPE_INTEGER);
432
433
434     case ACPI_TYPE_LOCAL_RESOURCE:
435     case ACPI_TYPE_LOCAL_RESOURCE_FIELD:
436
437         return (ACPI_BTYPE_REFERENCE);
438
439     default:
440         printf ("Unhandled encoded type: %X\n", Etype);
441         return (0);
442     }
443 }
444
445
446 /*******************************************************************************
447  *
448  * FUNCTION:    AnFormatBtype
449  *
450  * PARAMETERS:  Btype               - Bitfield of ACPI types
451  *              Buffer              - Where to put the ascii string
452  *
453  * RETURN:      None.
454  *
455  * DESCRIPTION: Convert a Btype to a string of ACPI types
456  *
457  ******************************************************************************/
458
459 static void
460 AnFormatBtype (
461     char                    *Buffer,
462     UINT32                  Btype)
463 {
464     UINT32                  Type;
465     BOOLEAN                 First = TRUE;
466
467
468     *Buffer = 0;
469
470     if (Btype == 0)
471     {
472         strcat (Buffer, "NoReturnValue");
473         return;
474     }
475
476     for (Type = 1; Type <= ACPI_TYPE_EXTERNAL_MAX; Type++)
477     {
478         if (Btype & 0x00000001)
479         {
480             if (!First)
481             {
482                 strcat (Buffer, "|");
483             }
484             First = FALSE;
485             strcat (Buffer, AcpiUtGetTypeName (Type));
486         }
487         Btype >>= 1;
488     }
489
490     if (Btype & 0x00000001)
491     {
492         if (!First)
493         {
494             strcat (Buffer, "|");
495         }
496         First = FALSE;
497         strcat (Buffer, "Reference");
498     }
499
500     Btype >>= 1;
501     if (Btype & 0x00000001)
502     {
503         if (!First)
504         {
505             strcat (Buffer, "|");
506         }
507         First = FALSE;
508         strcat (Buffer, "Resource");
509     }
510 }
511
512
513 /*******************************************************************************
514  *
515  * FUNCTION:    AnGetBtype
516  *
517  * PARAMETERS:  Op          - Parse node whose type will be returned.
518  *
519  * RETURN:      The Btype associated with the Op.
520  *
521  * DESCRIPTION: Get the (bitfield) ACPI type associated with the parse node.
522  *              Handles the case where the node is a name or method call and
523  *              the actual type must be obtained from the namespace node.
524  *
525  ******************************************************************************/
526
527 static UINT32
528 AnGetBtype (
529     ACPI_PARSE_OBJECT       *Op)
530 {
531     ACPI_NAMESPACE_NODE     *Node;
532     ACPI_PARSE_OBJECT       *ReferencedNode;
533     UINT32                  ThisNodeBtype = 0;
534
535
536     if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG)     ||
537         (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING)  ||
538         (Op->Asl.ParseOpcode == PARSEOP_METHODCALL))
539     {
540         Node = Op->Asl.Node;
541         if (!Node)
542         {
543             DbgPrint (ASL_DEBUG_OUTPUT,
544                 "No attached Nsnode: [%s] at line %d name [%s], ignoring typecheck\n",
545                 Op->Asl.ParseOpName, Op->Asl.LineNumber,
546                 Op->Asl.ExternalName);
547             return ACPI_UINT32_MAX;
548         }
549
550         ThisNodeBtype = AnMapEtypeToBtype (Node->Type);
551         if (!ThisNodeBtype)
552         {
553             AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, Op,
554                 "could not map type");
555         }
556
557         /*
558          * Since it was a named reference, enable the
559          * reference bit also
560          */
561         ThisNodeBtype |= ACPI_BTYPE_REFERENCE;
562
563         if (Op->Asl.ParseOpcode == PARSEOP_METHODCALL)
564         {
565             ReferencedNode = Node->Op;
566             if (!ReferencedNode)
567             {
568                 /* Check for an internal method */
569
570                 if (AnIsInternalMethod (Op))
571                 {
572                     return (AnGetInternalMethodReturnType (Op));
573                 }
574
575                 AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, Op,
576                     "null Op pointer");
577                 return ACPI_UINT32_MAX;
578             }
579
580             if (ReferencedNode->Asl.CompileFlags & NODE_METHOD_TYPED)
581             {
582                 ThisNodeBtype = ReferencedNode->Asl.AcpiBtype;
583             }
584             else
585             {
586                 return (ACPI_UINT32_MAX -1);
587             }
588         }
589     }
590     else
591     {
592         ThisNodeBtype = Op->Asl.AcpiBtype;
593     }
594
595     return (ThisNodeBtype);
596 }
597
598
599 /*******************************************************************************
600  *
601  * FUNCTION:    AnCheckForReservedName
602  *
603  * PARAMETERS:  Op              - A parse node
604  *              Name            - NameSeg to check
605  *
606  * RETURN:      None
607  *
608  * DESCRIPTION: Check a NameSeg against the reserved list.
609  *
610  ******************************************************************************/
611
612 static UINT32
613 AnCheckForReservedName (
614     ACPI_PARSE_OBJECT       *Op,
615     char                    *Name)
616 {
617     UINT32                  i;
618
619
620     if (Name[0] == 0)
621     {
622         AcpiOsPrintf ("Found a null name, external = %s\n",
623             Op->Asl.ExternalName);
624     }
625
626     /* All reserved names are prefixed with a single underscore */
627
628     if (Name[0] != '_')
629     {
630         return (ACPI_NOT_RESERVED_NAME);
631     }
632
633     /* Check for a standard reserved method name */
634
635     for (i = 0; ReservedMethods[i].Name; i++)
636     {
637         if (ACPI_COMPARE_NAME (Name, ReservedMethods[i].Name))
638         {
639             if (ReservedMethods[i].Flags & ASL_RSVD_SCOPE)
640             {
641                 AslError (ASL_ERROR, ASL_MSG_RESERVED_WORD, Op,
642                     Op->Asl.ExternalName);
643                 return (ACPI_PREDEFINED_NAME);
644             }
645             else if (ReservedMethods[i].Flags & ASL_RSVD_RESOURCE_NAME)
646             {
647                 AslError (ASL_ERROR, ASL_MSG_RESERVED_WORD, Op,
648                     Op->Asl.ExternalName);
649                 return (ACPI_PREDEFINED_NAME);
650             }
651
652             /* Return index into reserved array */
653
654             return i;
655         }
656     }
657
658     /*
659      * Now check for the "special" reserved names --
660      * GPE:  _Lxx
661      * GPE:  _Exx
662      * EC:   _Qxx
663      */
664     if ((Name[1] == 'L') ||
665         (Name[1] == 'E') ||
666         (Name[1] == 'Q'))
667     {
668         /* The next two characters must be hex digits */
669
670         if ((isxdigit (Name[2])) &&
671             (isxdigit (Name[3])))
672         {
673             return (ACPI_EVENT_RESERVED_NAME);
674         }
675     }
676
677
678     /* Check for the names reserved for the compiler itself: _T_x */
679
680     else if ((Op->Asl.ExternalName[1] == 'T') &&
681              (Op->Asl.ExternalName[2] == '_'))
682     {
683         /* Ignore if actually emitted by the compiler */
684
685         if (Op->Asl.CompileFlags & NODE_COMPILER_EMITTED)
686         {
687             return (ACPI_NOT_RESERVED_NAME);
688         }
689
690         /*
691          * Was not actually emitted by the compiler. This is a special case,
692          * however. If the ASL code being compiled was the result of a
693          * dissasembly, it may possibly contain valid compiler-emitted names
694          * of the form "_T_x". We don't want to issue an error or even a
695          * warning and force the user to manually change the names. So, we
696          * will issue a remark instead.
697          */
698         AslError (ASL_REMARK, ASL_MSG_COMPILER_RESERVED, Op, Op->Asl.ExternalName);
699         return (ACPI_COMPILER_RESERVED_NAME);
700     }
701
702     /*
703      * The name didn't match any of the known reserved names. Flag it as a
704      * warning, since the entire namespace starting with an underscore is
705      * reserved by the ACPI spec.
706      */
707     AslError (ASL_WARNING, ASL_MSG_UNKNOWN_RESERVED_NAME, Op,
708         Op->Asl.ExternalName);
709
710     return (ACPI_NOT_RESERVED_NAME);
711 }
712
713
714 /*******************************************************************************
715  *
716  * FUNCTION:    AnCheckForReservedMethod
717  *
718  * PARAMETERS:  Op              - A parse node of type "METHOD".
719  *              MethodInfo      - Saved info about this method
720  *
721  * RETURN:      None
722  *
723  * DESCRIPTION: If method is a reserved name, check that the number of arguments
724  *              and the return type (returns a value or not) is correct.
725  *
726  ******************************************************************************/
727
728 static void
729 AnCheckForReservedMethod (
730     ACPI_PARSE_OBJECT       *Op,
731     ASL_METHOD_INFO         *MethodInfo)
732 {
733     UINT32                  Index;
734     UINT32                  RequiredArgsCurrent;
735     UINT32                  RequiredArgsOld;
736
737
738     /* Check for a match against the reserved name list */
739
740     Index = AnCheckForReservedName (Op, Op->Asl.NameSeg);
741
742     switch (Index)
743     {
744     case ACPI_NOT_RESERVED_NAME:
745     case ACPI_PREDEFINED_NAME:
746     case ACPI_COMPILER_RESERVED_NAME:
747
748         /* Just return, nothing to do */
749         break;
750
751
752     case ACPI_EVENT_RESERVED_NAME:
753
754         Gbl_ReservedMethods++;
755
756         /* NumArguments must be zero for all _Lxx, _Exx, and _Qxx methods */
757
758         if (MethodInfo->NumArguments != 0)
759         {
760             sprintf (MsgBuffer, "%s requires %d",
761                         Op->Asl.ExternalName, 0);
762
763             AslError (ASL_WARNING, ASL_MSG_RESERVED_ARG_COUNT_HI, Op, MsgBuffer);
764         }
765         break;
766
767
768     default:
769
770         Gbl_ReservedMethods++;
771
772         /*
773          * Matched a reserved method name
774          *
775          * Validate the ASL-defined argument count. Allow two different legal
776          * arg counts.
777          */
778         RequiredArgsCurrent = ReservedMethods[Index].NumArguments & 0x0F;
779         RequiredArgsOld = ReservedMethods[Index].NumArguments >> 4;
780
781         if ((MethodInfo->NumArguments != RequiredArgsCurrent) &&
782             (MethodInfo->NumArguments != RequiredArgsOld))
783         {
784             sprintf (MsgBuffer, "%s requires %d",
785                         ReservedMethods[Index].Name,
786                         RequiredArgsCurrent);
787
788             if (MethodInfo->NumArguments > RequiredArgsCurrent)
789             {
790                 AslError (ASL_WARNING, ASL_MSG_RESERVED_ARG_COUNT_HI, Op,
791                     MsgBuffer);
792             }
793             else
794             {
795                 AslError (ASL_WARNING, ASL_MSG_RESERVED_ARG_COUNT_LO, Op,
796                     MsgBuffer);
797             }
798         }
799
800         if (MethodInfo->NumReturnNoValue &&
801             ReservedMethods[Index].Flags & ASL_RSVD_RETURN_VALUE)
802         {
803             sprintf (MsgBuffer, "%s", ReservedMethods[Index].Name);
804
805             AslError (ASL_WARNING, ASL_MSG_RESERVED_RETURN_VALUE, Op, MsgBuffer);
806         }
807         break;
808     }
809 }
810
811
812 /*******************************************************************************
813  *
814  * FUNCTION:    AnMapObjTypeToBtype
815  *
816  * PARAMETERS:  Op              - A parse node
817  *
818  * RETURN:      A Btype
819  *
820  * DESCRIPTION: Map object to the associated "Btype"
821  *
822  ******************************************************************************/
823
824 static UINT32
825 AnMapObjTypeToBtype (
826     ACPI_PARSE_OBJECT       *Op)
827 {
828
829     switch (Op->Asl.ParseOpcode)
830     {
831     case PARSEOP_OBJECTTYPE_BFF:        /* "BuffFieldObj" */
832         return (ACPI_BTYPE_BUFFER_FIELD);
833
834     case PARSEOP_OBJECTTYPE_BUF:        /* "BuffObj" */
835         return (ACPI_BTYPE_BUFFER);
836
837     case PARSEOP_OBJECTTYPE_DDB:        /* "DDBHandleObj" */
838         return (ACPI_BTYPE_DDB_HANDLE);
839
840     case PARSEOP_OBJECTTYPE_DEV:        /* "DeviceObj" */
841         return (ACPI_BTYPE_DEVICE);
842
843     case PARSEOP_OBJECTTYPE_EVT:        /* "EventObj" */
844         return (ACPI_BTYPE_EVENT);
845
846     case PARSEOP_OBJECTTYPE_FLD:        /* "FieldUnitObj" */
847         return (ACPI_BTYPE_FIELD_UNIT);
848
849     case PARSEOP_OBJECTTYPE_INT:        /* "IntObj" */
850         return (ACPI_BTYPE_INTEGER);
851
852     case PARSEOP_OBJECTTYPE_MTH:        /* "MethodObj" */
853         return (ACPI_BTYPE_METHOD);
854
855     case PARSEOP_OBJECTTYPE_MTX:        /* "MutexObj" */
856         return (ACPI_BTYPE_MUTEX);
857
858     case PARSEOP_OBJECTTYPE_OPR:        /* "OpRegionObj" */
859         return (ACPI_BTYPE_REGION);
860
861     case PARSEOP_OBJECTTYPE_PKG:        /* "PkgObj" */
862         return (ACPI_BTYPE_PACKAGE);
863
864     case PARSEOP_OBJECTTYPE_POW:        /* "PowerResObj" */
865         return (ACPI_BTYPE_POWER);
866
867     case PARSEOP_OBJECTTYPE_STR:        /* "StrObj" */
868         return (ACPI_BTYPE_STRING);
869
870     case PARSEOP_OBJECTTYPE_THZ:        /* "ThermalZoneObj" */
871         return (ACPI_BTYPE_THERMAL);
872
873     case PARSEOP_OBJECTTYPE_UNK:        /* "UnknownObj" */
874         return (ACPI_BTYPE_OBJECTS_AND_REFS);
875
876     default:
877         return (0);
878     }
879 }
880
881
882 /*******************************************************************************
883  *
884  * FUNCTION:    AnMethodAnalysisWalkBegin
885  *
886  * PARAMETERS:  ASL_WALK_CALLBACK
887  *
888  * RETURN:      Status
889  *
890  * DESCRIPTION: Descending callback for the analysis walk. Check methods for:
891  *              1) Initialized local variables
892  *              2) Valid arguments
893  *              3) Return types
894  *
895  ******************************************************************************/
896
897 ACPI_STATUS
898 AnMethodAnalysisWalkBegin (
899     ACPI_PARSE_OBJECT       *Op,
900     UINT32                  Level,
901     void                    *Context)
902 {
903     ASL_ANALYSIS_WALK_INFO  *WalkInfo = (ASL_ANALYSIS_WALK_INFO *) Context;
904     ASL_METHOD_INFO         *MethodInfo = WalkInfo->MethodStack;
905     ACPI_PARSE_OBJECT       *Next;
906     UINT32                  RegisterNumber;
907     UINT32                  i;
908     char                    LocalName[] = "Local0";
909     char                    ArgName[] = "Arg0";
910     ACPI_PARSE_OBJECT       *ArgNode;
911     ACPI_PARSE_OBJECT       *NextType;
912     ACPI_PARSE_OBJECT       *NextParamType;
913     UINT8                   ActualArgs = 0;
914
915
916     switch (Op->Asl.ParseOpcode)
917     {
918     case PARSEOP_METHOD:
919
920         TotalMethods++;
921
922         /* Create and init method info */
923
924         MethodInfo       = UtLocalCalloc (sizeof (ASL_METHOD_INFO));
925         MethodInfo->Next = WalkInfo->MethodStack;
926         MethodInfo->Op = Op;
927
928         WalkInfo->MethodStack = MethodInfo;
929
930         /* Get the name node, ignored here */
931
932         Next = Op->Asl.Child;
933
934         /* Get the NumArguments node */
935
936         Next = Next->Asl.Next;
937         MethodInfo->NumArguments = (UINT8)
938             (((UINT8) Next->Asl.Value.Integer) & 0x07);
939
940         /* Get the SerializeRule and SyncLevel nodes, ignored here */
941
942         Next = Next->Asl.Next;
943         Next = Next->Asl.Next;
944         ArgNode = Next;
945
946         /* Get the ReturnType node */
947
948         Next = Next->Asl.Next;
949
950         NextType = Next->Asl.Child;
951         while (NextType)
952         {
953             /* Get and map each of the ReturnTypes */
954
955             MethodInfo->ValidReturnTypes |= AnMapObjTypeToBtype (NextType);
956             NextType->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
957             NextType = NextType->Asl.Next;
958         }
959
960         /* Get the ParameterType node */
961
962         Next = Next->Asl.Next;
963
964         NextType = Next->Asl.Child;
965         while (NextType)
966         {
967             if (NextType->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
968             {
969                 NextParamType = NextType->Asl.Child;
970                 while (NextParamType)
971                 {
972                     MethodInfo->ValidArgTypes[ActualArgs] |= AnMapObjTypeToBtype (NextParamType);
973                     NextParamType->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
974                     NextParamType = NextParamType->Asl.Next;
975                 }
976             }
977             else
978             {
979                 MethodInfo->ValidArgTypes[ActualArgs] =
980                     AnMapObjTypeToBtype (NextType);
981                 NextType->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
982                 ActualArgs++;
983             }
984
985             NextType = NextType->Asl.Next;
986         }
987
988         if ((MethodInfo->NumArguments) &&
989             (MethodInfo->NumArguments != ActualArgs))
990         {
991             /* error: Param list did not match number of args */
992         }
993
994         /* Allow numarguments == 0 for Function() */
995
996         if ((!MethodInfo->NumArguments) && (ActualArgs))
997         {
998             MethodInfo->NumArguments = ActualArgs;
999             ArgNode->Asl.Value.Integer |= ActualArgs;
1000         }
1001
1002         /*
1003          * Actual arguments are initialized at method entry.
1004          * All other ArgX "registers" can be used as locals, so we
1005          * track their initialization.
1006          */
1007         for (i = 0; i < MethodInfo->NumArguments; i++)
1008         {
1009             MethodInfo->ArgInitialized[i] = TRUE;
1010         }
1011         break;
1012
1013
1014     case PARSEOP_METHODCALL:
1015
1016         if (MethodInfo &&
1017            (Op->Asl.Node == MethodInfo->Op->Asl.Node))
1018         {
1019             AslError (ASL_REMARK, ASL_MSG_RECURSION, Op, Op->Asl.ExternalName);
1020         }
1021         break;
1022
1023
1024     case PARSEOP_LOCAL0:
1025     case PARSEOP_LOCAL1:
1026     case PARSEOP_LOCAL2:
1027     case PARSEOP_LOCAL3:
1028     case PARSEOP_LOCAL4:
1029     case PARSEOP_LOCAL5:
1030     case PARSEOP_LOCAL6:
1031     case PARSEOP_LOCAL7:
1032
1033         if (!MethodInfo)
1034         {
1035             /*
1036              * Local was used outside a control method, or there was an error
1037              * in the method declaration.
1038              */
1039             AslError (ASL_REMARK, ASL_MSG_LOCAL_OUTSIDE_METHOD, Op, Op->Asl.ExternalName);
1040             return (AE_ERROR);
1041         }
1042
1043         RegisterNumber = (Op->Asl.AmlOpcode & 0x000F);
1044
1045         /*
1046          * If the local is being used as a target, mark the local
1047          * initialized
1048          */
1049         if (Op->Asl.CompileFlags & NODE_IS_TARGET)
1050         {
1051             MethodInfo->LocalInitialized[RegisterNumber] = TRUE;
1052         }
1053
1054         /*
1055          * Otherwise, this is a reference, check if the local
1056          * has been previously initialized.
1057          *
1058          * The only operator that accepts an uninitialized value is ObjectType()
1059          */
1060         else if ((!MethodInfo->LocalInitialized[RegisterNumber]) &&
1061                  (Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_OBJECTTYPE))
1062         {
1063             LocalName[strlen (LocalName) -1] = (char) (RegisterNumber + 0x30);
1064             AslError (ASL_ERROR, ASL_MSG_LOCAL_INIT, Op, LocalName);
1065         }
1066         break;
1067
1068
1069     case PARSEOP_ARG0:
1070     case PARSEOP_ARG1:
1071     case PARSEOP_ARG2:
1072     case PARSEOP_ARG3:
1073     case PARSEOP_ARG4:
1074     case PARSEOP_ARG5:
1075     case PARSEOP_ARG6:
1076
1077         if (!MethodInfo)
1078         {
1079             /*
1080              * Arg was used outside a control method, or there was an error
1081              * in the method declaration.
1082              */
1083             AslError (ASL_REMARK, ASL_MSG_LOCAL_OUTSIDE_METHOD, Op, Op->Asl.ExternalName);
1084             return (AE_ERROR);
1085         }
1086
1087         RegisterNumber = (Op->Asl.AmlOpcode & 0x000F) - 8;
1088         ArgName[strlen (ArgName) -1] = (char) (RegisterNumber + 0x30);
1089
1090         /*
1091          * If the Arg is being used as a target, mark the local
1092          * initialized
1093          */
1094         if (Op->Asl.CompileFlags & NODE_IS_TARGET)
1095         {
1096             MethodInfo->ArgInitialized[RegisterNumber] = TRUE;
1097         }
1098
1099         /*
1100          * Otherwise, this is a reference, check if the Arg
1101          * has been previously initialized.
1102          *
1103          * The only operator that accepts an uninitialized value is ObjectType()
1104          */
1105         else if ((!MethodInfo->ArgInitialized[RegisterNumber]) &&
1106                  (Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_OBJECTTYPE))
1107         {
1108             AslError (ASL_ERROR, ASL_MSG_ARG_INIT, Op, ArgName);
1109         }
1110
1111         /* Flag this arg if it is not a "real" argument to the method */
1112
1113         if (RegisterNumber >= MethodInfo->NumArguments)
1114         {
1115             AslError (ASL_REMARK, ASL_MSG_NOT_PARAMETER, Op, ArgName);
1116         }
1117         break;
1118
1119
1120     case PARSEOP_RETURN:
1121
1122         if (!MethodInfo)
1123         {
1124             /*
1125              * Probably was an error in the method declaration,
1126              * no additional error here
1127              */
1128             ACPI_WARNING ((AE_INFO, "%p, No parent method", Op));
1129             return (AE_ERROR);
1130         }
1131
1132         /* Child indicates a return value */
1133
1134         if ((Op->Asl.Child) &&
1135             (Op->Asl.Child->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG))
1136         {
1137             MethodInfo->NumReturnWithValue++;
1138         }
1139         else
1140         {
1141             MethodInfo->NumReturnNoValue++;
1142         }
1143         break;
1144
1145
1146     case PARSEOP_BREAK:
1147     case PARSEOP_CONTINUE:
1148
1149         Next = Op->Asl.Parent;
1150         while (Next)
1151         {
1152             if (Next->Asl.ParseOpcode == PARSEOP_WHILE)
1153             {
1154                 break;
1155             }
1156             Next = Next->Asl.Parent;
1157         }
1158
1159         if (!Next)
1160         {
1161             AslError (ASL_ERROR, ASL_MSG_NO_WHILE, Op, NULL);
1162         }
1163         break;
1164
1165
1166     case PARSEOP_STALL:
1167
1168         /* We can range check if the argument is an integer */
1169
1170         if ((Op->Asl.Child->Asl.ParseOpcode == PARSEOP_INTEGER) &&
1171             (Op->Asl.Child->Asl.Value.Integer > ACPI_UINT8_MAX))
1172         {
1173             AslError (ASL_ERROR, ASL_MSG_INVALID_TIME, Op, NULL);
1174         }
1175         break;
1176
1177
1178     case PARSEOP_DEVICE:
1179     case PARSEOP_EVENT:
1180     case PARSEOP_MUTEX:
1181     case PARSEOP_OPERATIONREGION:
1182     case PARSEOP_POWERRESOURCE:
1183     case PARSEOP_PROCESSOR:
1184     case PARSEOP_THERMALZONE:
1185
1186         /*
1187          * The first operand is a name to be created in the namespace.
1188          * Check against the reserved list.
1189          */
1190         i = AnCheckForReservedName (Op, Op->Asl.NameSeg);
1191         if (i < ACPI_VALID_RESERVED_NAME_MAX)
1192         {
1193             AslError (ASL_ERROR, ASL_MSG_RESERVED_USE, Op, Op->Asl.ExternalName);
1194         }
1195         break;
1196
1197
1198     case PARSEOP_NAME:
1199
1200         i = AnCheckForReservedName (Op, Op->Asl.NameSeg);
1201         if (i < ACPI_VALID_RESERVED_NAME_MAX)
1202         {
1203             if (ReservedMethods[i].NumArguments > 0)
1204             {
1205                 /*
1206                  * This reserved name must be a control method because
1207                  * it must have arguments
1208                  */
1209                 AslError (ASL_ERROR, ASL_MSG_RESERVED_METHOD, Op,
1210                     "with arguments");
1211             }
1212
1213             /* Typechecking for _HID */
1214
1215             else if (!ACPI_STRCMP (METHOD_NAME__HID, ReservedMethods[i].Name))
1216             {
1217                 /* Examine the second operand to typecheck it */
1218
1219                 Next = Op->Asl.Child->Asl.Next;
1220
1221                 if ((Next->Asl.ParseOpcode != PARSEOP_INTEGER) &&
1222                     (Next->Asl.ParseOpcode != PARSEOP_STRING_LITERAL))
1223                 {
1224                     /* _HID must be a string or an integer */
1225
1226                     AslError (ASL_ERROR, ASL_MSG_RESERVED_OPERAND_TYPE, Next,
1227                         "String or Integer");
1228                 }
1229
1230                 if (Next->Asl.ParseOpcode == PARSEOP_STRING_LITERAL)
1231                 {
1232                     /*
1233                      * _HID is a string, all characters must be alphanumeric.
1234                      * One of the things we want to catch here is the use of
1235                      * a leading asterisk in the string.
1236                      */
1237                     for (i = 0; Next->Asl.Value.String[i]; i++)
1238                     {
1239                         if (!isalnum (Next->Asl.Value.String[i]))
1240                         {
1241                             AslError (ASL_ERROR, ASL_MSG_ALPHANUMERIC_STRING,
1242                                 Next, Next->Asl.Value.String);
1243                             break;
1244                         }
1245                     }
1246                 }
1247             }
1248         }
1249         break;
1250
1251
1252     default:
1253         break;
1254     }
1255
1256     return AE_OK;
1257 }
1258
1259
1260 /*******************************************************************************
1261  *
1262  * FUNCTION:    AnLastStatementIsReturn
1263  *
1264  * PARAMETERS:  Op            - A method parse node
1265  *
1266  * RETURN:      TRUE if last statement is an ASL RETURN. False otherwise
1267  *
1268  * DESCRIPTION: Walk down the list of top level statements within a method
1269  *              to find the last one. Check if that last statement is in
1270  *              fact a RETURN statement.
1271  *
1272  ******************************************************************************/
1273
1274 static BOOLEAN
1275 AnLastStatementIsReturn (
1276     ACPI_PARSE_OBJECT       *Op)
1277 {
1278     ACPI_PARSE_OBJECT       *Next;
1279
1280
1281     /*
1282      * Check if last statement is a return
1283      */
1284     Next = ASL_GET_CHILD_NODE (Op);
1285     while (Next)
1286     {
1287         if ((!Next->Asl.Next) &&
1288             (Next->Asl.ParseOpcode == PARSEOP_RETURN))
1289         {
1290             return TRUE;
1291         }
1292
1293         Next = ASL_GET_PEER_NODE (Next);
1294     }
1295
1296     return FALSE;
1297 }
1298
1299
1300 /*******************************************************************************
1301  *
1302  * FUNCTION:    AnMethodAnalysisWalkEnd
1303  *
1304  * PARAMETERS:  ASL_WALK_CALLBACK
1305  *
1306  * RETURN:      Status
1307  *
1308  * DESCRIPTION: Ascending callback for analysis walk. Complete method
1309  *              return analysis.
1310  *
1311  ******************************************************************************/
1312
1313 ACPI_STATUS
1314 AnMethodAnalysisWalkEnd (
1315     ACPI_PARSE_OBJECT       *Op,
1316     UINT32                  Level,
1317     void                    *Context)
1318 {
1319     ASL_ANALYSIS_WALK_INFO  *WalkInfo = (ASL_ANALYSIS_WALK_INFO *) Context;
1320     ASL_METHOD_INFO         *MethodInfo = WalkInfo->MethodStack;
1321
1322
1323     switch (Op->Asl.ParseOpcode)
1324     {
1325     case PARSEOP_METHOD:
1326     case PARSEOP_RETURN:
1327         if (!MethodInfo)
1328         {
1329             printf ("No method info for method! [%s]\n", Op->Asl.Namepath);
1330             AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, Op,
1331                 "No method info for this method");
1332             CmCleanupAndExit ();
1333             return (AE_AML_INTERNAL);
1334         }
1335         break;
1336
1337     default:
1338         break;
1339     }
1340
1341     switch (Op->Asl.ParseOpcode)
1342     {
1343     case PARSEOP_METHOD:
1344
1345         WalkInfo->MethodStack = MethodInfo->Next;
1346
1347         /*
1348          * Check if there is no return statement at the end of the
1349          * method AND we can actually get there -- i.e., the execution
1350          * of the method can possibly terminate without a return statement.
1351          */
1352         if ((!AnLastStatementIsReturn (Op)) &&
1353             (!(Op->Asl.CompileFlags & NODE_HAS_NO_EXIT)))
1354         {
1355             /*
1356              * No return statement, and execution can possibly exit
1357              * via this path. This is equivalent to Return ()
1358              */
1359             MethodInfo->NumReturnNoValue++;
1360         }
1361
1362         /*
1363          * Check for case where some return statements have a return value
1364          * and some do not. Exit without a return statement is a return with
1365          * no value
1366          */
1367         if (MethodInfo->NumReturnNoValue &&
1368             MethodInfo->NumReturnWithValue)
1369         {
1370             AslError (ASL_WARNING, ASL_MSG_RETURN_TYPES, Op,
1371                 Op->Asl.ExternalName);
1372         }
1373
1374         /*
1375          * If there are any RETURN() statements with no value, or there is a
1376          * control path that allows the method to exit without a return value,
1377          * we mark the method as a method that does not return a value. This
1378          * knowledge can be used to check method invocations that expect a
1379          * returned value.
1380          */
1381         if (MethodInfo->NumReturnNoValue)
1382         {
1383             if (MethodInfo->NumReturnWithValue)
1384             {
1385                 Op->Asl.CompileFlags |= NODE_METHOD_SOME_NO_RETVAL;
1386             }
1387             else
1388             {
1389                 Op->Asl.CompileFlags |= NODE_METHOD_NO_RETVAL;
1390             }
1391         }
1392
1393         /*
1394          * Check predefined method names for correct return behavior
1395          * and correct number of arguments
1396          */
1397         AnCheckForReservedMethod (Op, MethodInfo);
1398         ACPI_FREE (MethodInfo);
1399         break;
1400
1401
1402     case PARSEOP_RETURN:
1403
1404         /*
1405          * The parent block does not "exit" and continue execution -- the
1406          * method is terminated here with the Return() statement.
1407          */
1408         Op->Asl.Parent->Asl.CompileFlags |= NODE_HAS_NO_EXIT;
1409
1410         /* Used in the "typing" pass later */
1411
1412         Op->Asl.ParentMethod = MethodInfo->Op;
1413
1414         /*
1415          * If there is a peer node after the return statement, then this
1416          * node is unreachable code -- i.e., it won't be executed because of
1417          * the preceeding Return() statement.
1418          */
1419         if (Op->Asl.Next)
1420         {
1421             AslError (ASL_WARNING, ASL_MSG_UNREACHABLE_CODE, Op->Asl.Next, NULL);
1422         }
1423         break;
1424
1425
1426     case PARSEOP_IF:
1427
1428         if ((Op->Asl.CompileFlags & NODE_HAS_NO_EXIT) &&
1429             (Op->Asl.Next) &&
1430             (Op->Asl.Next->Asl.ParseOpcode == PARSEOP_ELSE))
1431         {
1432             /*
1433              * This IF has a corresponding ELSE. The IF block has no exit,
1434              * (it contains an unconditional Return)
1435              * mark the ELSE block to remember this fact.
1436              */
1437             Op->Asl.Next->Asl.CompileFlags |= NODE_IF_HAS_NO_EXIT;
1438         }
1439         break;
1440
1441
1442     case PARSEOP_ELSE:
1443
1444         if ((Op->Asl.CompileFlags & NODE_HAS_NO_EXIT) &&
1445             (Op->Asl.CompileFlags & NODE_IF_HAS_NO_EXIT))
1446         {
1447             /*
1448              * This ELSE block has no exit and the corresponding IF block
1449              * has no exit either. Therefore, the parent node has no exit.
1450              */
1451             Op->Asl.Parent->Asl.CompileFlags |= NODE_HAS_NO_EXIT;
1452         }
1453         break;
1454
1455
1456     default:
1457
1458         if ((Op->Asl.CompileFlags & NODE_HAS_NO_EXIT) &&
1459             (Op->Asl.Parent))
1460         {
1461             /* If this node has no exit, then the parent has no exit either */
1462
1463             Op->Asl.Parent->Asl.CompileFlags |= NODE_HAS_NO_EXIT;
1464         }
1465         break;
1466     }
1467
1468     return AE_OK;
1469 }
1470
1471
1472 /*******************************************************************************
1473  *
1474  * FUNCTION:    AnMethodTypingWalkBegin
1475  *
1476  * PARAMETERS:  ASL_WALK_CALLBACK
1477  *
1478  * RETURN:      Status
1479  *
1480  * DESCRIPTION: Descending callback for the typing walk.
1481  *
1482  ******************************************************************************/
1483
1484 ACPI_STATUS
1485 AnMethodTypingWalkBegin (
1486     ACPI_PARSE_OBJECT       *Op,
1487     UINT32                  Level,
1488     void                    *Context)
1489 {
1490
1491     return AE_OK;
1492 }
1493
1494
1495 /*******************************************************************************
1496  *
1497  * FUNCTION:    AnMethodTypingWalkEnd
1498  *
1499  * PARAMETERS:  ASL_WALK_CALLBACK
1500  *
1501  * RETURN:      Status
1502  *
1503  * DESCRIPTION: Ascending callback for typing walk. Complete the method
1504  *              return analysis. Check methods for:
1505  *              1) Initialized local variables
1506  *              2) Valid arguments
1507  *              3) Return types
1508  *
1509  ******************************************************************************/
1510
1511 ACPI_STATUS
1512 AnMethodTypingWalkEnd (
1513     ACPI_PARSE_OBJECT       *Op,
1514     UINT32                  Level,
1515     void                    *Context)
1516 {
1517     UINT32                  ThisNodeBtype;
1518
1519
1520     switch (Op->Asl.ParseOpcode)
1521     {
1522     case PARSEOP_METHOD:
1523
1524         Op->Asl.CompileFlags |= NODE_METHOD_TYPED;
1525         break;
1526
1527     case PARSEOP_RETURN:
1528
1529         if ((Op->Asl.Child) &&
1530             (Op->Asl.Child->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG))
1531         {
1532             ThisNodeBtype = AnGetBtype (Op->Asl.Child);
1533
1534             if ((Op->Asl.Child->Asl.ParseOpcode == PARSEOP_METHODCALL) &&
1535                 (ThisNodeBtype == (ACPI_UINT32_MAX -1)))
1536             {
1537                 /*
1538                  * The called method is untyped at this time (typically a
1539                  * forward reference).
1540                  *
1541                  * Check for a recursive method call first.
1542                  */
1543                 if (Op->Asl.ParentMethod != Op->Asl.Child->Asl.Node->Op)
1544                 {
1545                     /* We must type the method here */
1546
1547                     TrWalkParseTree (Op->Asl.Child->Asl.Node->Op,
1548                         ASL_WALK_VISIT_TWICE, AnMethodTypingWalkBegin,
1549                         AnMethodTypingWalkEnd, NULL);
1550
1551                     ThisNodeBtype = AnGetBtype (Op->Asl.Child);
1552                 }
1553             }
1554
1555             /* Returns a value, save the value type */
1556
1557             if (Op->Asl.ParentMethod)
1558             {
1559                 Op->Asl.ParentMethod->Asl.AcpiBtype |= ThisNodeBtype;
1560             }
1561         }
1562         break;
1563
1564     default:
1565         break;
1566     }
1567
1568     return AE_OK;
1569 }
1570
1571
1572 /*******************************************************************************
1573  *
1574  * FUNCTION:    AnCheckMethodReturnValue
1575  *
1576  * PARAMETERS:  Op                  - Parent
1577  *              OpInfo              - Parent info
1578  *              ArgOp               - Method invocation op
1579  *              RequiredBtypes      - What caller requires
1580  *              ThisNodeBtype       - What this node returns (if anything)
1581  *
1582  * RETURN:      None
1583  *
1584  * DESCRIPTION: Check a method invocation for 1) A return value and if it does
1585  *              in fact return a value, 2) check the type of the return value.
1586  *
1587  ******************************************************************************/
1588
1589 static void
1590 AnCheckMethodReturnValue (
1591     ACPI_PARSE_OBJECT       *Op,
1592     const ACPI_OPCODE_INFO  *OpInfo,
1593     ACPI_PARSE_OBJECT       *ArgOp,
1594     UINT32                  RequiredBtypes,
1595     UINT32                  ThisNodeBtype)
1596 {
1597     ACPI_PARSE_OBJECT       *OwningOp;
1598     ACPI_NAMESPACE_NODE     *Node;
1599
1600
1601     Node = ArgOp->Asl.Node;
1602
1603
1604     /* Examine the parent op of this method */
1605
1606     OwningOp = Node->Op;
1607     if (OwningOp->Asl.CompileFlags & NODE_METHOD_NO_RETVAL)
1608     {
1609         /* Method NEVER returns a value */
1610
1611         AslError (ASL_ERROR, ASL_MSG_NO_RETVAL, Op, Op->Asl.ExternalName);
1612     }
1613     else if (OwningOp->Asl.CompileFlags & NODE_METHOD_SOME_NO_RETVAL)
1614     {
1615         /* Method SOMETIMES returns a value, SOMETIMES not */
1616
1617         AslError (ASL_WARNING, ASL_MSG_SOME_NO_RETVAL, Op, Op->Asl.ExternalName);
1618     }
1619     else if (!(ThisNodeBtype & RequiredBtypes))
1620     {
1621         /* Method returns a value, but the type is wrong */
1622
1623         AnFormatBtype (StringBuffer, ThisNodeBtype);
1624         AnFormatBtype (StringBuffer2, RequiredBtypes);
1625
1626
1627         /*
1628          * The case where the method does not return any value at all
1629          * was already handled in the namespace cross reference
1630          * -- Only issue an error if the method in fact returns a value,
1631          * but it is of the wrong type
1632          */
1633         if (ThisNodeBtype != 0)
1634         {
1635             sprintf (MsgBuffer,
1636                 "Method returns [%s], %s operator requires [%s]",
1637                 StringBuffer, OpInfo->Name, StringBuffer2);
1638
1639             AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, ArgOp, MsgBuffer);
1640         }
1641     }
1642 }
1643
1644
1645 /*******************************************************************************
1646  *
1647  * FUNCTION:    AnOperandTypecheckWalkBegin
1648  *
1649  * PARAMETERS:  ASL_WALK_CALLBACK
1650  *
1651  * RETURN:      Status
1652  *
1653  * DESCRIPTION: Descending callback for the analysis walk. Check methods for:
1654  *              1) Initialized local variables
1655  *              2) Valid arguments
1656  *              3) Return types
1657  *
1658  ******************************************************************************/
1659
1660 ACPI_STATUS
1661 AnOperandTypecheckWalkBegin (
1662     ACPI_PARSE_OBJECT       *Op,
1663     UINT32                  Level,
1664     void                    *Context)
1665 {
1666
1667     return AE_OK;
1668 }
1669
1670
1671 /*******************************************************************************
1672  *
1673  * FUNCTION:    AnOperandTypecheckWalkEnd
1674  *
1675  * PARAMETERS:  ASL_WALK_CALLBACK
1676  *
1677  * RETURN:      Status
1678  *
1679  * DESCRIPTION: Ascending callback for analysis walk. Complete method
1680  *              return analysis.
1681  *
1682  ******************************************************************************/
1683
1684 ACPI_STATUS
1685 AnOperandTypecheckWalkEnd (
1686     ACPI_PARSE_OBJECT       *Op,
1687     UINT32                  Level,
1688     void                    *Context)
1689 {
1690     const ACPI_OPCODE_INFO  *OpInfo;
1691     UINT32                  RuntimeArgTypes;
1692     UINT32                  RuntimeArgTypes2;
1693     UINT32                  RequiredBtypes;
1694     UINT32                  ThisNodeBtype;
1695     UINT32                  CommonBtypes;
1696     UINT32                  OpcodeClass;
1697     ACPI_PARSE_OBJECT       *ArgOp;
1698     UINT32                  ArgType;
1699
1700
1701     switch (Op->Asl.AmlOpcode)
1702     {
1703     case AML_RAW_DATA_BYTE:
1704     case AML_RAW_DATA_WORD:
1705     case AML_RAW_DATA_DWORD:
1706     case AML_RAW_DATA_QWORD:
1707     case AML_RAW_DATA_BUFFER:
1708     case AML_RAW_DATA_CHAIN:
1709     case AML_PACKAGE_LENGTH:
1710     case AML_UNASSIGNED_OPCODE:
1711     case AML_DEFAULT_ARG_OP:
1712
1713         /* Ignore the internal (compiler-only) AML opcodes */
1714
1715         return (AE_OK);
1716
1717     default:
1718         break;
1719     }
1720
1721     OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
1722     if (!OpInfo)
1723     {
1724         return (AE_OK);
1725     }
1726
1727     ArgOp           = Op->Asl.Child;
1728     RuntimeArgTypes = OpInfo->RuntimeArgs;
1729     OpcodeClass     = OpInfo->Class;
1730
1731 #ifdef ASL_ERROR_NAMED_OBJECT_IN_WHILE
1732     /*
1733      * Update 11/2008: In practice, we can't perform this check. A simple
1734      * analysis is not sufficient. Also, it can cause errors when compiling
1735      * disassembled code because of the way Switch operators are implemented
1736      * (a While(One) loop with a named temp variable created within.)
1737      */
1738
1739     /*
1740      * If we are creating a named object, check if we are within a while loop
1741      * by checking if the parent is a WHILE op. This is a simple analysis, but
1742      * probably sufficient for many cases.
1743      *
1744      * Allow Scope(), Buffer(), and Package().
1745      */
1746     if (((OpcodeClass == AML_CLASS_NAMED_OBJECT) && (Op->Asl.AmlOpcode != AML_SCOPE_OP)) ||
1747         ((OpcodeClass == AML_CLASS_CREATE) && (OpInfo->Flags & AML_NSNODE)))
1748     {
1749         if (Op->Asl.Parent->Asl.AmlOpcode == AML_WHILE_OP)
1750         {
1751             AslError (ASL_ERROR, ASL_MSG_NAMED_OBJECT_IN_WHILE, Op, NULL);
1752         }
1753     }
1754 #endif
1755
1756     /*
1757      * Special case for control opcodes IF/RETURN/WHILE since they
1758      * have no runtime arg list (at this time)
1759      */
1760     switch (Op->Asl.AmlOpcode)
1761     {
1762     case AML_IF_OP:
1763     case AML_WHILE_OP:
1764     case AML_RETURN_OP:
1765
1766         if (ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL)
1767         {
1768             /* Check for an internal method */
1769
1770             if (AnIsInternalMethod (ArgOp))
1771             {
1772                 return (AE_OK);
1773             }
1774
1775             /* The lone arg is a method call, check it */
1776
1777             RequiredBtypes = AnMapArgTypeToBtype (ARGI_INTEGER);
1778             if (Op->Asl.AmlOpcode == AML_RETURN_OP)
1779             {
1780                 RequiredBtypes = 0xFFFFFFFF;
1781             }
1782
1783             ThisNodeBtype = AnGetBtype (ArgOp);
1784             if (ThisNodeBtype == ACPI_UINT32_MAX)
1785             {
1786                 return (AE_OK);
1787             }
1788             AnCheckMethodReturnValue (Op, OpInfo, ArgOp,
1789                 RequiredBtypes, ThisNodeBtype);
1790         }
1791         return (AE_OK);
1792
1793     default:
1794         break;
1795     }
1796
1797     /* Ignore the non-executable opcodes */
1798
1799     if (RuntimeArgTypes == ARGI_INVALID_OPCODE)
1800     {
1801         return (AE_OK);
1802     }
1803
1804     switch (OpcodeClass)
1805     {
1806     case AML_CLASS_EXECUTE:
1807     case AML_CLASS_CREATE:
1808     case AML_CLASS_CONTROL:
1809     case AML_CLASS_RETURN_VALUE:
1810
1811         /* TBD: Change class or fix typechecking for these */
1812
1813         if ((Op->Asl.AmlOpcode == AML_BUFFER_OP)        ||
1814             (Op->Asl.AmlOpcode == AML_PACKAGE_OP)       ||
1815             (Op->Asl.AmlOpcode == AML_VAR_PACKAGE_OP))
1816         {
1817             break;
1818         }
1819
1820         /* Reverse the runtime argument list */
1821
1822         RuntimeArgTypes2 = 0;
1823         while ((ArgType = GET_CURRENT_ARG_TYPE (RuntimeArgTypes)))
1824         {
1825             RuntimeArgTypes2 <<= ARG_TYPE_WIDTH;
1826             RuntimeArgTypes2 |= ArgType;
1827             INCREMENT_ARG_LIST (RuntimeArgTypes);
1828         }
1829
1830         while ((ArgType = GET_CURRENT_ARG_TYPE (RuntimeArgTypes2)))
1831         {
1832             RequiredBtypes = AnMapArgTypeToBtype (ArgType);
1833
1834             ThisNodeBtype = AnGetBtype (ArgOp);
1835             if (ThisNodeBtype == ACPI_UINT32_MAX)
1836             {
1837                 goto NextArgument;
1838             }
1839
1840             /* Examine the arg based on the required type of the arg */
1841
1842             switch (ArgType)
1843             {
1844             case ARGI_TARGETREF:
1845
1846                 if (ArgOp->Asl.ParseOpcode == PARSEOP_ZERO)
1847                 {
1848                     /* ZERO is the placeholder for "don't store result" */
1849
1850                     ThisNodeBtype = RequiredBtypes;
1851                     break;
1852                 }
1853
1854                 if (ArgOp->Asl.ParseOpcode == PARSEOP_INTEGER)
1855                 {
1856                     /*
1857                      * This is the case where an original reference to a resource
1858                      * descriptor field has been replaced by an (Integer) offset.
1859                      * These named fields are supported at compile-time only;
1860                      * the names are not passed to the interpreter (via the AML).
1861                      */
1862                     if ((ArgOp->Asl.Node->Type == ACPI_TYPE_LOCAL_RESOURCE_FIELD) ||
1863                         (ArgOp->Asl.Node->Type == ACPI_TYPE_LOCAL_RESOURCE))
1864                     {
1865                         AslError (ASL_ERROR, ASL_MSG_RESOURCE_FIELD, ArgOp, NULL);
1866                     }
1867                     else
1868                     {
1869                         AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, ArgOp, NULL);
1870                     }
1871                     break;
1872                 }
1873
1874                 if ((ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL) ||
1875                     (ArgOp->Asl.ParseOpcode == PARSEOP_DEREFOF))
1876                 {
1877                     break;
1878                 }
1879
1880                 ThisNodeBtype = RequiredBtypes;
1881                 break;
1882
1883
1884             case ARGI_REFERENCE:            /* References */
1885             case ARGI_INTEGER_REF:
1886             case ARGI_OBJECT_REF:
1887             case ARGI_DEVICE_REF:
1888
1889                 switch (ArgOp->Asl.ParseOpcode)
1890                 {
1891                 case PARSEOP_LOCAL0:
1892                 case PARSEOP_LOCAL1:
1893                 case PARSEOP_LOCAL2:
1894                 case PARSEOP_LOCAL3:
1895                 case PARSEOP_LOCAL4:
1896                 case PARSEOP_LOCAL5:
1897                 case PARSEOP_LOCAL6:
1898                 case PARSEOP_LOCAL7:
1899
1900                     /* TBD: implement analysis of current value (type) of the local */
1901                     /* For now, just treat any local as a typematch */
1902
1903                     /*ThisNodeBtype = RequiredBtypes;*/
1904                     break;
1905
1906                 case PARSEOP_ARG0:
1907                 case PARSEOP_ARG1:
1908                 case PARSEOP_ARG2:
1909                 case PARSEOP_ARG3:
1910                 case PARSEOP_ARG4:
1911                 case PARSEOP_ARG5:
1912                 case PARSEOP_ARG6:
1913
1914                     /* Hard to analyze argument types, sow we won't */
1915                     /* For now, just treat any arg as a typematch */
1916
1917                     /* ThisNodeBtype = RequiredBtypes; */
1918                     break;
1919
1920                 case PARSEOP_DEBUG:
1921                     break;
1922
1923                 case PARSEOP_REFOF:
1924                 case PARSEOP_INDEX:
1925                 default:
1926                     break;
1927
1928                 }
1929                 break;
1930
1931             case ARGI_INTEGER:
1932             default:
1933                 break;
1934             }
1935
1936
1937             CommonBtypes = ThisNodeBtype & RequiredBtypes;
1938
1939             if (ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL)
1940             {
1941                 if (AnIsInternalMethod (ArgOp))
1942                 {
1943                     return (AE_OK);
1944                 }
1945
1946                 /* Check a method call for a valid return value */
1947
1948                 AnCheckMethodReturnValue (Op, OpInfo, ArgOp,
1949                     RequiredBtypes, ThisNodeBtype);
1950             }
1951
1952             /*
1953              * Now check if the actual type(s) match at least one
1954              * bit to the required type
1955              */
1956             else if (!CommonBtypes)
1957             {
1958                 /* No match -- this is a type mismatch error */
1959
1960                 AnFormatBtype (StringBuffer, ThisNodeBtype);
1961                 AnFormatBtype (StringBuffer2, RequiredBtypes);
1962
1963                 sprintf (MsgBuffer, "[%s] found, %s operator requires [%s]",
1964                             StringBuffer, OpInfo->Name, StringBuffer2);
1965
1966                 AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, ArgOp, MsgBuffer);
1967             }
1968
1969         NextArgument:
1970             ArgOp = ArgOp->Asl.Next;
1971             INCREMENT_ARG_LIST (RuntimeArgTypes2);
1972         }
1973         break;
1974
1975     default:
1976         break;
1977     }
1978
1979     return (AE_OK);
1980 }
1981
1982
1983 /*******************************************************************************
1984  *
1985  * FUNCTION:    AnIsResultUsed
1986  *
1987  * PARAMETERS:  Op              - Parent op for the operator
1988  *
1989  * RETURN:      TRUE if result from this operation is actually consumed
1990  *
1991  * DESCRIPTION: Determine if the function result value from an operator is
1992  *              used.
1993  *
1994  ******************************************************************************/
1995
1996 BOOLEAN
1997 AnIsResultUsed (
1998     ACPI_PARSE_OBJECT       *Op)
1999 {
2000     ACPI_PARSE_OBJECT       *Parent;
2001
2002
2003     switch (Op->Asl.ParseOpcode)
2004     {
2005     case PARSEOP_INCREMENT:
2006     case PARSEOP_DECREMENT:
2007
2008         /* These are standalone operators, no return value */
2009
2010         return (TRUE);
2011
2012     default:
2013         break;
2014     }
2015
2016     /* Examine parent to determine if the return value is used */
2017
2018     Parent = Op->Asl.Parent;
2019     switch (Parent->Asl.ParseOpcode)
2020     {
2021     /* If/While - check if the operator is the predicate */
2022
2023     case PARSEOP_IF:
2024     case PARSEOP_WHILE:
2025
2026         /* First child is the predicate */
2027
2028         if (Parent->Asl.Child == Op)
2029         {
2030             return (TRUE);
2031         }
2032         return (FALSE);
2033
2034     /* Not used if one of these is the parent */
2035
2036     case PARSEOP_METHOD:
2037     case PARSEOP_DEFINITIONBLOCK:
2038     case PARSEOP_ELSE:
2039
2040         return (FALSE);
2041
2042     default:
2043         /* Any other type of parent means that the result is used */
2044
2045         return (TRUE);
2046     }
2047 }
2048
2049
2050 /*******************************************************************************
2051  *
2052  * FUNCTION:    AnOtherSemanticAnalysisWalkBegin
2053  *
2054  * PARAMETERS:  ASL_WALK_CALLBACK
2055  *
2056  * RETURN:      Status
2057  *
2058  * DESCRIPTION: Descending callback for the analysis walk. Checks for
2059  *              miscellaneous issues in the code.
2060  *
2061  ******************************************************************************/
2062
2063 ACPI_STATUS
2064 AnOtherSemanticAnalysisWalkBegin (
2065     ACPI_PARSE_OBJECT       *Op,
2066     UINT32                  Level,
2067     void                    *Context)
2068 {
2069     ACPI_PARSE_OBJECT       *ArgNode;
2070     ACPI_PARSE_OBJECT       *PrevArgNode = NULL;
2071     const ACPI_OPCODE_INFO  *OpInfo;
2072
2073
2074     OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
2075
2076     /*
2077      * Determine if an execution class operator actually does something by
2078      * checking if it has a target and/or the function return value is used.
2079      * (Target is optional, so a standalone statement can actually do nothing.)
2080      */
2081     if ((OpInfo->Class == AML_CLASS_EXECUTE) &&
2082         (OpInfo->Flags & AML_HAS_RETVAL) &&
2083         (!AnIsResultUsed (Op)))
2084     {
2085         if (OpInfo->Flags & AML_HAS_TARGET)
2086         {
2087             /*
2088              * Find the target node, it is always the last child. If the traget
2089              * is not specified in the ASL, a default node of type Zero was
2090              * created by the parser.
2091              */
2092             ArgNode = Op->Asl.Child;
2093             while (ArgNode->Asl.Next)
2094             {
2095                 PrevArgNode = ArgNode;
2096                 ArgNode = ArgNode->Asl.Next;
2097             }
2098
2099             /* Divide() is the only weird case, it has two targets */
2100
2101             if (Op->Asl.AmlOpcode == AML_DIVIDE_OP)
2102             {
2103                 if ((ArgNode->Asl.ParseOpcode == PARSEOP_ZERO) &&
2104                     (PrevArgNode->Asl.ParseOpcode == PARSEOP_ZERO))
2105                 {
2106                     AslError (ASL_WARNING, ASL_MSG_RESULT_NOT_USED, Op, Op->Asl.ExternalName);
2107                 }
2108             }
2109             else if (ArgNode->Asl.ParseOpcode == PARSEOP_ZERO)
2110             {
2111                 AslError (ASL_WARNING, ASL_MSG_RESULT_NOT_USED, Op, Op->Asl.ExternalName);
2112             }
2113         }
2114         else
2115         {
2116             /*
2117              * Has no target and the result is not used. Only a couple opcodes
2118              * can have this combination.
2119              */
2120             switch (Op->Asl.ParseOpcode)
2121             {
2122             case PARSEOP_ACQUIRE:
2123             case PARSEOP_WAIT:
2124             case PARSEOP_LOADTABLE:
2125                 break;
2126
2127             default:
2128                 AslError (ASL_WARNING, ASL_MSG_RESULT_NOT_USED, Op, Op->Asl.ExternalName);
2129                 break;
2130             }
2131         }
2132     }
2133
2134
2135     /*
2136      * Semantic checks for individual ASL operators
2137      */
2138     switch (Op->Asl.ParseOpcode)
2139     {
2140     case PARSEOP_ACQUIRE:
2141     case PARSEOP_WAIT:
2142         /*
2143          * Emit a warning if the timeout parameter for these operators is not
2144          * ACPI_WAIT_FOREVER, and the result value from the operator is not
2145          * checked, meaning that a timeout could happen, but the code
2146          * would not know about it.
2147          */
2148
2149         /* First child is the namepath, 2nd child is timeout */
2150
2151         ArgNode = Op->Asl.Child;
2152         ArgNode = ArgNode->Asl.Next;
2153
2154         /*
2155          * Check for the WAIT_FOREVER case - defined by the ACPI spec to be
2156          * 0xFFFF or greater
2157          */
2158         if (((ArgNode->Asl.ParseOpcode == PARSEOP_WORDCONST) ||
2159              (ArgNode->Asl.ParseOpcode == PARSEOP_INTEGER))  &&
2160              (ArgNode->Asl.Value.Integer >= (ACPI_INTEGER) ACPI_WAIT_FOREVER))
2161         {
2162             break;
2163         }
2164
2165         /*
2166          * The operation could timeout. If the return value is not used
2167          * (indicates timeout occurred), issue a warning
2168          */
2169         if (!AnIsResultUsed (Op))
2170         {
2171             AslError (ASL_WARNING, ASL_MSG_TIMEOUT, ArgNode, Op->Asl.ExternalName);
2172         }
2173         break;
2174
2175     case PARSEOP_CREATEFIELD:
2176         /*
2177          * Check for a zero Length (NumBits) operand. NumBits is the 3rd operand
2178          */
2179         ArgNode = Op->Asl.Child;
2180         ArgNode = ArgNode->Asl.Next;
2181         ArgNode = ArgNode->Asl.Next;
2182
2183         if ((ArgNode->Asl.ParseOpcode == PARSEOP_ZERO) ||
2184            ((ArgNode->Asl.ParseOpcode == PARSEOP_INTEGER) &&
2185             (ArgNode->Asl.Value.Integer == 0)))
2186         {
2187             AslError (ASL_ERROR, ASL_MSG_NON_ZERO, ArgNode, NULL);
2188         }
2189         break;
2190
2191     default:
2192         break;
2193     }
2194
2195     return AE_OK;
2196 }
2197
2198
2199 /*******************************************************************************
2200  *
2201  * FUNCTION:    AnOtherSemanticAnalysisWalkEnd
2202  *
2203  * PARAMETERS:  ASL_WALK_CALLBACK
2204  *
2205  * RETURN:      Status
2206  *
2207  * DESCRIPTION: Ascending callback for analysis walk. Complete method
2208  *              return analysis.
2209  *
2210  ******************************************************************************/
2211
2212 ACPI_STATUS
2213 AnOtherSemanticAnalysisWalkEnd (
2214     ACPI_PARSE_OBJECT       *Op,
2215     UINT32                  Level,
2216     void                    *Context)
2217 {
2218
2219     return AE_OK;
2220
2221 }
2222
2223
2224 #ifdef ACPI_OBSOLETE_FUNCTIONS
2225 /*******************************************************************************
2226  *
2227  * FUNCTION:    AnMapBtypeToEtype
2228  *
2229  * PARAMETERS:  Btype               - Bitfield of ACPI types
2230  *
2231  * RETURN:      The Etype corresponding the the Btype
2232  *
2233  * DESCRIPTION: Convert a bitfield type to an encoded type
2234  *
2235  ******************************************************************************/
2236
2237 UINT32
2238 AnMapBtypeToEtype (
2239     UINT32              Btype)
2240 {
2241     UINT32              i;
2242     UINT32              Etype;
2243
2244
2245     if (Btype == 0)
2246     {
2247         return 0;
2248     }
2249
2250     Etype = 1;
2251     for (i = 1; i < Btype; i *= 2)
2252     {
2253         Etype++;
2254     }
2255
2256     return (Etype);
2257 }
2258 #endif
2259