1 /****************************************************************************** 2 * 3 * Module Name: nsutils - Utilities for accessing ACPI namespace, accessing 4 * parents and siblings and Scope manipulation 5 * 6 *****************************************************************************/ 7 8 /* 9 * Copyright (C) 2000 - 2014, Intel Corp. 10 * All rights reserved. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions, and the following disclaimer, 17 * without modification. 18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 19 * substantially similar to the "NO WARRANTY" disclaimer below 20 * ("Disclaimer") and any redistribution must be conditioned upon 21 * including a substantially similar Disclaimer requirement for further 22 * binary redistribution. 23 * 3. Neither the names of the above-listed copyright holders nor the names 24 * of any contributors may be used to endorse or promote products derived 25 * from this software without specific prior written permission. 26 * 27 * Alternatively, this software may be distributed under the terms of the 28 * GNU General Public License ("GPL") version 2 as published by the Free 29 * Software Foundation. 30 * 31 * NO WARRANTY 32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 42 * POSSIBILITY OF SUCH DAMAGES. 43 */ 44 45 #define __NSUTILS_C__ 46 47 #include "acpi.h" 48 #include "accommon.h" 49 #include "acnamesp.h" 50 #include "amlcode.h" 51 52 #define _COMPONENT ACPI_NAMESPACE 53 ACPI_MODULE_NAME ("nsutils") 54 55 /* Local prototypes */ 56 57 #ifdef ACPI_OBSOLETE_FUNCTIONS 58 ACPI_NAME 59 AcpiNsFindParentName ( 60 ACPI_NAMESPACE_NODE *NodeToSearch); 61 #endif 62 63 64 /******************************************************************************* 65 * 66 * FUNCTION: AcpiNsPrintNodePathname 67 * 68 * PARAMETERS: Node - Object 69 * Message - Prefix message 70 * 71 * DESCRIPTION: Print an object's full namespace pathname 72 * Manages allocation/freeing of a pathname buffer 73 * 74 ******************************************************************************/ 75 76 void 77 AcpiNsPrintNodePathname ( 78 ACPI_NAMESPACE_NODE *Node, 79 const char *Message) 80 { 81 ACPI_BUFFER Buffer; 82 ACPI_STATUS Status; 83 84 85 if (!Node) 86 { 87 AcpiOsPrintf ("[NULL NAME]"); 88 return; 89 } 90 91 /* Convert handle to full pathname and print it (with supplied message) */ 92 93 Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER; 94 95 Status = AcpiNsHandleToPathname (Node, &Buffer); 96 if (ACPI_SUCCESS (Status)) 97 { 98 if (Message) 99 { 100 AcpiOsPrintf ("%s ", Message); 101 } 102 103 AcpiOsPrintf ("[%s] (Node %p)", (char *) Buffer.Pointer, Node); 104 ACPI_FREE (Buffer.Pointer); 105 } 106 } 107 108 109 /******************************************************************************* 110 * 111 * FUNCTION: AcpiNsGetType 112 * 113 * PARAMETERS: Node - Parent Node to be examined 114 * 115 * RETURN: Type field from Node whose handle is passed 116 * 117 * DESCRIPTION: Return the type of a Namespace node 118 * 119 ******************************************************************************/ 120 121 ACPI_OBJECT_TYPE 122 AcpiNsGetType ( 123 ACPI_NAMESPACE_NODE *Node) 124 { 125 ACPI_FUNCTION_TRACE (NsGetType); 126 127 128 if (!Node) 129 { 130 ACPI_WARNING ((AE_INFO, "Null Node parameter")); 131 return_UINT8 (ACPI_TYPE_ANY); 132 } 133 134 return_UINT8 (Node->Type); 135 } 136 137 138 /******************************************************************************* 139 * 140 * FUNCTION: AcpiNsLocal 141 * 142 * PARAMETERS: Type - A namespace object type 143 * 144 * RETURN: LOCAL if names must be found locally in objects of the 145 * passed type, 0 if enclosing scopes should be searched 146 * 147 * DESCRIPTION: Returns scope rule for the given object type. 148 * 149 ******************************************************************************/ 150 151 UINT32 152 AcpiNsLocal ( 153 ACPI_OBJECT_TYPE Type) 154 { 155 ACPI_FUNCTION_TRACE (NsLocal); 156 157 158 if (!AcpiUtValidObjectType (Type)) 159 { 160 /* Type code out of range */ 161 162 ACPI_WARNING ((AE_INFO, "Invalid Object Type 0x%X", Type)); 163 return_UINT32 (ACPI_NS_NORMAL); 164 } 165 166 return_UINT32 (AcpiGbl_NsProperties[Type] & ACPI_NS_LOCAL); 167 } 168 169 170 /******************************************************************************* 171 * 172 * FUNCTION: AcpiNsGetInternalNameLength 173 * 174 * PARAMETERS: Info - Info struct initialized with the 175 * external name pointer. 176 * 177 * RETURN: None 178 * 179 * DESCRIPTION: Calculate the length of the internal (AML) namestring 180 * corresponding to the external (ASL) namestring. 181 * 182 ******************************************************************************/ 183 184 void 185 AcpiNsGetInternalNameLength ( 186 ACPI_NAMESTRING_INFO *Info) 187 { 188 const char *NextExternalChar; 189 UINT32 i; 190 191 192 ACPI_FUNCTION_ENTRY (); 193 194 195 NextExternalChar = Info->ExternalName; 196 Info->NumCarats = 0; 197 Info->NumSegments = 0; 198 Info->FullyQualified = FALSE; 199 200 /* 201 * For the internal name, the required length is 4 bytes per segment, plus 202 * 1 each for RootPrefix, MultiNamePrefixOp, segment count, trailing null 203 * (which is not really needed, but no there's harm in putting it there) 204 * 205 * strlen() + 1 covers the first NameSeg, which has no path separator 206 */ 207 if (ACPI_IS_ROOT_PREFIX (*NextExternalChar)) 208 { 209 Info->FullyQualified = TRUE; 210 NextExternalChar++; 211 212 /* Skip redundant RootPrefix, like \\_SB.PCI0.SBRG.EC0 */ 213 214 while (ACPI_IS_ROOT_PREFIX (*NextExternalChar)) 215 { 216 NextExternalChar++; 217 } 218 } 219 else 220 { 221 /* Handle Carat prefixes */ 222 223 while (ACPI_IS_PARENT_PREFIX (*NextExternalChar)) 224 { 225 Info->NumCarats++; 226 NextExternalChar++; 227 } 228 } 229 230 /* 231 * Determine the number of ACPI name "segments" by counting the number of 232 * path separators within the string. Start with one segment since the 233 * segment count is [(# separators) + 1], and zero separators is ok. 234 */ 235 if (*NextExternalChar) 236 { 237 Info->NumSegments = 1; 238 for (i = 0; NextExternalChar[i]; i++) 239 { 240 if (ACPI_IS_PATH_SEPARATOR (NextExternalChar[i])) 241 { 242 Info->NumSegments++; 243 } 244 } 245 } 246 247 Info->Length = (ACPI_NAME_SIZE * Info->NumSegments) + 248 4 + Info->NumCarats; 249 250 Info->NextExternalChar = NextExternalChar; 251 } 252 253 254 /******************************************************************************* 255 * 256 * FUNCTION: AcpiNsBuildInternalName 257 * 258 * PARAMETERS: Info - Info struct fully initialized 259 * 260 * RETURN: Status 261 * 262 * DESCRIPTION: Construct the internal (AML) namestring 263 * corresponding to the external (ASL) namestring. 264 * 265 ******************************************************************************/ 266 267 ACPI_STATUS 268 AcpiNsBuildInternalName ( 269 ACPI_NAMESTRING_INFO *Info) 270 { 271 UINT32 NumSegments = Info->NumSegments; 272 char *InternalName = Info->InternalName; 273 const char *ExternalName = Info->NextExternalChar; 274 char *Result = NULL; 275 UINT32 i; 276 277 278 ACPI_FUNCTION_TRACE (NsBuildInternalName); 279 280 281 /* Setup the correct prefixes, counts, and pointers */ 282 283 if (Info->FullyQualified) 284 { 285 InternalName[0] = AML_ROOT_PREFIX; 286 287 if (NumSegments <= 1) 288 { 289 Result = &InternalName[1]; 290 } 291 else if (NumSegments == 2) 292 { 293 InternalName[1] = AML_DUAL_NAME_PREFIX; 294 Result = &InternalName[2]; 295 } 296 else 297 { 298 InternalName[1] = AML_MULTI_NAME_PREFIX_OP; 299 InternalName[2] = (char) NumSegments; 300 Result = &InternalName[3]; 301 } 302 } 303 else 304 { 305 /* 306 * Not fully qualified. 307 * Handle Carats first, then append the name segments 308 */ 309 i = 0; 310 if (Info->NumCarats) 311 { 312 for (i = 0; i < Info->NumCarats; i++) 313 { 314 InternalName[i] = AML_PARENT_PREFIX; 315 } 316 } 317 318 if (NumSegments <= 1) 319 { 320 Result = &InternalName[i]; 321 } 322 else if (NumSegments == 2) 323 { 324 InternalName[i] = AML_DUAL_NAME_PREFIX; 325 Result = &InternalName[(ACPI_SIZE) i+1]; 326 } 327 else 328 { 329 InternalName[i] = AML_MULTI_NAME_PREFIX_OP; 330 InternalName[(ACPI_SIZE) i+1] = (char) NumSegments; 331 Result = &InternalName[(ACPI_SIZE) i+2]; 332 } 333 } 334 335 /* Build the name (minus path separators) */ 336 337 for (; NumSegments; NumSegments--) 338 { 339 for (i = 0; i < ACPI_NAME_SIZE; i++) 340 { 341 if (ACPI_IS_PATH_SEPARATOR (*ExternalName) || 342 (*ExternalName == 0)) 343 { 344 /* Pad the segment with underscore(s) if segment is short */ 345 346 Result[i] = '_'; 347 } 348 else 349 { 350 /* Convert the character to uppercase and save it */ 351 352 Result[i] = (char) ACPI_TOUPPER ((int) *ExternalName); 353 ExternalName++; 354 } 355 } 356 357 /* Now we must have a path separator, or the pathname is bad */ 358 359 if (!ACPI_IS_PATH_SEPARATOR (*ExternalName) && 360 (*ExternalName != 0)) 361 { 362 return_ACPI_STATUS (AE_BAD_PATHNAME); 363 } 364 365 /* Move on the next segment */ 366 367 ExternalName++; 368 Result += ACPI_NAME_SIZE; 369 } 370 371 /* Terminate the string */ 372 373 *Result = 0; 374 375 if (Info->FullyQualified) 376 { 377 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Returning [%p] (abs) \"\\%s\"\n", 378 InternalName, InternalName)); 379 } 380 else 381 { 382 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Returning [%p] (rel) \"%s\"\n", 383 InternalName, InternalName)); 384 } 385 386 return_ACPI_STATUS (AE_OK); 387 } 388 389 390 /******************************************************************************* 391 * 392 * FUNCTION: AcpiNsInternalizeName 393 * 394 * PARAMETERS: *ExternalName - External representation of name 395 * **Converted Name - Where to return the resulting 396 * internal represention of the name 397 * 398 * RETURN: Status 399 * 400 * DESCRIPTION: Convert an external representation (e.g. "\_PR_.CPU0") 401 * to internal form (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30) 402 * 403 *******************************************************************************/ 404 405 ACPI_STATUS 406 AcpiNsInternalizeName ( 407 const char *ExternalName, 408 char **ConvertedName) 409 { 410 char *InternalName; 411 ACPI_NAMESTRING_INFO Info; 412 ACPI_STATUS Status; 413 414 415 ACPI_FUNCTION_TRACE (NsInternalizeName); 416 417 418 if ((!ExternalName) || 419 (*ExternalName == 0) || 420 (!ConvertedName)) 421 { 422 return_ACPI_STATUS (AE_BAD_PARAMETER); 423 } 424 425 /* Get the length of the new internal name */ 426 427 Info.ExternalName = ExternalName; 428 AcpiNsGetInternalNameLength (&Info); 429 430 /* We need a segment to store the internal name */ 431 432 InternalName = ACPI_ALLOCATE_ZEROED (Info.Length); 433 if (!InternalName) 434 { 435 return_ACPI_STATUS (AE_NO_MEMORY); 436 } 437 438 /* Build the name */ 439 440 Info.InternalName = InternalName; 441 Status = AcpiNsBuildInternalName (&Info); 442 if (ACPI_FAILURE (Status)) 443 { 444 ACPI_FREE (InternalName); 445 return_ACPI_STATUS (Status); 446 } 447 448 *ConvertedName = InternalName; 449 return_ACPI_STATUS (AE_OK); 450 } 451 452 453 /******************************************************************************* 454 * 455 * FUNCTION: AcpiNsExternalizeName 456 * 457 * PARAMETERS: InternalNameLength - Lenth of the internal name below 458 * InternalName - Internal representation of name 459 * ConvertedNameLength - Where the length is returned 460 * ConvertedName - Where the resulting external name 461 * is returned 462 * 463 * RETURN: Status 464 * 465 * DESCRIPTION: Convert internal name (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30) 466 * to its external (printable) form (e.g. "\_PR_.CPU0") 467 * 468 ******************************************************************************/ 469 470 ACPI_STATUS 471 AcpiNsExternalizeName ( 472 UINT32 InternalNameLength, 473 const char *InternalName, 474 UINT32 *ConvertedNameLength, 475 char **ConvertedName) 476 { 477 UINT32 NamesIndex = 0; 478 UINT32 NumSegments = 0; 479 UINT32 RequiredLength; 480 UINT32 PrefixLength = 0; 481 UINT32 i = 0; 482 UINT32 j = 0; 483 484 485 ACPI_FUNCTION_TRACE (NsExternalizeName); 486 487 488 if (!InternalNameLength || 489 !InternalName || 490 !ConvertedName) 491 { 492 return_ACPI_STATUS (AE_BAD_PARAMETER); 493 } 494 495 /* Check for a prefix (one '\' | one or more '^') */ 496 497 switch (InternalName[0]) 498 { 499 case AML_ROOT_PREFIX: 500 501 PrefixLength = 1; 502 break; 503 504 case AML_PARENT_PREFIX: 505 506 for (i = 0; i < InternalNameLength; i++) 507 { 508 if (ACPI_IS_PARENT_PREFIX (InternalName[i])) 509 { 510 PrefixLength = i + 1; 511 } 512 else 513 { 514 break; 515 } 516 } 517 518 if (i == InternalNameLength) 519 { 520 PrefixLength = i; 521 } 522 523 break; 524 525 default: 526 527 break; 528 } 529 530 /* 531 * Check for object names. Note that there could be 0-255 of these 532 * 4-byte elements. 533 */ 534 if (PrefixLength < InternalNameLength) 535 { 536 switch (InternalName[PrefixLength]) 537 { 538 case AML_MULTI_NAME_PREFIX_OP: 539 540 /* <count> 4-byte names */ 541 542 NamesIndex = PrefixLength + 2; 543 NumSegments = (UINT8) 544 InternalName[(ACPI_SIZE) PrefixLength + 1]; 545 break; 546 547 case AML_DUAL_NAME_PREFIX: 548 549 /* Two 4-byte names */ 550 551 NamesIndex = PrefixLength + 1; 552 NumSegments = 2; 553 break; 554 555 case 0: 556 557 /* NullName */ 558 559 NamesIndex = 0; 560 NumSegments = 0; 561 break; 562 563 default: 564 565 /* one 4-byte name */ 566 567 NamesIndex = PrefixLength; 568 NumSegments = 1; 569 break; 570 } 571 } 572 573 /* 574 * Calculate the length of ConvertedName, which equals the length 575 * of the prefix, length of all object names, length of any required 576 * punctuation ('.') between object names, plus the NULL terminator. 577 */ 578 RequiredLength = PrefixLength + (4 * NumSegments) + 579 ((NumSegments > 0) ? (NumSegments - 1) : 0) + 1; 580 581 /* 582 * Check to see if we're still in bounds. If not, there's a problem 583 * with InternalName (invalid format). 584 */ 585 if (RequiredLength > InternalNameLength) 586 { 587 ACPI_ERROR ((AE_INFO, "Invalid internal name")); 588 return_ACPI_STATUS (AE_BAD_PATHNAME); 589 } 590 591 /* Build the ConvertedName */ 592 593 *ConvertedName = ACPI_ALLOCATE_ZEROED (RequiredLength); 594 if (!(*ConvertedName)) 595 { 596 return_ACPI_STATUS (AE_NO_MEMORY); 597 } 598 599 j = 0; 600 601 for (i = 0; i < PrefixLength; i++) 602 { 603 (*ConvertedName)[j++] = InternalName[i]; 604 } 605 606 if (NumSegments > 0) 607 { 608 for (i = 0; i < NumSegments; i++) 609 { 610 if (i > 0) 611 { 612 (*ConvertedName)[j++] = '.'; 613 } 614 615 /* Copy and validate the 4-char name segment */ 616 617 ACPI_MOVE_NAME (&(*ConvertedName)[j], &InternalName[NamesIndex]); 618 AcpiUtRepairName (&(*ConvertedName)[j]); 619 620 j += ACPI_NAME_SIZE; 621 NamesIndex += ACPI_NAME_SIZE; 622 } 623 } 624 625 if (ConvertedNameLength) 626 { 627 *ConvertedNameLength = (UINT32) RequiredLength; 628 } 629 630 return_ACPI_STATUS (AE_OK); 631 } 632 633 634 /******************************************************************************* 635 * 636 * FUNCTION: AcpiNsValidateHandle 637 * 638 * PARAMETERS: Handle - Handle to be validated and typecast to a 639 * namespace node. 640 * 641 * RETURN: A pointer to a namespace node 642 * 643 * DESCRIPTION: Convert a namespace handle to a namespace node. Handles special 644 * cases for the root node. 645 * 646 * NOTE: Real integer handles would allow for more verification 647 * and keep all pointers within this subsystem - however this introduces 648 * more overhead and has not been necessary to this point. Drivers 649 * holding handles are typically notified before a node becomes invalid 650 * due to a table unload. 651 * 652 ******************************************************************************/ 653 654 ACPI_NAMESPACE_NODE * 655 AcpiNsValidateHandle ( 656 ACPI_HANDLE Handle) 657 { 658 659 ACPI_FUNCTION_ENTRY (); 660 661 662 /* Parameter validation */ 663 664 if ((!Handle) || (Handle == ACPI_ROOT_OBJECT)) 665 { 666 return (AcpiGbl_RootNode); 667 } 668 669 /* We can at least attempt to verify the handle */ 670 671 if (ACPI_GET_DESCRIPTOR_TYPE (Handle) != ACPI_DESC_TYPE_NAMED) 672 { 673 return (NULL); 674 } 675 676 return (ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Handle)); 677 } 678 679 680 /******************************************************************************* 681 * 682 * FUNCTION: AcpiNsTerminate 683 * 684 * PARAMETERS: none 685 * 686 * RETURN: none 687 * 688 * DESCRIPTION: free memory allocated for namespace and ACPI table storage. 689 * 690 ******************************************************************************/ 691 692 void 693 AcpiNsTerminate ( 694 void) 695 { 696 ACPI_STATUS Status; 697 698 699 ACPI_FUNCTION_TRACE (NsTerminate); 700 701 702 /* 703 * Free the entire namespace -- all nodes and all objects 704 * attached to the nodes 705 */ 706 AcpiNsDeleteNamespaceSubtree (AcpiGbl_RootNode); 707 708 /* Delete any objects attached to the root node */ 709 710 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 711 if (ACPI_FAILURE (Status)) 712 { 713 return_VOID; 714 } 715 716 AcpiNsDeleteNode (AcpiGbl_RootNode); 717 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 718 719 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Namespace freed\n")); 720 return_VOID; 721 } 722 723 724 /******************************************************************************* 725 * 726 * FUNCTION: AcpiNsOpensScope 727 * 728 * PARAMETERS: Type - A valid namespace type 729 * 730 * RETURN: NEWSCOPE if the passed type "opens a name scope" according 731 * to the ACPI specification, else 0 732 * 733 ******************************************************************************/ 734 735 UINT32 736 AcpiNsOpensScope ( 737 ACPI_OBJECT_TYPE Type) 738 { 739 ACPI_FUNCTION_ENTRY (); 740 741 742 if (Type > ACPI_TYPE_LOCAL_MAX) 743 { 744 /* type code out of range */ 745 746 ACPI_WARNING ((AE_INFO, "Invalid Object Type 0x%X", Type)); 747 return (ACPI_NS_NORMAL); 748 } 749 750 return (((UINT32) AcpiGbl_NsProperties[Type]) & ACPI_NS_NEWSCOPE); 751 } 752 753 754 /******************************************************************************* 755 * 756 * FUNCTION: AcpiNsGetNode 757 * 758 * PARAMETERS: *Pathname - Name to be found, in external (ASL) format. The 759 * \ (backslash) and ^ (carat) prefixes, and the 760 * . (period) to separate segments are supported. 761 * PrefixNode - Root of subtree to be searched, or NS_ALL for the 762 * root of the name space. If Name is fully 763 * qualified (first INT8 is '\'), the passed value 764 * of Scope will not be accessed. 765 * Flags - Used to indicate whether to perform upsearch or 766 * not. 767 * ReturnNode - Where the Node is returned 768 * 769 * DESCRIPTION: Look up a name relative to a given scope and return the 770 * corresponding Node. NOTE: Scope can be null. 771 * 772 * MUTEX: Locks namespace 773 * 774 ******************************************************************************/ 775 776 ACPI_STATUS 777 AcpiNsGetNode ( 778 ACPI_NAMESPACE_NODE *PrefixNode, 779 const char *Pathname, 780 UINT32 Flags, 781 ACPI_NAMESPACE_NODE **ReturnNode) 782 { 783 ACPI_GENERIC_STATE ScopeInfo; 784 ACPI_STATUS Status; 785 char *InternalPath; 786 787 788 ACPI_FUNCTION_TRACE_PTR (NsGetNode, ACPI_CAST_PTR (char, Pathname)); 789 790 791 /* Simplest case is a null pathname */ 792 793 if (!Pathname) 794 { 795 *ReturnNode = PrefixNode; 796 if (!PrefixNode) 797 { 798 *ReturnNode = AcpiGbl_RootNode; 799 } 800 return_ACPI_STATUS (AE_OK); 801 } 802 803 /* Quick check for a reference to the root */ 804 805 if (ACPI_IS_ROOT_PREFIX (Pathname[0]) && (!Pathname[1])) 806 { 807 *ReturnNode = AcpiGbl_RootNode; 808 return_ACPI_STATUS (AE_OK); 809 } 810 811 /* Convert path to internal representation */ 812 813 Status = AcpiNsInternalizeName (Pathname, &InternalPath); 814 if (ACPI_FAILURE (Status)) 815 { 816 return_ACPI_STATUS (Status); 817 } 818 819 /* Must lock namespace during lookup */ 820 821 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 822 if (ACPI_FAILURE (Status)) 823 { 824 goto Cleanup; 825 } 826 827 /* Setup lookup scope (search starting point) */ 828 829 ScopeInfo.Scope.Node = PrefixNode; 830 831 /* Lookup the name in the namespace */ 832 833 Status = AcpiNsLookup (&ScopeInfo, InternalPath, ACPI_TYPE_ANY, 834 ACPI_IMODE_EXECUTE, (Flags | ACPI_NS_DONT_OPEN_SCOPE), 835 NULL, ReturnNode); 836 if (ACPI_FAILURE (Status)) 837 { 838 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%s, %s\n", 839 Pathname, AcpiFormatException (Status))); 840 } 841 842 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 843 844 Cleanup: 845 ACPI_FREE (InternalPath); 846 return_ACPI_STATUS (Status); 847 }