Subversion Repositories Kolibri OS

Rev

Rev 1498 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1498 serge 1
/*******************************************************************************
2
 *
3
 * Module Name: rscalc - Calculate stream and list lengths
4
 *
5
 ******************************************************************************/
6
 
7
/******************************************************************************
8
 *
9
 * 1. Copyright Notice
10
 *
2216 Serge 11
 * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
1498 serge 12
 * All rights reserved.
13
 *
14
 * 2. License
15
 *
16
 * 2.1. This is your license from Intel Corp. under its intellectual property
17
 * rights.  You may have additional license terms from the party that provided
18
 * you this software, covering your right to use that party's intellectual
19
 * property rights.
20
 *
21
 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22
 * copy of the source code appearing in this file ("Covered Code") an
23
 * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24
 * base code distributed originally by Intel ("Original Intel Code") to copy,
25
 * make derivatives, distribute, use and display any portion of the Covered
26
 * Code in any form, with the right to sublicense such rights; and
27
 *
28
 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29
 * license (with the right to sublicense), under only those claims of Intel
30
 * patents that are infringed by the Original Intel Code, to make, use, sell,
31
 * offer to sell, and import the Covered Code and derivative works thereof
32
 * solely to the minimum extent necessary to exercise the above copyright
33
 * license, and in no event shall the patent license extend to any additions
34
 * to or modifications of the Original Intel Code.  No other license or right
35
 * is granted directly or by implication, estoppel or otherwise;
36
 *
37
 * The above copyright and patent license is granted only if the following
38
 * conditions are met:
39
 *
40
 * 3. Conditions
41
 *
42
 * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43
 * Redistribution of source code of any substantial portion of the Covered
44
 * Code or modification with rights to further distribute source must include
45
 * the above Copyright Notice, the above License, this list of Conditions,
46
 * and the following Disclaimer and Export Compliance provision.  In addition,
47
 * Licensee must cause all Covered Code to which Licensee contributes to
48
 * contain a file documenting the changes Licensee made to create that Covered
49
 * Code and the date of any change.  Licensee must include in that file the
50
 * documentation of any changes made by any predecessor Licensee.  Licensee
51
 * must include a prominent statement that the modification is derived,
52
 * directly or indirectly, from Original Intel Code.
53
 *
54
 * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55
 * Redistribution of source code of any substantial portion of the Covered
56
 * Code or modification without rights to further distribute source must
57
 * include the following Disclaimer and Export Compliance provision in the
58
 * documentation and/or other materials provided with distribution.  In
59
 * addition, Licensee may not authorize further sublicense of source of any
60
 * portion of the Covered Code, and must include terms to the effect that the
61
 * license from Licensee to its licensee is limited to the intellectual
62
 * property embodied in the software Licensee provides to its licensee, and
63
 * not to intellectual property embodied in modifications its licensee may
64
 * make.
65
 *
66
 * 3.3. Redistribution of Executable. Redistribution in executable form of any
67
 * substantial portion of the Covered Code or modification must reproduce the
68
 * above Copyright Notice, and the following Disclaimer and Export Compliance
69
 * provision in the documentation and/or other materials provided with the
70
 * distribution.
71
 *
72
 * 3.4. Intel retains all right, title, and interest in and to the Original
73
 * Intel Code.
74
 *
75
 * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76
 * Intel shall be used in advertising or otherwise to promote the sale, use or
77
 * other dealings in products derived from or relating to the Covered Code
78
 * without prior written authorization from Intel.
79
 *
80
 * 4. Disclaimer and Export Compliance
81
 *
82
 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83
 * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84
 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
85
 * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
86
 * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
87
 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88
 * PARTICULAR PURPOSE.
89
 *
90
 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91
 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92
 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93
 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94
 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95
 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
96
 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97
 * LIMITED REMEDY.
98
 *
99
 * 4.3. Licensee shall not export, either directly or indirectly, any of this
100
 * software or system incorporating such software without first obtaining any
101
 * required license or other approval from the U. S. Department of Commerce or
102
 * any other agency or department of the United States Government.  In the
103
 * event Licensee exports any such software from the United States or
104
 * re-exports any such software from a foreign destination, Licensee shall
105
 * ensure that the distribution and export/re-export of the software is in
106
 * compliance with all laws, regulations, orders, or other restrictions of the
107
 * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108
 * any of its subsidiaries will export/re-export any technical data, process,
109
 * software, or service, directly or indirectly, to any country for which the
110
 * United States government or any agency thereof requires an export license,
111
 * other governmental approval, or letter of assurance, without first obtaining
112
 * such license, approval or letter.
113
 *
114
 *****************************************************************************/
115
 
116
#define __RSCALC_C__
117
 
118
#include "acpi.h"
119
#include "accommon.h"
120
#include "acresrc.h"
121
#include "acnamesp.h"
122
 
123
 
124
#define _COMPONENT          ACPI_RESOURCES
125
        ACPI_MODULE_NAME    ("rscalc")
126
 
127
 
128
/* Local prototypes */
129
 
130
static UINT8
131
AcpiRsCountSetBits (
132
    UINT16                  BitField);
133
 
134
static ACPI_RS_LENGTH
135
AcpiRsStructOptionLength (
136
    ACPI_RESOURCE_SOURCE    *ResourceSource);
137
 
138
static UINT32
139
AcpiRsStreamOptionLength (
140
    UINT32                  ResourceLength,
141
    UINT32                  MinimumTotalLength);
142
 
143
 
144
/*******************************************************************************
145
 *
146
 * FUNCTION:    AcpiRsCountSetBits
147
 *
148
 * PARAMETERS:  BitField        - Field in which to count bits
149
 *
150
 * RETURN:      Number of bits set within the field
151
 *
152
 * DESCRIPTION: Count the number of bits set in a resource field. Used for
153
 *              (Short descriptor) interrupt and DMA lists.
154
 *
155
 ******************************************************************************/
156
 
157
static UINT8
158
AcpiRsCountSetBits (
159
    UINT16                  BitField)
160
{
161
    UINT8                   BitsSet;
162
 
163
 
164
    ACPI_FUNCTION_ENTRY ();
165
 
166
 
167
    for (BitsSet = 0; BitField; BitsSet++)
168
    {
169
        /* Zero the least significant bit that is set */
170
 
171
        BitField &= (UINT16) (BitField - 1);
172
    }
173
 
174
    return (BitsSet);
175
}
176
 
177
 
178
/*******************************************************************************
179
 *
180
 * FUNCTION:    AcpiRsStructOptionLength
181
 *
182
 * PARAMETERS:  ResourceSource      - Pointer to optional descriptor field
183
 *
184
 * RETURN:      Status
185
 *
186
 * DESCRIPTION: Common code to handle optional ResourceSourceIndex and
187
 *              ResourceSource fields in some Large descriptors. Used during
188
 *              list-to-stream conversion
189
 *
190
 ******************************************************************************/
191
 
192
static ACPI_RS_LENGTH
193
AcpiRsStructOptionLength (
194
    ACPI_RESOURCE_SOURCE    *ResourceSource)
195
{
196
    ACPI_FUNCTION_ENTRY ();
197
 
198
 
199
    /*
200
     * If the ResourceSource string is valid, return the size of the string
201
     * (StringLength includes the NULL terminator) plus the size of the
202
     * ResourceSourceIndex (1).
203
     */
204
    if (ResourceSource->StringPtr)
205
    {
206
        return ((ACPI_RS_LENGTH) (ResourceSource->StringLength + 1));
207
    }
208
 
209
    return (0);
210
}
211
 
212
 
213
/*******************************************************************************
214
 *
215
 * FUNCTION:    AcpiRsStreamOptionLength
216
 *
217
 * PARAMETERS:  ResourceLength      - Length from the resource header
218
 *              MinimumTotalLength  - Minimum length of this resource, before
219
 *                                    any optional fields. Includes header size
220
 *
221
 * RETURN:      Length of optional string (0 if no string present)
222
 *
223
 * DESCRIPTION: Common code to handle optional ResourceSourceIndex and
224
 *              ResourceSource fields in some Large descriptors. Used during
225
 *              stream-to-list conversion
226
 *
227
 ******************************************************************************/
228
 
229
static UINT32
230
AcpiRsStreamOptionLength (
231
    UINT32                  ResourceLength,
232
    UINT32                  MinimumAmlResourceLength)
233
{
234
    UINT32                  StringLength = 0;
235
 
236
 
237
    ACPI_FUNCTION_ENTRY ();
238
 
239
 
240
    /*
241
     * The ResourceSourceIndex and ResourceSource are optional elements of some
242
     * Large-type resource descriptors.
243
     */
244
 
245
    /*
246
     * If the length of the actual resource descriptor is greater than the ACPI
247
     * spec-defined minimum length, it means that a ResourceSourceIndex exists
248
     * and is followed by a (required) null terminated string. The string length
249
     * (including the null terminator) is the resource length minus the minimum
250
     * length, minus one byte for the ResourceSourceIndex itself.
251
     */
252
    if (ResourceLength > MinimumAmlResourceLength)
253
    {
254
        /* Compute the length of the optional string */
255
 
256
        StringLength = ResourceLength - MinimumAmlResourceLength - 1;
257
    }
258
 
259
    /*
260
     * Round the length up to a multiple of the native word in order to
261
     * guarantee that the entire resource descriptor is native word aligned
262
     */
263
    return ((UINT32) ACPI_ROUND_UP_TO_NATIVE_WORD (StringLength));
264
}
265
 
266
 
267
/*******************************************************************************
268
 *
269
 * FUNCTION:    AcpiRsGetAmlLength
270
 *
271
 * PARAMETERS:  Resource            - Pointer to the resource linked list
272
 *              SizeNeeded          - Where the required size is returned
273
 *
274
 * RETURN:      Status
275
 *
276
 * DESCRIPTION: Takes a linked list of internal resource descriptors and
277
 *              calculates the size buffer needed to hold the corresponding
278
 *              external resource byte stream.
279
 *
280
 ******************************************************************************/
281
 
282
ACPI_STATUS
283
AcpiRsGetAmlLength (
284
    ACPI_RESOURCE           *Resource,
285
    ACPI_SIZE               *SizeNeeded)
286
{
287
    ACPI_SIZE               AmlSizeNeeded = 0;
288
    ACPI_RS_LENGTH          TotalSize;
289
 
290
 
291
    ACPI_FUNCTION_TRACE (RsGetAmlLength);
292
 
293
 
294
    /* Traverse entire list of internal resource descriptors */
295
 
296
    while (Resource)
297
    {
298
        /* Validate the descriptor type */
299
 
300
        if (Resource->Type > ACPI_RESOURCE_TYPE_MAX)
301
        {
302
            return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE);
303
        }
304
 
305
        /* Get the base size of the (external stream) resource descriptor */
306
 
307
        TotalSize = AcpiGbl_AmlResourceSizes [Resource->Type];
308
 
309
        /*
310
         * Augment the base size for descriptors with optional and/or
311
         * variable-length fields
312
         */
313
        switch (Resource->Type)
314
        {
315
        case ACPI_RESOURCE_TYPE_IRQ:
316
 
317
            /* Length can be 3 or 2 */
318
 
319
            if (Resource->Data.Irq.DescriptorLength == 2)
320
            {
321
                TotalSize--;
322
            }
323
            break;
324
 
325
 
326
        case ACPI_RESOURCE_TYPE_START_DEPENDENT:
327
 
328
            /* Length can be 1 or 0 */
329
 
330
            if (Resource->Data.Irq.DescriptorLength == 0)
331
            {
332
                TotalSize--;
333
            }
334
            break;
335
 
336
 
337
        case ACPI_RESOURCE_TYPE_VENDOR:
338
            /*
339
             * Vendor Defined Resource:
340
             * For a Vendor Specific resource, if the Length is between 1 and 7
341
             * it will be created as a Small Resource data type, otherwise it
342
             * is a Large Resource data type.
343
             */
344
            if (Resource->Data.Vendor.ByteLength > 7)
345
            {
346
                /* Base size of a Large resource descriptor */
347
 
348
                TotalSize = sizeof (AML_RESOURCE_LARGE_HEADER);
349
            }
350
 
351
            /* Add the size of the vendor-specific data */
352
 
353
            TotalSize = (ACPI_RS_LENGTH)
354
                (TotalSize + Resource->Data.Vendor.ByteLength);
355
            break;
356
 
357
 
358
        case ACPI_RESOURCE_TYPE_END_TAG:
359
            /*
360
             * End Tag:
361
             * We are done -- return the accumulated total size.
362
             */
363
            *SizeNeeded = AmlSizeNeeded + TotalSize;
364
 
365
            /* Normal exit */
366
 
367
            return_ACPI_STATUS (AE_OK);
368
 
369
 
370
        case ACPI_RESOURCE_TYPE_ADDRESS16:
371
            /*
372
             * 16-Bit Address Resource:
373
             * Add the size of the optional ResourceSource info
374
             */
375
            TotalSize = (ACPI_RS_LENGTH)
376
                (TotalSize + AcpiRsStructOptionLength (
377
                                &Resource->Data.Address16.ResourceSource));
378
            break;
379
 
380
 
381
        case ACPI_RESOURCE_TYPE_ADDRESS32:
382
            /*
383
             * 32-Bit Address Resource:
384
             * Add the size of the optional ResourceSource info
385
             */
386
            TotalSize = (ACPI_RS_LENGTH)
387
                (TotalSize + AcpiRsStructOptionLength (
388
                                &Resource->Data.Address32.ResourceSource));
389
            break;
390
 
391
 
392
        case ACPI_RESOURCE_TYPE_ADDRESS64:
393
            /*
394
             * 64-Bit Address Resource:
395
             * Add the size of the optional ResourceSource info
396
             */
397
            TotalSize = (ACPI_RS_LENGTH)
398
                (TotalSize + AcpiRsStructOptionLength (
399
                                &Resource->Data.Address64.ResourceSource));
400
            break;
401
 
402
 
403
        case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
404
            /*
405
             * Extended IRQ Resource:
406
             * Add the size of each additional optional interrupt beyond the
407
             * required 1 (4 bytes for each UINT32 interrupt number)
408
             */
409
            TotalSize = (ACPI_RS_LENGTH)
410
                (TotalSize +
411
                ((Resource->Data.ExtendedIrq.InterruptCount - 1) * 4) +
412
 
413
                /* Add the size of the optional ResourceSource info */
414
 
415
                AcpiRsStructOptionLength (
416
                    &Resource->Data.ExtendedIrq.ResourceSource));
417
            break;
418
 
419
 
420
        default:
421
            break;
422
        }
423
 
424
        /* Update the total */
425
 
426
        AmlSizeNeeded += TotalSize;
427
 
428
        /* Point to the next object */
429
 
430
        Resource = ACPI_ADD_PTR (ACPI_RESOURCE, Resource, Resource->Length);
431
    }
432
 
433
    /* Did not find an EndTag resource descriptor */
434
 
435
    return_ACPI_STATUS (AE_AML_NO_RESOURCE_END_TAG);
436
}
437
 
438
 
439
/*******************************************************************************
440
 *
441
 * FUNCTION:    AcpiRsGetListLength
442
 *
443
 * PARAMETERS:  AmlBuffer           - Pointer to the resource byte stream
444
 *              AmlBufferLength     - Size of AmlBuffer
445
 *              SizeNeeded          - Where the size needed is returned
446
 *
447
 * RETURN:      Status
448
 *
449
 * DESCRIPTION: Takes an external resource byte stream and calculates the size
450
 *              buffer needed to hold the corresponding internal resource
451
 *              descriptor linked list.
452
 *
453
 ******************************************************************************/
454
 
455
ACPI_STATUS
456
AcpiRsGetListLength (
457
    UINT8                   *AmlBuffer,
458
    UINT32                  AmlBufferLength,
459
    ACPI_SIZE               *SizeNeeded)
460
{
461
    ACPI_STATUS             Status;
462
    UINT8                   *EndAml;
463
    UINT8                   *Buffer;
464
    UINT32                  BufferSize;
465
    UINT16                  Temp16;
466
    UINT16                  ResourceLength;
467
    UINT32                  ExtraStructBytes;
468
    UINT8                   ResourceIndex;
469
    UINT8                   MinimumAmlResourceLength;
470
 
471
 
472
    ACPI_FUNCTION_TRACE (RsGetListLength);
473
 
474
 
475
    *SizeNeeded = 0;
476
    EndAml = AmlBuffer + AmlBufferLength;
477
 
478
    /* Walk the list of AML resource descriptors */
479
 
480
    while (AmlBuffer < EndAml)
481
    {
482
        /* Validate the Resource Type and Resource Length */
483
 
484
        Status = AcpiUtValidateResource (AmlBuffer, &ResourceIndex);
485
        if (ACPI_FAILURE (Status))
486
        {
487
            return_ACPI_STATUS (Status);
488
        }
489
 
490
        /* Get the resource length and base (minimum) AML size */
491
 
492
        ResourceLength = AcpiUtGetResourceLength (AmlBuffer);
493
        MinimumAmlResourceLength = AcpiGbl_ResourceAmlSizes[ResourceIndex];
494
 
495
        /*
496
         * Augment the size for descriptors with optional
497
         * and/or variable length fields
498
         */
499
        ExtraStructBytes = 0;
500
        Buffer = AmlBuffer + AcpiUtGetResourceHeaderLength (AmlBuffer);
501
 
502
        switch (AcpiUtGetResourceType (AmlBuffer))
503
        {
504
        case ACPI_RESOURCE_NAME_IRQ:
505
            /*
506
             * IRQ Resource:
507
             * Get the number of bits set in the 16-bit IRQ mask
508
             */
509
            ACPI_MOVE_16_TO_16 (&Temp16, Buffer);
510
            ExtraStructBytes = AcpiRsCountSetBits (Temp16);
511
            break;
512
 
513
 
514
        case ACPI_RESOURCE_NAME_DMA:
515
            /*
516
             * DMA Resource:
517
             * Get the number of bits set in the 8-bit DMA mask
518
             */
519
            ExtraStructBytes = AcpiRsCountSetBits (*Buffer);
520
            break;
521
 
522
 
523
        case ACPI_RESOURCE_NAME_VENDOR_SMALL:
524
        case ACPI_RESOURCE_NAME_VENDOR_LARGE:
525
            /*
526
             * Vendor Resource:
527
             * Get the number of vendor data bytes
528
             */
529
            ExtraStructBytes = ResourceLength;
530
            break;
531
 
532
 
533
        case ACPI_RESOURCE_NAME_END_TAG:
534
            /*
535
             * End Tag:
536
             * This is the normal exit, add size of EndTag
537
             */
538
            *SizeNeeded += ACPI_RS_SIZE_MIN;
539
            return_ACPI_STATUS (AE_OK);
540
 
541
 
542
        case ACPI_RESOURCE_NAME_ADDRESS32:
543
        case ACPI_RESOURCE_NAME_ADDRESS16:
544
        case ACPI_RESOURCE_NAME_ADDRESS64:
545
            /*
546
             * Address Resource:
547
             * Add the size of the optional ResourceSource
548
             */
549
            ExtraStructBytes = AcpiRsStreamOptionLength (
550
                ResourceLength, MinimumAmlResourceLength);
551
            break;
552
 
553
 
554
        case ACPI_RESOURCE_NAME_EXTENDED_IRQ:
555
            /*
556
             * Extended IRQ Resource:
557
             * Using the InterruptTableLength, add 4 bytes for each additional
558
             * interrupt. Note: at least one interrupt is required and is
559
             * included in the minimum descriptor size (reason for the -1)
560
             */
561
            ExtraStructBytes = (Buffer[1] - 1) * sizeof (UINT32);
562
 
563
            /* Add the size of the optional ResourceSource */
564
 
565
            ExtraStructBytes += AcpiRsStreamOptionLength (
566
                ResourceLength - ExtraStructBytes, MinimumAmlResourceLength);
567
            break;
568
 
569
 
570
        default:
571
            break;
572
        }
573
 
574
        /*
575
         * Update the required buffer size for the internal descriptor structs
576
         *
577
         * Important: Round the size up for the appropriate alignment. This
578
         * is a requirement on IA64.
579
         */
580
        BufferSize = AcpiGbl_ResourceStructSizes[ResourceIndex] +
581
                        ExtraStructBytes;
582
        BufferSize = (UINT32) ACPI_ROUND_UP_TO_NATIVE_WORD (BufferSize);
583
 
584
        *SizeNeeded += BufferSize;
585
 
586
        ACPI_DEBUG_PRINT ((ACPI_DB_RESOURCES,
587
            "Type %.2X, AmlLength %.2X InternalLength %.2X\n",
588
            AcpiUtGetResourceType (AmlBuffer),
589
            AcpiUtGetDescriptorLength (AmlBuffer), BufferSize));
590
 
591
        /*
592
         * Point to the next resource within the AML stream using the length
593
         * contained in the resource descriptor header
594
         */
595
        AmlBuffer += AcpiUtGetDescriptorLength (AmlBuffer);
596
    }
597
 
598
    /* Did not find an EndTag resource descriptor */
599
 
600
    return_ACPI_STATUS (AE_AML_NO_RESOURCE_END_TAG);
601
}
602
 
603
 
604
/*******************************************************************************
605
 *
606
 * FUNCTION:    AcpiRsGetPciRoutingTableLength
607
 *
608
 * PARAMETERS:  PackageObject           - Pointer to the package object
609
 *              BufferSizeNeeded        - UINT32 pointer of the size buffer
610
 *                                        needed to properly return the
611
 *                                        parsed data
612
 *
613
 * RETURN:      Status
614
 *
615
 * DESCRIPTION: Given a package representing a PCI routing table, this
616
 *              calculates the size of the corresponding linked list of
617
 *              descriptions.
618
 *
619
 ******************************************************************************/
620
 
621
ACPI_STATUS
622
AcpiRsGetPciRoutingTableLength (
623
    ACPI_OPERAND_OBJECT     *PackageObject,
624
    ACPI_SIZE               *BufferSizeNeeded)
625
{
626
    UINT32                  NumberOfElements;
627
    ACPI_SIZE               TempSizeNeeded = 0;
628
    ACPI_OPERAND_OBJECT     **TopObjectList;
629
    UINT32                  Index;
630
    ACPI_OPERAND_OBJECT     *PackageElement;
631
    ACPI_OPERAND_OBJECT     **SubObjectList;
632
    BOOLEAN                 NameFound;
633
    UINT32                  TableIndex;
634
 
635
 
636
    ACPI_FUNCTION_TRACE (RsGetPciRoutingTableLength);
637
 
638
 
639
    NumberOfElements = PackageObject->Package.Count;
640
 
641
    /*
642
     * Calculate the size of the return buffer.
643
     * The base size is the number of elements * the sizes of the
644
     * structures.  Additional space for the strings is added below.
645
     * The minus one is to subtract the size of the UINT8 Source[1]
646
     * member because it is added below.
647
     *
648
     * But each PRT_ENTRY structure has a pointer to a string and
649
     * the size of that string must be found.
650
     */
651
    TopObjectList = PackageObject->Package.Elements;
652
 
653
    for (Index = 0; Index < NumberOfElements; Index++)
654
    {
655
        /* Dereference the sub-package */
656
 
657
        PackageElement = *TopObjectList;
658
 
659
        /* We must have a valid Package object */
660
 
661
        if (!PackageElement ||
662
            (PackageElement->Common.Type != ACPI_TYPE_PACKAGE))
663
        {
664
            return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
665
        }
666
 
667
        /*
668
         * The SubObjectList will now point to an array of the
669
         * four IRQ elements: Address, Pin, Source and SourceIndex
670
         */
671
        SubObjectList = PackageElement->Package.Elements;
672
 
673
        /* Scan the IrqTableElements for the Source Name String */
674
 
675
        NameFound = FALSE;
676
 
677
        for (TableIndex = 0; TableIndex < 4 && !NameFound; TableIndex++)
678
        {
679
            if (*SubObjectList && /* Null object allowed */
680
 
681
                ((ACPI_TYPE_STRING ==
682
                    (*SubObjectList)->Common.Type) ||
683
 
684
                ((ACPI_TYPE_LOCAL_REFERENCE ==
685
                    (*SubObjectList)->Common.Type) &&
686
 
687
                    ((*SubObjectList)->Reference.Class ==
688
                        ACPI_REFCLASS_NAME))))
689
            {
690
                NameFound = TRUE;
691
            }
692
            else
693
            {
694
                /* Look at the next element */
695
 
696
                SubObjectList++;
697
            }
698
        }
699
 
700
        TempSizeNeeded += (sizeof (ACPI_PCI_ROUTING_TABLE) - 4);
701
 
702
        /* Was a String type found? */
703
 
704
        if (NameFound)
705
        {
706
            if ((*SubObjectList)->Common.Type == ACPI_TYPE_STRING)
707
            {
708
                /*
709
                 * The length String.Length field does not include the
710
                 * terminating NULL, add 1
711
                 */
712
                TempSizeNeeded += ((ACPI_SIZE)
713
                    (*SubObjectList)->String.Length + 1);
714
            }
715
            else
716
            {
717
                TempSizeNeeded += AcpiNsGetPathnameLength (
718
                                    (*SubObjectList)->Reference.Node);
719
            }
720
        }
721
        else
722
        {
723
            /*
724
             * If no name was found, then this is a NULL, which is
725
             * translated as a UINT32 zero.
726
             */
727
            TempSizeNeeded += sizeof (UINT32);
728
        }
729
 
730
        /* Round up the size since each element must be aligned */
731
 
732
        TempSizeNeeded = ACPI_ROUND_UP_TO_64BIT (TempSizeNeeded);
733
 
734
        /* Point to the next ACPI_OPERAND_OBJECT */
735
 
736
        TopObjectList++;
737
    }
738
 
739
    /*
740
     * Add an extra element to the end of the list, essentially a
741
     * NULL terminator
742
     */
743
    *BufferSizeNeeded = TempSizeNeeded + sizeof (ACPI_PCI_ROUTING_TABLE);
744
    return_ACPI_STATUS (AE_OK);
745
}