1 /****************************************************************************** 2 * 3 * Module Name: dtutils.c - Utility routines for the data table compiler 4 * 5 *****************************************************************************/ 6 7 /****************************************************************************** 8 * 9 * 1. Copyright Notice 10 * 11 * Some or all of this work - Copyright (c) 1999 - 2010, 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 #define __DTUTILS_C__ 117 118 #include <contrib/dev/acpica/compiler/aslcompiler.h> 119 #include <contrib/dev/acpica/compiler/dtcompiler.h> 120 #include <contrib/dev/acpica/include/actables.h> 121 122 #define _COMPONENT DT_COMPILER 123 ACPI_MODULE_NAME ("dtutils") 124 125 /* Local prototypes */ 126 127 static void 128 DtSum ( 129 DT_SUBTABLE *Subtable, 130 void *Context, 131 void *ReturnValue); 132 133 134 /****************************************************************************** 135 * 136 * FUNCTION: DtError 137 * 138 * PARAMETERS: Level - Seriousness (Warning/error, etc.) 139 * MessageId - Index into global message buffer 140 * Op - Parse node where error happened 141 * ExtraMessage - additional error message 142 * 143 * RETURN: None 144 * 145 * DESCRIPTION: Common error interface for data table compiler 146 * 147 *****************************************************************************/ 148 149 void 150 DtError ( 151 UINT8 Level, 152 UINT8 MessageId, 153 DT_FIELD *FieldObject, 154 char *ExtraMessage) 155 { 156 157 switch (Level) 158 { 159 case ASL_WARNING2: 160 case ASL_WARNING3: 161 if (Gbl_WarningLevel < Level) 162 { 163 return; 164 } 165 break; 166 167 default: 168 break; 169 } 170 171 if (FieldObject) 172 { 173 AslCommonError (Level, MessageId, 174 FieldObject->Line, 175 FieldObject->Line, 176 FieldObject->ByteOffset, 177 FieldObject->Column, 178 Gbl_Files[ASL_FILE_INPUT].Filename, ExtraMessage); 179 } 180 else 181 { 182 AslCommonError (Level, MessageId, 0, 183 0, 0, 0, 0, ExtraMessage); 184 } 185 } 186 187 188 /****************************************************************************** 189 * 190 * FUNCTION: DtNameError 191 * 192 * PARAMETERS: Level - Seriousness (Warning/error, etc.) 193 * MessageId - Index into global message buffer 194 * Op - Parse node where error happened 195 * ExtraMessage - additional error message 196 * 197 * RETURN: None 198 * 199 * DESCRIPTION: Error interface for named objects 200 * 201 *****************************************************************************/ 202 203 void 204 DtNameError ( 205 UINT8 Level, 206 UINT8 MessageId, 207 DT_FIELD *FieldObject, 208 char *ExtraMessage) 209 { 210 211 switch (Level) 212 { 213 case ASL_WARNING2: 214 case ASL_WARNING3: 215 if (Gbl_WarningLevel < Level) 216 { 217 return; 218 } 219 break; 220 221 default: 222 break; 223 } 224 225 if (FieldObject) 226 { 227 AslCommonError (Level, MessageId, 228 FieldObject->Line, 229 FieldObject->Line, 230 FieldObject->ByteOffset, 231 FieldObject->NameColumn, 232 Gbl_Files[ASL_FILE_INPUT].Filename, ExtraMessage); 233 } 234 else 235 { 236 AslCommonError (Level, MessageId, 0, 237 0, 0, 0, 0, ExtraMessage); 238 } 239 } 240 241 242 /******************************************************************************* 243 * 244 * FUNCTION: DtFatal 245 * 246 * PARAMETERS: None 247 * 248 * RETURN: None 249 * 250 * DESCRIPTION: Dump the error log and abort the compiler. Used for serious 251 * compile or I/O errors 252 * 253 ******************************************************************************/ 254 255 void 256 DtFatal ( 257 UINT8 MessageId, 258 DT_FIELD *FieldObject, 259 char *ExtraMessage) 260 { 261 262 DtError (ASL_ERROR, MessageId, FieldObject, ExtraMessage); 263 264 CmCleanupAndExit (); 265 exit (1); 266 } 267 268 269 /****************************************************************************** 270 * 271 * FUNCTION: DtStrtoul64 272 * 273 * PARAMETERS: String - Null terminated string 274 * ReturnInteger - Where the converted integer is returned 275 * 276 * RETURN: Status 277 * 278 * DESCRIPTION: Simple conversion of a string hex integer constant to unsigned 279 * value. Assumes no leading "0x" for the constant. 280 * 281 * Portability note: The reason this function exists is because a 64-bit 282 * sscanf is not available in all environments. 283 * 284 *****************************************************************************/ 285 286 ACPI_STATUS 287 DtStrtoul64 ( 288 char *String, 289 UINT64 *ReturnInteger) 290 { 291 char *ThisChar = String; 292 UINT32 ThisDigit; 293 UINT64 ReturnValue = 0; 294 int DigitCount = 0; 295 296 297 /* Skip over any white space in the buffer */ 298 299 while ((*ThisChar == ' ') || (*ThisChar == '\t')) 300 { 301 ThisChar++; 302 } 303 304 /* Skip leading zeros */ 305 306 while ((*ThisChar) == '0') 307 { 308 ThisChar++; 309 } 310 311 /* Convert character-by-character */ 312 313 while (*ThisChar) 314 { 315 if (ACPI_IS_DIGIT (*ThisChar)) 316 { 317 /* Convert ASCII 0-9 to Decimal value */ 318 319 ThisDigit = ((UINT8) *ThisChar) - '0'; 320 } 321 else /* Letter */ 322 { 323 ThisDigit = (UINT32) ACPI_TOUPPER (*ThisChar); 324 if (!ACPI_IS_XDIGIT ((char) ThisDigit)) 325 { 326 /* Not A-F */ 327 328 return (AE_BAD_CHARACTER); 329 } 330 331 /* Convert ASCII Hex char (A-F) to value */ 332 333 ThisDigit = (ThisDigit - 'A') + 10; 334 } 335 336 /* Insert the 4-bit hex digit */ 337 338 ReturnValue <<= 4; 339 ReturnValue += ThisDigit; 340 341 ThisChar++; 342 DigitCount++; 343 if (DigitCount > 16) 344 { 345 /* Value is too large (> 64 bits/8 bytes/16 hex digits) */ 346 347 return (AE_LIMIT); 348 } 349 } 350 351 *ReturnInteger = ReturnValue; 352 return (AE_OK); 353 } 354 355 356 /****************************************************************************** 357 * 358 * FUNCTION: DtGetFileSize 359 * 360 * PARAMETERS: Handle - Open file handler 361 * 362 * RETURN: Current file size 363 * 364 * DESCRIPTION: Get the current size of a file. Seek to the EOF and get the 365 * offset. Seek back to the original location. 366 * 367 *****************************************************************************/ 368 369 UINT32 370 DtGetFileSize ( 371 FILE *Handle) 372 { 373 int CurrentOffset; 374 int LastOffset; 375 376 377 CurrentOffset = ftell (Handle); 378 fseek (Handle, 0, SEEK_END); 379 LastOffset = ftell (Handle); 380 fseek (Handle, CurrentOffset, SEEK_SET); 381 382 return ((UINT32) LastOffset); 383 } 384 385 386 /****************************************************************************** 387 * 388 * FUNCTION: DtGetFieldValue 389 * 390 * PARAMETERS: Field - Current field list pointer 391 * Name - Field name 392 * 393 * RETURN: Field value 394 * 395 * DESCRIPTION: Get field value 396 * 397 *****************************************************************************/ 398 399 char * 400 DtGetFieldValue ( 401 DT_FIELD *Field, 402 char *Name) 403 { 404 405 /* Search the field list for the name */ 406 407 while (Field) 408 { 409 if (!ACPI_STRCMP (Name, Field->Name)) 410 { 411 return (Field->Value); 412 } 413 414 Field = Field->Next; 415 } 416 417 return (NULL); 418 } 419 420 421 /****************************************************************************** 422 * 423 * FUNCTION: DtGetFieldType 424 * 425 * PARAMETERS: Info - Data table info 426 * 427 * RETURN: Field type 428 * 429 * DESCRIPTION: Get field type 430 * 431 *****************************************************************************/ 432 433 UINT8 434 DtGetFieldType ( 435 ACPI_DMTABLE_INFO *Info) 436 { 437 UINT8 Type; 438 439 440 /* DT_FLAG means that this is the start of a block of flag bits */ 441 /* TBD - we can make these a separate opcode later */ 442 443 if (Info->Flags & DT_FLAG) 444 { 445 return (DT_FIELD_TYPE_FLAGS_INTEGER); 446 } 447 448 /* Type is based upon the opcode for this field in the info table */ 449 450 switch (Info->Opcode) 451 { 452 case ACPI_DMT_FLAG0: 453 case ACPI_DMT_FLAG1: 454 case ACPI_DMT_FLAG2: 455 case ACPI_DMT_FLAG3: 456 case ACPI_DMT_FLAG4: 457 case ACPI_DMT_FLAG5: 458 case ACPI_DMT_FLAG6: 459 case ACPI_DMT_FLAG7: 460 case ACPI_DMT_FLAGS0: 461 case ACPI_DMT_FLAGS2: 462 Type = DT_FIELD_TYPE_FLAG; 463 break; 464 465 case ACPI_DMT_NAME4: 466 case ACPI_DMT_SIG: 467 case ACPI_DMT_NAME6: 468 case ACPI_DMT_NAME8: 469 case ACPI_DMT_STRING: 470 Type = DT_FIELD_TYPE_STRING; 471 break; 472 473 case ACPI_DMT_BUFFER: 474 case ACPI_DMT_BUF16: 475 case ACPI_DMT_PCI_PATH: 476 Type = DT_FIELD_TYPE_BUFFER; 477 break; 478 479 case ACPI_DMT_GAS: 480 case ACPI_DMT_HESTNTFY: 481 Type = DT_FIELD_TYPE_INLINE_SUBTABLE; 482 break; 483 484 default: 485 Type = DT_FIELD_TYPE_INTEGER; 486 break; 487 } 488 489 return (Type); 490 } 491 492 493 /****************************************************************************** 494 * 495 * FUNCTION: DtGetBufferLength 496 * 497 * PARAMETERS: Buffer - List of integers, 498 * for example "10 3A 4F 2E" 499 * 500 * RETURN: Count of integer 501 * 502 * DESCRIPTION: Get length of bytes needed to store the integers 503 * 504 *****************************************************************************/ 505 506 UINT32 507 DtGetBufferLength ( 508 char *Buffer) 509 { 510 UINT32 ByteLength = 0; 511 512 513 while (*Buffer) 514 { 515 if (*Buffer == ' ') 516 { 517 ByteLength++; 518 519 while (*Buffer == ' ') 520 { 521 Buffer++; 522 } 523 } 524 525 Buffer++; 526 } 527 528 return (++ByteLength); 529 } 530 531 532 /****************************************************************************** 533 * 534 * FUNCTION: DtGetFieldLength 535 * 536 * PARAMETERS: Field - Current field list pointer 537 * Info - Data table info 538 * 539 * RETURN: Field length 540 * 541 * DESCRIPTION: Get length of bytes needed to compile the field 542 * 543 * Note: This function must remain in sync with AcpiDmDumpTable. 544 * 545 *****************************************************************************/ 546 547 UINT32 548 DtGetFieldLength ( 549 DT_FIELD *Field, 550 ACPI_DMTABLE_INFO *Info) 551 { 552 UINT32 ByteLength = 0; 553 char *Value; 554 555 556 /* Length is based upon the opcode for this field in the info table */ 557 558 switch (Info->Opcode) 559 { 560 case ACPI_DMT_FLAG0: 561 case ACPI_DMT_FLAG1: 562 case ACPI_DMT_FLAG2: 563 case ACPI_DMT_FLAG3: 564 case ACPI_DMT_FLAG4: 565 case ACPI_DMT_FLAG5: 566 case ACPI_DMT_FLAG6: 567 case ACPI_DMT_FLAG7: 568 case ACPI_DMT_FLAGS0: 569 case ACPI_DMT_FLAGS2: 570 ByteLength = 0; 571 break; 572 573 case ACPI_DMT_UINT8: 574 case ACPI_DMT_CHKSUM: 575 case ACPI_DMT_SPACEID: 576 case ACPI_DMT_IVRS: 577 case ACPI_DMT_MADT: 578 case ACPI_DMT_SRAT: 579 case ACPI_DMT_ASF: 580 case ACPI_DMT_HESTNTYP: 581 case ACPI_DMT_FADTPM: 582 case ACPI_DMT_EINJACT: 583 case ACPI_DMT_EINJINST: 584 case ACPI_DMT_ERSTACT: 585 case ACPI_DMT_ERSTINST: 586 ByteLength = 1; 587 break; 588 589 case ACPI_DMT_UINT16: 590 case ACPI_DMT_DMAR: 591 case ACPI_DMT_HEST: 592 case ACPI_DMT_PCI_PATH: 593 ByteLength = 2; 594 break; 595 596 case ACPI_DMT_UINT24: 597 ByteLength = 3; 598 break; 599 600 case ACPI_DMT_UINT32: 601 case ACPI_DMT_NAME4: 602 case ACPI_DMT_SIG: 603 ByteLength = 4; 604 break; 605 606 case ACPI_DMT_NAME6: 607 ByteLength = 6; 608 break; 609 610 case ACPI_DMT_UINT56: 611 ByteLength = 7; 612 break; 613 614 case ACPI_DMT_UINT64: 615 case ACPI_DMT_NAME8: 616 ByteLength = 8; 617 break; 618 619 case ACPI_DMT_STRING: 620 Value = DtGetFieldValue (Field, Info->Name); 621 622 /* TBD: error if Value is NULL? (as below?) */ 623 624 ByteLength = ACPI_STRLEN (Value) + 1; 625 break; 626 627 case ACPI_DMT_GAS: 628 ByteLength = sizeof (ACPI_GENERIC_ADDRESS); 629 break; 630 631 case ACPI_DMT_HESTNTFY: 632 ByteLength = sizeof (ACPI_HEST_NOTIFY); 633 break; 634 635 case ACPI_DMT_BUFFER: 636 Value = DtGetFieldValue (Field, Info->Name); 637 if (Value) 638 { 639 ByteLength = DtGetBufferLength (Value); 640 } 641 else 642 { /* At this point, this is a fatal error */ 643 644 sprintf (MsgBuffer, "Expected \"%s\"", Info->Name); 645 DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, MsgBuffer); 646 } 647 break; 648 649 case ACPI_DMT_BUF16: 650 ByteLength = 16; 651 break; 652 653 default: 654 DtFatal (ASL_MSG_COMPILER_INTERNAL, Field, "Invalid table opcode"); 655 break; 656 } 657 658 return (ByteLength); 659 } 660 661 662 /****************************************************************************** 663 * 664 * FUNCTION: DtSum 665 * 666 * PARAMETERS: DT_WALK_CALLBACK: 667 * Subtable - Subtable 668 * Context - Unused 669 * ReturnValue - Store the checksum of subtable 670 * 671 * RETURN: Status 672 * 673 * DESCRIPTION: Get the checksum of subtable 674 * 675 *****************************************************************************/ 676 677 static void 678 DtSum ( 679 DT_SUBTABLE *Subtable, 680 void *Context, 681 void *ReturnValue) 682 { 683 UINT8 Checksum; 684 UINT8 *Sum = ReturnValue; 685 686 687 Checksum = AcpiTbChecksum (Subtable->Buffer, Subtable->Length); 688 *Sum = (UINT8) (*Sum + Checksum); 689 } 690 691 692 /****************************************************************************** 693 * 694 * FUNCTION: DtSetTableChecksum 695 * 696 * PARAMETERS: ChecksumPointer - Where to return the checksum 697 * 698 * RETURN: None 699 * 700 * DESCRIPTION: Set checksum of the whole data table into the checksum field 701 * 702 *****************************************************************************/ 703 704 void 705 DtSetTableChecksum ( 706 UINT8 *ChecksumPointer) 707 { 708 UINT8 Checksum = 0; 709 UINT8 OldSum; 710 711 712 DtWalkTableTree (Gbl_RootTable, DtSum, NULL, &Checksum); 713 714 OldSum = *ChecksumPointer; 715 Checksum = (UINT8) (Checksum - OldSum); 716 717 /* Compute the final checksum */ 718 719 Checksum = (UINT8) (0 - Checksum); 720 *ChecksumPointer = Checksum; 721 } 722 723 724 /****************************************************************************** 725 * 726 * FUNCTION: DtSetTableLength 727 * 728 * PARAMETERS: None 729 * 730 * RETURN: None 731 * 732 * DESCRIPTION: Walk the subtables and set all the length fields 733 * 734 *****************************************************************************/ 735 736 void 737 DtSetTableLength ( 738 void) 739 { 740 DT_SUBTABLE *ParentTable; 741 DT_SUBTABLE *ChildTable; 742 743 744 ParentTable = Gbl_RootTable; 745 ChildTable = NULL; 746 747 if (!ParentTable) 748 { 749 return; 750 } 751 752 DtSetSubtableLength (ParentTable); 753 754 while (1) 755 { 756 ChildTable = DtGetNextSubtable (ParentTable, ChildTable); 757 if (ChildTable) 758 { 759 if (ChildTable->LengthField) 760 { 761 DtSetSubtableLength (ChildTable); 762 } 763 764 if (ChildTable->Child) 765 { 766 ParentTable = ChildTable; 767 ChildTable = NULL; 768 } 769 else 770 { 771 ParentTable->TotalLength += ChildTable->TotalLength; 772 if (ParentTable->LengthField) 773 { 774 DtSetSubtableLength (ParentTable); 775 } 776 } 777 } 778 else 779 { 780 ChildTable = ParentTable; 781 782 if (ChildTable == Gbl_RootTable) 783 { 784 break; 785 } 786 787 ParentTable = DtGetParentSubtable (ParentTable); 788 789 ParentTable->TotalLength += ChildTable->TotalLength; 790 if (ParentTable->LengthField) 791 { 792 DtSetSubtableLength (ParentTable); 793 } 794 } 795 } 796 } 797 798 799 /****************************************************************************** 800 * 801 * FUNCTION: DtWalkTableTree 802 * 803 * PARAMETERS: StartTable - Subtable in the tree where walking begins 804 * UserFunction - Called during the walk 805 * Context - Passed to user function 806 * ReturnValue - The return value of UserFunction 807 * 808 * RETURN: None 809 * 810 * DESCRIPTION: Performs a depth-first walk of the subtable tree 811 * 812 *****************************************************************************/ 813 814 void 815 DtWalkTableTree ( 816 DT_SUBTABLE *StartTable, 817 DT_WALK_CALLBACK UserFunction, 818 void *Context, 819 void *ReturnValue) 820 { 821 DT_SUBTABLE *ParentTable; 822 DT_SUBTABLE *ChildTable; 823 824 825 ParentTable = StartTable; 826 ChildTable = NULL; 827 828 if (!ParentTable) 829 { 830 return; 831 } 832 833 UserFunction (ParentTable, Context, ReturnValue); 834 835 while (1) 836 { 837 ChildTable = DtGetNextSubtable (ParentTable, ChildTable); 838 if (ChildTable) 839 { 840 UserFunction (ChildTable, Context, ReturnValue); 841 842 if (ChildTable->Child) 843 { 844 ParentTable = ChildTable; 845 ChildTable = NULL; 846 } 847 } 848 else 849 { 850 ChildTable = ParentTable; 851 if (ChildTable == Gbl_RootTable) 852 { 853 break; 854 } 855 856 ParentTable = DtGetParentSubtable (ParentTable); 857 858 if (ChildTable->Peer == StartTable) 859 { 860 break; 861 } 862 } 863 } 864 } 865 866 867 /****************************************************************************** 868 * 869 * FUNCTION: DtFreeFieldList 870 * 871 * PARAMETERS: None 872 * 873 * RETURN: None 874 * 875 * DESCRIPTION: Free the field list 876 * 877 *****************************************************************************/ 878 879 void 880 DtFreeFieldList ( 881 void) 882 { 883 DT_FIELD *Field = Gbl_FieldList; 884 DT_FIELD *NextField; 885 886 887 /* Walk and free entire field list */ 888 889 while (Field) 890 { 891 NextField = Field->Next; /* Save link */ 892 893 if (!(Field->Flags & DT_FIELD_NOT_ALLOCATED)) 894 { 895 ACPI_FREE (Field->Name); 896 ACPI_FREE (Field->Value); 897 } 898 899 ACPI_FREE (Field); 900 Field = NextField; 901 } 902 } 903