1 /******************************************************************************* 2 * 3 * Module Name: nsaccess - Top-level functions for accessing ACPI namespace 4 * 5 ******************************************************************************/ 6 7 /****************************************************************************** 8 * 9 * 1. Copyright Notice 10 * 11 * Some or all of this work - Copyright (c) 1999 - 2017, Intel Corp. 12 * All rights reserved. 13 * 14 * 2. License 15 * 16 * 2.1. This is your license from Intel Corp. under its intellectual property 17 * rights. You may have additional license terms from the party that provided 18 * you this software, covering your right to use that party's intellectual 19 * property rights. 20 * 21 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 22 * copy of the source code appearing in this file ("Covered Code") an 23 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 24 * base code distributed originally by Intel ("Original Intel Code") to copy, 25 * make derivatives, distribute, use and display any portion of the Covered 26 * Code in any form, with the right to sublicense such rights; and 27 * 28 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 29 * license (with the right to sublicense), under only those claims of Intel 30 * patents that are infringed by the Original Intel Code, to make, use, sell, 31 * offer to sell, and import the Covered Code and derivative works thereof 32 * solely to the minimum extent necessary to exercise the above copyright 33 * license, and in no event shall the patent license extend to any additions 34 * to or modifications of the Original Intel Code. No other license or right 35 * is granted directly or by implication, estoppel or otherwise; 36 * 37 * The above copyright and patent license is granted only if the following 38 * conditions are met: 39 * 40 * 3. Conditions 41 * 42 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 43 * Redistribution of source code of any substantial portion of the Covered 44 * Code or modification with rights to further distribute source must include 45 * the above Copyright Notice, the above License, this list of Conditions, 46 * and the following Disclaimer and Export Compliance provision. In addition, 47 * Licensee must cause all Covered Code to which Licensee contributes to 48 * contain a file documenting the changes Licensee made to create that Covered 49 * Code and the date of any change. Licensee must include in that file the 50 * documentation of any changes made by any predecessor Licensee. Licensee 51 * must include a prominent statement that the modification is derived, 52 * directly or indirectly, from Original Intel Code. 53 * 54 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 55 * Redistribution of source code of any substantial portion of the Covered 56 * Code or modification without rights to further distribute source must 57 * include the following Disclaimer and Export Compliance provision in the 58 * documentation and/or other materials provided with distribution. In 59 * addition, Licensee may not authorize further sublicense of source of any 60 * portion of the Covered Code, and must include terms to the effect that the 61 * license from Licensee to its licensee is limited to the intellectual 62 * property embodied in the software Licensee provides to its licensee, and 63 * not to intellectual property embodied in modifications its licensee may 64 * make. 65 * 66 * 3.3. Redistribution of Executable. Redistribution in executable form of any 67 * substantial portion of the Covered Code or modification must reproduce the 68 * above Copyright Notice, and the following Disclaimer and Export Compliance 69 * provision in the documentation and/or other materials provided with the 70 * distribution. 71 * 72 * 3.4. Intel retains all right, title, and interest in and to the Original 73 * Intel Code. 74 * 75 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 76 * Intel shall be used in advertising or otherwise to promote the sale, use or 77 * other dealings in products derived from or relating to the Covered Code 78 * without prior written authorization from Intel. 79 * 80 * 4. Disclaimer and Export Compliance 81 * 82 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 83 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 84 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 85 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 86 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 87 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 88 * PARTICULAR PURPOSE. 89 * 90 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 91 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 92 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 93 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 94 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 95 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 96 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 97 * LIMITED REMEDY. 98 * 99 * 4.3. Licensee shall not export, either directly or indirectly, any of this 100 * software or system incorporating such software without first obtaining any 101 * required license or other approval from the U. S. Department of Commerce or 102 * any other agency or department of the United States Government. In the 103 * event Licensee exports any such software from the United States or 104 * re-exports any such software from a foreign destination, Licensee shall 105 * ensure that the distribution and export/re-export of the software is in 106 * compliance with all laws, regulations, orders, or other restrictions of the 107 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 108 * any of its subsidiaries will export/re-export any technical data, process, 109 * software, or service, directly or indirectly, to any country for which the 110 * United States government or any agency thereof requires an export license, 111 * other governmental approval, or letter of assurance, without first obtaining 112 * such license, approval or letter. 113 * 114 ***************************************************************************** 115 * 116 * Alternatively, you may choose to be licensed under the terms of the 117 * following license: 118 * 119 * Redistribution and use in source and binary forms, with or without 120 * modification, are permitted provided that the following conditions 121 * are met: 122 * 1. Redistributions of source code must retain the above copyright 123 * notice, this list of conditions, and the following disclaimer, 124 * without modification. 125 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 126 * substantially similar to the "NO WARRANTY" disclaimer below 127 * ("Disclaimer") and any redistribution must be conditioned upon 128 * including a substantially similar Disclaimer requirement for further 129 * binary redistribution. 130 * 3. Neither the names of the above-listed copyright holders nor the names 131 * of any contributors may be used to endorse or promote products derived 132 * from this software without specific prior written permission. 133 * 134 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 135 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 136 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 137 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 138 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 139 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 140 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 141 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 142 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 143 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 144 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 145 * 146 * Alternatively, you may choose to be licensed under the terms of the 147 * GNU General Public License ("GPL") version 2 as published by the Free 148 * Software Foundation. 149 * 150 *****************************************************************************/ 151 152 #include <contrib/dev/acpica/include/acpi.h> 153 #include <contrib/dev/acpica/include/accommon.h> 154 #include <contrib/dev/acpica/include/amlcode.h> 155 #include <contrib/dev/acpica/include/acnamesp.h> 156 #include <contrib/dev/acpica/include/acdispat.h> 157 158 159 #define _COMPONENT ACPI_NAMESPACE 160 ACPI_MODULE_NAME ("nsaccess") 161 162 163 /******************************************************************************* 164 * 165 * FUNCTION: AcpiNsRootInitialize 166 * 167 * PARAMETERS: None 168 * 169 * RETURN: Status 170 * 171 * DESCRIPTION: Allocate and initialize the default root named objects 172 * 173 * MUTEX: Locks namespace for entire execution 174 * 175 ******************************************************************************/ 176 177 ACPI_STATUS 178 AcpiNsRootInitialize ( 179 void) 180 { 181 ACPI_STATUS Status; 182 const ACPI_PREDEFINED_NAMES *InitVal = NULL; 183 ACPI_NAMESPACE_NODE *NewNode; 184 ACPI_OPERAND_OBJECT *ObjDesc; 185 ACPI_STRING Val = NULL; 186 187 188 ACPI_FUNCTION_TRACE (NsRootInitialize); 189 190 191 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 192 if (ACPI_FAILURE (Status)) 193 { 194 return_ACPI_STATUS (Status); 195 } 196 197 /* 198 * The global root ptr is initially NULL, so a non-NULL value indicates 199 * that AcpiNsRootInitialize() has already been called; just return. 200 */ 201 if (AcpiGbl_RootNode) 202 { 203 Status = AE_OK; 204 goto UnlockAndExit; 205 } 206 207 /* 208 * Tell the rest of the subsystem that the root is initialized 209 * (This is OK because the namespace is locked) 210 */ 211 AcpiGbl_RootNode = &AcpiGbl_RootNodeStruct; 212 213 /* Enter the pre-defined names in the name table */ 214 215 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 216 "Entering predefined entries into namespace\n")); 217 218 for (InitVal = AcpiGbl_PreDefinedNames; InitVal->Name; InitVal++) 219 { 220 /* _OSI is optional for now, will be permanent later */ 221 222 if (!strcmp (InitVal->Name, "_OSI") && !AcpiGbl_CreateOsiMethod) 223 { 224 continue; 225 } 226 227 Status = AcpiNsLookup (NULL, ACPI_CAST_PTR (char, InitVal->Name), 228 InitVal->Type, ACPI_IMODE_LOAD_PASS2, ACPI_NS_NO_UPSEARCH, 229 NULL, &NewNode); 230 if (ACPI_FAILURE (Status)) 231 { 232 ACPI_EXCEPTION ((AE_INFO, Status, 233 "Could not create predefined name %s", 234 InitVal->Name)); 235 continue; 236 } 237 238 /* 239 * Name entered successfully. If entry in PreDefinedNames[] specifies 240 * an initial value, create the initial value. 241 */ 242 if (InitVal->Val) 243 { 244 Status = AcpiOsPredefinedOverride (InitVal, &Val); 245 if (ACPI_FAILURE (Status)) 246 { 247 ACPI_ERROR ((AE_INFO, 248 "Could not override predefined %s", 249 InitVal->Name)); 250 } 251 252 if (!Val) 253 { 254 Val = InitVal->Val; 255 } 256 257 /* 258 * Entry requests an initial value, allocate a 259 * descriptor for it. 260 */ 261 ObjDesc = AcpiUtCreateInternalObject (InitVal->Type); 262 if (!ObjDesc) 263 { 264 Status = AE_NO_MEMORY; 265 goto UnlockAndExit; 266 } 267 268 /* 269 * Convert value string from table entry to 270 * internal representation. Only types actually 271 * used for initial values are implemented here. 272 */ 273 switch (InitVal->Type) 274 { 275 case ACPI_TYPE_METHOD: 276 277 ObjDesc->Method.ParamCount = (UINT8) ACPI_TO_INTEGER (Val); 278 ObjDesc->Common.Flags |= AOPOBJ_DATA_VALID; 279 280 #if defined (ACPI_ASL_COMPILER) 281 282 /* Save the parameter count for the iASL compiler */ 283 284 NewNode->Value = ObjDesc->Method.ParamCount; 285 #else 286 /* Mark this as a very SPECIAL method */ 287 288 ObjDesc->Method.InfoFlags = ACPI_METHOD_INTERNAL_ONLY; 289 ObjDesc->Method.Dispatch.Implementation = AcpiUtOsiImplementation; 290 #endif 291 break; 292 293 case ACPI_TYPE_INTEGER: 294 295 ObjDesc->Integer.Value = ACPI_TO_INTEGER (Val); 296 break; 297 298 case ACPI_TYPE_STRING: 299 300 /* Build an object around the static string */ 301 302 ObjDesc->String.Length = (UINT32) strlen (Val); 303 ObjDesc->String.Pointer = Val; 304 ObjDesc->Common.Flags |= AOPOBJ_STATIC_POINTER; 305 break; 306 307 case ACPI_TYPE_MUTEX: 308 309 ObjDesc->Mutex.Node = NewNode; 310 ObjDesc->Mutex.SyncLevel = (UINT8) (ACPI_TO_INTEGER (Val) - 1); 311 312 /* Create a mutex */ 313 314 Status = AcpiOsCreateMutex (&ObjDesc->Mutex.OsMutex); 315 if (ACPI_FAILURE (Status)) 316 { 317 AcpiUtRemoveReference (ObjDesc); 318 goto UnlockAndExit; 319 } 320 321 /* Special case for ACPI Global Lock */ 322 323 if (strcmp (InitVal->Name, "_GL_") == 0) 324 { 325 AcpiGbl_GlobalLockMutex = ObjDesc; 326 327 /* Create additional counting semaphore for global lock */ 328 329 Status = AcpiOsCreateSemaphore ( 330 1, 0, &AcpiGbl_GlobalLockSemaphore); 331 if (ACPI_FAILURE (Status)) 332 { 333 AcpiUtRemoveReference (ObjDesc); 334 goto UnlockAndExit; 335 } 336 } 337 break; 338 339 default: 340 341 ACPI_ERROR ((AE_INFO, "Unsupported initial type value 0x%X", 342 InitVal->Type)); 343 AcpiUtRemoveReference (ObjDesc); 344 ObjDesc = NULL; 345 continue; 346 } 347 348 /* Store pointer to value descriptor in the Node */ 349 350 Status = AcpiNsAttachObject (NewNode, ObjDesc, 351 ObjDesc->Common.Type); 352 353 /* Remove local reference to the object */ 354 355 AcpiUtRemoveReference (ObjDesc); 356 } 357 } 358 359 360 UnlockAndExit: 361 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 362 363 /* Save a handle to "_GPE", it is always present */ 364 365 if (ACPI_SUCCESS (Status)) 366 { 367 Status = AcpiNsGetNode (NULL, "\\_GPE", ACPI_NS_NO_UPSEARCH, 368 &AcpiGbl_FadtGpeDevice); 369 } 370 371 return_ACPI_STATUS (Status); 372 } 373 374 375 /******************************************************************************* 376 * 377 * FUNCTION: AcpiNsLookup 378 * 379 * PARAMETERS: ScopeInfo - Current scope info block 380 * Pathname - Search pathname, in internal format 381 * (as represented in the AML stream) 382 * Type - Type associated with name 383 * InterpreterMode - IMODE_LOAD_PASS2 => add name if not found 384 * Flags - Flags describing the search restrictions 385 * WalkState - Current state of the walk 386 * ReturnNode - Where the Node is placed (if found 387 * or created successfully) 388 * 389 * RETURN: Status 390 * 391 * DESCRIPTION: Find or enter the passed name in the name space. 392 * Log an error if name not found in Exec mode. 393 * 394 * MUTEX: Assumes namespace is locked. 395 * 396 ******************************************************************************/ 397 398 ACPI_STATUS 399 AcpiNsLookup ( 400 ACPI_GENERIC_STATE *ScopeInfo, 401 char *Pathname, 402 ACPI_OBJECT_TYPE Type, 403 ACPI_INTERPRETER_MODE InterpreterMode, 404 UINT32 Flags, 405 ACPI_WALK_STATE *WalkState, 406 ACPI_NAMESPACE_NODE **ReturnNode) 407 { 408 ACPI_STATUS Status; 409 char *Path = Pathname; 410 ACPI_NAMESPACE_NODE *PrefixNode; 411 ACPI_NAMESPACE_NODE *CurrentNode = NULL; 412 ACPI_NAMESPACE_NODE *ThisNode = NULL; 413 UINT32 NumSegments; 414 UINT32 NumCarats; 415 ACPI_NAME SimpleName; 416 ACPI_OBJECT_TYPE TypeToCheckFor; 417 ACPI_OBJECT_TYPE ThisSearchType; 418 UINT32 SearchParentFlag = ACPI_NS_SEARCH_PARENT; 419 UINT32 LocalFlags; 420 421 422 ACPI_FUNCTION_TRACE (NsLookup); 423 424 425 if (!ReturnNode) 426 { 427 return_ACPI_STATUS (AE_BAD_PARAMETER); 428 } 429 430 LocalFlags = Flags & 431 ~(ACPI_NS_ERROR_IF_FOUND | ACPI_NS_OVERRIDE_IF_FOUND | 432 ACPI_NS_SEARCH_PARENT); 433 *ReturnNode = ACPI_ENTRY_NOT_FOUND; 434 AcpiGbl_NsLookupCount++; 435 436 if (!AcpiGbl_RootNode) 437 { 438 return_ACPI_STATUS (AE_NO_NAMESPACE); 439 } 440 441 /* Get the prefix scope. A null scope means use the root scope */ 442 443 if ((!ScopeInfo) || 444 (!ScopeInfo->Scope.Node)) 445 { 446 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 447 "Null scope prefix, using root node (%p)\n", 448 AcpiGbl_RootNode)); 449 450 PrefixNode = AcpiGbl_RootNode; 451 } 452 else 453 { 454 PrefixNode = ScopeInfo->Scope.Node; 455 if (ACPI_GET_DESCRIPTOR_TYPE (PrefixNode) != ACPI_DESC_TYPE_NAMED) 456 { 457 ACPI_ERROR ((AE_INFO, "%p is not a namespace node [%s]", 458 PrefixNode, AcpiUtGetDescriptorName (PrefixNode))); 459 return_ACPI_STATUS (AE_AML_INTERNAL); 460 } 461 462 if (!(Flags & ACPI_NS_PREFIX_IS_SCOPE)) 463 { 464 /* 465 * This node might not be a actual "scope" node (such as a 466 * Device/Method, etc.) It could be a Package or other object 467 * node. Backup up the tree to find the containing scope node. 468 */ 469 while (!AcpiNsOpensScope (PrefixNode->Type) && 470 PrefixNode->Type != ACPI_TYPE_ANY) 471 { 472 PrefixNode = PrefixNode->Parent; 473 } 474 } 475 } 476 477 /* Save type. TBD: may be no longer necessary */ 478 479 TypeToCheckFor = Type; 480 481 /* 482 * Begin examination of the actual pathname 483 */ 484 if (!Pathname) 485 { 486 /* A Null NamePath is allowed and refers to the root */ 487 488 NumSegments = 0; 489 ThisNode = AcpiGbl_RootNode; 490 Path = ""; 491 492 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 493 "Null Pathname (Zero segments), Flags=%X\n", Flags)); 494 } 495 else 496 { 497 /* 498 * Name pointer is valid (and must be in internal name format) 499 * 500 * Check for scope prefixes: 501 * 502 * As represented in the AML stream, a namepath consists of an 503 * optional scope prefix followed by a name segment part. 504 * 505 * If present, the scope prefix is either a Root Prefix (in 506 * which case the name is fully qualified), or one or more 507 * Parent Prefixes (in which case the name's scope is relative 508 * to the current scope). 509 */ 510 if (*Path == (UINT8) AML_ROOT_PREFIX) 511 { 512 /* Pathname is fully qualified, start from the root */ 513 514 ThisNode = AcpiGbl_RootNode; 515 SearchParentFlag = ACPI_NS_NO_UPSEARCH; 516 517 /* Point to name segment part */ 518 519 Path++; 520 521 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 522 "Path is absolute from root [%p]\n", ThisNode)); 523 } 524 else 525 { 526 /* Pathname is relative to current scope, start there */ 527 528 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 529 "Searching relative to prefix scope [%4.4s] (%p)\n", 530 AcpiUtGetNodeName (PrefixNode), PrefixNode)); 531 532 /* 533 * Handle multiple Parent Prefixes (carat) by just getting 534 * the parent node for each prefix instance. 535 */ 536 ThisNode = PrefixNode; 537 NumCarats = 0; 538 while (*Path == (UINT8) AML_PARENT_PREFIX) 539 { 540 /* Name is fully qualified, no search rules apply */ 541 542 SearchParentFlag = ACPI_NS_NO_UPSEARCH; 543 544 /* 545 * Point past this prefix to the name segment 546 * part or the next Parent Prefix 547 */ 548 Path++; 549 550 /* Backup to the parent node */ 551 552 NumCarats++; 553 ThisNode = ThisNode->Parent; 554 if (!ThisNode) 555 { 556 /* Current scope has no parent scope */ 557 558 ACPI_ERROR ((AE_INFO, 559 "%s: Path has too many parent prefixes (^) " 560 "- reached beyond root node", Pathname)); 561 return_ACPI_STATUS (AE_NOT_FOUND); 562 } 563 } 564 565 if (SearchParentFlag == ACPI_NS_NO_UPSEARCH) 566 { 567 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 568 "Search scope is [%4.4s], path has %u carat(s)\n", 569 AcpiUtGetNodeName (ThisNode), NumCarats)); 570 } 571 } 572 573 /* 574 * Determine the number of ACPI name segments in this pathname. 575 * 576 * The segment part consists of either: 577 * - A Null name segment (0) 578 * - A DualNamePrefix followed by two 4-byte name segments 579 * - A MultiNamePrefix followed by a byte indicating the 580 * number of segments and the segments themselves. 581 * - A single 4-byte name segment 582 * 583 * Examine the name prefix opcode, if any, to determine the number of 584 * segments. 585 */ 586 switch (*Path) 587 { 588 case 0: 589 /* 590 * Null name after a root or parent prefixes. We already 591 * have the correct target node and there are no name segments. 592 */ 593 NumSegments = 0; 594 Type = ThisNode->Type; 595 596 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 597 "Prefix-only Pathname (Zero name segments), Flags=%X\n", 598 Flags)); 599 break; 600 601 case AML_DUAL_NAME_PREFIX: 602 603 /* More than one NameSeg, search rules do not apply */ 604 605 SearchParentFlag = ACPI_NS_NO_UPSEARCH; 606 607 /* Two segments, point to first name segment */ 608 609 NumSegments = 2; 610 Path++; 611 612 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 613 "Dual Pathname (2 segments, Flags=%X)\n", Flags)); 614 break; 615 616 case AML_MULTI_NAME_PREFIX: 617 618 /* More than one NameSeg, search rules do not apply */ 619 620 SearchParentFlag = ACPI_NS_NO_UPSEARCH; 621 622 /* Extract segment count, point to first name segment */ 623 624 Path++; 625 NumSegments = (UINT32) (UINT8) *Path; 626 Path++; 627 628 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 629 "Multi Pathname (%u Segments, Flags=%X)\n", 630 NumSegments, Flags)); 631 break; 632 633 default: 634 /* 635 * Not a Null name, no Dual or Multi prefix, hence there is 636 * only one name segment and Pathname is already pointing to it. 637 */ 638 NumSegments = 1; 639 640 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 641 "Simple Pathname (1 segment, Flags=%X)\n", Flags)); 642 break; 643 } 644 645 ACPI_DEBUG_EXEC (AcpiNsPrintPathname (NumSegments, Path)); 646 } 647 648 649 /* 650 * Search namespace for each segment of the name. Loop through and 651 * verify (or add to the namespace) each name segment. 652 * 653 * The object type is significant only at the last name 654 * segment. (We don't care about the types along the path, only 655 * the type of the final target object.) 656 */ 657 ThisSearchType = ACPI_TYPE_ANY; 658 CurrentNode = ThisNode; 659 while (NumSegments && CurrentNode) 660 { 661 NumSegments--; 662 if (!NumSegments) 663 { 664 /* This is the last segment, enable typechecking */ 665 666 ThisSearchType = Type; 667 668 /* 669 * Only allow automatic parent search (search rules) if the caller 670 * requested it AND we have a single, non-fully-qualified NameSeg 671 */ 672 if ((SearchParentFlag != ACPI_NS_NO_UPSEARCH) && 673 (Flags & ACPI_NS_SEARCH_PARENT)) 674 { 675 LocalFlags |= ACPI_NS_SEARCH_PARENT; 676 } 677 678 /* Set error flag according to caller */ 679 680 if (Flags & ACPI_NS_ERROR_IF_FOUND) 681 { 682 LocalFlags |= ACPI_NS_ERROR_IF_FOUND; 683 } 684 685 /* Set override flag according to caller */ 686 687 if (Flags & ACPI_NS_OVERRIDE_IF_FOUND) 688 { 689 LocalFlags |= ACPI_NS_OVERRIDE_IF_FOUND; 690 } 691 } 692 693 /* Extract one ACPI name from the front of the pathname */ 694 695 ACPI_MOVE_32_TO_32 (&SimpleName, Path); 696 697 /* Try to find the single (4 character) ACPI name */ 698 699 Status = AcpiNsSearchAndEnter (SimpleName, WalkState, CurrentNode, 700 InterpreterMode, ThisSearchType, LocalFlags, &ThisNode); 701 if (ACPI_FAILURE (Status)) 702 { 703 if (Status == AE_NOT_FOUND) 704 { 705 /* Name not found in ACPI namespace */ 706 707 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 708 "Name [%4.4s] not found in scope [%4.4s] %p\n", 709 (char *) &SimpleName, (char *) &CurrentNode->Name, 710 CurrentNode)); 711 } 712 713 *ReturnNode = ThisNode; 714 return_ACPI_STATUS (Status); 715 } 716 717 /* More segments to follow? */ 718 719 if (NumSegments > 0) 720 { 721 /* 722 * If we have an alias to an object that opens a scope (such as a 723 * device or processor), we need to dereference the alias here so 724 * that we can access any children of the original node (via the 725 * remaining segments). 726 */ 727 if (ThisNode->Type == ACPI_TYPE_LOCAL_ALIAS) 728 { 729 if (!ThisNode->Object) 730 { 731 return_ACPI_STATUS (AE_NOT_EXIST); 732 } 733 734 if (AcpiNsOpensScope (((ACPI_NAMESPACE_NODE *) 735 ThisNode->Object)->Type)) 736 { 737 ThisNode = (ACPI_NAMESPACE_NODE *) ThisNode->Object; 738 } 739 } 740 } 741 742 /* Special handling for the last segment (NumSegments == 0) */ 743 744 else 745 { 746 /* 747 * Sanity typecheck of the target object: 748 * 749 * If 1) This is the last segment (NumSegments == 0) 750 * 2) And we are looking for a specific type 751 * (Not checking for TYPE_ANY) 752 * 3) Which is not an alias 753 * 4) Which is not a local type (TYPE_SCOPE) 754 * 5) And the type of target object is known (not TYPE_ANY) 755 * 6) And target object does not match what we are looking for 756 * 757 * Then we have a type mismatch. Just warn and ignore it. 758 */ 759 if ((TypeToCheckFor != ACPI_TYPE_ANY) && 760 (TypeToCheckFor != ACPI_TYPE_LOCAL_ALIAS) && 761 (TypeToCheckFor != ACPI_TYPE_LOCAL_METHOD_ALIAS) && 762 (TypeToCheckFor != ACPI_TYPE_LOCAL_SCOPE) && 763 (ThisNode->Type != ACPI_TYPE_ANY) && 764 (ThisNode->Type != TypeToCheckFor)) 765 { 766 /* Complain about a type mismatch */ 767 768 ACPI_WARNING ((AE_INFO, 769 "NsLookup: Type mismatch on %4.4s (%s), searching for (%s)", 770 ACPI_CAST_PTR (char, &SimpleName), 771 AcpiUtGetTypeName (ThisNode->Type), 772 AcpiUtGetTypeName (TypeToCheckFor))); 773 } 774 775 /* 776 * If this is the last name segment and we are not looking for a 777 * specific type, but the type of found object is known, use that 778 * type to (later) see if it opens a scope. 779 */ 780 if (Type == ACPI_TYPE_ANY) 781 { 782 Type = ThisNode->Type; 783 } 784 } 785 786 /* Point to next name segment and make this node current */ 787 788 Path += ACPI_NAME_SIZE; 789 CurrentNode = ThisNode; 790 } 791 792 /* Always check if we need to open a new scope */ 793 794 if (!(Flags & ACPI_NS_DONT_OPEN_SCOPE) && (WalkState)) 795 { 796 /* 797 * If entry is a type which opens a scope, push the new scope on the 798 * scope stack. 799 */ 800 if (AcpiNsOpensScope (Type)) 801 { 802 Status = AcpiDsScopeStackPush (ThisNode, Type, WalkState); 803 if (ACPI_FAILURE (Status)) 804 { 805 return_ACPI_STATUS (Status); 806 } 807 } 808 } 809 810 *ReturnNode = ThisNode; 811 return_ACPI_STATUS (AE_OK); 812 } 813