rscalc.c revision 73561
1/*******************************************************************************
2 *
3 * Module Name: rscalc - AcpiRsCalculateByteStreamLength
4 *                       AcpiRsCalculateListLength
5 *              $Revision: 21 $
6 *
7 ******************************************************************************/
8
9/******************************************************************************
10 *
11 * 1. Copyright Notice
12 *
13 * Some or all of this work - Copyright (c) 1999, 2000, 2001, Intel Corp.
14 * All rights 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#include "acresrc.h"
122#include "amlcode.h"
123#include "acnamesp.h"
124
125#define _COMPONENT          RESOURCE_MANAGER
126        MODULE_NAME         ("rscalc")
127
128
129/*******************************************************************************
130 *
131 * FUNCTION:    AcpiRsCalculateByteStreamLength
132 *
133 * PARAMETERS:  LinkedList          - Pointer to the resource linked list
134 *              SizeNeeded          - UINT32 pointer of the size buffer needed
135 *                                      to properly return the parsed data
136 *
137 * RETURN:      Status  AE_OK if okay, else a valid ACPI_STATUS code
138 *
139 * DESCRIPTION: Takes the resource byte stream and parses it once, calculating
140 *              the size buffer needed to hold the linked list that conveys
141 *              the resource data.
142 *
143 ******************************************************************************/
144
145ACPI_STATUS
146AcpiRsCalculateByteStreamLength (
147    RESOURCE                *LinkedList,
148    UINT32                  *SizeNeeded)
149{
150    UINT32                  ByteStreamSizeNeeded = 0;
151    UINT32                  SegmentSize;
152    EXTENDED_IRQ_RESOURCE   *ExIrq = NULL;
153    BOOLEAN                 Done = FALSE;
154
155
156    FUNCTION_TRACE ("RsCalculateByteStreamLength");
157
158
159    while (!Done)
160    {
161
162        /*
163         * Init the variable that will hold the size to add to the
164         *  total.
165         */
166        SegmentSize = 0;
167
168        switch (LinkedList->Id)
169        {
170        case Irq:
171            /*
172             * IRQ Resource
173             */
174            /*
175             * For an IRQ Resource, Byte 3, although optional, will
176             *  always be created - it holds IRQ information.
177             */
178            SegmentSize = 4;
179            break;
180
181        case Dma:
182            /*
183             * DMA Resource
184             */
185            /*
186             * For this resource the size is static
187             */
188            SegmentSize = 3;
189            break;
190
191        case StartDependentFunctions:
192            /*
193             * Start Dependent Functions Resource
194             */
195            /*
196             * For a StartDependentFunctions Resource, Byte 1,
197             * although optional, will always be created.
198             */
199            SegmentSize = 2;
200            break;
201
202        case EndDependentFunctions:
203            /*
204             * End Dependent Functions Resource
205             */
206            /*
207             * For this resource the size is static
208             */
209            SegmentSize = 1;
210            break;
211
212        case Io:
213            /*
214             * IO Port Resource
215             */
216            /*
217             * For this resource the size is static
218             */
219            SegmentSize = 8;
220            break;
221
222        case FixedIo:
223            /*
224             * Fixed IO Port Resource
225             */
226            /*
227             * For this resource the size is static
228             */
229            SegmentSize = 4;
230            break;
231
232        case VendorSpecific:
233            /*
234             * Vendor Defined Resource
235             */
236            /*
237             * For a Vendor Specific resource, if the Length is
238             *  between 1 and 7 it will be created as a Small
239             *  Resource data type, otherwise it is a Large
240             *  Resource data type.
241             */
242            if(LinkedList->Data.VendorSpecific.Length > 7)
243            {
244                SegmentSize = 3;
245            }
246            else
247            {
248                SegmentSize = 1;
249            }
250            SegmentSize +=
251                LinkedList->Data.VendorSpecific.Length;
252            break;
253
254        case EndTag:
255            /*
256             * End Tag
257             */
258            /*
259             * For this resource the size is static
260             */
261            SegmentSize = 2;
262            Done = TRUE;
263            break;
264
265        case Memory24:
266            /*
267             * 24-Bit Memory Resource
268             */
269            /*
270             * For this resource the size is static
271             */
272            SegmentSize = 12;
273            break;
274
275        case Memory32:
276            /*
277             * 32-Bit Memory Range Resource
278             */
279            /*
280             * For this resource the size is static
281             */
282            SegmentSize = 20;
283            break;
284
285        case FixedMemory32:
286            /*
287             * 32-Bit Fixed Memory Resource
288             */
289            /*
290             * For this resource the size is static
291             */
292            SegmentSize = 12;
293            break;
294
295        case Address16:
296            /*
297             * 16-Bit Address Resource
298             */
299            /*
300             * The base size of this byte stream is 16. If a
301             *  Resource Source string is not NULL, add 1 for
302             *  the Index + the length of the null terminated
303             *  string Resource Source + 1 for the null.
304             */
305            SegmentSize = 16;
306
307            if(NULL != LinkedList->Data.Address16.ResourceSource)
308            {
309                SegmentSize += (1 +
310                    LinkedList->Data.Address16.ResourceSourceStringLength);
311            }
312            break;
313
314        case Address32:
315            /*
316             * 32-Bit Address Resource
317             */
318            /*
319             * The base size of this byte stream is 26. If a Resource
320             *  Source string is not NULL, add 1 for the Index + the
321             *  length of the null terminated string Resource Source +
322             *  1 for the null.
323             */
324            SegmentSize = 26;
325
326            if(NULL != LinkedList->Data.Address16.ResourceSource)
327            {
328                SegmentSize += (1 +
329                    LinkedList->Data.Address16.ResourceSourceStringLength);
330            }
331            break;
332
333        case ExtendedIrq:
334            /*
335             * Extended IRQ Resource
336             */
337            /*
338             * The base size of this byte stream is 9. This is for an
339             *  Interrupt table length of 1.  For each additional
340             *  interrupt, add 4.
341             * If a Resource Source string is not NULL, add 1 for the
342             *  Index + the length of the null terminated string
343             *  Resource Source + 1 for the null.
344             */
345            SegmentSize = 9;
346
347            SegmentSize +=
348                (LinkedList->Data.ExtendedIrq.NumberOfInterrupts -
349                 1) * 4;
350
351            if(NULL != ExIrq->ResourceSource)
352            {
353                SegmentSize += (1 +
354                    LinkedList->Data.ExtendedIrq.ResourceSourceStringLength);
355            }
356            break;
357
358        default:
359            /*
360             * If we get here, everything is out of sync,
361             *  so exit with an error
362             */
363            return_ACPI_STATUS (AE_AML_ERROR);
364            break;
365
366        } /* switch (LinkedList->Id) */
367
368        /*
369         * Update the total
370         */
371        ByteStreamSizeNeeded += SegmentSize;
372
373        /*
374         * Point to the next object
375         */
376        LinkedList = (RESOURCE *) ((NATIVE_UINT) LinkedList +
377                     (NATIVE_UINT) LinkedList->Length);
378    }
379
380    /*
381     * This is the data the caller needs
382     */
383    *SizeNeeded = ByteStreamSizeNeeded;
384
385    return_ACPI_STATUS (AE_OK);
386}
387
388
389/*******************************************************************************
390 *
391 * FUNCTION:    AcpiRsCalculateListLength
392 *
393 * PARAMETERS:  ByteStreamBuffer        - Pointer to the resource byte stream
394 *              ByteStreamBufferLength  - Size of ByteStreamBuffer
395 *              SizeNeeded              - UINT32 pointer of the size buffer
396 *                                          needed to properly return the
397 *                                          parsed data
398 *
399 * RETURN:      Status  AE_OK if okay, else a valid ACPI_STATUS code
400 *
401 * DESCRIPTION: Takes the resource byte stream and parses it once, calculating
402 *              the size buffer needed to hold the linked list that conveys
403 *              the resource data.
404 *
405 ******************************************************************************/
406
407ACPI_STATUS
408AcpiRsCalculateListLength (
409    UINT8                   *ByteStreamBuffer,
410    UINT32                  ByteStreamBufferLength,
411    UINT32                  *SizeNeeded)
412{
413    UINT32                  BufferSize = 0;
414    UINT32                  BytesParsed = 0;
415    UINT8                   NumberOfInterrupts = 0;
416    UINT8                   NumberOfChannels = 0;
417    UINT8                   ResourceType;
418    UINT32                  StructureSize;
419    UINT32                  BytesConsumed;
420    UINT8                   *Buffer;
421    UINT8                   Temp8;
422    UINT16                  Temp16;
423    UINT8                   Index;
424    UINT8                   AdditionalBytes;
425
426
427    FUNCTION_TRACE ("RsCalculateListLength");
428
429
430    while (BytesParsed < ByteStreamBufferLength)
431    {
432        /*
433         * Look at the next byte in the stream
434         */
435        ResourceType = *ByteStreamBuffer;
436
437        /*
438         * See if this is a small or large resource
439         */
440        if(ResourceType & 0x80)
441        {
442            /*
443             * Large Resource Type
444             */
445            switch (ResourceType)
446            {
447            case MEMORY_RANGE_24:
448                /*
449                 * 24-Bit Memory Resource
450                 */
451                BytesConsumed = 12;
452
453                StructureSize = sizeof (MEMORY24_RESOURCE) +
454                                RESOURCE_LENGTH_NO_DATA;
455                break;
456
457            case LARGE_VENDOR_DEFINED:
458                /*
459                 * Vendor Defined Resource
460                 */
461                Buffer = ByteStreamBuffer;
462                ++Buffer;
463
464                MOVE_UNALIGNED16_TO_16 (&Temp16, Buffer);
465                BytesConsumed = Temp16 + 3;
466
467                /*
468                 * Ensure a 32-bit boundary for the structure
469                 */
470                Temp16 = (UINT16) ROUND_UP_TO_32BITS (Temp16);
471
472                StructureSize = sizeof (VENDOR_RESOURCE) +
473                                RESOURCE_LENGTH_NO_DATA +
474                                (Temp16 * sizeof (UINT8));
475                break;
476
477            case MEMORY_RANGE_32:
478                /*
479                 * 32-Bit Memory Range Resource
480                 */
481
482                BytesConsumed = 20;
483
484                StructureSize = sizeof (MEMORY32_RESOURCE) +
485                                RESOURCE_LENGTH_NO_DATA;
486                break;
487
488            case FIXED_MEMORY_RANGE_32:
489                /*
490                 * 32-Bit Fixed Memory Resource
491                 */
492                BytesConsumed = 12;
493
494                StructureSize = sizeof(FIXED_MEMORY32_RESOURCE) +
495                                RESOURCE_LENGTH_NO_DATA;
496                break;
497
498            case DWORD_ADDRESS_SPACE:
499                /*
500                 * 32-Bit Address Resource
501                 */
502                Buffer = ByteStreamBuffer;
503
504                ++Buffer;
505                MOVE_UNALIGNED16_TO_16 (&Temp16, Buffer);
506
507                BytesConsumed = Temp16 + 3;
508
509                /*
510                 * Resource Source Index and Resource Source are
511                 *  optional elements.  Check the length of the
512                 *  Bytestream.  If it is greater than 23, that
513                 *  means that an Index exists and is followed by
514                 *  a null termininated string.  Therefore, set
515                 *  the temp variable to the length minus the minimum
516                 *  byte stream length plus the byte for the Index to
517                 *  determine the size of the NULL terminiated string.
518                 */
519                if (23 < Temp16)
520                {
521                    Temp8 = (UINT8) (Temp16 - 24);
522                }
523                else
524                {
525                    Temp8 = 0;
526                }
527
528                /*
529                 * Ensure a 32-bit boundary for the structure
530                 */
531                Temp8 = (UINT8) ROUND_UP_TO_32BITS (Temp8);
532
533                StructureSize = sizeof (ADDRESS32_RESOURCE) +
534                                RESOURCE_LENGTH_NO_DATA +
535                                (Temp8 * sizeof (UINT8));
536                break;
537
538            case WORD_ADDRESS_SPACE:
539                /*
540                 * 16-Bit Address Resource
541                 */
542                Buffer = ByteStreamBuffer;
543
544                ++Buffer;
545                MOVE_UNALIGNED16_TO_16 (&Temp16, Buffer);
546
547                BytesConsumed = Temp16 + 3;
548
549                /*
550                 * Resource Source Index and Resource Source are
551                 *  optional elements.  Check the length of the
552                 *  Bytestream.  If it is greater than 13, that
553                 *  means that an Index exists and is followed by
554                 *  a null termininated string.  Therefore, set
555                 *  the temp variable to the length minus the minimum
556                 *  byte stream length plus the byte for the Index to
557                 *  determine the size of the NULL terminiated string.
558                 */
559                if (13 < Temp16)
560                {
561                    Temp8 = (UINT8) (Temp16 - 14);
562                }
563                else
564                {
565                    Temp8 = 0;
566                }
567
568                /*
569                 * Ensure a 32-bit boundry for the structure
570                 */
571                Temp8 = (UINT8) ROUND_UP_TO_32BITS (Temp8);
572
573                StructureSize = sizeof (ADDRESS16_RESOURCE) +
574                                RESOURCE_LENGTH_NO_DATA +
575                                (Temp8 * sizeof (UINT8));
576                break;
577
578            case EXTENDED_IRQ:
579                /*
580                 * Extended IRQ
581                 */
582                Buffer = ByteStreamBuffer;
583
584                ++Buffer;
585                MOVE_UNALIGNED16_TO_16 (&Temp16, Buffer);
586
587                BytesConsumed = Temp16 + 3;
588
589                /*
590                 * Point past the length field and the
591                 *  Interrupt vector flags to save off the
592                 *  Interrupt table length to the Temp8 variable.
593                 */
594                Buffer += 3;
595                Temp8 = *Buffer;
596
597                /*
598                 * To compensate for multiple interrupt numbers,
599                 *  Add 4 bytes for each additional interrupts
600                 *  greater than 1
601                 */
602                AdditionalBytes = (UINT8) ((Temp8 - 1) * 4);
603
604                /*
605                 * Resource Source Index and Resource Source are
606                 *  optional elements.  Check the length of the
607                 *  Bytestream.  If it is greater than 9, that
608                 *  means that an Index exists and is followed by
609                 *  a null termininated string.  Therefore, set
610                 *  the temp variable to the length minus the minimum
611                 *  byte stream length plus the byte for the Index to
612                 *  determine the size of the NULL terminiated string.
613                 */
614                if (9 + AdditionalBytes < Temp16)
615                {
616                    Temp8 = (UINT8) (Temp16 - (9 + AdditionalBytes));
617                }
618
619                else
620                {
621                    Temp8 = 0;
622                }
623
624                /*
625                 * Ensure a 32-bit boundry for the structure
626                 */
627                Temp8 = (UINT8) ROUND_UP_TO_32BITS (Temp8);
628
629                StructureSize = sizeof (EXTENDED_IRQ_RESOURCE) +
630                                RESOURCE_LENGTH_NO_DATA +
631                                (AdditionalBytes * sizeof (UINT8)) +
632                                (Temp8 * sizeof (UINT8));
633
634                break;
635
636/* TBD: [Future] 64-bit not currently supported */
637/*
638            case 0x8A:
639                break;
640*/
641
642            default:
643                /*
644                 * If we get here, everything is out of sync,
645                 *  so exit with an error
646                 */
647                return_ACPI_STATUS (AE_AML_ERROR);
648                break;
649            }
650        }
651
652        else
653        {
654            /*
655             * Small Resource Type
656             *  Only bits 7:3 are valid
657             */
658            ResourceType >>= 3;
659
660            switch (ResourceType)
661            {
662            case IRQ_FORMAT:
663                /*
664                 * IRQ Resource
665                 */
666                /*
667                 * Determine if it there are two or three
668                 *  trailing bytes
669                 */
670                Buffer = ByteStreamBuffer;
671                Temp8 = *Buffer;
672
673                if(Temp8 & 0x01)
674                {
675                    BytesConsumed = 4;
676                }
677
678                else
679                {
680                    BytesConsumed = 3;
681                }
682
683                /*
684                 * Point past the descriptor
685                 */
686                ++Buffer;
687
688                /*
689                 * Look at the number of bits set
690                 */
691                MOVE_UNALIGNED16_TO_16 (&Temp16, Buffer);
692
693                for (Index = 0; Index < 16; Index++)
694                {
695                    if (Temp16 & 0x1)
696                    {
697                        ++NumberOfInterrupts;
698                    }
699
700                    Temp16 >>= 1;
701                }
702
703                StructureSize = sizeof (IO_RESOURCE) +
704                                RESOURCE_LENGTH_NO_DATA +
705                                (NumberOfInterrupts * sizeof (UINT32));
706                break;
707
708
709            case DMA_FORMAT:
710
711                /*
712                 * DMA Resource
713                 */
714                Buffer = ByteStreamBuffer;
715
716                BytesConsumed = 3;
717
718                /*
719                 * Point past the descriptor
720                 */
721                ++Buffer;
722
723                /*
724                 * Look at the number of bits set
725                 */
726                Temp8 = *Buffer;
727
728                for(Index = 0; Index < 8; Index++)
729                {
730                    if(Temp8 & 0x1)
731                    {
732                        ++NumberOfChannels;
733                    }
734
735                    Temp8 >>= 1;
736                }
737
738                StructureSize = sizeof (DMA_RESOURCE) +
739                                RESOURCE_LENGTH_NO_DATA +
740                                (NumberOfChannels * sizeof (UINT32));
741                break;
742
743
744            case START_DEPENDENT_TAG:
745
746                /*
747                 * Start Dependent Functions Resource
748                 */
749                /*
750                 * Determine if it there are two or three trailing bytes
751                 */
752                Buffer = ByteStreamBuffer;
753                Temp8 = *Buffer;
754
755                if(Temp8 & 0x01)
756                {
757                    BytesConsumed = 2;
758                }
759                else
760                {
761                    BytesConsumed = 1;
762                }
763
764
765                StructureSize =
766                        sizeof (START_DEPENDENT_FUNCTIONS_RESOURCE) +
767                        RESOURCE_LENGTH_NO_DATA;
768                break;
769
770
771            case END_DEPENDENT_TAG:
772
773                /*
774                 * End Dependent Functions Resource
775                 */
776                BytesConsumed = 1;
777                StructureSize = RESOURCE_LENGTH;
778                break;
779
780
781            case IO_PORT_DESCRIPTOR:
782                /*
783                 * IO Port Resource
784                 */
785                BytesConsumed = 8;
786                StructureSize = sizeof (IO_RESOURCE) +
787                                RESOURCE_LENGTH_NO_DATA;
788                break;
789
790
791            case FIXED_LOCATION_IO_DESCRIPTOR:
792
793                /*
794                 * Fixed IO Port Resource
795                 */
796                BytesConsumed = 4;
797                StructureSize = sizeof (FIXED_IO_RESOURCE) +
798                                RESOURCE_LENGTH_NO_DATA;
799                break;
800
801
802            case SMALL_VENDOR_DEFINED:
803
804                /*
805                 * Vendor Specific Resource
806                 */
807                Buffer = ByteStreamBuffer;
808
809                Temp8 = *Buffer;
810                Temp8 = (UINT8) (Temp8 & 0x7);
811                BytesConsumed = Temp8 + 1;
812
813                /*
814                 * Ensure a 32-bit boundry for the structure
815                 */
816                Temp8 = (UINT8) ROUND_UP_TO_32BITS (Temp8);
817                StructureSize = sizeof (VENDOR_RESOURCE) +
818                                RESOURCE_LENGTH_NO_DATA +
819                                (Temp8 * sizeof (UINT8));
820                break;
821
822
823            case END_TAG:
824
825                /*
826                 * End Tag
827                 */
828                BytesConsumed = 2;
829                StructureSize = RESOURCE_LENGTH;
830                ByteStreamBufferLength = BytesParsed;
831                break;
832
833
834            default:
835                /*
836                 * If we get here, everything is out of sync,
837                 *  so exit with an error
838                 */
839                return_ACPI_STATUS (AE_AML_ERROR);
840                break;
841
842            } /* switch */
843
844        }  /* if(ResourceType & 0x80) */
845
846        /*
847         * Update the return value and counter
848         */
849        BufferSize += StructureSize;
850        BytesParsed += BytesConsumed;
851
852        /*
853         * Set the byte stream to point to the next resource
854         */
855        ByteStreamBuffer += BytesConsumed;
856
857    }
858
859    /*
860     * This is the data the caller needs
861     */
862    *SizeNeeded = BufferSize;
863
864    return_ACPI_STATUS (AE_OK);
865}
866
867
868/*******************************************************************************
869 *
870 * FUNCTION:    AcpiRsCalculatePciRoutingTableLength
871 *
872 * PARAMETERS:  PackageObject           - Pointer to the package object
873 *              BufferSizeNeeded        - UINT32 pointer of the size buffer
874 *                                          needed to properly return the
875 *                                          parsed data
876 *
877 * RETURN:      Status  AE_OK
878 *
879 * DESCRIPTION: Given a package representing a PCI routing table, this
880 *                calculates the size of the corresponding linked list of
881 *                descriptions.
882 *
883 ******************************************************************************/
884
885ACPI_STATUS
886AcpiRsCalculatePciRoutingTableLength (
887    ACPI_OPERAND_OBJECT     *PackageObject,
888    UINT32                  *BufferSizeNeeded)
889{
890    UINT32                  NumberOfElements;
891    UINT32                  TempSizeNeeded = 0;
892    ACPI_OPERAND_OBJECT     **TopObjectList;
893    UINT32                  Index;
894    ACPI_OPERAND_OBJECT     *PackageElement;
895    ACPI_OPERAND_OBJECT     **SubObjectList;
896    BOOLEAN                 NameFound;
897    UINT32                  TableIndex;
898
899
900    FUNCTION_TRACE ("AcpiRsCalculatePciRoutingTableLength");
901
902
903    NumberOfElements = PackageObject->Package.Count;
904
905    /*
906     * Calculate the size of the return buffer.
907     * The base size is the number of elements * the sizes of the
908     * structures.  Additional space for the strings is added below.
909     * The minus one is to subtract the size of the UINT8 Source[1]
910     * member because it is added below.
911     *
912     * NOTE: The NumberOfElements is incremented by one to add an end
913     * table structure that is essentially a structure of zeros.
914     */
915
916    /*
917     * But each PRT_ENTRY structure has a pointer to a string and
918     * the size of that string must be found.
919     */
920    TopObjectList = PackageObject->Package.Elements;
921
922    for (Index = 0; Index < NumberOfElements; Index++)
923    {
924        /*
925         * Dereference the sub-package
926         */
927        PackageElement = *TopObjectList;
928
929        /*
930         * The SubObjectList will now point to an array of the
931         * four IRQ elements: Address, Pin, Source and SourceIndex
932         */
933        SubObjectList = PackageElement->Package.Elements;
934
935        /*
936         * Scan the IrqTableElements for the Source Name String
937         */
938        NameFound = FALSE;
939
940        for (TableIndex = 0; TableIndex < 4 && !NameFound; TableIndex++)
941        {
942            if ((ACPI_TYPE_STRING == (*SubObjectList)->Common.Type) ||
943                ((INTERNAL_TYPE_REFERENCE == (*SubObjectList)->Common.Type) &&
944                    ((*SubObjectList)->Reference.OpCode == AML_NAMEPATH_OP)))
945            {
946                NameFound = TRUE;
947            }
948
949            else
950            {
951                /*
952                 * Look at the next element
953                 */
954                SubObjectList++;
955            }
956        }
957
958        TempSizeNeeded += (sizeof (PCI_ROUTING_TABLE) - 4);
959
960        /*
961         * Was a String type found?
962         */
963        if (TRUE == NameFound)
964        {
965            if (ACPI_TYPE_STRING == (*SubObjectList)->Common.Type)
966            {
967                /*
968                 * The length String.Length field includes the
969                 * terminating NULL
970                 */
971                TempSizeNeeded += (*SubObjectList)->String.Length;
972            }
973            else
974            {
975                TempSizeNeeded += AcpiNsGetPathnameLength ((*SubObjectList)->Reference.Node);
976            }
977        }
978
979        else
980        {
981            /*
982             * If no name was found, then this is a NULL, which is
983             *  translated as a UINT32 zero.
984             */
985            TempSizeNeeded += sizeof(UINT32);
986        }
987
988
989        /* Round up the size since each element must be aligned */
990
991        TempSizeNeeded = ROUND_UP_TO_64BITS (TempSizeNeeded);
992
993        /*
994         * Point to the next ACPI_OPERAND_OBJECT
995         */
996        TopObjectList++;
997    }
998
999
1000    *BufferSizeNeeded = TempSizeNeeded;
1001
1002    return_ACPI_STATUS (AE_OK);
1003}
1004