LCOV - code coverage report
Current view: top level - drivers/acpi/acpica - nsnames.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 77 146 52.7 %
Date: 2022-04-01 14:17:54 Functions: 5 8 62.5 %
Branches: 34 84 40.5 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
       2                 :            : /*******************************************************************************
       3                 :            :  *
       4                 :            :  * Module Name: nsnames - Name manipulation and search
       5                 :            :  *
       6                 :            :  ******************************************************************************/
       7                 :            : 
       8                 :            : #include <acpi/acpi.h>
       9                 :            : #include "accommon.h"
      10                 :            : #include "amlcode.h"
      11                 :            : #include "acnamesp.h"
      12                 :            : 
      13                 :            : #define _COMPONENT          ACPI_NAMESPACE
      14                 :            : ACPI_MODULE_NAME("nsnames")
      15                 :            : 
      16                 :            : /* Local Prototypes */
      17                 :            : static void acpi_ns_normalize_pathname(char *original_path);
      18                 :            : 
      19                 :            : /*******************************************************************************
      20                 :            :  *
      21                 :            :  * FUNCTION:    acpi_ns_get_external_pathname
      22                 :            :  *
      23                 :            :  * PARAMETERS:  node            - Namespace node whose pathname is needed
      24                 :            :  *
      25                 :            :  * RETURN:      Pointer to storage containing the fully qualified name of
      26                 :            :  *              the node, In external format (name segments separated by path
      27                 :            :  *              separators.)
      28                 :            :  *
      29                 :            :  * DESCRIPTION: Used to obtain the full pathname to a namespace node, usually
      30                 :            :  *              for error and debug statements.
      31                 :            :  *
      32                 :            :  ******************************************************************************/
      33                 :            : 
      34                 :          0 : char *acpi_ns_get_external_pathname(struct acpi_namespace_node *node)
      35                 :            : {
      36                 :          0 :         char *name_buffer;
      37                 :            : 
      38                 :          0 :         ACPI_FUNCTION_TRACE_PTR(ns_get_external_pathname, node);
      39                 :            : 
      40                 :          0 :         name_buffer = acpi_ns_get_normalized_pathname(node, FALSE);
      41                 :          0 :         return_PTR(name_buffer);
      42                 :            : }
      43                 :            : 
      44                 :            : /*******************************************************************************
      45                 :            :  *
      46                 :            :  * FUNCTION:    acpi_ns_get_pathname_length
      47                 :            :  *
      48                 :            :  * PARAMETERS:  node        - Namespace node
      49                 :            :  *
      50                 :            :  * RETURN:      Length of path, including prefix
      51                 :            :  *
      52                 :            :  * DESCRIPTION: Get the length of the pathname string for this node
      53                 :            :  *
      54                 :            :  ******************************************************************************/
      55                 :            : 
      56                 :       2816 : acpi_size acpi_ns_get_pathname_length(struct acpi_namespace_node *node)
      57                 :            : {
      58                 :       2816 :         acpi_size size;
      59                 :            : 
      60                 :            :         /* Validate the Node */
      61                 :            : 
      62         [ -  + ]:       2816 :         if (ACPI_GET_DESCRIPTOR_TYPE(node) != ACPI_DESC_TYPE_NAMED) {
      63                 :          0 :                 ACPI_ERROR((AE_INFO,
      64                 :            :                             "Invalid/cached reference target node: %p, descriptor type %d",
      65                 :            :                             node, ACPI_GET_DESCRIPTOR_TYPE(node)));
      66                 :          0 :                 return (0);
      67                 :            :         }
      68                 :            : 
      69                 :       2816 :         size = acpi_ns_build_normalized_path(node, NULL, 0, FALSE);
      70                 :       2816 :         return (size);
      71                 :            : }
      72                 :            : 
      73                 :            : /*******************************************************************************
      74                 :            :  *
      75                 :            :  * FUNCTION:    acpi_ns_handle_to_name
      76                 :            :  *
      77                 :            :  * PARAMETERS:  target_handle           - Handle of named object whose name is
      78                 :            :  *                                        to be found
      79                 :            :  *              buffer                  - Where the name is returned
      80                 :            :  *
      81                 :            :  * RETURN:      Status, Buffer is filled with name if status is AE_OK
      82                 :            :  *
      83                 :            :  * DESCRIPTION: Build and return a full namespace name
      84                 :            :  *
      85                 :            :  ******************************************************************************/
      86                 :            : 
      87                 :            : acpi_status
      88                 :        616 : acpi_ns_handle_to_name(acpi_handle target_handle, struct acpi_buffer *buffer)
      89                 :            : {
      90                 :        616 :         acpi_status status;
      91                 :        616 :         struct acpi_namespace_node *node;
      92                 :        616 :         const char *node_name;
      93                 :            : 
      94                 :        616 :         ACPI_FUNCTION_TRACE_PTR(ns_handle_to_name, target_handle);
      95                 :            : 
      96                 :        616 :         node = acpi_ns_validate_handle(target_handle);
      97         [ +  - ]:        616 :         if (!node) {
      98                 :            :                 return_ACPI_STATUS(AE_BAD_PARAMETER);
      99                 :            :         }
     100                 :            : 
     101                 :            :         /* Validate/Allocate/Clear caller buffer */
     102                 :            : 
     103                 :        616 :         status = acpi_ut_initialize_buffer(buffer, ACPI_PATH_SEGMENT_LENGTH);
     104         [ +  - ]:        616 :         if (ACPI_FAILURE(status)) {
     105                 :            :                 return_ACPI_STATUS(status);
     106                 :            :         }
     107                 :            : 
     108                 :            :         /* Just copy the ACPI name from the Node and zero terminate it */
     109                 :            : 
     110                 :        616 :         node_name = acpi_ut_get_node_name(node);
     111                 :        616 :         ACPI_COPY_NAMESEG(buffer->pointer, node_name);
     112                 :        616 :         ((char *)buffer->pointer)[ACPI_NAMESEG_SIZE] = 0;
     113                 :            : 
     114                 :        616 :         ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "%4.4s\n", (char *)buffer->pointer));
     115                 :        616 :         return_ACPI_STATUS(AE_OK);
     116                 :            : }
     117                 :            : 
     118                 :            : /*******************************************************************************
     119                 :            :  *
     120                 :            :  * FUNCTION:    acpi_ns_handle_to_pathname
     121                 :            :  *
     122                 :            :  * PARAMETERS:  target_handle           - Handle of named object whose name is
     123                 :            :  *                                        to be found
     124                 :            :  *              buffer                  - Where the pathname is returned
     125                 :            :  *              no_trailing             - Remove trailing '_' for each name
     126                 :            :  *                                        segment
     127                 :            :  *
     128                 :            :  * RETURN:      Status, Buffer is filled with pathname if status is AE_OK
     129                 :            :  *
     130                 :            :  * DESCRIPTION: Build and return a full namespace pathname
     131                 :            :  *
     132                 :            :  ******************************************************************************/
     133                 :            : 
     134                 :            : acpi_status
     135                 :       3454 : acpi_ns_handle_to_pathname(acpi_handle target_handle,
     136                 :            :                            struct acpi_buffer *buffer, u8 no_trailing)
     137                 :            : {
     138                 :       3454 :         acpi_status status;
     139                 :       3454 :         struct acpi_namespace_node *node;
     140                 :       3454 :         acpi_size required_size;
     141                 :            : 
     142                 :       3454 :         ACPI_FUNCTION_TRACE_PTR(ns_handle_to_pathname, target_handle);
     143                 :            : 
     144                 :       3454 :         node = acpi_ns_validate_handle(target_handle);
     145         [ +  - ]:       3454 :         if (!node) {
     146                 :            :                 return_ACPI_STATUS(AE_BAD_PARAMETER);
     147                 :            :         }
     148                 :            : 
     149                 :            :         /* Determine size required for the caller buffer */
     150                 :            : 
     151                 :       6908 :         required_size =
     152                 :       3454 :             acpi_ns_build_normalized_path(node, NULL, 0, no_trailing);
     153         [ +  - ]:       3454 :         if (!required_size) {
     154                 :            :                 return_ACPI_STATUS(AE_BAD_PARAMETER);
     155                 :            :         }
     156                 :            : 
     157                 :            :         /* Validate/Allocate/Clear caller buffer */
     158                 :            : 
     159                 :       3454 :         status = acpi_ut_initialize_buffer(buffer, required_size);
     160         [ +  - ]:       3454 :         if (ACPI_FAILURE(status)) {
     161                 :            :                 return_ACPI_STATUS(status);
     162                 :            :         }
     163                 :            : 
     164                 :            :         /* Build the path in the caller buffer */
     165                 :            : 
     166                 :       3454 :         (void)acpi_ns_build_normalized_path(node, buffer->pointer,
     167                 :            :                                             required_size, no_trailing);
     168                 :            : 
     169                 :            :         ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "%s [%X]\n",
     170                 :       3454 :                           (char *)buffer->pointer, (u32) required_size));
     171                 :       3454 :         return_ACPI_STATUS(AE_OK);
     172                 :            : }
     173                 :            : 
     174                 :            : /*******************************************************************************
     175                 :            :  *
     176                 :            :  * FUNCTION:    acpi_ns_build_normalized_path
     177                 :            :  *
     178                 :            :  * PARAMETERS:  node        - Namespace node
     179                 :            :  *              full_path   - Where the path name is returned
     180                 :            :  *              path_size   - Size of returned path name buffer
     181                 :            :  *              no_trailing - Remove trailing '_' from each name segment
     182                 :            :  *
     183                 :            :  * RETURN:      Return 1 if the AML path is empty, otherwise returning (length
     184                 :            :  *              of pathname + 1) which means the 'FullPath' contains a trailing
     185                 :            :  *              null.
     186                 :            :  *
     187                 :            :  * DESCRIPTION: Build and return a full namespace pathname.
     188                 :            :  *              Note that if the size of 'FullPath' isn't large enough to
     189                 :            :  *              contain the namespace node's path name, the actual required
     190                 :            :  *              buffer length is returned, and it should be greater than
     191                 :            :  *              'PathSize'. So callers are able to check the returning value
     192                 :            :  *              to determine the buffer size of 'FullPath'.
     193                 :            :  *
     194                 :            :  ******************************************************************************/
     195                 :            : 
     196                 :            : u32
     197                 :      28314 : acpi_ns_build_normalized_path(struct acpi_namespace_node *node,
     198                 :            :                               char *full_path, u32 path_size, u8 no_trailing)
     199                 :            : {
     200                 :      28314 :         u32 length = 0, i;
     201                 :      28314 :         char name[ACPI_NAMESEG_SIZE];
     202                 :      28314 :         u8 do_no_trailing;
     203                 :      28314 :         char c, *left, *right;
     204                 :      28314 :         struct acpi_namespace_node *next_node;
     205                 :            : 
     206                 :      28314 :         ACPI_FUNCTION_TRACE_PTR(ns_build_normalized_path, node);
     207                 :            : 
     208                 :            : #define ACPI_PATH_PUT8(path, size, byte, length)    \
     209                 :            :         do {                                            \
     210                 :            :                 if ((length) < (size))                      \
     211                 :            :                 {                                           \
     212                 :            :                         (path)[(length)] = (byte);              \
     213                 :            :                 }                                           \
     214                 :            :                 (length)++;                                 \
     215                 :            :         } while (0)
     216                 :            : 
     217                 :            :         /*
     218                 :            :          * Make sure the path_size is correct, so that we don't need to
     219                 :            :          * validate both full_path and path_size.
     220                 :            :          */
     221         [ +  + ]:      28314 :         if (!full_path) {
     222                 :      15565 :                 path_size = 0;
     223                 :            :         }
     224                 :            : 
     225         [ +  - ]:      28314 :         if (!node) {
     226                 :          0 :                 goto build_trailing_null;
     227                 :            :         }
     228                 :            : 
     229                 :            :         next_node = node;
     230   [ +  -  +  + ]:     117326 :         while (next_node && next_node != acpi_gbl_root_node) {
     231         [ +  + ]:      89012 :                 if (next_node != node) {
     232         [ +  + ]:      60764 :                         ACPI_PATH_PUT8(full_path, path_size,
     233                 :            :                                        AML_DUAL_NAME_PREFIX, length);
     234                 :            :                 }
     235                 :            : 
     236                 :      89012 :                 ACPI_MOVE_32_TO_32(name, &next_node->name);
     237                 :      89012 :                 do_no_trailing = no_trailing;
     238         [ +  + ]:     445060 :                 for (i = 0; i < 4; i++) {
     239                 :     356048 :                         c = name[4 - i - 1];
     240         [ +  + ]:     356048 :                         if (do_no_trailing && c != '_') {
     241                 :            :                                 do_no_trailing = FALSE;
     242                 :            :                         }
     243         [ +  + ]:     287562 :                         if (!do_no_trailing) {
     244         [ +  + ]:     356048 :                                 ACPI_PATH_PUT8(full_path, path_size, c, length);
     245                 :            :                         }
     246                 :            :                 }
     247                 :            : 
     248                 :      89012 :                 next_node = next_node->parent;
     249                 :            :         }
     250                 :            : 
     251         [ +  + ]:      28314 :         ACPI_PATH_PUT8(full_path, path_size, AML_ROOT_PREFIX, length);
     252                 :            : 
     253                 :            :         /* Reverse the path string */
     254                 :            : 
     255         [ +  + ]:      28314 :         if (length <= path_size) {
     256                 :      12749 :                 left = full_path;
     257                 :      12749 :                 right = full_path + length - 1;
     258                 :            : 
     259         [ +  + ]:     108042 :                 while (left < right) {
     260                 :      95293 :                         c = *left;
     261                 :      95293 :                         *left++ = *right;
     262                 :      95293 :                         *right-- = c;
     263                 :            :                 }
     264                 :            :         }
     265                 :            : 
     266                 :            :         /* Append the trailing null */
     267                 :            : 
     268                 :      28314 : build_trailing_null:
     269         [ +  + ]:      28314 :         ACPI_PATH_PUT8(full_path, path_size, '\0', length);
     270                 :            : 
     271                 :            : #undef ACPI_PATH_PUT8
     272                 :            : 
     273                 :      28314 :         return_UINT32(length);
     274                 :            : }
     275                 :            : 
     276                 :            : /*******************************************************************************
     277                 :            :  *
     278                 :            :  * FUNCTION:    acpi_ns_get_normalized_pathname
     279                 :            :  *
     280                 :            :  * PARAMETERS:  node            - Namespace node whose pathname is needed
     281                 :            :  *              no_trailing     - Remove trailing '_' from each name segment
     282                 :            :  *
     283                 :            :  * RETURN:      Pointer to storage containing the fully qualified name of
     284                 :            :  *              the node, In external format (name segments separated by path
     285                 :            :  *              separators.)
     286                 :            :  *
     287                 :            :  * DESCRIPTION: Used to obtain the full pathname to a namespace node, usually
     288                 :            :  *              for error and debug statements. All trailing '_' will be
     289                 :            :  *              removed from the full pathname if 'NoTrailing' is specified..
     290                 :            :  *
     291                 :            :  ******************************************************************************/
     292                 :            : 
     293                 :       9295 : char *acpi_ns_get_normalized_pathname(struct acpi_namespace_node *node,
     294                 :            :                                       u8 no_trailing)
     295                 :            : {
     296                 :       9295 :         char *name_buffer;
     297                 :       9295 :         acpi_size size;
     298                 :            : 
     299                 :       9295 :         ACPI_FUNCTION_TRACE_PTR(ns_get_normalized_pathname, node);
     300                 :            : 
     301                 :            :         /* Calculate required buffer size based on depth below root */
     302                 :            : 
     303                 :       9295 :         size = acpi_ns_build_normalized_path(node, NULL, 0, no_trailing);
     304         [ +  - ]:       9295 :         if (!size) {
     305                 :            :                 return_PTR(NULL);
     306                 :            :         }
     307                 :            : 
     308                 :            :         /* Allocate a buffer to be returned to caller */
     309                 :            : 
     310                 :       9295 :         name_buffer = ACPI_ALLOCATE_ZEROED(size);
     311         [ -  + ]:       9295 :         if (!name_buffer) {
     312                 :          0 :                 ACPI_ERROR((AE_INFO, "Could not allocate %u bytes", (u32)size));
     313                 :          0 :                 return_PTR(NULL);
     314                 :            :         }
     315                 :            : 
     316                 :            :         /* Build the path in the allocated buffer */
     317                 :            : 
     318                 :       9295 :         (void)acpi_ns_build_normalized_path(node, name_buffer, size,
     319                 :            :                                             no_trailing);
     320                 :            : 
     321                 :            :         ACPI_DEBUG_PRINT_RAW((ACPI_DB_NAMES, "%s: Path \"%s\"\n",
     322                 :       9295 :                               ACPI_GET_FUNCTION_NAME, name_buffer));
     323                 :            : 
     324                 :       9295 :         return_PTR(name_buffer);
     325                 :            : }
     326                 :            : 
     327                 :            : /*******************************************************************************
     328                 :            :  *
     329                 :            :  * FUNCTION:    acpi_ns_build_prefixed_pathname
     330                 :            :  *
     331                 :            :  * PARAMETERS:  prefix_scope        - Scope/Path that prefixes the internal path
     332                 :            :  *              internal_path       - Name or path of the namespace node
     333                 :            :  *
     334                 :            :  * RETURN:      None
     335                 :            :  *
     336                 :            :  * DESCRIPTION: Construct a fully qualified pathname from a concatenation of:
     337                 :            :  *              1) Path associated with the prefix_scope namespace node
     338                 :            :  *              2) External path representation of the Internal path
     339                 :            :  *
     340                 :            :  ******************************************************************************/
     341                 :            : 
     342                 :          0 : char *acpi_ns_build_prefixed_pathname(union acpi_generic_state *prefix_scope,
     343                 :            :                                       const char *internal_path)
     344                 :            : {
     345                 :          0 :         acpi_status status;
     346                 :          0 :         char *full_path = NULL;
     347                 :          0 :         char *external_path = NULL;
     348                 :          0 :         char *prefix_path = NULL;
     349                 :          0 :         u32 prefix_path_length = 0;
     350                 :            : 
     351                 :            :         /* If there is a prefix, get the pathname to it */
     352                 :            : 
     353   [ #  #  #  # ]:          0 :         if (prefix_scope && prefix_scope->scope.node) {
     354                 :          0 :                 prefix_path =
     355                 :          0 :                     acpi_ns_get_normalized_pathname(prefix_scope->scope.node,
     356                 :            :                                                     TRUE);
     357         [ #  # ]:          0 :                 if (prefix_path) {
     358                 :          0 :                         prefix_path_length = strlen(prefix_path);
     359                 :            :                 }
     360                 :            :         }
     361                 :            : 
     362                 :          0 :         status = acpi_ns_externalize_name(ACPI_UINT32_MAX, internal_path,
     363                 :            :                                           NULL, &external_path);
     364         [ #  # ]:          0 :         if (ACPI_FAILURE(status)) {
     365                 :          0 :                 goto cleanup;
     366                 :            :         }
     367                 :            : 
     368                 :            :         /* Merge the prefix path and the path. 2 is for one dot and trailing null */
     369                 :            : 
     370                 :          0 :         full_path =
     371                 :          0 :             ACPI_ALLOCATE_ZEROED(prefix_path_length + strlen(external_path) +
     372                 :            :                                  2);
     373         [ #  # ]:          0 :         if (!full_path) {
     374                 :          0 :                 goto cleanup;
     375                 :            :         }
     376                 :            : 
     377                 :            :         /* Don't merge if the External path is already fully qualified */
     378                 :            : 
     379   [ #  #  #  #  :          0 :         if (prefix_path && (*external_path != '\\') && (*external_path != '^')) {
                   #  # ]
     380                 :          0 :                 strcat(full_path, prefix_path);
     381         [ #  # ]:          0 :                 if (prefix_path[1]) {
     382                 :          0 :                         strcat(full_path, ".");
     383                 :            :                 }
     384                 :            :         }
     385                 :            : 
     386                 :          0 :         acpi_ns_normalize_pathname(external_path);
     387                 :          0 :         strcat(full_path, external_path);
     388                 :            : 
     389                 :          0 : cleanup:
     390         [ #  # ]:          0 :         if (prefix_path) {
     391                 :          0 :                 ACPI_FREE(prefix_path);
     392                 :            :         }
     393         [ #  # ]:          0 :         if (external_path) {
     394                 :          0 :                 ACPI_FREE(external_path);
     395                 :            :         }
     396                 :            : 
     397                 :          0 :         return (full_path);
     398                 :            : }
     399                 :            : 
     400                 :            : /*******************************************************************************
     401                 :            :  *
     402                 :            :  * FUNCTION:    acpi_ns_normalize_pathname
     403                 :            :  *
     404                 :            :  * PARAMETERS:  original_path       - Path to be normalized, in External format
     405                 :            :  *
     406                 :            :  * RETURN:      The original path is processed in-place
     407                 :            :  *
     408                 :            :  * DESCRIPTION: Remove trailing underscores from each element of a path.
     409                 :            :  *
     410                 :            :  *              For example:  \A___.B___.C___ becomes \A.B.C
     411                 :            :  *
     412                 :            :  ******************************************************************************/
     413                 :            : 
     414                 :          0 : static void acpi_ns_normalize_pathname(char *original_path)
     415                 :            : {
     416                 :          0 :         char *input_path = original_path;
     417                 :          0 :         char *new_path_buffer;
     418                 :          0 :         char *new_path;
     419                 :          0 :         u32 i;
     420                 :            : 
     421                 :            :         /* Allocate a temp buffer in which to construct the new path */
     422                 :            : 
     423                 :          0 :         new_path_buffer = ACPI_ALLOCATE_ZEROED(strlen(input_path) + 1);
     424                 :          0 :         new_path = new_path_buffer;
     425         [ #  # ]:          0 :         if (!new_path_buffer) {
     426                 :            :                 return;
     427                 :            :         }
     428                 :            : 
     429                 :            :         /* Special characters may appear at the beginning of the path */
     430                 :            : 
     431         [ #  # ]:          0 :         if (*input_path == '\\') {
     432                 :          0 :                 *new_path = *input_path;
     433                 :          0 :                 new_path++;
     434                 :          0 :                 input_path++;
     435                 :            :         }
     436                 :            : 
     437         [ #  # ]:          0 :         while (*input_path == '^') {
     438                 :          0 :                 *new_path = *input_path;
     439                 :          0 :                 new_path++;
     440                 :          0 :                 input_path++;
     441                 :            :         }
     442                 :            : 
     443                 :            :         /* Remainder of the path */
     444                 :            : 
     445         [ #  # ]:          0 :         while (*input_path) {
     446                 :            : 
     447                 :            :                 /* Do one nameseg at a time */
     448                 :            : 
     449   [ #  #  #  # ]:          0 :                 for (i = 0; (i < ACPI_NAMESEG_SIZE) && *input_path; i++) {
     450   [ #  #  #  # ]:          0 :                         if ((i == 0) || (*input_path != '_')) { /* First char is allowed to be underscore */
     451                 :          0 :                                 *new_path = *input_path;
     452                 :          0 :                                 new_path++;
     453                 :            :                         }
     454                 :            : 
     455                 :          0 :                         input_path++;
     456                 :            :                 }
     457                 :            : 
     458                 :            :                 /* Dot means that there are more namesegs to come */
     459                 :            : 
     460         [ #  # ]:          0 :                 if (*input_path == '.') {
     461                 :          0 :                         *new_path = *input_path;
     462                 :          0 :                         new_path++;
     463                 :          0 :                         input_path++;
     464                 :            :                 }
     465                 :            :         }
     466                 :            : 
     467                 :          0 :         *new_path = 0;
     468                 :          0 :         strcpy(original_path, new_path_buffer);
     469                 :          0 :         ACPI_FREE(new_path_buffer);
     470                 :            : }

Generated by: LCOV version 1.14