LCOV - code coverage report
Current view: top level - drivers/acpi/acpica - nsaccess.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 177 216 81.9 %
Date: 2022-04-01 14:35:51 Functions: 2 2 100.0 %
Branches: 77 113 68.1 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
       2                 :            : /*******************************************************************************
       3                 :            :  *
       4                 :            :  * Module Name: nsaccess - Top-level functions for accessing ACPI namespace
       5                 :            :  *
       6                 :            :  ******************************************************************************/
       7                 :            : 
       8                 :            : #include <acpi/acpi.h>
       9                 :            : #include "accommon.h"
      10                 :            : #include "amlcode.h"
      11                 :            : #include "acnamesp.h"
      12                 :            : #include "acdispat.h"
      13                 :            : 
      14                 :            : #ifdef ACPI_ASL_COMPILER
      15                 :            : #include "acdisasm.h"
      16                 :            : #endif
      17                 :            : 
      18                 :            : #define _COMPONENT          ACPI_NAMESPACE
      19                 :            : ACPI_MODULE_NAME("nsaccess")
      20                 :            : 
      21                 :            : /*******************************************************************************
      22                 :            :  *
      23                 :            :  * FUNCTION:    acpi_ns_root_initialize
      24                 :            :  *
      25                 :            :  * PARAMETERS:  None
      26                 :            :  *
      27                 :            :  * RETURN:      Status
      28                 :            :  *
      29                 :            :  * DESCRIPTION: Allocate and initialize the default root named objects
      30                 :            :  *
      31                 :            :  * MUTEX:       Locks namespace for entire execution
      32                 :            :  *
      33                 :            :  ******************************************************************************/
      34                 :         21 : acpi_status acpi_ns_root_initialize(void)
      35                 :            : {
      36                 :         21 :         acpi_status status;
      37                 :         21 :         const struct acpi_predefined_names *init_val = NULL;
      38                 :         21 :         struct acpi_namespace_node *new_node;
      39                 :         21 :         struct acpi_namespace_node *prev_node = NULL;
      40                 :         21 :         union acpi_operand_object *obj_desc;
      41                 :         21 :         acpi_string val = NULL;
      42                 :            : 
      43                 :         21 :         ACPI_FUNCTION_TRACE(ns_root_initialize);
      44                 :            : 
      45                 :         21 :         status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
      46         [ +  - ]:         21 :         if (ACPI_FAILURE(status)) {
      47                 :            :                 return_ACPI_STATUS(status);
      48                 :            :         }
      49                 :            : 
      50                 :            :         /*
      51                 :            :          * The global root ptr is initially NULL, so a non-NULL value indicates
      52                 :            :          * that acpi_ns_root_initialize() has already been called; just return.
      53                 :            :          */
      54         [ -  + ]:         21 :         if (acpi_gbl_root_node) {
      55                 :          0 :                 status = AE_OK;
      56                 :          0 :                 goto unlock_and_exit;
      57                 :            :         }
      58                 :            : 
      59                 :            :         /*
      60                 :            :          * Tell the rest of the subsystem that the root is initialized
      61                 :            :          * (This is OK because the namespace is locked)
      62                 :            :          */
      63                 :         21 :         acpi_gbl_root_node = &acpi_gbl_root_node_struct;
      64                 :            : 
      65                 :            :         /* Enter the predefined names in the name table */
      66                 :            : 
      67                 :            :         ACPI_DEBUG_PRINT((ACPI_DB_INFO,
      68                 :         21 :                           "Entering predefined entries into namespace\n"));
      69                 :            : 
      70                 :            :         /*
      71                 :            :          * Create the initial (default) namespace.
      72                 :            :          * This namespace looks like something similar to this:
      73                 :            :          *
      74                 :            :          *   ACPI Namespace (from Namespace Root):
      75                 :            :          *    0  _GPE Scope        00203160 00
      76                 :            :          *    0  _PR_ Scope        002031D0 00
      77                 :            :          *    0  _SB_ Device       00203240 00 Notify Object: 0020ADD8
      78                 :            :          *    0  _SI_ Scope        002032B0 00
      79                 :            :          *    0  _TZ_ Device       00203320 00
      80                 :            :          *    0  _REV Integer      00203390 00 = 0000000000000002
      81                 :            :          *    0  _OS_ String       00203488 00 Len 14 "Microsoft Windows NT"
      82                 :            :          *    0  _GL_ Mutex        00203580 00 Object 002035F0
      83                 :            :          *    0  _OSI Method       00203678 00 Args 1 Len 0000 Aml 00000000
      84                 :            :          */
      85         [ +  + ]:        210 :         for (init_val = acpi_gbl_pre_defined_names; init_val->name; init_val++) {
      86                 :        189 :                 status = AE_OK;
      87                 :            : 
      88                 :            :                 /* _OSI is optional for now, will be permanent later */
      89                 :            : 
      90         [ +  + ]:        189 :                 if (!strcmp(init_val->name, "_OSI")
      91         [ -  + ]:         21 :                     && !acpi_gbl_create_osi_method) {
      92                 :          0 :                         continue;
      93                 :            :                 }
      94                 :            : 
      95                 :            :                 /*
      96                 :            :                  * Create, init, and link the new predefined name
      97                 :            :                  * Note: No need to use acpi_ns_lookup here because all the
      98                 :            :                  * predefined names are at the root level. It is much easier to
      99                 :            :                  * just create and link the new node(s) here.
     100                 :            :                  */
     101                 :        189 :                 new_node =
     102                 :        189 :                     ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_namespace_node));
     103         [ -  + ]:        189 :                 if (!new_node) {
     104                 :          0 :                         status = AE_NO_MEMORY;
     105                 :          0 :                         goto unlock_and_exit;
     106                 :            :                 }
     107                 :            : 
     108                 :        189 :                 ACPI_COPY_NAMESEG(new_node->name.ascii, init_val->name);
     109                 :        189 :                 new_node->descriptor_type = ACPI_DESC_TYPE_NAMED;
     110                 :        189 :                 new_node->type = init_val->type;
     111                 :            : 
     112         [ +  + ]:        189 :                 if (!prev_node) {
     113                 :         21 :                         acpi_gbl_root_node_struct.child = new_node;
     114                 :            :                 } else {
     115                 :        168 :                         prev_node->peer = new_node;
     116                 :            :                 }
     117                 :            : 
     118                 :        189 :                 new_node->parent = &acpi_gbl_root_node_struct;
     119                 :        189 :                 prev_node = new_node;
     120                 :            : 
     121                 :            :                 /*
     122                 :            :                  * Name entered successfully. If entry in pre_defined_names[] specifies
     123                 :            :                  * an initial value, create the initial value.
     124                 :            :                  */
     125         [ +  + ]:        189 :                 if (init_val->val) {
     126                 :         84 :                         status = acpi_os_predefined_override(init_val, &val);
     127         [ -  + ]:         84 :                         if (ACPI_FAILURE(status)) {
     128                 :          0 :                                 ACPI_ERROR((AE_INFO,
     129                 :            :                                             "Could not override predefined %s",
     130                 :            :                                             init_val->name));
     131                 :            :                         }
     132                 :            : 
     133         [ +  - ]:         84 :                         if (!val) {
     134                 :         84 :                                 val = init_val->val;
     135                 :            :                         }
     136                 :            : 
     137                 :            :                         /*
     138                 :            :                          * Entry requests an initial value, allocate a
     139                 :            :                          * descriptor for it.
     140                 :            :                          */
     141                 :         84 :                         obj_desc =
     142                 :         84 :                             acpi_ut_create_internal_object(init_val->type);
     143         [ -  + ]:         84 :                         if (!obj_desc) {
     144                 :          0 :                                 status = AE_NO_MEMORY;
     145                 :          0 :                                 goto unlock_and_exit;
     146                 :            :                         }
     147                 :            : 
     148                 :            :                         /*
     149                 :            :                          * Convert value string from table entry to
     150                 :            :                          * internal representation. Only types actually
     151                 :            :                          * used for initial values are implemented here.
     152                 :            :                          */
     153   [ +  +  +  +  :         84 :                         switch (init_val->type) {
                      - ]
     154                 :         21 :                         case ACPI_TYPE_METHOD:
     155                 :            : 
     156                 :         21 :                                 obj_desc->method.param_count =
     157                 :         21 :                                     (u8) ACPI_TO_INTEGER(val);
     158                 :         21 :                                 obj_desc->common.flags |= AOPOBJ_DATA_VALID;
     159                 :            : 
     160                 :            : #if defined (ACPI_ASL_COMPILER)
     161                 :            : 
     162                 :            :                                 /* Save the parameter count for the iASL compiler */
     163                 :            : 
     164                 :            :                                 new_node->value = obj_desc->method.param_count;
     165                 :            : #else
     166                 :            :                                 /* Mark this as a very SPECIAL method (_OSI) */
     167                 :            : 
     168                 :         21 :                                 obj_desc->method.info_flags =
     169                 :            :                                     ACPI_METHOD_INTERNAL_ONLY;
     170                 :         21 :                                 obj_desc->method.dispatch.implementation =
     171                 :            :                                     acpi_ut_osi_implementation;
     172                 :            : #endif
     173                 :         21 :                                 break;
     174                 :            : 
     175                 :         21 :                         case ACPI_TYPE_INTEGER:
     176                 :            : 
     177                 :         21 :                                 obj_desc->integer.value = ACPI_TO_INTEGER(val);
     178                 :         21 :                                 break;
     179                 :            : 
     180                 :         21 :                         case ACPI_TYPE_STRING:
     181                 :            : 
     182                 :            :                                 /* Build an object around the static string */
     183                 :            : 
     184                 :         21 :                                 obj_desc->string.length = (u32)strlen(val);
     185                 :         21 :                                 obj_desc->string.pointer = val;
     186                 :         21 :                                 obj_desc->common.flags |= AOPOBJ_STATIC_POINTER;
     187                 :         21 :                                 break;
     188                 :            : 
     189                 :         21 :                         case ACPI_TYPE_MUTEX:
     190                 :            : 
     191                 :         21 :                                 obj_desc->mutex.node = new_node;
     192                 :         21 :                                 obj_desc->mutex.sync_level =
     193                 :         21 :                                     (u8) (ACPI_TO_INTEGER(val) - 1);
     194                 :            : 
     195                 :            :                                 /* Create a mutex */
     196                 :            : 
     197                 :         21 :                                 status =
     198                 :         21 :                                     acpi_os_create_mutex(&obj_desc->mutex.
     199                 :            :                                                          os_mutex);
     200         [ -  + ]:         21 :                                 if (ACPI_FAILURE(status)) {
     201                 :          0 :                                         acpi_ut_remove_reference(obj_desc);
     202                 :          0 :                                         goto unlock_and_exit;
     203                 :            :                                 }
     204                 :            : 
     205                 :            :                                 /* Special case for ACPI Global Lock */
     206                 :            : 
     207         [ +  - ]:         21 :                                 if (strcmp(init_val->name, "_GL_") == 0) {
     208                 :         21 :                                         acpi_gbl_global_lock_mutex = obj_desc;
     209                 :            : 
     210                 :            :                                         /* Create additional counting semaphore for global lock */
     211                 :            : 
     212                 :         21 :                                         status =
     213                 :         21 :                                             acpi_os_create_semaphore(1, 0,
     214                 :            :                                                                      &acpi_gbl_global_lock_semaphore);
     215         [ -  + ]:         21 :                                         if (ACPI_FAILURE(status)) {
     216                 :          0 :                                                 acpi_ut_remove_reference
     217                 :            :                                                     (obj_desc);
     218                 :          0 :                                                 goto unlock_and_exit;
     219                 :            :                                         }
     220                 :            :                                 }
     221                 :            :                                 break;
     222                 :            : 
     223                 :          0 :                         default:
     224                 :            : 
     225                 :          0 :                                 ACPI_ERROR((AE_INFO,
     226                 :            :                                             "Unsupported initial type value 0x%X",
     227                 :            :                                             init_val->type));
     228                 :          0 :                                 acpi_ut_remove_reference(obj_desc);
     229                 :          0 :                                 obj_desc = NULL;
     230                 :          0 :                                 continue;
     231                 :            :                         }
     232                 :            : 
     233                 :            :                         /* Store pointer to value descriptor in the Node */
     234                 :            : 
     235                 :         84 :                         status = acpi_ns_attach_object(new_node, obj_desc,
     236                 :         84 :                                                        obj_desc->common.type);
     237                 :            : 
     238                 :            :                         /* Remove local reference to the object */
     239                 :            : 
     240                 :         84 :                         acpi_ut_remove_reference(obj_desc);
     241                 :            :                 }
     242                 :            :         }
     243                 :            : 
     244                 :         21 : unlock_and_exit:
     245                 :         21 :         (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
     246                 :            : 
     247                 :            :         /* Save a handle to "_GPE", it is always present */
     248                 :            : 
     249         [ +  - ]:         21 :         if (ACPI_SUCCESS(status)) {
     250                 :         21 :                 status = acpi_ns_get_node(NULL, "\\_GPE", ACPI_NS_NO_UPSEARCH,
     251                 :            :                                           &acpi_gbl_fadt_gpe_device);
     252                 :            :         }
     253                 :            : 
     254                 :            :         return_ACPI_STATUS(status);
     255                 :            : }
     256                 :            : 
     257                 :            : /*******************************************************************************
     258                 :            :  *
     259                 :            :  * FUNCTION:    acpi_ns_lookup
     260                 :            :  *
     261                 :            :  * PARAMETERS:  scope_info      - Current scope info block
     262                 :            :  *              pathname        - Search pathname, in internal format
     263                 :            :  *                                (as represented in the AML stream)
     264                 :            :  *              type            - Type associated with name
     265                 :            :  *              interpreter_mode - IMODE_LOAD_PASS2 => add name if not found
     266                 :            :  *              flags           - Flags describing the search restrictions
     267                 :            :  *              walk_state      - Current state of the walk
     268                 :            :  *              return_node     - Where the Node is placed (if found
     269                 :            :  *                                or created successfully)
     270                 :            :  *
     271                 :            :  * RETURN:      Status
     272                 :            :  *
     273                 :            :  * DESCRIPTION: Find or enter the passed name in the name space.
     274                 :            :  *              Log an error if name not found in Exec mode.
     275                 :            :  *
     276                 :            :  * MUTEX:       Assumes namespace is locked.
     277                 :            :  *
     278                 :            :  ******************************************************************************/
     279                 :            : 
     280                 :            : acpi_status
     281                 :     118713 : acpi_ns_lookup(union acpi_generic_state *scope_info,
     282                 :            :                char *pathname,
     283                 :            :                acpi_object_type type,
     284                 :            :                acpi_interpreter_mode interpreter_mode,
     285                 :            :                u32 flags,
     286                 :            :                struct acpi_walk_state *walk_state,
     287                 :            :                struct acpi_namespace_node **return_node)
     288                 :            : {
     289                 :     118713 :         acpi_status status;
     290                 :     118713 :         char *path = pathname;
     291                 :     118713 :         char *external_path;
     292                 :     118713 :         struct acpi_namespace_node *prefix_node;
     293                 :     118713 :         struct acpi_namespace_node *current_node = NULL;
     294                 :     118713 :         struct acpi_namespace_node *this_node = NULL;
     295                 :     118713 :         u32 num_segments;
     296                 :     118713 :         u32 num_carats;
     297                 :     118713 :         acpi_name simple_name;
     298                 :     118713 :         acpi_object_type type_to_check_for;
     299                 :     118713 :         acpi_object_type this_search_type;
     300                 :     118713 :         u32 search_parent_flag = ACPI_NS_SEARCH_PARENT;
     301                 :     118713 :         u32 local_flags;
     302                 :     118713 :         acpi_interpreter_mode local_interpreter_mode;
     303                 :            : 
     304                 :     118713 :         ACPI_FUNCTION_TRACE(ns_lookup);
     305                 :            : 
     306         [ +  - ]:     118713 :         if (!return_node) {
     307                 :            :                 return_ACPI_STATUS(AE_BAD_PARAMETER);
     308                 :            :         }
     309                 :            : 
     310                 :     118713 :         local_flags = flags &
     311                 :            :             ~(ACPI_NS_ERROR_IF_FOUND | ACPI_NS_OVERRIDE_IF_FOUND |
     312                 :            :               ACPI_NS_SEARCH_PARENT);
     313                 :     118713 :         *return_node = ACPI_ENTRY_NOT_FOUND;
     314                 :     118713 :         acpi_gbl_ns_lookup_count++;
     315                 :            : 
     316         [ +  - ]:     118713 :         if (!acpi_gbl_root_node) {
     317                 :            :                 return_ACPI_STATUS(AE_NO_NAMESPACE);
     318                 :            :         }
     319                 :            : 
     320                 :            :         /* Get the prefix scope. A null scope means use the root scope */
     321                 :            : 
     322   [ +  -  +  + ]:     118713 :         if ((!scope_info) || (!scope_info->scope.node)) {
     323                 :            :                 ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
     324                 :            :                                   "Null scope prefix, using root node (%p)\n",
     325                 :            :                                   acpi_gbl_root_node));
     326                 :            : 
     327                 :            :                 prefix_node = acpi_gbl_root_node;
     328                 :            :         } else {
     329                 :     117012 :                 prefix_node = scope_info->scope.node;
     330         [ -  + ]:     117012 :                 if (ACPI_GET_DESCRIPTOR_TYPE(prefix_node) !=
     331                 :            :                     ACPI_DESC_TYPE_NAMED) {
     332                 :          0 :                         ACPI_ERROR((AE_INFO, "%p is not a namespace node [%s]",
     333                 :            :                                     prefix_node,
     334                 :            :                                     acpi_ut_get_descriptor_name(prefix_node)));
     335                 :          0 :                         return_ACPI_STATUS(AE_AML_INTERNAL);
     336                 :            :                 }
     337                 :            : 
     338         [ +  - ]:     117012 :                 if (!(flags & ACPI_NS_PREFIX_IS_SCOPE)) {
     339                 :            :                         /*
     340                 :            :                          * This node might not be a actual "scope" node (such as a
     341                 :            :                          * Device/Method, etc.)  It could be a Package or other object
     342                 :            :                          * node. Backup up the tree to find the containing scope node.
     343                 :            :                          */
     344         [ -  + ]:     117012 :                         while (!acpi_ns_opens_scope(prefix_node->type) &&
     345         [ #  # ]:          0 :                                prefix_node->type != ACPI_TYPE_ANY) {
     346                 :          0 :                                 prefix_node = prefix_node->parent;
     347                 :            :                         }
     348                 :            :                 }
     349                 :            :         }
     350                 :            : 
     351                 :            :         /* Save type. TBD: may be no longer necessary */
     352                 :            : 
     353                 :     118713 :         type_to_check_for = type;
     354                 :            : 
     355                 :            :         /*
     356                 :            :          * Begin examination of the actual pathname
     357                 :            :          */
     358         [ -  + ]:     118713 :         if (!pathname) {
     359                 :            : 
     360                 :            :                 /* A Null name_path is allowed and refers to the root */
     361                 :            : 
     362                 :          0 :                 num_segments = 0;
     363                 :          0 :                 this_node = acpi_gbl_root_node;
     364                 :          0 :                 path = "";
     365                 :            : 
     366                 :            :                 ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
     367                 :            :                                   "Null Pathname (Zero segments), Flags=%X\n",
     368                 :          0 :                                   flags));
     369                 :            :         } else {
     370                 :            :                 /*
     371                 :            :                  * Name pointer is valid (and must be in internal name format)
     372                 :            :                  *
     373                 :            :                  * Check for scope prefixes:
     374                 :            :                  *
     375                 :            :                  * As represented in the AML stream, a namepath consists of an
     376                 :            :                  * optional scope prefix followed by a name segment part.
     377                 :            :                  *
     378                 :            :                  * If present, the scope prefix is either a Root Prefix (in
     379                 :            :                  * which case the name is fully qualified), or one or more
     380                 :            :                  * Parent Prefixes (in which case the name's scope is relative
     381                 :            :                  * to the current scope).
     382                 :            :                  */
     383         [ +  + ]:     118713 :                 if (*path == (u8) AML_ROOT_PREFIX) {
     384                 :            : 
     385                 :            :                         /* Pathname is fully qualified, start from the root */
     386                 :            : 
     387                 :       2310 :                         this_node = acpi_gbl_root_node;
     388                 :       2310 :                         search_parent_flag = ACPI_NS_NO_UPSEARCH;
     389                 :            : 
     390                 :            :                         /* Point to name segment part */
     391                 :            : 
     392                 :       2310 :                         path++;
     393                 :            : 
     394                 :            :                         ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
     395                 :            :                                           "Path is absolute from root [%p]\n",
     396                 :       2310 :                                           this_node));
     397                 :            :                 } else {
     398                 :            :                         /* Pathname is relative to current scope, start there */
     399                 :            : 
     400                 :            :                         ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
     401                 :            :                                           "Searching relative to prefix scope [%4.4s] (%p)\n",
     402                 :            :                                           acpi_ut_get_node_name(prefix_node),
     403                 :     116403 :                                           prefix_node));
     404                 :            : 
     405                 :            :                         /*
     406                 :            :                          * Handle multiple Parent Prefixes (carat) by just getting
     407                 :            :                          * the parent node for each prefix instance.
     408                 :            :                          */
     409                 :     116403 :                         this_node = prefix_node;
     410                 :     116403 :                         num_carats = 0;
     411         [ +  + ]:     116424 :                         while (*path == (u8) AML_PARENT_PREFIX) {
     412                 :            : 
     413                 :            :                                 /* Name is fully qualified, no search rules apply */
     414                 :            : 
     415                 :         21 :                                 search_parent_flag = ACPI_NS_NO_UPSEARCH;
     416                 :            : 
     417                 :            :                                 /*
     418                 :            :                                  * Point past this prefix to the name segment
     419                 :            :                                  * part or the next Parent Prefix
     420                 :            :                                  */
     421                 :         21 :                                 path++;
     422                 :            : 
     423                 :            :                                 /* Backup to the parent node */
     424                 :            : 
     425                 :         21 :                                 num_carats++;
     426                 :         21 :                                 this_node = this_node->parent;
     427         [ -  + ]:         21 :                                 if (!this_node) {
     428                 :            :                                         /*
     429                 :            :                                          * Current scope has no parent scope. Externalize
     430                 :            :                                          * the internal path for error message.
     431                 :            :                                          */
     432                 :          0 :                                         status =
     433                 :          0 :                                             acpi_ns_externalize_name
     434                 :            :                                             (ACPI_UINT32_MAX, pathname, NULL,
     435                 :            :                                              &external_path);
     436         [ #  # ]:          0 :                                         if (ACPI_SUCCESS(status)) {
     437                 :          0 :                                                 ACPI_ERROR((AE_INFO,
     438                 :            :                                                             "%s: Path has too many parent prefixes (^)",
     439                 :            :                                                             external_path));
     440                 :            : 
     441                 :          0 :                                                 ACPI_FREE(external_path);
     442                 :            :                                         }
     443                 :            : 
     444                 :          0 :                                         return_ACPI_STATUS(AE_NOT_FOUND);
     445                 :            :                                 }
     446                 :            :                         }
     447                 :            : 
     448                 :            :                         if (search_parent_flag == ACPI_NS_NO_UPSEARCH) {
     449                 :            :                                 ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
     450                 :            :                                                   "Search scope is [%4.4s], path has %u carat(s)\n",
     451                 :            :                                                   acpi_ut_get_node_name
     452                 :     118713 :                                                   (this_node), num_carats));
     453                 :            :                         }
     454                 :            :                 }
     455                 :            : 
     456                 :            :                 /*
     457                 :            :                  * Determine the number of ACPI name segments in this pathname.
     458                 :            :                  *
     459                 :            :                  * The segment part consists of either:
     460                 :            :                  *  - A Null name segment (0)
     461                 :            :                  *  - A dual_name_prefix followed by two 4-byte name segments
     462                 :            :                  *  - A multi_name_prefix followed by a byte indicating the
     463                 :            :                  *      number of segments and the segments themselves.
     464                 :            :                  *  - A single 4-byte name segment
     465                 :            :                  *
     466                 :            :                  * Examine the name prefix opcode, if any, to determine the number of
     467                 :            :                  * segments.
     468                 :            :                  */
     469   [ +  +  +  + ]:     118713 :                 switch (*path) {
     470                 :         42 :                 case 0:
     471                 :            :                         /*
     472                 :            :                          * Null name after a root or parent prefixes. We already
     473                 :            :                          * have the correct target node and there are no name segments.
     474                 :            :                          */
     475                 :         42 :                         num_segments = 0;
     476                 :         42 :                         type = this_node->type;
     477                 :            : 
     478                 :            :                         ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
     479                 :            :                                           "Prefix-only Pathname (Zero name segments), Flags=%X\n",
     480                 :         42 :                                           flags));
     481                 :         42 :                         break;
     482                 :            : 
     483                 :        189 :                 case AML_DUAL_NAME_PREFIX:
     484                 :            : 
     485                 :            :                         /* More than one name_seg, search rules do not apply */
     486                 :            : 
     487                 :        189 :                         search_parent_flag = ACPI_NS_NO_UPSEARCH;
     488                 :            : 
     489                 :            :                         /* Two segments, point to first name segment */
     490                 :            : 
     491                 :        189 :                         num_segments = 2;
     492                 :        189 :                         path++;
     493                 :            : 
     494                 :            :                         ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
     495                 :            :                                           "Dual Pathname (2 segments, Flags=%X)\n",
     496                 :        189 :                                           flags));
     497                 :        189 :                         break;
     498                 :            : 
     499                 :        483 :                 case AML_MULTI_NAME_PREFIX:
     500                 :            : 
     501                 :            :                         /* More than one name_seg, search rules do not apply */
     502                 :            : 
     503                 :        483 :                         search_parent_flag = ACPI_NS_NO_UPSEARCH;
     504                 :            : 
     505                 :            :                         /* Extract segment count, point to first name segment */
     506                 :            : 
     507                 :        483 :                         path++;
     508                 :        483 :                         num_segments = (u32) (u8) * path;
     509                 :        483 :                         path++;
     510                 :            : 
     511                 :            :                         ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
     512                 :            :                                           "Multi Pathname (%u Segments, Flags=%X)\n",
     513                 :        483 :                                           num_segments, flags));
     514                 :        483 :                         break;
     515                 :            : 
     516                 :            :                 default:
     517                 :            :                         /*
     518                 :            :                          * Not a Null name, no Dual or Multi prefix, hence there is
     519                 :            :                          * only one name segment and Pathname is already pointing to it.
     520                 :            :                          */
     521                 :            :                         num_segments = 1;
     522                 :            : 
     523                 :            :                         ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
     524                 :            :                                           "Simple Pathname (1 segment, Flags=%X)\n",
     525                 :            :                                           flags));
     526                 :            :                         break;
     527                 :            :                 }
     528                 :            : 
     529                 :     118713 :                 ACPI_DEBUG_EXEC(acpi_ns_print_pathname(num_segments, path));
     530                 :            :         }
     531                 :            : 
     532                 :            :         /*
     533                 :            :          * Search namespace for each segment of the name. Loop through and
     534                 :            :          * verify (or add to the namespace) each name segment.
     535                 :            :          *
     536                 :            :          * The object type is significant only at the last name
     537                 :            :          * segment. (We don't care about the types along the path, only
     538                 :            :          * the type of the final target object.)
     539                 :            :          */
     540                 :     118713 :         this_search_type = ACPI_TYPE_ANY;
     541                 :     118713 :         current_node = this_node;
     542                 :            : 
     543         [ +  + ]:     162414 :         while (num_segments && current_node) {
     544                 :     120162 :                 num_segments--;
     545         [ +  + ]:     120162 :                 if (!num_segments) {
     546                 :            : 
     547                 :            :                         /* This is the last segment, enable typechecking */
     548                 :            : 
     549                 :     118671 :                         this_search_type = type;
     550                 :            : 
     551                 :            :                         /*
     552                 :            :                          * Only allow automatic parent search (search rules) if the caller
     553                 :            :                          * requested it AND we have a single, non-fully-qualified name_seg
     554                 :            :                          */
     555         [ +  + ]:     118671 :                         if ((search_parent_flag != ACPI_NS_NO_UPSEARCH) &&
     556         [ +  + ]:     116277 :                             (flags & ACPI_NS_SEARCH_PARENT)) {
     557                 :      13524 :                                 local_flags |= ACPI_NS_SEARCH_PARENT;
     558                 :            :                         }
     559                 :            : 
     560                 :            :                         /* Set error flag according to caller */
     561                 :            : 
     562         [ +  + ]:     118671 :                         if (flags & ACPI_NS_ERROR_IF_FOUND) {
     563                 :       6405 :                                 local_flags |= ACPI_NS_ERROR_IF_FOUND;
     564                 :            :                         }
     565                 :            : 
     566                 :            :                         /* Set override flag according to caller */
     567                 :            : 
     568         [ -  + ]:     118671 :                         if (flags & ACPI_NS_OVERRIDE_IF_FOUND) {
     569                 :          0 :                                 local_flags |= ACPI_NS_OVERRIDE_IF_FOUND;
     570                 :            :                         }
     571                 :            :                 }
     572                 :            : 
     573                 :            :                 /* Handle opcodes that create a new name_seg via a full name_path */
     574                 :            : 
     575                 :     120162 :                 local_interpreter_mode = interpreter_mode;
     576   [ +  +  +  + ]:     120162 :                 if ((flags & ACPI_NS_PREFIX_MUST_EXIST) && (num_segments > 0)) {
     577                 :            : 
     578                 :            :                         /* Every element of the path must exist (except for the final name_seg) */
     579                 :            : 
     580                 :         84 :                         local_interpreter_mode = ACPI_IMODE_EXECUTE;
     581                 :            :                 }
     582                 :            : 
     583                 :            :                 /* Extract one ACPI name from the front of the pathname */
     584                 :            : 
     585                 :     120162 :                 ACPI_MOVE_32_TO_32(&simple_name, path);
     586                 :            : 
     587                 :            :                 /* Try to find the single (4 character) ACPI name */
     588                 :            : 
     589                 :     120162 :                 status =
     590                 :     120162 :                     acpi_ns_search_and_enter(simple_name, walk_state,
     591                 :            :                                              current_node,
     592                 :            :                                              local_interpreter_mode,
     593                 :            :                                              this_search_type, local_flags,
     594                 :            :                                              &this_node);
     595         [ +  + ]:     120162 :                 if (ACPI_FAILURE(status)) {
     596         [ +  - ]:      76461 :                         if (status == AE_NOT_FOUND) {
     597                 :            : #if !defined ACPI_ASL_COMPILER  /* Note: iASL reports this error by itself, not needed here */
     598         [ -  + ]:      76461 :                                 if (flags & ACPI_NS_PREFIX_MUST_EXIST) {
     599                 :          0 :                                         acpi_os_printf(ACPI_MSG_BIOS_ERROR
     600                 :            :                                                        "Object does not exist: %4.4s\n",
     601                 :            :                                                        (char *)&simple_name);
     602                 :            :                                 }
     603                 :            : #endif
     604                 :            :                                 /* Name not found in ACPI namespace */
     605                 :            : 
     606                 :            :                                 ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
     607                 :            :                                                   "Name [%4.4s] not found in scope [%4.4s] %p\n",
     608                 :            :                                                   (char *)&simple_name,
     609                 :            :                                                   (char *)&current_node->name,
     610                 :      76461 :                                                   current_node));
     611                 :            :                         }
     612                 :            : #ifdef ACPI_EXEC_APP
     613                 :            :                         if ((status == AE_ALREADY_EXISTS) &&
     614                 :            :                             (this_node->flags & ANOBJ_NODE_EARLY_INIT)) {
     615                 :            :                                 this_node->flags &= ~ANOBJ_NODE_EARLY_INIT;
     616                 :            :                                 status = AE_OK;
     617                 :            :                         }
     618                 :            : #endif
     619                 :            : 
     620                 :            : #ifdef ACPI_ASL_COMPILER
     621                 :            :                         /*
     622                 :            :                          * If this ACPI name already exists within the namespace as an
     623                 :            :                          * external declaration, then mark the external as a conflicting
     624                 :            :                          * declaration and proceed to process the current node as if it did
     625                 :            :                          * not exist in the namespace. If this node is not processed as
     626                 :            :                          * normal, then it could cause improper namespace resolution
     627                 :            :                          * by failing to open a new scope.
     628                 :            :                          */
     629                 :            :                         if (acpi_gbl_disasm_flag &&
     630                 :            :                             (status == AE_ALREADY_EXISTS) &&
     631                 :            :                             ((this_node->flags & ANOBJ_IS_EXTERNAL) ||
     632                 :            :                              (walk_state
     633                 :            :                               && walk_state->opcode == AML_EXTERNAL_OP))) {
     634                 :            :                                 this_node->flags &= ~ANOBJ_IS_EXTERNAL;
     635                 :            :                                 this_node->type = (u8)this_search_type;
     636                 :            :                                 if (walk_state->opcode != AML_EXTERNAL_OP) {
     637                 :            :                                         acpi_dm_mark_external_conflict
     638                 :            :                                             (this_node);
     639                 :            :                                 }
     640                 :            :                                 break;
     641                 :            :                         }
     642                 :            : #endif
     643                 :            : 
     644                 :      76461 :                         *return_node = this_node;
     645                 :      76461 :                         return_ACPI_STATUS(status);
     646                 :            :                 }
     647                 :            : 
     648                 :            :                 /* More segments to follow? */
     649                 :            : 
     650         [ +  + ]:      43701 :                 if (num_segments > 0) {
     651                 :            :                         /*
     652                 :            :                          * If we have an alias to an object that opens a scope (such as a
     653                 :            :                          * device or processor), we need to dereference the alias here so
     654                 :            :                          * that we can access any children of the original node (via the
     655                 :            :                          * remaining segments).
     656                 :            :                          */
     657         [ -  + ]:       1491 :                         if (this_node->type == ACPI_TYPE_LOCAL_ALIAS) {
     658         [ #  # ]:          0 :                                 if (!this_node->object) {
     659                 :            :                                         return_ACPI_STATUS(AE_NOT_EXIST);
     660                 :            :                                 }
     661                 :            : 
     662         [ #  # ]:          0 :                                 if (acpi_ns_opens_scope
     663                 :            :                                     (((struct acpi_namespace_node *)
     664                 :          0 :                                       this_node->object)->type)) {
     665                 :          0 :                                         this_node =
     666                 :            :                                             (struct acpi_namespace_node *)
     667                 :          0 :                                             this_node->object;
     668                 :            :                                 }
     669                 :            :                         }
     670                 :            :                 }
     671                 :            : 
     672                 :            :                 /* Special handling for the last segment (num_segments == 0) */
     673                 :            : 
     674                 :            :                 else {
     675                 :            :                         /*
     676                 :            :                          * Sanity typecheck of the target object:
     677                 :            :                          *
     678                 :            :                          * If 1) This is the last segment (num_segments == 0)
     679                 :            :                          *    2) And we are looking for a specific type
     680                 :            :                          *       (Not checking for TYPE_ANY)
     681                 :            :                          *    3) Which is not an alias
     682                 :            :                          *    4) Which is not a local type (TYPE_SCOPE)
     683                 :            :                          *    5) And the type of target object is known (not TYPE_ANY)
     684                 :            :                          *    6) And target object does not match what we are looking for
     685                 :            :                          *
     686                 :            :                          * Then we have a type mismatch. Just warn and ignore it.
     687                 :            :                          */
     688                 :      42210 :                         if ((type_to_check_for != ACPI_TYPE_ANY) &&
     689         [ +  + ]:      42210 :                             (type_to_check_for != ACPI_TYPE_LOCAL_ALIAS) &&
     690                 :       4305 :                             (type_to_check_for != ACPI_TYPE_LOCAL_METHOD_ALIAS)
     691         [ +  + ]:       4305 :                             && (type_to_check_for != ACPI_TYPE_LOCAL_SCOPE)
     692         [ +  - ]:       4011 :                             && (this_node->type != ACPI_TYPE_ANY)
     693         [ -  + ]:       4011 :                             && (this_node->type != type_to_check_for)) {
     694                 :            : 
     695                 :            :                                 /* Complain about a type mismatch */
     696                 :            : 
     697                 :          0 :                                 ACPI_WARNING((AE_INFO,
     698                 :            :                                               "NsLookup: Type mismatch on %4.4s (%s), searching for (%s)",
     699                 :            :                                               ACPI_CAST_PTR(char, &simple_name),
     700                 :            :                                               acpi_ut_get_type_name(this_node->
     701                 :            :                                                                     type),
     702                 :            :                                               acpi_ut_get_type_name
     703                 :            :                                               (type_to_check_for)));
     704                 :            :                         }
     705                 :            : 
     706                 :            :                         /*
     707                 :            :                          * If this is the last name segment and we are not looking for a
     708                 :            :                          * specific type, but the type of found object is known, use that
     709                 :            :                          * type to (later) see if it opens a scope.
     710                 :            :                          */
     711         [ +  + ]:      42210 :                         if (type == ACPI_TYPE_ANY) {
     712                 :      37905 :                                 type = this_node->type;
     713                 :            :                         }
     714                 :            :                 }
     715                 :            : 
     716                 :            :                 /* Point to next name segment and make this node current */
     717                 :            : 
     718                 :      43701 :                 path += ACPI_NAMESEG_SIZE;
     719                 :      43701 :                 current_node = this_node;
     720                 :            :         }
     721                 :            : 
     722                 :            :         /* Always check if we need to open a new scope */
     723                 :            : 
     724   [ +  +  +  - ]:      42252 :         if (!(flags & ACPI_NS_DONT_OPEN_SCOPE) && (walk_state)) {
     725                 :            :                 /*
     726                 :            :                  * If entry is a type which opens a scope, push the new scope on the
     727                 :            :                  * scope stack.
     728                 :            :                  */
     729         [ +  + ]:       6279 :                 if (acpi_ns_opens_scope(type)) {
     730                 :       3066 :                         status =
     731                 :       3066 :                             acpi_ds_scope_stack_push(this_node, type,
     732                 :            :                                                      walk_state);
     733         [ +  - ]:       3066 :                         if (ACPI_FAILURE(status)) {
     734                 :            :                                 return_ACPI_STATUS(status);
     735                 :            :                         }
     736                 :            :                 }
     737                 :            :         }
     738                 :            : #ifdef ACPI_EXEC_APP
     739                 :            :         if (flags & ACPI_NS_EARLY_INIT) {
     740                 :            :                 this_node->flags |= ANOBJ_NODE_EARLY_INIT;
     741                 :            :         }
     742                 :            : #endif
     743                 :            : 
     744                 :      42252 :         *return_node = this_node;
     745                 :      42252 :         return_ACPI_STATUS(AE_OK);
     746                 :            : }

Generated by: LCOV version 1.14