Home | History | Annotate | Line # | Download | only in namespace
nsnames.c revision 1.1.1.8
      1 /*******************************************************************************
      2  *
      3  * Module Name: nsnames - Name manipulation and search
      4  *
      5  ******************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2017, Intel Corp.
      9  * All rights reserved.
     10  *
     11  * Redistribution and use in source and binary forms, with or without
     12  * modification, are permitted provided that the following conditions
     13  * are met:
     14  * 1. Redistributions of source code must retain the above copyright
     15  *    notice, this list of conditions, and the following disclaimer,
     16  *    without modification.
     17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
     18  *    substantially similar to the "NO WARRANTY" disclaimer below
     19  *    ("Disclaimer") and any redistribution must be conditioned upon
     20  *    including a substantially similar Disclaimer requirement for further
     21  *    binary redistribution.
     22  * 3. Neither the names of the above-listed copyright holders nor the names
     23  *    of any contributors may be used to endorse or promote products derived
     24  *    from this software without specific prior written permission.
     25  *
     26  * Alternatively, this software may be distributed under the terms of the
     27  * GNU General Public License ("GPL") version 2 as published by the Free
     28  * Software Foundation.
     29  *
     30  * NO WARRANTY
     31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
     34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
     40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     41  * POSSIBILITY OF SUCH DAMAGES.
     42  */
     43 
     44 #include "acpi.h"
     45 #include "accommon.h"
     46 #include "amlcode.h"
     47 #include "acnamesp.h"
     48 
     49 
     50 #define _COMPONENT          ACPI_NAMESPACE
     51         ACPI_MODULE_NAME    ("nsnames")
     52 
     53 
     54 /*******************************************************************************
     55  *
     56  * FUNCTION:    AcpiNsGetExternalPathname
     57  *
     58  * PARAMETERS:  Node            - Namespace node whose pathname is needed
     59  *
     60  * RETURN:      Pointer to storage containing the fully qualified name of
     61  *              the node, In external format (name segments separated by path
     62  *              separators.)
     63  *
     64  * DESCRIPTION: Used to obtain the full pathname to a namespace node, usually
     65  *              for error and debug statements.
     66  *
     67  ******************************************************************************/
     68 
     69 char *
     70 AcpiNsGetExternalPathname (
     71     ACPI_NAMESPACE_NODE     *Node)
     72 {
     73     char                    *NameBuffer;
     74 
     75 
     76     ACPI_FUNCTION_TRACE_PTR (NsGetExternalPathname, Node);
     77 
     78 
     79     NameBuffer = AcpiNsGetNormalizedPathname (Node, FALSE);
     80     return_PTR (NameBuffer);
     81 }
     82 
     83 
     84 /*******************************************************************************
     85  *
     86  * FUNCTION:    AcpiNsGetPathnameLength
     87  *
     88  * PARAMETERS:  Node        - Namespace node
     89  *
     90  * RETURN:      Length of path, including prefix
     91  *
     92  * DESCRIPTION: Get the length of the pathname string for this node
     93  *
     94  ******************************************************************************/
     95 
     96 ACPI_SIZE
     97 AcpiNsGetPathnameLength (
     98     ACPI_NAMESPACE_NODE     *Node)
     99 {
    100     ACPI_SIZE               Size;
    101 
    102 
    103     ACPI_FUNCTION_ENTRY ();
    104 
    105 
    106     Size = AcpiNsBuildNormalizedPath (Node, NULL, 0, FALSE);
    107     return (Size);
    108 }
    109 
    110 
    111 /*******************************************************************************
    112  *
    113  * FUNCTION:    AcpiNsHandleToName
    114  *
    115  * PARAMETERS:  TargetHandle            - Handle of named object whose name is
    116  *                                        to be found
    117  *              Buffer                  - Where the name is returned
    118  *
    119  * RETURN:      Status, Buffer is filled with name if status is AE_OK
    120  *
    121  * DESCRIPTION: Build and return a full namespace name
    122  *
    123  ******************************************************************************/
    124 
    125 ACPI_STATUS
    126 AcpiNsHandleToName (
    127     ACPI_HANDLE             TargetHandle,
    128     ACPI_BUFFER             *Buffer)
    129 {
    130     ACPI_STATUS             Status;
    131     ACPI_NAMESPACE_NODE     *Node;
    132     const char              *NodeName;
    133 
    134 
    135     ACPI_FUNCTION_TRACE_PTR (NsHandleToName, TargetHandle);
    136 
    137 
    138     Node = AcpiNsValidateHandle (TargetHandle);
    139     if (!Node)
    140     {
    141         return_ACPI_STATUS (AE_BAD_PARAMETER);
    142     }
    143 
    144     /* Validate/Allocate/Clear caller buffer */
    145 
    146     Status = AcpiUtInitializeBuffer (Buffer, ACPI_PATH_SEGMENT_LENGTH);
    147     if (ACPI_FAILURE (Status))
    148     {
    149         return_ACPI_STATUS (Status);
    150     }
    151 
    152     /* Just copy the ACPI name from the Node and zero terminate it */
    153 
    154     NodeName = AcpiUtGetNodeName (Node);
    155     ACPI_MOVE_NAME (Buffer->Pointer, NodeName);
    156     ((char *) Buffer->Pointer) [ACPI_NAME_SIZE] = 0;
    157 
    158     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%4.4s\n", (char *) Buffer->Pointer));
    159     return_ACPI_STATUS (AE_OK);
    160 }
    161 
    162 
    163 /*******************************************************************************
    164  *
    165  * FUNCTION:    AcpiNsHandleToPathname
    166  *
    167  * PARAMETERS:  TargetHandle            - Handle of named object whose name is
    168  *                                        to be found
    169  *              Buffer                  - Where the pathname is returned
    170  *              NoTrailing              - Remove trailing '_' for each name
    171  *                                        segment
    172  *
    173  * RETURN:      Status, Buffer is filled with pathname if status is AE_OK
    174  *
    175  * DESCRIPTION: Build and return a full namespace pathname
    176  *
    177  ******************************************************************************/
    178 
    179 ACPI_STATUS
    180 AcpiNsHandleToPathname (
    181     ACPI_HANDLE             TargetHandle,
    182     ACPI_BUFFER             *Buffer,
    183     BOOLEAN                 NoTrailing)
    184 {
    185     ACPI_STATUS             Status;
    186     ACPI_NAMESPACE_NODE     *Node;
    187     ACPI_SIZE               RequiredSize;
    188 
    189 
    190     ACPI_FUNCTION_TRACE_PTR (NsHandleToPathname, TargetHandle);
    191 
    192 
    193     Node = AcpiNsValidateHandle (TargetHandle);
    194     if (!Node)
    195     {
    196         return_ACPI_STATUS (AE_BAD_PARAMETER);
    197     }
    198 
    199     /* Determine size required for the caller buffer */
    200 
    201     RequiredSize = AcpiNsBuildNormalizedPath (Node, NULL, 0, NoTrailing);
    202     if (!RequiredSize)
    203     {
    204         return_ACPI_STATUS (AE_BAD_PARAMETER);
    205     }
    206 
    207     /* Validate/Allocate/Clear caller buffer */
    208 
    209     Status = AcpiUtInitializeBuffer (Buffer, RequiredSize);
    210     if (ACPI_FAILURE (Status))
    211     {
    212         return_ACPI_STATUS (Status);
    213     }
    214 
    215     /* Build the path in the caller buffer */
    216 
    217     (void) AcpiNsBuildNormalizedPath (Node, Buffer->Pointer,
    218         RequiredSize, NoTrailing);
    219     if (ACPI_FAILURE (Status))
    220     {
    221         return_ACPI_STATUS (Status);
    222     }
    223 
    224     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%s [%X]\n",
    225         (char *) Buffer->Pointer, (UINT32) RequiredSize));
    226     return_ACPI_STATUS (AE_OK);
    227 }
    228 
    229 
    230 /*******************************************************************************
    231  *
    232  * FUNCTION:    AcpiNsBuildNormalizedPath
    233  *
    234  * PARAMETERS:  Node        - Namespace node
    235  *              FullPath    - Where the path name is returned
    236  *              PathSize    - Size of returned path name buffer
    237  *              NoTrailing  - Remove trailing '_' from each name segment
    238  *
    239  * RETURN:      Return 1 if the AML path is empty, otherwise returning (length
    240  *              of pathname + 1) which means the 'FullPath' contains a trailing
    241  *              null.
    242  *
    243  * DESCRIPTION: Build and return a full namespace pathname.
    244  *              Note that if the size of 'FullPath' isn't large enough to
    245  *              contain the namespace node's path name, the actual required
    246  *              buffer length is returned, and it should be greater than
    247  *              'PathSize'. So callers are able to check the returning value
    248  *              to determine the buffer size of 'FullPath'.
    249  *
    250  ******************************************************************************/
    251 
    252 UINT32
    253 AcpiNsBuildNormalizedPath (
    254     ACPI_NAMESPACE_NODE     *Node,
    255     char                    *FullPath,
    256     UINT32                  PathSize,
    257     BOOLEAN                 NoTrailing)
    258 {
    259     UINT32                  Length = 0, i;
    260     char                    Name[ACPI_NAME_SIZE];
    261     BOOLEAN                 DoNoTrailing;
    262     char                    c, *Left, *Right;
    263     ACPI_NAMESPACE_NODE     *NextNode;
    264 
    265 
    266     ACPI_FUNCTION_TRACE_PTR (NsBuildNormalizedPath, Node);
    267 
    268 
    269 #define ACPI_PATH_PUT8(Path, Size, Byte, Length)    \
    270     do {                                            \
    271         if ((Length) < (Size))                      \
    272         {                                           \
    273             (Path)[(Length)] = (Byte);              \
    274         }                                           \
    275         (Length)++;                                 \
    276     } while (0)
    277 
    278     /*
    279      * Make sure the PathSize is correct, so that we don't need to
    280      * validate both FullPath and PathSize.
    281      */
    282     if (!FullPath)
    283     {
    284         PathSize = 0;
    285     }
    286 
    287     if (!Node)
    288     {
    289         goto BuildTrailingNull;
    290     }
    291 
    292     NextNode = Node;
    293     while (NextNode && NextNode != AcpiGbl_RootNode)
    294     {
    295         if (NextNode != Node)
    296         {
    297             ACPI_PATH_PUT8(FullPath, PathSize, AML_DUAL_NAME_PREFIX, Length);
    298         }
    299 
    300         ACPI_MOVE_32_TO_32 (Name, &NextNode->Name);
    301         DoNoTrailing = NoTrailing;
    302         for (i = 0; i < 4; i++)
    303         {
    304             c = Name[4-i-1];
    305             if (DoNoTrailing && c != '_')
    306             {
    307                 DoNoTrailing = FALSE;
    308             }
    309             if (!DoNoTrailing)
    310             {
    311                 ACPI_PATH_PUT8(FullPath, PathSize, c, Length);
    312             }
    313         }
    314 
    315         NextNode = NextNode->Parent;
    316     }
    317 
    318     ACPI_PATH_PUT8(FullPath, PathSize, AML_ROOT_PREFIX, Length);
    319 
    320     /* Reverse the path string */
    321 
    322     if (Length <= PathSize)
    323     {
    324         Left = FullPath;
    325         Right = FullPath+Length - 1;
    326 
    327         while (Left < Right)
    328         {
    329             c = *Left;
    330             *Left++ = *Right;
    331             *Right-- = c;
    332         }
    333     }
    334 
    335     /* Append the trailing null */
    336 
    337 BuildTrailingNull:
    338     ACPI_PATH_PUT8 (FullPath, PathSize, '\0', Length);
    339 
    340 #undef ACPI_PATH_PUT8
    341 
    342     return_UINT32 (Length);
    343 }
    344 
    345 
    346 /*******************************************************************************
    347  *
    348  * FUNCTION:    AcpiNsGetNormalizedPathname
    349  *
    350  * PARAMETERS:  Node            - Namespace node whose pathname is needed
    351  *              NoTrailing      - Remove trailing '_' from each name segment
    352  *
    353  * RETURN:      Pointer to storage containing the fully qualified name of
    354  *              the node, In external format (name segments separated by path
    355  *              separators.)
    356  *
    357  * DESCRIPTION: Used to obtain the full pathname to a namespace node, usually
    358  *              for error and debug statements. All trailing '_' will be
    359  *              removed from the full pathname if 'NoTrailing' is specified..
    360  *
    361  ******************************************************************************/
    362 
    363 char *
    364 AcpiNsGetNormalizedPathname (
    365     ACPI_NAMESPACE_NODE     *Node,
    366     BOOLEAN                 NoTrailing)
    367 {
    368     char                    *NameBuffer;
    369     ACPI_SIZE               Size;
    370 
    371 
    372     ACPI_FUNCTION_TRACE_PTR (NsGetNormalizedPathname, Node);
    373 
    374 
    375     /* Calculate required buffer size based on depth below root */
    376 
    377     Size = AcpiNsBuildNormalizedPath (Node, NULL, 0, NoTrailing);
    378     if (!Size)
    379     {
    380         return_PTR (NULL);
    381     }
    382 
    383     /* Allocate a buffer to be returned to caller */
    384 
    385     NameBuffer = ACPI_ALLOCATE_ZEROED (Size);
    386     if (!NameBuffer)
    387     {
    388         ACPI_ERROR ((AE_INFO,
    389             "Could not allocate %u bytes", (UINT32) Size));
    390         return_PTR (NULL);
    391     }
    392 
    393     /* Build the path in the allocated buffer */
    394 
    395     (void) AcpiNsBuildNormalizedPath (Node, NameBuffer, Size, NoTrailing);
    396 
    397     return_PTR (NameBuffer);
    398 }
    399