Subversion Repositories Kolibri OS

Rev

Rev 1498 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /******************************************************************************
  2.  *
  3.  * Module Name: nsutils - Utilities for accessing ACPI namespace, accessing
  4.  *                        parents and siblings and Scope manipulation
  5.  *
  6.  *****************************************************************************/
  7.  
  8. /******************************************************************************
  9.  *
  10.  * 1. Copyright Notice
  11.  *
  12.  * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
  13.  * All rights reserved.
  14.  *
  15.  * 2. License
  16.  *
  17.  * 2.1. This is your license from Intel Corp. under its intellectual property
  18.  * rights.  You may have additional license terms from the party that provided
  19.  * you this software, covering your right to use that party's intellectual
  20.  * property rights.
  21.  *
  22.  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
  23.  * copy of the source code appearing in this file ("Covered Code") an
  24.  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
  25.  * base code distributed originally by Intel ("Original Intel Code") to copy,
  26.  * make derivatives, distribute, use and display any portion of the Covered
  27.  * Code in any form, with the right to sublicense such rights; and
  28.  *
  29.  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
  30.  * license (with the right to sublicense), under only those claims of Intel
  31.  * patents that are infringed by the Original Intel Code, to make, use, sell,
  32.  * offer to sell, and import the Covered Code and derivative works thereof
  33.  * solely to the minimum extent necessary to exercise the above copyright
  34.  * license, and in no event shall the patent license extend to any additions
  35.  * to or modifications of the Original Intel Code.  No other license or right
  36.  * is granted directly or by implication, estoppel or otherwise;
  37.  *
  38.  * The above copyright and patent license is granted only if the following
  39.  * conditions are met:
  40.  *
  41.  * 3. Conditions
  42.  *
  43.  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
  44.  * Redistribution of source code of any substantial portion of the Covered
  45.  * Code or modification with rights to further distribute source must include
  46.  * the above Copyright Notice, the above License, this list of Conditions,
  47.  * and the following Disclaimer and Export Compliance provision.  In addition,
  48.  * Licensee must cause all Covered Code to which Licensee contributes to
  49.  * contain a file documenting the changes Licensee made to create that Covered
  50.  * Code and the date of any change.  Licensee must include in that file the
  51.  * documentation of any changes made by any predecessor Licensee.  Licensee
  52.  * must include a prominent statement that the modification is derived,
  53.  * directly or indirectly, from Original Intel Code.
  54.  *
  55.  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
  56.  * Redistribution of source code of any substantial portion of the Covered
  57.  * Code or modification without rights to further distribute source must
  58.  * include the following Disclaimer and Export Compliance provision in the
  59.  * documentation and/or other materials provided with distribution.  In
  60.  * addition, Licensee may not authorize further sublicense of source of any
  61.  * portion of the Covered Code, and must include terms to the effect that the
  62.  * license from Licensee to its licensee is limited to the intellectual
  63.  * property embodied in the software Licensee provides to its licensee, and
  64.  * not to intellectual property embodied in modifications its licensee may
  65.  * make.
  66.  *
  67.  * 3.3. Redistribution of Executable. Redistribution in executable form of any
  68.  * substantial portion of the Covered Code or modification must reproduce the
  69.  * above Copyright Notice, and the following Disclaimer and Export Compliance
  70.  * provision in the documentation and/or other materials provided with the
  71.  * distribution.
  72.  *
  73.  * 3.4. Intel retains all right, title, and interest in and to the Original
  74.  * Intel Code.
  75.  *
  76.  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
  77.  * Intel shall be used in advertising or otherwise to promote the sale, use or
  78.  * other dealings in products derived from or relating to the Covered Code
  79.  * without prior written authorization from Intel.
  80.  *
  81.  * 4. Disclaimer and Export Compliance
  82.  *
  83.  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
  84.  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
  85.  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
  86.  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
  87.  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
  88.  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
  89.  * PARTICULAR PURPOSE.
  90.  *
  91.  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
  92.  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
  93.  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
  94.  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
  95.  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
  96.  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
  97.  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
  98.  * LIMITED REMEDY.
  99.  *
  100.  * 4.3. Licensee shall not export, either directly or indirectly, any of this
  101.  * software or system incorporating such software without first obtaining any
  102.  * required license or other approval from the U. S. Department of Commerce or
  103.  * any other agency or department of the United States Government.  In the
  104.  * event Licensee exports any such software from the United States or
  105.  * re-exports any such software from a foreign destination, Licensee shall
  106.  * ensure that the distribution and export/re-export of the software is in
  107.  * compliance with all laws, regulations, orders, or other restrictions of the
  108.  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
  109.  * any of its subsidiaries will export/re-export any technical data, process,
  110.  * software, or service, directly or indirectly, to any country for which the
  111.  * United States government or any agency thereof requires an export license,
  112.  * other governmental approval, or letter of assurance, without first obtaining
  113.  * such license, approval or letter.
  114.  *
  115.  *****************************************************************************/
  116.  
  117. #define __NSUTILS_C__
  118.  
  119. #include "acpi.h"
  120. #include "accommon.h"
  121. #include "acnamesp.h"
  122. #include "amlcode.h"
  123.  
  124. #define _COMPONENT          ACPI_NAMESPACE
  125.         ACPI_MODULE_NAME    ("nsutils")
  126.  
  127. /* Local prototypes */
  128.  
  129. static BOOLEAN
  130. AcpiNsValidPathSeparator (
  131.     char                    Sep);
  132.  
  133. #ifdef ACPI_OBSOLETE_FUNCTIONS
  134. ACPI_NAME
  135. AcpiNsFindParentName (
  136.     ACPI_NAMESPACE_NODE     *NodeToSearch);
  137. #endif
  138.  
  139.  
  140. /*******************************************************************************
  141.  *
  142.  * FUNCTION:    AcpiNsPrintNodePathname
  143.  *
  144.  * PARAMETERS:  Node            - Object
  145.  *              Message         - Prefix message
  146.  *
  147.  * DESCRIPTION: Print an object's full namespace pathname
  148.  *              Manages allocation/freeing of a pathname buffer
  149.  *
  150.  ******************************************************************************/
  151.  
  152. void
  153. AcpiNsPrintNodePathname (
  154.     ACPI_NAMESPACE_NODE     *Node,
  155.     const char              *Message)
  156. {
  157.     ACPI_BUFFER             Buffer;
  158.     ACPI_STATUS             Status;
  159.  
  160.  
  161.     if (!Node)
  162.     {
  163.         AcpiOsPrintf ("[NULL NAME]");
  164.         return;
  165.     }
  166.  
  167.     /* Convert handle to full pathname and print it (with supplied message) */
  168.  
  169.     Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
  170.  
  171.     Status = AcpiNsHandleToPathname (Node, &Buffer);
  172.     if (ACPI_SUCCESS (Status))
  173.     {
  174.         if (Message)
  175.         {
  176.             AcpiOsPrintf ("%s ", Message);
  177.         }
  178.  
  179.         AcpiOsPrintf ("[%s] (Node %p)", (char *) Buffer.Pointer, Node);
  180.         ACPI_FREE (Buffer.Pointer);
  181.     }
  182. }
  183.  
  184.  
  185. /*******************************************************************************
  186.  *
  187.  * FUNCTION:    AcpiNsValidRootPrefix
  188.  *
  189.  * PARAMETERS:  Prefix          - Character to be checked
  190.  *
  191.  * RETURN:      TRUE if a valid prefix
  192.  *
  193.  * DESCRIPTION: Check if a character is a valid ACPI Root prefix
  194.  *
  195.  ******************************************************************************/
  196.  
  197. BOOLEAN
  198. AcpiNsValidRootPrefix (
  199.     char                    Prefix)
  200. {
  201.  
  202.     return ((BOOLEAN) (Prefix == '\\'));
  203. }
  204.  
  205.  
  206. /*******************************************************************************
  207.  *
  208.  * FUNCTION:    AcpiNsValidPathSeparator
  209.  *
  210.  * PARAMETERS:  Sep         - Character to be checked
  211.  *
  212.  * RETURN:      TRUE if a valid path separator
  213.  *
  214.  * DESCRIPTION: Check if a character is a valid ACPI path separator
  215.  *
  216.  ******************************************************************************/
  217.  
  218. static BOOLEAN
  219. AcpiNsValidPathSeparator (
  220.     char                    Sep)
  221. {
  222.  
  223.     return ((BOOLEAN) (Sep == '.'));
  224. }
  225.  
  226.  
  227. /*******************************************************************************
  228.  *
  229.  * FUNCTION:    AcpiNsGetType
  230.  *
  231.  * PARAMETERS:  Node        - Parent Node to be examined
  232.  *
  233.  * RETURN:      Type field from Node whose handle is passed
  234.  *
  235.  * DESCRIPTION: Return the type of a Namespace node
  236.  *
  237.  ******************************************************************************/
  238.  
  239. ACPI_OBJECT_TYPE
  240. AcpiNsGetType (
  241.     ACPI_NAMESPACE_NODE     *Node)
  242. {
  243.     ACPI_FUNCTION_TRACE (NsGetType);
  244.  
  245.  
  246.     if (!Node)
  247.     {
  248.         ACPI_WARNING ((AE_INFO, "Null Node parameter"));
  249.         return_UINT32 (ACPI_TYPE_ANY);
  250.     }
  251.  
  252.     return_UINT32 ((ACPI_OBJECT_TYPE) Node->Type);
  253. }
  254.  
  255.  
  256. /*******************************************************************************
  257.  *
  258.  * FUNCTION:    AcpiNsLocal
  259.  *
  260.  * PARAMETERS:  Type        - A namespace object type
  261.  *
  262.  * RETURN:      LOCAL if names must be found locally in objects of the
  263.  *              passed type, 0 if enclosing scopes should be searched
  264.  *
  265.  * DESCRIPTION: Returns scope rule for the given object type.
  266.  *
  267.  ******************************************************************************/
  268.  
  269. UINT32
  270. AcpiNsLocal (
  271.     ACPI_OBJECT_TYPE        Type)
  272. {
  273.     ACPI_FUNCTION_TRACE (NsLocal);
  274.  
  275.  
  276.     if (!AcpiUtValidObjectType (Type))
  277.     {
  278.         /* Type code out of range  */
  279.  
  280.         ACPI_WARNING ((AE_INFO, "Invalid Object Type 0x%X", Type));
  281.         return_UINT32 (ACPI_NS_NORMAL);
  282.     }
  283.  
  284.     return_UINT32 ((UINT32) AcpiGbl_NsProperties[Type] & ACPI_NS_LOCAL);
  285. }
  286.  
  287.  
  288. /*******************************************************************************
  289.  *
  290.  * FUNCTION:    AcpiNsGetInternalNameLength
  291.  *
  292.  * PARAMETERS:  Info            - Info struct initialized with the
  293.  *                                external name pointer.
  294.  *
  295.  * RETURN:      None
  296.  *
  297.  * DESCRIPTION: Calculate the length of the internal (AML) namestring
  298.  *              corresponding to the external (ASL) namestring.
  299.  *
  300.  ******************************************************************************/
  301.  
  302. void
  303. AcpiNsGetInternalNameLength (
  304.     ACPI_NAMESTRING_INFO    *Info)
  305. {
  306.     const char              *NextExternalChar;
  307.     UINT32                  i;
  308.  
  309.  
  310.     ACPI_FUNCTION_ENTRY ();
  311.  
  312.  
  313.     NextExternalChar = Info->ExternalName;
  314.     Info->NumCarats = 0;
  315.     Info->NumSegments = 0;
  316.     Info->FullyQualified = FALSE;
  317.  
  318.     /*
  319.      * For the internal name, the required length is 4 bytes per segment, plus
  320.      * 1 each for RootPrefix, MultiNamePrefixOp, segment count, trailing null
  321.      * (which is not really needed, but no there's harm in putting it there)
  322.      *
  323.      * strlen() + 1 covers the first NameSeg, which has no path separator
  324.      */
  325.     if (AcpiNsValidRootPrefix (*NextExternalChar))
  326.     {
  327.         Info->FullyQualified = TRUE;
  328.         NextExternalChar++;
  329.  
  330.         /* Skip redundant RootPrefix, like \\_SB.PCI0.SBRG.EC0 */
  331.  
  332.         while (AcpiNsValidRootPrefix (*NextExternalChar))
  333.         {
  334.             NextExternalChar++;
  335.         }
  336.     }
  337.     else
  338.     {
  339.         /* Handle Carat prefixes */
  340.  
  341.         while (*NextExternalChar == '^')
  342.         {
  343.             Info->NumCarats++;
  344.             NextExternalChar++;
  345.         }
  346.     }
  347.  
  348.     /*
  349.      * Determine the number of ACPI name "segments" by counting the number of
  350.      * path separators within the string. Start with one segment since the
  351.      * segment count is [(# separators) + 1], and zero separators is ok.
  352.      */
  353.     if (*NextExternalChar)
  354.     {
  355.         Info->NumSegments = 1;
  356.         for (i = 0; NextExternalChar[i]; i++)
  357.         {
  358.             if (AcpiNsValidPathSeparator (NextExternalChar[i]))
  359.             {
  360.                 Info->NumSegments++;
  361.             }
  362.         }
  363.     }
  364.  
  365.     Info->Length = (ACPI_NAME_SIZE * Info->NumSegments) +
  366.                     4 + Info->NumCarats;
  367.  
  368.     Info->NextExternalChar = NextExternalChar;
  369. }
  370.  
  371.  
  372. /*******************************************************************************
  373.  *
  374.  * FUNCTION:    AcpiNsBuildInternalName
  375.  *
  376.  * PARAMETERS:  Info            - Info struct fully initialized
  377.  *
  378.  * RETURN:      Status
  379.  *
  380.  * DESCRIPTION: Construct the internal (AML) namestring
  381.  *              corresponding to the external (ASL) namestring.
  382.  *
  383.  ******************************************************************************/
  384.  
  385. ACPI_STATUS
  386. AcpiNsBuildInternalName (
  387.     ACPI_NAMESTRING_INFO    *Info)
  388. {
  389.     UINT32                  NumSegments = Info->NumSegments;
  390.     char                    *InternalName = Info->InternalName;
  391.     const char              *ExternalName = Info->NextExternalChar;
  392.     char                    *Result = NULL;
  393.     UINT32                  i;
  394.  
  395.  
  396.     ACPI_FUNCTION_TRACE (NsBuildInternalName);
  397.  
  398.  
  399.     /* Setup the correct prefixes, counts, and pointers */
  400.  
  401.     if (Info->FullyQualified)
  402.     {
  403.         InternalName[0] = '\\';
  404.  
  405.         if (NumSegments <= 1)
  406.         {
  407.             Result = &InternalName[1];
  408.         }
  409.         else if (NumSegments == 2)
  410.         {
  411.             InternalName[1] = AML_DUAL_NAME_PREFIX;
  412.             Result = &InternalName[2];
  413.         }
  414.         else
  415.         {
  416.             InternalName[1] = AML_MULTI_NAME_PREFIX_OP;
  417.             InternalName[2] = (char) NumSegments;
  418.             Result = &InternalName[3];
  419.         }
  420.     }
  421.     else
  422.     {
  423.         /*
  424.          * Not fully qualified.
  425.          * Handle Carats first, then append the name segments
  426.          */
  427.         i = 0;
  428.         if (Info->NumCarats)
  429.         {
  430.             for (i = 0; i < Info->NumCarats; i++)
  431.             {
  432.                 InternalName[i] = '^';
  433.             }
  434.         }
  435.  
  436.         if (NumSegments <= 1)
  437.         {
  438.             Result = &InternalName[i];
  439.         }
  440.         else if (NumSegments == 2)
  441.         {
  442.             InternalName[i] = AML_DUAL_NAME_PREFIX;
  443.             Result = &InternalName[(ACPI_SIZE) i+1];
  444.         }
  445.         else
  446.         {
  447.             InternalName[i] = AML_MULTI_NAME_PREFIX_OP;
  448.             InternalName[(ACPI_SIZE) i+1] = (char) NumSegments;
  449.             Result = &InternalName[(ACPI_SIZE) i+2];
  450.         }
  451.     }
  452.  
  453.     /* Build the name (minus path separators) */
  454.  
  455.     for (; NumSegments; NumSegments--)
  456.     {
  457.         for (i = 0; i < ACPI_NAME_SIZE; i++)
  458.         {
  459.             if (AcpiNsValidPathSeparator (*ExternalName) ||
  460.                (*ExternalName == 0))
  461.             {
  462.                 /* Pad the segment with underscore(s) if segment is short */
  463.  
  464.                 Result[i] = '_';
  465.             }
  466.             else
  467.             {
  468.                 /* Convert the character to uppercase and save it */
  469.  
  470.                 Result[i] = (char) ACPI_TOUPPER ((int) *ExternalName);
  471.                 ExternalName++;
  472.             }
  473.         }
  474.  
  475.         /* Now we must have a path separator, or the pathname is bad */
  476.  
  477.         if (!AcpiNsValidPathSeparator (*ExternalName) &&
  478.             (*ExternalName != 0))
  479.         {
  480.             return_ACPI_STATUS (AE_BAD_PARAMETER);
  481.         }
  482.  
  483.         /* Move on the next segment */
  484.  
  485.         ExternalName++;
  486.         Result += ACPI_NAME_SIZE;
  487.     }
  488.  
  489.     /* Terminate the string */
  490.  
  491.     *Result = 0;
  492.  
  493.     if (Info->FullyQualified)
  494.     {
  495.         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Returning [%p] (abs) \"\\%s\"\n",
  496.             InternalName, InternalName));
  497.     }
  498.     else
  499.     {
  500.         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Returning [%p] (rel) \"%s\"\n",
  501.             InternalName, InternalName));
  502.     }
  503.  
  504.     return_ACPI_STATUS (AE_OK);
  505. }
  506.  
  507.  
  508. /*******************************************************************************
  509.  *
  510.  * FUNCTION:    AcpiNsInternalizeName
  511.  *
  512.  * PARAMETERS:  *ExternalName           - External representation of name
  513.  *              **Converted Name        - Where to return the resulting
  514.  *                                        internal represention of the name
  515.  *
  516.  * RETURN:      Status
  517.  *
  518.  * DESCRIPTION: Convert an external representation (e.g. "\_PR_.CPU0")
  519.  *              to internal form (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30)
  520.  *
  521.  *******************************************************************************/
  522.  
  523. ACPI_STATUS
  524. AcpiNsInternalizeName (
  525.     const char              *ExternalName,
  526.     char                    **ConvertedName)
  527. {
  528.     char                    *InternalName;
  529.     ACPI_NAMESTRING_INFO    Info;
  530.     ACPI_STATUS             Status;
  531.  
  532.  
  533.     ACPI_FUNCTION_TRACE (NsInternalizeName);
  534.  
  535.  
  536.     if ((!ExternalName)      ||
  537.         (*ExternalName == 0) ||
  538.         (!ConvertedName))
  539.     {
  540.         return_ACPI_STATUS (AE_BAD_PARAMETER);
  541.     }
  542.  
  543.     /* Get the length of the new internal name */
  544.  
  545.     Info.ExternalName = ExternalName;
  546.     AcpiNsGetInternalNameLength (&Info);
  547.  
  548.     /* We need a segment to store the internal  name */
  549.  
  550.     InternalName = ACPI_ALLOCATE_ZEROED (Info.Length);
  551.     if (!InternalName)
  552.     {
  553.         return_ACPI_STATUS (AE_NO_MEMORY);
  554.     }
  555.  
  556.     /* Build the name */
  557.  
  558.     Info.InternalName = InternalName;
  559.     Status = AcpiNsBuildInternalName (&Info);
  560.     if (ACPI_FAILURE (Status))
  561.     {
  562.         ACPI_FREE (InternalName);
  563.         return_ACPI_STATUS (Status);
  564.     }
  565.  
  566.     *ConvertedName = InternalName;
  567.     return_ACPI_STATUS (AE_OK);
  568. }
  569.  
  570.  
  571. /*******************************************************************************
  572.  *
  573.  * FUNCTION:    AcpiNsExternalizeName
  574.  *
  575.  * PARAMETERS:  InternalNameLength  - Lenth of the internal name below
  576.  *              InternalName        - Internal representation of name
  577.  *              ConvertedNameLength - Where the length is returned
  578.  *              ConvertedName       - Where the resulting external name
  579.  *                                    is returned
  580.  *
  581.  * RETURN:      Status
  582.  *
  583.  * DESCRIPTION: Convert internal name (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30)
  584.  *              to its external (printable) form (e.g. "\_PR_.CPU0")
  585.  *
  586.  ******************************************************************************/
  587.  
  588. ACPI_STATUS
  589. AcpiNsExternalizeName (
  590.     UINT32                  InternalNameLength,
  591.     const char              *InternalName,
  592.     UINT32                  *ConvertedNameLength,
  593.     char                    **ConvertedName)
  594. {
  595.     UINT32                  NamesIndex = 0;
  596.     UINT32                  NumSegments = 0;
  597.     UINT32                  RequiredLength;
  598.     UINT32                  PrefixLength = 0;
  599.     UINT32                  i = 0;
  600.     UINT32                  j = 0;
  601.  
  602.  
  603.     ACPI_FUNCTION_TRACE (NsExternalizeName);
  604.  
  605.  
  606.     if (!InternalNameLength     ||
  607.         !InternalName           ||
  608.         !ConvertedName)
  609.     {
  610.         return_ACPI_STATUS (AE_BAD_PARAMETER);
  611.     }
  612.  
  613.     /* Check for a prefix (one '\' | one or more '^') */
  614.  
  615.     switch (InternalName[0])
  616.     {
  617.     case '\\':
  618.         PrefixLength = 1;
  619.         break;
  620.  
  621.     case '^':
  622.         for (i = 0; i < InternalNameLength; i++)
  623.         {
  624.             if (InternalName[i] == '^')
  625.             {
  626.                 PrefixLength = i + 1;
  627.             }
  628.             else
  629.             {
  630.                 break;
  631.             }
  632.         }
  633.  
  634.         if (i == InternalNameLength)
  635.         {
  636.             PrefixLength = i;
  637.         }
  638.  
  639.         break;
  640.  
  641.     default:
  642.         break;
  643.     }
  644.  
  645.     /*
  646.      * Check for object names. Note that there could be 0-255 of these
  647.      * 4-byte elements.
  648.      */
  649.     if (PrefixLength < InternalNameLength)
  650.     {
  651.         switch (InternalName[PrefixLength])
  652.         {
  653.         case AML_MULTI_NAME_PREFIX_OP:
  654.  
  655.             /* <count> 4-byte names */
  656.  
  657.             NamesIndex = PrefixLength + 2;
  658.             NumSegments = (UINT8)
  659.                 InternalName[(ACPI_SIZE) PrefixLength + 1];
  660.             break;
  661.  
  662.         case AML_DUAL_NAME_PREFIX:
  663.  
  664.             /* Two 4-byte names */
  665.  
  666.             NamesIndex = PrefixLength + 1;
  667.             NumSegments = 2;
  668.             break;
  669.  
  670.         case 0:
  671.  
  672.             /* NullName */
  673.  
  674.             NamesIndex = 0;
  675.             NumSegments = 0;
  676.             break;
  677.  
  678.         default:
  679.  
  680.             /* one 4-byte name */
  681.  
  682.             NamesIndex = PrefixLength;
  683.             NumSegments = 1;
  684.             break;
  685.         }
  686.     }
  687.  
  688.     /*
  689.      * Calculate the length of ConvertedName, which equals the length
  690.      * of the prefix, length of all object names, length of any required
  691.      * punctuation ('.') between object names, plus the NULL terminator.
  692.      */
  693.     RequiredLength = PrefixLength + (4 * NumSegments) +
  694.                         ((NumSegments > 0) ? (NumSegments - 1) : 0) + 1;
  695.  
  696.     /*
  697.      * Check to see if we're still in bounds.  If not, there's a problem
  698.      * with InternalName (invalid format).
  699.      */
  700.     if (RequiredLength > InternalNameLength)
  701.     {
  702.         ACPI_ERROR ((AE_INFO, "Invalid internal name"));
  703.         return_ACPI_STATUS (AE_BAD_PATHNAME);
  704.     }
  705.  
  706.     /* Build the ConvertedName */
  707.  
  708.     *ConvertedName = ACPI_ALLOCATE_ZEROED (RequiredLength);
  709.     if (!(*ConvertedName))
  710.     {
  711.         return_ACPI_STATUS (AE_NO_MEMORY);
  712.     }
  713.  
  714.     j = 0;
  715.  
  716.     for (i = 0; i < PrefixLength; i++)
  717.     {
  718.         (*ConvertedName)[j++] = InternalName[i];
  719.     }
  720.  
  721.     if (NumSegments > 0)
  722.     {
  723.         for (i = 0; i < NumSegments; i++)
  724.         {
  725.             if (i > 0)
  726.             {
  727.                 (*ConvertedName)[j++] = '.';
  728.             }
  729.  
  730.             (*ConvertedName)[j++] = InternalName[NamesIndex++];
  731.             (*ConvertedName)[j++] = InternalName[NamesIndex++];
  732.             (*ConvertedName)[j++] = InternalName[NamesIndex++];
  733.             (*ConvertedName)[j++] = InternalName[NamesIndex++];
  734.         }
  735.     }
  736.  
  737.     if (ConvertedNameLength)
  738.     {
  739.         *ConvertedNameLength = (UINT32) RequiredLength;
  740.     }
  741.  
  742.     return_ACPI_STATUS (AE_OK);
  743. }
  744.  
  745.  
  746. /*******************************************************************************
  747.  *
  748.  * FUNCTION:    AcpiNsValidateHandle
  749.  *
  750.  * PARAMETERS:  Handle          - Handle to be validated and typecast to a
  751.  *                                namespace node.
  752.  *
  753.  * RETURN:      A pointer to a namespace node
  754.  *
  755.  * DESCRIPTION: Convert a namespace handle to a namespace node. Handles special
  756.  *              cases for the root node.
  757.  *
  758.  * NOTE: Real integer handles would allow for more verification
  759.  *       and keep all pointers within this subsystem - however this introduces
  760.  *       more overhead and has not been necessary to this point. Drivers
  761.  *       holding handles are typically notified before a node becomes invalid
  762.  *       due to a table unload.
  763.  *
  764.  ******************************************************************************/
  765.  
  766. ACPI_NAMESPACE_NODE *
  767. AcpiNsValidateHandle (
  768.     ACPI_HANDLE             Handle)
  769. {
  770.  
  771.     ACPI_FUNCTION_ENTRY ();
  772.  
  773.  
  774.     /* Parameter validation */
  775.  
  776.     if ((!Handle) || (Handle == ACPI_ROOT_OBJECT))
  777.     {
  778.         return (AcpiGbl_RootNode);
  779.     }
  780.  
  781.     /* We can at least attempt to verify the handle */
  782.  
  783.     if (ACPI_GET_DESCRIPTOR_TYPE (Handle) != ACPI_DESC_TYPE_NAMED)
  784.     {
  785.         return (NULL);
  786.     }
  787.  
  788.     return (ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Handle));
  789. }
  790.  
  791.  
  792. /*******************************************************************************
  793.  *
  794.  * FUNCTION:    AcpiNsTerminate
  795.  *
  796.  * PARAMETERS:  none
  797.  *
  798.  * RETURN:      none
  799.  *
  800.  * DESCRIPTION: free memory allocated for namespace and ACPI table storage.
  801.  *
  802.  ******************************************************************************/
  803.  
  804. void
  805. AcpiNsTerminate (
  806.     void)
  807. {
  808.     ACPI_OPERAND_OBJECT     *ObjDesc;
  809.  
  810.  
  811.     ACPI_FUNCTION_TRACE (NsTerminate);
  812.  
  813.  
  814.     /*
  815.      * 1) Free the entire namespace -- all nodes and objects
  816.      *
  817.      * Delete all object descriptors attached to namepsace nodes
  818.      */
  819.     AcpiNsDeleteNamespaceSubtree (AcpiGbl_RootNode);
  820.  
  821.     /* Detach any objects attached to the root */
  822.  
  823.     ObjDesc = AcpiNsGetAttachedObject (AcpiGbl_RootNode);
  824.     if (ObjDesc)
  825.     {
  826.         AcpiNsDetachObject (AcpiGbl_RootNode);
  827.     }
  828.  
  829.     ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Namespace freed\n"));
  830.     return_VOID;
  831. }
  832.  
  833.  
  834. /*******************************************************************************
  835.  *
  836.  * FUNCTION:    AcpiNsOpensScope
  837.  *
  838.  * PARAMETERS:  Type        - A valid namespace type
  839.  *
  840.  * RETURN:      NEWSCOPE if the passed type "opens a name scope" according
  841.  *              to the ACPI specification, else 0
  842.  *
  843.  ******************************************************************************/
  844.  
  845. UINT32
  846. AcpiNsOpensScope (
  847.     ACPI_OBJECT_TYPE        Type)
  848. {
  849.     ACPI_FUNCTION_TRACE_STR (NsOpensScope, AcpiUtGetTypeName (Type));
  850.  
  851.  
  852.     if (!AcpiUtValidObjectType (Type))
  853.     {
  854.         /* type code out of range  */
  855.  
  856.         ACPI_WARNING ((AE_INFO, "Invalid Object Type 0x%X", Type));
  857.         return_UINT32 (ACPI_NS_NORMAL);
  858.     }
  859.  
  860.     return_UINT32 (((UINT32) AcpiGbl_NsProperties[Type]) & ACPI_NS_NEWSCOPE);
  861. }
  862.  
  863.  
  864. /*******************************************************************************
  865.  *
  866.  * FUNCTION:    AcpiNsGetNode
  867.  *
  868.  * PARAMETERS:  *Pathname   - Name to be found, in external (ASL) format. The
  869.  *                            \ (backslash) and ^ (carat) prefixes, and the
  870.  *                            . (period) to separate segments are supported.
  871.  *              PrefixNode   - Root of subtree to be searched, or NS_ALL for the
  872.  *                            root of the name space.  If Name is fully
  873.  *                            qualified (first INT8 is '\'), the passed value
  874.  *                            of Scope will not be accessed.
  875.  *              Flags       - Used to indicate whether to perform upsearch or
  876.  *                            not.
  877.  *              ReturnNode  - Where the Node is returned
  878.  *
  879.  * DESCRIPTION: Look up a name relative to a given scope and return the
  880.  *              corresponding Node.  NOTE: Scope can be null.
  881.  *
  882.  * MUTEX:       Locks namespace
  883.  *
  884.  ******************************************************************************/
  885.  
  886. ACPI_STATUS
  887. AcpiNsGetNode (
  888.     ACPI_NAMESPACE_NODE     *PrefixNode,
  889.     const char              *Pathname,
  890.     UINT32                  Flags,
  891.     ACPI_NAMESPACE_NODE     **ReturnNode)
  892. {
  893.     ACPI_GENERIC_STATE      ScopeInfo;
  894.     ACPI_STATUS             Status;
  895.     char                    *InternalPath;
  896.  
  897.  
  898.     ACPI_FUNCTION_TRACE_PTR (NsGetNode, ACPI_CAST_PTR (char, Pathname));
  899.  
  900.  
  901.     if (!Pathname)
  902.     {
  903.         *ReturnNode = PrefixNode;
  904.         if (!PrefixNode)
  905.         {
  906.             *ReturnNode = AcpiGbl_RootNode;
  907.         }
  908.         return_ACPI_STATUS (AE_OK);
  909.     }
  910.  
  911.     /* Convert path to internal representation */
  912.  
  913.     Status = AcpiNsInternalizeName (Pathname, &InternalPath);
  914.     if (ACPI_FAILURE (Status))
  915.     {
  916.         return_ACPI_STATUS (Status);
  917.     }
  918.  
  919.     /* Must lock namespace during lookup */
  920.  
  921.     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
  922.     if (ACPI_FAILURE (Status))
  923.     {
  924.         goto Cleanup;
  925.     }
  926.  
  927.     /* Setup lookup scope (search starting point) */
  928.  
  929.     ScopeInfo.Scope.Node = PrefixNode;
  930.  
  931.     /* Lookup the name in the namespace */
  932.  
  933.     Status = AcpiNsLookup (&ScopeInfo, InternalPath, ACPI_TYPE_ANY,
  934.                 ACPI_IMODE_EXECUTE, (Flags | ACPI_NS_DONT_OPEN_SCOPE),
  935.                 NULL, ReturnNode);
  936.     if (ACPI_FAILURE (Status))
  937.     {
  938.         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%s, %s\n",
  939.                 Pathname, AcpiFormatException (Status)));
  940.     }
  941.  
  942.     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
  943.  
  944. Cleanup:
  945.     ACPI_FREE (InternalPath);
  946.     return_ACPI_STATUS (Status);
  947. }
  948.