OSDN Git Service

klibc基本機能実装. ACPICAの準備
[vaneos/DivergeMirror.git] / drivers / acpi / compiler / aslwalks.c
1 /******************************************************************************
2  *
3  * Module Name: aslwalks.c - Miscellaneous analytical parse tree walks
4  *
5  *****************************************************************************/
6
7 /******************************************************************************
8  *
9  * 1. Copyright Notice
10  *
11  * Some or all of this work - Copyright (c) 1999 - 2015, Intel Corp.
12  * All rights reserved.
13  *
14  * 2. License
15  *
16  * 2.1. This is your license from Intel Corp. under its intellectual property
17  * rights. You may have additional license terms from the party that provided
18  * you this software, covering your right to use that party's intellectual
19  * property rights.
20  *
21  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22  * copy of the source code appearing in this file ("Covered Code") an
23  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24  * base code distributed originally by Intel ("Original Intel Code") to copy,
25  * make derivatives, distribute, use and display any portion of the Covered
26  * Code in any form, with the right to sublicense such rights; and
27  *
28  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29  * license (with the right to sublicense), under only those claims of Intel
30  * patents that are infringed by the Original Intel Code, to make, use, sell,
31  * offer to sell, and import the Covered Code and derivative works thereof
32  * solely to the minimum extent necessary to exercise the above copyright
33  * license, and in no event shall the patent license extend to any additions
34  * to or modifications of the Original Intel Code. No other license or right
35  * is granted directly or by implication, estoppel or otherwise;
36  *
37  * The above copyright and patent license is granted only if the following
38  * conditions are met:
39  *
40  * 3. Conditions
41  *
42  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43  * Redistribution of source code of any substantial portion of the Covered
44  * Code or modification with rights to further distribute source must include
45  * the above Copyright Notice, the above License, this list of Conditions,
46  * and the following Disclaimer and Export Compliance provision. In addition,
47  * Licensee must cause all Covered Code to which Licensee contributes to
48  * contain a file documenting the changes Licensee made to create that Covered
49  * Code and the date of any change. Licensee must include in that file the
50  * documentation of any changes made by any predecessor Licensee. Licensee
51  * must include a prominent statement that the modification is derived,
52  * directly or indirectly, from Original Intel Code.
53  *
54  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55  * Redistribution of source code of any substantial portion of the Covered
56  * Code or modification without rights to further distribute source must
57  * include the following Disclaimer and Export Compliance provision in the
58  * documentation and/or other materials provided with distribution. In
59  * addition, Licensee may not authorize further sublicense of source of any
60  * portion of the Covered Code, and must include terms to the effect that the
61  * license from Licensee to its licensee is limited to the intellectual
62  * property embodied in the software Licensee provides to its licensee, and
63  * not to intellectual property embodied in modifications its licensee may
64  * make.
65  *
66  * 3.3. Redistribution of Executable. Redistribution in executable form of any
67  * substantial portion of the Covered Code or modification must reproduce the
68  * above Copyright Notice, and the following Disclaimer and Export Compliance
69  * provision in the documentation and/or other materials provided with the
70  * distribution.
71  *
72  * 3.4. Intel retains all right, title, and interest in and to the Original
73  * Intel Code.
74  *
75  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76  * Intel shall be used in advertising or otherwise to promote the sale, use or
77  * other dealings in products derived from or relating to the Covered Code
78  * without prior written authorization from Intel.
79  *
80  * 4. Disclaimer and Export Compliance
81  *
82  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88  * PARTICULAR PURPOSE.
89  *
90  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97  * LIMITED REMEDY.
98  *
99  * 4.3. Licensee shall not export, either directly or indirectly, any of this
100  * software or system incorporating such software without first obtaining any
101  * required license or other approval from the U. S. Department of Commerce or
102  * any other agency or department of the United States Government. In the
103  * event Licensee exports any such software from the United States or
104  * re-exports any such software from a foreign destination, Licensee shall
105  * ensure that the distribution and export/re-export of the software is in
106  * compliance with all laws, regulations, orders, or other restrictions of the
107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108  * any of its subsidiaries will export/re-export any technical data, process,
109  * software, or service, directly or indirectly, to any country for which the
110  * United States government or any agency thereof requires an export license,
111  * other governmental approval, or letter of assurance, without first obtaining
112  * such license, approval or letter.
113  *
114  *****************************************************************************/
115
116 #include "aslcompiler.h"
117 #include "aslcompiler.y.h"
118 #include "acparser.h"
119 #include "amlcode.h"
120
121
122 #define _COMPONENT          ACPI_COMPILER
123         ACPI_MODULE_NAME    ("aslwalks")
124
125
126 /*******************************************************************************
127  *
128  * FUNCTION:    AnMethodTypingWalkEnd
129  *
130  * PARAMETERS:  ASL_WALK_CALLBACK
131  *
132  * RETURN:      Status
133  *
134  * DESCRIPTION: Ascending callback for typing walk. Complete the method
135  *              return analysis. Check methods for:
136  *              1) Initialized local variables
137  *              2) Valid arguments
138  *              3) Return types
139  *
140  ******************************************************************************/
141
142 ACPI_STATUS
143 AnMethodTypingWalkEnd (
144     ACPI_PARSE_OBJECT       *Op,
145     UINT32                  Level,
146     void                    *Context)
147 {
148     UINT32                  ThisNodeBtype;
149
150
151     switch (Op->Asl.ParseOpcode)
152     {
153     case PARSEOP_METHOD:
154
155         Op->Asl.CompileFlags |= NODE_METHOD_TYPED;
156         break;
157
158     case PARSEOP_RETURN:
159
160         if ((Op->Asl.Child) &&
161             (Op->Asl.Child->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG))
162         {
163             ThisNodeBtype = AnGetBtype (Op->Asl.Child);
164
165             if ((Op->Asl.Child->Asl.ParseOpcode == PARSEOP_METHODCALL) &&
166                 (ThisNodeBtype == (ACPI_UINT32_MAX -1)))
167             {
168                 /*
169                  * The called method is untyped at this time (typically a
170                  * forward reference).
171                  *
172                  * Check for a recursive method call first.
173                  */
174                 if (Op->Asl.ParentMethod != Op->Asl.Child->Asl.Node->Op)
175                 {
176                     /* We must type the method here */
177
178                     TrWalkParseTree (Op->Asl.Child->Asl.Node->Op,
179                         ASL_WALK_VISIT_UPWARD, NULL,
180                         AnMethodTypingWalkEnd, NULL);
181
182                     ThisNodeBtype = AnGetBtype (Op->Asl.Child);
183                 }
184             }
185
186             /* Returns a value, save the value type */
187
188             if (Op->Asl.ParentMethod)
189             {
190                 Op->Asl.ParentMethod->Asl.AcpiBtype |= ThisNodeBtype;
191             }
192         }
193         break;
194
195     default:
196
197         break;
198     }
199
200     return (AE_OK);
201 }
202
203
204 /*******************************************************************************
205  *
206  * FUNCTION:    AnOperandTypecheckWalkEnd
207  *
208  * PARAMETERS:  ASL_WALK_CALLBACK
209  *
210  * RETURN:      Status
211  *
212  * DESCRIPTION: Ascending callback for analysis walk. Complete method
213  *              return analysis.
214  *
215  ******************************************************************************/
216
217 ACPI_STATUS
218 AnOperandTypecheckWalkEnd (
219     ACPI_PARSE_OBJECT       *Op,
220     UINT32                  Level,
221     void                    *Context)
222 {
223     const ACPI_OPCODE_INFO  *OpInfo;
224     UINT32                  RuntimeArgTypes;
225     UINT32                  RuntimeArgTypes2;
226     UINT32                  RequiredBtypes;
227     UINT32                  ThisNodeBtype;
228     UINT32                  CommonBtypes;
229     UINT32                  OpcodeClass;
230     ACPI_PARSE_OBJECT       *ArgOp;
231     UINT32                  ArgType;
232
233
234     switch (Op->Asl.AmlOpcode)
235     {
236     case AML_RAW_DATA_BYTE:
237     case AML_RAW_DATA_WORD:
238     case AML_RAW_DATA_DWORD:
239     case AML_RAW_DATA_QWORD:
240     case AML_RAW_DATA_BUFFER:
241     case AML_RAW_DATA_CHAIN:
242     case AML_PACKAGE_LENGTH:
243     case AML_UNASSIGNED_OPCODE:
244     case AML_DEFAULT_ARG_OP:
245
246         /* Ignore the internal (compiler-only) AML opcodes */
247
248         return (AE_OK);
249
250     default:
251
252         break;
253     }
254
255     OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
256     if (!OpInfo)
257     {
258         return (AE_OK);
259     }
260
261     ArgOp           = Op->Asl.Child;
262     RuntimeArgTypes = OpInfo->RuntimeArgs;
263     OpcodeClass     = OpInfo->Class;
264
265 #ifdef ASL_ERROR_NAMED_OBJECT_IN_WHILE
266     /*
267      * Update 11/2008: In practice, we can't perform this check. A simple
268      * analysis is not sufficient. Also, it can cause errors when compiling
269      * disassembled code because of the way Switch operators are implemented
270      * (a While(One) loop with a named temp variable created within.)
271      */
272
273     /*
274      * If we are creating a named object, check if we are within a while loop
275      * by checking if the parent is a WHILE op. This is a simple analysis, but
276      * probably sufficient for many cases.
277      *
278      * Allow Scope(), Buffer(), and Package().
279      */
280     if (((OpcodeClass == AML_CLASS_NAMED_OBJECT) && (Op->Asl.AmlOpcode != AML_SCOPE_OP)) ||
281         ((OpcodeClass == AML_CLASS_CREATE) && (OpInfo->Flags & AML_NSNODE)))
282     {
283         if (Op->Asl.Parent->Asl.AmlOpcode == AML_WHILE_OP)
284         {
285             AslError (ASL_ERROR, ASL_MSG_NAMED_OBJECT_IN_WHILE, Op, NULL);
286         }
287     }
288 #endif
289
290     /*
291      * Special case for control opcodes IF/RETURN/WHILE since they
292      * have no runtime arg list (at this time)
293      */
294     switch (Op->Asl.AmlOpcode)
295     {
296     case AML_IF_OP:
297     case AML_WHILE_OP:
298     case AML_RETURN_OP:
299
300         if (ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL)
301         {
302             /* Check for an internal method */
303
304             if (AnIsInternalMethod (ArgOp))
305             {
306                 return (AE_OK);
307             }
308
309             /* The lone arg is a method call, check it */
310
311             RequiredBtypes = AnMapArgTypeToBtype (ARGI_INTEGER);
312             if (Op->Asl.AmlOpcode == AML_RETURN_OP)
313             {
314                 RequiredBtypes = 0xFFFFFFFF;
315             }
316
317             ThisNodeBtype = AnGetBtype (ArgOp);
318             if (ThisNodeBtype == ACPI_UINT32_MAX)
319             {
320                 return (AE_OK);
321             }
322             AnCheckMethodReturnValue (Op, OpInfo, ArgOp,
323                 RequiredBtypes, ThisNodeBtype);
324         }
325         return (AE_OK);
326
327     case AML_EXTERNAL_OP:
328         /*
329          * Not really a "runtime" opcode since it used by disassembler only.
330          * The parser will find any issues with the operands.
331          */
332         return (AE_OK);
333
334     default:
335
336         break;
337     }
338
339     /* Ignore the non-executable opcodes */
340
341     if (RuntimeArgTypes == ARGI_INVALID_OPCODE)
342     {
343         return (AE_OK);
344     }
345
346     switch (OpcodeClass)
347     {
348     case AML_CLASS_EXECUTE:
349     case AML_CLASS_CREATE:
350     case AML_CLASS_CONTROL:
351     case AML_CLASS_RETURN_VALUE:
352
353         /* TBD: Change class or fix typechecking for these */
354
355         if ((Op->Asl.AmlOpcode == AML_BUFFER_OP)        ||
356             (Op->Asl.AmlOpcode == AML_PACKAGE_OP)       ||
357             (Op->Asl.AmlOpcode == AML_VAR_PACKAGE_OP))
358         {
359             break;
360         }
361
362         /* Reverse the runtime argument list */
363
364         RuntimeArgTypes2 = 0;
365         while ((ArgType = GET_CURRENT_ARG_TYPE (RuntimeArgTypes)))
366         {
367             RuntimeArgTypes2 <<= ARG_TYPE_WIDTH;
368             RuntimeArgTypes2 |= ArgType;
369             INCREMENT_ARG_LIST (RuntimeArgTypes);
370         }
371
372         while ((ArgType = GET_CURRENT_ARG_TYPE (RuntimeArgTypes2)))
373         {
374             RequiredBtypes = AnMapArgTypeToBtype (ArgType);
375
376             if (!ArgOp)
377             {
378                 AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, Op,
379                     "Null ArgOp in argument loop");
380                 AslAbort ();
381             }
382
383             ThisNodeBtype = AnGetBtype (ArgOp);
384             if (ThisNodeBtype == ACPI_UINT32_MAX)
385             {
386                 goto NextArgument;
387             }
388
389             /* Examine the arg based on the required type of the arg */
390
391             switch (ArgType)
392             {
393             case ARGI_TARGETREF:
394
395                 if (ArgOp->Asl.ParseOpcode == PARSEOP_ZERO)
396                 {
397                     /* ZERO is the placeholder for "don't store result" */
398
399                     ThisNodeBtype = RequiredBtypes;
400                     break;
401                 }
402
403                 if (ArgOp->Asl.ParseOpcode == PARSEOP_INTEGER)
404                 {
405                     /*
406                      * This is the case where an original reference to a resource
407                      * descriptor field has been replaced by an (Integer) offset.
408                      * These named fields are supported at compile-time only;
409                      * the names are not passed to the interpreter (via the AML).
410                      */
411                     if ((ArgOp->Asl.Node->Type == ACPI_TYPE_LOCAL_RESOURCE_FIELD) ||
412                         (ArgOp->Asl.Node->Type == ACPI_TYPE_LOCAL_RESOURCE))
413                     {
414                         AslError (ASL_ERROR, ASL_MSG_RESOURCE_FIELD, ArgOp, NULL);
415                     }
416                     else
417                     {
418                         AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, ArgOp, NULL);
419                     }
420                     break;
421                 }
422
423                 if ((ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL) ||
424                     (ArgOp->Asl.ParseOpcode == PARSEOP_DEREFOF))
425                 {
426                     break;
427                 }
428
429                 ThisNodeBtype = RequiredBtypes;
430                 break;
431
432
433             case ARGI_REFERENCE:            /* References */
434             case ARGI_INTEGER_REF:
435             case ARGI_OBJECT_REF:
436             case ARGI_DEVICE_REF:
437
438                 switch (ArgOp->Asl.ParseOpcode)
439                 {
440                 case PARSEOP_LOCAL0:
441                 case PARSEOP_LOCAL1:
442                 case PARSEOP_LOCAL2:
443                 case PARSEOP_LOCAL3:
444                 case PARSEOP_LOCAL4:
445                 case PARSEOP_LOCAL5:
446                 case PARSEOP_LOCAL6:
447                 case PARSEOP_LOCAL7:
448
449                     /* TBD: implement analysis of current value (type) of the local */
450                     /* For now, just treat any local as a typematch */
451
452                     /*ThisNodeBtype = RequiredBtypes;*/
453                     break;
454
455                 case PARSEOP_ARG0:
456                 case PARSEOP_ARG1:
457                 case PARSEOP_ARG2:
458                 case PARSEOP_ARG3:
459                 case PARSEOP_ARG4:
460                 case PARSEOP_ARG5:
461                 case PARSEOP_ARG6:
462
463                     /* Hard to analyze argument types, sow we won't */
464                     /* For now, just treat any arg as a typematch */
465
466                     /* ThisNodeBtype = RequiredBtypes; */
467                     break;
468
469                 case PARSEOP_DEBUG:
470                 case PARSEOP_REFOF:
471                 case PARSEOP_INDEX:
472                 default:
473
474                     break;
475
476                 }
477                 break;
478
479             case ARGI_INTEGER:
480             default:
481
482                 break;
483             }
484
485
486             CommonBtypes = ThisNodeBtype & RequiredBtypes;
487
488             if (ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL)
489             {
490                 if (AnIsInternalMethod (ArgOp))
491                 {
492                     return (AE_OK);
493                 }
494
495                 /* Check a method call for a valid return value */
496
497                 AnCheckMethodReturnValue (Op, OpInfo, ArgOp,
498                     RequiredBtypes, ThisNodeBtype);
499             }
500
501             /*
502              * Now check if the actual type(s) match at least one
503              * bit to the required type
504              */
505             else if (!CommonBtypes)
506             {
507                 /* No match -- this is a type mismatch error */
508
509                 AnFormatBtype (StringBuffer, ThisNodeBtype);
510                 AnFormatBtype (StringBuffer2, RequiredBtypes);
511
512                 sprintf (MsgBuffer, "[%s] found, %s operator requires [%s]",
513                             StringBuffer, OpInfo->Name, StringBuffer2);
514
515                 AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, ArgOp, MsgBuffer);
516             }
517
518         NextArgument:
519             ArgOp = ArgOp->Asl.Next;
520             INCREMENT_ARG_LIST (RuntimeArgTypes2);
521         }
522         break;
523
524     default:
525
526         break;
527     }
528
529     return (AE_OK);
530 }
531
532
533 /*******************************************************************************
534  *
535  * FUNCTION:    AnOtherSemanticAnalysisWalkBegin
536  *
537  * PARAMETERS:  ASL_WALK_CALLBACK
538  *
539  * RETURN:      Status
540  *
541  * DESCRIPTION: Descending callback for the analysis walk. Checks for
542  *              miscellaneous issues in the code.
543  *
544  ******************************************************************************/
545
546 ACPI_STATUS
547 AnOtherSemanticAnalysisWalkBegin (
548     ACPI_PARSE_OBJECT       *Op,
549     UINT32                  Level,
550     void                    *Context)
551 {
552     ACPI_PARSE_OBJECT       *ArgNode;
553     ACPI_PARSE_OBJECT       *PrevArgNode = NULL;
554     const ACPI_OPCODE_INFO  *OpInfo;
555     ACPI_NAMESPACE_NODE     *Node;
556
557
558     OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
559
560     /*
561      * Determine if an execution class operator actually does something by
562      * checking if it has a target and/or the function return value is used.
563      * (Target is optional, so a standalone statement can actually do nothing.)
564      */
565     if ((OpInfo->Class == AML_CLASS_EXECUTE) &&
566         (OpInfo->Flags & AML_HAS_RETVAL) &&
567         (!AnIsResultUsed (Op)))
568     {
569         if (OpInfo->Flags & AML_HAS_TARGET)
570         {
571             /*
572              * Find the target node, it is always the last child. If the traget
573              * is not specified in the ASL, a default node of type Zero was
574              * created by the parser.
575              */
576             ArgNode = Op->Asl.Child;
577             while (ArgNode->Asl.Next)
578             {
579                 PrevArgNode = ArgNode;
580                 ArgNode = ArgNode->Asl.Next;
581             }
582
583             /* Divide() is the only weird case, it has two targets */
584
585             if (Op->Asl.AmlOpcode == AML_DIVIDE_OP)
586             {
587                 if ((ArgNode->Asl.ParseOpcode == PARSEOP_ZERO) &&
588                     (PrevArgNode) &&
589                     (PrevArgNode->Asl.ParseOpcode == PARSEOP_ZERO))
590                 {
591                     AslError (ASL_ERROR, ASL_MSG_RESULT_NOT_USED,
592                         Op, Op->Asl.ExternalName);
593                 }
594             }
595             else if (ArgNode->Asl.ParseOpcode == PARSEOP_ZERO)
596             {
597                 AslError (ASL_ERROR, ASL_MSG_RESULT_NOT_USED,
598                     Op, Op->Asl.ExternalName);
599             }
600         }
601         else
602         {
603             /*
604              * Has no target and the result is not used. Only a couple opcodes
605              * can have this combination.
606              */
607             switch (Op->Asl.ParseOpcode)
608             {
609             case PARSEOP_ACQUIRE:
610             case PARSEOP_WAIT:
611             case PARSEOP_LOADTABLE:
612
613                 break;
614
615             default:
616
617                 AslError (ASL_ERROR, ASL_MSG_RESULT_NOT_USED,
618                     Op, Op->Asl.ExternalName);
619                 break;
620             }
621         }
622     }
623
624
625     /*
626      * Semantic checks for individual ASL operators
627      */
628     switch (Op->Asl.ParseOpcode)
629     {
630     case PARSEOP_ACQUIRE:
631     case PARSEOP_WAIT:
632         /*
633          * Emit a warning if the timeout parameter for these operators is not
634          * ACPI_WAIT_FOREVER, and the result value from the operator is not
635          * checked, meaning that a timeout could happen, but the code
636          * would not know about it.
637          */
638
639         /* First child is the namepath, 2nd child is timeout */
640
641         ArgNode = Op->Asl.Child;
642         ArgNode = ArgNode->Asl.Next;
643
644         /*
645          * Check for the WAIT_FOREVER case - defined by the ACPI spec to be
646          * 0xFFFF or greater
647          */
648         if (((ArgNode->Asl.ParseOpcode == PARSEOP_WORDCONST) ||
649              (ArgNode->Asl.ParseOpcode == PARSEOP_INTEGER))  &&
650              (ArgNode->Asl.Value.Integer >= (UINT64) ACPI_WAIT_FOREVER))
651         {
652             break;
653         }
654
655         /*
656          * The operation could timeout. If the return value is not used
657          * (indicates timeout occurred), issue a warning
658          */
659         if (!AnIsResultUsed (Op))
660         {
661             AslError (ASL_WARNING, ASL_MSG_TIMEOUT, ArgNode,
662                 Op->Asl.ExternalName);
663         }
664         break;
665
666     case PARSEOP_CREATEFIELD:
667         /*
668          * Check for a zero Length (NumBits) operand. NumBits is the 3rd operand
669          */
670         ArgNode = Op->Asl.Child;
671         ArgNode = ArgNode->Asl.Next;
672         ArgNode = ArgNode->Asl.Next;
673
674         if ((ArgNode->Asl.ParseOpcode == PARSEOP_ZERO) ||
675            ((ArgNode->Asl.ParseOpcode == PARSEOP_INTEGER) &&
676             (ArgNode->Asl.Value.Integer == 0)))
677         {
678             AslError (ASL_ERROR, ASL_MSG_NON_ZERO, ArgNode, NULL);
679         }
680         break;
681
682     case PARSEOP_CONNECTION:
683         /*
684          * Ensure that the referenced operation region has the correct SPACE_ID.
685          * From the grammar/parser, we know the parent is a FIELD definition.
686          */
687         ArgNode = Op->Asl.Parent;       /* Field definition */
688         ArgNode = ArgNode->Asl.Child;   /* First child is the OpRegion Name */
689         Node = ArgNode->Asl.Node;       /* OpRegion namespace node */
690         if (!Node)
691         {
692             break;
693         }
694
695         ArgNode = Node->Op;             /* OpRegion definition */
696         ArgNode = ArgNode->Asl.Child;   /* First child is the OpRegion Name */
697         ArgNode = ArgNode->Asl.Next;    /* Next peer is the SPACE_ID (what we want) */
698
699         /*
700          * The Connection() operator is only valid for the following operation
701          * region SpaceIds: GeneralPurposeIo and GenericSerialBus.
702          */
703         if ((ArgNode->Asl.Value.Integer != ACPI_ADR_SPACE_GPIO) &&
704             (ArgNode->Asl.Value.Integer != ACPI_ADR_SPACE_GSBUS))
705         {
706             AslError (ASL_ERROR, ASL_MSG_CONNECTION_INVALID, Op, NULL);
707         }
708         break;
709
710     case PARSEOP_FIELD:
711         /*
712          * Ensure that fields for GeneralPurposeIo and GenericSerialBus
713          * contain at least one Connection() operator
714          */
715         ArgNode = Op->Asl.Child;        /* 1st child is the OpRegion Name */
716         Node = ArgNode->Asl.Node;       /* OpRegion namespace node */
717         if (!Node)
718         {
719             break;
720         }
721
722         ArgNode = Node->Op;             /* OpRegion definition */
723         ArgNode = ArgNode->Asl.Child;   /* First child is the OpRegion Name */
724         ArgNode = ArgNode->Asl.Next;    /* Next peer is the SPACE_ID (what we want) */
725
726         /* We are only interested in GeneralPurposeIo and GenericSerialBus */
727
728         if ((ArgNode->Asl.Value.Integer != ACPI_ADR_SPACE_GPIO) &&
729             (ArgNode->Asl.Value.Integer != ACPI_ADR_SPACE_GSBUS))
730         {
731             break;
732         }
733
734         ArgNode = Op->Asl.Child;        /* 1st child is the OpRegion Name */
735         ArgNode = ArgNode->Asl.Next;    /* AccessType */
736         ArgNode = ArgNode->Asl.Next;    /* LockRule */
737         ArgNode = ArgNode->Asl.Next;    /* UpdateRule */
738         ArgNode = ArgNode->Asl.Next;    /* Start of FieldUnitList */
739
740         /* Walk the FieldUnitList */
741
742         while (ArgNode)
743         {
744             if (ArgNode->Asl.ParseOpcode == PARSEOP_CONNECTION)
745             {
746                 break;
747             }
748             else if (ArgNode->Asl.ParseOpcode == PARSEOP_NAMESEG)
749             {
750                 AslError (ASL_ERROR, ASL_MSG_CONNECTION_MISSING, ArgNode, NULL);
751                 break;
752             }
753
754             ArgNode = ArgNode->Asl.Next;
755         }
756         break;
757
758     default:
759
760         break;
761     }
762
763     return (AE_OK);
764 }