Home | History | Annotate | Line # | Download | only in namespace
nsutils.c revision 1.1.1.3
      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 - 2013, 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 }
    848