Path: blob/main/sys/contrib/dev/acpica/components/resources/rscalc.c
48406 views
/*******************************************************************************1*2* Module Name: rscalc - Calculate stream and list lengths3*4******************************************************************************/56/******************************************************************************7*8* 1. Copyright Notice9*10* Some or all of this work - Copyright (c) 1999 - 2025, Intel Corp.11* All rights reserved.12*13* 2. License14*15* 2.1. This is your license from Intel Corp. under its intellectual property16* rights. You may have additional license terms from the party that provided17* you this software, covering your right to use that party's intellectual18* property rights.19*20* 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a21* copy of the source code appearing in this file ("Covered Code") an22* irrevocable, perpetual, worldwide license under Intel's copyrights in the23* base code distributed originally by Intel ("Original Intel Code") to copy,24* make derivatives, distribute, use and display any portion of the Covered25* Code in any form, with the right to sublicense such rights; and26*27* 2.3. Intel grants Licensee a non-exclusive and non-transferable patent28* license (with the right to sublicense), under only those claims of Intel29* patents that are infringed by the Original Intel Code, to make, use, sell,30* offer to sell, and import the Covered Code and derivative works thereof31* solely to the minimum extent necessary to exercise the above copyright32* license, and in no event shall the patent license extend to any additions33* to or modifications of the Original Intel Code. No other license or right34* is granted directly or by implication, estoppel or otherwise;35*36* The above copyright and patent license is granted only if the following37* conditions are met:38*39* 3. Conditions40*41* 3.1. Redistribution of Source with Rights to Further Distribute Source.42* Redistribution of source code of any substantial portion of the Covered43* Code or modification with rights to further distribute source must include44* the above Copyright Notice, the above License, this list of Conditions,45* and the following Disclaimer and Export Compliance provision. In addition,46* Licensee must cause all Covered Code to which Licensee contributes to47* contain a file documenting the changes Licensee made to create that Covered48* Code and the date of any change. Licensee must include in that file the49* documentation of any changes made by any predecessor Licensee. Licensee50* must include a prominent statement that the modification is derived,51* directly or indirectly, from Original Intel Code.52*53* 3.2. Redistribution of Source with no Rights to Further Distribute Source.54* Redistribution of source code of any substantial portion of the Covered55* Code or modification without rights to further distribute source must56* include the following Disclaimer and Export Compliance provision in the57* documentation and/or other materials provided with distribution. In58* addition, Licensee may not authorize further sublicense of source of any59* portion of the Covered Code, and must include terms to the effect that the60* license from Licensee to its licensee is limited to the intellectual61* property embodied in the software Licensee provides to its licensee, and62* not to intellectual property embodied in modifications its licensee may63* make.64*65* 3.3. Redistribution of Executable. Redistribution in executable form of any66* substantial portion of the Covered Code or modification must reproduce the67* above Copyright Notice, and the following Disclaimer and Export Compliance68* provision in the documentation and/or other materials provided with the69* distribution.70*71* 3.4. Intel retains all right, title, and interest in and to the Original72* Intel Code.73*74* 3.5. Neither the name Intel nor any other trademark owned or controlled by75* Intel shall be used in advertising or otherwise to promote the sale, use or76* other dealings in products derived from or relating to the Covered Code77* without prior written authorization from Intel.78*79* 4. Disclaimer and Export Compliance80*81* 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED82* HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE83* IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,84* INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY85* UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY86* IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A87* PARTICULAR PURPOSE.88*89* 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES90* OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR91* COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,92* SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY93* CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL94* HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS95* SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY96* LIMITED REMEDY.97*98* 4.3. Licensee shall not export, either directly or indirectly, any of this99* software or system incorporating such software without first obtaining any100* required license or other approval from the U. S. Department of Commerce or101* any other agency or department of the United States Government. In the102* event Licensee exports any such software from the United States or103* re-exports any such software from a foreign destination, Licensee shall104* ensure that the distribution and export/re-export of the software is in105* compliance with all laws, regulations, orders, or other restrictions of the106* U.S. Export Administration Regulations. Licensee agrees that neither it nor107* any of its subsidiaries will export/re-export any technical data, process,108* software, or service, directly or indirectly, to any country for which the109* United States government or any agency thereof requires an export license,110* other governmental approval, or letter of assurance, without first obtaining111* such license, approval or letter.112*113*****************************************************************************114*115* Alternatively, you may choose to be licensed under the terms of the116* following license:117*118* Redistribution and use in source and binary forms, with or without119* modification, are permitted provided that the following conditions120* are met:121* 1. Redistributions of source code must retain the above copyright122* notice, this list of conditions, and the following disclaimer,123* without modification.124* 2. Redistributions in binary form must reproduce at minimum a disclaimer125* substantially similar to the "NO WARRANTY" disclaimer below126* ("Disclaimer") and any redistribution must be conditioned upon127* including a substantially similar Disclaimer requirement for further128* binary redistribution.129* 3. Neither the names of the above-listed copyright holders nor the names130* of any contributors may be used to endorse or promote products derived131* from this software without specific prior written permission.132*133* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS134* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT135* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR136* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT137* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,138* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT139* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,140* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY141* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT142* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE143* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.144*145* Alternatively, you may choose to be licensed under the terms of the146* GNU General Public License ("GPL") version 2 as published by the Free147* Software Foundation.148*149*****************************************************************************/150151#include <contrib/dev/acpica/include/acpi.h>152#include <contrib/dev/acpica/include/accommon.h>153#include <contrib/dev/acpica/include/acresrc.h>154#include <contrib/dev/acpica/include/acnamesp.h>155156157#define _COMPONENT ACPI_RESOURCES158ACPI_MODULE_NAME ("rscalc")159160161/* Local prototypes */162163static UINT8164AcpiRsCountSetBits (165UINT16 BitField);166167static ACPI_RS_LENGTH168AcpiRsStructOptionLength (169ACPI_RESOURCE_SOURCE *ResourceSource);170171static UINT32172AcpiRsStreamOptionLength (173UINT32 ResourceLength,174UINT32 MinimumTotalLength);175176177/*******************************************************************************178*179* FUNCTION: AcpiRsCountSetBits180*181* PARAMETERS: BitField - Field in which to count bits182*183* RETURN: Number of bits set within the field184*185* DESCRIPTION: Count the number of bits set in a resource field. Used for186* (Short descriptor) interrupt and DMA lists.187*188******************************************************************************/189190static UINT8191AcpiRsCountSetBits (192UINT16 BitField)193{194UINT8 BitsSet;195196197ACPI_FUNCTION_ENTRY ();198199200for (BitsSet = 0; BitField; BitsSet++)201{202/* Zero the least significant bit that is set */203204BitField &= (UINT16) (BitField - 1);205}206207return (BitsSet);208}209210211/*******************************************************************************212*213* FUNCTION: AcpiRsStructOptionLength214*215* PARAMETERS: ResourceSource - Pointer to optional descriptor field216*217* RETURN: Status218*219* DESCRIPTION: Common code to handle optional ResourceSourceIndex and220* ResourceSource fields in some Large descriptors. Used during221* list-to-stream conversion222*223******************************************************************************/224225static ACPI_RS_LENGTH226AcpiRsStructOptionLength (227ACPI_RESOURCE_SOURCE *ResourceSource)228{229ACPI_FUNCTION_ENTRY ();230231232/*233* If the ResourceSource string is valid, return the size of the string234* (StringLength includes the NULL terminator) plus the size of the235* ResourceSourceIndex (1).236*/237if (ResourceSource->StringPtr)238{239return ((ACPI_RS_LENGTH) (ResourceSource->StringLength + 1));240}241242return (0);243}244245246/*******************************************************************************247*248* FUNCTION: AcpiRsStreamOptionLength249*250* PARAMETERS: ResourceLength - Length from the resource header251* MinimumTotalLength - Minimum length of this resource, before252* any optional fields. Includes header size253*254* RETURN: Length of optional string (0 if no string present)255*256* DESCRIPTION: Common code to handle optional ResourceSourceIndex and257* ResourceSource fields in some Large descriptors. Used during258* stream-to-list conversion259*260******************************************************************************/261262static UINT32263AcpiRsStreamOptionLength (264UINT32 ResourceLength,265UINT32 MinimumAmlResourceLength)266{267UINT32 StringLength = 0;268269270ACPI_FUNCTION_ENTRY ();271272273/*274* The ResourceSourceIndex and ResourceSource are optional elements of275* some Large-type resource descriptors.276*/277278/*279* If the length of the actual resource descriptor is greater than the280* ACPI spec-defined minimum length, it means that a ResourceSourceIndex281* exists and is followed by a (required) null terminated string. The282* string length (including the null terminator) is the resource length283* minus the minimum length, minus one byte for the ResourceSourceIndex284* itself.285*/286if (ResourceLength > MinimumAmlResourceLength)287{288/* Compute the length of the optional string */289290StringLength = ResourceLength - MinimumAmlResourceLength - 1;291}292293/*294* Round the length up to a multiple of the native word in order to295* guarantee that the entire resource descriptor is native word aligned296*/297return ((UINT32) ACPI_ROUND_UP_TO_NATIVE_WORD (StringLength));298}299300301/*******************************************************************************302*303* FUNCTION: AcpiRsGetAmlLength304*305* PARAMETERS: Resource - Pointer to the resource linked list306* ResourceListSize - Size of the resource linked list307* SizeNeeded - Where the required size is returned308*309* RETURN: Status310*311* DESCRIPTION: Takes a linked list of internal resource descriptors and312* calculates the size buffer needed to hold the corresponding313* external resource byte stream.314*315******************************************************************************/316317ACPI_STATUS318AcpiRsGetAmlLength (319ACPI_RESOURCE *Resource,320ACPI_SIZE ResourceListSize,321ACPI_SIZE *SizeNeeded)322{323ACPI_SIZE AmlSizeNeeded = 0;324ACPI_RESOURCE *ResourceEnd;325ACPI_RS_LENGTH TotalSize;326327328ACPI_FUNCTION_TRACE (RsGetAmlLength);329330331/* Traverse entire list of internal resource descriptors */332333ResourceEnd = ACPI_ADD_PTR (ACPI_RESOURCE, Resource, ResourceListSize);334while (Resource < ResourceEnd)335{336/* Validate the descriptor type */337338if (Resource->Type > ACPI_RESOURCE_TYPE_MAX)339{340return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE);341}342343/* Sanity check the length. It must not be zero, or we loop forever */344345if (!Resource->Length)346{347return_ACPI_STATUS (AE_AML_BAD_RESOURCE_LENGTH);348}349350/* Get the base size of the (external stream) resource descriptor */351352TotalSize = AcpiGbl_AmlResourceSizes [Resource->Type];353354/*355* Augment the base size for descriptors with optional and/or356* variable-length fields357*/358switch (Resource->Type)359{360case ACPI_RESOURCE_TYPE_IRQ:361362/* Length can be 3 or 2 */363364if (Resource->Data.Irq.DescriptorLength == 2)365{366TotalSize--;367}368break;369370371case ACPI_RESOURCE_TYPE_START_DEPENDENT:372373/* Length can be 1 or 0 */374375if (Resource->Data.Irq.DescriptorLength == 0)376{377TotalSize--;378}379break;380381382case ACPI_RESOURCE_TYPE_VENDOR:383/*384* Vendor Defined Resource:385* For a Vendor Specific resource, if the Length is between 1 and 7386* it will be created as a Small Resource data type, otherwise it387* is a Large Resource data type.388*/389if (Resource->Data.Vendor.ByteLength > 7)390{391/* Base size of a Large resource descriptor */392393TotalSize = sizeof (AML_RESOURCE_LARGE_HEADER);394}395396/* Add the size of the vendor-specific data */397398TotalSize = (ACPI_RS_LENGTH)399(TotalSize + Resource->Data.Vendor.ByteLength);400break;401402403case ACPI_RESOURCE_TYPE_END_TAG:404/*405* End Tag:406* We are done -- return the accumulated total size.407*/408*SizeNeeded = AmlSizeNeeded + TotalSize;409410/* Normal exit */411412return_ACPI_STATUS (AE_OK);413414415case ACPI_RESOURCE_TYPE_ADDRESS16:416/*417* 16-Bit Address Resource:418* Add the size of the optional ResourceSource info419*/420TotalSize = (ACPI_RS_LENGTH) (TotalSize +421AcpiRsStructOptionLength (422&Resource->Data.Address16.ResourceSource));423break;424425426case ACPI_RESOURCE_TYPE_ADDRESS32:427/*428* 32-Bit Address Resource:429* Add the size of the optional ResourceSource info430*/431TotalSize = (ACPI_RS_LENGTH) (TotalSize +432AcpiRsStructOptionLength (433&Resource->Data.Address32.ResourceSource));434break;435436437case ACPI_RESOURCE_TYPE_ADDRESS64:438/*439* 64-Bit Address Resource:440* Add the size of the optional ResourceSource info441*/442TotalSize = (ACPI_RS_LENGTH) (TotalSize +443AcpiRsStructOptionLength (444&Resource->Data.Address64.ResourceSource));445break;446447448case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:449/*450* Extended IRQ Resource:451* Add the size of each additional optional interrupt beyond the452* required 1 (4 bytes for each UINT32 interrupt number)453*/454TotalSize = (ACPI_RS_LENGTH) (TotalSize +455((Resource->Data.ExtendedIrq.InterruptCount - 1) * 4) +456457/* Add the size of the optional ResourceSource info */458459AcpiRsStructOptionLength (460&Resource->Data.ExtendedIrq.ResourceSource));461break;462463464case ACPI_RESOURCE_TYPE_GPIO:465466TotalSize = (ACPI_RS_LENGTH) (TotalSize +467(Resource->Data.Gpio.PinTableLength * 2) +468Resource->Data.Gpio.ResourceSource.StringLength +469Resource->Data.Gpio.VendorLength);470471break;472473case ACPI_RESOURCE_TYPE_PIN_FUNCTION:474475TotalSize = (ACPI_RS_LENGTH) (TotalSize +476(Resource->Data.PinFunction.PinTableLength * 2) +477Resource->Data.PinFunction.ResourceSource.StringLength +478Resource->Data.PinFunction.VendorLength);479480break;481482case ACPI_RESOURCE_TYPE_CLOCK_INPUT:483484TotalSize = (ACPI_RS_LENGTH) (TotalSize +485Resource->Data.ClockInput.ResourceSource.StringLength);486487break;488489490case ACPI_RESOURCE_TYPE_SERIAL_BUS:491492TotalSize = AcpiGbl_AmlResourceSerialBusSizes [493Resource->Data.CommonSerialBus.Type];494495TotalSize = (ACPI_RS_LENGTH) (TotalSize +496Resource->Data.I2cSerialBus.ResourceSource.StringLength +497Resource->Data.I2cSerialBus.VendorLength);498499break;500501case ACPI_RESOURCE_TYPE_PIN_CONFIG:502503TotalSize = (ACPI_RS_LENGTH) (TotalSize +504(Resource->Data.PinConfig.PinTableLength * 2) +505Resource->Data.PinConfig.ResourceSource.StringLength +506Resource->Data.PinConfig.VendorLength);507508break;509510case ACPI_RESOURCE_TYPE_PIN_GROUP:511512TotalSize = (ACPI_RS_LENGTH) (TotalSize +513(Resource->Data.PinGroup.PinTableLength * 2) +514Resource->Data.PinGroup.ResourceLabel.StringLength +515Resource->Data.PinGroup.VendorLength);516517break;518519case ACPI_RESOURCE_TYPE_PIN_GROUP_FUNCTION:520521TotalSize = (ACPI_RS_LENGTH) (TotalSize +522Resource->Data.PinGroupFunction.ResourceSource.StringLength +523Resource->Data.PinGroupFunction.ResourceSourceLabel.StringLength +524Resource->Data.PinGroupFunction.VendorLength);525526break;527528case ACPI_RESOURCE_TYPE_PIN_GROUP_CONFIG:529530TotalSize = (ACPI_RS_LENGTH) (TotalSize +531Resource->Data.PinGroupConfig.ResourceSource.StringLength +532Resource->Data.PinGroupConfig.ResourceSourceLabel.StringLength +533Resource->Data.PinGroupConfig.VendorLength);534535break;536537default:538539break;540}541542/* Update the total */543544AmlSizeNeeded += TotalSize;545546/* Point to the next object */547548Resource = ACPI_ADD_PTR (ACPI_RESOURCE, Resource, Resource->Length);549}550551/* Did not find an EndTag resource descriptor */552553return_ACPI_STATUS (AE_AML_NO_RESOURCE_END_TAG);554}555556557/*******************************************************************************558*559* FUNCTION: AcpiRsGetListLength560*561* PARAMETERS: AmlBuffer - Pointer to the resource byte stream562* AmlBufferLength - Size of AmlBuffer563* SizeNeeded - Where the size needed is returned564*565* RETURN: Status566*567* DESCRIPTION: Takes an external resource byte stream and calculates the size568* buffer needed to hold the corresponding internal resource569* descriptor linked list.570*571******************************************************************************/572573ACPI_STATUS574AcpiRsGetListLength (575UINT8 *AmlBuffer,576UINT32 AmlBufferLength,577ACPI_SIZE *SizeNeeded)578{579ACPI_STATUS Status;580UINT8 *EndAml;581UINT8 *Buffer;582UINT32 BufferSize;583UINT16 Temp16;584UINT16 ResourceLength;585UINT32 ExtraStructBytes;586UINT8 ResourceIndex;587UINT8 MinimumAmlResourceLength;588AML_RESOURCE *AmlResource;589590591ACPI_FUNCTION_TRACE (RsGetListLength);592593594*SizeNeeded = ACPI_RS_SIZE_MIN; /* Minimum size is one EndTag */595EndAml = AmlBuffer + AmlBufferLength;596597/* Walk the list of AML resource descriptors */598599while (AmlBuffer < EndAml)600{601/* Validate the Resource Type and Resource Length */602603Status = AcpiUtValidateResource (NULL, AmlBuffer, &ResourceIndex);604if (ACPI_FAILURE (Status))605{606/*607* Exit on failure. Cannot continue because the descriptor length608* may be bogus also.609*/610return_ACPI_STATUS (Status);611}612613AmlResource = (void *) AmlBuffer;614615/* Get the resource length and base (minimum) AML size */616617ResourceLength = AcpiUtGetResourceLength (AmlBuffer);618MinimumAmlResourceLength = AcpiGbl_ResourceAmlSizes[ResourceIndex];619620/*621* Augment the size for descriptors with optional622* and/or variable length fields623*/624ExtraStructBytes = 0;625Buffer = AmlBuffer + AcpiUtGetResourceHeaderLength (AmlBuffer);626627switch (AcpiUtGetResourceType (AmlBuffer))628{629case ACPI_RESOURCE_NAME_IRQ:630/*631* IRQ Resource:632* Get the number of bits set in the 16-bit IRQ mask633*/634ACPI_MOVE_16_TO_16 (&Temp16, Buffer);635ExtraStructBytes = AcpiRsCountSetBits (Temp16);636break;637638639case ACPI_RESOURCE_NAME_DMA:640/*641* DMA Resource:642* Get the number of bits set in the 8-bit DMA mask643*/644ExtraStructBytes = AcpiRsCountSetBits (*Buffer);645break;646647648case ACPI_RESOURCE_NAME_VENDOR_SMALL:649case ACPI_RESOURCE_NAME_VENDOR_LARGE:650/*651* Vendor Resource:652* Get the number of vendor data bytes653*/654ExtraStructBytes = ResourceLength;655656/*657* There is already one byte included in the minimum658* descriptor size. If there are extra struct bytes,659* subtract one from the count.660*/661if (ExtraStructBytes)662{663ExtraStructBytes--;664}665break;666667668case ACPI_RESOURCE_NAME_END_TAG:669/*670* End Tag: This is the normal exit671*/672return_ACPI_STATUS (AE_OK);673674675case ACPI_RESOURCE_NAME_ADDRESS32:676case ACPI_RESOURCE_NAME_ADDRESS16:677case ACPI_RESOURCE_NAME_ADDRESS64:678/*679* Address Resource:680* Add the size of the optional ResourceSource681*/682ExtraStructBytes = AcpiRsStreamOptionLength (683ResourceLength, MinimumAmlResourceLength);684break;685686687case ACPI_RESOURCE_NAME_EXTENDED_IRQ:688/*689* Extended IRQ Resource:690* Using the InterruptTableLength, add 4 bytes for each additional691* interrupt. Note: at least one interrupt is required and is692* included in the minimum descriptor size (reason for the -1)693*/694ExtraStructBytes = (Buffer[1] - 1) * sizeof (UINT32);695696/* Add the size of the optional ResourceSource */697698ExtraStructBytes += AcpiRsStreamOptionLength (699ResourceLength - ExtraStructBytes, MinimumAmlResourceLength);700break;701702case ACPI_RESOURCE_NAME_GPIO:703704/* Vendor data is optional */705706if (AmlResource->Gpio.VendorLength)707{708ExtraStructBytes +=709AmlResource->Gpio.VendorOffset -710AmlResource->Gpio.PinTableOffset +711AmlResource->Gpio.VendorLength;712}713else714{715ExtraStructBytes +=716AmlResource->LargeHeader.ResourceLength +717sizeof (AML_RESOURCE_LARGE_HEADER) -718AmlResource->Gpio.PinTableOffset;719}720break;721722case ACPI_RESOURCE_NAME_PIN_FUNCTION:723724/* Vendor data is optional */725726if (AmlResource->PinFunction.VendorLength)727{728ExtraStructBytes +=729AmlResource->PinFunction.VendorOffset -730AmlResource->PinFunction.PinTableOffset +731AmlResource->PinFunction.VendorLength;732}733else734{735ExtraStructBytes +=736AmlResource->LargeHeader.ResourceLength +737sizeof (AML_RESOURCE_LARGE_HEADER) -738AmlResource->PinFunction.PinTableOffset;739}740break;741742case ACPI_RESOURCE_NAME_SERIAL_BUS: {743744MinimumAmlResourceLength = AcpiGbl_ResourceAmlSerialBusSizes[745AmlResource->CommonSerialBus.Type];746ExtraStructBytes +=747AmlResource->CommonSerialBus.ResourceLength -748MinimumAmlResourceLength;749break;750}751752case ACPI_RESOURCE_NAME_PIN_CONFIG:753754/* Vendor data is optional */755756if (AmlResource->PinConfig.VendorLength)757{758ExtraStructBytes +=759AmlResource->PinConfig.VendorOffset -760AmlResource->PinConfig.PinTableOffset +761AmlResource->PinConfig.VendorLength;762}763else764{765ExtraStructBytes +=766AmlResource->LargeHeader.ResourceLength +767sizeof (AML_RESOURCE_LARGE_HEADER) -768AmlResource->PinConfig.PinTableOffset;769}770break;771772case ACPI_RESOURCE_NAME_PIN_GROUP:773774ExtraStructBytes +=775AmlResource->PinGroup.VendorOffset -776AmlResource->PinGroup.PinTableOffset +777AmlResource->PinGroup.VendorLength;778779break;780781case ACPI_RESOURCE_NAME_PIN_GROUP_FUNCTION:782783ExtraStructBytes +=784AmlResource->PinGroupFunction.VendorOffset -785AmlResource->PinGroupFunction.ResSourceOffset +786AmlResource->PinGroupFunction.VendorLength;787788break;789790case ACPI_RESOURCE_NAME_PIN_GROUP_CONFIG:791792ExtraStructBytes +=793AmlResource->PinGroupConfig.VendorOffset -794AmlResource->PinGroupConfig.ResSourceOffset +795AmlResource->PinGroupConfig.VendorLength;796797break;798799case ACPI_RESOURCE_NAME_CLOCK_INPUT:800ExtraStructBytes = AcpiRsStreamOptionLength (801ResourceLength, MinimumAmlResourceLength);802803break;804805default:806807break;808}809810/*811* Update the required buffer size for the internal descriptor structs812*813* Important: Round the size up for the appropriate alignment. This814* is a requirement on IA64.815*/816if (AcpiUtGetResourceType (AmlBuffer) ==817ACPI_RESOURCE_NAME_SERIAL_BUS)818{819BufferSize = AcpiGbl_ResourceStructSerialBusSizes[820AmlResource->CommonSerialBus.Type] + ExtraStructBytes;821}822else823{824BufferSize = AcpiGbl_ResourceStructSizes[ResourceIndex] +825ExtraStructBytes;826}827828BufferSize = (UINT32) ACPI_ROUND_UP_TO_NATIVE_WORD (BufferSize);829*SizeNeeded += BufferSize;830831ACPI_DEBUG_PRINT ((ACPI_DB_RESOURCES,832"Type %.2X, AmlLength %.2X InternalLength %.2X%8X\n",833AcpiUtGetResourceType (AmlBuffer),834AcpiUtGetDescriptorLength (AmlBuffer), ACPI_FORMAT_UINT64(*SizeNeeded)));835836/*837* Point to the next resource within the AML stream using the length838* contained in the resource descriptor header839*/840AmlBuffer += AcpiUtGetDescriptorLength (AmlBuffer);841}842843/* Did not find an EndTag resource descriptor */844845return_ACPI_STATUS (AE_AML_NO_RESOURCE_END_TAG);846}847848849/*******************************************************************************850*851* FUNCTION: AcpiRsGetPciRoutingTableLength852*853* PARAMETERS: PackageObject - Pointer to the package object854* BufferSizeNeeded - UINT32 pointer of the size buffer855* needed to properly return the856* parsed data857*858* RETURN: Status859*860* DESCRIPTION: Given a package representing a PCI routing table, this861* calculates the size of the corresponding linked list of862* descriptions.863*864******************************************************************************/865866ACPI_STATUS867AcpiRsGetPciRoutingTableLength (868ACPI_OPERAND_OBJECT *PackageObject,869ACPI_SIZE *BufferSizeNeeded)870{871UINT32 NumberOfElements;872ACPI_SIZE TempSizeNeeded = 0;873ACPI_OPERAND_OBJECT **TopObjectList;874UINT32 Index;875ACPI_OPERAND_OBJECT *PackageElement;876ACPI_OPERAND_OBJECT **SubObjectList;877BOOLEAN NameFound;878UINT32 TableIndex;879880881ACPI_FUNCTION_TRACE (RsGetPciRoutingTableLength);882883884NumberOfElements = PackageObject->Package.Count;885886/*887* Calculate the size of the return buffer.888* The base size is the number of elements * the sizes of the889* structures. Additional space for the strings is added below.890* The minus one is to subtract the size of the UINT8 Source[1]891* member because it is added below.892*893* But each PRT_ENTRY structure has a pointer to a string and894* the size of that string must be found.895*/896TopObjectList = PackageObject->Package.Elements;897898for (Index = 0; Index < NumberOfElements; Index++)899{900/* Dereference the subpackage */901902PackageElement = *TopObjectList;903904/* We must have a valid Package object */905906if (!PackageElement ||907(PackageElement->Common.Type != ACPI_TYPE_PACKAGE))908{909return_ACPI_STATUS (AE_AML_OPERAND_TYPE);910}911912/*913* The SubObjectList will now point to an array of the914* four IRQ elements: Address, Pin, Source and SourceIndex915*/916SubObjectList = PackageElement->Package.Elements;917918/* Scan the IrqTableElements for the Source Name String */919920NameFound = FALSE;921922for (TableIndex = 0;923TableIndex < PackageElement->Package.Count && !NameFound;924TableIndex++)925{926if (*SubObjectList && /* Null object allowed */927928((ACPI_TYPE_STRING ==929(*SubObjectList)->Common.Type) ||930931((ACPI_TYPE_LOCAL_REFERENCE ==932(*SubObjectList)->Common.Type) &&933934((*SubObjectList)->Reference.Class ==935ACPI_REFCLASS_NAME))))936{937NameFound = TRUE;938}939else940{941/* Look at the next element */942943SubObjectList++;944}945}946947TempSizeNeeded += (sizeof (ACPI_PCI_ROUTING_TABLE) - 4);948949/* Was a String type found? */950951if (NameFound)952{953if ((*SubObjectList)->Common.Type == ACPI_TYPE_STRING)954{955/*956* The length String.Length field does not include the957* terminating NULL, add 1958*/959TempSizeNeeded += ((ACPI_SIZE)960(*SubObjectList)->String.Length + 1);961}962else963{964TempSizeNeeded += AcpiNsGetPathnameLength (965(*SubObjectList)->Reference.Node);966}967}968else969{970/*971* If no name was found, then this is a NULL, which is972* translated as a UINT32 zero.973*/974TempSizeNeeded += sizeof (UINT32);975}976977/* Round up the size since each element must be aligned */978979TempSizeNeeded = ACPI_ROUND_UP_TO_64BIT (TempSizeNeeded);980981/* Point to the next ACPI_OPERAND_OBJECT */982983TopObjectList++;984}985986/*987* Add an extra element to the end of the list, essentially a988* NULL terminator989*/990*BufferSizeNeeded = TempSizeNeeded + sizeof (ACPI_PCI_ROUTING_TABLE);991return_ACPI_STATUS (AE_OK);992}993994995