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
AcpiRsCountSetBits(UINT16 BitField)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
AcpiRsStructOptionLength(ACPI_RESOURCE_SOURCE * ResourceSource)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
AcpiRsStreamOptionLength(UINT32 ResourceLength,UINT32 MinimumAmlResourceLength)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
AcpiRsGetAmlLength(ACPI_RESOURCE * Resource,ACPI_SIZE ResourceListSize,ACPI_SIZE * SizeNeeded)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
AcpiRsGetListLength(UINT8 * AmlBuffer,UINT32 AmlBufferLength,ACPI_SIZE * SizeNeeded)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
AcpiRsGetPciRoutingTableLength(ACPI_OPERAND_OBJECT * PackageObject,ACPI_SIZE * BufferSizeNeeded)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 }
753