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