Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:03

0001 /******************************************************************************
0002  *
0003  * Module Name: nsutils - Utilities for accessing ACPI namespace, accessing
0004  *                        parents and siblings and Scope manipulation
0005  *
0006  *****************************************************************************/
0007 
0008 /******************************************************************************
0009  *
0010  * 1. Copyright Notice
0011  *
0012  * Some or all of this work - Copyright (c) 1999 - 2024, Intel Corp.
0013  * All rights reserved.
0014  *
0015  * 2. License
0016  *
0017  * 2.1. This is your license from Intel Corp. under its intellectual property
0018  * rights. You may have additional license terms from the party that provided
0019  * you this software, covering your right to use that party's intellectual
0020  * property rights.
0021  *
0022  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
0023  * copy of the source code appearing in this file ("Covered Code") an
0024  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
0025  * base code distributed originally by Intel ("Original Intel Code") to copy,
0026  * make derivatives, distribute, use and display any portion of the Covered
0027  * Code in any form, with the right to sublicense such rights; and
0028  *
0029  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
0030  * license (with the right to sublicense), under only those claims of Intel
0031  * patents that are infringed by the Original Intel Code, to make, use, sell,
0032  * offer to sell, and import the Covered Code and derivative works thereof
0033  * solely to the minimum extent necessary to exercise the above copyright
0034  * license, and in no event shall the patent license extend to any additions
0035  * to or modifications of the Original Intel Code. No other license or right
0036  * is granted directly or by implication, estoppel or otherwise;
0037  *
0038  * The above copyright and patent license is granted only if the following
0039  * conditions are met:
0040  *
0041  * 3. Conditions
0042  *
0043  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
0044  * Redistribution of source code of any substantial portion of the Covered
0045  * Code or modification with rights to further distribute source must include
0046  * the above Copyright Notice, the above License, this list of Conditions,
0047  * and the following Disclaimer and Export Compliance provision. In addition,
0048  * Licensee must cause all Covered Code to which Licensee contributes to
0049  * contain a file documenting the changes Licensee made to create that Covered
0050  * Code and the date of any change. Licensee must include in that file the
0051  * documentation of any changes made by any predecessor Licensee. Licensee
0052  * must include a prominent statement that the modification is derived,
0053  * directly or indirectly, from Original Intel Code.
0054  *
0055  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
0056  * Redistribution of source code of any substantial portion of the Covered
0057  * Code or modification without rights to further distribute source must
0058  * include the following Disclaimer and Export Compliance provision in the
0059  * documentation and/or other materials provided with distribution. In
0060  * addition, Licensee may not authorize further sublicense of source of any
0061  * portion of the Covered Code, and must include terms to the effect that the
0062  * license from Licensee to its licensee is limited to the intellectual
0063  * property embodied in the software Licensee provides to its licensee, and
0064  * not to intellectual property embodied in modifications its licensee may
0065  * make.
0066  *
0067  * 3.3. Redistribution of Executable. Redistribution in executable form of any
0068  * substantial portion of the Covered Code or modification must reproduce the
0069  * above Copyright Notice, and the following Disclaimer and Export Compliance
0070  * provision in the documentation and/or other materials provided with the
0071  * distribution.
0072  *
0073  * 3.4. Intel retains all right, title, and interest in and to the Original
0074  * Intel Code.
0075  *
0076  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
0077  * Intel shall be used in advertising or otherwise to promote the sale, use or
0078  * other dealings in products derived from or relating to the Covered Code
0079  * without prior written authorization from Intel.
0080  *
0081  * 4. Disclaimer and Export Compliance
0082  *
0083  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
0084  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
0085  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
0086  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
0087  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
0088  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
0089  * PARTICULAR PURPOSE.
0090  *
0091  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
0092  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
0093  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
0094  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
0095  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
0096  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
0097  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
0098  * LIMITED REMEDY.
0099  *
0100  * 4.3. Licensee shall not export, either directly or indirectly, any of this
0101  * software or system incorporating such software without first obtaining any
0102  * required license or other approval from the U. S. Department of Commerce or
0103  * any other agency or department of the United States Government. In the
0104  * event Licensee exports any such software from the United States or
0105  * re-exports any such software from a foreign destination, Licensee shall
0106  * ensure that the distribution and export/re-export of the software is in
0107  * compliance with all laws, regulations, orders, or other restrictions of the
0108  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
0109  * any of its subsidiaries will export/re-export any technical data, process,
0110  * software, or service, directly or indirectly, to any country for which the
0111  * United States government or any agency thereof requires an export license,
0112  * other governmental approval, or letter of assurance, without first obtaining
0113  * such license, approval or letter.
0114  *
0115  *****************************************************************************
0116  *
0117  * Alternatively, you may choose to be licensed under the terms of the
0118  * following license:
0119  *
0120  * Redistribution and use in source and binary forms, with or without
0121  * modification, are permitted provided that the following conditions
0122  * are met:
0123  * 1. Redistributions of source code must retain the above copyright
0124  *    notice, this list of conditions, and the following disclaimer,
0125  *    without modification.
0126  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
0127  *    substantially similar to the "NO WARRANTY" disclaimer below
0128  *    ("Disclaimer") and any redistribution must be conditioned upon
0129  *    including a substantially similar Disclaimer requirement for further
0130  *    binary redistribution.
0131  * 3. Neither the names of the above-listed copyright holders nor the names
0132  *    of any contributors may be used to endorse or promote products derived
0133  *    from this software without specific prior written permission.
0134  *
0135  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
0136  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
0137  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
0138  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
0139  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
0140  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
0141  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
0142  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
0143  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0144  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
0145  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0146  *
0147  * Alternatively, you may choose to be licensed under the terms of the
0148  * GNU General Public License ("GPL") version 2 as published by the Free
0149  * Software Foundation.
0150  *
0151  *****************************************************************************/
0152 
0153 #include "acpi.h"
0154 #include "accommon.h"
0155 #include "acnamesp.h"
0156 #include "amlcode.h"
0157 
0158 #define _COMPONENT          ACPI_NAMESPACE
0159         ACPI_MODULE_NAME    ("nsutils")
0160 
0161 /* Local prototypes */
0162 
0163 #ifdef ACPI_OBSOLETE_FUNCTIONS
0164 ACPI_NAME
0165 AcpiNsFindParentName (
0166     ACPI_NAMESPACE_NODE     *NodeToSearch);
0167 #endif
0168 
0169 
0170 /*******************************************************************************
0171  *
0172  * FUNCTION:    AcpiNsPrintNodePathname
0173  *
0174  * PARAMETERS:  Node            - Object
0175  *              Message         - Prefix message
0176  *
0177  * DESCRIPTION: Print an object's full namespace pathname
0178  *              Manages allocation/freeing of a pathname buffer
0179  *
0180  ******************************************************************************/
0181 
0182 void
0183 AcpiNsPrintNodePathname (
0184     ACPI_NAMESPACE_NODE     *Node,
0185     const char              *Message)
0186 {
0187     ACPI_BUFFER             Buffer;
0188     ACPI_STATUS             Status;
0189 
0190 
0191     if (!Node)
0192     {
0193         AcpiOsPrintf ("[NULL NAME]");
0194         return;
0195     }
0196 
0197     /* Convert handle to full pathname and print it (with supplied message) */
0198 
0199     Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
0200 
0201     Status = AcpiNsHandleToPathname (Node, &Buffer, TRUE);
0202     if (ACPI_SUCCESS (Status))
0203     {
0204         if (Message)
0205         {
0206             AcpiOsPrintf ("%s ", Message);
0207         }
0208 
0209         AcpiOsPrintf ("%s", (char *) Buffer.Pointer);
0210         ACPI_FREE (Buffer.Pointer);
0211     }
0212 }
0213 
0214 
0215 /*******************************************************************************
0216  *
0217  * FUNCTION:    AcpiNsGetType
0218  *
0219  * PARAMETERS:  Node        - Parent Node to be examined
0220  *
0221  * RETURN:      Type field from Node whose handle is passed
0222  *
0223  * DESCRIPTION: Return the type of a Namespace node
0224  *
0225  ******************************************************************************/
0226 
0227 ACPI_OBJECT_TYPE
0228 AcpiNsGetType (
0229     ACPI_NAMESPACE_NODE     *Node)
0230 {
0231     ACPI_FUNCTION_TRACE (NsGetType);
0232 
0233 
0234     if (!Node)
0235     {
0236         ACPI_WARNING ((AE_INFO, "Null Node parameter"));
0237         return_UINT8 (ACPI_TYPE_ANY);
0238     }
0239 
0240     return_UINT8 (Node->Type);
0241 }
0242 
0243 
0244 /*******************************************************************************
0245  *
0246  * FUNCTION:    AcpiNsLocal
0247  *
0248  * PARAMETERS:  Type        - A namespace object type
0249  *
0250  * RETURN:      LOCAL if names must be found locally in objects of the
0251  *              passed type, 0 if enclosing scopes should be searched
0252  *
0253  * DESCRIPTION: Returns scope rule for the given object type.
0254  *
0255  ******************************************************************************/
0256 
0257 UINT32
0258 AcpiNsLocal (
0259     ACPI_OBJECT_TYPE        Type)
0260 {
0261     ACPI_FUNCTION_TRACE (NsLocal);
0262 
0263 
0264     if (!AcpiUtValidObjectType (Type))
0265     {
0266         /* Type code out of range  */
0267 
0268         ACPI_WARNING ((AE_INFO, "Invalid Object Type 0x%X", Type));
0269         return_UINT32 (ACPI_NS_NORMAL);
0270     }
0271 
0272     return_UINT32 (AcpiGbl_NsProperties[Type] & ACPI_NS_LOCAL);
0273 }
0274 
0275 
0276 /*******************************************************************************
0277  *
0278  * FUNCTION:    AcpiNsGetInternalNameLength
0279  *
0280  * PARAMETERS:  Info            - Info struct initialized with the
0281  *                                external name pointer.
0282  *
0283  * RETURN:      None
0284  *
0285  * DESCRIPTION: Calculate the length of the internal (AML) namestring
0286  *              corresponding to the external (ASL) namestring.
0287  *
0288  ******************************************************************************/
0289 
0290 void
0291 AcpiNsGetInternalNameLength (
0292     ACPI_NAMESTRING_INFO    *Info)
0293 {
0294     const char              *NextExternalChar;
0295     UINT32                  i;
0296 
0297 
0298     ACPI_FUNCTION_ENTRY ();
0299 
0300 
0301     NextExternalChar = Info->ExternalName;
0302     Info->NumCarats = 0;
0303     Info->NumSegments = 0;
0304     Info->FullyQualified = FALSE;
0305 
0306     /*
0307      * For the internal name, the required length is 4 bytes per segment,
0308      * plus 1 each for RootPrefix, MultiNamePrefixOp, segment count,
0309      * trailing null (which is not really needed, but no there's harm in
0310      * putting it there)
0311      *
0312      * strlen() + 1 covers the first NameSeg, which has no path separator
0313      */
0314     if (ACPI_IS_ROOT_PREFIX (*NextExternalChar))
0315     {
0316         Info->FullyQualified = TRUE;
0317         NextExternalChar++;
0318 
0319         /* Skip redundant RootPrefix, like \\_SB.PCI0.SBRG.EC0 */
0320 
0321         while (ACPI_IS_ROOT_PREFIX (*NextExternalChar))
0322         {
0323             NextExternalChar++;
0324         }
0325     }
0326     else
0327     {
0328         /* Handle Carat prefixes */
0329 
0330         while (ACPI_IS_PARENT_PREFIX (*NextExternalChar))
0331         {
0332             Info->NumCarats++;
0333             NextExternalChar++;
0334         }
0335     }
0336 
0337     /*
0338      * Determine the number of ACPI name "segments" by counting the number of
0339      * path separators within the string. Start with one segment since the
0340      * segment count is [(# separators) + 1], and zero separators is ok.
0341      */
0342     if (*NextExternalChar)
0343     {
0344         Info->NumSegments = 1;
0345         for (i = 0; NextExternalChar[i]; i++)
0346         {
0347             if (ACPI_IS_PATH_SEPARATOR (NextExternalChar[i]))
0348             {
0349                 Info->NumSegments++;
0350             }
0351         }
0352     }
0353 
0354     Info->Length = (ACPI_NAMESEG_SIZE * Info->NumSegments) +
0355         4 + Info->NumCarats;
0356 
0357     Info->NextExternalChar = NextExternalChar;
0358 }
0359 
0360 
0361 /*******************************************************************************
0362  *
0363  * FUNCTION:    AcpiNsBuildInternalName
0364  *
0365  * PARAMETERS:  Info            - Info struct fully initialized
0366  *
0367  * RETURN:      Status
0368  *
0369  * DESCRIPTION: Construct the internal (AML) namestring
0370  *              corresponding to the external (ASL) namestring.
0371  *
0372  ******************************************************************************/
0373 
0374 ACPI_STATUS
0375 AcpiNsBuildInternalName (
0376     ACPI_NAMESTRING_INFO    *Info)
0377 {
0378     UINT32                  NumSegments = Info->NumSegments;
0379     char                    *InternalName = Info->InternalName;
0380     const char              *ExternalName = Info->NextExternalChar;
0381     char                    *Result = NULL;
0382     UINT32                  i;
0383 
0384 
0385     ACPI_FUNCTION_TRACE (NsBuildInternalName);
0386 
0387 
0388     /* Setup the correct prefixes, counts, and pointers */
0389 
0390     if (Info->FullyQualified)
0391     {
0392         InternalName[0] = AML_ROOT_PREFIX;
0393 
0394         if (NumSegments <= 1)
0395         {
0396             Result = &InternalName[1];
0397         }
0398         else if (NumSegments == 2)
0399         {
0400             InternalName[1] = AML_DUAL_NAME_PREFIX;
0401             Result = &InternalName[2];
0402         }
0403         else
0404         {
0405             InternalName[1] = AML_MULTI_NAME_PREFIX;
0406             InternalName[2] = (char) NumSegments;
0407             Result = &InternalName[3];
0408         }
0409     }
0410     else
0411     {
0412         /*
0413          * Not fully qualified.
0414          * Handle Carats first, then append the name segments
0415          */
0416         i = 0;
0417         if (Info->NumCarats)
0418         {
0419             for (i = 0; i < Info->NumCarats; i++)
0420             {
0421                 InternalName[i] = AML_PARENT_PREFIX;
0422             }
0423         }
0424 
0425         if (NumSegments <= 1)
0426         {
0427             Result = &InternalName[i];
0428         }
0429         else if (NumSegments == 2)
0430         {
0431             InternalName[i] = AML_DUAL_NAME_PREFIX;
0432             Result = &InternalName[(ACPI_SIZE) i+1];
0433         }
0434         else
0435         {
0436             InternalName[i] = AML_MULTI_NAME_PREFIX;
0437             InternalName[(ACPI_SIZE) i+1] = (char) NumSegments;
0438             Result = &InternalName[(ACPI_SIZE) i+2];
0439         }
0440     }
0441 
0442     /* Build the name (minus path separators) */
0443 
0444     for (; NumSegments; NumSegments--)
0445     {
0446         for (i = 0; i < ACPI_NAMESEG_SIZE; i++)
0447         {
0448             if (ACPI_IS_PATH_SEPARATOR (*ExternalName) ||
0449                (*ExternalName == 0))
0450             {
0451                 /* Pad the segment with underscore(s) if segment is short */
0452 
0453                 Result[i] = '_';
0454             }
0455             else
0456             {
0457                 /* Convert the character to uppercase and save it */
0458 
0459                 Result[i] = (char) toupper ((int) *ExternalName);
0460                 ExternalName++;
0461             }
0462         }
0463 
0464         /* Now we must have a path separator, or the pathname is bad */
0465 
0466         if (!ACPI_IS_PATH_SEPARATOR (*ExternalName) &&
0467             (*ExternalName != 0))
0468         {
0469             return_ACPI_STATUS (AE_BAD_PATHNAME);
0470         }
0471 
0472         /* Move on the next segment */
0473 
0474         ExternalName++;
0475         Result += ACPI_NAMESEG_SIZE;
0476     }
0477 
0478     /* Terminate the string */
0479 
0480     *Result = 0;
0481 
0482     if (Info->FullyQualified)
0483     {
0484         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Returning [%p] (abs) \"\\%s\"\n",
0485             InternalName, InternalName));
0486     }
0487     else
0488     {
0489         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Returning [%p] (rel) \"%s\"\n",
0490             InternalName, InternalName));
0491     }
0492 
0493     return_ACPI_STATUS (AE_OK);
0494 }
0495 
0496 
0497 /*******************************************************************************
0498  *
0499  * FUNCTION:    AcpiNsInternalizeName
0500  *
0501  * PARAMETERS:  *ExternalName           - External representation of name
0502  *              **Converted Name        - Where to return the resulting
0503  *                                        internal representation of the name
0504  *
0505  * RETURN:      Status
0506  *
0507  * DESCRIPTION: Convert an external representation (e.g. "\_PR_.CPU0")
0508  *              to internal form (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30)
0509  *
0510  *******************************************************************************/
0511 
0512 ACPI_STATUS
0513 AcpiNsInternalizeName (
0514     const char              *ExternalName,
0515     char                    **ConvertedName)
0516 {
0517     char                    *InternalName;
0518     ACPI_NAMESTRING_INFO    Info;
0519     ACPI_STATUS             Status;
0520 
0521 
0522     ACPI_FUNCTION_TRACE (NsInternalizeName);
0523 
0524 
0525     if ((!ExternalName)      ||
0526         (*ExternalName == 0) ||
0527         (!ConvertedName))
0528     {
0529         return_ACPI_STATUS (AE_BAD_PARAMETER);
0530     }
0531 
0532     /* Get the length of the new internal name */
0533 
0534     Info.ExternalName = ExternalName;
0535     AcpiNsGetInternalNameLength (&Info);
0536 
0537     /* We need a segment to store the internal  name */
0538 
0539     InternalName = ACPI_ALLOCATE_ZEROED (Info.Length);
0540     if (!InternalName)
0541     {
0542         return_ACPI_STATUS (AE_NO_MEMORY);
0543     }
0544 
0545     /* Build the name */
0546 
0547     Info.InternalName = InternalName;
0548     Status = AcpiNsBuildInternalName (&Info);
0549     if (ACPI_FAILURE (Status))
0550     {
0551         ACPI_FREE (InternalName);
0552         return_ACPI_STATUS (Status);
0553     }
0554 
0555     *ConvertedName = InternalName;
0556     return_ACPI_STATUS (AE_OK);
0557 }
0558 
0559 
0560 /*******************************************************************************
0561  *
0562  * FUNCTION:    AcpiNsExternalizeName
0563  *
0564  * PARAMETERS:  InternalNameLength  - Length of the internal name below
0565  *              InternalName        - Internal representation of name
0566  *              ConvertedNameLength - Where the length is returned
0567  *              ConvertedName       - Where the resulting external name
0568  *                                    is returned
0569  *
0570  * RETURN:      Status
0571  *
0572  * DESCRIPTION: Convert internal name (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30)
0573  *              to its external (printable) form (e.g. "\_PR_.CPU0")
0574  *
0575  ******************************************************************************/
0576 
0577 ACPI_STATUS
0578 AcpiNsExternalizeName (
0579     UINT32                  InternalNameLength,
0580     const char              *InternalName,
0581     UINT32                  *ConvertedNameLength,
0582     char                    **ConvertedName)
0583 {
0584     UINT32                  NamesIndex = 0;
0585     UINT32                  NumSegments = 0;
0586     UINT32                  RequiredLength;
0587     UINT32                  PrefixLength = 0;
0588     UINT32                  i = 0;
0589     UINT32                  j = 0;
0590 
0591 
0592     ACPI_FUNCTION_TRACE (NsExternalizeName);
0593 
0594 
0595     if (!InternalNameLength     ||
0596         !InternalName           ||
0597         !ConvertedName)
0598     {
0599         return_ACPI_STATUS (AE_BAD_PARAMETER);
0600     }
0601 
0602     /* Check for a prefix (one '\' | one or more '^') */
0603 
0604     switch (InternalName[0])
0605     {
0606     case AML_ROOT_PREFIX:
0607 
0608         PrefixLength = 1;
0609         break;
0610 
0611     case AML_PARENT_PREFIX:
0612 
0613         for (i = 0; i < InternalNameLength; i++)
0614         {
0615             if (ACPI_IS_PARENT_PREFIX (InternalName[i]))
0616             {
0617                 PrefixLength = i + 1;
0618             }
0619             else
0620             {
0621                 break;
0622             }
0623         }
0624 
0625         if (i == InternalNameLength)
0626         {
0627             PrefixLength = i;
0628         }
0629 
0630         break;
0631 
0632     default:
0633 
0634         break;
0635     }
0636 
0637     /*
0638      * Check for object names. Note that there could be 0-255 of these
0639      * 4-byte elements.
0640      */
0641     if (PrefixLength < InternalNameLength)
0642     {
0643         switch (InternalName[PrefixLength])
0644         {
0645         case AML_MULTI_NAME_PREFIX:
0646 
0647             /* <count> 4-byte names */
0648 
0649             NamesIndex = PrefixLength + 2;
0650             NumSegments = (UINT8)
0651                 InternalName[(ACPI_SIZE) PrefixLength + 1];
0652             break;
0653 
0654         case AML_DUAL_NAME_PREFIX:
0655 
0656             /* Two 4-byte names */
0657 
0658             NamesIndex = PrefixLength + 1;
0659             NumSegments = 2;
0660             break;
0661 
0662         case 0:
0663 
0664             /* NullName */
0665 
0666             NamesIndex = 0;
0667             NumSegments = 0;
0668             break;
0669 
0670         default:
0671 
0672             /* one 4-byte name */
0673 
0674             NamesIndex = PrefixLength;
0675             NumSegments = 1;
0676             break;
0677         }
0678     }
0679 
0680     /*
0681      * Calculate the length of ConvertedName, which equals the length
0682      * of the prefix, length of all object names, length of any required
0683      * punctuation ('.') between object names, plus the NULL terminator.
0684      */
0685     RequiredLength = PrefixLength + (4 * NumSegments) +
0686         ((NumSegments > 0) ? (NumSegments - 1) : 0) + 1;
0687 
0688     /*
0689      * Check to see if we're still in bounds. If not, there's a problem
0690      * with InternalName (invalid format).
0691      */
0692     if (RequiredLength > InternalNameLength)
0693     {
0694         ACPI_ERROR ((AE_INFO, "Invalid internal name"));
0695         return_ACPI_STATUS (AE_BAD_PATHNAME);
0696     }
0697 
0698     /* Build the ConvertedName */
0699 
0700     *ConvertedName = ACPI_ALLOCATE_ZEROED (RequiredLength);
0701     if (!(*ConvertedName))
0702     {
0703         return_ACPI_STATUS (AE_NO_MEMORY);
0704     }
0705 
0706     j = 0;
0707 
0708     for (i = 0; i < PrefixLength; i++)
0709     {
0710         (*ConvertedName)[j++] = InternalName[i];
0711     }
0712 
0713     if (NumSegments > 0)
0714     {
0715         for (i = 0; i < NumSegments; i++)
0716         {
0717             if (i > 0)
0718             {
0719                 (*ConvertedName)[j++] = '.';
0720             }
0721 
0722             /* Copy and validate the 4-char name segment */
0723 
0724             ACPI_COPY_NAMESEG (&(*ConvertedName)[j],
0725                 &InternalName[NamesIndex]);
0726             AcpiUtRepairName (&(*ConvertedName)[j]);
0727 
0728             j += ACPI_NAMESEG_SIZE;
0729             NamesIndex += ACPI_NAMESEG_SIZE;
0730         }
0731     }
0732 
0733     if (ConvertedNameLength)
0734     {
0735         *ConvertedNameLength = (UINT32) RequiredLength;
0736     }
0737 
0738     return_ACPI_STATUS (AE_OK);
0739 }
0740 
0741 
0742 /*******************************************************************************
0743  *
0744  * FUNCTION:    AcpiNsValidateHandle
0745  *
0746  * PARAMETERS:  Handle          - Handle to be validated and typecast to a
0747  *                                namespace node.
0748  *
0749  * RETURN:      A pointer to a namespace node
0750  *
0751  * DESCRIPTION: Convert a namespace handle to a namespace node. Handles special
0752  *              cases for the root node.
0753  *
0754  * NOTE: Real integer handles would allow for more verification
0755  *       and keep all pointers within this subsystem - however this introduces
0756  *       more overhead and has not been necessary to this point. Drivers
0757  *       holding handles are typically notified before a node becomes invalid
0758  *       due to a table unload.
0759  *
0760  ******************************************************************************/
0761 
0762 ACPI_NAMESPACE_NODE *
0763 AcpiNsValidateHandle (
0764     ACPI_HANDLE             Handle)
0765 {
0766 
0767     ACPI_FUNCTION_ENTRY ();
0768 
0769 
0770     /* Parameter validation */
0771 
0772     if ((!Handle) || (Handle == ACPI_ROOT_OBJECT))
0773     {
0774         return (AcpiGbl_RootNode);
0775     }
0776 
0777     /* We can at least attempt to verify the handle */
0778 
0779     if (ACPI_GET_DESCRIPTOR_TYPE (Handle) != ACPI_DESC_TYPE_NAMED)
0780     {
0781         return (NULL);
0782     }
0783 
0784     return (ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Handle));
0785 }
0786 
0787 
0788 /*******************************************************************************
0789  *
0790  * FUNCTION:    AcpiNsTerminate
0791  *
0792  * PARAMETERS:  none
0793  *
0794  * RETURN:      none
0795  *
0796  * DESCRIPTION: free memory allocated for namespace and ACPI table storage.
0797  *
0798  ******************************************************************************/
0799 
0800 void
0801 AcpiNsTerminate (
0802     void)
0803 {
0804     ACPI_STATUS             Status;
0805 
0806 
0807     ACPI_FUNCTION_TRACE (NsTerminate);
0808 
0809 
0810     /*
0811      * Free the entire namespace -- all nodes and all objects
0812      * attached to the nodes
0813      */
0814     AcpiNsDeleteNamespaceSubtree (AcpiGbl_RootNode);
0815 
0816     /* Delete any objects attached to the root node */
0817 
0818     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
0819     if (ACPI_FAILURE (Status))
0820     {
0821         return_VOID;
0822     }
0823 
0824     AcpiNsDeleteNode (AcpiGbl_RootNode);
0825     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
0826 
0827     ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Namespace freed\n"));
0828     return_VOID;
0829 }
0830 
0831 
0832 /*******************************************************************************
0833  *
0834  * FUNCTION:    AcpiNsOpensScope
0835  *
0836  * PARAMETERS:  Type        - A valid namespace type
0837  *
0838  * RETURN:      NEWSCOPE if the passed type "opens a name scope" according
0839  *              to the ACPI specification, else 0
0840  *
0841  ******************************************************************************/
0842 
0843 UINT32
0844 AcpiNsOpensScope (
0845     ACPI_OBJECT_TYPE        Type)
0846 {
0847     ACPI_FUNCTION_ENTRY ();
0848 
0849 
0850     if (Type > ACPI_TYPE_LOCAL_MAX)
0851     {
0852         /* type code out of range  */
0853 
0854         ACPI_WARNING ((AE_INFO, "Invalid Object Type 0x%X", Type));
0855         return (ACPI_NS_NORMAL);
0856     }
0857 
0858     return (((UINT32) AcpiGbl_NsProperties[Type]) & ACPI_NS_NEWSCOPE);
0859 }
0860 
0861 
0862 /*******************************************************************************
0863  *
0864  * FUNCTION:    AcpiNsGetNodeUnlocked
0865  *
0866  * PARAMETERS:  *Pathname   - Name to be found, in external (ASL) format. The
0867  *                            \ (backslash) and ^ (carat) prefixes, and the
0868  *                            . (period) to separate segments are supported.
0869  *              PrefixNode   - Root of subtree to be searched, or NS_ALL for the
0870  *                            root of the name space. If Name is fully
0871  *                            qualified (first INT8 is '\'), the passed value
0872  *                            of Scope will not be accessed.
0873  *              Flags       - Used to indicate whether to perform upsearch or
0874  *                            not.
0875  *              ReturnNode  - Where the Node is returned
0876  *
0877  * DESCRIPTION: Look up a name relative to a given scope and return the
0878  *              corresponding Node. NOTE: Scope can be null.
0879  *
0880  * MUTEX:       Doesn't locks namespace
0881  *
0882  ******************************************************************************/
0883 
0884 ACPI_STATUS
0885 AcpiNsGetNodeUnlocked (
0886     ACPI_NAMESPACE_NODE     *PrefixNode,
0887     const char              *Pathname,
0888     UINT32                  Flags,
0889     ACPI_NAMESPACE_NODE     **ReturnNode)
0890 {
0891     ACPI_GENERIC_STATE      ScopeInfo;
0892     ACPI_STATUS             Status;
0893     char                    *InternalPath;
0894 
0895 
0896     ACPI_FUNCTION_TRACE_PTR (NsGetNodeUnlocked, ACPI_CAST_PTR (char, Pathname));
0897 
0898 
0899     /* Simplest case is a null pathname */
0900 
0901     if (!Pathname)
0902     {
0903         *ReturnNode = PrefixNode;
0904         if (!PrefixNode)
0905         {
0906             *ReturnNode = AcpiGbl_RootNode;
0907         }
0908 
0909         return_ACPI_STATUS (AE_OK);
0910     }
0911 
0912     /* Quick check for a reference to the root */
0913 
0914     if (ACPI_IS_ROOT_PREFIX (Pathname[0]) && (!Pathname[1]))
0915     {
0916         *ReturnNode = AcpiGbl_RootNode;
0917         return_ACPI_STATUS (AE_OK);
0918     }
0919 
0920     /* Convert path to internal representation */
0921 
0922     Status = AcpiNsInternalizeName (Pathname, &InternalPath);
0923     if (ACPI_FAILURE (Status))
0924     {
0925         return_ACPI_STATUS (Status);
0926     }
0927 
0928     /* Setup lookup scope (search starting point) */
0929 
0930     ScopeInfo.Scope.Node = PrefixNode;
0931 
0932     /* Lookup the name in the namespace */
0933 
0934     Status = AcpiNsLookup (&ScopeInfo, InternalPath, ACPI_TYPE_ANY,
0935         ACPI_IMODE_EXECUTE, (Flags | ACPI_NS_DONT_OPEN_SCOPE),
0936         NULL, ReturnNode);
0937     if (ACPI_FAILURE (Status))
0938     {
0939         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%s, %s\n",
0940             Pathname, AcpiFormatException (Status)));
0941     }
0942 
0943     ACPI_FREE (InternalPath);
0944     return_ACPI_STATUS (Status);
0945 }
0946 
0947 
0948 /*******************************************************************************
0949  *
0950  * FUNCTION:    AcpiNsGetNode
0951  *
0952  * PARAMETERS:  *Pathname   - Name to be found, in external (ASL) format. The
0953  *                            \ (backslash) and ^ (carat) prefixes, and the
0954  *                            . (period) to separate segments are supported.
0955  *              PrefixNode   - Root of subtree to be searched, or NS_ALL for the
0956  *                            root of the name space. If Name is fully
0957  *                            qualified (first INT8 is '\'), the passed value
0958  *                            of Scope will not be accessed.
0959  *              Flags       - Used to indicate whether to perform upsearch or
0960  *                            not.
0961  *              ReturnNode  - Where the Node is returned
0962  *
0963  * DESCRIPTION: Look up a name relative to a given scope and return the
0964  *              corresponding Node. NOTE: Scope can be null.
0965  *
0966  * MUTEX:       Locks namespace
0967  *
0968  ******************************************************************************/
0969 
0970 ACPI_STATUS
0971 AcpiNsGetNode (
0972     ACPI_NAMESPACE_NODE     *PrefixNode,
0973     const char              *Pathname,
0974     UINT32                  Flags,
0975     ACPI_NAMESPACE_NODE     **ReturnNode)
0976 {
0977     ACPI_STATUS             Status;
0978 
0979 
0980     ACPI_FUNCTION_TRACE_PTR (NsGetNode, ACPI_CAST_PTR (char, Pathname));
0981 
0982 
0983     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
0984     if (ACPI_FAILURE (Status))
0985     {
0986         return_ACPI_STATUS (Status);
0987     }
0988 
0989     Status = AcpiNsGetNodeUnlocked (PrefixNode, Pathname,
0990         Flags, ReturnNode);
0991 
0992     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
0993     return_ACPI_STATUS (Status);
0994 }