dtutils.c revision 208625
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 "aslcompiler.h" 119#include "dtcompiler.h" 120#include "actables.h" 121 122#define _COMPONENT DT_COMPILER 123 ACPI_MODULE_NAME ("dtutils") 124 125/* Local prototypes */ 126 127static void 128DtSum ( 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 149void 150DtError ( 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 203void 204DtNameError ( 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 255void 256DtFatal ( 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 286ACPI_STATUS 287DtStrtoul64 ( 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 369UINT32 370DtGetFileSize ( 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 399char * 400DtGetFieldValue ( 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 433UINT8 434DtGetFieldType ( 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 Type = DT_FIELD_TYPE_BUFFER; 476 break; 477 478 case ACPI_DMT_PCI_PATH: 479 Type = DT_FIELD_TYPE_PCI_PATH; 480 break; 481 482 case ACPI_DMT_GAS: 483 case ACPI_DMT_HESTNTFY: 484 Type = DT_FIELD_TYPE_INLINE_SUBTABLE; 485 break; 486 487 default: 488 Type = DT_FIELD_TYPE_INTEGER; 489 break; 490 } 491 492 return (Type); 493} 494 495 496/****************************************************************************** 497 * 498 * FUNCTION: DtGetBufferLength 499 * 500 * PARAMETERS: Buffer - List of integers, 501 * for example "10 3A 4F 2E" 502 * 503 * RETURN: Count of integer 504 * 505 * DESCRIPTION: Get length of bytes needed to store the integers 506 * 507 *****************************************************************************/ 508 509UINT32 510DtGetBufferLength ( 511 char *Buffer) 512{ 513 UINT32 ByteLength = 0; 514 515 516 while (*Buffer) 517 { 518 if (*Buffer == ' ') 519 { 520 ByteLength++; 521 522 while (*Buffer == ' ') 523 { 524 Buffer++; 525 } 526 } 527 528 Buffer++; 529 } 530 531 return (++ByteLength); 532} 533 534 535/****************************************************************************** 536 * 537 * FUNCTION: DtGetFieldLength 538 * 539 * PARAMETERS: Field - Current field list pointer 540 * Info - Data table info 541 * 542 * RETURN: Field length 543 * 544 * DESCRIPTION: Get length of bytes needed to compile the field 545 * 546 *****************************************************************************/ 547 548UINT32 549DtGetFieldLength ( 550 DT_FIELD *Field, 551 ACPI_DMTABLE_INFO *Info) 552{ 553 UINT32 ByteLength = 0; 554 char *Value; 555 556 557 /* Length is based upon the opcode for this field in the info table */ 558 559 switch (Info->Opcode) 560 { 561 case ACPI_DMT_FLAG0: 562 case ACPI_DMT_FLAG1: 563 case ACPI_DMT_FLAG2: 564 case ACPI_DMT_FLAG3: 565 case ACPI_DMT_FLAG4: 566 case ACPI_DMT_FLAG5: 567 case ACPI_DMT_FLAG6: 568 case ACPI_DMT_FLAG7: 569 case ACPI_DMT_FLAGS0: 570 case ACPI_DMT_FLAGS2: 571 ByteLength = 0; 572 break; 573 574 case ACPI_DMT_UINT8: 575 case ACPI_DMT_CHKSUM: 576 case ACPI_DMT_SPACEID: 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_IVRS: 583 ByteLength = 1; 584 break; 585 586 case ACPI_DMT_UINT16: 587 case ACPI_DMT_DMAR: 588 case ACPI_DMT_HEST: 589 case ACPI_DMT_PCI_PATH: 590 ByteLength = 2; 591 break; 592 593 case ACPI_DMT_UINT24: 594 ByteLength = 3; 595 break; 596 597 case ACPI_DMT_UINT32: 598 case ACPI_DMT_NAME4: 599 case ACPI_DMT_SIG: 600 ByteLength = 4; 601 break; 602 603 case ACPI_DMT_NAME6: 604 ByteLength = 6; 605 break; 606 607 case ACPI_DMT_UINT56: 608 ByteLength = 7; 609 break; 610 611 case ACPI_DMT_UINT64: 612 case ACPI_DMT_NAME8: 613 ByteLength = 8; 614 break; 615 616 case ACPI_DMT_STRING: 617 Value = DtGetFieldValue (Field, Info->Name); 618 619 /* TBD: error if Value is NULL? (as below?) */ 620 621 ByteLength = ACPI_STRLEN (Value) + 1; 622 break; 623 624 case ACPI_DMT_GAS: 625 ByteLength = sizeof (ACPI_GENERIC_ADDRESS); 626 break; 627 628 case ACPI_DMT_HESTNTFY: 629 ByteLength = sizeof (ACPI_HEST_NOTIFY); 630 break; 631 632 case ACPI_DMT_BUFFER: 633 Value = DtGetFieldValue (Field, Info->Name); 634 if (Value) 635 { 636 ByteLength = DtGetBufferLength (Value); 637 } 638 else 639 { /* At this point, this is a fatal error */ 640 641 sprintf (MsgBuffer, "Expected \"%s\"", Info->Name); 642 DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, MsgBuffer); 643 } 644 break; 645 646 case ACPI_DMT_BUF16: 647 ByteLength = 16; 648 break; 649 650 default: 651 DtFatal (ASL_MSG_COMPILER_INTERNAL, Field, "Invalid table opcode"); 652 break; 653 } 654 655 return (ByteLength); 656} 657 658 659/****************************************************************************** 660 * 661 * FUNCTION: DtSum 662 * 663 * PARAMETERS: DT_WALK_CALLBACK: 664 * Subtable - Subtable 665 * Context - Unused 666 * ReturnValue - Store the checksum of subtable 667 * 668 * RETURN: Status 669 * 670 * DESCRIPTION: Get the checksum of subtable 671 * 672 *****************************************************************************/ 673 674static void 675DtSum ( 676 DT_SUBTABLE *Subtable, 677 void *Context, 678 void *ReturnValue) 679{ 680 UINT8 Checksum; 681 UINT8 *Sum = ReturnValue; 682 683 684 Checksum = AcpiTbChecksum (Subtable->Buffer, Subtable->Length); 685 *Sum = (UINT8) (*Sum + Checksum); 686} 687 688 689/****************************************************************************** 690 * 691 * FUNCTION: DtSetTableChecksum 692 * 693 * PARAMETERS: ChecksumPointer - Where to return the checksum 694 * 695 * RETURN: None 696 * 697 * DESCRIPTION: Set checksum of the whole data table into the checksum field 698 * 699 *****************************************************************************/ 700 701void 702DtSetTableChecksum ( 703 UINT8 *ChecksumPointer) 704{ 705 UINT8 Checksum = 0; 706 UINT8 OldSum; 707 708 709 DtWalkTableTree (Gbl_RootTable, DtSum, NULL, &Checksum); 710 711 OldSum = *ChecksumPointer; 712 Checksum = (UINT8) (Checksum - OldSum); 713 714 /* Compute the final checksum */ 715 716 Checksum = (UINT8) (0 - Checksum); 717 *ChecksumPointer = Checksum; 718} 719 720 721/****************************************************************************** 722 * 723 * FUNCTION: DtSetTableLength 724 * 725 * PARAMETERS: None 726 * 727 * RETURN: None 728 * 729 * DESCRIPTION: Walk the subtables and set all the length fields 730 * 731 *****************************************************************************/ 732 733void 734DtSetTableLength ( 735 void) 736{ 737 DT_SUBTABLE *ParentTable; 738 DT_SUBTABLE *ChildTable; 739 740 741 ParentTable = Gbl_RootTable; 742 ChildTable = NULL; 743 744 if (!ParentTable) 745 { 746 return; 747 } 748 749 DtSetSubtableLength (ParentTable); 750 751 while (1) 752 { 753 ChildTable = DtGetNextSubtable (ParentTable, ChildTable); 754 if (ChildTable) 755 { 756 if (ChildTable->Child) 757 { 758 ParentTable = ChildTable; 759 ChildTable = NULL; 760 } 761 else 762 { 763 ParentTable->TotalLength += ChildTable->TotalLength; 764 if (ParentTable->LengthField) 765 { 766 DtSetSubtableLength (ParentTable); 767 } 768 } 769 } 770 else 771 { 772 ChildTable = ParentTable; 773 774 if (ChildTable == Gbl_RootTable) 775 { 776 break; 777 } 778 779 ParentTable = DtGetParentSubtable (ParentTable); 780 781 ParentTable->TotalLength += ChildTable->TotalLength; 782 if (ParentTable->LengthField) 783 { 784 DtSetSubtableLength (ParentTable); 785 } 786 } 787 } 788} 789 790 791/****************************************************************************** 792 * 793 * FUNCTION: DtWalkTableTree 794 * 795 * PARAMETERS: StartTable - Subtable in the tree where walking begins 796 * UserFunction - Called during the walk 797 * Context - Passed to user function 798 * ReturnValue - The return value of UserFunction 799 * 800 * RETURN: None 801 * 802 * DESCRIPTION: Performs a depth-first walk of the subtable tree 803 * 804 *****************************************************************************/ 805 806void 807DtWalkTableTree ( 808 DT_SUBTABLE *StartTable, 809 DT_WALK_CALLBACK UserFunction, 810 void *Context, 811 void *ReturnValue) 812{ 813 DT_SUBTABLE *ParentTable; 814 DT_SUBTABLE *ChildTable; 815 816 817 ParentTable = StartTable; 818 ChildTable = NULL; 819 820 if (!ParentTable) 821 { 822 return; 823 } 824 825 UserFunction (ParentTable, Context, ReturnValue); 826 827 while (1) 828 { 829 ChildTable = DtGetNextSubtable (ParentTable, ChildTable); 830 if (ChildTable) 831 { 832 UserFunction (ChildTable, Context, ReturnValue); 833 834 if (ChildTable->Child) 835 { 836 ParentTable = ChildTable; 837 ChildTable = NULL; 838 } 839 } 840 else 841 { 842 ChildTable = ParentTable; 843 if (ChildTable == Gbl_RootTable) 844 { 845 break; 846 } 847 848 ParentTable = DtGetParentSubtable (ParentTable); 849 850 if (ChildTable->Peer == StartTable) 851 { 852 break; 853 } 854 } 855 } 856} 857 858 859/****************************************************************************** 860 * 861 * FUNCTION: DtFreeFieldList 862 * 863 * PARAMETERS: None 864 * 865 * RETURN: None 866 * 867 * DESCRIPTION: Free the field list 868 * 869 *****************************************************************************/ 870 871void 872DtFreeFieldList ( 873 void) 874{ 875 DT_FIELD *Field = Gbl_FieldList; 876 DT_FIELD *NextField; 877 878 879 /* Walk and free entire field list */ 880 881 while (Field) 882 { 883 NextField = Field->Next; /* Save link */ 884 885 if (!(Field->Flags & DT_FIELD_NOT_ALLOCATED)) 886 { 887 ACPI_FREE (Field->Name); 888 ACPI_FREE (Field->Value); 889 } 890 891 ACPI_FREE (Field); 892 Field = NextField; 893 } 894} 895