* Intel ACPI 20030228 distribution with local DragonFly changes.
[dragonfly.git] / sys / contrib / dev / acpica / nsaccess.c
1 /*******************************************************************************
2  *
3  * Module Name: nsaccess - Top-level functions for accessing ACPI namespace
4  *              $Revision: 171 $
5  *
6  ******************************************************************************/
7
8 /******************************************************************************
9  *
10  * 1. Copyright Notice
11  *
12  * Some or all of this work - Copyright (c) 1999 - 2003, Intel Corp.
13  * All rights reserved.
14  *
15  * 2. License
16  *
17  * 2.1. This is your license from Intel Corp. under its intellectual property
18  * rights.  You may have additional license terms from the party that provided
19  * you this software, covering your right to use that party's intellectual
20  * property rights.
21  *
22  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
23  * copy of the source code appearing in this file ("Covered Code") an
24  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
25  * base code distributed originally by Intel ("Original Intel Code") to copy,
26  * make derivatives, distribute, use and display any portion of the Covered
27  * Code in any form, with the right to sublicense such rights; and
28  *
29  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
30  * license (with the right to sublicense), under only those claims of Intel
31  * patents that are infringed by the Original Intel Code, to make, use, sell,
32  * offer to sell, and import the Covered Code and derivative works thereof
33  * solely to the minimum extent necessary to exercise the above copyright
34  * license, and in no event shall the patent license extend to any additions
35  * to or modifications of the Original Intel Code.  No other license or right
36  * is granted directly or by implication, estoppel or otherwise;
37  *
38  * The above copyright and patent license is granted only if the following
39  * conditions are met:
40  *
41  * 3. Conditions
42  *
43  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
44  * Redistribution of source code of any substantial portion of the Covered
45  * Code or modification with rights to further distribute source must include
46  * the above Copyright Notice, the above License, this list of Conditions,
47  * and the following Disclaimer and Export Compliance provision.  In addition,
48  * Licensee must cause all Covered Code to which Licensee contributes to
49  * contain a file documenting the changes Licensee made to create that Covered
50  * Code and the date of any change.  Licensee must include in that file the
51  * documentation of any changes made by any predecessor Licensee.  Licensee
52  * must include a prominent statement that the modification is derived,
53  * directly or indirectly, from Original Intel Code.
54  *
55  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
56  * Redistribution of source code of any substantial portion of the Covered
57  * Code or modification without rights to further distribute source must
58  * include the following Disclaimer and Export Compliance provision in the
59  * documentation and/or other materials provided with distribution.  In
60  * addition, Licensee may not authorize further sublicense of source of any
61  * portion of the Covered Code, and must include terms to the effect that the
62  * license from Licensee to its licensee is limited to the intellectual
63  * property embodied in the software Licensee provides to its licensee, and
64  * not to intellectual property embodied in modifications its licensee may
65  * make.
66  *
67  * 3.3. Redistribution of Executable. Redistribution in executable form of any
68  * substantial portion of the Covered Code or modification must reproduce the
69  * above Copyright Notice, and the following Disclaimer and Export Compliance
70  * provision in the documentation and/or other materials provided with the
71  * distribution.
72  *
73  * 3.4. Intel retains all right, title, and interest in and to the Original
74  * Intel Code.
75  *
76  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
77  * Intel shall be used in advertising or otherwise to promote the sale, use or
78  * other dealings in products derived from or relating to the Covered Code
79  * without prior written authorization from Intel.
80  *
81  * 4. Disclaimer and Export Compliance
82  *
83  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
84  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
85  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
86  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
87  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
88  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
89  * PARTICULAR PURPOSE.
90  *
91  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
92  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
93  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
94  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
95  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
96  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
97  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
98  * LIMITED REMEDY.
99  *
100  * 4.3. Licensee shall not export, either directly or indirectly, any of this
101  * software or system incorporating such software without first obtaining any
102  * required license or other approval from the U. S. Department of Commerce or
103  * any other agency or department of the United States Government.  In the
104  * event Licensee exports any such software from the United States or
105  * re-exports any such software from a foreign destination, Licensee shall
106  * ensure that the distribution and export/re-export of the software is in
107  * compliance with all laws, regulations, orders, or other restrictions of the
108  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
109  * any of its subsidiaries will export/re-export any technical data, process,
110  * software, or service, directly or indirectly, to any country for which the
111  * United States government or any agency thereof requires an export license,
112  * other governmental approval, or letter of assurance, without first obtaining
113  * such license, approval or letter.
114  *
115  *****************************************************************************/
116 /* $DragonFly: src/sys/contrib/dev/acpica/Attic/nsaccess.c,v 1.1 2003/09/24 03:32:16 drhodus Exp $                                                               */
117
118 #define __NSACCESS_C__
119
120 #include "acpi.h"
121 #include "amlcode.h"
122 #include "acnamesp.h"
123 #include "acdispat.h"
124
125
126 #define _COMPONENT          ACPI_NAMESPACE
127         ACPI_MODULE_NAME    ("nsaccess")
128
129
130 /*******************************************************************************
131  *
132  * FUNCTION:    AcpiNsRootInitialize
133  *
134  * PARAMETERS:  None
135  *
136  * RETURN:      Status
137  *
138  * DESCRIPTION: Allocate and initialize the default root named objects
139  *
140  * MUTEX:       Locks namespace for entire execution
141  *
142  ******************************************************************************/
143
144 ACPI_STATUS
145 AcpiNsRootInitialize (void)
146 {
147     ACPI_STATUS                 Status;
148     const ACPI_PREDEFINED_NAMES *InitVal = NULL;
149     ACPI_NAMESPACE_NODE         *NewNode;
150     ACPI_OPERAND_OBJECT         *ObjDesc;
151
152
153     ACPI_FUNCTION_TRACE ("NsRootInitialize");
154
155
156     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
157     if (ACPI_FAILURE (Status))
158     {
159         return_ACPI_STATUS (Status);
160     }
161
162     /*
163      * The global root ptr is initially NULL, so a non-NULL value indicates
164      * that AcpiNsRootInitialize() has already been called; just return.
165      */
166     if (AcpiGbl_RootNode)
167     {
168         Status = AE_OK;
169         goto UnlockAndExit;
170     }
171
172     /*
173      * Tell the rest of the subsystem that the root is initialized
174      * (This is OK because the namespace is locked)
175      */
176     AcpiGbl_RootNode = &AcpiGbl_RootNodeStruct;
177
178     /* Enter the pre-defined names in the name table */
179
180     ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
181         "Entering predefined entries into namespace\n"));
182
183     for (InitVal = AcpiGbl_PreDefinedNames; InitVal->Name; InitVal++)
184     {
185         Status = AcpiNsLookup (NULL, InitVal->Name, InitVal->Type,
186                         ACPI_IMODE_LOAD_PASS2, ACPI_NS_NO_UPSEARCH, NULL, &NewNode);
187
188         if (ACPI_FAILURE (Status) || (!NewNode)) /* Must be on same line for code converter */
189         {
190             ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
191                 "Could not create predefined name %s, %s\n",
192                 InitVal->Name, AcpiFormatException (Status)));
193         }
194
195         /*
196          * Name entered successfully.
197          * If entry in PreDefinedNames[] specifies an
198          * initial value, create the initial value.
199          */
200         if (InitVal->Val)
201         {
202             ACPI_STRING Val;
203
204             Status = AcpiOsPredefinedOverride(InitVal, &Val);
205             if (ACPI_FAILURE (Status))
206             {
207                 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not override predefined %s\n",
208                     InitVal->Name));
209             }
210
211             if (!Val)
212             {
213                 Val = InitVal->Val;
214             }
215
216             /*
217              * Entry requests an initial value, allocate a
218              * descriptor for it.
219              */
220             ObjDesc = AcpiUtCreateInternalObject (InitVal->Type);
221             if (!ObjDesc)
222             {
223                 Status = AE_NO_MEMORY;
224                 goto UnlockAndExit;
225             }
226
227             /*
228              * Convert value string from table entry to
229              * internal representation. Only types actually
230              * used for initial values are implemented here.
231              */
232             switch (InitVal->Type)
233             {
234             case ACPI_TYPE_METHOD:
235                 ObjDesc->Method.ParamCount =
236                         (UINT8) ACPI_STRTOUL (Val, NULL, 10);
237                 ObjDesc->Common.Flags |= AOPOBJ_DATA_VALID;
238
239 #if defined (ACPI_NO_METHOD_EXECUTION) || defined (ACPI_CONSTANT_EVAL_ONLY)
240
241                 /* Compiler cheats by putting parameter count in the OwnerID */
242
243                 NewNode->OwnerId = ObjDesc->Method.ParamCount;
244 #endif
245                 break;
246
247             case ACPI_TYPE_INTEGER:
248
249                 ObjDesc->Integer.Value =
250                         (ACPI_INTEGER) ACPI_STRTOUL (Val, NULL, 10);
251                 break;
252
253
254             case ACPI_TYPE_STRING:
255
256                 /*
257                  * Build an object around the static string
258                  */
259                 ObjDesc->String.Length = (UINT32) ACPI_STRLEN (Val);
260                 ObjDesc->String.Pointer = Val;
261                 ObjDesc->Common.Flags |= AOPOBJ_STATIC_POINTER;
262                 break;
263
264
265             case ACPI_TYPE_MUTEX:
266
267                 ObjDesc->Mutex.Node = NewNode;
268                 ObjDesc->Mutex.SyncLevel =
269                             (UINT16) ACPI_STRTOUL (Val, NULL, 10);
270
271                 if (ACPI_STRCMP (InitVal->Name, "_GL_") == 0)
272                 {
273                     /*
274                      * Create a counting semaphore for the
275                      * global lock
276                      */
277                     Status = AcpiOsCreateSemaphore (ACPI_NO_UNIT_LIMIT,
278                                             1, &ObjDesc->Mutex.Semaphore);
279                     if (ACPI_FAILURE (Status))
280                     {
281                         goto UnlockAndExit;
282                     }
283
284                     /*
285                      * We just created the mutex for the
286                      * global lock, save it
287                      */
288                     AcpiGbl_GlobalLockSemaphore = ObjDesc->Mutex.Semaphore;
289                 }
290                 else
291                 {
292                     /* Create a mutex */
293
294                     Status = AcpiOsCreateSemaphore (1, 1,
295                                         &ObjDesc->Mutex.Semaphore);
296                     if (ACPI_FAILURE (Status))
297                     {
298                         goto UnlockAndExit;
299                     }
300                 }
301                 break;
302
303
304             default:
305                 ACPI_REPORT_ERROR (("Unsupported initial type value %X\n",
306                     InitVal->Type));
307                 AcpiUtRemoveReference (ObjDesc);
308                 ObjDesc = NULL;
309                 continue;
310             }
311
312             /* Store pointer to value descriptor in the Node */
313
314             Status = AcpiNsAttachObject (NewNode, ObjDesc, ACPI_GET_OBJECT_TYPE (ObjDesc));
315
316             /* Remove local reference to the object */
317
318             AcpiUtRemoveReference (ObjDesc);
319         }
320     }
321
322
323 UnlockAndExit:
324     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
325     return_ACPI_STATUS (Status);
326 }
327
328
329 /*******************************************************************************
330  *
331  * FUNCTION:    AcpiNsLookup
332  *
333  * PARAMETERS:  PrefixNode      - Search scope if name is not fully qualified
334  *              Pathname        - Search pathname, in internal format
335  *                                (as represented in the AML stream)
336  *              Type            - Type associated with name
337  *              InterpreterMode - IMODE_LOAD_PASS2 => add name if not found
338  *              Flags           - Flags describing the search restrictions
339  *              WalkState       - Current state of the walk
340  *              ReturnNode      - Where the Node is placed (if found
341  *                                or created successfully)
342  *
343  * RETURN:      Status
344  *
345  * DESCRIPTION: Find or enter the passed name in the name space.
346  *              Log an error if name not found in Exec mode.
347  *
348  * MUTEX:       Assumes namespace is locked.
349  *
350  ******************************************************************************/
351
352 ACPI_STATUS
353 AcpiNsLookup (
354     ACPI_GENERIC_STATE      *ScopeInfo,
355     char                    *Pathname,
356     ACPI_OBJECT_TYPE        Type,
357     ACPI_INTERPRETER_MODE   InterpreterMode,
358     UINT32                  Flags,
359     ACPI_WALK_STATE         *WalkState,
360     ACPI_NAMESPACE_NODE     **ReturnNode)
361 {
362     ACPI_STATUS             Status;
363     char                    *Path = Pathname;
364     ACPI_NAMESPACE_NODE     *PrefixNode;
365     ACPI_NAMESPACE_NODE     *CurrentNode = NULL;
366     ACPI_NAMESPACE_NODE     *ThisNode = NULL;
367     UINT32                  NumSegments;
368     UINT32                  NumCarats;
369     ACPI_NAME               SimpleName;
370     ACPI_OBJECT_TYPE        TypeToCheckFor;
371     ACPI_OBJECT_TYPE        ThisSearchType;
372     UINT32                  SearchParentFlag = ACPI_NS_SEARCH_PARENT;
373     UINT32                  LocalFlags = Flags & ~(ACPI_NS_ERROR_IF_FOUND |
374                                                    ACPI_NS_SEARCH_PARENT);
375
376
377     ACPI_FUNCTION_TRACE ("NsLookup");
378
379
380     if (!ReturnNode)
381     {
382         return_ACPI_STATUS (AE_BAD_PARAMETER);
383     }
384
385     AcpiGbl_NsLookupCount++;
386     *ReturnNode = ACPI_ENTRY_NOT_FOUND;
387
388     if (!AcpiGbl_RootNode)
389     {
390         return_ACPI_STATUS (AE_NO_NAMESPACE);
391     }
392
393     /*
394      * Get the prefix scope.
395      * A null scope means use the root scope
396      */
397     if ((!ScopeInfo) ||
398         (!ScopeInfo->Scope.Node))
399     {
400         ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
401             "Null scope prefix, using root node (%p)\n",
402             AcpiGbl_RootNode));
403
404         PrefixNode = AcpiGbl_RootNode;
405     }
406     else
407     {
408         PrefixNode = ScopeInfo->Scope.Node;
409         if (ACPI_GET_DESCRIPTOR_TYPE (PrefixNode) != ACPI_DESC_TYPE_NAMED)
410         {
411             ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "[%p] Not a namespace node\n",
412                 PrefixNode));
413             return_ACPI_STATUS (AE_AML_INTERNAL);
414         }
415
416         /*
417          * This node might not be a actual "scope" node (such as a
418          * Device/Method, etc.)  It could be a Package or other object node.
419          * Backup up the tree to find the containing scope node.
420          */
421         while (!AcpiNsOpensScope (PrefixNode->Type) &&
422                 PrefixNode->Type != ACPI_TYPE_ANY)
423         {
424             PrefixNode = AcpiNsGetParentNode (PrefixNode);
425         }
426     }
427
428     /* Save type   TBD: may be no longer necessary */
429
430     TypeToCheckFor = Type;
431
432     /*
433      * Begin examination of the actual pathname
434      */
435     if (!Pathname)
436     {
437         /* A Null NamePath is allowed and refers to the root */
438
439         NumSegments  = 0;
440         ThisNode     = AcpiGbl_RootNode;
441         Path     = "";
442
443         ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
444             "Null Pathname (Zero segments), Flags=%X\n", Flags));
445     }
446     else
447     {
448         /*
449          * Name pointer is valid (and must be in internal name format)
450          *
451          * Check for scope prefixes:
452          *
453          * As represented in the AML stream, a namepath consists of an
454          * optional scope prefix followed by a name segment part.
455          *
456          * If present, the scope prefix is either a Root Prefix (in
457          * which case the name is fully qualified), or one or more
458          * Parent Prefixes (in which case the name's scope is relative
459          * to the current scope).
460          */
461         if (*Path == (UINT8) AML_ROOT_PREFIX)
462         {
463             /* Pathname is fully qualified, start from the root */
464
465             ThisNode = AcpiGbl_RootNode;
466             SearchParentFlag = ACPI_NS_NO_UPSEARCH;
467
468             /* Point to name segment part */
469
470             Path++;
471
472             ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
473                 "Path is absolute from root [%p]\n", ThisNode));
474         }
475         else
476         {
477             /* Pathname is relative to current scope, start there */
478
479             ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
480                 "Searching relative to prefix scope [%4.4s] (%p)\n",
481                 PrefixNode->Name.Ascii, PrefixNode));
482
483             /*
484              * Handle multiple Parent Prefixes (carat) by just getting
485              * the parent node for each prefix instance.
486              */
487             ThisNode = PrefixNode;
488             NumCarats = 0;
489             while (*Path == (UINT8) AML_PARENT_PREFIX)
490             {
491                 /* Name is fully qualified, no search rules apply */
492
493                 SearchParentFlag = ACPI_NS_NO_UPSEARCH;
494                 /*
495                  * Point past this prefix to the name segment
496                  * part or the next Parent Prefix
497                  */
498                 Path++;
499
500                 /* Backup to the parent node */
501
502                 NumCarats++;
503                 ThisNode = AcpiNsGetParentNode (ThisNode);
504                 if (!ThisNode)
505                 {
506                     /* Current scope has no parent scope */
507
508                     ACPI_REPORT_ERROR (
509                         ("ACPI path has too many parent prefixes (^) - reached beyond root node\n"));
510                     return_ACPI_STATUS (AE_NOT_FOUND);
511                 }
512             }
513
514             if (SearchParentFlag == ACPI_NS_NO_UPSEARCH)
515             {
516                 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
517                     "Search scope is [%4.4s], path has %d carat(s)\n",
518                     ThisNode->Name.Ascii, NumCarats));
519             }
520         }
521
522         /*
523          * Determine the number of ACPI name segments in this pathname.
524          *
525          * The segment part consists of either:
526          *  - A Null name segment (0)
527          *  - A DualNamePrefix followed by two 4-byte name segments
528          *  - A MultiNamePrefix followed by a byte indicating the
529          *      number of segments and the segments themselves.
530          *  - A single 4-byte name segment
531          *
532          * Examine the name prefix opcode, if any, to determine the number of
533          * segments.
534          */
535         switch (*Path)
536         {
537         case 0:
538             /*
539              * Null name after a root or parent prefixes. We already
540              * have the correct target node and there are no name segments.
541              */
542             NumSegments  = 0;
543             Type = ThisNode->Type;
544
545             ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
546                 "Prefix-only Pathname (Zero name segments), Flags=%X\n", Flags));
547             break;
548
549         case AML_DUAL_NAME_PREFIX:
550
551             /* More than one NameSeg, search rules do not apply */
552
553             SearchParentFlag = ACPI_NS_NO_UPSEARCH;
554
555             /* Two segments, point to first name segment */
556
557             NumSegments = 2;
558             Path++;
559
560             ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
561                 "Dual Pathname (2 segments, Flags=%X)\n", Flags));
562             break;
563
564         case AML_MULTI_NAME_PREFIX_OP:
565
566             /* More than one NameSeg, search rules do not apply */
567
568             SearchParentFlag = ACPI_NS_NO_UPSEARCH;
569
570             /* Extract segment count, point to first name segment */
571
572             Path++;
573             NumSegments = (UINT32) (UINT8) *Path;
574             Path++;
575
576             ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
577                 "Multi Pathname (%d Segments, Flags=%X) \n",
578                 NumSegments, Flags));
579             break;
580
581         default:
582             /*
583              * Not a Null name, no Dual or Multi prefix, hence there is
584              * only one name segment and Pathname is already pointing to it.
585              */
586             NumSegments = 1;
587
588             ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
589                 "Simple Pathname (1 segment, Flags=%X)\n", Flags));
590             break;
591         }
592
593         ACPI_DEBUG_EXEC (AcpiNsPrintPathname (NumSegments, Path));
594     }
595
596
597     /*
598      * Search namespace for each segment of the name.  Loop through and
599      * verify (or add to the namespace) each name segment.
600      *
601      * The object type is significant only at the last name
602      * segment.  (We don't care about the types along the path, only
603      * the type of the final target object.)
604      */
605     ThisSearchType = ACPI_TYPE_ANY;
606     CurrentNode = ThisNode;
607     while (NumSegments && CurrentNode)
608     {
609         NumSegments--;
610         if (!NumSegments)
611         {
612             /*
613              * This is the last segment, enable typechecking
614              */
615             ThisSearchType = Type;
616
617             /*
618              * Only allow automatic parent search (search rules) if the caller
619              * requested it AND we have a single, non-fully-qualified NameSeg
620              */
621             if ((SearchParentFlag != ACPI_NS_NO_UPSEARCH) &&
622                 (Flags & ACPI_NS_SEARCH_PARENT))
623             {
624                 LocalFlags |= ACPI_NS_SEARCH_PARENT;
625             }
626
627             /* Set error flag according to caller */
628
629             if (Flags & ACPI_NS_ERROR_IF_FOUND)
630             {
631                 LocalFlags |= ACPI_NS_ERROR_IF_FOUND;
632             }
633         }
634
635         /* Extract one ACPI name from the front of the pathname */
636
637         ACPI_MOVE_UNALIGNED32_TO_32 (&SimpleName, Path);
638
639         /* Try to find the single (4 character) ACPI name */
640
641         Status = AcpiNsSearchAndEnter (SimpleName, WalkState, CurrentNode,
642                         InterpreterMode, ThisSearchType, LocalFlags, &ThisNode);
643         if (ACPI_FAILURE (Status))
644         {
645             if (Status == AE_NOT_FOUND)
646             {
647                 /* Name not found in ACPI namespace */
648
649                 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
650                     "Name [%4.4s] not found in scope [%4.4s] %p\n",
651                     (char *) &SimpleName, (char *) &CurrentNode->Name,
652                     CurrentNode));
653             }
654
655             *ReturnNode = ThisNode;
656             return_ACPI_STATUS (Status);
657         }
658
659         /*
660          * Sanity typecheck of the target object:
661          *
662          * If 1) This is the last segment (NumSegments == 0)
663          *    2) And we are looking for a specific type
664          *       (Not checking for TYPE_ANY)
665          *    3) Which is not an alias
666          *    4) Which is not a local type (TYPE_SCOPE)
667          *    5) And the type of target object is known (not TYPE_ANY)
668          *    6) And target object does not match what we are looking for
669          *
670          * Then we have a type mismatch.  Just warn and ignore it.
671          */
672         if ((NumSegments        == 0)                               &&
673             (TypeToCheckFor     != ACPI_TYPE_ANY)                   &&
674             (TypeToCheckFor     != ACPI_TYPE_LOCAL_ALIAS)           &&
675             (TypeToCheckFor     != ACPI_TYPE_LOCAL_SCOPE)           &&
676             (ThisNode->Type     != ACPI_TYPE_ANY)                   &&
677             (ThisNode->Type     != TypeToCheckFor))
678         {
679             /* Complain about a type mismatch */
680
681             ACPI_REPORT_WARNING (
682                 ("NsLookup: Type mismatch on %4.4s (%s), searching for (%s)\n",
683                 (char *) &SimpleName, AcpiUtGetTypeName (ThisNode->Type),
684                 AcpiUtGetTypeName (TypeToCheckFor)));
685         }
686
687         /*
688          * If this is the last name segment and we are not looking for a
689          * specific type, but the type of found object is known, use that type
690          * to see if it opens a scope.
691          */
692         if ((NumSegments == 0) && (Type == ACPI_TYPE_ANY))
693         {
694             Type = ThisNode->Type;
695         }
696
697         /* Point to next name segment and make this node current */
698
699         Path += ACPI_NAME_SIZE;
700         CurrentNode = ThisNode;
701     }
702
703     /*
704      * Always check if we need to open a new scope
705      */
706     if (!(Flags & ACPI_NS_DONT_OPEN_SCOPE) && (WalkState))
707     {
708         /*
709          * If entry is a type which opens a scope, push the new scope on the
710          * scope stack.
711          */
712         if (AcpiNsOpensScope (Type))
713         {
714             Status = AcpiDsScopeStackPush (ThisNode, Type, WalkState);
715             if (ACPI_FAILURE (Status))
716             {
717                 return_ACPI_STATUS (Status);
718             }
719         }
720     }
721
722     *ReturnNode = ThisNode;
723     return_ACPI_STATUS (AE_OK);
724 }
725