asllookup.c revision 212761
1/******************************************************************************
2 *
3 * Module Name: asllookup- Namespace lookup
4 *
5 *****************************************************************************/
6
7/******************************************************************************
8 *
9 * 1. Copyright Notice
10 *
11 * Some or all of this work - Copyright (c) 1999 - 2010, 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
117#include <contrib/dev/acpica/compiler/aslcompiler.h>
118#include "aslcompiler.y.h"
119
120#include <contrib/dev/acpica/include/acparser.h>
121#include <contrib/dev/acpica/include/amlcode.h>
122#include <contrib/dev/acpica/include/acnamesp.h>
123#include <contrib/dev/acpica/include/acdispat.h>
124
125
126#define _COMPONENT          ACPI_COMPILER
127        ACPI_MODULE_NAME    ("asllookup")
128
129/* Local prototypes */
130
131static ACPI_STATUS
132LsCompareOneNamespaceObject (
133    ACPI_HANDLE             ObjHandle,
134    UINT32                  Level,
135    void                    *Context,
136    void                    **ReturnValue);
137
138static ACPI_STATUS
139LsDoOneNamespaceObject (
140    ACPI_HANDLE             ObjHandle,
141    UINT32                  Level,
142    void                    *Context,
143    void                    **ReturnValue);
144
145static BOOLEAN
146LkObjectExists (
147    char                    *Name);
148
149static void
150LkCheckFieldRange (
151    ACPI_PARSE_OBJECT       *Op,
152    UINT32                  RegionBitLength,
153    UINT32                  FieldBitOffset,
154    UINT32                  FieldBitLength,
155    UINT32                  AccessBitWidth);
156
157static ACPI_STATUS
158LkNamespaceLocateBegin (
159    ACPI_PARSE_OBJECT       *Op,
160    UINT32                  Level,
161    void                    *Context);
162
163static ACPI_STATUS
164LkNamespaceLocateEnd (
165    ACPI_PARSE_OBJECT       *Op,
166    UINT32                  Level,
167    void                    *Context);
168
169static ACPI_STATUS
170LkIsObjectUsed (
171    ACPI_HANDLE             ObjHandle,
172    UINT32                  Level,
173    void                    *Context,
174    void                    **ReturnValue);
175
176static ACPI_STATUS
177LsDoOnePathname (
178    ACPI_HANDLE             ObjHandle,
179    UINT32                  Level,
180    void                    *Context,
181    void                    **ReturnValue);
182
183static ACPI_PARSE_OBJECT *
184LkGetNameOp (
185    ACPI_PARSE_OBJECT       *Op);
186
187
188/*******************************************************************************
189 *
190 * FUNCTION:    LsDoOneNamespaceObject
191 *
192 * PARAMETERS:  ACPI_WALK_CALLBACK
193 *
194 * RETURN:      Status
195 *
196 * DESCRIPTION: Dump a namespace object to the namespace output file.
197 *              Called during the walk of the namespace to dump all objects.
198 *
199 ******************************************************************************/
200
201static ACPI_STATUS
202LsDoOneNamespaceObject (
203    ACPI_HANDLE             ObjHandle,
204    UINT32                  Level,
205    void                    *Context,
206    void                    **ReturnValue)
207{
208    ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
209    ACPI_OPERAND_OBJECT     *ObjDesc;
210    ACPI_PARSE_OBJECT       *Op;
211
212
213    Gbl_NumNamespaceObjects++;
214
215    FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "%5u  [%u]  %*s %4.4s - %s",
216        Gbl_NumNamespaceObjects, Level, (Level * 3), " ",
217        &Node->Name,
218        AcpiUtGetTypeName (Node->Type));
219
220    Op = Node->Op;
221    ObjDesc = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, Node->Object);
222
223    if (!Op)
224    {
225        FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "\n");
226        return (AE_OK);
227    }
228
229
230    if ((ObjDesc) &&
231        (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc) == ACPI_DESC_TYPE_OPERAND))
232    {
233        switch (Node->Type)
234        {
235        case ACPI_TYPE_INTEGER:
236
237            FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
238                "       [Initial Value   0x%8.8X%8.8X]",
239                ACPI_FORMAT_UINT64 (ObjDesc->Integer.Value));
240            break;
241
242
243        case ACPI_TYPE_STRING:
244
245            FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
246                "        [Initial Value   \"%s\"]",
247                ObjDesc->String.Pointer);
248            break;
249
250        default:
251            /* Nothing to do for other types */
252            break;
253        }
254
255    }
256    else
257    {
258        switch (Node->Type)
259        {
260        case ACPI_TYPE_INTEGER:
261
262            if (Op->Asl.ParseOpcode == PARSEOP_NAME)
263            {
264                Op = Op->Asl.Child;
265            }
266            if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG)  ||
267                (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING))
268            {
269                Op = Op->Asl.Next;
270            }
271            FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
272                "       [Initial Value   0x%8.8X%8.8X]",
273                ACPI_FORMAT_UINT64 (Op->Asl.Value.Integer));
274            break;
275
276
277        case ACPI_TYPE_STRING:
278
279            if (Op->Asl.ParseOpcode == PARSEOP_NAME)
280            {
281                Op = Op->Asl.Child;
282            }
283            if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG)  ||
284                (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING))
285            {
286                Op = Op->Asl.Next;
287            }
288            FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
289                "        [Initial Value   \"%s\"]",
290                Op->Asl.Value.String);
291            break;
292
293
294        case ACPI_TYPE_LOCAL_REGION_FIELD:
295
296            if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG)  ||
297                (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING))
298            {
299                Op = Op->Asl.Child;
300            }
301            FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
302                "   [Offset 0x%04X   Length 0x%04X bits]",
303                Op->Asl.Parent->Asl.ExtraValue, (UINT32) Op->Asl.Value.Integer);
304            break;
305
306
307        case ACPI_TYPE_BUFFER_FIELD:
308
309            switch (Op->Asl.ParseOpcode)
310            {
311            case PARSEOP_CREATEBYTEFIELD:
312                FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "   [BYTE  ( 8 bit)]");
313                break;
314
315            case PARSEOP_CREATEDWORDFIELD:
316                FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "   [DWORD (32 bit)]");
317                break;
318
319            case PARSEOP_CREATEQWORDFIELD:
320                FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "   [QWORD (64 bit)]");
321                break;
322
323            case PARSEOP_CREATEWORDFIELD:
324                FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "   [WORD  (16 bit)]");
325                break;
326
327            case PARSEOP_CREATEBITFIELD:
328                FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "   [BIT   ( 1 bit)]");
329                break;
330
331            case PARSEOP_CREATEFIELD:
332                FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "   [Arbitrary Bit Field]");
333                break;
334
335            default:
336                break;
337
338            }
339            break;
340
341
342        case ACPI_TYPE_PACKAGE:
343
344            if (Op->Asl.ParseOpcode == PARSEOP_NAME)
345            {
346                Op = Op->Asl.Child;
347            }
348            if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG)  ||
349                (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING))
350            {
351                Op = Op->Asl.Next;
352            }
353            Op = Op->Asl.Child;
354
355            if ((Op->Asl.ParseOpcode == PARSEOP_BYTECONST) ||
356                (Op->Asl.ParseOpcode == PARSEOP_RAW_DATA))
357            {
358                FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
359                    "       [Initial Length  0x%.2X elements]",
360                    Op->Asl.Value.Integer);
361            }
362            break;
363
364
365        case ACPI_TYPE_BUFFER:
366
367            if (Op->Asl.ParseOpcode == PARSEOP_NAME)
368            {
369                Op = Op->Asl.Child;
370            }
371            if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG)  ||
372                (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING))
373            {
374                Op = Op->Asl.Next;
375            }
376            Op = Op->Asl.Child;
377
378            if (Op && (Op->Asl.ParseOpcode == PARSEOP_INTEGER))
379            {
380                FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
381                    "        [Initial Length  0x%.2X bytes]",
382                    Op->Asl.Value.Integer);
383            }
384            break;
385
386
387        case ACPI_TYPE_METHOD:
388
389            FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
390                "        [Code Length     0x%.4X bytes]",
391                Op->Asl.AmlSubtreeLength);
392            break;
393
394
395        case ACPI_TYPE_LOCAL_RESOURCE:
396
397            FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
398                "  [Desc Offset     0x%.4X Bytes]", Node->Value);
399            break;
400
401
402        case ACPI_TYPE_LOCAL_RESOURCE_FIELD:
403
404            if (Node->Flags & 0x80)
405            {
406                FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
407                    "   [Field Offset    0x%.4X Bits 0x%.4X Bytes]",
408                    Node->Value, Node->Value / 8);
409            }
410            else
411            {
412                FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT,
413                    "   [Field Offset    0x%.4X Bytes]", Node->Value);
414            }
415            break;
416
417
418        default:
419            /* Nothing to do for other types */
420            break;
421        }
422    }
423
424    FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "\n");
425    return (AE_OK);
426}
427
428
429/*******************************************************************************
430 *
431 * FUNCTION:    LsSetupNsList
432 *
433 * PARAMETERS:  Handle          - local file handle
434 *
435 * RETURN:      None
436 *
437 * DESCRIPTION: Set the namespace output file to the input handle
438 *
439 ******************************************************************************/
440
441void
442LsSetupNsList (
443    void                    *Handle)
444{
445
446    Gbl_NsOutputFlag = TRUE;
447    Gbl_Files[ASL_FILE_NAMESPACE_OUTPUT].Handle = Handle;
448}
449
450
451/*******************************************************************************
452 *
453 * FUNCTION:    LsDoOnePathname
454 *
455 * PARAMETERS:  ACPI_WALK_CALLBACK
456 *
457 * RETURN:      Status
458 *
459 * DESCRIPTION: Print the full pathname for a namespace node.
460 *
461 ******************************************************************************/
462
463static ACPI_STATUS
464LsDoOnePathname (
465    ACPI_HANDLE             ObjHandle,
466    UINT32                  Level,
467    void                    *Context,
468    void                    **ReturnValue)
469{
470    ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
471    ACPI_STATUS             Status;
472    ACPI_BUFFER             TargetPath;
473
474
475    TargetPath.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
476    Status = AcpiNsHandleToPathname (Node, &TargetPath);
477    if (ACPI_FAILURE (Status))
478    {
479        return (Status);
480    }
481
482    FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "%s\n", TargetPath.Pointer);
483    ACPI_FREE (TargetPath.Pointer);
484
485    return (AE_OK);
486}
487
488
489/*******************************************************************************
490 *
491 * FUNCTION:    LsDisplayNamespace
492 *
493 * PARAMETERS:  None
494 *
495 * RETURN:      Status
496 *
497 * DESCRIPTION: Walk the namespace an display information about each node
498 *              in the tree.  Information is written to the optional
499 *              namespace output file.
500 *
501 ******************************************************************************/
502
503ACPI_STATUS
504LsDisplayNamespace (
505    void)
506{
507    ACPI_STATUS             Status;
508
509
510    if (!Gbl_NsOutputFlag)
511    {
512        return (AE_OK);
513    }
514
515    Gbl_NumNamespaceObjects = 0;
516
517    /* File header */
518
519    FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "Contents of ACPI Namespace\n\n");
520    FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "Count  Depth    Name - Type\n\n");
521
522    /* Walk entire namespace from the root */
523
524    Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
525                ACPI_UINT32_MAX, FALSE, LsDoOneNamespaceObject, NULL,
526                NULL, NULL);
527
528    /* Print the full pathname for each namespace node */
529
530    FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "\nNamespace pathnames\n\n");
531
532    Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
533                ACPI_UINT32_MAX, FALSE, LsDoOnePathname, NULL,
534                NULL, NULL);
535
536    return (Status);
537}
538
539
540/*******************************************************************************
541 *
542 * FUNCTION:    LsCompareOneNamespaceObject
543 *
544 * PARAMETERS:  ACPI_WALK_CALLBACK
545 *
546 * RETURN:      Status
547 *
548 * DESCRIPTION: Compare name of one object.
549 *
550 ******************************************************************************/
551
552static ACPI_STATUS
553LsCompareOneNamespaceObject (
554    ACPI_HANDLE             ObjHandle,
555    UINT32                  Level,
556    void                    *Context,
557    void                    **ReturnValue)
558{
559    ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
560
561
562    /* Simply check the name */
563
564    if (*((UINT32 *) (Context)) == Node->Name.Integer)
565    {
566        /* Abort walk if we found one instance */
567
568        return (AE_CTRL_TRUE);
569    }
570
571    return (AE_OK);
572}
573
574
575/*******************************************************************************
576 *
577 * FUNCTION:    LkObjectExists
578 *
579 * PARAMETERS:  Name            - 4 char ACPI name
580 *
581 * RETURN:      TRUE if name exists in namespace
582 *
583 * DESCRIPTION: Walk the namespace to find an object
584 *
585 ******************************************************************************/
586
587static BOOLEAN
588LkObjectExists (
589    char                    *Name)
590{
591    ACPI_STATUS             Status;
592
593
594    /* Walk entire namespace from the supplied root */
595
596    Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
597                ACPI_UINT32_MAX, FALSE, LsCompareOneNamespaceObject, NULL,
598                Name, NULL);
599    if (Status == AE_CTRL_TRUE)
600    {
601        /* At least one instance of the name was found */
602
603        return (TRUE);
604    }
605
606    return (FALSE);
607}
608
609
610/*******************************************************************************
611 *
612 * FUNCTION:    LkGetNameOp
613 *
614 * PARAMETERS:  Op              - Current Op
615 *
616 * RETURN:      NameOp associated with the input op
617 *
618 * DESCRIPTION: Find the name declaration op associated with the operator
619 *
620 ******************************************************************************/
621
622static ACPI_PARSE_OBJECT *
623LkGetNameOp (
624    ACPI_PARSE_OBJECT       *Op)
625{
626    const ACPI_OPCODE_INFO  *OpInfo;
627    ACPI_PARSE_OBJECT       *NameOp = Op;
628
629
630    OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
631
632
633    /* Get the NamePath from the appropriate place */
634
635    if (OpInfo->Flags & AML_NAMED)
636    {
637        /* For nearly all NAMED operators, the name reference is the first child */
638
639        NameOp = Op->Asl.Child;
640        if (Op->Asl.AmlOpcode == AML_ALIAS_OP)
641        {
642            /*
643             * ALIAS is the only oddball opcode, the name declaration
644             * (alias name) is the second operand
645             */
646            NameOp = Op->Asl.Child->Asl.Next;
647        }
648    }
649    else if (OpInfo->Flags & AML_CREATE)
650    {
651        /* Name must appear as the last parameter */
652
653        NameOp = Op->Asl.Child;
654        while (!(NameOp->Asl.CompileFlags & NODE_IS_NAME_DECLARATION))
655        {
656            NameOp = NameOp->Asl.Next;
657        }
658    }
659
660    return (NameOp);
661}
662
663
664/*******************************************************************************
665 *
666 * FUNCTION:    LkIsObjectUsed
667 *
668 * PARAMETERS:  ACPI_WALK_CALLBACK
669 *
670 * RETURN:      Status
671 *
672 * DESCRIPTION: Check for an unreferenced namespace object and emit a warning.
673 *              We have to be careful, because some types and names are
674 *              typically or always unreferenced, we don't want to issue
675 *              excessive warnings.
676 *
677 ******************************************************************************/
678
679static ACPI_STATUS
680LkIsObjectUsed (
681    ACPI_HANDLE             ObjHandle,
682    UINT32                  Level,
683    void                    *Context,
684    void                    **ReturnValue)
685{
686    ACPI_NAMESPACE_NODE     *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle);
687
688
689    /* Referenced flag is set during the namespace xref */
690
691    if (Node->Flags & ANOBJ_IS_REFERENCED)
692    {
693        return (AE_OK);
694    }
695
696    /*
697     * Ignore names that start with an underscore,
698     * these are the reserved ACPI names and are typically not referenced,
699     * they are called by the host OS.
700     */
701    if (Node->Name.Ascii[0] == '_')
702    {
703        return (AE_OK);
704    }
705
706    /* There are some types that are typically not referenced, ignore them */
707
708    switch (Node->Type)
709    {
710    case ACPI_TYPE_DEVICE:
711    case ACPI_TYPE_PROCESSOR:
712    case ACPI_TYPE_POWER:
713    case ACPI_TYPE_LOCAL_RESOURCE:
714        return (AE_OK);
715
716    default:
717        break;
718    }
719
720    /* All others are valid unreferenced namespace objects */
721
722    if (Node->Op)
723    {
724        AslError (ASL_WARNING2, ASL_MSG_NOT_REFERENCED, LkGetNameOp (Node->Op), NULL);
725    }
726    return (AE_OK);
727}
728
729
730/*******************************************************************************
731 *
732 * FUNCTION:    LkFindUnreferencedObjects
733 *
734 * PARAMETERS:  None
735 *
736 * RETURN:      None
737 *
738 * DESCRIPTION: Namespace walk to find objects that are not referenced in any
739 *              way. Must be called after the namespace has been cross
740 *              referenced.
741 *
742 ******************************************************************************/
743
744void
745LkFindUnreferencedObjects (
746    void)
747{
748
749    /* Walk entire namespace from the supplied root */
750
751    (void) AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
752                ACPI_UINT32_MAX, FALSE, LkIsObjectUsed, NULL,
753                NULL, NULL);
754}
755
756
757/*******************************************************************************
758 *
759 * FUNCTION:    LkCrossReferenceNamespace
760 *
761 * PARAMETERS:  None
762 *
763 * RETURN:      Status
764 *
765 * DESCRIPTION: Perform a cross reference check of the parse tree against the
766 *              namespace.  Every named referenced within the parse tree
767 *              should be get resolved with a namespace lookup.  If not, the
768 *              original reference in the ASL code is invalid -- i.e., refers
769 *              to a non-existent object.
770 *
771 * NOTE:  The ASL "External" operator causes the name to be inserted into the
772 *        namespace so that references to the external name will be resolved
773 *        correctly here.
774 *
775 ******************************************************************************/
776
777ACPI_STATUS
778LkCrossReferenceNamespace (
779    void)
780{
781    ACPI_WALK_STATE         *WalkState;
782
783
784    DbgPrint (ASL_DEBUG_OUTPUT, "\nCross referencing namespace\n\n");
785
786    /*
787     * Create a new walk state for use when looking up names
788     * within the namespace (Passed as context to the callbacks)
789     */
790    WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL);
791    if (!WalkState)
792    {
793        return AE_NO_MEMORY;
794    }
795
796    /* Walk the entire parse tree */
797
798    TrWalkParseTree (RootNode, ASL_WALK_VISIT_TWICE, LkNamespaceLocateBegin,
799                        LkNamespaceLocateEnd, WalkState);
800    return AE_OK;
801}
802
803
804/*******************************************************************************
805 *
806 * FUNCTION:    LkCheckFieldRange
807 *
808 * PARAMETERS:  RegionBitLength     - Length of entire parent region
809 *              FieldBitOffset      - Start of the field unit (within region)
810 *              FieldBitLength      - Entire length of field unit
811 *              AccessBitWidth      - Access width of the field unit
812 *
813 * RETURN:      None
814 *
815 * DESCRIPTION: Check one field unit to make sure it fits in the parent
816 *              op region.
817 *
818 * Note: AccessBitWidth must be either 8,16,32, or 64
819 *
820 ******************************************************************************/
821
822static void
823LkCheckFieldRange (
824    ACPI_PARSE_OBJECT       *Op,
825    UINT32                  RegionBitLength,
826    UINT32                  FieldBitOffset,
827    UINT32                  FieldBitLength,
828    UINT32                  AccessBitWidth)
829{
830    UINT32                  FieldEndBitOffset;
831
832
833    /*
834     * Check each field unit against the region size.  The entire
835     * field unit (start offset plus length) must fit within the
836     * region.
837     */
838    FieldEndBitOffset = FieldBitOffset + FieldBitLength;
839
840    if (FieldEndBitOffset > RegionBitLength)
841    {
842        /* Field definition itself is beyond the end-of-region */
843
844        AslError (ASL_ERROR, ASL_MSG_FIELD_UNIT_OFFSET, Op, NULL);
845        return;
846    }
847
848    /*
849     * Now check that the field plus AccessWidth doesn't go beyond
850     * the end-of-region.  Assumes AccessBitWidth is a power of 2
851     */
852    FieldEndBitOffset = ACPI_ROUND_UP (FieldEndBitOffset, AccessBitWidth);
853
854    if (FieldEndBitOffset > RegionBitLength)
855    {
856        /* Field definition combined with the access is beyond EOR */
857
858        AslError (ASL_ERROR, ASL_MSG_FIELD_UNIT_ACCESS_WIDTH, Op, NULL);
859    }
860}
861
862/*******************************************************************************
863 *
864 * FUNCTION:    LkNamespaceLocateBegin
865 *
866 * PARAMETERS:  ASL_WALK_CALLBACK
867 *
868 * RETURN:      Status
869 *
870 * DESCRIPTION: Descending callback used during cross-reference.  For named
871 *              object references, attempt to locate the name in the
872 *              namespace.
873 *
874 * NOTE: ASL references to named fields within resource descriptors are
875 *       resolved to integer values here.  Therefore, this step is an
876 *       important part of the code generation.  We don't know that the
877 *       name refers to a resource descriptor until now.
878 *
879 ******************************************************************************/
880
881static ACPI_STATUS
882LkNamespaceLocateBegin (
883    ACPI_PARSE_OBJECT       *Op,
884    UINT32                  Level,
885    void                    *Context)
886{
887    ACPI_WALK_STATE         *WalkState = (ACPI_WALK_STATE *) Context;
888    ACPI_NAMESPACE_NODE     *Node;
889    ACPI_STATUS             Status;
890    ACPI_OBJECT_TYPE        ObjectType;
891    char                    *Path;
892    UINT8                   PassedArgs;
893    ACPI_PARSE_OBJECT       *NextOp;
894    ACPI_PARSE_OBJECT       *OwningOp;
895    ACPI_PARSE_OBJECT       *SpaceIdOp;
896    UINT32                  MinimumLength;
897    UINT32                  Temp;
898    const ACPI_OPCODE_INFO  *OpInfo;
899    UINT32                  Flags;
900
901
902    ACPI_FUNCTION_TRACE_PTR (LkNamespaceLocateBegin, Op);
903
904    /*
905     * If this node is the actual declaration of a name
906     * [such as the XXXX name in "Method (XXXX)"],
907     * we are not interested in it here.  We only care about names that are
908     * references to other objects within the namespace and the parent objects
909     * of name declarations
910     */
911    if (Op->Asl.CompileFlags & NODE_IS_NAME_DECLARATION)
912    {
913        return (AE_OK);
914    }
915
916    /* We are only interested in opcodes that have an associated name */
917
918    OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
919
920    if ((!(OpInfo->Flags & AML_NAMED)) &&
921        (!(OpInfo->Flags & AML_CREATE)) &&
922        (Op->Asl.ParseOpcode != PARSEOP_NAMESTRING) &&
923        (Op->Asl.ParseOpcode != PARSEOP_NAMESEG)    &&
924        (Op->Asl.ParseOpcode != PARSEOP_METHODCALL))
925    {
926        return (AE_OK);
927    }
928
929    /*
930     * One special case: CondRefOf operator - we don't care if the name exists
931     * or not at this point, just ignore it, the point of the operator is to
932     * determine if the name exists at runtime.
933     */
934    if ((Op->Asl.Parent) &&
935        (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_CONDREFOF))
936    {
937        return (AE_OK);
938    }
939
940    /*
941     * We must enable the "search-to-root" for single NameSegs, but
942     * we have to be very careful about opening up scopes
943     */
944    Flags = ACPI_NS_SEARCH_PARENT;
945    if ((Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) ||
946        (Op->Asl.ParseOpcode == PARSEOP_NAMESEG)    ||
947        (Op->Asl.ParseOpcode == PARSEOP_METHODCALL))
948    {
949        /*
950         * These are name references, do not push the scope stack
951         * for them.
952         */
953        Flags |= ACPI_NS_DONT_OPEN_SCOPE;
954    }
955
956    /* Get the NamePath from the appropriate place */
957
958    if (OpInfo->Flags & AML_NAMED)
959    {
960        /* For nearly all NAMED operators, the name reference is the first child */
961
962        Path = Op->Asl.Child->Asl.Value.String;
963        if (Op->Asl.AmlOpcode == AML_ALIAS_OP)
964        {
965            /*
966             * ALIAS is the only oddball opcode, the name declaration
967             * (alias name) is the second operand
968             */
969            Path = Op->Asl.Child->Asl.Next->Asl.Value.String;
970        }
971    }
972    else if (OpInfo->Flags & AML_CREATE)
973    {
974        /* Name must appear as the last parameter */
975
976        NextOp = Op->Asl.Child;
977        while (!(NextOp->Asl.CompileFlags & NODE_IS_NAME_DECLARATION))
978        {
979            NextOp = NextOp->Asl.Next;
980        }
981        Path = NextOp->Asl.Value.String;
982    }
983    else
984    {
985        Path = Op->Asl.Value.String;
986    }
987
988    ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);
989    ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
990        "Type=%s\n", AcpiUtGetTypeName (ObjectType)));
991
992    /*
993     * Lookup the name in the namespace.  Name must exist at this point, or it
994     * is an invalid reference.
995     *
996     * The namespace is also used as a lookup table for references to resource
997     * descriptors and the fields within them.
998     */
999    Gbl_NsLookupCount++;
1000
1001    Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType,
1002                ACPI_IMODE_EXECUTE, Flags, WalkState, &(Node));
1003    if (ACPI_FAILURE (Status))
1004    {
1005        if (Status == AE_NOT_FOUND)
1006        {
1007            /*
1008             * We didn't find the name reference by path -- we can qualify this
1009             * a little better before we print an error message
1010             */
1011            if (strlen (Path) == ACPI_NAME_SIZE)
1012            {
1013                /* A simple, one-segment ACPI name */
1014
1015                if (LkObjectExists (Path))
1016                {
1017                    /*
1018                     * There exists such a name, but we couldn't get to it
1019                     * from this scope
1020                     */
1021                    AslError (ASL_ERROR, ASL_MSG_NOT_REACHABLE, Op,
1022                        Op->Asl.ExternalName);
1023                }
1024                else
1025                {
1026                    /* The name doesn't exist, period */
1027
1028                    AslError (ASL_ERROR, ASL_MSG_NOT_EXIST,
1029                        Op, Op->Asl.ExternalName);
1030                }
1031            }
1032            else
1033            {
1034                /* Check for a fully qualified path */
1035
1036                if (Path[0] == AML_ROOT_PREFIX)
1037                {
1038                    /* Gave full path, the object does not exist */
1039
1040                    AslError (ASL_ERROR, ASL_MSG_NOT_EXIST, Op,
1041                        Op->Asl.ExternalName);
1042                }
1043                else
1044                {
1045                    /*
1046                     * We can't tell whether it doesn't exist or just
1047                     * can't be reached.
1048                     */
1049                    AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op,
1050                        Op->Asl.ExternalName);
1051                }
1052            }
1053
1054            Status = AE_OK;
1055        }
1056        return (Status);
1057    }
1058
1059    /* Check for a reference vs. name declaration */
1060
1061    if (!(OpInfo->Flags & AML_NAMED) &&
1062        !(OpInfo->Flags & AML_CREATE))
1063    {
1064        /* This node has been referenced, mark it for reference check */
1065
1066        Node->Flags |= ANOBJ_IS_REFERENCED;
1067    }
1068
1069    /* Attempt to optimize the NamePath */
1070
1071    OptOptimizeNamePath (Op, OpInfo->Flags, WalkState, Path, Node);
1072
1073    /*
1074     * 1) Dereference an alias (A name reference that is an alias)
1075     *    Aliases are not nested, the alias always points to the final object
1076     */
1077    if ((Op->Asl.ParseOpcode != PARSEOP_ALIAS) &&
1078        (Node->Type == ACPI_TYPE_LOCAL_ALIAS))
1079    {
1080        /* This node points back to the original PARSEOP_ALIAS */
1081
1082        NextOp = Node->Op;
1083
1084        /* The first child is the alias target op */
1085
1086        NextOp = NextOp->Asl.Child;
1087
1088        /* That in turn points back to original target alias node */
1089
1090        if (NextOp->Asl.Node)
1091        {
1092            Node = NextOp->Asl.Node;
1093        }
1094
1095        /* Else - forward reference to alias, will be resolved later */
1096    }
1097
1098    /* 2) Check for a reference to a resource descriptor */
1099
1100    if ((Node->Type == ACPI_TYPE_LOCAL_RESOURCE_FIELD) ||
1101             (Node->Type == ACPI_TYPE_LOCAL_RESOURCE))
1102    {
1103        /*
1104         * This was a reference to a field within a resource descriptor.  Extract
1105         * the associated field offset (either a bit or byte offset depending on
1106         * the field type) and change the named reference into an integer for
1107         * AML code generation
1108         */
1109        Temp = Node->Value;
1110        if (Node->Flags & ANOBJ_IS_BIT_OFFSET)
1111        {
1112            Op->Asl.CompileFlags |= NODE_IS_BIT_OFFSET;
1113        }
1114
1115        /* Perform BitOffset <--> ByteOffset conversion if necessary */
1116
1117        switch (Op->Asl.Parent->Asl.AmlOpcode)
1118        {
1119        case AML_CREATE_FIELD_OP:
1120
1121            /* We allow a Byte offset to Bit Offset conversion for this op */
1122
1123            if (!(Op->Asl.CompileFlags & NODE_IS_BIT_OFFSET))
1124            {
1125                /* Simply multiply byte offset times 8 to get bit offset */
1126
1127                Temp = ACPI_MUL_8 (Temp);
1128            }
1129            break;
1130
1131
1132        case AML_CREATE_BIT_FIELD_OP:
1133
1134            /* This op requires a Bit Offset */
1135
1136            if (!(Op->Asl.CompileFlags & NODE_IS_BIT_OFFSET))
1137            {
1138                AslError (ASL_ERROR, ASL_MSG_BYTES_TO_BITS, Op, NULL);
1139            }
1140            break;
1141
1142
1143        case AML_CREATE_BYTE_FIELD_OP:
1144        case AML_CREATE_WORD_FIELD_OP:
1145        case AML_CREATE_DWORD_FIELD_OP:
1146        case AML_CREATE_QWORD_FIELD_OP:
1147        case AML_INDEX_OP:
1148
1149            /* These Ops require Byte offsets */
1150
1151            if (Op->Asl.CompileFlags & NODE_IS_BIT_OFFSET)
1152            {
1153                AslError (ASL_ERROR, ASL_MSG_BITS_TO_BYTES, Op, NULL);
1154            }
1155            break;
1156
1157
1158        default:
1159            /* Nothing to do for other opcodes */
1160            break;
1161        }
1162
1163        /* Now convert this node to an integer whose value is the field offset */
1164
1165        Op->Asl.AmlLength       = 0;
1166        Op->Asl.ParseOpcode     = PARSEOP_INTEGER;
1167        Op->Asl.Value.Integer   = (UINT64) Temp;
1168        Op->Asl.CompileFlags   |= NODE_IS_RESOURCE_FIELD;
1169
1170        OpcGenerateAmlOpcode (Op);
1171    }
1172
1173    /* 3) Check for a method invocation */
1174
1175    else if ((((Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) || (Op->Asl.ParseOpcode == PARSEOP_NAMESEG)) &&
1176                (Node->Type == ACPI_TYPE_METHOD) &&
1177                (Op->Asl.Parent) &&
1178                (Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_METHOD))   ||
1179
1180                (Op->Asl.ParseOpcode == PARSEOP_METHODCALL))
1181    {
1182
1183        /*
1184         * A reference to a method within one of these opcodes is not an
1185         * invocation of the method, it is simply a reference to the method.
1186         */
1187        if ((Op->Asl.Parent) &&
1188           ((Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_REFOF)      ||
1189            (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_DEREFOF)    ||
1190            (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_OBJECTTYPE)))
1191        {
1192            return (AE_OK);
1193        }
1194        /*
1195         * There are two types of method invocation:
1196         * 1) Invocation with arguments -- the parser recognizes this
1197         *    as a METHODCALL.
1198         * 2) Invocation with no arguments --the parser cannot determine that
1199         *    this is a method invocation, therefore we have to figure it out
1200         *    here.
1201         */
1202        if (Node->Type != ACPI_TYPE_METHOD)
1203        {
1204            sprintf (MsgBuffer, "%s is a %s",
1205                    Op->Asl.ExternalName, AcpiUtGetTypeName (Node->Type));
1206
1207            AslError (ASL_ERROR, ASL_MSG_NOT_METHOD, Op, MsgBuffer);
1208            return (AE_OK);
1209        }
1210
1211        /* Save the method node in the caller's op */
1212
1213        Op->Asl.Node = Node;
1214        if (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_CONDREFOF)
1215        {
1216            return (AE_OK);
1217        }
1218
1219        /*
1220         * This is a method invocation, with or without arguments.
1221         * Count the number of arguments, each appears as a child
1222         * under the parent node
1223         */
1224        Op->Asl.ParseOpcode = PARSEOP_METHODCALL;
1225        UtSetParseOpName (Op);
1226
1227        PassedArgs = 0;
1228        NextOp     = Op->Asl.Child;
1229
1230        while (NextOp)
1231        {
1232            PassedArgs++;
1233            NextOp = NextOp->Asl.Next;
1234        }
1235
1236        if (Node->Value != ASL_EXTERNAL_METHOD)
1237        {
1238            /*
1239             * Check the parsed arguments with the number expected by the
1240             * method declaration itself
1241             */
1242            if (PassedArgs != Node->Value)
1243            {
1244                sprintf (MsgBuffer, "%s requires %u", Op->Asl.ExternalName,
1245                            Node->Value);
1246
1247                if (PassedArgs < Node->Value)
1248                {
1249                    AslError (ASL_ERROR, ASL_MSG_ARG_COUNT_LO, Op, MsgBuffer);
1250                }
1251                else
1252                {
1253                    AslError (ASL_ERROR, ASL_MSG_ARG_COUNT_HI, Op, MsgBuffer);
1254                }
1255            }
1256        }
1257    }
1258
1259    /* 4) Check for an ASL Field definition */
1260
1261    else if ((Op->Asl.Parent) &&
1262            ((Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_FIELD)     ||
1263             (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_BANKFIELD)))
1264    {
1265        /*
1266         * Offset checking for fields.  If the parent operation region has a
1267         * constant length (known at compile time), we can check fields
1268         * defined in that region against the region length.  This will catch
1269         * fields and field units that cannot possibly fit within the region.
1270         *
1271         * Note: Index fields do not directly reference an operation region,
1272         * thus they are not included in this check.
1273         */
1274        if (Op == Op->Asl.Parent->Asl.Child)
1275        {
1276            /*
1277             * This is the first child of the field node, which is
1278             * the name of the region.  Get the parse node for the
1279             * region -- which contains the length of the region.
1280             */
1281            OwningOp = Node->Op;
1282            Op->Asl.Parent->Asl.ExtraValue =
1283                ACPI_MUL_8 ((UINT32) OwningOp->Asl.Value.Integer);
1284
1285            /* Examine the field access width */
1286
1287            switch ((UINT8) Op->Asl.Parent->Asl.Value.Integer)
1288            {
1289            case AML_FIELD_ACCESS_ANY:
1290            case AML_FIELD_ACCESS_BYTE:
1291            case AML_FIELD_ACCESS_BUFFER:
1292            default:
1293                MinimumLength = 1;
1294                break;
1295
1296            case AML_FIELD_ACCESS_WORD:
1297                MinimumLength = 2;
1298                break;
1299
1300            case AML_FIELD_ACCESS_DWORD:
1301                MinimumLength = 4;
1302                break;
1303
1304            case AML_FIELD_ACCESS_QWORD:
1305                MinimumLength = 8;
1306                break;
1307            }
1308
1309            /*
1310             * Is the region at least as big as the access width?
1311             * Note: DataTableRegions have 0 length
1312             */
1313            if (((UINT32) OwningOp->Asl.Value.Integer) &&
1314                ((UINT32) OwningOp->Asl.Value.Integer < MinimumLength))
1315            {
1316                AslError (ASL_ERROR, ASL_MSG_FIELD_ACCESS_WIDTH, Op, NULL);
1317            }
1318
1319            /*
1320             * Check EC/CMOS/SMBUS fields to make sure that the correct
1321             * access type is used (BYTE for EC/CMOS, BUFFER for SMBUS)
1322             */
1323            SpaceIdOp = OwningOp->Asl.Child->Asl.Next;
1324            switch ((UINT32) SpaceIdOp->Asl.Value.Integer)
1325            {
1326            case REGION_EC:
1327            case REGION_CMOS:
1328
1329                if ((UINT8) Op->Asl.Parent->Asl.Value.Integer != AML_FIELD_ACCESS_BYTE)
1330                {
1331                    AslError (ASL_ERROR, ASL_MSG_REGION_BYTE_ACCESS, Op, NULL);
1332                }
1333                break;
1334
1335            case REGION_SMBUS:
1336            case REGION_IPMI:
1337
1338                if ((UINT8) Op->Asl.Parent->Asl.Value.Integer != AML_FIELD_ACCESS_BUFFER)
1339                {
1340                    AslError (ASL_ERROR, ASL_MSG_REGION_BUFFER_ACCESS, Op, NULL);
1341                }
1342                break;
1343
1344            default:
1345
1346                /* Nothing to do for other address spaces */
1347                break;
1348            }
1349        }
1350        else
1351        {
1352            /*
1353             * This is one element of the field list.  Check to make sure
1354             * that it does not go beyond the end of the parent operation region.
1355             *
1356             * In the code below:
1357             *    Op->Asl.Parent->Asl.ExtraValue      - Region Length (bits)
1358             *    Op->Asl.ExtraValue                  - Field start offset (bits)
1359             *    Op->Asl.Child->Asl.Value.Integer32  - Field length (bits)
1360             *    Op->Asl.Child->Asl.ExtraValue       - Field access width (bits)
1361             */
1362            if (Op->Asl.Parent->Asl.ExtraValue && Op->Asl.Child)
1363            {
1364                LkCheckFieldRange (Op,
1365                            Op->Asl.Parent->Asl.ExtraValue,
1366                            Op->Asl.ExtraValue,
1367                            (UINT32) Op->Asl.Child->Asl.Value.Integer,
1368                            Op->Asl.Child->Asl.ExtraValue);
1369            }
1370        }
1371    }
1372
1373    Op->Asl.Node = Node;
1374    return (Status);
1375}
1376
1377
1378/*******************************************************************************
1379 *
1380 * FUNCTION:    LkNamespaceLocateEnd
1381 *
1382 * PARAMETERS:  ASL_WALK_CALLBACK
1383 *
1384 * RETURN:      Status
1385 *
1386 * DESCRIPTION: Ascending callback used during cross reference.  We only
1387 *              need to worry about scope management here.
1388 *
1389 ******************************************************************************/
1390
1391static ACPI_STATUS
1392LkNamespaceLocateEnd (
1393    ACPI_PARSE_OBJECT       *Op,
1394    UINT32                  Level,
1395    void                    *Context)
1396{
1397    ACPI_WALK_STATE         *WalkState = (ACPI_WALK_STATE *) Context;
1398    const ACPI_OPCODE_INFO  *OpInfo;
1399
1400
1401    ACPI_FUNCTION_TRACE (LkNamespaceLocateEnd);
1402
1403
1404    /* We are only interested in opcodes that have an associated name */
1405
1406    OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
1407    if (!(OpInfo->Flags & AML_NAMED))
1408    {
1409        return (AE_OK);
1410    }
1411
1412    /* Not interested in name references, we did not open a scope for them */
1413
1414    if ((Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) ||
1415        (Op->Asl.ParseOpcode == PARSEOP_NAMESEG)    ||
1416        (Op->Asl.ParseOpcode == PARSEOP_METHODCALL))
1417    {
1418        return (AE_OK);
1419    }
1420
1421    /* Pop the scope stack if necessary */
1422
1423    if (AcpiNsOpensScope (AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode)))
1424    {
1425
1426        ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
1427            "%s: Popping scope for Op %p\n",
1428            AcpiUtGetTypeName (OpInfo->ObjectType), Op));
1429
1430        (void) AcpiDsScopeStackPop (WalkState);
1431    }
1432
1433    return (AE_OK);
1434}
1435
1436
1437