1/*******************************************************************************
2 *
3 * Module Name: rscalc - Calculate stream and list lengths
4 *
5 ******************************************************************************/
6
7/******************************************************************************
8 *
9 * 1. Copyright Notice
10 *
11 * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp.
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
130static UINT8
131AcpiRsCountSetBits (
132    UINT16                  BitField);
133
134static ACPI_RS_LENGTH
135AcpiRsStructOptionLength (
136    ACPI_RESOURCE_SOURCE    *ResourceSource);
137
138static UINT32
139AcpiRsStreamOptionLength (
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
157static UINT8
158AcpiRsCountSetBits (
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
192static ACPI_RS_LENGTH
193AcpiRsStructOptionLength (
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
229static UINT32
230AcpiRsStreamOptionLength (
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
282ACPI_STATUS
283AcpiRsGetAmlLength (
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
455ACPI_STATUS
456AcpiRsGetListLength (
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
621ACPI_STATUS
622AcpiRsGetPciRoutingTableLength (
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}
746