root/drivers/acpi/acpica/nsaccess.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ACPI_MODULE_NAME
  2. acpi_ns_lookup

   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 acpi_status acpi_ns_root_initialize(void)
  35 {
  36         acpi_status status;
  37         const struct acpi_predefined_names *init_val = NULL;
  38         struct acpi_namespace_node *new_node;
  39         struct acpi_namespace_node *prev_node = NULL;
  40         union acpi_operand_object *obj_desc;
  41         acpi_string val = NULL;
  42 
  43         ACPI_FUNCTION_TRACE(ns_root_initialize);
  44 
  45         status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
  46         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         if (acpi_gbl_root_node) {
  55                 status = AE_OK;
  56                 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         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                           "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         for (init_val = acpi_gbl_pre_defined_names; init_val->name; init_val++) {
  86                 status = AE_OK;
  87 
  88                 /* _OSI is optional for now, will be permanent later */
  89 
  90                 if (!strcmp(init_val->name, "_OSI")
  91                     && !acpi_gbl_create_osi_method) {
  92                         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                 new_node =
 102                     ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_namespace_node));
 103                 if (!new_node) {
 104                         status = AE_NO_MEMORY;
 105                         goto unlock_and_exit;
 106                 }
 107 
 108                 ACPI_COPY_NAMESEG(new_node->name.ascii, init_val->name);
 109                 new_node->descriptor_type = ACPI_DESC_TYPE_NAMED;
 110                 new_node->type = init_val->type;
 111 
 112                 if (!prev_node) {
 113                         acpi_gbl_root_node_struct.child = new_node;
 114                 } else {
 115                         prev_node->peer = new_node;
 116                 }
 117 
 118                 new_node->parent = &acpi_gbl_root_node_struct;
 119                 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                 if (init_val->val) {
 126                         status = acpi_os_predefined_override(init_val, &val);
 127                         if (ACPI_FAILURE(status)) {
 128                                 ACPI_ERROR((AE_INFO,
 129                                             "Could not override predefined %s",
 130                                             init_val->name));
 131                         }
 132 
 133                         if (!val) {
 134                                 val = init_val->val;
 135                         }
 136 
 137                         /*
 138                          * Entry requests an initial value, allocate a
 139                          * descriptor for it.
 140                          */
 141                         obj_desc =
 142                             acpi_ut_create_internal_object(init_val->type);
 143                         if (!obj_desc) {
 144                                 status = AE_NO_MEMORY;
 145                                 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                         switch (init_val->type) {
 154                         case ACPI_TYPE_METHOD:
 155 
 156                                 obj_desc->method.param_count =
 157                                     (u8) ACPI_TO_INTEGER(val);
 158                                 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                                 obj_desc->method.info_flags =
 169                                     ACPI_METHOD_INTERNAL_ONLY;
 170                                 obj_desc->method.dispatch.implementation =
 171                                     acpi_ut_osi_implementation;
 172 #endif
 173                                 break;
 174 
 175                         case ACPI_TYPE_INTEGER:
 176 
 177                                 obj_desc->integer.value = ACPI_TO_INTEGER(val);
 178                                 break;
 179 
 180                         case ACPI_TYPE_STRING:
 181 
 182                                 /* Build an object around the static string */
 183 
 184                                 obj_desc->string.length = (u32)strlen(val);
 185                                 obj_desc->string.pointer = val;
 186                                 obj_desc->common.flags |= AOPOBJ_STATIC_POINTER;
 187                                 break;
 188 
 189                         case ACPI_TYPE_MUTEX:
 190 
 191                                 obj_desc->mutex.node = new_node;
 192                                 obj_desc->mutex.sync_level =
 193                                     (u8) (ACPI_TO_INTEGER(val) - 1);
 194 
 195                                 /* Create a mutex */
 196 
 197                                 status =
 198                                     acpi_os_create_mutex(&obj_desc->mutex.
 199                                                          os_mutex);
 200                                 if (ACPI_FAILURE(status)) {
 201                                         acpi_ut_remove_reference(obj_desc);
 202                                         goto unlock_and_exit;
 203                                 }
 204 
 205                                 /* Special case for ACPI Global Lock */
 206 
 207                                 if (strcmp(init_val->name, "_GL_") == 0) {
 208                                         acpi_gbl_global_lock_mutex = obj_desc;
 209 
 210                                         /* Create additional counting semaphore for global lock */
 211 
 212                                         status =
 213                                             acpi_os_create_semaphore(1, 0,
 214                                                                      &acpi_gbl_global_lock_semaphore);
 215                                         if (ACPI_FAILURE(status)) {
 216                                                 acpi_ut_remove_reference
 217                                                     (obj_desc);
 218                                                 goto unlock_and_exit;
 219                                         }
 220                                 }
 221                                 break;
 222 
 223                         default:
 224 
 225                                 ACPI_ERROR((AE_INFO,
 226                                             "Unsupported initial type value 0x%X",
 227                                             init_val->type));
 228                                 acpi_ut_remove_reference(obj_desc);
 229                                 obj_desc = NULL;
 230                                 continue;
 231                         }
 232 
 233                         /* Store pointer to value descriptor in the Node */
 234 
 235                         status = acpi_ns_attach_object(new_node, obj_desc,
 236                                                        obj_desc->common.type);
 237 
 238                         /* Remove local reference to the object */
 239 
 240                         acpi_ut_remove_reference(obj_desc);
 241                 }
 242         }
 243 
 244 unlock_and_exit:
 245         (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
 246 
 247         /* Save a handle to "_GPE", it is always present */
 248 
 249         if (ACPI_SUCCESS(status)) {
 250                 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 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         acpi_status status;
 290         char *path = pathname;
 291         char *external_path;
 292         struct acpi_namespace_node *prefix_node;
 293         struct acpi_namespace_node *current_node = NULL;
 294         struct acpi_namespace_node *this_node = NULL;
 295         u32 num_segments;
 296         u32 num_carats;
 297         acpi_name simple_name;
 298         acpi_object_type type_to_check_for;
 299         acpi_object_type this_search_type;
 300         u32 search_parent_flag = ACPI_NS_SEARCH_PARENT;
 301         u32 local_flags;
 302         acpi_interpreter_mode local_interpreter_mode;
 303 
 304         ACPI_FUNCTION_TRACE(ns_lookup);
 305 
 306         if (!return_node) {
 307                 return_ACPI_STATUS(AE_BAD_PARAMETER);
 308         }
 309 
 310         local_flags = flags &
 311             ~(ACPI_NS_ERROR_IF_FOUND | ACPI_NS_OVERRIDE_IF_FOUND |
 312               ACPI_NS_SEARCH_PARENT);
 313         *return_node = ACPI_ENTRY_NOT_FOUND;
 314         acpi_gbl_ns_lookup_count++;
 315 
 316         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         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                 prefix_node = scope_info->scope.node;
 330                 if (ACPI_GET_DESCRIPTOR_TYPE(prefix_node) !=
 331                     ACPI_DESC_TYPE_NAMED) {
 332                         ACPI_ERROR((AE_INFO, "%p is not a namespace node [%s]",
 333                                     prefix_node,
 334                                     acpi_ut_get_descriptor_name(prefix_node)));
 335                         return_ACPI_STATUS(AE_AML_INTERNAL);
 336                 }
 337 
 338                 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                         while (!acpi_ns_opens_scope(prefix_node->type) &&
 345                                prefix_node->type != ACPI_TYPE_ANY) {
 346                                 prefix_node = prefix_node->parent;
 347                         }
 348                 }
 349         }
 350 
 351         /* Save type. TBD: may be no longer necessary */
 352 
 353         type_to_check_for = type;
 354 
 355         /*
 356          * Begin examination of the actual pathname
 357          */
 358         if (!pathname) {
 359 
 360                 /* A Null name_path is allowed and refers to the root */
 361 
 362                 num_segments = 0;
 363                 this_node = acpi_gbl_root_node;
 364                 path = "";
 365 
 366                 ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
 367                                   "Null Pathname (Zero segments), Flags=%X\n",
 368                                   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                 if (*path == (u8) AML_ROOT_PREFIX) {
 384 
 385                         /* Pathname is fully qualified, start from the root */
 386 
 387                         this_node = acpi_gbl_root_node;
 388                         search_parent_flag = ACPI_NS_NO_UPSEARCH;
 389 
 390                         /* Point to name segment part */
 391 
 392                         path++;
 393 
 394                         ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
 395                                           "Path is absolute from root [%p]\n",
 396                                           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                                           prefix_node));
 404 
 405                         /*
 406                          * Handle multiple Parent Prefixes (carat) by just getting
 407                          * the parent node for each prefix instance.
 408                          */
 409                         this_node = prefix_node;
 410                         num_carats = 0;
 411                         while (*path == (u8) AML_PARENT_PREFIX) {
 412 
 413                                 /* Name is fully qualified, no search rules apply */
 414 
 415                                 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                                 path++;
 422 
 423                                 /* Backup to the parent node */
 424 
 425                                 num_carats++;
 426                                 this_node = this_node->parent;
 427                                 if (!this_node) {
 428                                         /*
 429                                          * Current scope has no parent scope. Externalize
 430                                          * the internal path for error message.
 431                                          */
 432                                         status =
 433                                             acpi_ns_externalize_name
 434                                             (ACPI_UINT32_MAX, pathname, NULL,
 435                                              &external_path);
 436                                         if (ACPI_SUCCESS(status)) {
 437                                                 ACPI_ERROR((AE_INFO,
 438                                                             "%s: Path has too many parent prefixes (^)",
 439                                                             external_path));
 440 
 441                                                 ACPI_FREE(external_path);
 442                                         }
 443 
 444                                         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                                                   (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                 switch (*path) {
 470                 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                         num_segments = 0;
 476                         type = this_node->type;
 477 
 478                         ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
 479                                           "Prefix-only Pathname (Zero name segments), Flags=%X\n",
 480                                           flags));
 481                         break;
 482 
 483                 case AML_DUAL_NAME_PREFIX:
 484 
 485                         /* More than one name_seg, search rules do not apply */
 486 
 487                         search_parent_flag = ACPI_NS_NO_UPSEARCH;
 488 
 489                         /* Two segments, point to first name segment */
 490 
 491                         num_segments = 2;
 492                         path++;
 493 
 494                         ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
 495                                           "Dual Pathname (2 segments, Flags=%X)\n",
 496                                           flags));
 497                         break;
 498 
 499                 case AML_MULTI_NAME_PREFIX:
 500 
 501                         /* More than one name_seg, search rules do not apply */
 502 
 503                         search_parent_flag = ACPI_NS_NO_UPSEARCH;
 504 
 505                         /* Extract segment count, point to first name segment */
 506 
 507                         path++;
 508                         num_segments = (u32) (u8) * path;
 509                         path++;
 510 
 511                         ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
 512                                           "Multi Pathname (%u Segments, Flags=%X)\n",
 513                                           num_segments, flags));
 514                         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                 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         this_search_type = ACPI_TYPE_ANY;
 541         current_node = this_node;
 542 
 543         while (num_segments && current_node) {
 544                 num_segments--;
 545                 if (!num_segments) {
 546 
 547                         /* This is the last segment, enable typechecking */
 548 
 549                         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                         if ((search_parent_flag != ACPI_NS_NO_UPSEARCH) &&
 556                             (flags & ACPI_NS_SEARCH_PARENT)) {
 557                                 local_flags |= ACPI_NS_SEARCH_PARENT;
 558                         }
 559 
 560                         /* Set error flag according to caller */
 561 
 562                         if (flags & ACPI_NS_ERROR_IF_FOUND) {
 563                                 local_flags |= ACPI_NS_ERROR_IF_FOUND;
 564                         }
 565 
 566                         /* Set override flag according to caller */
 567 
 568                         if (flags & ACPI_NS_OVERRIDE_IF_FOUND) {
 569                                 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                 local_interpreter_mode = interpreter_mode;
 576                 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                         local_interpreter_mode = ACPI_IMODE_EXECUTE;
 581                 }
 582 
 583                 /* Extract one ACPI name from the front of the pathname */
 584 
 585                 ACPI_MOVE_32_TO_32(&simple_name, path);
 586 
 587                 /* Try to find the single (4 character) ACPI name */
 588 
 589                 status =
 590                     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                 if (ACPI_FAILURE(status)) {
 596                         if (status == AE_NOT_FOUND) {
 597 #if !defined ACPI_ASL_COMPILER  /* Note: iASL reports this error by itself, not needed here */
 598                                 if (flags & ACPI_NS_PREFIX_MUST_EXIST) {
 599                                         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                                                   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                         *return_node = this_node;
 645                         return_ACPI_STATUS(status);
 646                 }
 647 
 648                 /* More segments to follow? */
 649 
 650                 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                         if (this_node->type == ACPI_TYPE_LOCAL_ALIAS) {
 658                                 if (!this_node->object) {
 659                                         return_ACPI_STATUS(AE_NOT_EXIST);
 660                                 }
 661 
 662                                 if (acpi_ns_opens_scope
 663                                     (((struct acpi_namespace_node *)
 664                                       this_node->object)->type)) {
 665                                         this_node =
 666                                             (struct acpi_namespace_node *)
 667                                             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                         if ((type_to_check_for != ACPI_TYPE_ANY) &&
 689                             (type_to_check_for != ACPI_TYPE_LOCAL_ALIAS) &&
 690                             (type_to_check_for != ACPI_TYPE_LOCAL_METHOD_ALIAS)
 691                             && (type_to_check_for != ACPI_TYPE_LOCAL_SCOPE)
 692                             && (this_node->type != ACPI_TYPE_ANY)
 693                             && (this_node->type != type_to_check_for)) {
 694 
 695                                 /* Complain about a type mismatch */
 696 
 697                                 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                         if (type == ACPI_TYPE_ANY) {
 712                                 type = this_node->type;
 713                         }
 714                 }
 715 
 716                 /* Point to next name segment and make this node current */
 717 
 718                 path += ACPI_NAMESEG_SIZE;
 719                 current_node = this_node;
 720         }
 721 
 722         /* Always check if we need to open a new scope */
 723 
 724         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                 if (acpi_ns_opens_scope(type)) {
 730                         status =
 731                             acpi_ds_scope_stack_push(this_node, type,
 732                                                      walk_state);
 733                         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         *return_node = this_node;
 745         return_ACPI_STATUS(AE_OK);
 746 }

/* [<][>][^][v][top][bottom][index][help] */