Subversion Repositories Kolibri OS

Rev

Go to most recent revision | 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 - 2010, 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:    AcpiNsReportError
  143.  *
  144.  * PARAMETERS:  ModuleName          - Caller's module name (for error output)
  145.  *              LineNumber          - Caller's line number (for error output)
  146.  *              InternalName        - Name or path of the namespace node
  147.  *              LookupStatus        - Exception code from NS lookup
  148.  *
  149.  * RETURN:      None
  150.  *
  151.  * DESCRIPTION: Print warning message with full pathname
  152.  *
  153.  ******************************************************************************/
  154.  
  155. void
  156. AcpiNsReportError (
  157.     const char              *ModuleName,
  158.     UINT32                  LineNumber,
  159.     const char              *InternalName,
  160.     ACPI_STATUS             LookupStatus)
  161. {
  162.     ACPI_STATUS             Status;
  163.     UINT32                  BadName;
  164.     char                    *Name = NULL;
  165.  
  166.  
  167.     AcpiOsPrintf ("ACPI Error (%s-%04d): ", ModuleName, LineNumber);
  168.  
  169.     if (LookupStatus == AE_BAD_CHARACTER)
  170.     {
  171.         /* There is a non-ascii character in the name */
  172.  
  173.         ACPI_MOVE_32_TO_32 (&BadName, ACPI_CAST_PTR (UINT32, InternalName));
  174.         AcpiOsPrintf ("[0x%4.4X] (NON-ASCII)", BadName);
  175.     }
  176.     else
  177.     {
  178.         /* Convert path to external format */
  179.  
  180.         Status = AcpiNsExternalizeName (ACPI_UINT32_MAX,
  181.                     InternalName, NULL, &Name);
  182.  
  183.         /* Print target name */
  184.  
  185.         if (ACPI_SUCCESS (Status))
  186.         {
  187.             AcpiOsPrintf ("[%s]", Name);
  188.         }
  189.         else
  190.         {
  191.             AcpiOsPrintf ("[COULD NOT EXTERNALIZE NAME]");
  192.         }
  193.  
  194.         if (Name)
  195.         {
  196.             ACPI_FREE (Name);
  197.         }
  198.     }
  199.  
  200.     AcpiOsPrintf (" Namespace lookup failure, %s\n",
  201.         AcpiFormatException (LookupStatus));
  202. }
  203.  
  204.  
  205. /*******************************************************************************
  206.  *
  207.  * FUNCTION:    AcpiNsReportMethodError
  208.  *
  209.  * PARAMETERS:  ModuleName          - Caller's module name (for error output)
  210.  *              LineNumber          - Caller's line number (for error output)
  211.  *              Message             - Error message to use on failure
  212.  *              PrefixNode          - Prefix relative to the path
  213.  *              Path                - Path to the node (optional)
  214.  *              MethodStatus        - Execution status
  215.  *
  216.  * RETURN:      None
  217.  *
  218.  * DESCRIPTION: Print warning message with full pathname
  219.  *
  220.  ******************************************************************************/
  221.  
  222. void
  223. AcpiNsReportMethodError (
  224.     const char              *ModuleName,
  225.     UINT32                  LineNumber,
  226.     const char              *Message,
  227.     ACPI_NAMESPACE_NODE     *PrefixNode,
  228.     const char              *Path,
  229.     ACPI_STATUS             MethodStatus)
  230. {
  231.     ACPI_STATUS             Status;
  232.     ACPI_NAMESPACE_NODE     *Node = PrefixNode;
  233.  
  234.  
  235.     AcpiOsPrintf ("ACPI Error (%s-%04d): ", ModuleName, LineNumber);
  236.  
  237.     if (Path)
  238.     {
  239.         Status = AcpiNsGetNode (PrefixNode, Path, ACPI_NS_NO_UPSEARCH,
  240.                     &Node);
  241.         if (ACPI_FAILURE (Status))
  242.         {
  243.             AcpiOsPrintf ("[Could not get node by pathname]");
  244.         }
  245.     }
  246.  
  247.     AcpiNsPrintNodePathname (Node, Message);
  248.     AcpiOsPrintf (", %s\n", AcpiFormatException (MethodStatus));
  249. }
  250.  
  251.  
  252. /*******************************************************************************
  253.  *
  254.  * FUNCTION:    AcpiNsPrintNodePathname
  255.  *
  256.  * PARAMETERS:  Node            - Object
  257.  *              Message         - Prefix message
  258.  *
  259.  * DESCRIPTION: Print an object's full namespace pathname
  260.  *              Manages allocation/freeing of a pathname buffer
  261.  *
  262.  ******************************************************************************/
  263.  
  264. void
  265. AcpiNsPrintNodePathname (
  266.     ACPI_NAMESPACE_NODE     *Node,
  267.     const char              *Message)
  268. {
  269.     ACPI_BUFFER             Buffer;
  270.     ACPI_STATUS             Status;
  271.  
  272.  
  273.     if (!Node)
  274.     {
  275.         AcpiOsPrintf ("[NULL NAME]");
  276.         return;
  277.     }
  278.  
  279.     /* Convert handle to full pathname and print it (with supplied message) */
  280.  
  281.     Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
  282.  
  283.     Status = AcpiNsHandleToPathname (Node, &Buffer);
  284.     if (ACPI_SUCCESS (Status))
  285.     {
  286.         if (Message)
  287.         {
  288.             AcpiOsPrintf ("%s ", Message);
  289.         }
  290.  
  291.         AcpiOsPrintf ("[%s] (Node %p)", (char *) Buffer.Pointer, Node);
  292.         ACPI_FREE (Buffer.Pointer);
  293.     }
  294. }
  295.  
  296.  
  297. /*******************************************************************************
  298.  *
  299.  * FUNCTION:    AcpiNsValidRootPrefix
  300.  *
  301.  * PARAMETERS:  Prefix          - Character to be checked
  302.  *
  303.  * RETURN:      TRUE if a valid prefix
  304.  *
  305.  * DESCRIPTION: Check if a character is a valid ACPI Root prefix
  306.  *
  307.  ******************************************************************************/
  308.  
  309. BOOLEAN
  310. AcpiNsValidRootPrefix (
  311.     char                    Prefix)
  312. {
  313.  
  314.     return ((BOOLEAN) (Prefix == '\\'));
  315. }
  316.  
  317.  
  318. /*******************************************************************************
  319.  *
  320.  * FUNCTION:    AcpiNsValidPathSeparator
  321.  *
  322.  * PARAMETERS:  Sep         - Character to be checked
  323.  *
  324.  * RETURN:      TRUE if a valid path separator
  325.  *
  326.  * DESCRIPTION: Check if a character is a valid ACPI path separator
  327.  *
  328.  ******************************************************************************/
  329.  
  330. static BOOLEAN
  331. AcpiNsValidPathSeparator (
  332.     char                    Sep)
  333. {
  334.  
  335.     return ((BOOLEAN) (Sep == '.'));
  336. }
  337.  
  338.  
  339. /*******************************************************************************
  340.  *
  341.  * FUNCTION:    AcpiNsGetType
  342.  *
  343.  * PARAMETERS:  Node        - Parent Node to be examined
  344.  *
  345.  * RETURN:      Type field from Node whose handle is passed
  346.  *
  347.  * DESCRIPTION: Return the type of a Namespace node
  348.  *
  349.  ******************************************************************************/
  350.  
  351. ACPI_OBJECT_TYPE
  352. AcpiNsGetType (
  353.     ACPI_NAMESPACE_NODE     *Node)
  354. {
  355.     ACPI_FUNCTION_TRACE (NsGetType);
  356.  
  357.  
  358.     if (!Node)
  359.     {
  360.         ACPI_WARNING ((AE_INFO, "Null Node parameter"));
  361.         return_UINT32 (ACPI_TYPE_ANY);
  362.     }
  363.  
  364.     return_UINT32 ((ACPI_OBJECT_TYPE) Node->Type);
  365. }
  366.  
  367.  
  368. /*******************************************************************************
  369.  *
  370.  * FUNCTION:    AcpiNsLocal
  371.  *
  372.  * PARAMETERS:  Type        - A namespace object type
  373.  *
  374.  * RETURN:      LOCAL if names must be found locally in objects of the
  375.  *              passed type, 0 if enclosing scopes should be searched
  376.  *
  377.  * DESCRIPTION: Returns scope rule for the given object type.
  378.  *
  379.  ******************************************************************************/
  380.  
  381. UINT32
  382. AcpiNsLocal (
  383.     ACPI_OBJECT_TYPE        Type)
  384. {
  385.     ACPI_FUNCTION_TRACE (NsLocal);
  386.  
  387.  
  388.     if (!AcpiUtValidObjectType (Type))
  389.     {
  390.         /* Type code out of range  */
  391.  
  392.         ACPI_WARNING ((AE_INFO, "Invalid Object Type 0x%X", Type));
  393.         return_UINT32 (ACPI_NS_NORMAL);
  394.     }
  395.  
  396.     return_UINT32 ((UINT32) AcpiGbl_NsProperties[Type] & ACPI_NS_LOCAL);
  397. }
  398.  
  399.  
  400. /*******************************************************************************
  401.  *
  402.  * FUNCTION:    AcpiNsGetInternalNameLength
  403.  *
  404.  * PARAMETERS:  Info            - Info struct initialized with the
  405.  *                                external name pointer.
  406.  *
  407.  * RETURN:      None
  408.  *
  409.  * DESCRIPTION: Calculate the length of the internal (AML) namestring
  410.  *              corresponding to the external (ASL) namestring.
  411.  *
  412.  ******************************************************************************/
  413.  
  414. void
  415. AcpiNsGetInternalNameLength (
  416.     ACPI_NAMESTRING_INFO    *Info)
  417. {
  418.     const char              *NextExternalChar;
  419.     UINT32                  i;
  420.  
  421.  
  422.     ACPI_FUNCTION_ENTRY ();
  423.  
  424.  
  425.     NextExternalChar = Info->ExternalName;
  426.     Info->NumCarats = 0;
  427.     Info->NumSegments = 0;
  428.     Info->FullyQualified = FALSE;
  429.  
  430.     /*
  431.      * For the internal name, the required length is 4 bytes per segment, plus
  432.      * 1 each for RootPrefix, MultiNamePrefixOp, segment count, trailing null
  433.      * (which is not really needed, but no there's harm in putting it there)
  434.      *
  435.      * strlen() + 1 covers the first NameSeg, which has no path separator
  436.      */
  437.     if (AcpiNsValidRootPrefix (*NextExternalChar))
  438.     {
  439.         Info->FullyQualified = TRUE;
  440.         NextExternalChar++;
  441.  
  442.         /* Skip redundant RootPrefix, like \\_SB.PCI0.SBRG.EC0 */
  443.  
  444.         while (AcpiNsValidRootPrefix (*NextExternalChar))
  445.         {
  446.             NextExternalChar++;
  447.         }
  448.     }
  449.     else
  450.     {
  451.         /* Handle Carat prefixes */
  452.  
  453.         while (*NextExternalChar == '^')
  454.         {
  455.             Info->NumCarats++;
  456.             NextExternalChar++;
  457.         }
  458.     }
  459.  
  460.     /*
  461.      * Determine the number of ACPI name "segments" by counting the number of
  462.      * path separators within the string. Start with one segment since the
  463.      * segment count is [(# separators) + 1], and zero separators is ok.
  464.      */
  465.     if (*NextExternalChar)
  466.     {
  467.         Info->NumSegments = 1;
  468.         for (i = 0; NextExternalChar[i]; i++)
  469.         {
  470.             if (AcpiNsValidPathSeparator (NextExternalChar[i]))
  471.             {
  472.                 Info->NumSegments++;
  473.             }
  474.         }
  475.     }
  476.  
  477.     Info->Length = (ACPI_NAME_SIZE * Info->NumSegments) +
  478.                     4 + Info->NumCarats;
  479.  
  480.     Info->NextExternalChar = NextExternalChar;
  481. }
  482.  
  483.  
  484. /*******************************************************************************
  485.  *
  486.  * FUNCTION:    AcpiNsBuildInternalName
  487.  *
  488.  * PARAMETERS:  Info            - Info struct fully initialized
  489.  *
  490.  * RETURN:      Status
  491.  *
  492.  * DESCRIPTION: Construct the internal (AML) namestring
  493.  *              corresponding to the external (ASL) namestring.
  494.  *
  495.  ******************************************************************************/
  496.  
  497. ACPI_STATUS
  498. AcpiNsBuildInternalName (
  499.     ACPI_NAMESTRING_INFO    *Info)
  500. {
  501.     UINT32                  NumSegments = Info->NumSegments;
  502.     char                    *InternalName = Info->InternalName;
  503.     const char              *ExternalName = Info->NextExternalChar;
  504.     char                    *Result = NULL;
  505.     UINT32                  i;
  506.  
  507.  
  508.     ACPI_FUNCTION_TRACE (NsBuildInternalName);
  509.  
  510.  
  511.     /* Setup the correct prefixes, counts, and pointers */
  512.  
  513.     if (Info->FullyQualified)
  514.     {
  515.         InternalName[0] = '\\';
  516.  
  517.         if (NumSegments <= 1)
  518.         {
  519.             Result = &InternalName[1];
  520.         }
  521.         else if (NumSegments == 2)
  522.         {
  523.             InternalName[1] = AML_DUAL_NAME_PREFIX;
  524.             Result = &InternalName[2];
  525.         }
  526.         else
  527.         {
  528.             InternalName[1] = AML_MULTI_NAME_PREFIX_OP;
  529.             InternalName[2] = (char) NumSegments;
  530.             Result = &InternalName[3];
  531.         }
  532.     }
  533.     else
  534.     {
  535.         /*
  536.          * Not fully qualified.
  537.          * Handle Carats first, then append the name segments
  538.          */
  539.         i = 0;
  540.         if (Info->NumCarats)
  541.         {
  542.             for (i = 0; i < Info->NumCarats; i++)
  543.             {
  544.                 InternalName[i] = '^';
  545.             }
  546.         }
  547.  
  548.         if (NumSegments <= 1)
  549.         {
  550.             Result = &InternalName[i];
  551.         }
  552.         else if (NumSegments == 2)
  553.         {
  554.             InternalName[i] = AML_DUAL_NAME_PREFIX;
  555.             Result = &InternalName[(ACPI_SIZE) i+1];
  556.         }
  557.         else
  558.         {
  559.             InternalName[i] = AML_MULTI_NAME_PREFIX_OP;
  560.             InternalName[(ACPI_SIZE) i+1] = (char) NumSegments;
  561.             Result = &InternalName[(ACPI_SIZE) i+2];
  562.         }
  563.     }
  564.  
  565.     /* Build the name (minus path separators) */
  566.  
  567.     for (; NumSegments; NumSegments--)
  568.     {
  569.         for (i = 0; i < ACPI_NAME_SIZE; i++)
  570.         {
  571.             if (AcpiNsValidPathSeparator (*ExternalName) ||
  572.                (*ExternalName == 0))
  573.             {
  574.                 /* Pad the segment with underscore(s) if segment is short */
  575.  
  576.                 Result[i] = '_';
  577.             }
  578.             else
  579.             {
  580.                 /* Convert the character to uppercase and save it */
  581.  
  582.                 Result[i] = (char) ACPI_TOUPPER ((int) *ExternalName);
  583.                 ExternalName++;
  584.             }
  585.         }
  586.  
  587.         /* Now we must have a path separator, or the pathname is bad */
  588.  
  589.         if (!AcpiNsValidPathSeparator (*ExternalName) &&
  590.             (*ExternalName != 0))
  591.         {
  592.             return_ACPI_STATUS (AE_BAD_PARAMETER);
  593.         }
  594.  
  595.         /* Move on the next segment */
  596.  
  597.         ExternalName++;
  598.         Result += ACPI_NAME_SIZE;
  599.     }
  600.  
  601.     /* Terminate the string */
  602.  
  603.     *Result = 0;
  604.  
  605.     if (Info->FullyQualified)
  606.     {
  607.         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Returning [%p] (abs) \"\\%s\"\n",
  608.             InternalName, InternalName));
  609.     }
  610.     else
  611.     {
  612.         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Returning [%p] (rel) \"%s\"\n",
  613.             InternalName, InternalName));
  614.     }
  615.  
  616.     return_ACPI_STATUS (AE_OK);
  617. }
  618.  
  619.  
  620. /*******************************************************************************
  621.  *
  622.  * FUNCTION:    AcpiNsInternalizeName
  623.  *
  624.  * PARAMETERS:  *ExternalName           - External representation of name
  625.  *              **Converted Name        - Where to return the resulting
  626.  *                                        internal represention of the name
  627.  *
  628.  * RETURN:      Status
  629.  *
  630.  * DESCRIPTION: Convert an external representation (e.g. "\_PR_.CPU0")
  631.  *              to internal form (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30)
  632.  *
  633.  *******************************************************************************/
  634.  
  635. ACPI_STATUS
  636. AcpiNsInternalizeName (
  637.     const char              *ExternalName,
  638.     char                    **ConvertedName)
  639. {
  640.     char                    *InternalName;
  641.     ACPI_NAMESTRING_INFO    Info;
  642.     ACPI_STATUS             Status;
  643.  
  644.  
  645.     ACPI_FUNCTION_TRACE (NsInternalizeName);
  646.  
  647.  
  648.     if ((!ExternalName)      ||
  649.         (*ExternalName == 0) ||
  650.         (!ConvertedName))
  651.     {
  652.         return_ACPI_STATUS (AE_BAD_PARAMETER);
  653.     }
  654.  
  655.     /* Get the length of the new internal name */
  656.  
  657.     Info.ExternalName = ExternalName;
  658.     AcpiNsGetInternalNameLength (&Info);
  659.  
  660.     /* We need a segment to store the internal  name */
  661.  
  662.     InternalName = ACPI_ALLOCATE_ZEROED (Info.Length);
  663.     if (!InternalName)
  664.     {
  665.         return_ACPI_STATUS (AE_NO_MEMORY);
  666.     }
  667.  
  668.     /* Build the name */
  669.  
  670.     Info.InternalName = InternalName;
  671.     Status = AcpiNsBuildInternalName (&Info);
  672.     if (ACPI_FAILURE (Status))
  673.     {
  674.         ACPI_FREE (InternalName);
  675.         return_ACPI_STATUS (Status);
  676.     }
  677.  
  678.     *ConvertedName = InternalName;
  679.     return_ACPI_STATUS (AE_OK);
  680. }
  681.  
  682.  
  683. /*******************************************************************************
  684.  *
  685.  * FUNCTION:    AcpiNsExternalizeName
  686.  *
  687.  * PARAMETERS:  InternalNameLength  - Lenth of the internal name below
  688.  *              InternalName        - Internal representation of name
  689.  *              ConvertedNameLength - Where the length is returned
  690.  *              ConvertedName       - Where the resulting external name
  691.  *                                    is returned
  692.  *
  693.  * RETURN:      Status
  694.  *
  695.  * DESCRIPTION: Convert internal name (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30)
  696.  *              to its external (printable) form (e.g. "\_PR_.CPU0")
  697.  *
  698.  ******************************************************************************/
  699.  
  700. ACPI_STATUS
  701. AcpiNsExternalizeName (
  702.     UINT32                  InternalNameLength,
  703.     const char              *InternalName,
  704.     UINT32                  *ConvertedNameLength,
  705.     char                    **ConvertedName)
  706. {
  707.     UINT32                  NamesIndex = 0;
  708.     UINT32                  NumSegments = 0;
  709.     UINT32                  RequiredLength;
  710.     UINT32                  PrefixLength = 0;
  711.     UINT32                  i = 0;
  712.     UINT32                  j = 0;
  713.  
  714.  
  715.     ACPI_FUNCTION_TRACE (NsExternalizeName);
  716.  
  717.  
  718.     if (!InternalNameLength     ||
  719.         !InternalName           ||
  720.         !ConvertedName)
  721.     {
  722.         return_ACPI_STATUS (AE_BAD_PARAMETER);
  723.     }
  724.  
  725.     /* Check for a prefix (one '\' | one or more '^') */
  726.  
  727.     switch (InternalName[0])
  728.     {
  729.     case '\\':
  730.         PrefixLength = 1;
  731.         break;
  732.  
  733.     case '^':
  734.         for (i = 0; i < InternalNameLength; i++)
  735.         {
  736.             if (InternalName[i] == '^')
  737.             {
  738.                 PrefixLength = i + 1;
  739.             }
  740.             else
  741.             {
  742.                 break;
  743.             }
  744.         }
  745.  
  746.         if (i == InternalNameLength)
  747.         {
  748.             PrefixLength = i;
  749.         }
  750.  
  751.         break;
  752.  
  753.     default:
  754.         break;
  755.     }
  756.  
  757.     /*
  758.      * Check for object names. Note that there could be 0-255 of these
  759.      * 4-byte elements.
  760.      */
  761.     if (PrefixLength < InternalNameLength)
  762.     {
  763.         switch (InternalName[PrefixLength])
  764.         {
  765.         case AML_MULTI_NAME_PREFIX_OP:
  766.  
  767.             /* <count> 4-byte names */
  768.  
  769.             NamesIndex = PrefixLength + 2;
  770.             NumSegments = (UINT8)
  771.                 InternalName[(ACPI_SIZE) PrefixLength + 1];
  772.             break;
  773.  
  774.         case AML_DUAL_NAME_PREFIX:
  775.  
  776.             /* Two 4-byte names */
  777.  
  778.             NamesIndex = PrefixLength + 1;
  779.             NumSegments = 2;
  780.             break;
  781.  
  782.         case 0:
  783.  
  784.             /* NullName */
  785.  
  786.             NamesIndex = 0;
  787.             NumSegments = 0;
  788.             break;
  789.  
  790.         default:
  791.  
  792.             /* one 4-byte name */
  793.  
  794.             NamesIndex = PrefixLength;
  795.             NumSegments = 1;
  796.             break;
  797.         }
  798.     }
  799.  
  800.     /*
  801.      * Calculate the length of ConvertedName, which equals the length
  802.      * of the prefix, length of all object names, length of any required
  803.      * punctuation ('.') between object names, plus the NULL terminator.
  804.      */
  805.     RequiredLength = PrefixLength + (4 * NumSegments) +
  806.                         ((NumSegments > 0) ? (NumSegments - 1) : 0) + 1;
  807.  
  808.     /*
  809.      * Check to see if we're still in bounds.  If not, there's a problem
  810.      * with InternalName (invalid format).
  811.      */
  812.     if (RequiredLength > InternalNameLength)
  813.     {
  814.         ACPI_ERROR ((AE_INFO, "Invalid internal name"));
  815.         return_ACPI_STATUS (AE_BAD_PATHNAME);
  816.     }
  817.  
  818.     /* Build the ConvertedName */
  819.  
  820.     *ConvertedName = ACPI_ALLOCATE_ZEROED (RequiredLength);
  821.     if (!(*ConvertedName))
  822.     {
  823.         return_ACPI_STATUS (AE_NO_MEMORY);
  824.     }
  825.  
  826.     j = 0;
  827.  
  828.     for (i = 0; i < PrefixLength; i++)
  829.     {
  830.         (*ConvertedName)[j++] = InternalName[i];
  831.     }
  832.  
  833.     if (NumSegments > 0)
  834.     {
  835.         for (i = 0; i < NumSegments; i++)
  836.         {
  837.             if (i > 0)
  838.             {
  839.                 (*ConvertedName)[j++] = '.';
  840.             }
  841.  
  842.             (*ConvertedName)[j++] = InternalName[NamesIndex++];
  843.             (*ConvertedName)[j++] = InternalName[NamesIndex++];
  844.             (*ConvertedName)[j++] = InternalName[NamesIndex++];
  845.             (*ConvertedName)[j++] = InternalName[NamesIndex++];
  846.         }
  847.     }
  848.  
  849.     if (ConvertedNameLength)
  850.     {
  851.         *ConvertedNameLength = (UINT32) RequiredLength;
  852.     }
  853.  
  854.     return_ACPI_STATUS (AE_OK);
  855. }
  856.  
  857.  
  858. /*******************************************************************************
  859.  *
  860.  * FUNCTION:    AcpiNsValidateHandle
  861.  *
  862.  * PARAMETERS:  Handle          - Handle to be validated and typecast to a
  863.  *                                namespace node.
  864.  *
  865.  * RETURN:      A pointer to a namespace node
  866.  *
  867.  * DESCRIPTION: Convert a namespace handle to a namespace node. Handles special
  868.  *              cases for the root node.
  869.  *
  870.  * NOTE: Real integer handles would allow for more verification
  871.  *       and keep all pointers within this subsystem - however this introduces
  872.  *       more overhead and has not been necessary to this point. Drivers
  873.  *       holding handles are typically notified before a node becomes invalid
  874.  *       due to a table unload.
  875.  *
  876.  ******************************************************************************/
  877.  
  878. ACPI_NAMESPACE_NODE *
  879. AcpiNsValidateHandle (
  880.     ACPI_HANDLE             Handle)
  881. {
  882.  
  883.     ACPI_FUNCTION_ENTRY ();
  884.  
  885.  
  886.     /* Parameter validation */
  887.  
  888.     if ((!Handle) || (Handle == ACPI_ROOT_OBJECT))
  889.     {
  890.         return (AcpiGbl_RootNode);
  891.     }
  892.  
  893.     /* We can at least attempt to verify the handle */
  894.  
  895.     if (ACPI_GET_DESCRIPTOR_TYPE (Handle) != ACPI_DESC_TYPE_NAMED)
  896.     {
  897.         return (NULL);
  898.     }
  899.  
  900.     return (ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Handle));
  901. }
  902.  
  903.  
  904. /*******************************************************************************
  905.  *
  906.  * FUNCTION:    AcpiNsTerminate
  907.  *
  908.  * PARAMETERS:  none
  909.  *
  910.  * RETURN:      none
  911.  *
  912.  * DESCRIPTION: free memory allocated for namespace and ACPI table storage.
  913.  *
  914.  ******************************************************************************/
  915.  
  916. void
  917. AcpiNsTerminate (
  918.     void)
  919. {
  920.     ACPI_OPERAND_OBJECT     *ObjDesc;
  921.  
  922.  
  923.     ACPI_FUNCTION_TRACE (NsTerminate);
  924.  
  925.  
  926.     /*
  927.      * 1) Free the entire namespace -- all nodes and objects
  928.      *
  929.      * Delete all object descriptors attached to namepsace nodes
  930.      */
  931.     AcpiNsDeleteNamespaceSubtree (AcpiGbl_RootNode);
  932.  
  933.     /* Detach any objects attached to the root */
  934.  
  935.     ObjDesc = AcpiNsGetAttachedObject (AcpiGbl_RootNode);
  936.     if (ObjDesc)
  937.     {
  938.         AcpiNsDetachObject (AcpiGbl_RootNode);
  939.     }
  940.  
  941.     ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Namespace freed\n"));
  942.     return_VOID;
  943. }
  944.  
  945.  
  946. /*******************************************************************************
  947.  *
  948.  * FUNCTION:    AcpiNsOpensScope
  949.  *
  950.  * PARAMETERS:  Type        - A valid namespace type
  951.  *
  952.  * RETURN:      NEWSCOPE if the passed type "opens a name scope" according
  953.  *              to the ACPI specification, else 0
  954.  *
  955.  ******************************************************************************/
  956.  
  957. UINT32
  958. AcpiNsOpensScope (
  959.     ACPI_OBJECT_TYPE        Type)
  960. {
  961.     ACPI_FUNCTION_TRACE_STR (NsOpensScope, AcpiUtGetTypeName (Type));
  962.  
  963.  
  964.     if (!AcpiUtValidObjectType (Type))
  965.     {
  966.         /* type code out of range  */
  967.  
  968.         ACPI_WARNING ((AE_INFO, "Invalid Object Type 0x%X", Type));
  969.         return_UINT32 (ACPI_NS_NORMAL);
  970.     }
  971.  
  972.     return_UINT32 (((UINT32) AcpiGbl_NsProperties[Type]) & ACPI_NS_NEWSCOPE);
  973. }
  974.  
  975.  
  976. /*******************************************************************************
  977.  *
  978.  * FUNCTION:    AcpiNsGetNode
  979.  *
  980.  * PARAMETERS:  *Pathname   - Name to be found, in external (ASL) format. The
  981.  *                            \ (backslash) and ^ (carat) prefixes, and the
  982.  *                            . (period) to separate segments are supported.
  983.  *              PrefixNode   - Root of subtree to be searched, or NS_ALL for the
  984.  *                            root of the name space.  If Name is fully
  985.  *                            qualified (first INT8 is '\'), the passed value
  986.  *                            of Scope will not be accessed.
  987.  *              Flags       - Used to indicate whether to perform upsearch or
  988.  *                            not.
  989.  *              ReturnNode  - Where the Node is returned
  990.  *
  991.  * DESCRIPTION: Look up a name relative to a given scope and return the
  992.  *              corresponding Node.  NOTE: Scope can be null.
  993.  *
  994.  * MUTEX:       Locks namespace
  995.  *
  996.  ******************************************************************************/
  997.  
  998. ACPI_STATUS
  999. AcpiNsGetNode (
  1000.     ACPI_NAMESPACE_NODE     *PrefixNode,
  1001.     const char              *Pathname,
  1002.     UINT32                  Flags,
  1003.     ACPI_NAMESPACE_NODE     **ReturnNode)
  1004. {
  1005.     ACPI_GENERIC_STATE      ScopeInfo;
  1006.     ACPI_STATUS             Status;
  1007.     char                    *InternalPath;
  1008.  
  1009.  
  1010.     ACPI_FUNCTION_TRACE_PTR (NsGetNode, ACPI_CAST_PTR (char, Pathname));
  1011.  
  1012.  
  1013.     if (!Pathname)
  1014.     {
  1015.         *ReturnNode = PrefixNode;
  1016.         if (!PrefixNode)
  1017.         {
  1018.             *ReturnNode = AcpiGbl_RootNode;
  1019.         }
  1020.         return_ACPI_STATUS (AE_OK);
  1021.     }
  1022.  
  1023.     /* Convert path to internal representation */
  1024.  
  1025.     Status = AcpiNsInternalizeName (Pathname, &InternalPath);
  1026.     if (ACPI_FAILURE (Status))
  1027.     {
  1028.         return_ACPI_STATUS (Status);
  1029.     }
  1030.  
  1031.     /* Must lock namespace during lookup */
  1032.  
  1033.     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
  1034.     if (ACPI_FAILURE (Status))
  1035.     {
  1036.         goto Cleanup;
  1037.     }
  1038.  
  1039.     /* Setup lookup scope (search starting point) */
  1040.  
  1041.     ScopeInfo.Scope.Node = PrefixNode;
  1042.  
  1043.     /* Lookup the name in the namespace */
  1044.  
  1045.     Status = AcpiNsLookup (&ScopeInfo, InternalPath, ACPI_TYPE_ANY,
  1046.                 ACPI_IMODE_EXECUTE, (Flags | ACPI_NS_DONT_OPEN_SCOPE),
  1047.                 NULL, ReturnNode);
  1048.     if (ACPI_FAILURE (Status))
  1049.     {
  1050.         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%s, %s\n",
  1051.                 Pathname, AcpiFormatException (Status)));
  1052.     }
  1053.  
  1054.     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
  1055.  
  1056. Cleanup:
  1057.     ACPI_FREE (InternalPath);
  1058.     return_ACPI_STATUS (Status);
  1059. }
  1060.