1 /******************************************************************************
   2  *
   3  * Module Name: nsutils - Utilities for accessing ACPI namespace, accessing
   4  *                        parents and siblings and Scope manipulation
   5  *
   6  *****************************************************************************/
   7 
   8 /*
   9  * Copyright (C) 2000 - 2014, Intel Corp.
  10  * All rights reserved.
  11  *
  12  * Redistribution and use in source and binary forms, with or without
  13  * modification, are permitted provided that the following conditions
  14  * are met:
  15  * 1. Redistributions of source code must retain the above copyright
  16  *    notice, this list of conditions, and the following disclaimer,
  17  *    without modification.
  18  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
  19  *    substantially similar to the "NO WARRANTY" disclaimer below
  20  *    ("Disclaimer") and any redistribution must be conditioned upon
  21  *    including a substantially similar Disclaimer requirement for further
  22  *    binary redistribution.
  23  * 3. Neither the names of the above-listed copyright holders nor the names
  24  *    of any contributors may be used to endorse or promote products derived
  25  *    from this software without specific prior written permission.
  26  *
  27  * Alternatively, this software may be distributed under the terms of the
  28  * GNU General Public License ("GPL") version 2 as published by the Free
  29  * Software Foundation.
  30  *
  31  * NO WARRANTY
  32  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  33  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  34  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
  35  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  36  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  37  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  38  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  39  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  40  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  41  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  42  * POSSIBILITY OF SUCH DAMAGES.
  43  */
  44 
  45 #define __NSUTILS_C__
  46 
  47 #include "acpi.h"
  48 #include "accommon.h"
  49 #include "acnamesp.h"
  50 #include "amlcode.h"
  51 
  52 #define _COMPONENT          ACPI_NAMESPACE
  53         ACPI_MODULE_NAME    ("nsutils")
  54 
  55 /* Local prototypes */
  56 
  57 #ifdef ACPI_OBSOLETE_FUNCTIONS
  58 ACPI_NAME
  59 AcpiNsFindParentName (
  60     ACPI_NAMESPACE_NODE     *NodeToSearch);
  61 #endif
  62 
  63 
  64 /*******************************************************************************
  65  *
  66  * FUNCTION:    AcpiNsPrintNodePathname
  67  *
  68  * PARAMETERS:  Node            - Object
  69  *              Message         - Prefix message
  70  *
  71  * DESCRIPTION: Print an object's full namespace pathname
  72  *              Manages allocation/freeing of a pathname buffer
  73  *
  74  ******************************************************************************/
  75 
  76 void
  77 AcpiNsPrintNodePathname (
  78     ACPI_NAMESPACE_NODE     *Node,
  79     const char              *Message)
  80 {
  81     ACPI_BUFFER             Buffer;
  82     ACPI_STATUS             Status;
  83 
  84 
  85     if (!Node)
  86     {
  87         AcpiOsPrintf ("[NULL NAME]");
  88         return;
  89     }
  90 
  91     /* Convert handle to full pathname and print it (with supplied message) */
  92 
  93     Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
  94 
  95     Status = AcpiNsHandleToPathname (Node, &Buffer);
  96     if (ACPI_SUCCESS (Status))
  97     {
  98         if (Message)
  99         {
 100             AcpiOsPrintf ("%s ", Message);
 101         }
 102 
 103         AcpiOsPrintf ("[%s] (Node %p)", (char *) Buffer.Pointer, Node);
 104         ACPI_FREE (Buffer.Pointer);
 105     }
 106 }
 107 
 108 
 109 /*******************************************************************************
 110  *
 111  * FUNCTION:    AcpiNsGetType
 112  *
 113  * PARAMETERS:  Node        - Parent Node to be examined
 114  *
 115  * RETURN:      Type field from Node whose handle is passed
 116  *
 117  * DESCRIPTION: Return the type of a Namespace node
 118  *
 119  ******************************************************************************/
 120 
 121 ACPI_OBJECT_TYPE
 122 AcpiNsGetType (
 123     ACPI_NAMESPACE_NODE     *Node)
 124 {
 125     ACPI_FUNCTION_TRACE (NsGetType);
 126 
 127 
 128     if (!Node)
 129     {
 130         ACPI_WARNING ((AE_INFO, "Null Node parameter"));
 131         return_UINT8 (ACPI_TYPE_ANY);
 132     }
 133 
 134     return_UINT8 (Node->Type);
 135 }
 136 
 137 
 138 /*******************************************************************************
 139  *
 140  * FUNCTION:    AcpiNsLocal
 141  *
 142  * PARAMETERS:  Type        - A namespace object type
 143  *
 144  * RETURN:      LOCAL if names must be found locally in objects of the
 145  *              passed type, 0 if enclosing scopes should be searched
 146  *
 147  * DESCRIPTION: Returns scope rule for the given object type.
 148  *
 149  ******************************************************************************/
 150 
 151 UINT32
 152 AcpiNsLocal (
 153     ACPI_OBJECT_TYPE        Type)
 154 {
 155     ACPI_FUNCTION_TRACE (NsLocal);
 156 
 157 
 158     if (!AcpiUtValidObjectType (Type))
 159     {
 160         /* Type code out of range  */
 161 
 162         ACPI_WARNING ((AE_INFO, "Invalid Object Type 0x%X", Type));
 163         return_UINT32 (ACPI_NS_NORMAL);
 164     }
 165 
 166     return_UINT32 (AcpiGbl_NsProperties[Type] & ACPI_NS_LOCAL);
 167 }
 168 
 169 
 170 /*******************************************************************************
 171  *
 172  * FUNCTION:    AcpiNsGetInternalNameLength
 173  *
 174  * PARAMETERS:  Info            - Info struct initialized with the
 175  *                                external name pointer.
 176  *
 177  * RETURN:      None
 178  *
 179  * DESCRIPTION: Calculate the length of the internal (AML) namestring
 180  *              corresponding to the external (ASL) namestring.
 181  *
 182  ******************************************************************************/
 183 
 184 void
 185 AcpiNsGetInternalNameLength (
 186     ACPI_NAMESTRING_INFO    *Info)
 187 {
 188     const char              *NextExternalChar;
 189     UINT32                  i;
 190 
 191 
 192     ACPI_FUNCTION_ENTRY ();
 193 
 194 
 195     NextExternalChar = Info->ExternalName;
 196     Info->NumCarats = 0;
 197     Info->NumSegments = 0;
 198     Info->FullyQualified = FALSE;
 199 
 200     /*
 201      * For the internal name, the required length is 4 bytes per segment, plus
 202      * 1 each for RootPrefix, MultiNamePrefixOp, segment count, trailing null
 203      * (which is not really needed, but no there's harm in putting it there)
 204      *
 205      * strlen() + 1 covers the first NameSeg, which has no path separator
 206      */
 207     if (ACPI_IS_ROOT_PREFIX (*NextExternalChar))
 208     {
 209         Info->FullyQualified = TRUE;
 210         NextExternalChar++;
 211 
 212         /* Skip redundant RootPrefix, like \\_SB.PCI0.SBRG.EC0 */
 213 
 214         while (ACPI_IS_ROOT_PREFIX (*NextExternalChar))
 215         {
 216             NextExternalChar++;
 217         }
 218     }
 219     else
 220     {
 221         /* Handle Carat prefixes */
 222 
 223         while (ACPI_IS_PARENT_PREFIX (*NextExternalChar))
 224         {
 225             Info->NumCarats++;
 226             NextExternalChar++;
 227         }
 228     }
 229 
 230     /*
 231      * Determine the number of ACPI name "segments" by counting the number of
 232      * path separators within the string. Start with one segment since the
 233      * segment count is [(# separators) + 1], and zero separators is ok.
 234      */
 235     if (*NextExternalChar)
 236     {
 237         Info->NumSegments = 1;
 238         for (i = 0; NextExternalChar[i]; i++)
 239         {
 240             if (ACPI_IS_PATH_SEPARATOR (NextExternalChar[i]))
 241             {
 242                 Info->NumSegments++;
 243             }
 244         }
 245     }
 246 
 247     Info->Length = (ACPI_NAME_SIZE * Info->NumSegments) +
 248                     4 + Info->NumCarats;
 249 
 250     Info->NextExternalChar = NextExternalChar;
 251 }
 252 
 253 
 254 /*******************************************************************************
 255  *
 256  * FUNCTION:    AcpiNsBuildInternalName
 257  *
 258  * PARAMETERS:  Info            - Info struct fully initialized
 259  *
 260  * RETURN:      Status
 261  *
 262  * DESCRIPTION: Construct the internal (AML) namestring
 263  *              corresponding to the external (ASL) namestring.
 264  *
 265  ******************************************************************************/
 266 
 267 ACPI_STATUS
 268 AcpiNsBuildInternalName (
 269     ACPI_NAMESTRING_INFO    *Info)
 270 {
 271     UINT32                  NumSegments = Info->NumSegments;
 272     char                    *InternalName = Info->InternalName;
 273     const char              *ExternalName = Info->NextExternalChar;
 274     char                    *Result = NULL;
 275     UINT32                  i;
 276 
 277 
 278     ACPI_FUNCTION_TRACE (NsBuildInternalName);
 279 
 280 
 281     /* Setup the correct prefixes, counts, and pointers */
 282 
 283     if (Info->FullyQualified)
 284     {
 285         InternalName[0] = AML_ROOT_PREFIX;
 286 
 287         if (NumSegments <= 1)
 288         {
 289             Result = &InternalName[1];
 290         }
 291         else if (NumSegments == 2)
 292         {
 293             InternalName[1] = AML_DUAL_NAME_PREFIX;
 294             Result = &InternalName[2];
 295         }
 296         else
 297         {
 298             InternalName[1] = AML_MULTI_NAME_PREFIX_OP;
 299             InternalName[2] = (char) NumSegments;
 300             Result = &InternalName[3];
 301         }
 302     }
 303     else
 304     {
 305         /*
 306          * Not fully qualified.
 307          * Handle Carats first, then append the name segments
 308          */
 309         i = 0;
 310         if (Info->NumCarats)
 311         {
 312             for (i = 0; i < Info->NumCarats; i++)
 313             {
 314                 InternalName[i] = AML_PARENT_PREFIX;
 315             }
 316         }
 317 
 318         if (NumSegments <= 1)
 319         {
 320             Result = &InternalName[i];
 321         }
 322         else if (NumSegments == 2)
 323         {
 324             InternalName[i] = AML_DUAL_NAME_PREFIX;
 325             Result = &InternalName[(ACPI_SIZE) i+1];
 326         }
 327         else
 328         {
 329             InternalName[i] = AML_MULTI_NAME_PREFIX_OP;
 330             InternalName[(ACPI_SIZE) i+1] = (char) NumSegments;
 331             Result = &InternalName[(ACPI_SIZE) i+2];
 332         }
 333     }
 334 
 335     /* Build the name (minus path separators) */
 336 
 337     for (; NumSegments; NumSegments--)
 338     {
 339         for (i = 0; i < ACPI_NAME_SIZE; i++)
 340         {
 341             if (ACPI_IS_PATH_SEPARATOR (*ExternalName) ||
 342                (*ExternalName == 0))
 343             {
 344                 /* Pad the segment with underscore(s) if segment is short */
 345 
 346                 Result[i] = '_';
 347             }
 348             else
 349             {
 350                 /* Convert the character to uppercase and save it */
 351 
 352                 Result[i] = (char) ACPI_TOUPPER ((int) *ExternalName);
 353                 ExternalName++;
 354             }
 355         }
 356 
 357         /* Now we must have a path separator, or the pathname is bad */
 358 
 359         if (!ACPI_IS_PATH_SEPARATOR (*ExternalName) &&
 360             (*ExternalName != 0))
 361         {
 362             return_ACPI_STATUS (AE_BAD_PATHNAME);
 363         }
 364 
 365         /* Move on the next segment */
 366 
 367         ExternalName++;
 368         Result += ACPI_NAME_SIZE;
 369     }
 370 
 371     /* Terminate the string */
 372 
 373     *Result = 0;
 374 
 375     if (Info->FullyQualified)
 376     {
 377         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Returning [%p] (abs) \"\\%s\"\n",
 378             InternalName, InternalName));
 379     }
 380     else
 381     {
 382         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Returning [%p] (rel) \"%s\"\n",
 383             InternalName, InternalName));
 384     }
 385 
 386     return_ACPI_STATUS (AE_OK);
 387 }
 388 
 389 
 390 /*******************************************************************************
 391  *
 392  * FUNCTION:    AcpiNsInternalizeName
 393  *
 394  * PARAMETERS:  *ExternalName           - External representation of name
 395  *              **Converted Name        - Where to return the resulting
 396  *                                        internal represention of the name
 397  *
 398  * RETURN:      Status
 399  *
 400  * DESCRIPTION: Convert an external representation (e.g. "\_PR_.CPU0")
 401  *              to internal form (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30)
 402  *
 403  *******************************************************************************/
 404 
 405 ACPI_STATUS
 406 AcpiNsInternalizeName (
 407     const char              *ExternalName,
 408     char                    **ConvertedName)
 409 {
 410     char                    *InternalName;
 411     ACPI_NAMESTRING_INFO    Info;
 412     ACPI_STATUS             Status;
 413 
 414 
 415     ACPI_FUNCTION_TRACE (NsInternalizeName);
 416 
 417 
 418     if ((!ExternalName)      ||
 419         (*ExternalName == 0) ||
 420         (!ConvertedName))
 421     {
 422         return_ACPI_STATUS (AE_BAD_PARAMETER);
 423     }
 424 
 425     /* Get the length of the new internal name */
 426 
 427     Info.ExternalName = ExternalName;
 428     AcpiNsGetInternalNameLength (&Info);
 429 
 430     /* We need a segment to store the internal  name */
 431 
 432     InternalName = ACPI_ALLOCATE_ZEROED (Info.Length);
 433     if (!InternalName)
 434     {
 435         return_ACPI_STATUS (AE_NO_MEMORY);
 436     }
 437 
 438     /* Build the name */
 439 
 440     Info.InternalName = InternalName;
 441     Status = AcpiNsBuildInternalName (&Info);
 442     if (ACPI_FAILURE (Status))
 443     {
 444         ACPI_FREE (InternalName);
 445         return_ACPI_STATUS (Status);
 446     }
 447 
 448     *ConvertedName = InternalName;
 449     return_ACPI_STATUS (AE_OK);
 450 }
 451 
 452 
 453 /*******************************************************************************
 454  *
 455  * FUNCTION:    AcpiNsExternalizeName
 456  *
 457  * PARAMETERS:  InternalNameLength  - Lenth of the internal name below
 458  *              InternalName        - Internal representation of name
 459  *              ConvertedNameLength - Where the length is returned
 460  *              ConvertedName       - Where the resulting external name
 461  *                                    is returned
 462  *
 463  * RETURN:      Status
 464  *
 465  * DESCRIPTION: Convert internal name (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30)
 466  *              to its external (printable) form (e.g. "\_PR_.CPU0")
 467  *
 468  ******************************************************************************/
 469 
 470 ACPI_STATUS
 471 AcpiNsExternalizeName (
 472     UINT32                  InternalNameLength,
 473     const char              *InternalName,
 474     UINT32                  *ConvertedNameLength,
 475     char                    **ConvertedName)
 476 {
 477     UINT32                  NamesIndex = 0;
 478     UINT32                  NumSegments = 0;
 479     UINT32                  RequiredLength;
 480     UINT32                  PrefixLength = 0;
 481     UINT32                  i = 0;
 482     UINT32                  j = 0;
 483 
 484 
 485     ACPI_FUNCTION_TRACE (NsExternalizeName);
 486 
 487 
 488     if (!InternalNameLength     ||
 489         !InternalName           ||
 490         !ConvertedName)
 491     {
 492         return_ACPI_STATUS (AE_BAD_PARAMETER);
 493     }
 494 
 495     /* Check for a prefix (one '\' | one or more '^') */
 496 
 497     switch (InternalName[0])
 498     {
 499     case AML_ROOT_PREFIX:
 500 
 501         PrefixLength = 1;
 502         break;
 503 
 504     case AML_PARENT_PREFIX:
 505 
 506         for (i = 0; i < InternalNameLength; i++)
 507         {
 508             if (ACPI_IS_PARENT_PREFIX (InternalName[i]))
 509             {
 510                 PrefixLength = i + 1;
 511             }
 512             else
 513             {
 514                 break;
 515             }
 516         }
 517 
 518         if (i == InternalNameLength)
 519         {
 520             PrefixLength = i;
 521         }
 522 
 523         break;
 524 
 525     default:
 526 
 527         break;
 528     }
 529 
 530     /*
 531      * Check for object names. Note that there could be 0-255 of these
 532      * 4-byte elements.
 533      */
 534     if (PrefixLength < InternalNameLength)
 535     {
 536         switch (InternalName[PrefixLength])
 537         {
 538         case AML_MULTI_NAME_PREFIX_OP:
 539 
 540             /* <count> 4-byte names */
 541 
 542             NamesIndex = PrefixLength + 2;
 543             NumSegments = (UINT8)
 544                 InternalName[(ACPI_SIZE) PrefixLength + 1];
 545             break;
 546 
 547         case AML_DUAL_NAME_PREFIX:
 548 
 549             /* Two 4-byte names */
 550 
 551             NamesIndex = PrefixLength + 1;
 552             NumSegments = 2;
 553             break;
 554 
 555         case 0:
 556 
 557             /* NullName */
 558 
 559             NamesIndex = 0;
 560             NumSegments = 0;
 561             break;
 562 
 563         default:
 564 
 565             /* one 4-byte name */
 566 
 567             NamesIndex = PrefixLength;
 568             NumSegments = 1;
 569             break;
 570         }
 571     }
 572 
 573     /*
 574      * Calculate the length of ConvertedName, which equals the length
 575      * of the prefix, length of all object names, length of any required
 576      * punctuation ('.') between object names, plus the NULL terminator.
 577      */
 578     RequiredLength = PrefixLength + (4 * NumSegments) +
 579                         ((NumSegments > 0) ? (NumSegments - 1) : 0) + 1;
 580 
 581     /*
 582      * Check to see if we're still in bounds. If not, there's a problem
 583      * with InternalName (invalid format).
 584      */
 585     if (RequiredLength > InternalNameLength)
 586     {
 587         ACPI_ERROR ((AE_INFO, "Invalid internal name"));
 588         return_ACPI_STATUS (AE_BAD_PATHNAME);
 589     }
 590 
 591     /* Build the ConvertedName */
 592 
 593     *ConvertedName = ACPI_ALLOCATE_ZEROED (RequiredLength);
 594     if (!(*ConvertedName))
 595     {
 596         return_ACPI_STATUS (AE_NO_MEMORY);
 597     }
 598 
 599     j = 0;
 600 
 601     for (i = 0; i < PrefixLength; i++)
 602     {
 603         (*ConvertedName)[j++] = InternalName[i];
 604     }
 605 
 606     if (NumSegments > 0)
 607     {
 608         for (i = 0; i < NumSegments; i++)
 609         {
 610             if (i > 0)
 611             {
 612                 (*ConvertedName)[j++] = '.';
 613             }
 614 
 615             /* Copy and validate the 4-char name segment */
 616 
 617             ACPI_MOVE_NAME (&(*ConvertedName)[j], &InternalName[NamesIndex]);
 618             AcpiUtRepairName (&(*ConvertedName)[j]);
 619 
 620             j += ACPI_NAME_SIZE;
 621             NamesIndex += ACPI_NAME_SIZE;
 622         }
 623     }
 624 
 625     if (ConvertedNameLength)
 626     {
 627         *ConvertedNameLength = (UINT32) RequiredLength;
 628     }
 629 
 630     return_ACPI_STATUS (AE_OK);
 631 }
 632 
 633 
 634 /*******************************************************************************
 635  *
 636  * FUNCTION:    AcpiNsValidateHandle
 637  *
 638  * PARAMETERS:  Handle          - Handle to be validated and typecast to a
 639  *                                namespace node.
 640  *
 641  * RETURN:      A pointer to a namespace node
 642  *
 643  * DESCRIPTION: Convert a namespace handle to a namespace node. Handles special
 644  *              cases for the root node.
 645  *
 646  * NOTE: Real integer handles would allow for more verification
 647  *       and keep all pointers within this subsystem - however this introduces
 648  *       more overhead and has not been necessary to this point. Drivers
 649  *       holding handles are typically notified before a node becomes invalid
 650  *       due to a table unload.
 651  *
 652  ******************************************************************************/
 653 
 654 ACPI_NAMESPACE_NODE *
 655 AcpiNsValidateHandle (
 656     ACPI_HANDLE             Handle)
 657 {
 658 
 659     ACPI_FUNCTION_ENTRY ();
 660 
 661 
 662     /* Parameter validation */
 663 
 664     if ((!Handle) || (Handle == ACPI_ROOT_OBJECT))
 665     {
 666         return (AcpiGbl_RootNode);
 667     }
 668 
 669     /* We can at least attempt to verify the handle */
 670 
 671     if (ACPI_GET_DESCRIPTOR_TYPE (Handle) != ACPI_DESC_TYPE_NAMED)
 672     {
 673         return (NULL);
 674     }
 675 
 676     return (ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Handle));
 677 }
 678 
 679 
 680 /*******************************************************************************
 681  *
 682  * FUNCTION:    AcpiNsTerminate
 683  *
 684  * PARAMETERS:  none
 685  *
 686  * RETURN:      none
 687  *
 688  * DESCRIPTION: free memory allocated for namespace and ACPI table storage.
 689  *
 690  ******************************************************************************/
 691 
 692 void
 693 AcpiNsTerminate (
 694     void)
 695 {
 696     ACPI_STATUS             Status;
 697 
 698 
 699     ACPI_FUNCTION_TRACE (NsTerminate);
 700 
 701 
 702     /*
 703      * Free the entire namespace -- all nodes and all objects
 704      * attached to the nodes
 705      */
 706     AcpiNsDeleteNamespaceSubtree (AcpiGbl_RootNode);
 707 
 708     /* Delete any objects attached to the root node */
 709 
 710     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
 711     if (ACPI_FAILURE (Status))
 712     {
 713         return_VOID;
 714     }
 715 
 716     AcpiNsDeleteNode (AcpiGbl_RootNode);
 717     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
 718 
 719     ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Namespace freed\n"));
 720     return_VOID;
 721 }
 722 
 723 
 724 /*******************************************************************************
 725  *
 726  * FUNCTION:    AcpiNsOpensScope
 727  *
 728  * PARAMETERS:  Type        - A valid namespace type
 729  *
 730  * RETURN:      NEWSCOPE if the passed type "opens a name scope" according
 731  *              to the ACPI specification, else 0
 732  *
 733  ******************************************************************************/
 734 
 735 UINT32
 736 AcpiNsOpensScope (
 737     ACPI_OBJECT_TYPE        Type)
 738 {
 739     ACPI_FUNCTION_ENTRY ();
 740 
 741 
 742     if (Type > ACPI_TYPE_LOCAL_MAX)
 743     {
 744         /* type code out of range  */
 745 
 746         ACPI_WARNING ((AE_INFO, "Invalid Object Type 0x%X", Type));
 747         return (ACPI_NS_NORMAL);
 748     }
 749 
 750     return (((UINT32) AcpiGbl_NsProperties[Type]) & ACPI_NS_NEWSCOPE);
 751 }
 752 
 753 
 754 /*******************************************************************************
 755  *
 756  * FUNCTION:    AcpiNsGetNode
 757  *
 758  * PARAMETERS:  *Pathname   - Name to be found, in external (ASL) format. The
 759  *                            \ (backslash) and ^ (carat) prefixes, and the
 760  *                            . (period) to separate segments are supported.
 761  *              PrefixNode   - Root of subtree to be searched, or NS_ALL for the
 762  *                            root of the name space. If Name is fully
 763  *                            qualified (first INT8 is '\'), the passed value
 764  *                            of Scope will not be accessed.
 765  *              Flags       - Used to indicate whether to perform upsearch or
 766  *                            not.
 767  *              ReturnNode  - Where the Node is returned
 768  *
 769  * DESCRIPTION: Look up a name relative to a given scope and return the
 770  *              corresponding Node. NOTE: Scope can be null.
 771  *
 772  * MUTEX:       Locks namespace
 773  *
 774  ******************************************************************************/
 775 
 776 ACPI_STATUS
 777 AcpiNsGetNode (
 778     ACPI_NAMESPACE_NODE     *PrefixNode,
 779     const char              *Pathname,
 780     UINT32                  Flags,
 781     ACPI_NAMESPACE_NODE     **ReturnNode)
 782 {
 783     ACPI_GENERIC_STATE      ScopeInfo;
 784     ACPI_STATUS             Status;
 785     char                    *InternalPath;
 786 
 787 
 788     ACPI_FUNCTION_TRACE_PTR (NsGetNode, ACPI_CAST_PTR (char, Pathname));
 789 
 790 
 791     /* Simplest case is a null pathname */
 792 
 793     if (!Pathname)
 794     {
 795         *ReturnNode = PrefixNode;
 796         if (!PrefixNode)
 797         {
 798             *ReturnNode = AcpiGbl_RootNode;
 799         }
 800         return_ACPI_STATUS (AE_OK);
 801     }
 802 
 803     /* Quick check for a reference to the root */
 804 
 805     if (ACPI_IS_ROOT_PREFIX (Pathname[0]) && (!Pathname[1]))
 806     {
 807         *ReturnNode = AcpiGbl_RootNode;
 808         return_ACPI_STATUS (AE_OK);
 809     }
 810 
 811     /* Convert path to internal representation */
 812 
 813     Status = AcpiNsInternalizeName (Pathname, &InternalPath);
 814     if (ACPI_FAILURE (Status))
 815     {
 816         return_ACPI_STATUS (Status);
 817     }
 818 
 819     /* Must lock namespace during lookup */
 820 
 821     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
 822     if (ACPI_FAILURE (Status))
 823     {
 824         goto Cleanup;
 825     }
 826 
 827     /* Setup lookup scope (search starting point) */
 828 
 829     ScopeInfo.Scope.Node = PrefixNode;
 830 
 831     /* Lookup the name in the namespace */
 832 
 833     Status = AcpiNsLookup (&ScopeInfo, InternalPath, ACPI_TYPE_ANY,
 834                 ACPI_IMODE_EXECUTE, (Flags | ACPI_NS_DONT_OPEN_SCOPE),
 835                 NULL, ReturnNode);
 836     if (ACPI_FAILURE (Status))
 837     {
 838         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%s, %s\n",
 839                 Pathname, AcpiFormatException (Status)));
 840     }
 841 
 842     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
 843 
 844 Cleanup:
 845     ACPI_FREE (InternalPath);
 846     return_ACPI_STATUS (Status);
 847 }