rscalc.c revision 138287
1275970Scy/*******************************************************************************
2275970Scy *
3275970Scy * Module Name: rscalc - Calculate stream and list lengths
4275970Scy *              $Revision: 52 $
5275970Scy *
6 ******************************************************************************/
7
8/******************************************************************************
9 *
10 * 1. Copyright Notice
11 *
12 * Some or all of this work - Copyright (c) 1999 - 2004, Intel Corp.
13 * All rights reserved.
14 *
15 * 2. License
16 *
17 * 2.1. This is your license from Intel Corp. under its intellectual property
18 * rights.  You may have additional license terms from the party that provided
19 * you this software, covering your right to use that party's intellectual
20 * property rights.
21 *
22 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
23 * copy of the source code appearing in this file ("Covered Code") an
24 * irrevocable, perpetual, worldwide license under Intel's copyrights in the
25 * base code distributed originally by Intel ("Original Intel Code") to copy,
26 * make derivatives, distribute, use and display any portion of the Covered
27 * Code in any form, with the right to sublicense such rights; and
28 *
29 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
30 * license (with the right to sublicense), under only those claims of Intel
31 * patents that are infringed by the Original Intel Code, to make, use, sell,
32 * offer to sell, and import the Covered Code and derivative works thereof
33 * solely to the minimum extent necessary to exercise the above copyright
34 * license, and in no event shall the patent license extend to any additions
35 * to or modifications of the Original Intel Code.  No other license or right
36 * is granted directly or by implication, estoppel or otherwise;
37 *
38 * The above copyright and patent license is granted only if the following
39 * conditions are met:
40 *
41 * 3. Conditions
42 *
43 * 3.1. Redistribution of Source with Rights to Further Distribute Source.
44 * Redistribution of source code of any substantial portion of the Covered
45 * Code or modification with rights to further distribute source must include
46 * the above Copyright Notice, the above License, this list of Conditions,
47 * and the following Disclaimer and Export Compliance provision.  In addition,
48 * Licensee must cause all Covered Code to which Licensee contributes to
49 * contain a file documenting the changes Licensee made to create that Covered
50 * Code and the date of any change.  Licensee must include in that file the
51 * documentation of any changes made by any predecessor Licensee.  Licensee
52 * must include a prominent statement that the modification is derived,
53 * directly or indirectly, from Original Intel Code.
54 *
55 * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
56 * Redistribution of source code of any substantial portion of the Covered
57 * Code or modification without rights to further distribute source must
58 * include the following Disclaimer and Export Compliance provision in the
59 * documentation and/or other materials provided with distribution.  In
60 * addition, Licensee may not authorize further sublicense of source of any
61 * portion of the Covered Code, and must include terms to the effect that the
62 * license from Licensee to its licensee is limited to the intellectual
63 * property embodied in the software Licensee provides to its licensee, and
64 * not to intellectual property embodied in modifications its licensee may
65 * make.
66 *
67 * 3.3. Redistribution of Executable. Redistribution in executable form of any
68 * substantial portion of the Covered Code or modification must reproduce the
69 * above Copyright Notice, and the following Disclaimer and Export Compliance
70 * provision in the documentation and/or other materials provided with the
71 * distribution.
72 *
73 * 3.4. Intel retains all right, title, and interest in and to the Original
74 * Intel Code.
75 *
76 * 3.5. Neither the name Intel nor any other trademark owned or controlled by
77 * Intel shall be used in advertising or otherwise to promote the sale, use or
78 * other dealings in products derived from or relating to the Covered Code
79 * without prior written authorization from Intel.
80 *
81 * 4. Disclaimer and Export Compliance
82 *
83 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
84 * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
85 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
86 * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
87 * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
88 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
89 * PARTICULAR PURPOSE.
90 *
91 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
92 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
93 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
94 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
95 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
96 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
97 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
98 * LIMITED REMEDY.
99 *
100 * 4.3. Licensee shall not export, either directly or indirectly, any of this
101 * software or system incorporating such software without first obtaining any
102 * required license or other approval from the U. S. Department of Commerce or
103 * any other agency or department of the United States Government.  In the
104 * event Licensee exports any such software from the United States or
105 * re-exports any such software from a foreign destination, Licensee shall
106 * ensure that the distribution and export/re-export of the software is in
107 * compliance with all laws, regulations, orders, or other restrictions of the
108 * U.S. Export Administration Regulations. Licensee agrees that neither it nor
109 * any of its subsidiaries will export/re-export any technical data, process,
110 * software, or service, directly or indirectly, to any country for which the
111 * United States government or any agency thereof requires an export license,
112 * other governmental approval, or letter of assurance, without first obtaining
113 * such license, approval or letter.
114 *
115 *****************************************************************************/
116
117#define __RSCALC_C__
118
119#include "acpi.h"
120#include "acresrc.h"
121#include "amlcode.h"
122#include "acnamesp.h"
123
124#define _COMPONENT          ACPI_RESOURCES
125        ACPI_MODULE_NAME    ("rscalc")
126
127
128/*******************************************************************************
129 *
130 * FUNCTION:    AcpiRsGetByteStreamLength
131 *
132 * PARAMETERS:  LinkedList          - Pointer to the resource linked list
133 *              SizeNeeded          - UINT32 pointer of the size buffer needed
134 *                                    to properly return the parsed data
135 *
136 * RETURN:      Status
137 *
138 * DESCRIPTION: Takes the resource byte stream and parses it once, calculating
139 *              the size buffer needed to hold the linked list that conveys
140 *              the resource data.
141 *
142 ******************************************************************************/
143
144ACPI_STATUS
145AcpiRsGetByteStreamLength (
146    ACPI_RESOURCE           *LinkedList,
147    ACPI_SIZE               *SizeNeeded)
148{
149    ACPI_SIZE               ByteStreamSizeNeeded = 0;
150    ACPI_SIZE               SegmentSize;
151    BOOLEAN                 Done = FALSE;
152
153
154    ACPI_FUNCTION_TRACE ("RsGetByteStreamLength");
155
156
157    while (!Done)
158    {
159        /*
160         * Init the variable that will hold the size to add to the total.
161         */
162        SegmentSize = 0;
163
164        switch (LinkedList->Id)
165        {
166        case ACPI_RSTYPE_IRQ:
167            /*
168             * IRQ Resource
169             * For an IRQ Resource, Byte 3, although optional, will always be
170             * created - it holds IRQ information.
171             */
172            SegmentSize = 4;
173            break;
174
175        case ACPI_RSTYPE_DMA:
176            /*
177             * DMA Resource
178             * For this resource the size is static
179             */
180            SegmentSize = 3;
181            break;
182
183        case ACPI_RSTYPE_START_DPF:
184            /*
185             * Start Dependent Functions Resource
186             * For a StartDependentFunctions Resource, Byte 1, although
187             * optional, will always be created.
188             */
189            SegmentSize = 2;
190            break;
191
192        case ACPI_RSTYPE_END_DPF:
193            /*
194             * End Dependent Functions Resource
195             * For this resource the size is static
196             */
197            SegmentSize = 1;
198            break;
199
200        case ACPI_RSTYPE_IO:
201            /*
202             * IO Port Resource
203             * For this resource the size is static
204             */
205            SegmentSize = 8;
206            break;
207
208        case ACPI_RSTYPE_FIXED_IO:
209            /*
210             * Fixed IO Port Resource
211             * For this resource the size is static
212             */
213            SegmentSize = 4;
214            break;
215
216        case ACPI_RSTYPE_VENDOR:
217            /*
218             * Vendor Defined Resource
219             * For a Vendor Specific resource, if the Length is between 1 and 7
220             * it will be created as a Small Resource data type, otherwise it
221             * is a Large Resource data type.
222             */
223            if (LinkedList->Data.VendorSpecific.Length > 7)
224            {
225                SegmentSize = 3;
226            }
227            else
228            {
229                SegmentSize = 1;
230            }
231            SegmentSize += LinkedList->Data.VendorSpecific.Length;
232            break;
233
234        case ACPI_RSTYPE_END_TAG:
235            /*
236             * End Tag
237             * For this resource the size is static
238             */
239            SegmentSize = 2;
240            Done = TRUE;
241            break;
242
243        case ACPI_RSTYPE_MEM24:
244            /*
245             * 24-Bit Memory Resource
246             * For this resource the size is static
247             */
248            SegmentSize = 12;
249            break;
250
251        case ACPI_RSTYPE_MEM32:
252            /*
253             * 32-Bit Memory Range Resource
254             * For this resource the size is static
255             */
256            SegmentSize = 20;
257            break;
258
259        case ACPI_RSTYPE_FIXED_MEM32:
260            /*
261             * 32-Bit Fixed Memory Resource
262             * For this resource the size is static
263             */
264            SegmentSize = 12;
265            break;
266
267        case ACPI_RSTYPE_ADDRESS16:
268            /*
269             * 16-Bit Address Resource
270             * The base size of this byte stream is 16. If a Resource Source
271             * string is not NULL, add 1 for the Index + the length of the null
272             * terminated string Resource Source + 1 for the null.
273             */
274            SegmentSize = 16;
275
276            if (LinkedList->Data.Address16.ResourceSource.StringPtr)
277            {
278                SegmentSize += LinkedList->Data.Address16.ResourceSource.StringLength;
279                SegmentSize++;
280            }
281            break;
282
283        case ACPI_RSTYPE_ADDRESS32:
284            /*
285             * 32-Bit Address Resource
286             * The base size of this byte stream is 26. If a Resource
287             * Source string is not NULL, add 1 for the Index + the
288             * length of the null terminated string Resource Source +
289             * 1 for the null.
290             */
291            SegmentSize = 26;
292
293            if (LinkedList->Data.Address32.ResourceSource.StringPtr)
294            {
295                SegmentSize += LinkedList->Data.Address32.ResourceSource.StringLength;
296                SegmentSize++;
297            }
298            break;
299
300        case ACPI_RSTYPE_ADDRESS64:
301            /*
302             * 64-Bit Address Resource
303             * The base size of this byte stream is 46. If a ResourceSource
304             * string is not NULL, add 1 for the Index + the length of the null
305             * terminated string Resource Source + 1 for the null.
306             */
307            SegmentSize = 46;
308
309            if (LinkedList->Data.Address64.ResourceSource.StringPtr)
310            {
311                SegmentSize += LinkedList->Data.Address64.ResourceSource.StringLength;
312                SegmentSize++;
313            }
314            break;
315
316        case ACPI_RSTYPE_EXT_IRQ:
317            /*
318             * Extended IRQ Resource
319             * The base size of this byte stream is 9. This is for an Interrupt
320             * table length of 1.  For each additional interrupt, add 4.
321             * If a Resource Source string is not NULL, add 1 for the
322             * Index + the length of the null terminated string
323             * Resource Source + 1 for the null.
324             */
325            SegmentSize = 9 +
326                (((ACPI_SIZE) LinkedList->Data.ExtendedIrq.NumberOfInterrupts - 1) * 4);
327
328            if (LinkedList->Data.ExtendedIrq.ResourceSource.StringPtr)
329            {
330                SegmentSize += LinkedList->Data.ExtendedIrq.ResourceSource.StringLength;
331                SegmentSize++;
332            }
333            break;
334
335        default:
336            /*
337             * If we get here, everything is out of sync, exit with error
338             */
339            return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE);
340
341        } /* switch (LinkedList->Id) */
342
343        /*
344         * Update the total
345         */
346        ByteStreamSizeNeeded += SegmentSize;
347
348        /*
349         * Point to the next object
350         */
351        LinkedList = ACPI_PTR_ADD (ACPI_RESOURCE,
352                        LinkedList, LinkedList->Length);
353    }
354
355    /*
356     * This is the data the caller needs
357     */
358    *SizeNeeded = ByteStreamSizeNeeded;
359    return_ACPI_STATUS (AE_OK);
360}
361
362
363/*******************************************************************************
364 *
365 * FUNCTION:    AcpiRsGetListLength
366 *
367 * PARAMETERS:  ByteStreamBuffer        - Pointer to the resource byte stream
368 *              ByteStreamBufferLength  - Size of ByteStreamBuffer
369 *              SizeNeeded              - UINT32 pointer of the size buffer
370 *                                        needed to properly return the
371 *                                        parsed data
372 *
373 * RETURN:      Status
374 *
375 * DESCRIPTION: Takes the resource byte stream and parses it once, calculating
376 *              the size buffer needed to hold the linked list that conveys
377 *              the resource data.
378 *
379 ******************************************************************************/
380
381ACPI_STATUS
382AcpiRsGetListLength (
383    UINT8                   *ByteStreamBuffer,
384    UINT32                  ByteStreamBufferLength,
385    ACPI_SIZE               *SizeNeeded)
386{
387    UINT32                  BufferSize = 0;
388    UINT32                  BytesParsed = 0;
389    UINT8                   NumberOfInterrupts = 0;
390    UINT8                   NumberOfChannels = 0;
391    UINT8                   ResourceType;
392    UINT32                  StructureSize;
393    UINT32                  BytesConsumed;
394    UINT8                   *Buffer;
395    UINT8                   Temp8;
396    UINT16                  Temp16;
397    UINT8                   Index;
398    UINT8                   AdditionalBytes;
399
400
401    ACPI_FUNCTION_TRACE ("RsGetListLength");
402
403
404    while (BytesParsed < ByteStreamBufferLength)
405    {
406        /*
407         * The next byte in the stream is the resource type
408         */
409        ResourceType = AcpiRsGetResourceType (*ByteStreamBuffer);
410
411        switch (ResourceType)
412        {
413        case ACPI_RDESC_TYPE_MEMORY_24:
414            /*
415             * 24-Bit Memory Resource
416             */
417            BytesConsumed = 12;
418
419            StructureSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_MEM24);
420            break;
421
422
423        case ACPI_RDESC_TYPE_LARGE_VENDOR:
424            /*
425             * Vendor Defined Resource
426             */
427            Buffer = ByteStreamBuffer;
428            ++Buffer;
429
430            ACPI_MOVE_16_TO_16 (&Temp16, Buffer);
431            BytesConsumed = Temp16 + 3;
432
433            /*
434             * Ensure a 32-bit boundary for the structure
435             */
436            Temp16 = (UINT16) ACPI_ROUND_UP_TO_32BITS (Temp16);
437
438            StructureSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_VENDOR) +
439                                (Temp16 * sizeof (UINT8));
440            break;
441
442
443        case ACPI_RDESC_TYPE_MEMORY_32:
444            /*
445             * 32-Bit Memory Range Resource
446             */
447            BytesConsumed = 20;
448
449            StructureSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_MEM32);
450            break;
451
452
453        case ACPI_RDESC_TYPE_FIXED_MEMORY_32:
454            /*
455             * 32-Bit Fixed Memory Resource
456             */
457            BytesConsumed = 12;
458
459            StructureSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_FIXED_MEM32);
460            break;
461
462
463        case ACPI_RDESC_TYPE_QWORD_ADDRESS_SPACE:
464            /*
465             * 64-Bit Address Resource
466             */
467            Buffer = ByteStreamBuffer;
468
469            ++Buffer;
470            ACPI_MOVE_16_TO_16 (&Temp16, Buffer);
471
472            BytesConsumed = Temp16 + 3;
473
474            /*
475             * Resource Source Index and Resource Source are optional elements.
476             * Check the length of the Bytestream.  If it is greater than 43,
477             * that means that an Index exists and is followed by a null
478             * terminated string.  Therefore, set the temp variable to the
479             * length minus the minimum byte stream length plus the byte for
480             * the Index to determine the size of the NULL terminated string.
481             */
482            if (43 < Temp16)
483            {
484                Temp8 = (UINT8) (Temp16 - 44);
485            }
486            else
487            {
488                Temp8 = 0;
489            }
490
491            /*
492             * Ensure a 64-bit boundary for the structure
493             */
494            Temp8 = (UINT8) ACPI_ROUND_UP_TO_64BITS (Temp8);
495
496            StructureSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_ADDRESS64) +
497                                (Temp8 * sizeof (UINT8));
498            break;
499
500
501        case ACPI_RDESC_TYPE_DWORD_ADDRESS_SPACE:
502            /*
503             * 32-Bit Address Resource
504             */
505            Buffer = ByteStreamBuffer;
506
507            ++Buffer;
508            ACPI_MOVE_16_TO_16 (&Temp16, Buffer);
509
510            BytesConsumed = Temp16 + 3;
511
512            /*
513             * Resource Source Index and Resource Source are optional elements.
514             * Check the length of the Bytestream.  If it is greater than 23,
515             * that means that an Index exists and is followed by a null
516             * terminated string.  Therefore, set the temp variable to the
517             * length minus the minimum byte stream length plus the byte for
518             * the Index to determine the size of the NULL terminated string.
519             */
520            if (23 < Temp16)
521            {
522                Temp8 = (UINT8) (Temp16 - 24);
523            }
524            else
525            {
526                Temp8 = 0;
527            }
528
529            /*
530             * Ensure a 32-bit boundary for the structure
531             */
532            Temp8 = (UINT8) ACPI_ROUND_UP_TO_32BITS (Temp8);
533
534            StructureSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_ADDRESS32) +
535                                (Temp8 * sizeof (UINT8));
536            break;
537
538
539        case ACPI_RDESC_TYPE_WORD_ADDRESS_SPACE:
540            /*
541             * 16-Bit Address Resource
542             */
543            Buffer = ByteStreamBuffer;
544
545            ++Buffer;
546            ACPI_MOVE_16_TO_16 (&Temp16, Buffer);
547
548            BytesConsumed = Temp16 + 3;
549
550            /*
551             * Resource Source Index and Resource Source are optional elements.
552             * Check the length of the Bytestream.  If it is greater than 13,
553             * that means that an Index exists and is followed by a null
554             * terminated string.  Therefore, set the temp variable to the
555             * length minus the minimum byte stream length plus the byte for
556             * the Index to determine the size of the NULL terminated string.
557             */
558            if (13 < Temp16)
559            {
560                Temp8 = (UINT8) (Temp16 - 14);
561            }
562            else
563            {
564                Temp8 = 0;
565            }
566
567            /*
568             * Ensure a 32-bit boundary for the structure
569             */
570            Temp8 = (UINT8) ACPI_ROUND_UP_TO_32BITS (Temp8);
571
572            StructureSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_ADDRESS16) +
573                                (Temp8 * sizeof (UINT8));
574            break;
575
576
577        case ACPI_RDESC_TYPE_EXTENDED_XRUPT:
578            /*
579             * Extended IRQ
580             */
581            Buffer = ByteStreamBuffer;
582
583            ++Buffer;
584            ACPI_MOVE_16_TO_16 (&Temp16, Buffer);
585
586            BytesConsumed = Temp16 + 3;
587
588            /*
589             * Point past the length field and the Interrupt vector flags to
590             * save off the Interrupt table length to the Temp8 variable.
591             */
592            Buffer += 3;
593            Temp8 = *Buffer;
594
595            /*
596             * To compensate for multiple interrupt numbers, add 4 bytes for
597             * each additional interrupts greater than 1
598             */
599            AdditionalBytes = (UINT8) ((Temp8 - 1) * 4);
600
601            /*
602             * Resource Source Index and Resource Source are optional elements.
603             * Check the length of the Bytestream.  If it is greater than 9,
604             * that means that an Index exists and is followed by a null
605             * terminated string.  Therefore, set the temp variable to the
606             * length minus the minimum byte stream length plus the byte for
607             * the Index to determine the size of the NULL terminated string.
608             */
609            if (9 + AdditionalBytes < Temp16)
610            {
611                Temp8 = (UINT8) (Temp16 - (9 + AdditionalBytes));
612            }
613            else
614            {
615                Temp8 = 0;
616            }
617
618            /*
619             * Ensure a 32-bit boundary for the structure
620             */
621            Temp8 = (UINT8) ACPI_ROUND_UP_TO_32BITS (Temp8);
622
623            StructureSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_EXT_IRQ) +
624                                (AdditionalBytes * sizeof (UINT8)) +
625                                (Temp8 * sizeof (UINT8));
626            break;
627
628
629        case ACPI_RDESC_TYPE_IRQ_FORMAT:
630            /*
631             * IRQ Resource.
632             * Determine if it there are two or three trailing bytes
633             */
634            Buffer = ByteStreamBuffer;
635            Temp8 = *Buffer;
636
637            if(Temp8 & 0x01)
638            {
639                BytesConsumed = 4;
640            }
641            else
642            {
643                BytesConsumed = 3;
644            }
645
646            /* Point past the descriptor */
647
648            ++Buffer;
649
650            /*
651             * Look at the number of bits set
652             */
653            ACPI_MOVE_16_TO_16 (&Temp16, Buffer);
654
655            for (Index = 0; Index < 16; Index++)
656            {
657                if (Temp16 & 0x1)
658                {
659                    ++NumberOfInterrupts;
660                }
661
662                Temp16 >>= 1;
663            }
664
665            StructureSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_IO) +
666                                (NumberOfInterrupts * sizeof (UINT32));
667            break;
668
669
670        case ACPI_RDESC_TYPE_DMA_FORMAT:
671            /*
672             * DMA Resource
673             */
674            Buffer = ByteStreamBuffer;
675            BytesConsumed = 3;
676
677            /* Point past the descriptor */
678
679            ++Buffer;
680
681            /*
682             * Look at the number of bits set
683             */
684            Temp8 = *Buffer;
685
686            for(Index = 0; Index < 8; Index++)
687            {
688                if(Temp8 & 0x1)
689                {
690                    ++NumberOfChannels;
691                }
692
693                Temp8 >>= 1;
694            }
695
696            StructureSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_DMA) +
697                                (NumberOfChannels * sizeof (UINT32));
698            break;
699
700
701        case ACPI_RDESC_TYPE_START_DEPENDENT:
702            /*
703             * Start Dependent Functions Resource
704             * Determine if it there are two or three trailing bytes
705             */
706            Buffer = ByteStreamBuffer;
707            Temp8 = *Buffer;
708
709            if(Temp8 & 0x01)
710            {
711                BytesConsumed = 2;
712            }
713            else
714            {
715                BytesConsumed = 1;
716            }
717
718            StructureSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_START_DPF);
719            break;
720
721
722        case ACPI_RDESC_TYPE_END_DEPENDENT:
723            /*
724             * End Dependent Functions Resource
725             */
726            BytesConsumed = 1;
727            StructureSize = ACPI_RESOURCE_LENGTH;
728            break;
729
730
731        case ACPI_RDESC_TYPE_IO_PORT:
732            /*
733             * IO Port Resource
734             */
735            BytesConsumed = 8;
736            StructureSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_IO);
737            break;
738
739
740        case ACPI_RDESC_TYPE_FIXED_IO_PORT:
741            /*
742             * Fixed IO Port Resource
743             */
744            BytesConsumed = 4;
745            StructureSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_FIXED_IO);
746            break;
747
748
749        case ACPI_RDESC_TYPE_SMALL_VENDOR:
750            /*
751             * Vendor Specific Resource
752             */
753            Buffer = ByteStreamBuffer;
754
755            Temp8 = *Buffer;
756            Temp8 = (UINT8) (Temp8 & 0x7);
757            BytesConsumed = Temp8 + 1;
758
759            /*
760             * Ensure a 32-bit boundary for the structure
761             */
762            Temp8 = (UINT8) ACPI_ROUND_UP_TO_32BITS (Temp8);
763            StructureSize = ACPI_SIZEOF_RESOURCE (ACPI_RESOURCE_VENDOR) +
764                                (Temp8 * sizeof (UINT8));
765            break;
766
767
768        case ACPI_RDESC_TYPE_END_TAG:
769            /*
770             * End Tag
771             */
772            BytesConsumed = 2;
773            StructureSize = ACPI_RESOURCE_LENGTH;
774            ByteStreamBufferLength = BytesParsed;
775            break;
776
777
778        default:
779            /*
780             * If we get here, everything is out of sync,
781             * exit with an error
782             */
783            return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE);
784        }
785
786        /*
787         * Update the return value and counter
788         */
789        BufferSize += (UINT32) ACPI_ALIGN_RESOURCE_SIZE (StructureSize);
790        BytesParsed += BytesConsumed;
791
792        /*
793         * Set the byte stream to point to the next resource
794         */
795        ByteStreamBuffer += BytesConsumed;
796    }
797
798    /*
799     * This is the data the caller needs
800     */
801    *SizeNeeded = BufferSize;
802    return_ACPI_STATUS (AE_OK);
803}
804
805
806/*******************************************************************************
807 *
808 * FUNCTION:    AcpiRsGetPciRoutingTableLength
809 *
810 * PARAMETERS:  PackageObject           - Pointer to the package object
811 *              BufferSizeNeeded        - UINT32 pointer of the size buffer
812 *                                        needed to properly return the
813 *                                        parsed data
814 *
815 * RETURN:      Status
816 *
817 * DESCRIPTION: Given a package representing a PCI routing table, this
818 *              calculates the size of the corresponding linked list of
819 *              descriptions.
820 *
821 ******************************************************************************/
822
823ACPI_STATUS
824AcpiRsGetPciRoutingTableLength (
825    ACPI_OPERAND_OBJECT     *PackageObject,
826    ACPI_SIZE               *BufferSizeNeeded)
827{
828    UINT32                  NumberOfElements;
829    ACPI_SIZE               TempSizeNeeded = 0;
830    ACPI_OPERAND_OBJECT     **TopObjectList;
831    UINT32                  Index;
832    ACPI_OPERAND_OBJECT     *PackageElement;
833    ACPI_OPERAND_OBJECT     **SubObjectList;
834    BOOLEAN                 NameFound;
835    UINT32                  TableIndex;
836
837
838    ACPI_FUNCTION_TRACE ("RsGetPciRoutingTableLength");
839
840
841    NumberOfElements = PackageObject->Package.Count;
842
843    /*
844     * Calculate the size of the return buffer.
845     * The base size is the number of elements * the sizes of the
846     * structures.  Additional space for the strings is added below.
847     * The minus one is to subtract the size of the UINT8 Source[1]
848     * member because it is added below.
849     *
850     * But each PRT_ENTRY structure has a pointer to a string and
851     * the size of that string must be found.
852     */
853    TopObjectList = PackageObject->Package.Elements;
854
855    for (Index = 0; Index < NumberOfElements; Index++)
856    {
857        /*
858         * Dereference the sub-package
859         */
860        PackageElement = *TopObjectList;
861
862        /*
863         * The SubObjectList will now point to an array of the
864         * four IRQ elements: Address, Pin, Source and SourceIndex
865         */
866        SubObjectList = PackageElement->Package.Elements;
867
868        /*
869         * Scan the IrqTableElements for the Source Name String
870         */
871        NameFound = FALSE;
872
873        for (TableIndex = 0; TableIndex < 4 && !NameFound; TableIndex++)
874        {
875            if ((ACPI_TYPE_STRING == ACPI_GET_OBJECT_TYPE (*SubObjectList)) ||
876                ((ACPI_TYPE_LOCAL_REFERENCE == ACPI_GET_OBJECT_TYPE (*SubObjectList)) &&
877                    ((*SubObjectList)->Reference.Opcode == AML_INT_NAMEPATH_OP)))
878            {
879                NameFound = TRUE;
880            }
881            else
882            {
883                /*
884                 * Look at the next element
885                 */
886                SubObjectList++;
887            }
888        }
889
890        TempSizeNeeded += (sizeof (ACPI_PCI_ROUTING_TABLE) - 4);
891
892        /*
893         * Was a String type found?
894         */
895        if (NameFound)
896        {
897            if (ACPI_GET_OBJECT_TYPE (*SubObjectList) == ACPI_TYPE_STRING)
898            {
899                /*
900                 * The length String.Length field does not include the
901                 * terminating NULL, add 1
902                 */
903                TempSizeNeeded += ((ACPI_SIZE) (*SubObjectList)->String.Length + 1);
904            }
905            else
906            {
907                TempSizeNeeded += AcpiNsGetPathnameLength (
908                                    (*SubObjectList)->Reference.Node);
909            }
910        }
911        else
912        {
913            /*
914             * If no name was found, then this is a NULL, which is
915             * translated as a UINT32 zero.
916             */
917            TempSizeNeeded += sizeof (UINT32);
918        }
919
920        /* Round up the size since each element must be aligned */
921
922        TempSizeNeeded = ACPI_ROUND_UP_TO_64BITS (TempSizeNeeded);
923
924        /*
925         * Point to the next ACPI_OPERAND_OBJECT
926         */
927        TopObjectList++;
928    }
929
930    /*
931     * Adding an extra element to the end of the list, essentially a NULL terminator
932     */
933    *BufferSizeNeeded = TempSizeNeeded + sizeof (ACPI_PCI_ROUTING_TABLE);
934    return_ACPI_STATUS (AE_OK);
935}
936