:pserver:cvsanon@mok.lvcm.com:/CVS/ReactOS reactos
[reactos.git] / drivers / bus / acpi / resource / rscalc.c
1 /*******************************************************************************
2  *
3  * Module Name: rscalc - Acpi_rs_calculate_byte_stream_length
4  *                       Acpi_rs_calculate_list_length
5  *              $Revision$
6  *
7  ******************************************************************************/
8
9 /*
10  *  Copyright (C) 2000, 2001 R. Byron Moore
11  *
12  *  This program is free software; you can redistribute it and/or modify
13  *  it under the terms of the GNU General Public License as published by
14  *  the Free Software Foundation; either version 2 of the License, or
15  *  (at your option) any later version.
16  *
17  *  This program is distributed in the hope that it will be useful,
18  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
19  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  *  GNU General Public License for more details.
21  *
22  *  You should have received a copy of the GNU General Public License
23  *  along with this program; if not, write to the Free Software
24  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
25  */
26
27
28 #include "acpi.h"
29 #include "acresrc.h"
30 #include "amlcode.h"
31 #include "acnamesp.h"
32
33 #define _COMPONENT          ACPI_RESOURCES
34          MODULE_NAME         ("rscalc")
35
36
37 /*******************************************************************************
38  *
39  * FUNCTION:    Acpi_rs_calculate_byte_stream_length
40  *
41  * PARAMETERS:  Linked_list         - Pointer to the resource linked list
42  *              Size_needed         - u32 pointer of the size buffer needed
43  *                                      to properly return the parsed data
44  *
45  * RETURN:      Status  AE_OK if okay, else a valid ACPI_STATUS code
46  *
47  * DESCRIPTION: Takes the resource byte stream and parses it once, calculating
48  *              the size buffer needed to hold the linked list that conveys
49  *              the resource data.
50  *
51  ******************************************************************************/
52
53 ACPI_STATUS
54 acpi_rs_calculate_byte_stream_length (
55         RESOURCE                *linked_list,
56         u32                     *size_needed)
57 {
58         u32                     byte_stream_size_needed = 0;
59         u32                     segment_size;
60         EXTENDED_IRQ_RESOURCE   *ex_irq = NULL;
61         u8                      done = FALSE;
62
63
64         while (!done) {
65
66                 /*
67                  * Init the variable that will hold the size to add to the
68                  *  total.
69                  */
70                 segment_size = 0;
71
72                 switch (linked_list->id) {
73                 case irq:
74                         /*
75                          * IRQ Resource
76                          */
77                         /*
78                          * For an IRQ Resource, Byte 3, although optional, will
79                          *  always be created - it holds IRQ information.
80                          */
81                         segment_size = 4;
82                         break;
83
84                 case dma:
85                         /*
86                          * DMA Resource
87                          */
88                         /*
89                          * For this resource the size is static
90                          */
91                         segment_size = 3;
92                         break;
93
94                 case start_dependent_functions:
95                         /*
96                          * Start Dependent Functions Resource
97                          */
98                         /*
99                          * For a Start_dependent_functions Resource, Byte 1,
100                          * although optional, will always be created.
101                          */
102                         segment_size = 2;
103                         break;
104
105                 case end_dependent_functions:
106                         /*
107                          * End Dependent Functions Resource
108                          */
109                         /*
110                          * For this resource the size is static
111                          */
112                         segment_size = 1;
113                         break;
114
115                 case io:
116                         /*
117                          * IO Port Resource
118                          */
119                         /*
120                          * For this resource the size is static
121                          */
122                         segment_size = 8;
123                         break;
124
125                 case fixed_io:
126                         /*
127                          * Fixed IO Port Resource
128                          */
129                         /*
130                          * For this resource the size is static
131                          */
132                         segment_size = 4;
133                         break;
134
135                 case vendor_specific:
136                         /*
137                          * Vendor Defined Resource
138                          */
139                         /*
140                          * For a Vendor Specific resource, if the Length is
141                          *  between 1 and 7 it will be created as a Small
142                          *  Resource data type, otherwise it is a Large
143                          *  Resource data type.
144                          */
145                         if(linked_list->data.vendor_specific.length > 7) {
146                                 segment_size = 3;
147                         }
148                         else {
149                                 segment_size = 1;
150                         }
151                         segment_size +=
152                                 linked_list->data.vendor_specific.length;
153                         break;
154
155                 case end_tag:
156                         /*
157                          * End Tag
158                          */
159                         /*
160                          * For this resource the size is static
161                          */
162                         segment_size = 2;
163                         done = TRUE;
164                         break;
165
166                 case memory24:
167                         /*
168                          * 24-Bit Memory Resource
169                          */
170                         /*
171                          * For this resource the size is static
172                          */
173                         segment_size = 12;
174                         break;
175
176                 case memory32:
177                         /*
178                          * 32-Bit Memory Range Resource
179                          */
180                         /*
181                          * For this resource the size is static
182                          */
183                         segment_size = 20;
184                         break;
185
186                 case fixed_memory32:
187                         /*
188                          * 32-Bit Fixed Memory Resource
189                          */
190                         /*
191                          * For this resource the size is static
192                          */
193                         segment_size = 12;
194                         break;
195
196                 case address16:
197                         /*
198                          * 16-Bit Address Resource
199                          */
200                         /*
201                          * The base size of this byte stream is 16. If a
202                          *  Resource Source string is not NULL, add 1 for
203                          *  the Index + the length of the null terminated
204                          *  string Resource Source + 1 for the null.
205                          */
206                         segment_size = 16;
207
208                         if(NULL != linked_list->data.address16.resource_source) {
209                                 segment_size += (1 +
210                                         linked_list->data.address16.resource_source_string_length);
211                         }
212                         break;
213
214                 case address32:
215                         /*
216                          * 32-Bit Address Resource
217                          */
218                         /*
219                          * The base size of this byte stream is 26. If a Resource
220                          *  Source string is not NULL, add 1 for the Index + the
221                          *  length of the null terminated string Resource Source +
222                          *  1 for the null.
223                          */
224                         segment_size = 26;
225
226                         if(NULL != linked_list->data.address16.resource_source) {
227                                 segment_size += (1 +
228                                         linked_list->data.address16.resource_source_string_length);
229                         }
230                         break;
231
232                 case extended_irq:
233                         /*
234                          * Extended IRQ Resource
235                          */
236                         /*
237                          * The base size of this byte stream is 9. This is for an
238                          *  Interrupt table length of 1.  For each additional
239                          *  interrupt, add 4.
240                          * If a Resource Source string is not NULL, add 1 for the
241                          *  Index + the length of the null terminated string
242                          *  Resource Source + 1 for the null.
243                          */
244                         segment_size = 9;
245
246                         segment_size +=
247                                 (linked_list->data.extended_irq.number_of_interrupts -
248                                  1) * 4;
249
250                         if(NULL != ex_irq->resource_source) {
251                                 segment_size += (1 +
252                                         linked_list->data.extended_irq.resource_source_string_length);
253                         }
254                         break;
255
256                 default:
257                         /*
258                          * If we get here, everything is out of sync,
259                          *  so exit with an error
260                          */
261                         return (AE_AML_ERROR);
262                         break;
263
264                 } /* switch (Linked_list->Id) */
265
266                 /*
267                  * Update the total
268                  */
269                 byte_stream_size_needed += segment_size;
270
271                 /*
272                  * Point to the next object
273                  */
274                 linked_list = (RESOURCE *) ((NATIVE_UINT) linked_list +
275                                   (NATIVE_UINT) linked_list->length);
276         }
277
278         /*
279          * This is the data the caller needs
280          */
281         *size_needed = byte_stream_size_needed;
282
283         return (AE_OK);
284 }
285
286
287 /*******************************************************************************
288  *
289  * FUNCTION:    Acpi_rs_calculate_list_length
290  *
291  * PARAMETERS:  Byte_stream_buffer      - Pointer to the resource byte stream
292  *              Byte_stream_buffer_length - Size of Byte_stream_buffer
293  *              Size_needed             - u32 pointer of the size buffer
294  *                                          needed to properly return the
295  *                                          parsed data
296  *
297  * RETURN:      Status  AE_OK if okay, else a valid ACPI_STATUS code
298  *
299  * DESCRIPTION: Takes the resource byte stream and parses it once, calculating
300  *              the size buffer needed to hold the linked list that conveys
301  *              the resource data.
302  *
303  ******************************************************************************/
304
305 ACPI_STATUS
306 acpi_rs_calculate_list_length (
307         u8                      *byte_stream_buffer,
308         u32                     byte_stream_buffer_length,
309         u32                     *size_needed)
310 {
311         u32                     buffer_size = 0;
312         u32                     bytes_parsed = 0;
313         u8                      number_of_interrupts = 0;
314         u8                      number_of_channels = 0;
315         u8                      resource_type;
316         u32                     structure_size;
317         u32                     bytes_consumed;
318         u8                      *buffer;
319         u8                      temp8;
320         u16                     temp16;
321         u8                      index;
322         u8                      additional_bytes;
323
324
325         while (bytes_parsed < byte_stream_buffer_length) {
326                 /*
327                  * Look at the next byte in the stream
328                  */
329                 resource_type = *byte_stream_buffer;
330
331                 /*
332                  * See if this is a small or large resource
333                  */
334                 if(resource_type & 0x80) {
335                         /*
336                          * Large Resource Type
337                          */
338                         switch (resource_type) {
339                         case MEMORY_RANGE_24:
340                                 /*
341                                  * 24-Bit Memory Resource
342                                  */
343                                 bytes_consumed = 12;
344
345                                 structure_size = sizeof (MEMORY24_RESOURCE) +
346                                                   RESOURCE_LENGTH_NO_DATA;
347                                 break;
348
349                         case LARGE_VENDOR_DEFINED:
350                                 /*
351                                  * Vendor Defined Resource
352                                  */
353                                 buffer = byte_stream_buffer;
354                                 ++buffer;
355
356                                 MOVE_UNALIGNED16_TO_16 (&temp16, buffer);
357                                 bytes_consumed = temp16 + 3;
358
359                                 /*
360                                  * Ensure a 32-bit boundary for the structure
361                                  */
362                                 temp16 = (u16) ROUND_UP_TO_32_bITS (temp16);
363
364                                 structure_size = sizeof (VENDOR_RESOURCE) +
365                                                   RESOURCE_LENGTH_NO_DATA +
366                                                   (temp16 * sizeof (u8));
367                                 break;
368
369                         case MEMORY_RANGE_32:
370                                 /*
371                                  * 32-Bit Memory Range Resource
372                                  */
373
374                                 bytes_consumed = 20;
375
376                                 structure_size = sizeof (MEMORY32_RESOURCE) +
377                                                   RESOURCE_LENGTH_NO_DATA;
378                                 break;
379
380                         case FIXED_MEMORY_RANGE_32:
381                                 /*
382                                  * 32-Bit Fixed Memory Resource
383                                  */
384                                 bytes_consumed = 12;
385
386                                 structure_size = sizeof(FIXED_MEMORY32_RESOURCE) +
387                                                   RESOURCE_LENGTH_NO_DATA;
388                                 break;
389
390                         case DWORD_ADDRESS_SPACE:
391                                 /*
392                                  * 32-Bit Address Resource
393                                  */
394                                 buffer = byte_stream_buffer;
395
396                                 ++buffer;
397                                 MOVE_UNALIGNED16_TO_16 (&temp16, buffer);
398
399                                 bytes_consumed = temp16 + 3;
400
401                                 /*
402                                  * Resource Source Index and Resource Source are
403                                  *  optional elements.  Check the length of the
404                                  *  Bytestream.  If it is greater than 23, that
405                                  *  means that an Index exists and is followed by
406                                  *  a null termininated string.  Therefore, set
407                                  *  the temp variable to the length minus the minimum
408                                  *  byte stream length plus the byte for the Index to
409                                  *  determine the size of the NULL terminiated string.
410                                  */
411                                 if (23 < temp16) {
412                                         temp8 = (u8) (temp16 - 24);
413                                 }
414                                 else {
415                                         temp8 = 0;
416                                 }
417
418                                 /*
419                                  * Ensure a 32-bit boundary for the structure
420                                  */
421                                 temp8 = (u8) ROUND_UP_TO_32_bITS (temp8);
422
423                                 structure_size = sizeof (ADDRESS32_RESOURCE) +
424                                                   RESOURCE_LENGTH_NO_DATA +
425                                                   (temp8 * sizeof (u8));
426                                 break;
427
428                         case WORD_ADDRESS_SPACE:
429                                 /*
430                                  * 16-Bit Address Resource
431                                  */
432                                 buffer = byte_stream_buffer;
433
434                                 ++buffer;
435                                 MOVE_UNALIGNED16_TO_16 (&temp16, buffer);
436
437                                 bytes_consumed = temp16 + 3;
438
439                                 /*
440                                  * Resource Source Index and Resource Source are
441                                  *  optional elements.  Check the length of the
442                                  *  Bytestream.  If it is greater than 13, that
443                                  *  means that an Index exists and is followed by
444                                  *  a null termininated string.  Therefore, set
445                                  *  the temp variable to the length minus the minimum
446                                  *  byte stream length plus the byte for the Index to
447                                  *  determine the size of the NULL terminiated string.
448                                  */
449                                 if (13 < temp16) {
450                                         temp8 = (u8) (temp16 - 14);
451                                 }
452                                 else {
453                                         temp8 = 0;
454                                 }
455
456                                 /*
457                                  * Ensure a 32-bit boundry for the structure
458                                  */
459                                 temp8 = (u8) ROUND_UP_TO_32_bITS (temp8);
460
461                                 structure_size = sizeof (ADDRESS16_RESOURCE) +
462                                                   RESOURCE_LENGTH_NO_DATA +
463                                                   (temp8 * sizeof (u8));
464                                 break;
465
466                         case EXTENDED_IRQ:
467                                 /*
468                                  * Extended IRQ
469                                  */
470                                 buffer = byte_stream_buffer;
471
472                                 ++buffer;
473                                 MOVE_UNALIGNED16_TO_16 (&temp16, buffer);
474
475                                 bytes_consumed = temp16 + 3;
476
477                                 /*
478                                  * Point past the length field and the
479                                  *  Interrupt vector flags to save off the
480                                  *  Interrupt table length to the Temp8 variable.
481                                  */
482                                 buffer += 3;
483                                 temp8 = *buffer;
484
485                                 /*
486                                  * To compensate for multiple interrupt numbers,
487                                  *  Add 4 bytes for each additional interrupts
488                                  *  greater than 1
489                                  */
490                                 additional_bytes = (u8) ((temp8 - 1) * 4);
491
492                                 /*
493                                  * Resource Source Index and Resource Source are
494                                  *  optional elements.  Check the length of the
495                                  *  Bytestream.  If it is greater than 9, that
496                                  *  means that an Index exists and is followed by
497                                  *  a null termininated string.  Therefore, set
498                                  *  the temp variable to the length minus the minimum
499                                  *  byte stream length plus the byte for the Index to
500                                  *  determine the size of the NULL terminiated string.
501                                  */
502                                 if (9 + additional_bytes < temp16) {
503                                         temp8 = (u8) (temp16 - (9 + additional_bytes));
504                                 }
505
506                                 else {
507                                         temp8 = 0;
508                                 }
509
510                                 /*
511                                  * Ensure a 32-bit boundry for the structure
512                                  */
513                                 temp8 = (u8) ROUND_UP_TO_32_bITS (temp8);
514
515                                 structure_size = sizeof (EXTENDED_IRQ_RESOURCE) +
516                                                   RESOURCE_LENGTH_NO_DATA +
517                                                   (additional_bytes * sizeof (u8)) +
518                                                   (temp8 * sizeof (u8));
519
520                                 break;
521
522 /* TBD: [Future] 64-bit not currently supported */
523 /*
524                         case 0x8A:
525                                 break;
526 */
527
528                         default:
529                                 /*
530                                  * If we get here, everything is out of sync,
531                                  *  so exit with an error
532                                  */
533                                 return (AE_AML_ERROR);
534                                 break;
535                         }
536                 }
537
538                 else {
539                         /*
540                          * Small Resource Type
541                          *  Only bits 7:3 are valid
542                          */
543                         resource_type >>= 3;
544
545                         switch (resource_type) {
546                         case IRQ_FORMAT:
547                                 /*
548                                  * IRQ Resource
549                                  */
550                                 /*
551                                  * Determine if it there are two or three
552                                  *  trailing bytes
553                                  */
554                                 buffer = byte_stream_buffer;
555                                 temp8 = *buffer;
556
557                                 if(temp8 & 0x01) {
558                                         bytes_consumed = 4;
559                                 }
560
561                                 else {
562                                         bytes_consumed = 3;
563                                 }
564
565                                 /*
566                                  * Point past the descriptor
567                                  */
568                                 ++buffer;
569
570                                 /*
571                                  * Look at the number of bits set
572                                  */
573                                 MOVE_UNALIGNED16_TO_16 (&temp16, buffer);
574
575                                 for (index = 0; index < 16; index++) {
576                                         if (temp16 & 0x1) {
577                                                 ++number_of_interrupts;
578                                         }
579
580                                         temp16 >>= 1;
581                                 }
582
583                                 structure_size = sizeof (IO_RESOURCE) +
584                                                   RESOURCE_LENGTH_NO_DATA +
585                                                   (number_of_interrupts * sizeof (u32));
586                                 break;
587
588
589                         case DMA_FORMAT:
590
591                                 /*
592                                  * DMA Resource
593                                  */
594                                 buffer = byte_stream_buffer;
595
596                                 bytes_consumed = 3;
597
598                                 /*
599                                  * Point past the descriptor
600                                  */
601                                 ++buffer;
602
603                                 /*
604                                  * Look at the number of bits set
605                                  */
606                                 temp8 = *buffer;
607
608                                 for(index = 0; index < 8; index++) {
609                                         if(temp8 & 0x1) {
610                                                 ++number_of_channels;
611                                         }
612
613                                         temp8 >>= 1;
614                                 }
615
616                                 structure_size = sizeof (DMA_RESOURCE) +
617                                                   RESOURCE_LENGTH_NO_DATA +
618                                                   (number_of_channels * sizeof (u32));
619                                 break;
620
621
622                         case START_DEPENDENT_TAG:
623
624                                 /*
625                                  * Start Dependent Functions Resource
626                                  */
627                                 /*
628                                  * Determine if it there are two or three trailing bytes
629                                  */
630                                 buffer = byte_stream_buffer;
631                                 temp8 = *buffer;
632
633                                 if(temp8 & 0x01) {
634                                         bytes_consumed = 2;
635                                 }
636                                 else {
637                                         bytes_consumed = 1;
638                                 }
639
640
641                                 structure_size =
642                                                 sizeof (START_DEPENDENT_FUNCTIONS_RESOURCE) +
643                                                 RESOURCE_LENGTH_NO_DATA;
644                                 break;
645
646
647                         case END_DEPENDENT_TAG:
648
649                                 /*
650                                  * End Dependent Functions Resource
651                                  */
652                                 bytes_consumed = 1;
653                                 structure_size = RESOURCE_LENGTH;
654                                 break;
655
656
657                         case IO_PORT_DESCRIPTOR:
658                                 /*
659                                  * IO Port Resource
660                                  */
661                                 bytes_consumed = 8;
662                                 structure_size = sizeof (IO_RESOURCE) +
663                                                   RESOURCE_LENGTH_NO_DATA;
664                                 break;
665
666
667                         case FIXED_LOCATION_IO_DESCRIPTOR:
668
669                                 /*
670                                  * Fixed IO Port Resource
671                                  */
672                                 bytes_consumed = 4;
673                                 structure_size = sizeof (FIXED_IO_RESOURCE) +
674                                                   RESOURCE_LENGTH_NO_DATA;
675                                 break;
676
677
678                         case SMALL_VENDOR_DEFINED:
679
680                                 /*
681                                  * Vendor Specific Resource
682                                  */
683                                 buffer = byte_stream_buffer;
684
685                                 temp8 = *buffer;
686                                 temp8 = (u8) (temp8 & 0x7);
687                                 bytes_consumed = temp8 + 1;
688
689                                 /*
690                                  * Ensure a 32-bit boundry for the structure
691                                  */
692                                 temp8 = (u8) ROUND_UP_TO_32_bITS (temp8);
693                                 structure_size = sizeof (VENDOR_RESOURCE) +
694                                                   RESOURCE_LENGTH_NO_DATA +
695                                                   (temp8 * sizeof (u8));
696                                 break;
697
698
699                         case END_TAG:
700
701                                 /*
702                                  * End Tag
703                                  */
704                                 bytes_consumed = 2;
705                                 structure_size = RESOURCE_LENGTH;
706                                 byte_stream_buffer_length = bytes_parsed;
707                                 break;
708
709
710                         default:
711                                 /*
712                                  * If we get here, everything is out of sync,
713                                  *  so exit with an error
714                                  */
715                                 return (AE_AML_ERROR);
716                                 break;
717
718                         } /* switch */
719
720                 }  /* if(Resource_type & 0x80) */
721
722                 /*
723                  * Update the return value and counter
724                  */
725                 buffer_size += structure_size;
726                 bytes_parsed += bytes_consumed;
727
728                 /*
729                  * Set the byte stream to point to the next resource
730                  */
731                 byte_stream_buffer += bytes_consumed;
732
733         }
734
735         /*
736          * This is the data the caller needs
737          */
738         *size_needed = buffer_size;
739
740         return (AE_OK);
741 }
742
743
744 /*******************************************************************************
745  *
746  * FUNCTION:    Acpi_rs_calculate_pci_routing_table_length
747  *
748  * PARAMETERS:  Package_object          - Pointer to the package object
749  *              Buffer_size_needed      - u32 pointer of the size buffer
750  *                                          needed to properly return the
751  *                                          parsed data
752  *
753  * RETURN:      Status  AE_OK
754  *
755  * DESCRIPTION: Given a package representing a PCI routing table, this
756  *                calculates the size of the corresponding linked list of
757  *                descriptions.
758  *
759  ******************************************************************************/
760
761 ACPI_STATUS
762 acpi_rs_calculate_pci_routing_table_length (
763         ACPI_OPERAND_OBJECT     *package_object,
764         u32                     *buffer_size_needed)
765 {
766         u32                     number_of_elements;
767         u32                     temp_size_needed = 0;
768         ACPI_OPERAND_OBJECT     **top_object_list;
769         u32                     index;
770         ACPI_OPERAND_OBJECT     *package_element;
771         ACPI_OPERAND_OBJECT     **sub_object_list;
772         u8                      name_found;
773         u32                     table_index;
774
775
776         number_of_elements = package_object->package.count;
777
778         /*
779          * Calculate the size of the return buffer.
780          * The base size is the number of elements * the sizes of the
781          * structures.  Additional space for the strings is added below.
782          * The minus one is to subtract the size of the u8 Source[1]
783          * member because it is added below.
784          */
785
786         /*
787          * But each PRT_ENTRY structure has a pointer to a string and
788          * the size of that string must be found.
789          */
790         top_object_list = package_object->package.elements;
791
792         for (index = 0; index < number_of_elements; index++) {
793                 /*
794                  * Dereference the sub-package
795                  */
796                 package_element = *top_object_list;
797
798                 /*
799                  * The Sub_object_list will now point to an array of the
800                  * four IRQ elements: Address, Pin, Source and Source_index
801                  */
802                 sub_object_list = package_element->package.elements;
803
804                 /*
805                  * Scan the Irq_table_elements for the Source Name String
806                  */
807                 name_found = FALSE;
808
809                 for (table_index = 0; table_index < 4 && !name_found; table_index++) {
810                         if ((ACPI_TYPE_STRING == (*sub_object_list)->common.type) ||
811                                 ((INTERNAL_TYPE_REFERENCE == (*sub_object_list)->common.type) &&
812                                         ((*sub_object_list)->reference.opcode == AML_NAMEPATH_OP))) {
813                                 name_found = TRUE;
814                         }
815
816                         else {
817                                 /*
818                                  * Look at the next element
819                                  */
820                                 sub_object_list++;
821                         }
822                 }
823
824                 temp_size_needed += (sizeof (PCI_ROUTING_TABLE) - 4);
825
826                 /*
827                  * Was a String type found?
828                  */
829                 if (TRUE == name_found) {
830                         if (ACPI_TYPE_STRING == (*sub_object_list)->common.type) {
831                                 /*
832                                  * The length String.Length field includes the
833                                  * terminating NULL
834                                  */
835                                 temp_size_needed += (*sub_object_list)->string.length;
836                         }
837                         else {
838                                 temp_size_needed += acpi_ns_get_pathname_length ((*sub_object_list)->reference.node);
839                         }
840                 }
841
842                 else {
843                         /*
844                          * If no name was found, then this is a NULL, which is
845                          *  translated as a u32 zero.
846                          */
847                         temp_size_needed += sizeof(u32);
848                 }
849
850
851                 /* Round up the size since each element must be aligned */
852
853                 temp_size_needed = ROUND_UP_TO_64_bITS (temp_size_needed);
854
855                 /*
856                  * Point to the next ACPI_OPERAND_OBJECT
857                  */
858                 top_object_list++;
859         }
860
861
862         /*
863          * Adding an extra element to the end of the list, essentially a NULL terminator
864          */
865         *buffer_size_needed = temp_size_needed + sizeof (PCI_ROUTING_TABLE);
866
867         return (AE_OK);
868 }