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