1 /*******************************************************************************
   2  *
   3  * Module Name: nsaccess - Top-level functions for accessing ACPI namespace
   4  *
   5  ******************************************************************************/
   6 
   7 /*
   8  * Copyright (C) 2000 - 2011, Intel Corp.
   9  * All rights reserved.
  10  *
  11  * Redistribution and use in source and binary forms, with or without
  12  * modification, are permitted provided that the following conditions
  13  * are met:
  14  * 1. Redistributions of source code must retain the above copyright
  15  *    notice, this list of conditions, and the following disclaimer,
  16  *    without modification.
  17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
  18  *    substantially similar to the "NO WARRANTY" disclaimer below
  19  *    ("Disclaimer") and any redistribution must be conditioned upon
  20  *    including a substantially similar Disclaimer requirement for further
  21  *    binary redistribution.
  22  * 3. Neither the names of the above-listed copyright holders nor the names
  23  *    of any contributors may be used to endorse or promote products derived
  24  *    from this software without specific prior written permission.
  25  *
  26  * Alternatively, this software may be distributed under the terms of the
  27  * GNU General Public License ("GPL") version 2 as published by the Free
  28  * Software Foundation.
  29  *
  30  * NO WARRANTY
  31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
  34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  41  * POSSIBILITY OF SUCH DAMAGES.
  42  */
  43 
  44 #define __NSACCESS_C__
  45 
  46 #include "acpi.h"
  47 #include "accommon.h"
  48 #include "amlcode.h"
  49 #include "acnamesp.h"
  50 #include "acdispat.h"
  51 
  52 
  53 #define _COMPONENT          ACPI_NAMESPACE
  54         ACPI_MODULE_NAME    ("nsaccess")
  55 
  56 
  57 /*******************************************************************************
  58  *
  59  * FUNCTION:    AcpiNsRootInitialize
  60  *
  61  * PARAMETERS:  None
  62  *
  63  * RETURN:      Status
  64  *
  65  * DESCRIPTION: Allocate and initialize the default root named objects
  66  *
  67  * MUTEX:       Locks namespace for entire execution
  68  *
  69  ******************************************************************************/
  70 
  71 ACPI_STATUS
  72 AcpiNsRootInitialize (
  73     void)
  74 {
  75     ACPI_STATUS                 Status;
  76     const ACPI_PREDEFINED_NAMES *InitVal = NULL;
  77     ACPI_NAMESPACE_NODE         *NewNode;
  78     ACPI_OPERAND_OBJECT         *ObjDesc;
  79     ACPI_STRING                 Val = NULL;
  80 
  81 
  82     ACPI_FUNCTION_TRACE (NsRootInitialize);
  83 
  84 
  85     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
  86     if (ACPI_FAILURE (Status))
  87     {
  88         return_ACPI_STATUS (Status);
  89     }
  90 
  91     /*
  92      * The global root ptr is initially NULL, so a non-NULL value indicates
  93      * that AcpiNsRootInitialize() has already been called; just return.
  94      */
  95     if (AcpiGbl_RootNode)
  96     {
  97         Status = AE_OK;
  98         goto UnlockAndExit;
  99     }
 100 
 101     /*
 102      * Tell the rest of the subsystem that the root is initialized
 103      * (This is OK because the namespace is locked)
 104      */
 105     AcpiGbl_RootNode = &AcpiGbl_RootNodeStruct;
 106 
 107     /* Enter the pre-defined names in the name table */
 108 
 109     ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
 110         "Entering predefined entries into namespace\n"));
 111 
 112     for (InitVal = AcpiGbl_PreDefinedNames; InitVal->Name; InitVal++)
 113     {
 114         /* _OSI is optional for now, will be permanent later */
 115 
 116         if (!ACPI_STRCMP (InitVal->Name, "_OSI") && !AcpiGbl_CreateOsiMethod)
 117         {
 118             continue;
 119         }
 120 
 121         Status = AcpiNsLookup (NULL, InitVal->Name, InitVal->Type,
 122                         ACPI_IMODE_LOAD_PASS2, ACPI_NS_NO_UPSEARCH,
 123                         NULL, &NewNode);
 124 
 125         if (ACPI_FAILURE (Status) || (!NewNode)) /* Must be on same line for code converter */
 126         {
 127             ACPI_EXCEPTION ((AE_INFO, Status,
 128                 "Could not create predefined name %s",
 129                 InitVal->Name));
 130         }
 131 
 132         /*
 133          * Name entered successfully. If entry in PreDefinedNames[] specifies
 134          * an initial value, create the initial value.
 135          */
 136         if (InitVal->Val)
 137         {
 138             Status = AcpiOsPredefinedOverride (InitVal, &Val);
 139             if (ACPI_FAILURE (Status))
 140             {
 141                 ACPI_ERROR ((AE_INFO,
 142                     "Could not override predefined %s",
 143                     InitVal->Name));
 144             }
 145 
 146             if (!Val)
 147             {
 148                 Val = InitVal->Val;
 149             }
 150 
 151             /*
 152              * Entry requests an initial value, allocate a
 153              * descriptor for it.
 154              */
 155             ObjDesc = AcpiUtCreateInternalObject (InitVal->Type);
 156             if (!ObjDesc)
 157             {
 158                 Status = AE_NO_MEMORY;
 159                 goto UnlockAndExit;
 160             }
 161 
 162             /*
 163              * Convert value string from table entry to
 164              * internal representation. Only types actually
 165              * used for initial values are implemented here.
 166              */
 167             switch (InitVal->Type)
 168             {
 169             case ACPI_TYPE_METHOD:
 170                 ObjDesc->Method.ParamCount = (UINT8) ACPI_TO_INTEGER (Val);
 171                 ObjDesc->Common.Flags |= AOPOBJ_DATA_VALID;
 172 
 173 #if defined (ACPI_ASL_COMPILER)
 174 
 175                 /* Save the parameter count for the iASL compiler */
 176 
 177                 NewNode->Value = ObjDesc->Method.ParamCount;
 178 #else
 179                 /* Mark this as a very SPECIAL method */
 180 
 181                 ObjDesc->Method.InfoFlags = ACPI_METHOD_INTERNAL_ONLY;
 182                 ObjDesc->Method.Dispatch.Implementation = AcpiUtOsiImplementation;
 183 #endif
 184                 break;
 185 
 186             case ACPI_TYPE_INTEGER:
 187 
 188                 ObjDesc->Integer.Value = ACPI_TO_INTEGER (Val);
 189                 break;
 190 
 191 
 192             case ACPI_TYPE_STRING:
 193 
 194                 /* Build an object around the static string */
 195 
 196                 ObjDesc->String.Length = (UINT32) ACPI_STRLEN (Val);
 197                 ObjDesc->String.Pointer = Val;
 198                 ObjDesc->Common.Flags |= AOPOBJ_STATIC_POINTER;
 199                 break;
 200 
 201 
 202             case ACPI_TYPE_MUTEX:
 203 
 204                 ObjDesc->Mutex.Node = NewNode;
 205                 ObjDesc->Mutex.SyncLevel = (UINT8) (ACPI_TO_INTEGER (Val) - 1);
 206 
 207                 /* Create a mutex */
 208 
 209                 Status = AcpiOsCreateMutex (&ObjDesc->Mutex.OsMutex);
 210                 if (ACPI_FAILURE (Status))
 211                 {
 212                     AcpiUtRemoveReference (ObjDesc);
 213                     goto UnlockAndExit;
 214                 }
 215 
 216                 /* Special case for ACPI Global Lock */
 217 
 218                 if (ACPI_STRCMP (InitVal->Name, "_GL_") == 0)
 219                 {
 220                     AcpiGbl_GlobalLockMutex = ObjDesc;
 221 
 222                     /* Create additional counting semaphore for global lock */
 223 
 224                     Status = AcpiOsCreateSemaphore (
 225                                 1, 0, &AcpiGbl_GlobalLockSemaphore);
 226                     if (ACPI_FAILURE (Status))
 227                     {
 228                         AcpiUtRemoveReference (ObjDesc);
 229                         goto UnlockAndExit;
 230                     }
 231                 }
 232                 break;
 233 
 234 
 235             default:
 236 
 237                 ACPI_ERROR ((AE_INFO, "Unsupported initial type value 0x%X",
 238                     InitVal->Type));
 239                 AcpiUtRemoveReference (ObjDesc);
 240                 ObjDesc = NULL;
 241                 continue;
 242             }
 243 
 244             /* Store pointer to value descriptor in the Node */
 245 
 246             Status = AcpiNsAttachObject (NewNode, ObjDesc,
 247                         ObjDesc->Common.Type);
 248 
 249             /* Remove local reference to the object */
 250 
 251             AcpiUtRemoveReference (ObjDesc);
 252         }
 253     }
 254 
 255 
 256 UnlockAndExit:
 257     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
 258 
 259     /* Save a handle to "_GPE", it is always present */
 260 
 261     if (ACPI_SUCCESS (Status))
 262     {
 263         Status = AcpiNsGetNode (NULL, "\\_GPE", ACPI_NS_NO_UPSEARCH,
 264                     &AcpiGbl_FadtGpeDevice);
 265     }
 266 
 267     return_ACPI_STATUS (Status);
 268 }
 269 
 270 
 271 /*******************************************************************************
 272  *
 273  * FUNCTION:    AcpiNsLookup
 274  *
 275  * PARAMETERS:  ScopeInfo       - Current scope info block
 276  *              Pathname        - Search pathname, in internal format
 277  *                                (as represented in the AML stream)
 278  *              Type            - Type associated with name
 279  *              InterpreterMode - IMODE_LOAD_PASS2 => add name if not found
 280  *              Flags           - Flags describing the search restrictions
 281  *              WalkState       - Current state of the walk
 282  *              ReturnNode      - Where the Node is placed (if found
 283  *                                or created successfully)
 284  *
 285  * RETURN:      Status
 286  *
 287  * DESCRIPTION: Find or enter the passed name in the name space.
 288  *              Log an error if name not found in Exec mode.
 289  *
 290  * MUTEX:       Assumes namespace is locked.
 291  *
 292  ******************************************************************************/
 293 
 294 ACPI_STATUS
 295 AcpiNsLookup (
 296     ACPI_GENERIC_STATE      *ScopeInfo,
 297     char                    *Pathname,
 298     ACPI_OBJECT_TYPE        Type,
 299     ACPI_INTERPRETER_MODE   InterpreterMode,
 300     UINT32                  Flags,
 301     ACPI_WALK_STATE         *WalkState,
 302     ACPI_NAMESPACE_NODE     **ReturnNode)
 303 {
 304     ACPI_STATUS             Status;
 305     char                    *Path = Pathname;
 306     ACPI_NAMESPACE_NODE     *PrefixNode;
 307     ACPI_NAMESPACE_NODE     *CurrentNode = NULL;
 308     ACPI_NAMESPACE_NODE     *ThisNode = NULL;
 309     UINT32                  NumSegments;
 310     UINT32                  NumCarats;
 311     ACPI_NAME               SimpleName;
 312     ACPI_OBJECT_TYPE        TypeToCheckFor;
 313     ACPI_OBJECT_TYPE        ThisSearchType;
 314     UINT32                  SearchParentFlag = ACPI_NS_SEARCH_PARENT;
 315     UINT32                  LocalFlags;
 316 
 317 
 318     ACPI_FUNCTION_TRACE (NsLookup);
 319 
 320 
 321     if (!ReturnNode)
 322     {
 323         return_ACPI_STATUS (AE_BAD_PARAMETER);
 324     }
 325 
 326     LocalFlags = Flags & ~(ACPI_NS_ERROR_IF_FOUND | ACPI_NS_SEARCH_PARENT);
 327     *ReturnNode = ACPI_ENTRY_NOT_FOUND;
 328     AcpiGbl_NsLookupCount++;
 329 
 330     if (!AcpiGbl_RootNode)
 331     {
 332         return_ACPI_STATUS (AE_NO_NAMESPACE);
 333     }
 334 
 335     /* Get the prefix scope. A null scope means use the root scope */
 336 
 337     if ((!ScopeInfo) ||
 338         (!ScopeInfo->Scope.Node))
 339     {
 340         ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
 341             "Null scope prefix, using root node (%p)\n",
 342             AcpiGbl_RootNode));
 343 
 344         PrefixNode = AcpiGbl_RootNode;
 345     }
 346     else
 347     {
 348         PrefixNode = ScopeInfo->Scope.Node;
 349         if (ACPI_GET_DESCRIPTOR_TYPE (PrefixNode) != ACPI_DESC_TYPE_NAMED)
 350         {
 351             ACPI_ERROR ((AE_INFO, "%p is not a namespace node [%s]",
 352                 PrefixNode, AcpiUtGetDescriptorName (PrefixNode)));
 353             return_ACPI_STATUS (AE_AML_INTERNAL);
 354         }
 355 
 356         if (!(Flags & ACPI_NS_PREFIX_IS_SCOPE))
 357         {
 358             /*
 359              * This node might not be a actual "scope" node (such as a
 360              * Device/Method, etc.)  It could be a Package or other object
 361              * node. Backup up the tree to find the containing scope node.
 362              */
 363             while (!AcpiNsOpensScope (PrefixNode->Type) &&
 364                     PrefixNode->Type != ACPI_TYPE_ANY)
 365             {
 366                 PrefixNode = PrefixNode->Parent;
 367             }
 368         }
 369     }
 370 
 371     /* Save type. TBD: may be no longer necessary */
 372 
 373     TypeToCheckFor = Type;
 374 
 375     /*
 376      * Begin examination of the actual pathname
 377      */
 378     if (!Pathname)
 379     {
 380         /* A Null NamePath is allowed and refers to the root */
 381 
 382         NumSegments = 0;
 383         ThisNode = AcpiGbl_RootNode;
 384         Path = "";
 385 
 386         ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
 387             "Null Pathname (Zero segments), Flags=%X\n", Flags));
 388     }
 389     else
 390     {
 391         /*
 392          * Name pointer is valid (and must be in internal name format)
 393          *
 394          * Check for scope prefixes:
 395          *
 396          * As represented in the AML stream, a namepath consists of an
 397          * optional scope prefix followed by a name segment part.
 398          *
 399          * If present, the scope prefix is either a Root Prefix (in
 400          * which case the name is fully qualified), or one or more
 401          * Parent Prefixes (in which case the name's scope is relative
 402          * to the current scope).
 403          */
 404         if (*Path == (UINT8) AML_ROOT_PREFIX)
 405         {
 406             /* Pathname is fully qualified, start from the root */
 407 
 408             ThisNode = AcpiGbl_RootNode;
 409             SearchParentFlag = ACPI_NS_NO_UPSEARCH;
 410 
 411             /* Point to name segment part */
 412 
 413             Path++;
 414 
 415             ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
 416                 "Path is absolute from root [%p]\n", ThisNode));
 417         }
 418         else
 419         {
 420             /* Pathname is relative to current scope, start there */
 421 
 422             ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
 423                 "Searching relative to prefix scope [%4.4s] (%p)\n",
 424                 AcpiUtGetNodeName (PrefixNode), PrefixNode));
 425 
 426             /*
 427              * Handle multiple Parent Prefixes (carat) by just getting
 428              * the parent node for each prefix instance.
 429              */
 430             ThisNode = PrefixNode;
 431             NumCarats = 0;
 432             while (*Path == (UINT8) AML_PARENT_PREFIX)
 433             {
 434                 /* Name is fully qualified, no search rules apply */
 435 
 436                 SearchParentFlag = ACPI_NS_NO_UPSEARCH;
 437 
 438                 /*
 439                  * Point past this prefix to the name segment
 440                  * part or the next Parent Prefix
 441                  */
 442                 Path++;
 443 
 444                 /* Backup to the parent node */
 445 
 446                 NumCarats++;
 447                 ThisNode = ThisNode->Parent;
 448                 if (!ThisNode)
 449                 {
 450                     /* Current scope has no parent scope */
 451 
 452                     ACPI_ERROR ((AE_INFO,
 453                         "ACPI path has too many parent prefixes (^) "
 454                         "- reached beyond root node"));
 455                     return_ACPI_STATUS (AE_NOT_FOUND);
 456                 }
 457             }
 458 
 459             if (SearchParentFlag == ACPI_NS_NO_UPSEARCH)
 460             {
 461                 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
 462                     "Search scope is [%4.4s], path has %u carat(s)\n",
 463                     AcpiUtGetNodeName (ThisNode), NumCarats));
 464             }
 465         }
 466 
 467         /*
 468          * Determine the number of ACPI name segments in this pathname.
 469          *
 470          * The segment part consists of either:
 471          *  - A Null name segment (0)
 472          *  - A DualNamePrefix followed by two 4-byte name segments
 473          *  - A MultiNamePrefix followed by a byte indicating the
 474          *      number of segments and the segments themselves.
 475          *  - A single 4-byte name segment
 476          *
 477          * Examine the name prefix opcode, if any, to determine the number of
 478          * segments.
 479          */
 480         switch (*Path)
 481         {
 482         case 0:
 483             /*
 484              * Null name after a root or parent prefixes. We already
 485              * have the correct target node and there are no name segments.
 486              */
 487             NumSegments  = 0;
 488             Type = ThisNode->Type;
 489 
 490             ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
 491                 "Prefix-only Pathname (Zero name segments), Flags=%X\n",
 492                 Flags));
 493             break;
 494 
 495         case AML_DUAL_NAME_PREFIX:
 496 
 497             /* More than one NameSeg, search rules do not apply */
 498 
 499             SearchParentFlag = ACPI_NS_NO_UPSEARCH;
 500 
 501             /* Two segments, point to first name segment */
 502 
 503             NumSegments = 2;
 504             Path++;
 505 
 506             ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
 507                 "Dual Pathname (2 segments, Flags=%X)\n", Flags));
 508             break;
 509 
 510         case AML_MULTI_NAME_PREFIX_OP:
 511 
 512             /* More than one NameSeg, search rules do not apply */
 513 
 514             SearchParentFlag = ACPI_NS_NO_UPSEARCH;
 515 
 516             /* Extract segment count, point to first name segment */
 517 
 518             Path++;
 519             NumSegments = (UINT32) (UINT8) *Path;
 520             Path++;
 521 
 522             ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
 523                 "Multi Pathname (%u Segments, Flags=%X)\n",
 524                 NumSegments, Flags));
 525             break;
 526 
 527         default:
 528             /*
 529              * Not a Null name, no Dual or Multi prefix, hence there is
 530              * only one name segment and Pathname is already pointing to it.
 531              */
 532             NumSegments = 1;
 533 
 534             ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
 535                 "Simple Pathname (1 segment, Flags=%X)\n", Flags));
 536             break;
 537         }
 538 
 539         ACPI_DEBUG_EXEC (AcpiNsPrintPathname (NumSegments, Path));
 540     }
 541 
 542 
 543     /*
 544      * Search namespace for each segment of the name. Loop through and
 545      * verify (or add to the namespace) each name segment.
 546      *
 547      * The object type is significant only at the last name
 548      * segment. (We don't care about the types along the path, only
 549      * the type of the final target object.)
 550      */
 551     ThisSearchType = ACPI_TYPE_ANY;
 552     CurrentNode = ThisNode;
 553     while (NumSegments && CurrentNode)
 554     {
 555         NumSegments--;
 556         if (!NumSegments)
 557         {
 558             /* This is the last segment, enable typechecking */
 559 
 560             ThisSearchType = Type;
 561 
 562             /*
 563              * Only allow automatic parent search (search rules) if the caller
 564              * requested it AND we have a single, non-fully-qualified NameSeg
 565              */
 566             if ((SearchParentFlag != ACPI_NS_NO_UPSEARCH) &&
 567                 (Flags & ACPI_NS_SEARCH_PARENT))
 568             {
 569                 LocalFlags |= ACPI_NS_SEARCH_PARENT;
 570             }
 571 
 572             /* Set error flag according to caller */
 573 
 574             if (Flags & ACPI_NS_ERROR_IF_FOUND)
 575             {
 576                 LocalFlags |= ACPI_NS_ERROR_IF_FOUND;
 577             }
 578         }
 579 
 580         /* Extract one ACPI name from the front of the pathname */
 581 
 582         ACPI_MOVE_32_TO_32 (&SimpleName, Path);
 583 
 584         /* Try to find the single (4 character) ACPI name */
 585 
 586         Status = AcpiNsSearchAndEnter (SimpleName, WalkState, CurrentNode,
 587                     InterpreterMode, ThisSearchType, LocalFlags, &ThisNode);
 588         if (ACPI_FAILURE (Status))
 589         {
 590             if (Status == AE_NOT_FOUND)
 591             {
 592                 /* Name not found in ACPI namespace */
 593 
 594                 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
 595                     "Name [%4.4s] not found in scope [%4.4s] %p\n",
 596                     (char *) &SimpleName, (char *) &CurrentNode->Name,
 597                     CurrentNode));
 598             }
 599 
 600             *ReturnNode = ThisNode;
 601             return_ACPI_STATUS (Status);
 602         }
 603 
 604         /* More segments to follow? */
 605 
 606         if (NumSegments > 0)
 607         {
 608             /*
 609              * If we have an alias to an object that opens a scope (such as a
 610              * device or processor), we need to dereference the alias here so
 611              * that we can access any children of the original node (via the
 612              * remaining segments).
 613              */
 614             if (ThisNode->Type == ACPI_TYPE_LOCAL_ALIAS)
 615             {
 616                 if (!ThisNode->Object)
 617                 {
 618                     return_ACPI_STATUS (AE_NOT_EXIST);
 619                 }
 620 
 621                 if (AcpiNsOpensScope (((ACPI_NAMESPACE_NODE *)
 622                         ThisNode->Object)->Type))
 623                 {
 624                     ThisNode = (ACPI_NAMESPACE_NODE *) ThisNode->Object;
 625                 }
 626             }
 627         }
 628 
 629         /* Special handling for the last segment (NumSegments == 0) */
 630 
 631         else
 632         {
 633             /*
 634              * Sanity typecheck of the target object:
 635              *
 636              * If 1) This is the last segment (NumSegments == 0)
 637              *    2) And we are looking for a specific type
 638              *       (Not checking for TYPE_ANY)
 639              *    3) Which is not an alias
 640              *    4) Which is not a local type (TYPE_SCOPE)
 641              *    5) And the type of target object is known (not TYPE_ANY)
 642              *    6) And target object does not match what we are looking for
 643              *
 644              * Then we have a type mismatch. Just warn and ignore it.
 645              */
 646             if ((TypeToCheckFor != ACPI_TYPE_ANY)                   &&
 647                 (TypeToCheckFor != ACPI_TYPE_LOCAL_ALIAS)           &&
 648                 (TypeToCheckFor != ACPI_TYPE_LOCAL_METHOD_ALIAS)    &&
 649                 (TypeToCheckFor != ACPI_TYPE_LOCAL_SCOPE)           &&
 650                 (ThisNode->Type != ACPI_TYPE_ANY)                   &&
 651                 (ThisNode->Type != TypeToCheckFor))
 652             {
 653                 /* Complain about a type mismatch */
 654 
 655                 ACPI_WARNING ((AE_INFO,
 656                     "NsLookup: Type mismatch on %4.4s (%s), searching for (%s)",
 657                     ACPI_CAST_PTR (char, &SimpleName),
 658                     AcpiUtGetTypeName (ThisNode->Type),
 659                     AcpiUtGetTypeName (TypeToCheckFor)));
 660             }
 661 
 662             /*
 663              * If this is the last name segment and we are not looking for a
 664              * specific type, but the type of found object is known, use that
 665              * type to (later) see if it opens a scope.
 666              */
 667             if (Type == ACPI_TYPE_ANY)
 668             {
 669                 Type = ThisNode->Type;
 670             }
 671         }
 672 
 673         /* Point to next name segment and make this node current */
 674 
 675         Path += ACPI_NAME_SIZE;
 676         CurrentNode = ThisNode;
 677     }
 678 
 679     /* Always check if we need to open a new scope */
 680 
 681     if (!(Flags & ACPI_NS_DONT_OPEN_SCOPE) && (WalkState))
 682     {
 683         /*
 684          * If entry is a type which opens a scope, push the new scope on the
 685          * scope stack.
 686          */
 687         if (AcpiNsOpensScope (Type))
 688         {
 689             Status = AcpiDsScopeStackPush (ThisNode, Type, WalkState);
 690             if (ACPI_FAILURE (Status))
 691             {
 692                 return_ACPI_STATUS (Status);
 693             }
 694         }
 695     }
 696 
 697     *ReturnNode = ThisNode;
 698     return_ACPI_STATUS (AE_OK);
 699 }
 700