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