1 /****************************************************************************** 2 * 3 * Module Name: nsutils - Utilities for accessing ACPI namespace, accessing 4 * parents and siblings and Scope manipulation 5 * $Revision: 1.153 $ 6 * 7 *****************************************************************************/ 8 9 /****************************************************************************** 10 * 11 * 1. Copyright Notice 12 * 13 * Some or all of this work - Copyright (c) 1999 - 2006, Intel Corp. 14 * All rights reserved. 15 * 16 * 2. License 17 * 18 * 2.1. This is your license from Intel Corp. under its intellectual property 19 * rights. You may have additional license terms from the party that provided 20 * you this software, covering your right to use that party's intellectual 21 * property rights. 22 * 23 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 24 * copy of the source code appearing in this file ("Covered Code") an 25 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 26 * base code distributed originally by Intel ("Original Intel Code") to copy, 27 * make derivatives, distribute, use and display any portion of the Covered 28 * Code in any form, with the right to sublicense such rights; and 29 * 30 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 31 * license (with the right to sublicense), under only those claims of Intel 32 * patents that are infringed by the Original Intel Code, to make, use, sell, 33 * offer to sell, and import the Covered Code and derivative works thereof 34 * solely to the minimum extent necessary to exercise the above copyright 35 * license, and in no event shall the patent license extend to any additions 36 * to or modifications of the Original Intel Code. No other license or right 37 * is granted directly or by implication, estoppel or otherwise; 38 * 39 * The above copyright and patent license is granted only if the following 40 * conditions are met: 41 * 42 * 3. Conditions 43 * 44 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 45 * Redistribution of source code of any substantial portion of the Covered 46 * Code or modification with rights to further distribute source must include 47 * the above Copyright Notice, the above License, this list of Conditions, 48 * and the following Disclaimer and Export Compliance provision. In addition, 49 * Licensee must cause all Covered Code to which Licensee contributes to 50 * contain a file documenting the changes Licensee made to create that Covered 51 * Code and the date of any change. Licensee must include in that file the 52 * documentation of any changes made by any predecessor Licensee. Licensee 53 * must include a prominent statement that the modification is derived, 54 * directly or indirectly, from Original Intel Code. 55 * 56 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 57 * Redistribution of source code of any substantial portion of the Covered 58 * Code or modification without rights to further distribute source must 59 * include the following Disclaimer and Export Compliance provision in the 60 * documentation and/or other materials provided with distribution. In 61 * addition, Licensee may not authorize further sublicense of source of any 62 * portion of the Covered Code, and must include terms to the effect that the 63 * license from Licensee to its licensee is limited to the intellectual 64 * property embodied in the software Licensee provides to its licensee, and 65 * not to intellectual property embodied in modifications its licensee may 66 * make. 67 * 68 * 3.3. Redistribution of Executable. Redistribution in executable form of any 69 * substantial portion of the Covered Code or modification must reproduce the 70 * above Copyright Notice, and the following Disclaimer and Export Compliance 71 * provision in the documentation and/or other materials provided with the 72 * distribution. 73 * 74 * 3.4. Intel retains all right, title, and interest in and to the Original 75 * Intel Code. 76 * 77 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 78 * Intel shall be used in advertising or otherwise to promote the sale, use or 79 * other dealings in products derived from or relating to the Covered Code 80 * without prior written authorization from Intel. 81 * 82 * 4. Disclaimer and Export Compliance 83 * 84 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 85 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 86 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 87 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 88 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 89 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 90 * PARTICULAR PURPOSE. 91 * 92 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 93 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 94 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 95 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 96 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 97 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 98 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 99 * LIMITED REMEDY. 100 * 101 * 4.3. Licensee shall not export, either directly or indirectly, any of this 102 * software or system incorporating such software without first obtaining any 103 * required license or other approval from the U. S. Department of Commerce or 104 * any other agency or department of the United States Government. In the 105 * event Licensee exports any such software from the United States or 106 * re-exports any such software from a foreign destination, Licensee shall 107 * ensure that the distribution and export/re-export of the software is in 108 * compliance with all laws, regulations, orders, or other restrictions of the 109 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 110 * any of its subsidiaries will export/re-export any technical data, process, 111 * software, or service, directly or indirectly, to any country for which the 112 * United States government or any agency thereof requires an export license, 113 * other governmental approval, or letter of assurance, without first obtaining 114 * such license, approval or letter. 115 * 116 *****************************************************************************/ 117 118 #define __NSUTILS_C__ 119 120 #include "acpi.h" 121 #include "acnamesp.h" 122 #include "amlcode.h" 123 #include "actables.h" 124 125 #define _COMPONENT ACPI_NAMESPACE 126 ACPI_MODULE_NAME ("nsutils") 127 128 /* Local prototypes */ 129 130 static BOOLEAN 131 AcpiNsValidPathSeparator ( 132 char Sep); 133 134 #ifdef ACPI_OBSOLETE_FUNCTIONS 135 ACPI_NAME 136 AcpiNsFindParentName ( 137 ACPI_NAMESPACE_NODE *NodeToSearch); 138 #endif 139 140 141 /******************************************************************************* 142 * 143 * FUNCTION: AcpiNsReportError 144 * 145 * PARAMETERS: ModuleName - Caller's module name (for error output) 146 * LineNumber - Caller's line number (for error output) 147 * InternalName - Name or path of the namespace node 148 * LookupStatus - Exception code from NS lookup 149 * 150 * RETURN: None 151 * 152 * DESCRIPTION: Print warning message with full pathname 153 * 154 ******************************************************************************/ 155 156 void 157 AcpiNsReportError ( 158 char *ModuleName, 159 UINT32 LineNumber, 160 char *InternalName, 161 ACPI_STATUS LookupStatus) 162 { 163 ACPI_STATUS Status; 164 UINT32 BadName; 165 char *Name = NULL; 166 167 168 AcpiOsPrintf ("ACPI Error (%s-%04d): ", ModuleName, LineNumber); 169 170 if (LookupStatus == AE_BAD_CHARACTER) 171 { 172 /* There is a non-ascii character in the name */ 173 174 ACPI_MOVE_32_TO_32 (&BadName, InternalName); 175 AcpiOsPrintf ("[0x%4.4X] (NON-ASCII)", BadName); 176 } 177 else 178 { 179 /* Convert path to external format */ 180 181 Status = AcpiNsExternalizeName (ACPI_UINT32_MAX, 182 InternalName, NULL, &Name); 183 184 /* Print target name */ 185 186 if (ACPI_SUCCESS (Status)) 187 { 188 AcpiOsPrintf ("[%s]", Name); 189 } 190 else 191 { 192 AcpiOsPrintf ("[COULD NOT EXTERNALIZE NAME]"); 193 } 194 195 if (Name) 196 { 197 ACPI_FREE (Name); 198 } 199 } 200 201 AcpiOsPrintf (" Namespace lookup failure, %s\n", 202 AcpiFormatException (LookupStatus)); 203 } 204 205 206 /******************************************************************************* 207 * 208 * FUNCTION: AcpiNsReportMethodError 209 * 210 * PARAMETERS: ModuleName - Caller's module name (for error output) 211 * LineNumber - Caller's line number (for error output) 212 * Message - Error message to use on failure 213 * PrefixNode - Prefix relative to the path 214 * Path - Path to the node (optional) 215 * MethodStatus - Execution status 216 * 217 * RETURN: None 218 * 219 * DESCRIPTION: Print warning message with full pathname 220 * 221 ******************************************************************************/ 222 223 void 224 AcpiNsReportMethodError ( 225 char *ModuleName, 226 UINT32 LineNumber, 227 char *Message, 228 ACPI_NAMESPACE_NODE *PrefixNode, 229 char *Path, 230 ACPI_STATUS MethodStatus) 231 { 232 ACPI_STATUS Status; 233 ACPI_NAMESPACE_NODE *Node = PrefixNode; 234 235 236 AcpiOsPrintf ("ACPI Error (%s-%04d): ", ModuleName, LineNumber); 237 238 if (Path) 239 { 240 Status = AcpiNsGetNode (PrefixNode, Path, ACPI_NS_NO_UPSEARCH, 241 &Node); 242 if (ACPI_FAILURE (Status)) 243 { 244 AcpiOsPrintf ("[Could not get node by pathname]"); 245 } 246 } 247 248 AcpiNsPrintNodePathname (Node, Message); 249 AcpiOsPrintf (", %s\n", AcpiFormatException (MethodStatus)); 250 } 251 252 253 /******************************************************************************* 254 * 255 * FUNCTION: AcpiNsPrintNodePathname 256 * 257 * PARAMETERS: Node - Object 258 * Message - Prefix message 259 * 260 * DESCRIPTION: Print an object's full namespace pathname 261 * Manages allocation/freeing of a pathname buffer 262 * 263 ******************************************************************************/ 264 265 void 266 AcpiNsPrintNodePathname ( 267 ACPI_NAMESPACE_NODE *Node, 268 char *Message) 269 { 270 ACPI_BUFFER Buffer; 271 ACPI_STATUS Status; 272 273 274 if (!Node) 275 { 276 AcpiOsPrintf ("[NULL NAME]"); 277 return; 278 } 279 280 /* Convert handle to full pathname and print it (with supplied message) */ 281 282 Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER; 283 284 Status = AcpiNsHandleToPathname (Node, &Buffer); 285 if (ACPI_SUCCESS (Status)) 286 { 287 if (Message) 288 { 289 AcpiOsPrintf ("%s ", Message); 290 } 291 292 AcpiOsPrintf ("[%s] (Node %p)", (char *) Buffer.Pointer, Node); 293 ACPI_FREE (Buffer.Pointer); 294 } 295 } 296 297 298 /******************************************************************************* 299 * 300 * FUNCTION: AcpiNsValidRootPrefix 301 * 302 * PARAMETERS: Prefix - Character to be checked 303 * 304 * RETURN: TRUE if a valid prefix 305 * 306 * DESCRIPTION: Check if a character is a valid ACPI Root prefix 307 * 308 ******************************************************************************/ 309 310 BOOLEAN 311 AcpiNsValidRootPrefix ( 312 char Prefix) 313 { 314 315 return ((BOOLEAN) (Prefix == '\\')); 316 } 317 318 319 /******************************************************************************* 320 * 321 * FUNCTION: AcpiNsValidPathSeparator 322 * 323 * PARAMETERS: Sep - Character to be checked 324 * 325 * RETURN: TRUE if a valid path separator 326 * 327 * DESCRIPTION: Check if a character is a valid ACPI path separator 328 * 329 ******************************************************************************/ 330 331 static BOOLEAN 332 AcpiNsValidPathSeparator ( 333 char Sep) 334 { 335 336 return ((BOOLEAN) (Sep == '.')); 337 } 338 339 340 /******************************************************************************* 341 * 342 * FUNCTION: AcpiNsGetType 343 * 344 * PARAMETERS: Node - Parent Node to be examined 345 * 346 * RETURN: Type field from Node whose handle is passed 347 * 348 * DESCRIPTION: Return the type of a Namespace node 349 * 350 ******************************************************************************/ 351 352 ACPI_OBJECT_TYPE 353 AcpiNsGetType ( 354 ACPI_NAMESPACE_NODE *Node) 355 { 356 ACPI_FUNCTION_TRACE (NsGetType); 357 358 359 if (!Node) 360 { 361 ACPI_WARNING ((AE_INFO, "Null Node parameter")); 362 return_UINT32 (ACPI_TYPE_ANY); 363 } 364 365 return_UINT32 ((ACPI_OBJECT_TYPE) Node->Type); 366 } 367 368 369 /******************************************************************************* 370 * 371 * FUNCTION: AcpiNsLocal 372 * 373 * PARAMETERS: Type - A namespace object type 374 * 375 * RETURN: LOCAL if names must be found locally in objects of the 376 * passed type, 0 if enclosing scopes should be searched 377 * 378 * DESCRIPTION: Returns scope rule for the given object type. 379 * 380 ******************************************************************************/ 381 382 UINT32 383 AcpiNsLocal ( 384 ACPI_OBJECT_TYPE Type) 385 { 386 ACPI_FUNCTION_TRACE (NsLocal); 387 388 389 if (!AcpiUtValidObjectType (Type)) 390 { 391 /* Type code out of range */ 392 393 ACPI_WARNING ((AE_INFO, "Invalid Object Type %X", Type)); 394 return_UINT32 (ACPI_NS_NORMAL); 395 } 396 397 return_UINT32 ((UINT32) AcpiGbl_NsProperties[Type] & ACPI_NS_LOCAL); 398 } 399 400 401 /******************************************************************************* 402 * 403 * FUNCTION: AcpiNsGetInternalNameLength 404 * 405 * PARAMETERS: Info - Info struct initialized with the 406 * external name pointer. 407 * 408 * RETURN: None 409 * 410 * DESCRIPTION: Calculate the length of the internal (AML) namestring 411 * corresponding to the external (ASL) namestring. 412 * 413 ******************************************************************************/ 414 415 void 416 AcpiNsGetInternalNameLength ( 417 ACPI_NAMESTRING_INFO *Info) 418 { 419 char *NextExternalChar; 420 UINT32 i; 421 422 423 ACPI_FUNCTION_ENTRY (); 424 425 426 NextExternalChar = Info->ExternalName; 427 Info->NumCarats = 0; 428 Info->NumSegments = 0; 429 Info->FullyQualified = FALSE; 430 431 /* 432 * For the internal name, the required length is 4 bytes per segment, plus 433 * 1 each for RootPrefix, MultiNamePrefixOp, segment count, trailing null 434 * (which is not really needed, but no there's harm in putting it there) 435 * 436 * strlen() + 1 covers the first NameSeg, which has no path separator 437 */ 438 if (AcpiNsValidRootPrefix (NextExternalChar[0])) 439 { 440 Info->FullyQualified = TRUE; 441 NextExternalChar++; 442 } 443 else 444 { 445 /* 446 * Handle Carat prefixes 447 */ 448 while (*NextExternalChar == '^') 449 { 450 Info->NumCarats++; 451 NextExternalChar++; 452 } 453 } 454 455 /* 456 * Determine the number of ACPI name "segments" by counting the number of 457 * path separators within the string. Start with one segment since the 458 * segment count is [(# separators) + 1], and zero separators is ok. 459 */ 460 if (*NextExternalChar) 461 { 462 Info->NumSegments = 1; 463 for (i = 0; NextExternalChar[i]; i++) 464 { 465 if (AcpiNsValidPathSeparator (NextExternalChar[i])) 466 { 467 Info->NumSegments++; 468 } 469 } 470 } 471 472 Info->Length = (ACPI_NAME_SIZE * Info->NumSegments) + 473 4 + Info->NumCarats; 474 475 Info->NextExternalChar = NextExternalChar; 476 } 477 478 479 /******************************************************************************* 480 * 481 * FUNCTION: AcpiNsBuildInternalName 482 * 483 * PARAMETERS: Info - Info struct fully initialized 484 * 485 * RETURN: Status 486 * 487 * DESCRIPTION: Construct the internal (AML) namestring 488 * corresponding to the external (ASL) namestring. 489 * 490 ******************************************************************************/ 491 492 ACPI_STATUS 493 AcpiNsBuildInternalName ( 494 ACPI_NAMESTRING_INFO *Info) 495 { 496 UINT32 NumSegments = Info->NumSegments; 497 char *InternalName = Info->InternalName; 498 char *ExternalName = Info->NextExternalChar; 499 char *Result = NULL; 500 ACPI_NATIVE_UINT i; 501 502 503 ACPI_FUNCTION_TRACE (NsBuildInternalName); 504 505 506 /* Setup the correct prefixes, counts, and pointers */ 507 508 if (Info->FullyQualified) 509 { 510 InternalName[0] = '\\'; 511 512 if (NumSegments <= 1) 513 { 514 Result = &InternalName[1]; 515 } 516 else if (NumSegments == 2) 517 { 518 InternalName[1] = AML_DUAL_NAME_PREFIX; 519 Result = &InternalName[2]; 520 } 521 else 522 { 523 InternalName[1] = AML_MULTI_NAME_PREFIX_OP; 524 InternalName[2] = (char) NumSegments; 525 Result = &InternalName[3]; 526 } 527 } 528 else 529 { 530 /* 531 * Not fully qualified. 532 * Handle Carats first, then append the name segments 533 */ 534 i = 0; 535 if (Info->NumCarats) 536 { 537 for (i = 0; i < Info->NumCarats; i++) 538 { 539 InternalName[i] = '^'; 540 } 541 } 542 543 if (NumSegments <= 1) 544 { 545 Result = &InternalName[i]; 546 } 547 else if (NumSegments == 2) 548 { 549 InternalName[i] = AML_DUAL_NAME_PREFIX; 550 Result = &InternalName[(ACPI_NATIVE_UINT) (i+1)]; 551 } 552 else 553 { 554 InternalName[i] = AML_MULTI_NAME_PREFIX_OP; 555 InternalName[(ACPI_NATIVE_UINT) (i+1)] = (char) NumSegments; 556 Result = &InternalName[(ACPI_NATIVE_UINT) (i+2)]; 557 } 558 } 559 560 /* Build the name (minus path separators) */ 561 562 for (; NumSegments; NumSegments--) 563 { 564 for (i = 0; i < ACPI_NAME_SIZE; i++) 565 { 566 if (AcpiNsValidPathSeparator (*ExternalName) || 567 (*ExternalName == 0)) 568 { 569 /* Pad the segment with underscore(s) if segment is short */ 570 571 Result[i] = '_'; 572 } 573 else 574 { 575 /* Convert the character to uppercase and save it */ 576 577 Result[i] = (char) ACPI_TOUPPER ((int) *ExternalName); 578 ExternalName++; 579 } 580 } 581 582 /* Now we must have a path separator, or the pathname is bad */ 583 584 if (!AcpiNsValidPathSeparator (*ExternalName) && 585 (*ExternalName != 0)) 586 { 587 return_ACPI_STATUS (AE_BAD_PARAMETER); 588 } 589 590 /* Move on the next segment */ 591 592 ExternalName++; 593 Result += ACPI_NAME_SIZE; 594 } 595 596 /* Terminate the string */ 597 598 *Result = 0; 599 600 if (Info->FullyQualified) 601 { 602 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Returning [%p] (abs) \"\\%s\"\n", 603 InternalName, InternalName)); 604 } 605 else 606 { 607 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Returning [%p] (rel) \"%s\"\n", 608 InternalName, InternalName)); 609 } 610 611 return_ACPI_STATUS (AE_OK); 612 } 613 614 615 /******************************************************************************* 616 * 617 * FUNCTION: AcpiNsInternalizeName 618 * 619 * PARAMETERS: *ExternalName - External representation of name 620 * **Converted Name - Where to return the resulting 621 * internal represention of the name 622 * 623 * RETURN: Status 624 * 625 * DESCRIPTION: Convert an external representation (e.g. "\_PR_.CPU0") 626 * to internal form (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30) 627 * 628 *******************************************************************************/ 629 630 ACPI_STATUS 631 AcpiNsInternalizeName ( 632 char *ExternalName, 633 char **ConvertedName) 634 { 635 char *InternalName; 636 ACPI_NAMESTRING_INFO Info; 637 ACPI_STATUS Status; 638 639 640 ACPI_FUNCTION_TRACE (NsInternalizeName); 641 642 643 if ((!ExternalName) || 644 (*ExternalName == 0) || 645 (!ConvertedName)) 646 { 647 return_ACPI_STATUS (AE_BAD_PARAMETER); 648 } 649 650 /* Get the length of the new internal name */ 651 652 Info.ExternalName = ExternalName; 653 AcpiNsGetInternalNameLength (&Info); 654 655 /* We need a segment to store the internal name */ 656 657 InternalName = ACPI_ALLOCATE_ZEROED (Info.Length); 658 if (!InternalName) 659 { 660 return_ACPI_STATUS (AE_NO_MEMORY); 661 } 662 663 /* Build the name */ 664 665 Info.InternalName = InternalName; 666 Status = AcpiNsBuildInternalName (&Info); 667 if (ACPI_FAILURE (Status)) 668 { 669 ACPI_FREE (InternalName); 670 return_ACPI_STATUS (Status); 671 } 672 673 *ConvertedName = InternalName; 674 return_ACPI_STATUS (AE_OK); 675 } 676 677 678 /******************************************************************************* 679 * 680 * FUNCTION: AcpiNsExternalizeName 681 * 682 * PARAMETERS: InternalNameLength - Lenth of the internal name below 683 * InternalName - Internal representation of name 684 * ConvertedNameLength - Where the length is returned 685 * ConvertedName - Where the resulting external name 686 * is returned 687 * 688 * RETURN: Status 689 * 690 * DESCRIPTION: Convert internal name (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30) 691 * to its external (printable) form (e.g. "\_PR_.CPU0") 692 * 693 ******************************************************************************/ 694 695 ACPI_STATUS 696 AcpiNsExternalizeName ( 697 UINT32 InternalNameLength, 698 char *InternalName, 699 UINT32 *ConvertedNameLength, 700 char **ConvertedName) 701 { 702 ACPI_NATIVE_UINT NamesIndex = 0; 703 ACPI_NATIVE_UINT NumSegments = 0; 704 ACPI_NATIVE_UINT RequiredLength; 705 ACPI_NATIVE_UINT PrefixLength = 0; 706 ACPI_NATIVE_UINT i = 0; 707 ACPI_NATIVE_UINT j = 0; 708 709 710 ACPI_FUNCTION_TRACE (NsExternalizeName); 711 712 713 if (!InternalNameLength || 714 !InternalName || 715 !ConvertedName) 716 { 717 return_ACPI_STATUS (AE_BAD_PARAMETER); 718 } 719 720 /* 721 * Check for a prefix (one '\' | one or more '^'). 722 */ 723 switch (InternalName[0]) 724 { 725 case '\\': 726 PrefixLength = 1; 727 break; 728 729 case '^': 730 for (i = 0; i < InternalNameLength; i++) 731 { 732 if (InternalName[i] == '^') 733 { 734 PrefixLength = i + 1; 735 } 736 else 737 { 738 break; 739 } 740 } 741 742 if (i == InternalNameLength) 743 { 744 PrefixLength = i; 745 } 746 747 break; 748 749 default: 750 break; 751 } 752 753 /* 754 * Check for object names. Note that there could be 0-255 of these 755 * 4-byte elements. 756 */ 757 if (PrefixLength < InternalNameLength) 758 { 759 switch (InternalName[PrefixLength]) 760 { 761 case AML_MULTI_NAME_PREFIX_OP: 762 763 /* <count> 4-byte names */ 764 765 NamesIndex = PrefixLength + 2; 766 NumSegments = (ACPI_NATIVE_UINT) (UINT8) 767 InternalName[(ACPI_NATIVE_UINT) (PrefixLength + 1)]; 768 break; 769 770 case AML_DUAL_NAME_PREFIX: 771 772 /* Two 4-byte names */ 773 774 NamesIndex = PrefixLength + 1; 775 NumSegments = 2; 776 break; 777 778 case 0: 779 780 /* NullName */ 781 782 NamesIndex = 0; 783 NumSegments = 0; 784 break; 785 786 default: 787 788 /* one 4-byte name */ 789 790 NamesIndex = PrefixLength; 791 NumSegments = 1; 792 break; 793 } 794 } 795 796 /* 797 * Calculate the length of ConvertedName, which equals the length 798 * of the prefix, length of all object names, length of any required 799 * punctuation ('.') between object names, plus the NULL terminator. 800 */ 801 RequiredLength = PrefixLength + (4 * NumSegments) + 802 ((NumSegments > 0) ? (NumSegments - 1) : 0) + 1; 803 804 /* 805 * Check to see if we're still in bounds. If not, there's a problem 806 * with InternalName (invalid format). 807 */ 808 if (RequiredLength > InternalNameLength) 809 { 810 ACPI_ERROR ((AE_INFO, "Invalid internal name")); 811 return_ACPI_STATUS (AE_BAD_PATHNAME); 812 } 813 814 /* 815 * Build ConvertedName 816 */ 817 *ConvertedName = ACPI_ALLOCATE_ZEROED (RequiredLength); 818 if (!(*ConvertedName)) 819 { 820 return_ACPI_STATUS (AE_NO_MEMORY); 821 } 822 823 j = 0; 824 825 for (i = 0; i < PrefixLength; i++) 826 { 827 (*ConvertedName)[j++] = InternalName[i]; 828 } 829 830 if (NumSegments > 0) 831 { 832 for (i = 0; i < NumSegments; i++) 833 { 834 if (i > 0) 835 { 836 (*ConvertedName)[j++] = '.'; 837 } 838 839 (*ConvertedName)[j++] = InternalName[NamesIndex++]; 840 (*ConvertedName)[j++] = InternalName[NamesIndex++]; 841 (*ConvertedName)[j++] = InternalName[NamesIndex++]; 842 (*ConvertedName)[j++] = InternalName[NamesIndex++]; 843 } 844 } 845 846 if (ConvertedNameLength) 847 { 848 *ConvertedNameLength = (UINT32) RequiredLength; 849 } 850 851 return_ACPI_STATUS (AE_OK); 852 } 853 854 855 /******************************************************************************* 856 * 857 * FUNCTION: AcpiNsMapHandleToNode 858 * 859 * PARAMETERS: Handle - Handle to be converted to an Node 860 * 861 * RETURN: A Name table entry pointer 862 * 863 * DESCRIPTION: Convert a namespace handle to a real Node 864 * 865 * Note: Real integer handles would allow for more verification 866 * and keep all pointers within this subsystem - however this introduces 867 * more (and perhaps unnecessary) overhead. 868 * 869 ******************************************************************************/ 870 871 ACPI_NAMESPACE_NODE * 872 AcpiNsMapHandleToNode ( 873 ACPI_HANDLE Handle) 874 { 875 876 ACPI_FUNCTION_ENTRY (); 877 878 879 /* 880 * Simple implementation 881 */ 882 if ((!Handle) || (Handle == ACPI_ROOT_OBJECT)) 883 { 884 return (AcpiGbl_RootNode); 885 } 886 887 /* We can at least attempt to verify the handle */ 888 889 if (ACPI_GET_DESCRIPTOR_TYPE (Handle) != ACPI_DESC_TYPE_NAMED) 890 { 891 return (NULL); 892 } 893 894 return (ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Handle)); 895 } 896 897 898 /******************************************************************************* 899 * 900 * FUNCTION: AcpiNsConvertEntryToHandle 901 * 902 * PARAMETERS: Node - Node to be converted to a Handle 903 * 904 * RETURN: A user handle 905 * 906 * DESCRIPTION: Convert a real Node to a namespace handle 907 * 908 ******************************************************************************/ 909 910 ACPI_HANDLE 911 AcpiNsConvertEntryToHandle ( 912 ACPI_NAMESPACE_NODE *Node) 913 { 914 915 916 /* 917 * Simple implementation for now; 918 */ 919 return ((ACPI_HANDLE) Node); 920 921 922 /* Example future implementation --------------------- 923 924 if (!Node) 925 { 926 return (NULL); 927 } 928 929 if (Node == AcpiGbl_RootNode) 930 { 931 return (ACPI_ROOT_OBJECT); 932 } 933 934 935 return ((ACPI_HANDLE) Node); 936 ------------------------------------------------------*/ 937 } 938 939 940 /******************************************************************************* 941 * 942 * FUNCTION: AcpiNsTerminate 943 * 944 * PARAMETERS: none 945 * 946 * RETURN: none 947 * 948 * DESCRIPTION: free memory allocated for namespace and ACPI table storage. 949 * 950 ******************************************************************************/ 951 952 void 953 AcpiNsTerminate ( 954 void) 955 { 956 ACPI_OPERAND_OBJECT *ObjDesc; 957 958 959 ACPI_FUNCTION_TRACE (NsTerminate); 960 961 962 /* 963 * 1) Free the entire namespace -- all nodes and objects 964 * 965 * Delete all object descriptors attached to namepsace nodes 966 */ 967 AcpiNsDeleteNamespaceSubtree (AcpiGbl_RootNode); 968 969 /* Detach any objects attached to the root */ 970 971 ObjDesc = AcpiNsGetAttachedObject (AcpiGbl_RootNode); 972 if (ObjDesc) 973 { 974 AcpiNsDetachObject (AcpiGbl_RootNode); 975 } 976 977 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Namespace freed\n")); 978 979 /* 980 * 2) Now we can delete the ACPI tables 981 */ 982 AcpiTbDeleteAllTables (); 983 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "ACPI Tables freed\n")); 984 985 return_VOID; 986 } 987 988 989 /******************************************************************************* 990 * 991 * FUNCTION: AcpiNsOpensScope 992 * 993 * PARAMETERS: Type - A valid namespace type 994 * 995 * RETURN: NEWSCOPE if the passed type "opens a name scope" according 996 * to the ACPI specification, else 0 997 * 998 ******************************************************************************/ 999 1000 UINT32 1001 AcpiNsOpensScope ( 1002 ACPI_OBJECT_TYPE Type) 1003 { 1004 ACPI_FUNCTION_TRACE_STR (NsOpensScope, AcpiUtGetTypeName (Type)); 1005 1006 1007 if (!AcpiUtValidObjectType (Type)) 1008 { 1009 /* type code out of range */ 1010 1011 ACPI_WARNING ((AE_INFO, "Invalid Object Type %X", Type)); 1012 return_UINT32 (ACPI_NS_NORMAL); 1013 } 1014 1015 return_UINT32 (((UINT32) AcpiGbl_NsProperties[Type]) & ACPI_NS_NEWSCOPE); 1016 } 1017 1018 1019 /******************************************************************************* 1020 * 1021 * FUNCTION: AcpiNsGetNode 1022 * 1023 * PARAMETERS: *Pathname - Name to be found, in external (ASL) format. The 1024 * \ (backslash) and ^ (carat) prefixes, and the 1025 * . (period) to separate segments are supported. 1026 * PrefixNode - Root of subtree to be searched, or NS_ALL for the 1027 * root of the name space. If Name is fully 1028 * qualified (first INT8 is '\'), the passed value 1029 * of Scope will not be accessed. 1030 * Flags - Used to indicate whether to perform upsearch or 1031 * not. 1032 * ReturnNode - Where the Node is returned 1033 * 1034 * DESCRIPTION: Look up a name relative to a given scope and return the 1035 * corresponding Node. NOTE: Scope can be null. 1036 * 1037 * MUTEX: Locks namespace 1038 * 1039 ******************************************************************************/ 1040 1041 ACPI_STATUS 1042 AcpiNsGetNode ( 1043 ACPI_NAMESPACE_NODE *PrefixNode, 1044 char *Pathname, 1045 UINT32 Flags, 1046 ACPI_NAMESPACE_NODE **ReturnNode) 1047 { 1048 ACPI_GENERIC_STATE ScopeInfo; 1049 ACPI_STATUS Status; 1050 char *InternalPath; 1051 1052 1053 ACPI_FUNCTION_TRACE_PTR (NsGetNode, Pathname); 1054 1055 1056 if (!Pathname) 1057 { 1058 *ReturnNode = PrefixNode; 1059 if (!PrefixNode) 1060 { 1061 *ReturnNode = AcpiGbl_RootNode; 1062 } 1063 return_ACPI_STATUS (AE_OK); 1064 } 1065 1066 /* Convert path to internal representation */ 1067 1068 Status = AcpiNsInternalizeName (Pathname, &InternalPath); 1069 if (ACPI_FAILURE (Status)) 1070 { 1071 return_ACPI_STATUS (Status); 1072 } 1073 1074 /* Must lock namespace during lookup */ 1075 1076 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 1077 if (ACPI_FAILURE (Status)) 1078 { 1079 goto Cleanup; 1080 } 1081 1082 /* Setup lookup scope (search starting point) */ 1083 1084 ScopeInfo.Scope.Node = PrefixNode; 1085 1086 /* Lookup the name in the namespace */ 1087 1088 Status = AcpiNsLookup (&ScopeInfo, InternalPath, ACPI_TYPE_ANY, 1089 ACPI_IMODE_EXECUTE, (Flags | ACPI_NS_DONT_OPEN_SCOPE), 1090 NULL, ReturnNode); 1091 if (ACPI_FAILURE (Status)) 1092 { 1093 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "%s, %s\n", 1094 Pathname, AcpiFormatException (Status))); 1095 } 1096 1097 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 1098 1099 Cleanup: 1100 ACPI_FREE (InternalPath); 1101 return_ACPI_STATUS (Status); 1102 } 1103 1104 1105 /******************************************************************************* 1106 * 1107 * FUNCTION: AcpiNsGetParentNode 1108 * 1109 * PARAMETERS: Node - Current table entry 1110 * 1111 * RETURN: Parent entry of the given entry 1112 * 1113 * DESCRIPTION: Obtain the parent entry for a given entry in the namespace. 1114 * 1115 ******************************************************************************/ 1116 1117 ACPI_NAMESPACE_NODE * 1118 AcpiNsGetParentNode ( 1119 ACPI_NAMESPACE_NODE *Node) 1120 { 1121 ACPI_FUNCTION_ENTRY (); 1122 1123 1124 if (!Node) 1125 { 1126 return (NULL); 1127 } 1128 1129 /* 1130 * Walk to the end of this peer list. The last entry is marked with a flag 1131 * and the peer pointer is really a pointer back to the parent. This saves 1132 * putting a parent back pointer in each and every named object! 1133 */ 1134 while (!(Node->Flags & ANOBJ_END_OF_PEER_LIST)) 1135 { 1136 Node = Node->Peer; 1137 } 1138 1139 return (Node->Peer); 1140 } 1141 1142 1143 /******************************************************************************* 1144 * 1145 * FUNCTION: AcpiNsGetNextValidNode 1146 * 1147 * PARAMETERS: Node - Current table entry 1148 * 1149 * RETURN: Next valid Node in the linked node list. NULL if no more valid 1150 * nodes. 1151 * 1152 * DESCRIPTION: Find the next valid node within a name table. 1153 * Useful for implementing NULL-end-of-list loops. 1154 * 1155 ******************************************************************************/ 1156 1157 ACPI_NAMESPACE_NODE * 1158 AcpiNsGetNextValidNode ( 1159 ACPI_NAMESPACE_NODE *Node) 1160 { 1161 1162 /* If we are at the end of this peer list, return NULL */ 1163 1164 if (Node->Flags & ANOBJ_END_OF_PEER_LIST) 1165 { 1166 return NULL; 1167 } 1168 1169 /* Otherwise just return the next peer */ 1170 1171 return (Node->Peer); 1172 } 1173 1174 1175 #ifdef ACPI_OBSOLETE_FUNCTIONS 1176 /******************************************************************************* 1177 * 1178 * FUNCTION: AcpiNsFindParentName 1179 * 1180 * PARAMETERS: *ChildNode - Named Obj whose name is to be found 1181 * 1182 * RETURN: The ACPI name 1183 * 1184 * DESCRIPTION: Search for the given obj in its parent scope and return the 1185 * name segment, or "????" if the parent name can't be found 1186 * (which "should not happen"). 1187 * 1188 ******************************************************************************/ 1189 1190 ACPI_NAME 1191 AcpiNsFindParentName ( 1192 ACPI_NAMESPACE_NODE *ChildNode) 1193 { 1194 ACPI_NAMESPACE_NODE *ParentNode; 1195 1196 1197 ACPI_FUNCTION_TRACE (NsFindParentName); 1198 1199 1200 if (ChildNode) 1201 { 1202 /* Valid entry. Get the parent Node */ 1203 1204 ParentNode = AcpiNsGetParentNode (ChildNode); 1205 if (ParentNode) 1206 { 1207 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 1208 "Parent of %p [%4.4s] is %p [%4.4s]\n", 1209 ChildNode, AcpiUtGetNodeName (ChildNode), 1210 ParentNode, AcpiUtGetNodeName (ParentNode))); 1211 1212 if (ParentNode->Name.Integer) 1213 { 1214 return_VALUE ((ACPI_NAME) ParentNode->Name.Integer); 1215 } 1216 } 1217 1218 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 1219 "Unable to find parent of %p (%4.4s)\n", 1220 ChildNode, AcpiUtGetNodeName (ChildNode))); 1221 } 1222 1223 return_VALUE (ACPI_UNKNOWN_NAME); 1224 } 1225 #endif 1226 1227 1228