Sync ACPICA with Intel's version 20141107.
[dragonfly.git] / sys / contrib / dev / acpica / source / components / resources / rscalc.c
1 /*******************************************************************************
2  *
3  * Module Name: rscalc - Calculate stream and list lengths
4  *
5  ******************************************************************************/
6
7 /*
8  * Copyright (C) 2000 - 2014, Intel Corp.
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions, and the following disclaimer,
16  *    without modification.
17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18  *    substantially similar to the "NO WARRANTY" disclaimer below
19  *    ("Disclaimer") and any redistribution must be conditioned upon
20  *    including a substantially similar Disclaimer requirement for further
21  *    binary redistribution.
22  * 3. Neither the names of the above-listed copyright holders nor the names
23  *    of any contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * Alternatively, this software may be distributed under the terms of the
27  * GNU General Public License ("GPL") version 2 as published by the Free
28  * Software Foundation.
29  *
30  * NO WARRANTY
31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41  * POSSIBILITY OF SUCH DAMAGES.
42  */
43
44 #include "acpi.h"
45 #include "accommon.h"
46 #include "acresrc.h"
47 #include "acnamesp.h"
48
49
50 #define _COMPONENT          ACPI_RESOURCES
51         ACPI_MODULE_NAME    ("rscalc")
52
53
54 /* Local prototypes */
55
56 static UINT8
57 AcpiRsCountSetBits (
58     UINT16                  BitField);
59
60 static ACPI_RS_LENGTH
61 AcpiRsStructOptionLength (
62     ACPI_RESOURCE_SOURCE    *ResourceSource);
63
64 static UINT32
65 AcpiRsStreamOptionLength (
66     UINT32                  ResourceLength,
67     UINT32                  MinimumTotalLength);
68
69
70 /*******************************************************************************
71  *
72  * FUNCTION:    AcpiRsCountSetBits
73  *
74  * PARAMETERS:  BitField        - Field in which to count bits
75  *
76  * RETURN:      Number of bits set within the field
77  *
78  * DESCRIPTION: Count the number of bits set in a resource field. Used for
79  *              (Short descriptor) interrupt and DMA lists.
80  *
81  ******************************************************************************/
82
83 static UINT8
84 AcpiRsCountSetBits (
85     UINT16                  BitField)
86 {
87     UINT8                   BitsSet;
88
89
90     ACPI_FUNCTION_ENTRY ();
91
92
93     for (BitsSet = 0; BitField; BitsSet++)
94     {
95         /* Zero the least significant bit that is set */
96
97         BitField &= (UINT16) (BitField - 1);
98     }
99
100     return (BitsSet);
101 }
102
103
104 /*******************************************************************************
105  *
106  * FUNCTION:    AcpiRsStructOptionLength
107  *
108  * PARAMETERS:  ResourceSource      - Pointer to optional descriptor field
109  *
110  * RETURN:      Status
111  *
112  * DESCRIPTION: Common code to handle optional ResourceSourceIndex and
113  *              ResourceSource fields in some Large descriptors. Used during
114  *              list-to-stream conversion
115  *
116  ******************************************************************************/
117
118 static ACPI_RS_LENGTH
119 AcpiRsStructOptionLength (
120     ACPI_RESOURCE_SOURCE    *ResourceSource)
121 {
122     ACPI_FUNCTION_ENTRY ();
123
124
125     /*
126      * If the ResourceSource string is valid, return the size of the string
127      * (StringLength includes the NULL terminator) plus the size of the
128      * ResourceSourceIndex (1).
129      */
130     if (ResourceSource->StringPtr)
131     {
132         return ((ACPI_RS_LENGTH) (ResourceSource->StringLength + 1));
133     }
134
135     return (0);
136 }
137
138
139 /*******************************************************************************
140  *
141  * FUNCTION:    AcpiRsStreamOptionLength
142  *
143  * PARAMETERS:  ResourceLength      - Length from the resource header
144  *              MinimumTotalLength  - Minimum length of this resource, before
145  *                                    any optional fields. Includes header size
146  *
147  * RETURN:      Length of optional string (0 if no string present)
148  *
149  * DESCRIPTION: Common code to handle optional ResourceSourceIndex and
150  *              ResourceSource fields in some Large descriptors. Used during
151  *              stream-to-list conversion
152  *
153  ******************************************************************************/
154
155 static UINT32
156 AcpiRsStreamOptionLength (
157     UINT32                  ResourceLength,
158     UINT32                  MinimumAmlResourceLength)
159 {
160     UINT32                  StringLength = 0;
161
162
163     ACPI_FUNCTION_ENTRY ();
164
165
166     /*
167      * The ResourceSourceIndex and ResourceSource are optional elements of some
168      * Large-type resource descriptors.
169      */
170
171     /*
172      * If the length of the actual resource descriptor is greater than the ACPI
173      * spec-defined minimum length, it means that a ResourceSourceIndex exists
174      * and is followed by a (required) null terminated string. The string length
175      * (including the null terminator) is the resource length minus the minimum
176      * length, minus one byte for the ResourceSourceIndex itself.
177      */
178     if (ResourceLength > MinimumAmlResourceLength)
179     {
180         /* Compute the length of the optional string */
181
182         StringLength = ResourceLength - MinimumAmlResourceLength - 1;
183     }
184
185     /*
186      * Round the length up to a multiple of the native word in order to
187      * guarantee that the entire resource descriptor is native word aligned
188      */
189     return ((UINT32) ACPI_ROUND_UP_TO_NATIVE_WORD (StringLength));
190 }
191
192
193 /*******************************************************************************
194  *
195  * FUNCTION:    AcpiRsGetAmlLength
196  *
197  * PARAMETERS:  Resource            - Pointer to the resource linked list
198  *              ResourceListSize    - Size of the resource linked list
199  *              SizeNeeded          - Where the required size is returned
200  *
201  * RETURN:      Status
202  *
203  * DESCRIPTION: Takes a linked list of internal resource descriptors and
204  *              calculates the size buffer needed to hold the corresponding
205  *              external resource byte stream.
206  *
207  ******************************************************************************/
208
209 ACPI_STATUS
210 AcpiRsGetAmlLength (
211     ACPI_RESOURCE           *Resource,
212     ACPI_SIZE               ResourceListSize,
213     ACPI_SIZE               *SizeNeeded)
214 {
215     ACPI_SIZE               AmlSizeNeeded = 0;
216     ACPI_RESOURCE           *ResourceEnd;
217     ACPI_RS_LENGTH          TotalSize;
218
219
220     ACPI_FUNCTION_TRACE (RsGetAmlLength);
221
222
223     /* Traverse entire list of internal resource descriptors */
224
225     ResourceEnd = ACPI_ADD_PTR (ACPI_RESOURCE, Resource, ResourceListSize);
226     while (Resource < ResourceEnd)
227     {
228         /* Validate the descriptor type */
229
230         if (Resource->Type > ACPI_RESOURCE_TYPE_MAX)
231         {
232             return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE);
233         }
234
235         /* Sanity check the length. It must not be zero, or we loop forever */
236
237         if (!Resource->Length)
238         {
239             return_ACPI_STATUS (AE_AML_BAD_RESOURCE_LENGTH);
240         }
241
242         /* Get the base size of the (external stream) resource descriptor */
243
244         TotalSize = AcpiGbl_AmlResourceSizes [Resource->Type];
245
246         /*
247          * Augment the base size for descriptors with optional and/or
248          * variable-length fields
249          */
250         switch (Resource->Type)
251         {
252         case ACPI_RESOURCE_TYPE_IRQ:
253
254             /* Length can be 3 or 2 */
255
256             if (Resource->Data.Irq.DescriptorLength == 2)
257             {
258                 TotalSize--;
259             }
260             break;
261
262
263         case ACPI_RESOURCE_TYPE_START_DEPENDENT:
264
265             /* Length can be 1 or 0 */
266
267             if (Resource->Data.Irq.DescriptorLength == 0)
268             {
269                 TotalSize--;
270             }
271             break;
272
273
274         case ACPI_RESOURCE_TYPE_VENDOR:
275             /*
276              * Vendor Defined Resource:
277              * For a Vendor Specific resource, if the Length is between 1 and 7
278              * it will be created as a Small Resource data type, otherwise it
279              * is a Large Resource data type.
280              */
281             if (Resource->Data.Vendor.ByteLength > 7)
282             {
283                 /* Base size of a Large resource descriptor */
284
285                 TotalSize = sizeof (AML_RESOURCE_LARGE_HEADER);
286             }
287
288             /* Add the size of the vendor-specific data */
289
290             TotalSize = (ACPI_RS_LENGTH)
291                 (TotalSize + Resource->Data.Vendor.ByteLength);
292             break;
293
294
295         case ACPI_RESOURCE_TYPE_END_TAG:
296             /*
297              * End Tag:
298              * We are done -- return the accumulated total size.
299              */
300             *SizeNeeded = AmlSizeNeeded + TotalSize;
301
302             /* Normal exit */
303
304             return_ACPI_STATUS (AE_OK);
305
306
307         case ACPI_RESOURCE_TYPE_ADDRESS16:
308             /*
309              * 16-Bit Address Resource:
310              * Add the size of the optional ResourceSource info
311              */
312             TotalSize = (ACPI_RS_LENGTH)
313                 (TotalSize + AcpiRsStructOptionLength (
314                                 &Resource->Data.Address16.ResourceSource));
315             break;
316
317
318         case ACPI_RESOURCE_TYPE_ADDRESS32:
319             /*
320              * 32-Bit Address Resource:
321              * Add the size of the optional ResourceSource info
322              */
323             TotalSize = (ACPI_RS_LENGTH)
324                 (TotalSize + AcpiRsStructOptionLength (
325                                 &Resource->Data.Address32.ResourceSource));
326             break;
327
328
329         case ACPI_RESOURCE_TYPE_ADDRESS64:
330             /*
331              * 64-Bit Address Resource:
332              * Add the size of the optional ResourceSource info
333              */
334             TotalSize = (ACPI_RS_LENGTH)
335                 (TotalSize + AcpiRsStructOptionLength (
336                                 &Resource->Data.Address64.ResourceSource));
337             break;
338
339
340         case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
341             /*
342              * Extended IRQ Resource:
343              * Add the size of each additional optional interrupt beyond the
344              * required 1 (4 bytes for each UINT32 interrupt number)
345              */
346             TotalSize = (ACPI_RS_LENGTH)
347                 (TotalSize +
348                 ((Resource->Data.ExtendedIrq.InterruptCount - 1) * 4) +
349
350                 /* Add the size of the optional ResourceSource info */
351
352                 AcpiRsStructOptionLength (
353                     &Resource->Data.ExtendedIrq.ResourceSource));
354             break;
355
356
357         case ACPI_RESOURCE_TYPE_GPIO:
358
359             TotalSize = (ACPI_RS_LENGTH) (TotalSize + (Resource->Data.Gpio.PinTableLength * 2) +
360                 Resource->Data.Gpio.ResourceSource.StringLength +
361                 Resource->Data.Gpio.VendorLength);
362
363             break;
364
365
366         case ACPI_RESOURCE_TYPE_SERIAL_BUS:
367
368             TotalSize = AcpiGbl_AmlResourceSerialBusSizes [Resource->Data.CommonSerialBus.Type];
369
370             TotalSize = (ACPI_RS_LENGTH) (TotalSize +
371                 Resource->Data.I2cSerialBus.ResourceSource.StringLength +
372                 Resource->Data.I2cSerialBus.VendorLength);
373
374             break;
375
376         default:
377
378             break;
379         }
380
381         /* Update the total */
382
383         AmlSizeNeeded += TotalSize;
384
385         /* Point to the next object */
386
387         Resource = ACPI_ADD_PTR (ACPI_RESOURCE, Resource, Resource->Length);
388     }
389
390     /* Did not find an EndTag resource descriptor */
391
392     return_ACPI_STATUS (AE_AML_NO_RESOURCE_END_TAG);
393 }
394
395
396 /*******************************************************************************
397  *
398  * FUNCTION:    AcpiRsGetListLength
399  *
400  * PARAMETERS:  AmlBuffer           - Pointer to the resource byte stream
401  *              AmlBufferLength     - Size of AmlBuffer
402  *              SizeNeeded          - Where the size needed is returned
403  *
404  * RETURN:      Status
405  *
406  * DESCRIPTION: Takes an external resource byte stream and calculates the size
407  *              buffer needed to hold the corresponding internal resource
408  *              descriptor linked list.
409  *
410  ******************************************************************************/
411
412 ACPI_STATUS
413 AcpiRsGetListLength (
414     UINT8                   *AmlBuffer,
415     UINT32                  AmlBufferLength,
416     ACPI_SIZE               *SizeNeeded)
417 {
418     ACPI_STATUS             Status;
419     UINT8                   *EndAml;
420     UINT8                   *Buffer;
421     UINT32                  BufferSize;
422     UINT16                  Temp16;
423     UINT16                  ResourceLength;
424     UINT32                  ExtraStructBytes;
425     UINT8                   ResourceIndex;
426     UINT8                   MinimumAmlResourceLength;
427     AML_RESOURCE            *AmlResource;
428
429
430     ACPI_FUNCTION_TRACE (RsGetListLength);
431
432
433     *SizeNeeded = ACPI_RS_SIZE_MIN;         /* Minimum size is one EndTag */
434     EndAml = AmlBuffer + AmlBufferLength;
435
436     /* Walk the list of AML resource descriptors */
437
438     while (AmlBuffer < EndAml)
439     {
440         /* Validate the Resource Type and Resource Length */
441
442         Status = AcpiUtValidateResource (NULL, AmlBuffer, &ResourceIndex);
443         if (ACPI_FAILURE (Status))
444         {
445             /*
446              * Exit on failure. Cannot continue because the descriptor length
447              * may be bogus also.
448              */
449             return_ACPI_STATUS (Status);
450         }
451
452         AmlResource = (void *) AmlBuffer;
453
454         /* Get the resource length and base (minimum) AML size */
455
456         ResourceLength = AcpiUtGetResourceLength (AmlBuffer);
457         MinimumAmlResourceLength = AcpiGbl_ResourceAmlSizes[ResourceIndex];
458
459         /*
460          * Augment the size for descriptors with optional
461          * and/or variable length fields
462          */
463         ExtraStructBytes = 0;
464         Buffer = AmlBuffer + AcpiUtGetResourceHeaderLength (AmlBuffer);
465
466         switch (AcpiUtGetResourceType (AmlBuffer))
467         {
468         case ACPI_RESOURCE_NAME_IRQ:
469             /*
470              * IRQ Resource:
471              * Get the number of bits set in the 16-bit IRQ mask
472              */
473             ACPI_MOVE_16_TO_16 (&Temp16, Buffer);
474             ExtraStructBytes = AcpiRsCountSetBits (Temp16);
475             break;
476
477
478         case ACPI_RESOURCE_NAME_DMA:
479             /*
480              * DMA Resource:
481              * Get the number of bits set in the 8-bit DMA mask
482              */
483             ExtraStructBytes = AcpiRsCountSetBits (*Buffer);
484             break;
485
486
487         case ACPI_RESOURCE_NAME_VENDOR_SMALL:
488         case ACPI_RESOURCE_NAME_VENDOR_LARGE:
489             /*
490              * Vendor Resource:
491              * Get the number of vendor data bytes
492              */
493             ExtraStructBytes = ResourceLength;
494
495             /*
496              * There is already one byte included in the minimum
497              * descriptor size. If there are extra struct bytes,
498              * subtract one from the count.
499              */
500             if (ExtraStructBytes)
501             {
502                 ExtraStructBytes--;
503             }
504             break;
505
506
507         case ACPI_RESOURCE_NAME_END_TAG:
508             /*
509              * End Tag: This is the normal exit
510              */
511             return_ACPI_STATUS (AE_OK);
512
513
514         case ACPI_RESOURCE_NAME_ADDRESS32:
515         case ACPI_RESOURCE_NAME_ADDRESS16:
516         case ACPI_RESOURCE_NAME_ADDRESS64:
517             /*
518              * Address Resource:
519              * Add the size of the optional ResourceSource
520              */
521             ExtraStructBytes = AcpiRsStreamOptionLength (
522                 ResourceLength, MinimumAmlResourceLength);
523             break;
524
525
526         case ACPI_RESOURCE_NAME_EXTENDED_IRQ:
527             /*
528              * Extended IRQ Resource:
529              * Using the InterruptTableLength, add 4 bytes for each additional
530              * interrupt. Note: at least one interrupt is required and is
531              * included in the minimum descriptor size (reason for the -1)
532              */
533             ExtraStructBytes = (Buffer[1] - 1) * sizeof (UINT32);
534
535             /* Add the size of the optional ResourceSource */
536
537             ExtraStructBytes += AcpiRsStreamOptionLength (
538                 ResourceLength - ExtraStructBytes, MinimumAmlResourceLength);
539             break;
540
541         case ACPI_RESOURCE_NAME_GPIO:
542
543             /* Vendor data is optional */
544
545             if (AmlResource->Gpio.VendorLength)
546             {
547                 ExtraStructBytes += AmlResource->Gpio.VendorOffset -
548                     AmlResource->Gpio.PinTableOffset + AmlResource->Gpio.VendorLength;
549             }
550             else
551             {
552                 ExtraStructBytes += AmlResource->LargeHeader.ResourceLength +
553                     sizeof (AML_RESOURCE_LARGE_HEADER) -
554                     AmlResource->Gpio.PinTableOffset;
555             }
556             break;
557
558         case ACPI_RESOURCE_NAME_SERIAL_BUS:
559
560             MinimumAmlResourceLength = AcpiGbl_ResourceAmlSerialBusSizes[
561                 AmlResource->CommonSerialBus.Type];
562             ExtraStructBytes += AmlResource->CommonSerialBus.ResourceLength -
563                 MinimumAmlResourceLength;
564             break;
565
566         default:
567
568             break;
569         }
570
571         /*
572          * Update the required buffer size for the internal descriptor structs
573          *
574          * Important: Round the size up for the appropriate alignment. This
575          * is a requirement on IA64.
576          */
577         if (AcpiUtGetResourceType (AmlBuffer) == ACPI_RESOURCE_NAME_SERIAL_BUS)
578         {
579             BufferSize = AcpiGbl_ResourceStructSerialBusSizes[
580                 AmlResource->CommonSerialBus.Type] + ExtraStructBytes;
581         }
582         else
583         {
584             BufferSize = AcpiGbl_ResourceStructSizes[ResourceIndex] +
585                         ExtraStructBytes;
586         }
587         BufferSize = (UINT32) ACPI_ROUND_UP_TO_NATIVE_WORD (BufferSize);
588
589         *SizeNeeded += BufferSize;
590
591         ACPI_DEBUG_PRINT ((ACPI_DB_RESOURCES,
592             "Type %.2X, AmlLength %.2X InternalLength %.2X\n",
593             AcpiUtGetResourceType (AmlBuffer),
594             AcpiUtGetDescriptorLength (AmlBuffer), BufferSize));
595
596         /*
597          * Point to the next resource within the AML stream using the length
598          * contained in the resource descriptor header
599          */
600         AmlBuffer += AcpiUtGetDescriptorLength (AmlBuffer);
601     }
602
603     /* Did not find an EndTag resource descriptor */
604
605     return_ACPI_STATUS (AE_AML_NO_RESOURCE_END_TAG);
606 }
607
608
609 /*******************************************************************************
610  *
611  * FUNCTION:    AcpiRsGetPciRoutingTableLength
612  *
613  * PARAMETERS:  PackageObject           - Pointer to the package object
614  *              BufferSizeNeeded        - UINT32 pointer of the size buffer
615  *                                        needed to properly return the
616  *                                        parsed data
617  *
618  * RETURN:      Status
619  *
620  * DESCRIPTION: Given a package representing a PCI routing table, this
621  *              calculates the size of the corresponding linked list of
622  *              descriptions.
623  *
624  ******************************************************************************/
625
626 ACPI_STATUS
627 AcpiRsGetPciRoutingTableLength (
628     ACPI_OPERAND_OBJECT     *PackageObject,
629     ACPI_SIZE               *BufferSizeNeeded)
630 {
631     UINT32                  NumberOfElements;
632     ACPI_SIZE               TempSizeNeeded = 0;
633     ACPI_OPERAND_OBJECT     **TopObjectList;
634     UINT32                  Index;
635     ACPI_OPERAND_OBJECT     *PackageElement;
636     ACPI_OPERAND_OBJECT     **SubObjectList;
637     BOOLEAN                 NameFound;
638     UINT32                  TableIndex;
639
640
641     ACPI_FUNCTION_TRACE (RsGetPciRoutingTableLength);
642
643
644     NumberOfElements = PackageObject->Package.Count;
645
646     /*
647      * Calculate the size of the return buffer.
648      * The base size is the number of elements * the sizes of the
649      * structures. Additional space for the strings is added below.
650      * The minus one is to subtract the size of the UINT8 Source[1]
651      * member because it is added below.
652      *
653      * But each PRT_ENTRY structure has a pointer to a string and
654      * the size of that string must be found.
655      */
656     TopObjectList = PackageObject->Package.Elements;
657
658     for (Index = 0; Index < NumberOfElements; Index++)
659     {
660         /* Dereference the subpackage */
661
662         PackageElement = *TopObjectList;
663
664         /* We must have a valid Package object */
665
666         if (!PackageElement ||
667             (PackageElement->Common.Type != ACPI_TYPE_PACKAGE))
668         {
669             return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
670         }
671
672         /*
673          * The SubObjectList will now point to an array of the
674          * four IRQ elements: Address, Pin, Source and SourceIndex
675          */
676         SubObjectList = PackageElement->Package.Elements;
677
678         /* Scan the IrqTableElements for the Source Name String */
679
680         NameFound = FALSE;
681
682         for (TableIndex = 0;
683              TableIndex < PackageElement->Package.Count && !NameFound;
684              TableIndex++)
685         {
686             if (*SubObjectList && /* Null object allowed */
687
688                 ((ACPI_TYPE_STRING ==
689                     (*SubObjectList)->Common.Type) ||
690
691                 ((ACPI_TYPE_LOCAL_REFERENCE ==
692                     (*SubObjectList)->Common.Type) &&
693
694                     ((*SubObjectList)->Reference.Class ==
695                         ACPI_REFCLASS_NAME))))
696             {
697                 NameFound = TRUE;
698             }
699             else
700             {
701                 /* Look at the next element */
702
703                 SubObjectList++;
704             }
705         }
706
707         TempSizeNeeded += (sizeof (ACPI_PCI_ROUTING_TABLE) - 4);
708
709         /* Was a String type found? */
710
711         if (NameFound)
712         {
713             if ((*SubObjectList)->Common.Type == ACPI_TYPE_STRING)
714             {
715                 /*
716                  * The length String.Length field does not include the
717                  * terminating NULL, add 1
718                  */
719                 TempSizeNeeded += ((ACPI_SIZE)
720                     (*SubObjectList)->String.Length + 1);
721             }
722             else
723             {
724                 TempSizeNeeded += AcpiNsGetPathnameLength (
725                                     (*SubObjectList)->Reference.Node);
726             }
727         }
728         else
729         {
730             /*
731              * If no name was found, then this is a NULL, which is
732              * translated as a UINT32 zero.
733              */
734             TempSizeNeeded += sizeof (UINT32);
735         }
736
737         /* Round up the size since each element must be aligned */
738
739         TempSizeNeeded = ACPI_ROUND_UP_TO_64BIT (TempSizeNeeded);
740
741         /* Point to the next ACPI_OPERAND_OBJECT */
742
743         TopObjectList++;
744     }
745
746     /*
747      * Add an extra element to the end of the list, essentially a
748      * NULL terminator
749      */
750     *BufferSizeNeeded = TempSizeNeeded + sizeof (ACPI_PCI_ROUTING_TABLE);
751     return_ACPI_STATUS (AE_OK);
752 }