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