]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/contrib/dev/acpica/nsaccess.c
merge fix for boot-time hang on centos' xen
[FreeBSD/FreeBSD.git] / sys / contrib / dev / acpica / nsaccess.c
1 /*******************************************************************************
2  *
3  * Module Name: nsaccess - Top-level functions for accessing ACPI namespace
4  *              $Revision: 184 $
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 <contrib/dev/acpica/acpi.h>
120 #include <contrib/dev/acpica/amlcode.h>
121 #include <contrib/dev/acpica/acnamesp.h>
122 #include <contrib/dev/acpica/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         /* _OSI is optional for now, will be permanent later */
186
187         if (!ACPI_STRCMP (InitVal->Name, "_OSI") && !AcpiGbl_CreateOsiMethod)
188         {
189             continue;
190         }
191
192         Status = AcpiNsLookup (NULL, InitVal->Name, InitVal->Type,
193                         ACPI_IMODE_LOAD_PASS2, ACPI_NS_NO_UPSEARCH,
194                         NULL, &NewNode);
195
196         if (ACPI_FAILURE (Status) || (!NewNode)) /* Must be on same line for code converter */
197         {
198             ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
199                 "Could not create predefined name %s, %s\n",
200                 InitVal->Name, AcpiFormatException (Status)));
201         }
202
203         /*
204          * Name entered successfully.
205          * If entry in PreDefinedNames[] specifies an
206          * initial value, create the initial value.
207          */
208         if (InitVal->Val)
209         {
210             Status = AcpiOsPredefinedOverride (InitVal, &Val);
211             if (ACPI_FAILURE (Status))
212             {
213                 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
214                     "Could not override predefined %s\n",
215                     InitVal->Name));
216             }
217
218             if (!Val)
219             {
220                 Val = InitVal->Val;
221             }
222
223             /*
224              * Entry requests an initial value, allocate a
225              * descriptor for it.
226              */
227             ObjDesc = AcpiUtCreateInternalObject (InitVal->Type);
228             if (!ObjDesc)
229             {
230                 Status = AE_NO_MEMORY;
231                 goto UnlockAndExit;
232             }
233
234             /*
235              * Convert value string from table entry to
236              * internal representation. Only types actually
237              * used for initial values are implemented here.
238              */
239             switch (InitVal->Type)
240             {
241             case ACPI_TYPE_METHOD:
242                 ObjDesc->Method.ParamCount = (UINT8) ACPI_STRTOUL
243                                                         (Val, NULL, 10);
244                 ObjDesc->Common.Flags |= AOPOBJ_DATA_VALID;
245
246 #if defined (_ACPI_ASL_COMPILER) || defined (_ACPI_DUMP_APP)
247
248                 /*
249                  * iASL Compiler cheats by putting parameter count
250                  * in the OwnerID
251                  */
252                 NewNode->OwnerId = ObjDesc->Method.ParamCount;
253 #else
254                 /* Mark this as a very SPECIAL method */
255
256                 ObjDesc->Method.MethodFlags = AML_METHOD_INTERNAL_ONLY;
257                 ObjDesc->Method.Implementation = AcpiUtOsiImplementation;
258 #endif
259                 break;
260
261             case ACPI_TYPE_INTEGER:
262
263                 ObjDesc->Integer.Value =
264                         (ACPI_INTEGER) ACPI_STRTOUL (Val, NULL, 10);
265                 break;
266
267
268             case ACPI_TYPE_STRING:
269
270                 /*
271                  * Build an object around the static string
272                  */
273                 ObjDesc->String.Length = (UINT32) ACPI_STRLEN (Val);
274                 ObjDesc->String.Pointer = Val;
275                 ObjDesc->Common.Flags |= AOPOBJ_STATIC_POINTER;
276                 break;
277
278
279             case ACPI_TYPE_MUTEX:
280
281                 ObjDesc->Mutex.Node = NewNode;
282                 ObjDesc->Mutex.SyncLevel = (UINT8) ACPI_STRTOUL
283                                                         (Val, NULL, 10);
284
285                 if (ACPI_STRCMP (InitVal->Name, "_GL_") == 0)
286                 {
287                     /*
288                      * Create a counting semaphore for the
289                      * global lock
290                      */
291                     Status = AcpiOsCreateSemaphore (ACPI_NO_UNIT_LIMIT,
292                                             1, &ObjDesc->Mutex.Semaphore);
293                     if (ACPI_FAILURE (Status))
294                     {
295                         AcpiUtRemoveReference (ObjDesc);
296                         goto UnlockAndExit;
297                     }
298
299                     /*
300                      * We just created the mutex for the
301                      * global lock, save it
302                      */
303                     AcpiGbl_GlobalLockSemaphore = ObjDesc->Mutex.Semaphore;
304                 }
305                 else
306                 {
307                     /* Create a mutex */
308
309                     Status = AcpiOsCreateSemaphore (1, 1,
310                                         &ObjDesc->Mutex.Semaphore);
311                     if (ACPI_FAILURE (Status))
312                     {
313                         AcpiUtRemoveReference (ObjDesc);
314                         goto UnlockAndExit;
315                     }
316                 }
317                 break;
318
319
320             default:
321
322                 ACPI_REPORT_ERROR (("Unsupported initial type value %X\n",
323                     InitVal->Type));
324                 AcpiUtRemoveReference (ObjDesc);
325                 ObjDesc = NULL;
326                 continue;
327             }
328
329             /* Store pointer to value descriptor in the Node */
330
331             Status = AcpiNsAttachObject (NewNode, ObjDesc,
332                         ACPI_GET_OBJECT_TYPE (ObjDesc));
333
334             /* Remove local reference to the object */
335
336             AcpiUtRemoveReference (ObjDesc);
337         }
338     }
339
340
341 UnlockAndExit:
342     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
343
344     /* Save a handle to "_GPE", it is always present */
345
346     if (ACPI_SUCCESS (Status))
347     {
348         Status = AcpiNsGetNodeByPath ("\\_GPE", NULL, ACPI_NS_NO_UPSEARCH,
349                         &AcpiGbl_FadtGpeDevice);
350     }
351
352     return_ACPI_STATUS (Status);
353 }
354
355
356 /*******************************************************************************
357  *
358  * FUNCTION:    AcpiNsLookup
359  *
360  * PARAMETERS:  PrefixNode      - Search scope if name is not fully qualified
361  *              Pathname        - Search pathname, in internal format
362  *                                (as represented in the AML stream)
363  *              Type            - Type associated with name
364  *              InterpreterMode - IMODE_LOAD_PASS2 => add name if not found
365  *              Flags           - Flags describing the search restrictions
366  *              WalkState       - Current state of the walk
367  *              ReturnNode      - Where the Node is placed (if found
368  *                                or created successfully)
369  *
370  * RETURN:      Status
371  *
372  * DESCRIPTION: Find or enter the passed name in the name space.
373  *              Log an error if name not found in Exec mode.
374  *
375  * MUTEX:       Assumes namespace is locked.
376  *
377  ******************************************************************************/
378
379 ACPI_STATUS
380 AcpiNsLookup (
381     ACPI_GENERIC_STATE      *ScopeInfo,
382     char                    *Pathname,
383     ACPI_OBJECT_TYPE        Type,
384     ACPI_INTERPRETER_MODE   InterpreterMode,
385     UINT32                  Flags,
386     ACPI_WALK_STATE         *WalkState,
387     ACPI_NAMESPACE_NODE     **ReturnNode)
388 {
389     ACPI_STATUS             Status;
390     char                    *Path = Pathname;
391     ACPI_NAMESPACE_NODE     *PrefixNode;
392     ACPI_NAMESPACE_NODE     *CurrentNode = NULL;
393     ACPI_NAMESPACE_NODE     *ThisNode = NULL;
394     UINT32                  NumSegments;
395     UINT32                  NumCarats;
396     ACPI_NAME               SimpleName;
397     ACPI_OBJECT_TYPE        TypeToCheckFor;
398     ACPI_OBJECT_TYPE        ThisSearchType;
399     UINT32                  SearchParentFlag = ACPI_NS_SEARCH_PARENT;
400     UINT32                  LocalFlags = Flags & ~(ACPI_NS_ERROR_IF_FOUND |
401                                                    ACPI_NS_SEARCH_PARENT);
402
403
404     ACPI_FUNCTION_TRACE ("NsLookup");
405
406
407     if (!ReturnNode)
408     {
409         return_ACPI_STATUS (AE_BAD_PARAMETER);
410     }
411
412     AcpiGbl_NsLookupCount++;
413     *ReturnNode = ACPI_ENTRY_NOT_FOUND;
414
415     if (!AcpiGbl_RootNode)
416     {
417         return_ACPI_STATUS (AE_NO_NAMESPACE);
418     }
419
420     /*
421      * Get the prefix scope.
422      * A null scope means use the root scope
423      */
424     if ((!ScopeInfo) ||
425         (!ScopeInfo->Scope.Node))
426     {
427         ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
428             "Null scope prefix, using root node (%p)\n",
429             AcpiGbl_RootNode));
430
431         PrefixNode = AcpiGbl_RootNode;
432     }
433     else
434     {
435         PrefixNode = ScopeInfo->Scope.Node;
436         if (ACPI_GET_DESCRIPTOR_TYPE (PrefixNode) != ACPI_DESC_TYPE_NAMED)
437         {
438             ACPI_REPORT_ERROR (("NsLookup: %p is not a namespace node [%s]\n",
439                     PrefixNode, AcpiUtGetDescriptorName (PrefixNode)));
440             return_ACPI_STATUS (AE_AML_INTERNAL);
441         }
442
443         /*
444          * This node might not be a actual "scope" node (such as a
445          * Device/Method, etc.)  It could be a Package or other object node.
446          * Backup up the tree to find the containing scope node.
447          */
448         while (!AcpiNsOpensScope (PrefixNode->Type) &&
449                 PrefixNode->Type != ACPI_TYPE_ANY)
450         {
451             PrefixNode = AcpiNsGetParentNode (PrefixNode);
452         }
453     }
454
455     /* Save type   TBD: may be no longer necessary */
456
457     TypeToCheckFor = Type;
458
459     /*
460      * Begin examination of the actual pathname
461      */
462     if (!Pathname)
463     {
464         /* A Null NamePath is allowed and refers to the root */
465
466         NumSegments  = 0;
467         ThisNode     = AcpiGbl_RootNode;
468         Path     = "";
469
470         ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
471             "Null Pathname (Zero segments), Flags=%X\n", Flags));
472     }
473     else
474     {
475         /*
476          * Name pointer is valid (and must be in internal name format)
477          *
478          * Check for scope prefixes:
479          *
480          * As represented in the AML stream, a namepath consists of an
481          * optional scope prefix followed by a name segment part.
482          *
483          * If present, the scope prefix is either a Root Prefix (in
484          * which case the name is fully qualified), or one or more
485          * Parent Prefixes (in which case the name's scope is relative
486          * to the current scope).
487          */
488         if (*Path == (UINT8) AML_ROOT_PREFIX)
489         {
490             /* Pathname is fully qualified, start from the root */
491
492             ThisNode = AcpiGbl_RootNode;
493             SearchParentFlag = ACPI_NS_NO_UPSEARCH;
494
495             /* Point to name segment part */
496
497             Path++;
498
499             ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
500                 "Path is absolute from root [%p]\n", ThisNode));
501         }
502         else
503         {
504             /* Pathname is relative to current scope, start there */
505
506             ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
507                 "Searching relative to prefix scope [%4.4s] (%p)\n",
508                 AcpiUtGetNodeName (PrefixNode), PrefixNode));
509
510             /*
511              * Handle multiple Parent Prefixes (carat) by just getting
512              * the parent node for each prefix instance.
513              */
514             ThisNode = PrefixNode;
515             NumCarats = 0;
516             while (*Path == (UINT8) AML_PARENT_PREFIX)
517             {
518                 /* Name is fully qualified, no search rules apply */
519
520                 SearchParentFlag = ACPI_NS_NO_UPSEARCH;
521                 /*
522                  * Point past this prefix to the name segment
523                  * part or the next Parent Prefix
524                  */
525                 Path++;
526
527                 /* Backup to the parent node */
528
529                 NumCarats++;
530                 ThisNode = AcpiNsGetParentNode (ThisNode);
531                 if (!ThisNode)
532                 {
533                     /* Current scope has no parent scope */
534
535                     ACPI_REPORT_ERROR (
536                         ("ACPI path has too many parent prefixes (^) - reached beyond root node\n"));
537                     return_ACPI_STATUS (AE_NOT_FOUND);
538                 }
539             }
540
541             if (SearchParentFlag == ACPI_NS_NO_UPSEARCH)
542             {
543                 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
544                     "Search scope is [%4.4s], path has %d carat(s)\n",
545                     AcpiUtGetNodeName (ThisNode), NumCarats));
546             }
547         }
548
549         /*
550          * Determine the number of ACPI name segments in this pathname.
551          *
552          * The segment part consists of either:
553          *  - A Null name segment (0)
554          *  - A DualNamePrefix followed by two 4-byte name segments
555          *  - A MultiNamePrefix followed by a byte indicating the
556          *      number of segments and the segments themselves.
557          *  - A single 4-byte name segment
558          *
559          * Examine the name prefix opcode, if any, to determine the number of
560          * segments.
561          */
562         switch (*Path)
563         {
564         case 0:
565             /*
566              * Null name after a root or parent prefixes. We already
567              * have the correct target node and there are no name segments.
568              */
569             NumSegments  = 0;
570             Type = ThisNode->Type;
571
572             ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
573                 "Prefix-only Pathname (Zero name segments), Flags=%X\n",
574                 Flags));
575             break;
576
577         case AML_DUAL_NAME_PREFIX:
578
579             /* More than one NameSeg, search rules do not apply */
580
581             SearchParentFlag = ACPI_NS_NO_UPSEARCH;
582
583             /* Two segments, point to first name segment */
584
585             NumSegments = 2;
586             Path++;
587
588             ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
589                 "Dual Pathname (2 segments, Flags=%X)\n", Flags));
590             break;
591
592         case AML_MULTI_NAME_PREFIX_OP:
593
594             /* More than one NameSeg, search rules do not apply */
595
596             SearchParentFlag = ACPI_NS_NO_UPSEARCH;
597
598             /* Extract segment count, point to first name segment */
599
600             Path++;
601             NumSegments = (UINT32) (UINT8) *Path;
602             Path++;
603
604             ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
605                 "Multi Pathname (%d Segments, Flags=%X) \n",
606                 NumSegments, Flags));
607             break;
608
609         default:
610             /*
611              * Not a Null name, no Dual or Multi prefix, hence there is
612              * only one name segment and Pathname is already pointing to it.
613              */
614             NumSegments = 1;
615
616             ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
617                 "Simple Pathname (1 segment, Flags=%X)\n", Flags));
618             break;
619         }
620
621         ACPI_DEBUG_EXEC (AcpiNsPrintPathname (NumSegments, Path));
622     }
623
624
625     /*
626      * Search namespace for each segment of the name.  Loop through and
627      * verify (or add to the namespace) each name segment.
628      *
629      * The object type is significant only at the last name
630      * segment.  (We don't care about the types along the path, only
631      * the type of the final target object.)
632      */
633     ThisSearchType = ACPI_TYPE_ANY;
634     CurrentNode = ThisNode;
635     while (NumSegments && CurrentNode)
636     {
637         NumSegments--;
638         if (!NumSegments)
639         {
640             /*
641              * This is the last segment, enable typechecking
642              */
643             ThisSearchType = Type;
644
645             /*
646              * Only allow automatic parent search (search rules) if the caller
647              * requested it AND we have a single, non-fully-qualified NameSeg
648              */
649             if ((SearchParentFlag != ACPI_NS_NO_UPSEARCH) &&
650                 (Flags & ACPI_NS_SEARCH_PARENT))
651             {
652                 LocalFlags |= ACPI_NS_SEARCH_PARENT;
653             }
654
655             /* Set error flag according to caller */
656
657             if (Flags & ACPI_NS_ERROR_IF_FOUND)
658             {
659                 LocalFlags |= ACPI_NS_ERROR_IF_FOUND;
660             }
661         }
662
663         /* Extract one ACPI name from the front of the pathname */
664
665         ACPI_MOVE_32_TO_32 (&SimpleName, Path);
666
667         /* Try to find the single (4 character) ACPI name */
668
669         Status = AcpiNsSearchAndEnter (SimpleName, WalkState, CurrentNode,
670                     InterpreterMode, ThisSearchType, LocalFlags, &ThisNode);
671         if (ACPI_FAILURE (Status))
672         {
673             if (Status == AE_NOT_FOUND)
674             {
675                 /* Name not found in ACPI namespace */
676
677                 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
678                     "Name [%4.4s] not found in scope [%4.4s] %p\n",
679                     (char *) &SimpleName, (char *) &CurrentNode->Name,
680                     CurrentNode));
681             }
682
683             *ReturnNode = ThisNode;
684             return_ACPI_STATUS (Status);
685         }
686
687         /*
688          * Sanity typecheck of the target object:
689          *
690          * If 1) This is the last segment (NumSegments == 0)
691          *    2) And we are looking for a specific type
692          *       (Not checking for TYPE_ANY)
693          *    3) Which is not an alias
694          *    4) Which is not a local type (TYPE_SCOPE)
695          *    5) And the type of target object is known (not TYPE_ANY)
696          *    6) And target object does not match what we are looking for
697          *
698          * Then we have a type mismatch.  Just warn and ignore it.
699          */
700         if ((NumSegments        == 0)                               &&
701             (TypeToCheckFor     != ACPI_TYPE_ANY)                   &&
702             (TypeToCheckFor     != ACPI_TYPE_LOCAL_ALIAS)           &&
703             (TypeToCheckFor     != ACPI_TYPE_LOCAL_METHOD_ALIAS)    &&
704             (TypeToCheckFor     != ACPI_TYPE_LOCAL_SCOPE)           &&
705             (ThisNode->Type     != ACPI_TYPE_ANY)                   &&
706             (ThisNode->Type     != TypeToCheckFor))
707         {
708             /* Complain about a type mismatch */
709
710             ACPI_REPORT_WARNING (
711                 ("NsLookup: Type mismatch on %4.4s (%s), searching for (%s)\n",
712                 (char *) &SimpleName, AcpiUtGetTypeName (ThisNode->Type),
713                 AcpiUtGetTypeName (TypeToCheckFor)));
714         }
715
716         /*
717          * If this is the last name segment and we are not looking for a
718          * specific type, but the type of found object is known, use that type
719          * to see if it opens a scope.
720          */
721         if ((NumSegments == 0) && (Type == ACPI_TYPE_ANY))
722         {
723             Type = ThisNode->Type;
724         }
725
726         /* Point to next name segment and make this node current */
727
728         Path += ACPI_NAME_SIZE;
729         CurrentNode = ThisNode;
730     }
731
732     /*
733      * Always check if we need to open a new scope
734      */
735     if (!(Flags & ACPI_NS_DONT_OPEN_SCOPE) && (WalkState))
736     {
737         /*
738          * If entry is a type which opens a scope, push the new scope on the
739          * scope stack.
740          */
741         if (AcpiNsOpensScope (Type))
742         {
743             Status = AcpiDsScopeStackPush (ThisNode, Type, WalkState);
744             if (ACPI_FAILURE (Status))
745             {
746                 return_ACPI_STATUS (Status);
747             }
748         }
749     }
750
751     *ReturnNode = ThisNode;
752     return_ACPI_STATUS (AE_OK);
753 }
754