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