Print this page
update to acpica-unix2-20131115
acpica-unix2-20130823
PANKOVs restructure
   1 /******************************************************************************
   2  *
   3  * Module Name: nsutils - Utilities for accessing ACPI namespace, accessing
   4  *                        parents and siblings and Scope manipulation
   5  *
   6  *****************************************************************************/
   7 
   8 /*
   9  * Copyright (C) 2000 - 2011, Intel Corp.
  10  * All rights reserved.
  11  *
  12  * Redistribution and use in source and binary forms, with or without
  13  * modification, are permitted provided that the following conditions
  14  * are met:
  15  * 1. Redistributions of source code must retain the above copyright
  16  *    notice, this list of conditions, and the following disclaimer,
  17  *    without modification.
  18  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
  19  *    substantially similar to the "NO WARRANTY" disclaimer below
  20  *    ("Disclaimer") and any redistribution must be conditioned upon
  21  *    including a substantially similar Disclaimer requirement for further
  22  *    binary redistribution.
  23  * 3. Neither the names of the above-listed copyright holders nor the names
  24  *    of any contributors may be used to endorse or promote products derived
  25  *    from this software without specific prior written permission.
  26  *
  27  * Alternatively, this software may be distributed under the terms of the
  28  * GNU General Public License ("GPL") version 2 as published by the Free
  29  * Software Foundation.


  37  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  38  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  39  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  40  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  41  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  42  * POSSIBILITY OF SUCH DAMAGES.
  43  */
  44 
  45 #define __NSUTILS_C__
  46 
  47 #include "acpi.h"
  48 #include "accommon.h"
  49 #include "acnamesp.h"
  50 #include "amlcode.h"
  51 
  52 #define _COMPONENT          ACPI_NAMESPACE
  53         ACPI_MODULE_NAME    ("nsutils")
  54 
  55 /* Local prototypes */
  56 
  57 static BOOLEAN
  58 AcpiNsValidPathSeparator (
  59     char                    Sep);
  60 
  61 #ifdef ACPI_OBSOLETE_FUNCTIONS
  62 ACPI_NAME
  63 AcpiNsFindParentName (
  64     ACPI_NAMESPACE_NODE     *NodeToSearch);
  65 #endif
  66 
  67 
  68 /*******************************************************************************
  69  *
  70  * FUNCTION:    AcpiNsPrintNodePathname
  71  *
  72  * PARAMETERS:  Node            - Object
  73  *              Message         - Prefix message
  74  *
  75  * DESCRIPTION: Print an object's full namespace pathname
  76  *              Manages allocation/freeing of a pathname buffer
  77  *
  78  ******************************************************************************/
  79 
  80 void


  95     /* Convert handle to full pathname and print it (with supplied message) */
  96 
  97     Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
  98 
  99     Status = AcpiNsHandleToPathname (Node, &Buffer);
 100     if (ACPI_SUCCESS (Status))
 101     {
 102         if (Message)
 103         {
 104             AcpiOsPrintf ("%s ", Message);
 105         }
 106 
 107         AcpiOsPrintf ("[%s] (Node %p)", (char *) Buffer.Pointer, Node);
 108         ACPI_FREE (Buffer.Pointer);
 109     }
 110 }
 111 
 112 
 113 /*******************************************************************************
 114  *
 115  * FUNCTION:    AcpiNsValidRootPrefix
 116  *
 117  * PARAMETERS:  Prefix          - Character to be checked
 118  *
 119  * RETURN:      TRUE if a valid prefix
 120  *
 121  * DESCRIPTION: Check if a character is a valid ACPI Root prefix
 122  *
 123  ******************************************************************************/
 124 
 125 BOOLEAN
 126 AcpiNsValidRootPrefix (
 127     char                    Prefix)
 128 {
 129 
 130     return ((BOOLEAN) (Prefix == '\\'));
 131 }
 132 
 133 
 134 /*******************************************************************************
 135  *
 136  * FUNCTION:    AcpiNsValidPathSeparator
 137  *
 138  * PARAMETERS:  Sep         - Character to be checked
 139  *
 140  * RETURN:      TRUE if a valid path separator
 141  *
 142  * DESCRIPTION: Check if a character is a valid ACPI path separator
 143  *
 144  ******************************************************************************/
 145 
 146 static BOOLEAN
 147 AcpiNsValidPathSeparator (
 148     char                    Sep)
 149 {
 150 
 151     return ((BOOLEAN) (Sep == '.'));
 152 }
 153 
 154 
 155 /*******************************************************************************
 156  *
 157  * FUNCTION:    AcpiNsGetType
 158  *
 159  * PARAMETERS:  Node        - Parent Node to be examined
 160  *
 161  * RETURN:      Type field from Node whose handle is passed
 162  *
 163  * DESCRIPTION: Return the type of a Namespace node
 164  *
 165  ******************************************************************************/
 166 
 167 ACPI_OBJECT_TYPE
 168 AcpiNsGetType (
 169     ACPI_NAMESPACE_NODE     *Node)
 170 {
 171     ACPI_FUNCTION_TRACE (NsGetType);
 172 
 173 
 174     if (!Node)
 175     {
 176         ACPI_WARNING ((AE_INFO, "Null Node parameter"));
 177         return_UINT32 (ACPI_TYPE_ANY);
 178     }
 179 
 180     return_UINT32 ((ACPI_OBJECT_TYPE) Node->Type);
 181 }
 182 
 183 
 184 /*******************************************************************************
 185  *
 186  * FUNCTION:    AcpiNsLocal
 187  *
 188  * PARAMETERS:  Type        - A namespace object type
 189  *
 190  * RETURN:      LOCAL if names must be found locally in objects of the
 191  *              passed type, 0 if enclosing scopes should be searched
 192  *
 193  * DESCRIPTION: Returns scope rule for the given object type.
 194  *
 195  ******************************************************************************/
 196 
 197 UINT32
 198 AcpiNsLocal (
 199     ACPI_OBJECT_TYPE        Type)
 200 {
 201     ACPI_FUNCTION_TRACE (NsLocal);
 202 
 203 
 204     if (!AcpiUtValidObjectType (Type))
 205     {
 206         /* Type code out of range  */
 207 
 208         ACPI_WARNING ((AE_INFO, "Invalid Object Type 0x%X", Type));
 209         return_UINT32 (ACPI_NS_NORMAL);
 210     }
 211 
 212     return_UINT32 ((UINT32) AcpiGbl_NsProperties[Type] & ACPI_NS_LOCAL);
 213 }
 214 
 215 
 216 /*******************************************************************************
 217  *
 218  * FUNCTION:    AcpiNsGetInternalNameLength
 219  *
 220  * PARAMETERS:  Info            - Info struct initialized with the
 221  *                                external name pointer.
 222  *
 223  * RETURN:      None
 224  *
 225  * DESCRIPTION: Calculate the length of the internal (AML) namestring
 226  *              corresponding to the external (ASL) namestring.
 227  *
 228  ******************************************************************************/
 229 
 230 void
 231 AcpiNsGetInternalNameLength (
 232     ACPI_NAMESTRING_INFO    *Info)
 233 {
 234     const char              *NextExternalChar;
 235     UINT32                  i;
 236 
 237 
 238     ACPI_FUNCTION_ENTRY ();
 239 
 240 
 241     NextExternalChar = Info->ExternalName;
 242     Info->NumCarats = 0;
 243     Info->NumSegments = 0;
 244     Info->FullyQualified = FALSE;
 245 
 246     /*
 247      * For the internal name, the required length is 4 bytes per segment, plus
 248      * 1 each for RootPrefix, MultiNamePrefixOp, segment count, trailing null
 249      * (which is not really needed, but no there's harm in putting it there)
 250      *
 251      * strlen() + 1 covers the first NameSeg, which has no path separator
 252      */
 253     if (AcpiNsValidRootPrefix (*NextExternalChar))
 254     {
 255         Info->FullyQualified = TRUE;
 256         NextExternalChar++;
 257 
 258         /* Skip redundant RootPrefix, like \\_SB.PCI0.SBRG.EC0 */
 259 
 260         while (AcpiNsValidRootPrefix (*NextExternalChar))
 261         {
 262             NextExternalChar++;
 263         }
 264     }
 265     else
 266     {
 267         /* Handle Carat prefixes */
 268 
 269         while (*NextExternalChar == '^')
 270         {
 271             Info->NumCarats++;
 272             NextExternalChar++;
 273         }
 274     }
 275 
 276     /*
 277      * Determine the number of ACPI name "segments" by counting the number of
 278      * path separators within the string. Start with one segment since the
 279      * segment count is [(# separators) + 1], and zero separators is ok.
 280      */
 281     if (*NextExternalChar)
 282     {
 283         Info->NumSegments = 1;
 284         for (i = 0; NextExternalChar[i]; i++)
 285         {
 286             if (AcpiNsValidPathSeparator (NextExternalChar[i]))
 287             {
 288                 Info->NumSegments++;
 289             }
 290         }
 291     }
 292 
 293     Info->Length = (ACPI_NAME_SIZE * Info->NumSegments) +
 294                     4 + Info->NumCarats;
 295 
 296     Info->NextExternalChar = NextExternalChar;
 297 }
 298 
 299 
 300 /*******************************************************************************
 301  *
 302  * FUNCTION:    AcpiNsBuildInternalName
 303  *
 304  * PARAMETERS:  Info            - Info struct fully initialized
 305  *
 306  * RETURN:      Status


 311  ******************************************************************************/
 312 
 313 ACPI_STATUS
 314 AcpiNsBuildInternalName (
 315     ACPI_NAMESTRING_INFO    *Info)
 316 {
 317     UINT32                  NumSegments = Info->NumSegments;
 318     char                    *InternalName = Info->InternalName;
 319     const char              *ExternalName = Info->NextExternalChar;
 320     char                    *Result = NULL;
 321     UINT32                  i;
 322 
 323 
 324     ACPI_FUNCTION_TRACE (NsBuildInternalName);
 325 
 326 
 327     /* Setup the correct prefixes, counts, and pointers */
 328 
 329     if (Info->FullyQualified)
 330     {
 331         InternalName[0] = '\\';
 332 
 333         if (NumSegments <= 1)
 334         {
 335             Result = &InternalName[1];
 336         }
 337         else if (NumSegments == 2)
 338         {
 339             InternalName[1] = AML_DUAL_NAME_PREFIX;
 340             Result = &InternalName[2];
 341         }
 342         else
 343         {
 344             InternalName[1] = AML_MULTI_NAME_PREFIX_OP;
 345             InternalName[2] = (char) NumSegments;
 346             Result = &InternalName[3];
 347         }
 348     }
 349     else
 350     {
 351         /*
 352          * Not fully qualified.
 353          * Handle Carats first, then append the name segments
 354          */
 355         i = 0;
 356         if (Info->NumCarats)
 357         {
 358             for (i = 0; i < Info->NumCarats; i++)
 359             {
 360                 InternalName[i] = '^';
 361             }
 362         }
 363 
 364         if (NumSegments <= 1)
 365         {
 366             Result = &InternalName[i];
 367         }
 368         else if (NumSegments == 2)
 369         {
 370             InternalName[i] = AML_DUAL_NAME_PREFIX;
 371             Result = &InternalName[(ACPI_SIZE) i+1];
 372         }
 373         else
 374         {
 375             InternalName[i] = AML_MULTI_NAME_PREFIX_OP;
 376             InternalName[(ACPI_SIZE) i+1] = (char) NumSegments;
 377             Result = &InternalName[(ACPI_SIZE) i+2];
 378         }
 379     }
 380 
 381     /* Build the name (minus path separators) */
 382 
 383     for (; NumSegments; NumSegments--)
 384     {
 385         for (i = 0; i < ACPI_NAME_SIZE; i++)
 386         {
 387             if (AcpiNsValidPathSeparator (*ExternalName) ||
 388                (*ExternalName == 0))
 389             {
 390                 /* Pad the segment with underscore(s) if segment is short */
 391 
 392                 Result[i] = '_';
 393             }
 394             else
 395             {
 396                 /* Convert the character to uppercase and save it */
 397 
 398                 Result[i] = (char) ACPI_TOUPPER ((int) *ExternalName);
 399                 ExternalName++;
 400             }
 401         }
 402 
 403         /* Now we must have a path separator, or the pathname is bad */
 404 
 405         if (!AcpiNsValidPathSeparator (*ExternalName) &&
 406             (*ExternalName != 0))
 407         {
 408             return_ACPI_STATUS (AE_BAD_PARAMETER);
 409         }
 410 
 411         /* Move on the next segment */
 412 
 413         ExternalName++;
 414         Result += ACPI_NAME_SIZE;
 415     }
 416 
 417     /* Terminate the string */
 418 
 419     *Result = 0;
 420 
 421     if (Info->FullyQualified)
 422     {
 423         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Returning [%p] (abs) \"\\%s\"\n",
 424             InternalName, InternalName));
 425     }
 426     else
 427     {
 428         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Returning [%p] (rel) \"%s\"\n",


 525     UINT32                  RequiredLength;
 526     UINT32                  PrefixLength = 0;
 527     UINT32                  i = 0;
 528     UINT32                  j = 0;
 529 
 530 
 531     ACPI_FUNCTION_TRACE (NsExternalizeName);
 532 
 533 
 534     if (!InternalNameLength     ||
 535         !InternalName           ||
 536         !ConvertedName)
 537     {
 538         return_ACPI_STATUS (AE_BAD_PARAMETER);
 539     }
 540 
 541     /* Check for a prefix (one '\' | one or more '^') */
 542 
 543     switch (InternalName[0])
 544     {
 545     case '\\':

 546         PrefixLength = 1;
 547         break;
 548 
 549     case '^':

 550         for (i = 0; i < InternalNameLength; i++)
 551         {
 552             if (InternalName[i] == '^')
 553             {
 554                 PrefixLength = i + 1;
 555             }
 556             else
 557             {
 558                 break;
 559             }
 560         }
 561 
 562         if (i == InternalNameLength)
 563         {
 564             PrefixLength = i;
 565         }
 566 
 567         break;
 568 
 569     default:

 570         break;
 571     }
 572 
 573     /*
 574      * Check for object names. Note that there could be 0-255 of these
 575      * 4-byte elements.
 576      */
 577     if (PrefixLength < InternalNameLength)
 578     {
 579         switch (InternalName[PrefixLength])
 580         {
 581         case AML_MULTI_NAME_PREFIX_OP:
 582 
 583             /* <count> 4-byte names */
 584 
 585             NamesIndex = PrefixLength + 2;
 586             NumSegments = (UINT8)
 587                 InternalName[(ACPI_SIZE) PrefixLength + 1];
 588             break;
 589 


 638     {
 639         return_ACPI_STATUS (AE_NO_MEMORY);
 640     }
 641 
 642     j = 0;
 643 
 644     for (i = 0; i < PrefixLength; i++)
 645     {
 646         (*ConvertedName)[j++] = InternalName[i];
 647     }
 648 
 649     if (NumSegments > 0)
 650     {
 651         for (i = 0; i < NumSegments; i++)
 652         {
 653             if (i > 0)
 654             {
 655                 (*ConvertedName)[j++] = '.';
 656             }
 657 
 658             (*ConvertedName)[j++] = InternalName[NamesIndex++];
 659             (*ConvertedName)[j++] = InternalName[NamesIndex++];
 660             (*ConvertedName)[j++] = InternalName[NamesIndex++];
 661             (*ConvertedName)[j++] = InternalName[NamesIndex++];



 662         }
 663     }
 664 
 665     if (ConvertedNameLength)
 666     {
 667         *ConvertedNameLength = (UINT32) RequiredLength;
 668     }
 669 
 670     return_ACPI_STATUS (AE_OK);
 671 }
 672 
 673 
 674 /*******************************************************************************
 675  *
 676  * FUNCTION:    AcpiNsValidateHandle
 677  *
 678  * PARAMETERS:  Handle          - Handle to be validated and typecast to a
 679  *                                namespace node.
 680  *
 681  * RETURN:      A pointer to a namespace node


 716     return (ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Handle));
 717 }
 718 
 719 
 720 /*******************************************************************************
 721  *
 722  * FUNCTION:    AcpiNsTerminate
 723  *
 724  * PARAMETERS:  none
 725  *
 726  * RETURN:      none
 727  *
 728  * DESCRIPTION: free memory allocated for namespace and ACPI table storage.
 729  *
 730  ******************************************************************************/
 731 
 732 void
 733 AcpiNsTerminate (
 734     void)
 735 {
 736     ACPI_OPERAND_OBJECT     *ObjDesc;
 737 
 738 
 739     ACPI_FUNCTION_TRACE (NsTerminate);
 740 
 741 
 742     /*
 743      * 1) Free the entire namespace -- all nodes and objects
 744      *
 745      * Delete all object descriptors attached to namepsace nodes
 746      */
 747     AcpiNsDeleteNamespaceSubtree (AcpiGbl_RootNode);
 748 
 749     /* Detach any objects attached to the root */
 750 
 751     ObjDesc = AcpiNsGetAttachedObject (AcpiGbl_RootNode);
 752     if (ObjDesc)
 753     {
 754         AcpiNsDetachObject (AcpiGbl_RootNode);
 755     }
 756 



 757     ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Namespace freed\n"));
 758     return_VOID;
 759 }
 760 
 761 
 762 /*******************************************************************************
 763  *
 764  * FUNCTION:    AcpiNsOpensScope
 765  *
 766  * PARAMETERS:  Type        - A valid namespace type
 767  *
 768  * RETURN:      NEWSCOPE if the passed type "opens a name scope" according
 769  *              to the ACPI specification, else 0
 770  *
 771  ******************************************************************************/
 772 
 773 UINT32
 774 AcpiNsOpensScope (
 775     ACPI_OBJECT_TYPE        Type)
 776 {
 777     ACPI_FUNCTION_TRACE_STR (NsOpensScope, AcpiUtGetTypeName (Type));
 778 
 779 
 780     if (!AcpiUtValidObjectType (Type))
 781     {
 782         /* type code out of range  */
 783 
 784         ACPI_WARNING ((AE_INFO, "Invalid Object Type 0x%X", Type));
 785         return_UINT32 (ACPI_NS_NORMAL);
 786     }
 787 
 788     return_UINT32 (((UINT32) AcpiGbl_NsProperties[Type]) & ACPI_NS_NEWSCOPE);
 789 }
 790 
 791 
 792 /*******************************************************************************
 793  *
 794  * FUNCTION:    AcpiNsGetNode
 795  *
 796  * PARAMETERS:  *Pathname   - Name to be found, in external (ASL) format. The
 797  *                            \ (backslash) and ^ (carat) prefixes, and the
 798  *                            . (period) to separate segments are supported.
 799  *              PrefixNode   - Root of subtree to be searched, or NS_ALL for the
 800  *                            root of the name space.  If Name is fully
 801  *                            qualified (first INT8 is '\'), the passed value
 802  *                            of Scope will not be accessed.
 803  *              Flags       - Used to indicate whether to perform upsearch or
 804  *                            not.
 805  *              ReturnNode  - Where the Node is returned
 806  *
 807  * DESCRIPTION: Look up a name relative to a given scope and return the
 808  *              corresponding Node.  NOTE: Scope can be null.
 809  *
 810  * MUTEX:       Locks namespace
 811  *
 812  ******************************************************************************/
 813 
 814 ACPI_STATUS
 815 AcpiNsGetNode (
 816     ACPI_NAMESPACE_NODE     *PrefixNode,
 817     const char              *Pathname,
 818     UINT32                  Flags,
 819     ACPI_NAMESPACE_NODE     **ReturnNode)
 820 {
 821     ACPI_GENERIC_STATE      ScopeInfo;
 822     ACPI_STATUS             Status;
 823     char                    *InternalPath;
 824 
 825 
 826     ACPI_FUNCTION_TRACE_PTR (NsGetNode, ACPI_CAST_PTR (char, Pathname));
 827 
 828 


 829     if (!Pathname)
 830     {
 831         *ReturnNode = PrefixNode;
 832         if (!PrefixNode)
 833         {
 834             *ReturnNode = AcpiGbl_RootNode;
 835         }
 836         return_ACPI_STATUS (AE_OK);
 837     }








 838 
 839     /* Convert path to internal representation */
 840 
 841     Status = AcpiNsInternalizeName (Pathname, &InternalPath);
 842     if (ACPI_FAILURE (Status))
 843     {
 844         return_ACPI_STATUS (Status);
 845     }
 846 
 847     /* Must lock namespace during lookup */
 848 
 849     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
 850     if (ACPI_FAILURE (Status))
 851     {
 852         goto Cleanup;
 853     }
 854 
 855     /* Setup lookup scope (search starting point) */
 856 
 857     ScopeInfo.Scope.Node = PrefixNode;
   1 /******************************************************************************
   2  *
   3  * Module Name: nsutils - Utilities for accessing ACPI namespace, accessing
   4  *                        parents and siblings and Scope manipulation
   5  *
   6  *****************************************************************************/
   7 
   8 /*
   9  * Copyright (C) 2000 - 2013, Intel Corp.
  10  * All rights reserved.
  11  *
  12  * Redistribution and use in source and binary forms, with or without
  13  * modification, are permitted provided that the following conditions
  14  * are met:
  15  * 1. Redistributions of source code must retain the above copyright
  16  *    notice, this list of conditions, and the following disclaimer,
  17  *    without modification.
  18  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
  19  *    substantially similar to the "NO WARRANTY" disclaimer below
  20  *    ("Disclaimer") and any redistribution must be conditioned upon
  21  *    including a substantially similar Disclaimer requirement for further
  22  *    binary redistribution.
  23  * 3. Neither the names of the above-listed copyright holders nor the names
  24  *    of any contributors may be used to endorse or promote products derived
  25  *    from this software without specific prior written permission.
  26  *
  27  * Alternatively, this software may be distributed under the terms of the
  28  * GNU General Public License ("GPL") version 2 as published by the Free
  29  * Software Foundation.


  37  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  38  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  39  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  40  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  41  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  42  * POSSIBILITY OF SUCH DAMAGES.
  43  */
  44 
  45 #define __NSUTILS_C__
  46 
  47 #include "acpi.h"
  48 #include "accommon.h"
  49 #include "acnamesp.h"
  50 #include "amlcode.h"
  51 
  52 #define _COMPONENT          ACPI_NAMESPACE
  53         ACPI_MODULE_NAME    ("nsutils")
  54 
  55 /* Local prototypes */
  56 




  57 #ifdef ACPI_OBSOLETE_FUNCTIONS
  58 ACPI_NAME
  59 AcpiNsFindParentName (
  60     ACPI_NAMESPACE_NODE     *NodeToSearch);
  61 #endif
  62 
  63 
  64 /*******************************************************************************
  65  *
  66  * FUNCTION:    AcpiNsPrintNodePathname
  67  *
  68  * PARAMETERS:  Node            - Object
  69  *              Message         - Prefix message
  70  *
  71  * DESCRIPTION: Print an object's full namespace pathname
  72  *              Manages allocation/freeing of a pathname buffer
  73  *
  74  ******************************************************************************/
  75 
  76 void


  91     /* Convert handle to full pathname and print it (with supplied message) */
  92 
  93     Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
  94 
  95     Status = AcpiNsHandleToPathname (Node, &Buffer);
  96     if (ACPI_SUCCESS (Status))
  97     {
  98         if (Message)
  99         {
 100             AcpiOsPrintf ("%s ", Message);
 101         }
 102 
 103         AcpiOsPrintf ("[%s] (Node %p)", (char *) Buffer.Pointer, Node);
 104         ACPI_FREE (Buffer.Pointer);
 105     }
 106 }
 107 
 108 
 109 /*******************************************************************************
 110  *










































 111  * FUNCTION:    AcpiNsGetType
 112  *
 113  * PARAMETERS:  Node        - Parent Node to be examined
 114  *
 115  * RETURN:      Type field from Node whose handle is passed
 116  *
 117  * DESCRIPTION: Return the type of a Namespace node
 118  *
 119  ******************************************************************************/
 120 
 121 ACPI_OBJECT_TYPE
 122 AcpiNsGetType (
 123     ACPI_NAMESPACE_NODE     *Node)
 124 {
 125     ACPI_FUNCTION_TRACE (NsGetType);
 126 
 127 
 128     if (!Node)
 129     {
 130         ACPI_WARNING ((AE_INFO, "Null Node parameter"));
 131         return_UINT8 (ACPI_TYPE_ANY);
 132     }
 133 
 134     return_UINT8 (Node->Type);
 135 }
 136 
 137 
 138 /*******************************************************************************
 139  *
 140  * FUNCTION:    AcpiNsLocal
 141  *
 142  * PARAMETERS:  Type        - A namespace object type
 143  *
 144  * RETURN:      LOCAL if names must be found locally in objects of the
 145  *              passed type, 0 if enclosing scopes should be searched
 146  *
 147  * DESCRIPTION: Returns scope rule for the given object type.
 148  *
 149  ******************************************************************************/
 150 
 151 UINT32
 152 AcpiNsLocal (
 153     ACPI_OBJECT_TYPE        Type)
 154 {
 155     ACPI_FUNCTION_TRACE (NsLocal);
 156 
 157 
 158     if (!AcpiUtValidObjectType (Type))
 159     {
 160         /* Type code out of range  */
 161 
 162         ACPI_WARNING ((AE_INFO, "Invalid Object Type 0x%X", Type));
 163         return_UINT32 (ACPI_NS_NORMAL);
 164     }
 165 
 166     return_UINT32 (AcpiGbl_NsProperties[Type] & ACPI_NS_LOCAL);
 167 }
 168 
 169 
 170 /*******************************************************************************
 171  *
 172  * FUNCTION:    AcpiNsGetInternalNameLength
 173  *
 174  * PARAMETERS:  Info            - Info struct initialized with the
 175  *                                external name pointer.
 176  *
 177  * RETURN:      None
 178  *
 179  * DESCRIPTION: Calculate the length of the internal (AML) namestring
 180  *              corresponding to the external (ASL) namestring.
 181  *
 182  ******************************************************************************/
 183 
 184 void
 185 AcpiNsGetInternalNameLength (
 186     ACPI_NAMESTRING_INFO    *Info)
 187 {
 188     const char              *NextExternalChar;
 189     UINT32                  i;
 190 
 191 
 192     ACPI_FUNCTION_ENTRY ();
 193 
 194 
 195     NextExternalChar = Info->ExternalName;
 196     Info->NumCarats = 0;
 197     Info->NumSegments = 0;
 198     Info->FullyQualified = FALSE;
 199 
 200     /*
 201      * For the internal name, the required length is 4 bytes per segment, plus
 202      * 1 each for RootPrefix, MultiNamePrefixOp, segment count, trailing null
 203      * (which is not really needed, but no there's harm in putting it there)
 204      *
 205      * strlen() + 1 covers the first NameSeg, which has no path separator
 206      */
 207     if (ACPI_IS_ROOT_PREFIX (*NextExternalChar))
 208     {
 209         Info->FullyQualified = TRUE;
 210         NextExternalChar++;
 211 
 212         /* Skip redundant RootPrefix, like \\_SB.PCI0.SBRG.EC0 */
 213 
 214         while (ACPI_IS_ROOT_PREFIX (*NextExternalChar))
 215         {
 216             NextExternalChar++;
 217         }
 218     }
 219     else
 220     {
 221         /* Handle Carat prefixes */
 222 
 223         while (ACPI_IS_PARENT_PREFIX (*NextExternalChar))
 224         {
 225             Info->NumCarats++;
 226             NextExternalChar++;
 227         }
 228     }
 229 
 230     /*
 231      * Determine the number of ACPI name "segments" by counting the number of
 232      * path separators within the string. Start with one segment since the
 233      * segment count is [(# separators) + 1], and zero separators is ok.
 234      */
 235     if (*NextExternalChar)
 236     {
 237         Info->NumSegments = 1;
 238         for (i = 0; NextExternalChar[i]; i++)
 239         {
 240             if (ACPI_IS_PATH_SEPARATOR (NextExternalChar[i]))
 241             {
 242                 Info->NumSegments++;
 243             }
 244         }
 245     }
 246 
 247     Info->Length = (ACPI_NAME_SIZE * Info->NumSegments) +
 248                     4 + Info->NumCarats;
 249 
 250     Info->NextExternalChar = NextExternalChar;
 251 }
 252 
 253 
 254 /*******************************************************************************
 255  *
 256  * FUNCTION:    AcpiNsBuildInternalName
 257  *
 258  * PARAMETERS:  Info            - Info struct fully initialized
 259  *
 260  * RETURN:      Status


 265  ******************************************************************************/
 266 
 267 ACPI_STATUS
 268 AcpiNsBuildInternalName (
 269     ACPI_NAMESTRING_INFO    *Info)
 270 {
 271     UINT32                  NumSegments = Info->NumSegments;
 272     char                    *InternalName = Info->InternalName;
 273     const char              *ExternalName = Info->NextExternalChar;
 274     char                    *Result = NULL;
 275     UINT32                  i;
 276 
 277 
 278     ACPI_FUNCTION_TRACE (NsBuildInternalName);
 279 
 280 
 281     /* Setup the correct prefixes, counts, and pointers */
 282 
 283     if (Info->FullyQualified)
 284     {
 285         InternalName[0] = AML_ROOT_PREFIX;
 286 
 287         if (NumSegments <= 1)
 288         {
 289             Result = &InternalName[1];
 290         }
 291         else if (NumSegments == 2)
 292         {
 293             InternalName[1] = AML_DUAL_NAME_PREFIX;
 294             Result = &InternalName[2];
 295         }
 296         else
 297         {
 298             InternalName[1] = AML_MULTI_NAME_PREFIX_OP;
 299             InternalName[2] = (char) NumSegments;
 300             Result = &InternalName[3];
 301         }
 302     }
 303     else
 304     {
 305         /*
 306          * Not fully qualified.
 307          * Handle Carats first, then append the name segments
 308          */
 309         i = 0;
 310         if (Info->NumCarats)
 311         {
 312             for (i = 0; i < Info->NumCarats; i++)
 313             {
 314                 InternalName[i] = AML_PARENT_PREFIX;
 315             }
 316         }
 317 
 318         if (NumSegments <= 1)
 319         {
 320             Result = &InternalName[i];
 321         }
 322         else if (NumSegments == 2)
 323         {
 324             InternalName[i] = AML_DUAL_NAME_PREFIX;
 325             Result = &InternalName[(ACPI_SIZE) i+1];
 326         }
 327         else
 328         {
 329             InternalName[i] = AML_MULTI_NAME_PREFIX_OP;
 330             InternalName[(ACPI_SIZE) i+1] = (char) NumSegments;
 331             Result = &InternalName[(ACPI_SIZE) i+2];
 332         }
 333     }
 334 
 335     /* Build the name (minus path separators) */
 336 
 337     for (; NumSegments; NumSegments--)
 338     {
 339         for (i = 0; i < ACPI_NAME_SIZE; i++)
 340         {
 341             if (ACPI_IS_PATH_SEPARATOR (*ExternalName) ||
 342                (*ExternalName == 0))
 343             {
 344                 /* Pad the segment with underscore(s) if segment is short */
 345 
 346                 Result[i] = '_';
 347             }
 348             else
 349             {
 350                 /* Convert the character to uppercase and save it */
 351 
 352                 Result[i] = (char) ACPI_TOUPPER ((int) *ExternalName);
 353                 ExternalName++;
 354             }
 355         }
 356 
 357         /* Now we must have a path separator, or the pathname is bad */
 358 
 359         if (!ACPI_IS_PATH_SEPARATOR (*ExternalName) &&
 360             (*ExternalName != 0))
 361         {
 362             return_ACPI_STATUS (AE_BAD_PATHNAME);
 363         }
 364 
 365         /* Move on the next segment */
 366 
 367         ExternalName++;
 368         Result += ACPI_NAME_SIZE;
 369     }
 370 
 371     /* Terminate the string */
 372 
 373     *Result = 0;
 374 
 375     if (Info->FullyQualified)
 376     {
 377         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Returning [%p] (abs) \"\\%s\"\n",
 378             InternalName, InternalName));
 379     }
 380     else
 381     {
 382         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Returning [%p] (rel) \"%s\"\n",


 479     UINT32                  RequiredLength;
 480     UINT32                  PrefixLength = 0;
 481     UINT32                  i = 0;
 482     UINT32                  j = 0;
 483 
 484 
 485     ACPI_FUNCTION_TRACE (NsExternalizeName);
 486 
 487 
 488     if (!InternalNameLength     ||
 489         !InternalName           ||
 490         !ConvertedName)
 491     {
 492         return_ACPI_STATUS (AE_BAD_PARAMETER);
 493     }
 494 
 495     /* Check for a prefix (one '\' | one or more '^') */
 496 
 497     switch (InternalName[0])
 498     {
 499     case AML_ROOT_PREFIX:
 500 
 501         PrefixLength = 1;
 502         break;
 503 
 504     case AML_PARENT_PREFIX:
 505 
 506         for (i = 0; i < InternalNameLength; i++)
 507         {
 508             if (ACPI_IS_PARENT_PREFIX (InternalName[i]))
 509             {
 510                 PrefixLength = i + 1;
 511             }
 512             else
 513             {
 514                 break;
 515             }
 516         }
 517 
 518         if (i == InternalNameLength)
 519         {
 520             PrefixLength = i;
 521         }
 522 
 523         break;
 524 
 525     default:
 526 
 527         break;
 528     }
 529 
 530     /*
 531      * Check for object names. Note that there could be 0-255 of these
 532      * 4-byte elements.
 533      */
 534     if (PrefixLength < InternalNameLength)
 535     {
 536         switch (InternalName[PrefixLength])
 537         {
 538         case AML_MULTI_NAME_PREFIX_OP:
 539 
 540             /* <count> 4-byte names */
 541 
 542             NamesIndex = PrefixLength + 2;
 543             NumSegments = (UINT8)
 544                 InternalName[(ACPI_SIZE) PrefixLength + 1];
 545             break;
 546 


 595     {
 596         return_ACPI_STATUS (AE_NO_MEMORY);
 597     }
 598 
 599     j = 0;
 600 
 601     for (i = 0; i < PrefixLength; i++)
 602     {
 603         (*ConvertedName)[j++] = InternalName[i];
 604     }
 605 
 606     if (NumSegments > 0)
 607     {
 608         for (i = 0; i < NumSegments; i++)
 609         {
 610             if (i > 0)
 611             {
 612                 (*ConvertedName)[j++] = '.';
 613             }
 614 
 615             /* Copy and validate the 4-char name segment */
 616 
 617             ACPI_MOVE_NAME (&(*ConvertedName)[j], &InternalName[NamesIndex]);
 618             AcpiUtRepairName (&(*ConvertedName)[j]);
 619 
 620             j += ACPI_NAME_SIZE;
 621             NamesIndex += ACPI_NAME_SIZE;
 622         }
 623     }
 624 
 625     if (ConvertedNameLength)
 626     {
 627         *ConvertedNameLength = (UINT32) RequiredLength;
 628     }
 629 
 630     return_ACPI_STATUS (AE_OK);
 631 }
 632 
 633 
 634 /*******************************************************************************
 635  *
 636  * FUNCTION:    AcpiNsValidateHandle
 637  *
 638  * PARAMETERS:  Handle          - Handle to be validated and typecast to a
 639  *                                namespace node.
 640  *
 641  * RETURN:      A pointer to a namespace node


 676     return (ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Handle));
 677 }
 678 
 679 
 680 /*******************************************************************************
 681  *
 682  * FUNCTION:    AcpiNsTerminate
 683  *
 684  * PARAMETERS:  none
 685  *
 686  * RETURN:      none
 687  *
 688  * DESCRIPTION: free memory allocated for namespace and ACPI table storage.
 689  *
 690  ******************************************************************************/
 691 
 692 void
 693 AcpiNsTerminate (
 694     void)
 695 {
 696     ACPI_STATUS             Status;
 697 
 698 
 699     ACPI_FUNCTION_TRACE (NsTerminate);
 700 
 701 
 702     /*
 703      * Free the entire namespace -- all nodes and all objects
 704      * attached to the nodes

 705      */
 706     AcpiNsDeleteNamespaceSubtree (AcpiGbl_RootNode);
 707 
 708     /* Delete any objects attached to the root node */
 709 
 710     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
 711     if (ACPI_FAILURE (Status))
 712     {
 713         return_VOID;
 714     }
 715 
 716     AcpiNsDeleteNode (AcpiGbl_RootNode);
 717     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
 718 
 719     ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Namespace freed\n"));
 720     return_VOID;
 721 }
 722 
 723 
 724 /*******************************************************************************
 725  *
 726  * FUNCTION:    AcpiNsOpensScope
 727  *
 728  * PARAMETERS:  Type        - A valid namespace type
 729  *
 730  * RETURN:      NEWSCOPE if the passed type "opens a name scope" according
 731  *              to the ACPI specification, else 0
 732  *
 733  ******************************************************************************/
 734 
 735 UINT32
 736 AcpiNsOpensScope (
 737     ACPI_OBJECT_TYPE        Type)
 738 {
 739     ACPI_FUNCTION_ENTRY ();
 740 
 741 
 742     if (Type > ACPI_TYPE_LOCAL_MAX)
 743     {
 744         /* type code out of range  */
 745 
 746         ACPI_WARNING ((AE_INFO, "Invalid Object Type 0x%X", Type));
 747         return (ACPI_NS_NORMAL);
 748     }
 749 
 750     return (((UINT32) AcpiGbl_NsProperties[Type]) & ACPI_NS_NEWSCOPE);
 751 }
 752 
 753 
 754 /*******************************************************************************
 755  *
 756  * FUNCTION:    AcpiNsGetNode
 757  *
 758  * PARAMETERS:  *Pathname   - Name to be found, in external (ASL) format. The
 759  *                            \ (backslash) and ^ (carat) prefixes, and the
 760  *                            . (period) to separate segments are supported.
 761  *              PrefixNode   - Root of subtree to be searched, or NS_ALL for the
 762  *                            root of the name space. If Name is fully
 763  *                            qualified (first INT8 is '\'), the passed value
 764  *                            of Scope will not be accessed.
 765  *              Flags       - Used to indicate whether to perform upsearch or
 766  *                            not.
 767  *              ReturnNode  - Where the Node is returned
 768  *
 769  * DESCRIPTION: Look up a name relative to a given scope and return the
 770  *              corresponding Node. NOTE: Scope can be null.
 771  *
 772  * MUTEX:       Locks namespace
 773  *
 774  ******************************************************************************/
 775 
 776 ACPI_STATUS
 777 AcpiNsGetNode (
 778     ACPI_NAMESPACE_NODE     *PrefixNode,
 779     const char              *Pathname,
 780     UINT32                  Flags,
 781     ACPI_NAMESPACE_NODE     **ReturnNode)
 782 {
 783     ACPI_GENERIC_STATE      ScopeInfo;
 784     ACPI_STATUS             Status;
 785     char                    *InternalPath;
 786 
 787 
 788     ACPI_FUNCTION_TRACE_PTR (NsGetNode, ACPI_CAST_PTR (char, Pathname));
 789 
 790 
 791     /* Simplest case is a null pathname */
 792 
 793     if (!Pathname)
 794     {
 795         *ReturnNode = PrefixNode;
 796         if (!PrefixNode)
 797         {
 798             *ReturnNode = AcpiGbl_RootNode;
 799         }
 800         return_ACPI_STATUS (AE_OK);
 801     }
 802 
 803     /* Quick check for a reference to the root */
 804 
 805     if (ACPI_IS_ROOT_PREFIX (Pathname[0]) && (!Pathname[1]))
 806     {
 807         *ReturnNode = AcpiGbl_RootNode;
 808         return_ACPI_STATUS (AE_OK);
 809     }
 810 
 811     /* Convert path to internal representation */
 812 
 813     Status = AcpiNsInternalizeName (Pathname, &InternalPath);
 814     if (ACPI_FAILURE (Status))
 815     {
 816         return_ACPI_STATUS (Status);
 817     }
 818 
 819     /* Must lock namespace during lookup */
 820 
 821     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
 822     if (ACPI_FAILURE (Status))
 823     {
 824         goto Cleanup;
 825     }
 826 
 827     /* Setup lookup scope (search starting point) */
 828 
 829     ScopeInfo.Scope.Node = PrefixNode;