1 /****************************************************************************** 2 * 3 * Module Name: aslanalyze.c - Support functions for parse tree walks 4 * 5 *****************************************************************************/ 6 7 /****************************************************************************** 8 * 9 * 1. Copyright Notice 10 * 11 * Some or all of this work - Copyright (c) 1999 - 2022, 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/compiler/aslcompiler.h> 153 #include "aslcompiler.y.h" 154 #include <contrib/dev/acpica/include/acnamesp.h> 155 #include <string.h> 156 157 158 #define _COMPONENT ACPI_COMPILER 159 ACPI_MODULE_NAME ("aslanalyze") 160 161 162 /* Local Prototypes */ 163 164 static ACPI_STATUS 165 ApDeviceSubtreeWalk ( 166 ACPI_PARSE_OBJECT *Op, 167 UINT32 Level, 168 void *Context); 169 170 171 /******************************************************************************* 172 * 173 * FUNCTION: AnIsInternalMethod 174 * 175 * PARAMETERS: Op - Current op 176 * 177 * RETURN: Boolean 178 * 179 * DESCRIPTION: Check for an internal control method. 180 * 181 ******************************************************************************/ 182 183 BOOLEAN 184 AnIsInternalMethod ( 185 ACPI_PARSE_OBJECT *Op) 186 { 187 188 if ((!strcmp (Op->Asl.ExternalName, "\\_OSI")) || 189 (!strcmp (Op->Asl.ExternalName, "_OSI"))) 190 { 191 return (TRUE); 192 } 193 194 return (FALSE); 195 } 196 197 198 /******************************************************************************* 199 * 200 * FUNCTION: AnGetInternalMethodReturnType 201 * 202 * PARAMETERS: Op - Current op 203 * 204 * RETURN: Btype 205 * 206 * DESCRIPTION: Get the return type of an internal method 207 * 208 ******************************************************************************/ 209 210 UINT32 211 AnGetInternalMethodReturnType ( 212 ACPI_PARSE_OBJECT *Op) 213 { 214 215 if ((!strcmp (Op->Asl.ExternalName, "\\_OSI")) || 216 (!strcmp (Op->Asl.ExternalName, "_OSI"))) 217 { 218 return (ACPI_BTYPE_STRING); 219 } 220 221 return (0); 222 } 223 224 225 /******************************************************************************* 226 * 227 * FUNCTION: AnCheckId 228 * 229 * PARAMETERS: Op - Current parse op 230 * Type - HID or CID 231 * 232 * RETURN: None 233 * 234 * DESCRIPTION: Perform various checks on _HID and _CID strings. Only limited 235 * checks can be performed on _CID strings. 236 * 237 ******************************************************************************/ 238 239 void 240 AnCheckId ( 241 ACPI_PARSE_OBJECT *Op, 242 ACPI_NAME Type) 243 { 244 UINT32 i; 245 ACPI_SIZE Length; 246 247 248 /* Only care about string versions of _HID/_CID (integers are legal) */ 249 250 if (Op->Asl.ParseOpcode != PARSEOP_STRING_LITERAL) 251 { 252 return; 253 } 254 255 /* For both _HID and _CID, the string must be non-null */ 256 257 Length = strlen (Op->Asl.Value.String); 258 if (!Length) 259 { 260 AslError (ASL_ERROR, ASL_MSG_NULL_STRING, Op, NULL); 261 return; 262 } 263 264 /* 265 * One of the things we want to catch here is the use of a leading 266 * asterisk in the string -- an odd construct that certain platform 267 * manufacturers are fond of. Technically, a leading asterisk is OK 268 * for _CID, but a valid use of this has not been seen. 269 */ 270 if (*Op->Asl.Value.String == '*') 271 { 272 AslError (ASL_ERROR, ASL_MSG_LEADING_ASTERISK, 273 Op, Op->Asl.Value.String); 274 return; 275 } 276 277 /* _CID strings are bus-specific, no more checks can be performed */ 278 279 if (Type == ASL_TYPE_CID) 280 { 281 return; 282 } 283 284 /* For _HID, all characters must be alphanumeric */ 285 286 for (i = 0; Op->Asl.Value.String[i]; i++) 287 { 288 if (!isalnum ((int) Op->Asl.Value.String[i])) 289 { 290 AslError (ASL_ERROR, ASL_MSG_ALPHANUMERIC_STRING, 291 Op, Op->Asl.Value.String); 292 return; 293 } 294 } 295 296 /* 297 * _HID String must be one of these forms: 298 * 299 * "AAA####" A is an uppercase letter and # is a hex digit 300 * "ACPI####" # is a hex digit 301 * "NNNN####" N is an uppercase letter or decimal digit (0-9) 302 * # is a hex digit (ACPI 5.0) 303 */ 304 if ((Length < 7) || (Length > 8)) 305 { 306 AslError (ASL_ERROR, ASL_MSG_HID_LENGTH, 307 Op, Op->Asl.Value.String); 308 return; 309 } 310 311 /* _HID Length is valid (7 or 8), now check prefix (first 3 or 4 chars) */ 312 313 if (Length == 7) 314 { 315 /* AAA####: Ensure the alphabetic prefix is all uppercase */ 316 317 for (i = 0; i < 3; i++) 318 { 319 if (!isupper ((int) Op->Asl.Value.String[i])) 320 { 321 AslError (ASL_ERROR, ASL_MSG_UPPER_CASE, 322 Op, &Op->Asl.Value.String[i]); 323 return; 324 } 325 } 326 } 327 else /* Length == 8 */ 328 { 329 /* 330 * ACPI#### or NNNN####: 331 * Ensure the prefix contains only uppercase alpha or decimal digits 332 */ 333 for (i = 0; i < 4; i++) 334 { 335 if (!isupper ((int) Op->Asl.Value.String[i]) && 336 !isdigit ((int) Op->Asl.Value.String[i])) 337 { 338 AslError (ASL_ERROR, ASL_MSG_HID_PREFIX, 339 Op, &Op->Asl.Value.String[i]); 340 return; 341 } 342 } 343 } 344 345 /* Remaining characters (suffix) must be hex digits */ 346 347 for (; i < Length; i++) 348 { 349 if (!isxdigit ((int) Op->Asl.Value.String[i])) 350 { 351 AslError (ASL_ERROR, ASL_MSG_HID_SUFFIX, 352 Op, &Op->Asl.Value.String[i]); 353 break; 354 } 355 } 356 } 357 358 359 /******************************************************************************* 360 * 361 * FUNCTION: AnLastStatementIsReturn 362 * 363 * PARAMETERS: Op - A method parse node 364 * 365 * RETURN: TRUE if last statement is an ASL RETURN. False otherwise 366 * 367 * DESCRIPTION: Walk down the list of top level statements within a method 368 * to find the last one. Check if that last statement is in 369 * fact a RETURN statement. 370 * 371 ******************************************************************************/ 372 373 BOOLEAN 374 AnLastStatementIsReturn ( 375 ACPI_PARSE_OBJECT *Op) 376 { 377 ACPI_PARSE_OBJECT *Next; 378 379 380 /* Check if last statement is a return */ 381 382 Next = ASL_GET_CHILD_NODE (Op); 383 while (Next) 384 { 385 if ((!Next->Asl.Next) && 386 (Next->Asl.ParseOpcode == PARSEOP_RETURN)) 387 { 388 return (TRUE); 389 } 390 391 Next = ASL_GET_PEER_NODE (Next); 392 } 393 394 return (FALSE); 395 } 396 397 398 /******************************************************************************* 399 * 400 * FUNCTION: AnCheckMethodReturnValue 401 * 402 * PARAMETERS: Op - Parent 403 * OpInfo - Parent info 404 * ArgOp - Method invocation op 405 * RequiredBtypes - What caller requires 406 * ThisNodeBtype - What this node returns (if anything) 407 * 408 * RETURN: None 409 * 410 * DESCRIPTION: Check a method invocation for 1) A return value and if it does 411 * in fact return a value, 2) check the type of the return value. 412 * 413 ******************************************************************************/ 414 415 void 416 AnCheckMethodReturnValue ( 417 ACPI_PARSE_OBJECT *Op, 418 const ACPI_OPCODE_INFO *OpInfo, 419 ACPI_PARSE_OBJECT *ArgOp, 420 UINT32 RequiredBtypes, 421 UINT32 ThisNodeBtype) 422 { 423 ACPI_PARSE_OBJECT *OwningOp; 424 ACPI_NAMESPACE_NODE *Node; 425 char *ExternalPath; 426 427 428 Node = ArgOp->Asl.Node; 429 430 if (!Node) 431 { 432 /* No error message, this can happen and is OK */ 433 434 return; 435 } 436 437 /* Examine the parent op of this method */ 438 439 OwningOp = Node->Op; 440 ExternalPath = AcpiNsGetNormalizedPathname (Node, TRUE); 441 442 if (OwningOp->Asl.CompileFlags & OP_METHOD_NO_RETVAL) 443 { 444 /* Method NEVER returns a value */ 445 446 AslError (ASL_ERROR, ASL_MSG_NO_RETVAL, Op, ExternalPath); 447 } 448 else if (OwningOp->Asl.CompileFlags & OP_METHOD_SOME_NO_RETVAL) 449 { 450 /* Method SOMETIMES returns a value, SOMETIMES not */ 451 452 AslError (ASL_WARNING, ASL_MSG_SOME_NO_RETVAL, Op, ExternalPath); 453 } 454 else if (!(ThisNodeBtype & RequiredBtypes)) 455 { 456 /* Method returns a value, but the type is wrong */ 457 458 AnFormatBtype (AslGbl_StringBuffer, ThisNodeBtype); 459 AnFormatBtype (AslGbl_StringBuffer2, RequiredBtypes); 460 461 /* 462 * The case where the method does not return any value at all 463 * was already handled in the namespace cross reference 464 * -- Only issue an error if the method in fact returns a value, 465 * but it is of the wrong type 466 */ 467 if (ThisNodeBtype != 0) 468 { 469 sprintf (AslGbl_MsgBuffer, 470 "Method returns [%s], %s operator requires [%s]", 471 AslGbl_StringBuffer, OpInfo->Name, AslGbl_StringBuffer2); 472 473 AslError (ASL_WARNING, ASL_MSG_INVALID_TYPE, ArgOp, AslGbl_MsgBuffer); 474 } 475 } 476 477 if (ExternalPath) 478 { 479 ACPI_FREE (ExternalPath); 480 } 481 } 482 483 484 /******************************************************************************* 485 * 486 * FUNCTION: AnIsResultUsed 487 * 488 * PARAMETERS: Op - Parent op for the operator 489 * 490 * RETURN: TRUE if result from this operation is actually consumed 491 * 492 * DESCRIPTION: Determine if the function result value from an operator is 493 * used. 494 * 495 ******************************************************************************/ 496 497 BOOLEAN 498 AnIsResultUsed ( 499 ACPI_PARSE_OBJECT *Op) 500 { 501 ACPI_PARSE_OBJECT *Parent; 502 503 504 switch (Op->Asl.ParseOpcode) 505 { 506 case PARSEOP_INCREMENT: 507 case PARSEOP_DECREMENT: 508 509 /* These are standalone operators, no return value */ 510 511 return (TRUE); 512 513 default: 514 515 break; 516 } 517 518 /* Examine parent to determine if the return value is used */ 519 520 Parent = Op->Asl.Parent; 521 switch (Parent->Asl.ParseOpcode) 522 { 523 /* If/While - check if the operator is the predicate */ 524 525 case PARSEOP_IF: 526 case PARSEOP_WHILE: 527 528 /* First child is the predicate */ 529 530 if (Parent->Asl.Child == Op) 531 { 532 return (TRUE); 533 } 534 535 return (FALSE); 536 537 /* Not used if one of these is the parent */ 538 539 case PARSEOP_METHOD: 540 case PARSEOP_DEFINITION_BLOCK: 541 case PARSEOP_ELSE: 542 543 return (FALSE); 544 545 default: 546 547 /* Any other type of parent means that the result is used */ 548 549 return (TRUE); 550 } 551 } 552 553 554 /******************************************************************************* 555 * 556 * FUNCTION: ApCheckForGpeNameConflict 557 * 558 * PARAMETERS: Op - Current parse op 559 * 560 * RETURN: None 561 * 562 * DESCRIPTION: Check for a conflict between GPE names within this scope. 563 * Conflict means two GPE names with the same GPE number, but 564 * different types -- such as _L1C and _E1C. 565 * 566 ******************************************************************************/ 567 568 void 569 ApCheckForGpeNameConflict ( 570 ACPI_PARSE_OBJECT *Op) 571 { 572 ACPI_PARSE_OBJECT *NextOp; 573 UINT32 GpeNumber; 574 char Name[ACPI_NAMESEG_SIZE + 1]; 575 char Target[ACPI_NAMESEG_SIZE]; 576 577 578 /* Need a null-terminated string version of NameSeg */ 579 580 ACPI_MOVE_32_TO_32 (Name, Op->Asl.NameSeg); 581 Name[ACPI_NAMESEG_SIZE] = 0; 582 583 /* 584 * For a GPE method: 585 * 1st char must be underscore 586 * 2nd char must be L or E 587 * 3rd/4th chars must be a hex number 588 */ 589 if ((Name[0] != '_') || 590 ((Name[1] != 'L') && (Name[1] != 'E'))) 591 { 592 return; 593 } 594 595 /* Verify 3rd/4th chars are a valid hex value */ 596 597 GpeNumber = strtoul (&Name[2], NULL, 16); 598 if (GpeNumber == ACPI_UINT32_MAX) 599 { 600 return; 601 } 602 603 /* 604 * We are now sure we have an _Lxx or _Exx. 605 * Create the target name that would cause collision (Flip E/L) 606 */ 607 ACPI_MOVE_32_TO_32 (Target, Name); 608 609 /* Inject opposite letter ("L" versus "E") */ 610 611 if (Name[1] == 'L') 612 { 613 Target[1] = 'E'; 614 } 615 else /* Name[1] == 'E' */ 616 { 617 Target[1] = 'L'; 618 } 619 620 /* Search all peers (objects within this scope) for target match */ 621 622 NextOp = Op->Asl.Next; 623 while (NextOp) 624 { 625 /* 626 * We mostly care about methods, but check Name() constructs also, 627 * even though they will get another error for not being a method. 628 * All GPE names must be defined as control methods. 629 */ 630 if ((NextOp->Asl.ParseOpcode == PARSEOP_METHOD) || 631 (NextOp->Asl.ParseOpcode == PARSEOP_NAME)) 632 { 633 if (ACPI_COMPARE_NAMESEG (Target, NextOp->Asl.NameSeg)) 634 { 635 /* Found both _Exy and _Lxy in the same scope, error */ 636 637 AslError (ASL_ERROR, ASL_MSG_GPE_NAME_CONFLICT, NextOp, 638 Name); 639 return; 640 } 641 } 642 643 NextOp = NextOp->Asl.Next; 644 } 645 646 /* OK, no conflict found */ 647 648 return; 649 } 650 651 652 /******************************************************************************* 653 * 654 * FUNCTION: ApCheckRegMethod 655 * 656 * PARAMETERS: Op - Current parse op 657 * 658 * RETURN: None 659 * 660 * DESCRIPTION: Ensure that a _REG method has a corresponding Operation 661 * Region declaration within the same scope. Note: _REG is defined 662 * to have two arguments and must therefore be defined as a 663 * control method. 664 * 665 ******************************************************************************/ 666 667 void 668 ApCheckRegMethod ( 669 ACPI_PARSE_OBJECT *Op) 670 { 671 ACPI_PARSE_OBJECT *Next; 672 ACPI_PARSE_OBJECT *Parent; 673 674 675 /* We are only interested in _REG methods */ 676 677 if (!ACPI_COMPARE_NAMESEG (METHOD_NAME__REG, &Op->Asl.NameSeg)) 678 { 679 return; 680 } 681 682 /* Get the start of the current scope */ 683 684 Parent = Op->Asl.Parent; 685 Next = Parent->Asl.Child; 686 687 /* Search entire scope for an operation region declaration */ 688 689 while (Next) 690 { 691 if (Next->Asl.ParseOpcode == PARSEOP_OPERATIONREGION) 692 { 693 return; /* Found region, OK */ 694 } 695 696 Next = Next->Asl.Next; 697 } 698 699 /* No region found, issue warning */ 700 701 AslError (ASL_WARNING, ASL_MSG_NO_REGION, Op, NULL); 702 } 703 704 705 /******************************************************************************* 706 * 707 * FUNCTION: ApFindNameInDeviceTree 708 * 709 * PARAMETERS: Name - Name to search for 710 * Op - Current parse op 711 * 712 * RETURN: TRUE if name found in the same scope as Op. 713 * 714 * DESCRIPTION: Determine if a name appears in the same scope as Op, as either 715 * a Method() or a Name(). "Same scope" can mean under an If or 716 * Else statement. 717 * 718 * NOTE: Detects _HID/_ADR in this type of construct (legal in ACPI 6.1+) 719 * 720 * Scope (\_SB.PCI0) 721 * { 722 * Device (I2C0) 723 * { 724 * If (SMD0 != 4) { 725 * Name (_HID, "INT3442") 726 * } Else { 727 * Name (_ADR, 0x400) 728 * } 729 * } 730 * } 731 ******************************************************************************/ 732 733 BOOLEAN 734 ApFindNameInDeviceTree ( 735 char *Name, 736 ACPI_PARSE_OBJECT *Op) 737 { 738 ACPI_STATUS Status; 739 740 741 Status = TrWalkParseTree (Op, ASL_WALK_VISIT_DOWNWARD, 742 ApDeviceSubtreeWalk, NULL, Name); 743 744 if (Status == AE_CTRL_TRUE) 745 { 746 return (TRUE); /* Found a match */ 747 } 748 749 return (FALSE); 750 } 751 752 753 /* Callback function for interface above */ 754 755 static ACPI_STATUS 756 ApDeviceSubtreeWalk ( 757 ACPI_PARSE_OBJECT *Op, 758 UINT32 Level, 759 void *Context) 760 { 761 char *Name = ACPI_CAST_PTR (char, Context); 762 763 764 switch (Op->Asl.ParseOpcode) 765 { 766 case PARSEOP_DEVICE: 767 768 /* Level 0 is the starting device, ignore it */ 769 770 if (Level > 0) 771 { 772 /* Ignore sub-devices */ 773 774 return (AE_CTRL_DEPTH); 775 } 776 break; 777 778 case PARSEOP_NAME: 779 case PARSEOP_METHOD: 780 781 /* These are what we are looking for */ 782 783 if (ACPI_COMPARE_NAMESEG (Name, Op->Asl.NameSeg)) 784 { 785 return (AE_CTRL_TRUE); 786 } 787 return (AE_CTRL_DEPTH); 788 789 case PARSEOP_SCOPE: 790 case PARSEOP_FIELD: 791 case PARSEOP_OPERATIONREGION: 792 793 /* 794 * We want to ignore these, because either they can be large 795 * subtrees or open a scope to somewhere else. 796 */ 797 return (AE_CTRL_DEPTH); 798 799 default: 800 break; 801 } 802 803 return (AE_OK); 804 } 805 806 807 /******************************************************************************* 808 * 809 * FUNCTION: ApFindNameInScope 810 * 811 * PARAMETERS: Name - Name to search for 812 * Op - Current parse op 813 * 814 * RETURN: TRUE if name found in the same scope as Op. 815 * 816 * DESCRIPTION: Determine if a name appears in the same scope as Op, as either 817 * a Method() or a Name(). 818 * 819 ******************************************************************************/ 820 821 BOOLEAN 822 ApFindNameInScope ( 823 char *Name, 824 ACPI_PARSE_OBJECT *Op) 825 { 826 ACPI_PARSE_OBJECT *Next; 827 ACPI_PARSE_OBJECT *Parent; 828 829 830 /* Get the start of the current scope */ 831 832 Parent = Op->Asl.Parent; 833 Next = Parent->Asl.Child; 834 835 /* Search entire scope for a match to the name */ 836 837 while (Next) 838 { 839 if ((Next->Asl.ParseOpcode == PARSEOP_METHOD) || 840 (Next->Asl.ParseOpcode == PARSEOP_NAME)) 841 { 842 if (ACPI_COMPARE_NAMESEG (Name, Next->Asl.NameSeg)) 843 { 844 return (TRUE); 845 } 846 } 847 848 Next = Next->Asl.Next; 849 } 850 851 return (FALSE); 852 } 853