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