Annotation of src/sys/external/bsd/acpica/dist/compiler/dtutils.c, Revision 1.1.1.2
1.1 jruoho 1: /******************************************************************************
2: *
3: * Module Name: dtutils.c - Utility routines for the data table compiler
4: *
5: *****************************************************************************/
6:
1.1.1.2 ! jruoho 7: /*
! 8: * Copyright (C) 2000 - 2011, Intel Corp.
1.1 jruoho 9: * All rights reserved.
10: *
1.1.1.2 ! jruoho 11: * Redistribution and use in source and binary forms, with or without
! 12: * modification, are permitted provided that the following conditions
! 13: * are met:
! 14: * 1. Redistributions of source code must retain the above copyright
! 15: * notice, this list of conditions, and the following disclaimer,
! 16: * without modification.
! 17: * 2. Redistributions in binary form must reproduce at minimum a disclaimer
! 18: * substantially similar to the "NO WARRANTY" disclaimer below
! 19: * ("Disclaimer") and any redistribution must be conditioned upon
! 20: * including a substantially similar Disclaimer requirement for further
! 21: * binary redistribution.
! 22: * 3. Neither the names of the above-listed copyright holders nor the names
! 23: * of any contributors may be used to endorse or promote products derived
! 24: * from this software without specific prior written permission.
! 25: *
! 26: * Alternatively, this software may be distributed under the terms of the
! 27: * GNU General Public License ("GPL") version 2 as published by the Free
! 28: * Software Foundation.
! 29: *
! 30: * NO WARRANTY
! 31: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
! 32: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
! 33: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
! 34: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
! 35: * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
! 36: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
! 37: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 38: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
! 39: * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
! 40: * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
! 41: * POSSIBILITY OF SUCH DAMAGES.
! 42: */
1.1 jruoho 43:
44: #define __DTUTILS_C__
45:
46: #include "aslcompiler.h"
47: #include "dtcompiler.h"
48: #include "actables.h"
49:
50: #define _COMPONENT DT_COMPILER
51: ACPI_MODULE_NAME ("dtutils")
52:
53: /* Local prototypes */
54:
55: static void
56: DtSum (
57: DT_SUBTABLE *Subtable,
58: void *Context,
59: void *ReturnValue);
60:
61:
62: /******************************************************************************
63: *
64: * FUNCTION: DtError
65: *
66: * PARAMETERS: Level - Seriousness (Warning/error, etc.)
67: * MessageId - Index into global message buffer
68: * Op - Parse node where error happened
69: * ExtraMessage - additional error message
70: *
71: * RETURN: None
72: *
73: * DESCRIPTION: Common error interface for data table compiler
74: *
75: *****************************************************************************/
76:
77: void
78: DtError (
79: UINT8 Level,
80: UINT8 MessageId,
81: DT_FIELD *FieldObject,
82: char *ExtraMessage)
83: {
84:
85: switch (Level)
86: {
87: case ASL_WARNING2:
88: case ASL_WARNING3:
89: if (Gbl_WarningLevel < Level)
90: {
91: return;
92: }
93: break;
94:
95: default:
96: break;
97: }
98:
99: if (FieldObject)
100: {
101: AslCommonError (Level, MessageId,
102: FieldObject->Line,
103: FieldObject->Line,
104: FieldObject->ByteOffset,
105: FieldObject->Column,
106: Gbl_Files[ASL_FILE_INPUT].Filename, ExtraMessage);
107: }
108: else
109: {
110: AslCommonError (Level, MessageId, 0,
111: 0, 0, 0, 0, ExtraMessage);
112: }
113: }
114:
115:
116: /******************************************************************************
117: *
118: * FUNCTION: DtNameError
119: *
120: * PARAMETERS: Level - Seriousness (Warning/error, etc.)
121: * MessageId - Index into global message buffer
122: * Op - Parse node where error happened
123: * ExtraMessage - additional error message
124: *
125: * RETURN: None
126: *
127: * DESCRIPTION: Error interface for named objects
128: *
129: *****************************************************************************/
130:
131: void
132: DtNameError (
133: UINT8 Level,
134: UINT8 MessageId,
135: DT_FIELD *FieldObject,
136: char *ExtraMessage)
137: {
138:
139: switch (Level)
140: {
141: case ASL_WARNING2:
142: case ASL_WARNING3:
143: if (Gbl_WarningLevel < Level)
144: {
145: return;
146: }
147: break;
148:
149: default:
150: break;
151: }
152:
153: if (FieldObject)
154: {
155: AslCommonError (Level, MessageId,
156: FieldObject->Line,
157: FieldObject->Line,
158: FieldObject->ByteOffset,
159: FieldObject->NameColumn,
160: Gbl_Files[ASL_FILE_INPUT].Filename, ExtraMessage);
161: }
162: else
163: {
164: AslCommonError (Level, MessageId, 0,
165: 0, 0, 0, 0, ExtraMessage);
166: }
167: }
168:
169:
170: /*******************************************************************************
171: *
172: * FUNCTION: DtFatal
173: *
174: * PARAMETERS: None
175: *
176: * RETURN: None
177: *
178: * DESCRIPTION: Dump the error log and abort the compiler. Used for serious
179: * compile or I/O errors
180: *
181: ******************************************************************************/
182:
183: void
184: DtFatal (
185: UINT8 MessageId,
186: DT_FIELD *FieldObject,
187: char *ExtraMessage)
188: {
189:
190: DtError (ASL_ERROR, MessageId, FieldObject, ExtraMessage);
191:
192: CmCleanupAndExit ();
193: exit (1);
194: }
195:
196:
197: /******************************************************************************
198: *
199: * FUNCTION: DtStrtoul64
200: *
201: * PARAMETERS: String - Null terminated string
202: * ReturnInteger - Where the converted integer is returned
203: *
204: * RETURN: Status
205: *
206: * DESCRIPTION: Simple conversion of a string hex integer constant to unsigned
207: * value. Assumes no leading "0x" for the constant.
208: *
209: * Portability note: The reason this function exists is because a 64-bit
210: * sscanf is not available in all environments.
211: *
212: *****************************************************************************/
213:
214: ACPI_STATUS
215: DtStrtoul64 (
216: char *String,
217: UINT64 *ReturnInteger)
218: {
219: char *ThisChar = String;
220: UINT32 ThisDigit;
221: UINT64 ReturnValue = 0;
222: int DigitCount = 0;
223:
224:
225: /* Skip over any white space in the buffer */
226:
227: while ((*ThisChar == ' ') || (*ThisChar == '\t'))
228: {
229: ThisChar++;
230: }
231:
232: /* Skip leading zeros */
233:
234: while ((*ThisChar) == '0')
235: {
236: ThisChar++;
237: }
238:
239: /* Convert character-by-character */
240:
241: while (*ThisChar)
242: {
243: if (ACPI_IS_DIGIT (*ThisChar))
244: {
245: /* Convert ASCII 0-9 to Decimal value */
246:
247: ThisDigit = ((UINT8) *ThisChar) - '0';
248: }
249: else /* Letter */
250: {
251: ThisDigit = (UINT32) ACPI_TOUPPER (*ThisChar);
252: if (!ACPI_IS_XDIGIT ((char) ThisDigit))
253: {
254: /* Not A-F */
255:
256: return (AE_BAD_CHARACTER);
257: }
258:
259: /* Convert ASCII Hex char (A-F) to value */
260:
261: ThisDigit = (ThisDigit - 'A') + 10;
262: }
263:
264: /* Insert the 4-bit hex digit */
265:
266: ReturnValue <<= 4;
267: ReturnValue += ThisDigit;
268:
269: ThisChar++;
270: DigitCount++;
271: if (DigitCount > 16)
272: {
273: /* Value is too large (> 64 bits/8 bytes/16 hex digits) */
274:
275: return (AE_LIMIT);
276: }
277: }
278:
279: *ReturnInteger = ReturnValue;
280: return (AE_OK);
281: }
282:
283:
284: /******************************************************************************
285: *
286: * FUNCTION: DtGetFileSize
287: *
288: * PARAMETERS: Handle - Open file handler
289: *
290: * RETURN: Current file size
291: *
292: * DESCRIPTION: Get the current size of a file. Seek to the EOF and get the
293: * offset. Seek back to the original location.
294: *
295: *****************************************************************************/
296:
297: UINT32
298: DtGetFileSize (
299: FILE *Handle)
300: {
301: int CurrentOffset;
302: int LastOffset;
303:
304:
305: CurrentOffset = ftell (Handle);
306: fseek (Handle, 0, SEEK_END);
307: LastOffset = ftell (Handle);
308: fseek (Handle, CurrentOffset, SEEK_SET);
309:
310: return ((UINT32) LastOffset);
311: }
312:
313:
314: /******************************************************************************
315: *
316: * FUNCTION: DtGetFieldValue
317: *
318: * PARAMETERS: Field - Current field list pointer
319: * Name - Field name
320: *
321: * RETURN: Field value
322: *
323: * DESCRIPTION: Get field value
324: *
325: *****************************************************************************/
326:
327: char *
328: DtGetFieldValue (
329: DT_FIELD *Field,
330: char *Name)
331: {
332:
333: /* Search the field list for the name */
334:
335: while (Field)
336: {
337: if (!ACPI_STRCMP (Name, Field->Name))
338: {
339: return (Field->Value);
340: }
341:
342: Field = Field->Next;
343: }
344:
345: return (NULL);
346: }
347:
348:
349: /******************************************************************************
350: *
351: * FUNCTION: DtGetFieldType
352: *
353: * PARAMETERS: Info - Data table info
354: *
355: * RETURN: Field type
356: *
357: * DESCRIPTION: Get field type
358: *
359: *****************************************************************************/
360:
361: UINT8
362: DtGetFieldType (
363: ACPI_DMTABLE_INFO *Info)
364: {
365: UINT8 Type;
366:
367:
368: /* DT_FLAG means that this is the start of a block of flag bits */
369: /* TBD - we can make these a separate opcode later */
370:
371: if (Info->Flags & DT_FLAG)
372: {
373: return (DT_FIELD_TYPE_FLAGS_INTEGER);
374: }
375:
376: /* Type is based upon the opcode for this field in the info table */
377:
378: switch (Info->Opcode)
379: {
380: case ACPI_DMT_FLAG0:
381: case ACPI_DMT_FLAG1:
382: case ACPI_DMT_FLAG2:
383: case ACPI_DMT_FLAG3:
384: case ACPI_DMT_FLAG4:
385: case ACPI_DMT_FLAG5:
386: case ACPI_DMT_FLAG6:
387: case ACPI_DMT_FLAG7:
388: case ACPI_DMT_FLAGS0:
389: case ACPI_DMT_FLAGS2:
390: Type = DT_FIELD_TYPE_FLAG;
391: break;
392:
393: case ACPI_DMT_NAME4:
394: case ACPI_DMT_SIG:
395: case ACPI_DMT_NAME6:
396: case ACPI_DMT_NAME8:
397: case ACPI_DMT_STRING:
398: Type = DT_FIELD_TYPE_STRING;
399: break;
400:
401: case ACPI_DMT_BUFFER:
1.1.1.2 ! jruoho 402: case ACPI_DMT_BUF7:
1.1 jruoho 403: case ACPI_DMT_BUF16:
404: case ACPI_DMT_PCI_PATH:
1.1.1.2 ! jruoho 405: Type = DT_FIELD_TYPE_BUFFER;
1.1 jruoho 406: break;
407:
408: case ACPI_DMT_GAS:
409: case ACPI_DMT_HESTNTFY:
410: Type = DT_FIELD_TYPE_INLINE_SUBTABLE;
411: break;
412:
1.1.1.2 ! jruoho 413: case ACPI_DMT_UNICODE:
! 414: Type = DT_FIELD_TYPE_UNICODE;
! 415: break;
! 416:
! 417: case ACPI_DMT_UUID:
! 418: Type = DT_FIELD_TYPE_UUID;
! 419: break;
! 420:
! 421: case ACPI_DMT_DEVICE_PATH:
! 422: Type = DT_FIELD_TYPE_DEVICE_PATH;
! 423: break;
! 424:
! 425: case ACPI_DMT_LABEL:
! 426: Type = DT_FIELD_TYPE_LABEL;
! 427: break;
! 428:
1.1 jruoho 429: default:
430: Type = DT_FIELD_TYPE_INTEGER;
431: break;
432: }
433:
434: return (Type);
435: }
436:
437:
438: /******************************************************************************
439: *
440: * FUNCTION: DtGetBufferLength
441: *
442: * PARAMETERS: Buffer - List of integers,
443: * for example "10 3A 4F 2E"
444: *
445: * RETURN: Count of integer
446: *
447: * DESCRIPTION: Get length of bytes needed to store the integers
448: *
449: *****************************************************************************/
450:
451: UINT32
452: DtGetBufferLength (
453: char *Buffer)
454: {
455: UINT32 ByteLength = 0;
456:
457:
458: while (*Buffer)
459: {
460: if (*Buffer == ' ')
461: {
462: ByteLength++;
463:
464: while (*Buffer == ' ')
465: {
466: Buffer++;
467: }
468: }
469:
470: Buffer++;
471: }
472:
473: return (++ByteLength);
474: }
475:
476:
477: /******************************************************************************
478: *
479: * FUNCTION: DtGetFieldLength
480: *
481: * PARAMETERS: Field - Current field list pointer
482: * Info - Data table info
483: *
484: * RETURN: Field length
485: *
486: * DESCRIPTION: Get length of bytes needed to compile the field
487: *
1.1.1.2 ! jruoho 488: * Note: This function must remain in sync with AcpiDmDumpTable.
! 489: *
1.1 jruoho 490: *****************************************************************************/
491:
492: UINT32
493: DtGetFieldLength (
494: DT_FIELD *Field,
495: ACPI_DMTABLE_INFO *Info)
496: {
497: UINT32 ByteLength = 0;
498: char *Value;
499:
500:
501: /* Length is based upon the opcode for this field in the info table */
502:
503: switch (Info->Opcode)
504: {
505: case ACPI_DMT_FLAG0:
506: case ACPI_DMT_FLAG1:
507: case ACPI_DMT_FLAG2:
508: case ACPI_DMT_FLAG3:
509: case ACPI_DMT_FLAG4:
510: case ACPI_DMT_FLAG5:
511: case ACPI_DMT_FLAG6:
512: case ACPI_DMT_FLAG7:
513: case ACPI_DMT_FLAGS0:
514: case ACPI_DMT_FLAGS2:
1.1.1.2 ! jruoho 515: case ACPI_DMT_LABEL:
1.1 jruoho 516: ByteLength = 0;
517: break;
518:
519: case ACPI_DMT_UINT8:
520: case ACPI_DMT_CHKSUM:
521: case ACPI_DMT_SPACEID:
1.1.1.2 ! jruoho 522: case ACPI_DMT_ACCWIDTH:
! 523: case ACPI_DMT_IVRS:
1.1 jruoho 524: case ACPI_DMT_MADT:
525: case ACPI_DMT_SRAT:
526: case ACPI_DMT_ASF:
527: case ACPI_DMT_HESTNTYP:
528: case ACPI_DMT_FADTPM:
1.1.1.2 ! jruoho 529: case ACPI_DMT_EINJACT:
! 530: case ACPI_DMT_EINJINST:
! 531: case ACPI_DMT_ERSTACT:
! 532: case ACPI_DMT_ERSTINST:
1.1 jruoho 533: ByteLength = 1;
534: break;
535:
536: case ACPI_DMT_UINT16:
537: case ACPI_DMT_DMAR:
538: case ACPI_DMT_HEST:
539: case ACPI_DMT_PCI_PATH:
540: ByteLength = 2;
541: break;
542:
543: case ACPI_DMT_UINT24:
544: ByteLength = 3;
545: break;
546:
547: case ACPI_DMT_UINT32:
548: case ACPI_DMT_NAME4:
549: case ACPI_DMT_SIG:
550: ByteLength = 4;
551: break;
552:
553: case ACPI_DMT_NAME6:
554: ByteLength = 6;
555: break;
556:
557: case ACPI_DMT_UINT56:
1.1.1.2 ! jruoho 558: case ACPI_DMT_BUF7:
1.1 jruoho 559: ByteLength = 7;
560: break;
561:
562: case ACPI_DMT_UINT64:
563: case ACPI_DMT_NAME8:
564: ByteLength = 8;
565: break;
566:
567: case ACPI_DMT_STRING:
568: Value = DtGetFieldValue (Field, Info->Name);
1.1.1.2 ! jruoho 569: if (Value)
! 570: {
! 571: ByteLength = ACPI_STRLEN (Value) + 1;
! 572: }
! 573: else
! 574: { /* At this point, this is a fatal error */
1.1 jruoho 575:
1.1.1.2 ! jruoho 576: sprintf (MsgBuffer, "Expected \"%s\"", Info->Name);
! 577: DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, MsgBuffer);
! 578: }
1.1 jruoho 579: break;
580:
581: case ACPI_DMT_GAS:
582: ByteLength = sizeof (ACPI_GENERIC_ADDRESS);
583: break;
584:
585: case ACPI_DMT_HESTNTFY:
586: ByteLength = sizeof (ACPI_HEST_NOTIFY);
587: break;
588:
589: case ACPI_DMT_BUFFER:
590: Value = DtGetFieldValue (Field, Info->Name);
591: if (Value)
592: {
593: ByteLength = DtGetBufferLength (Value);
594: }
595: else
596: { /* At this point, this is a fatal error */
597:
598: sprintf (MsgBuffer, "Expected \"%s\"", Info->Name);
599: DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, MsgBuffer);
600: }
601: break;
602:
603: case ACPI_DMT_BUF16:
1.1.1.2 ! jruoho 604: case ACPI_DMT_UUID:
1.1 jruoho 605: ByteLength = 16;
606: break;
607:
1.1.1.2 ! jruoho 608: case ACPI_DMT_UNICODE:
! 609: Value = DtGetFieldValue (Field, Info->Name);
! 610:
! 611: /* TBD: error if Value is NULL? (as below?) */
! 612:
! 613: ByteLength = (ACPI_STRLEN (Value) + 1) * sizeof(UINT16);
! 614: break;
! 615:
1.1 jruoho 616: default:
617: DtFatal (ASL_MSG_COMPILER_INTERNAL, Field, "Invalid table opcode");
618: break;
619: }
620:
621: return (ByteLength);
622: }
623:
624:
625: /******************************************************************************
626: *
627: * FUNCTION: DtSum
628: *
629: * PARAMETERS: DT_WALK_CALLBACK:
630: * Subtable - Subtable
631: * Context - Unused
632: * ReturnValue - Store the checksum of subtable
633: *
634: * RETURN: Status
635: *
636: * DESCRIPTION: Get the checksum of subtable
637: *
638: *****************************************************************************/
639:
640: static void
641: DtSum (
642: DT_SUBTABLE *Subtable,
643: void *Context,
644: void *ReturnValue)
645: {
646: UINT8 Checksum;
647: UINT8 *Sum = ReturnValue;
648:
649:
650: Checksum = AcpiTbChecksum (Subtable->Buffer, Subtable->Length);
651: *Sum = (UINT8) (*Sum + Checksum);
652: }
653:
654:
655: /******************************************************************************
656: *
657: * FUNCTION: DtSetTableChecksum
658: *
659: * PARAMETERS: ChecksumPointer - Where to return the checksum
660: *
661: * RETURN: None
662: *
663: * DESCRIPTION: Set checksum of the whole data table into the checksum field
664: *
665: *****************************************************************************/
666:
667: void
668: DtSetTableChecksum (
669: UINT8 *ChecksumPointer)
670: {
671: UINT8 Checksum = 0;
672: UINT8 OldSum;
673:
674:
675: DtWalkTableTree (Gbl_RootTable, DtSum, NULL, &Checksum);
676:
677: OldSum = *ChecksumPointer;
678: Checksum = (UINT8) (Checksum - OldSum);
679:
680: /* Compute the final checksum */
681:
682: Checksum = (UINT8) (0 - Checksum);
683: *ChecksumPointer = Checksum;
684: }
685:
686:
687: /******************************************************************************
688: *
689: * FUNCTION: DtSetTableLength
690: *
691: * PARAMETERS: None
692: *
693: * RETURN: None
694: *
695: * DESCRIPTION: Walk the subtables and set all the length fields
696: *
697: *****************************************************************************/
698:
699: void
700: DtSetTableLength (
701: void)
702: {
703: DT_SUBTABLE *ParentTable;
704: DT_SUBTABLE *ChildTable;
705:
706:
707: ParentTable = Gbl_RootTable;
708: ChildTable = NULL;
709:
710: if (!ParentTable)
711: {
712: return;
713: }
714:
715: DtSetSubtableLength (ParentTable);
716:
717: while (1)
718: {
719: ChildTable = DtGetNextSubtable (ParentTable, ChildTable);
720: if (ChildTable)
721: {
1.1.1.2 ! jruoho 722: if (ChildTable->LengthField)
! 723: {
! 724: DtSetSubtableLength (ChildTable);
! 725: }
! 726:
1.1 jruoho 727: if (ChildTable->Child)
728: {
729: ParentTable = ChildTable;
730: ChildTable = NULL;
731: }
732: else
733: {
734: ParentTable->TotalLength += ChildTable->TotalLength;
735: if (ParentTable->LengthField)
736: {
737: DtSetSubtableLength (ParentTable);
738: }
739: }
740: }
741: else
742: {
743: ChildTable = ParentTable;
744:
745: if (ChildTable == Gbl_RootTable)
746: {
747: break;
748: }
749:
750: ParentTable = DtGetParentSubtable (ParentTable);
751:
752: ParentTable->TotalLength += ChildTable->TotalLength;
753: if (ParentTable->LengthField)
754: {
755: DtSetSubtableLength (ParentTable);
756: }
757: }
758: }
759: }
760:
761:
762: /******************************************************************************
763: *
764: * FUNCTION: DtWalkTableTree
765: *
766: * PARAMETERS: StartTable - Subtable in the tree where walking begins
767: * UserFunction - Called during the walk
768: * Context - Passed to user function
769: * ReturnValue - The return value of UserFunction
770: *
771: * RETURN: None
772: *
773: * DESCRIPTION: Performs a depth-first walk of the subtable tree
774: *
775: *****************************************************************************/
776:
777: void
778: DtWalkTableTree (
779: DT_SUBTABLE *StartTable,
780: DT_WALK_CALLBACK UserFunction,
781: void *Context,
782: void *ReturnValue)
783: {
784: DT_SUBTABLE *ParentTable;
785: DT_SUBTABLE *ChildTable;
786:
787:
788: ParentTable = StartTable;
789: ChildTable = NULL;
790:
791: if (!ParentTable)
792: {
793: return;
794: }
795:
796: UserFunction (ParentTable, Context, ReturnValue);
797:
798: while (1)
799: {
800: ChildTable = DtGetNextSubtable (ParentTable, ChildTable);
801: if (ChildTable)
802: {
803: UserFunction (ChildTable, Context, ReturnValue);
804:
805: if (ChildTable->Child)
806: {
807: ParentTable = ChildTable;
808: ChildTable = NULL;
809: }
810: }
811: else
812: {
813: ChildTable = ParentTable;
814: if (ChildTable == Gbl_RootTable)
815: {
816: break;
817: }
818:
819: ParentTable = DtGetParentSubtable (ParentTable);
820:
821: if (ChildTable->Peer == StartTable)
822: {
823: break;
824: }
825: }
826: }
827: }
828:
829:
830: /******************************************************************************
831: *
832: * FUNCTION: DtFreeFieldList
833: *
834: * PARAMETERS: None
835: *
836: * RETURN: None
837: *
838: * DESCRIPTION: Free the field list
839: *
840: *****************************************************************************/
841:
842: void
843: DtFreeFieldList (
844: void)
845: {
846: DT_FIELD *Field = Gbl_FieldList;
847: DT_FIELD *NextField;
848:
849:
850: /* Walk and free entire field list */
851:
852: while (Field)
853: {
854: NextField = Field->Next; /* Save link */
855:
856: if (!(Field->Flags & DT_FIELD_NOT_ALLOCATED))
857: {
858: ACPI_FREE (Field->Name);
859: ACPI_FREE (Field->Value);
860: }
861:
862: ACPI_FREE (Field);
863: Field = NextField;
864: }
865: }
CVSweb <webmaster@jp.NetBSD.org>