ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

rscalc.c
Go to the documentation of this file.
00001 /*******************************************************************************
00002  *
00003  * Module Name: rscalc - Calculate stream and list lengths
00004  *
00005  ******************************************************************************/
00006 
00007 /******************************************************************************
00008  *
00009  * 1. Copyright Notice
00010  *
00011  * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
00012  * All rights reserved.
00013  *
00014  * 2. License
00015  *
00016  * 2.1. This is your license from Intel Corp. under its intellectual property
00017  * rights.  You may have additional license terms from the party that provided
00018  * you this software, covering your right to use that party's intellectual
00019  * property rights.
00020  *
00021  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
00022  * copy of the source code appearing in this file ("Covered Code") an
00023  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
00024  * base code distributed originally by Intel ("Original Intel Code") to copy,
00025  * make derivatives, distribute, use and display any portion of the Covered
00026  * Code in any form, with the right to sublicense such rights; and
00027  *
00028  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
00029  * license (with the right to sublicense), under only those claims of Intel
00030  * patents that are infringed by the Original Intel Code, to make, use, sell,
00031  * offer to sell, and import the Covered Code and derivative works thereof
00032  * solely to the minimum extent necessary to exercise the above copyright
00033  * license, and in no event shall the patent license extend to any additions
00034  * to or modifications of the Original Intel Code.  No other license or right
00035  * is granted directly or by implication, estoppel or otherwise;
00036  *
00037  * The above copyright and patent license is granted only if the following
00038  * conditions are met:
00039  *
00040  * 3. Conditions
00041  *
00042  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
00043  * Redistribution of source code of any substantial portion of the Covered
00044  * Code or modification with rights to further distribute source must include
00045  * the above Copyright Notice, the above License, this list of Conditions,
00046  * and the following Disclaimer and Export Compliance provision.  In addition,
00047  * Licensee must cause all Covered Code to which Licensee contributes to
00048  * contain a file documenting the changes Licensee made to create that Covered
00049  * Code and the date of any change.  Licensee must include in that file the
00050  * documentation of any changes made by any predecessor Licensee.  Licensee
00051  * must include a prominent statement that the modification is derived,
00052  * directly or indirectly, from Original Intel Code.
00053  *
00054  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
00055  * Redistribution of source code of any substantial portion of the Covered
00056  * Code or modification without rights to further distribute source must
00057  * include the following Disclaimer and Export Compliance provision in the
00058  * documentation and/or other materials provided with distribution.  In
00059  * addition, Licensee may not authorize further sublicense of source of any
00060  * portion of the Covered Code, and must include terms to the effect that the
00061  * license from Licensee to its licensee is limited to the intellectual
00062  * property embodied in the software Licensee provides to its licensee, and
00063  * not to intellectual property embodied in modifications its licensee may
00064  * make.
00065  *
00066  * 3.3. Redistribution of Executable. Redistribution in executable form of any
00067  * substantial portion of the Covered Code or modification must reproduce the
00068  * above Copyright Notice, and the following Disclaimer and Export Compliance
00069  * provision in the documentation and/or other materials provided with the
00070  * distribution.
00071  *
00072  * 3.4. Intel retains all right, title, and interest in and to the Original
00073  * Intel Code.
00074  *
00075  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
00076  * Intel shall be used in advertising or otherwise to promote the sale, use or
00077  * other dealings in products derived from or relating to the Covered Code
00078  * without prior written authorization from Intel.
00079  *
00080  * 4. Disclaimer and Export Compliance
00081  *
00082  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
00083  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
00084  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
00085  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
00086  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
00087  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
00088  * PARTICULAR PURPOSE.
00089  *
00090  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
00091  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
00092  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
00093  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
00094  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
00095  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
00096  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
00097  * LIMITED REMEDY.
00098  *
00099  * 4.3. Licensee shall not export, either directly or indirectly, any of this
00100  * software or system incorporating such software without first obtaining any
00101  * required license or other approval from the U. S. Department of Commerce or
00102  * any other agency or department of the United States Government.  In the
00103  * event Licensee exports any such software from the United States or
00104  * re-exports any such software from a foreign destination, Licensee shall
00105  * ensure that the distribution and export/re-export of the software is in
00106  * compliance with all laws, regulations, orders, or other restrictions of the
00107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
00108  * any of its subsidiaries will export/re-export any technical data, process,
00109  * software, or service, directly or indirectly, to any country for which the
00110  * United States government or any agency thereof requires an export license,
00111  * other governmental approval, or letter of assurance, without first obtaining
00112  * such license, approval or letter.
00113  *
00114  *****************************************************************************/
00115 
00116 #define __RSCALC_C__
00117 
00118 #include "acpi.h"
00119 #include "accommon.h"
00120 #include "acresrc.h"
00121 #include "acnamesp.h"
00122 
00123 
00124 #define _COMPONENT          ACPI_RESOURCES
00125         ACPI_MODULE_NAME    ("rscalc")
00126 
00127 
00128 /* Local prototypes */
00129 
00130 static UINT8
00131 AcpiRsCountSetBits (
00132     UINT16                  BitField);
00133 
00134 static ACPI_RS_LENGTH
00135 AcpiRsStructOptionLength (
00136     ACPI_RESOURCE_SOURCE    *ResourceSource);
00137 
00138 static UINT32
00139 AcpiRsStreamOptionLength (
00140     UINT32                  ResourceLength,
00141     UINT32                  MinimumTotalLength);
00142 
00143 
00144 /*******************************************************************************
00145  *
00146  * FUNCTION:    AcpiRsCountSetBits
00147  *
00148  * PARAMETERS:  BitField        - Field in which to count bits
00149  *
00150  * RETURN:      Number of bits set within the field
00151  *
00152  * DESCRIPTION: Count the number of bits set in a resource field. Used for
00153  *              (Short descriptor) interrupt and DMA lists.
00154  *
00155  ******************************************************************************/
00156 
00157 static UINT8
00158 AcpiRsCountSetBits (
00159     UINT16                  BitField)
00160 {
00161     UINT8                   BitsSet;
00162 
00163 
00164     ACPI_FUNCTION_ENTRY ();
00165 
00166 
00167     for (BitsSet = 0; BitField; BitsSet++)
00168     {
00169         /* Zero the least significant bit that is set */
00170 
00171         BitField &= (UINT16) (BitField - 1);
00172     }
00173 
00174     return (BitsSet);
00175 }
00176 
00177 
00178 /*******************************************************************************
00179  *
00180  * FUNCTION:    AcpiRsStructOptionLength
00181  *
00182  * PARAMETERS:  ResourceSource      - Pointer to optional descriptor field
00183  *
00184  * RETURN:      Status
00185  *
00186  * DESCRIPTION: Common code to handle optional ResourceSourceIndex and
00187  *              ResourceSource fields in some Large descriptors. Used during
00188  *              list-to-stream conversion
00189  *
00190  ******************************************************************************/
00191 
00192 static ACPI_RS_LENGTH
00193 AcpiRsStructOptionLength (
00194     ACPI_RESOURCE_SOURCE    *ResourceSource)
00195 {
00196     ACPI_FUNCTION_ENTRY ();
00197 
00198 
00199     /*
00200      * If the ResourceSource string is valid, return the size of the string
00201      * (StringLength includes the NULL terminator) plus the size of the
00202      * ResourceSourceIndex (1).
00203      */
00204     if (ResourceSource->StringPtr)
00205     {
00206         return ((ACPI_RS_LENGTH) (ResourceSource->StringLength + 1));
00207     }
00208 
00209     return (0);
00210 }
00211 
00212 
00213 /*******************************************************************************
00214  *
00215  * FUNCTION:    AcpiRsStreamOptionLength
00216  *
00217  * PARAMETERS:  ResourceLength      - Length from the resource header
00218  *              MinimumTotalLength  - Minimum length of this resource, before
00219  *                                    any optional fields. Includes header size
00220  *
00221  * RETURN:      Length of optional string (0 if no string present)
00222  *
00223  * DESCRIPTION: Common code to handle optional ResourceSourceIndex and
00224  *              ResourceSource fields in some Large descriptors. Used during
00225  *              stream-to-list conversion
00226  *
00227  ******************************************************************************/
00228 
00229 static UINT32
00230 AcpiRsStreamOptionLength (
00231     UINT32                  ResourceLength,
00232     UINT32                  MinimumAmlResourceLength)
00233 {
00234     UINT32                  StringLength = 0;
00235 
00236 
00237     ACPI_FUNCTION_ENTRY ();
00238 
00239 
00240     /*
00241      * The ResourceSourceIndex and ResourceSource are optional elements of some
00242      * Large-type resource descriptors.
00243      */
00244 
00245     /*
00246      * If the length of the actual resource descriptor is greater than the ACPI
00247      * spec-defined minimum length, it means that a ResourceSourceIndex exists
00248      * and is followed by a (required) null terminated string. The string length
00249      * (including the null terminator) is the resource length minus the minimum
00250      * length, minus one byte for the ResourceSourceIndex itself.
00251      */
00252     if (ResourceLength > MinimumAmlResourceLength)
00253     {
00254         /* Compute the length of the optional string */
00255 
00256         StringLength = ResourceLength - MinimumAmlResourceLength - 1;
00257     }
00258 
00259     /*
00260      * Round the length up to a multiple of the native word in order to
00261      * guarantee that the entire resource descriptor is native word aligned
00262      */
00263     return ((UINT32) ACPI_ROUND_UP_TO_NATIVE_WORD (StringLength));
00264 }
00265 
00266 
00267 /*******************************************************************************
00268  *
00269  * FUNCTION:    AcpiRsGetAmlLength
00270  *
00271  * PARAMETERS:  Resource            - Pointer to the resource linked list
00272  *              SizeNeeded          - Where the required size is returned
00273  *
00274  * RETURN:      Status
00275  *
00276  * DESCRIPTION: Takes a linked list of internal resource descriptors and
00277  *              calculates the size buffer needed to hold the corresponding
00278  *              external resource byte stream.
00279  *
00280  ******************************************************************************/
00281 
00282 ACPI_STATUS
00283 AcpiRsGetAmlLength (
00284     ACPI_RESOURCE           *Resource,
00285     ACPI_SIZE               *SizeNeeded)
00286 {
00287     ACPI_SIZE               AmlSizeNeeded = 0;
00288     ACPI_RS_LENGTH          TotalSize;
00289 
00290 
00291     ACPI_FUNCTION_TRACE (RsGetAmlLength);
00292 
00293 
00294     /* Traverse entire list of internal resource descriptors */
00295 
00296     while (Resource)
00297     {
00298         /* Validate the descriptor type */
00299 
00300         if (Resource->Type > ACPI_RESOURCE_TYPE_MAX)
00301         {
00302             return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE);
00303         }
00304 
00305         /* Get the base size of the (external stream) resource descriptor */
00306 
00307         TotalSize = AcpiGbl_AmlResourceSizes [Resource->Type];
00308 
00309         /*
00310          * Augment the base size for descriptors with optional and/or
00311          * variable-length fields
00312          */
00313         switch (Resource->Type)
00314         {
00315         case ACPI_RESOURCE_TYPE_IRQ:
00316 
00317             /* Length can be 3 or 2 */
00318 
00319             if (Resource->Data.Irq.DescriptorLength == 2)
00320             {
00321                 TotalSize--;
00322             }
00323             break;
00324 
00325 
00326         case ACPI_RESOURCE_TYPE_START_DEPENDENT:
00327 
00328             /* Length can be 1 or 0 */
00329 
00330             if (Resource->Data.Irq.DescriptorLength == 0)
00331             {
00332                 TotalSize--;
00333             }
00334             break;
00335 
00336 
00337         case ACPI_RESOURCE_TYPE_VENDOR:
00338             /*
00339              * Vendor Defined Resource:
00340              * For a Vendor Specific resource, if the Length is between 1 and 7
00341              * it will be created as a Small Resource data type, otherwise it
00342              * is a Large Resource data type.
00343              */
00344             if (Resource->Data.Vendor.ByteLength > 7)
00345             {
00346                 /* Base size of a Large resource descriptor */
00347 
00348                 TotalSize = sizeof (AML_RESOURCE_LARGE_HEADER);
00349             }
00350 
00351             /* Add the size of the vendor-specific data */
00352 
00353             TotalSize = (ACPI_RS_LENGTH)
00354                 (TotalSize + Resource->Data.Vendor.ByteLength);
00355             break;
00356 
00357 
00358         case ACPI_RESOURCE_TYPE_END_TAG:
00359             /*
00360              * End Tag:
00361              * We are done -- return the accumulated total size.
00362              */
00363             *SizeNeeded = AmlSizeNeeded + TotalSize;
00364 
00365             /* Normal exit */
00366 
00367             return_ACPI_STATUS (AE_OK);
00368 
00369 
00370         case ACPI_RESOURCE_TYPE_ADDRESS16:
00371             /*
00372              * 16-Bit Address Resource:
00373              * Add the size of the optional ResourceSource info
00374              */
00375             TotalSize = (ACPI_RS_LENGTH)
00376                 (TotalSize + AcpiRsStructOptionLength (
00377                                 &Resource->Data.Address16.ResourceSource));
00378             break;
00379 
00380 
00381         case ACPI_RESOURCE_TYPE_ADDRESS32:
00382             /*
00383              * 32-Bit Address Resource:
00384              * Add the size of the optional ResourceSource info
00385              */
00386             TotalSize = (ACPI_RS_LENGTH)
00387                 (TotalSize + AcpiRsStructOptionLength (
00388                                 &Resource->Data.Address32.ResourceSource));
00389             break;
00390 
00391 
00392         case ACPI_RESOURCE_TYPE_ADDRESS64:
00393             /*
00394              * 64-Bit Address Resource:
00395              * Add the size of the optional ResourceSource info
00396              */
00397             TotalSize = (ACPI_RS_LENGTH)
00398                 (TotalSize + AcpiRsStructOptionLength (
00399                                 &Resource->Data.Address64.ResourceSource));
00400             break;
00401 
00402 
00403         case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
00404             /*
00405              * Extended IRQ Resource:
00406              * Add the size of each additional optional interrupt beyond the
00407              * required 1 (4 bytes for each UINT32 interrupt number)
00408              */
00409             TotalSize = (ACPI_RS_LENGTH)
00410                 (TotalSize +
00411                 ((Resource->Data.ExtendedIrq.InterruptCount - 1) * 4) +
00412 
00413                 /* Add the size of the optional ResourceSource info */
00414 
00415                 AcpiRsStructOptionLength (
00416                     &Resource->Data.ExtendedIrq.ResourceSource));
00417             break;
00418 
00419 
00420         default:
00421             break;
00422         }
00423 
00424         /* Update the total */
00425 
00426         AmlSizeNeeded += TotalSize;
00427 
00428         /* Point to the next object */
00429 
00430         Resource = ACPI_ADD_PTR (ACPI_RESOURCE, Resource, Resource->Length);
00431     }
00432 
00433     /* Did not find an EndTag resource descriptor */
00434 
00435     return_ACPI_STATUS (AE_AML_NO_RESOURCE_END_TAG);
00436 }
00437 
00438 
00439 /*******************************************************************************
00440  *
00441  * FUNCTION:    AcpiRsGetListLength
00442  *
00443  * PARAMETERS:  AmlBuffer           - Pointer to the resource byte stream
00444  *              AmlBufferLength     - Size of AmlBuffer
00445  *              SizeNeeded          - Where the size needed is returned
00446  *
00447  * RETURN:      Status
00448  *
00449  * DESCRIPTION: Takes an external resource byte stream and calculates the size
00450  *              buffer needed to hold the corresponding internal resource
00451  *              descriptor linked list.
00452  *
00453  ******************************************************************************/
00454 
00455 ACPI_STATUS
00456 AcpiRsGetListLength (
00457     UINT8                   *AmlBuffer,
00458     UINT32                  AmlBufferLength,
00459     ACPI_SIZE               *SizeNeeded)
00460 {
00461     ACPI_STATUS             Status;
00462     UINT8                   *EndAml;
00463     UINT8                   *Buffer;
00464     UINT32                  BufferSize;
00465     UINT16                  Temp16;
00466     UINT16                  ResourceLength;
00467     UINT32                  ExtraStructBytes;
00468     UINT8                   ResourceIndex;
00469     UINT8                   MinimumAmlResourceLength;
00470 
00471 
00472     ACPI_FUNCTION_TRACE (RsGetListLength);
00473 
00474 
00475     *SizeNeeded = 0;
00476     EndAml = AmlBuffer + AmlBufferLength;
00477 
00478     /* Walk the list of AML resource descriptors */
00479 
00480     while (AmlBuffer < EndAml)
00481     {
00482         /* Validate the Resource Type and Resource Length */
00483 
00484         Status = AcpiUtValidateResource (AmlBuffer, &ResourceIndex);
00485         if (ACPI_FAILURE (Status))
00486         {
00487             return_ACPI_STATUS (Status);
00488         }
00489 
00490         /* Get the resource length and base (minimum) AML size */
00491 
00492         ResourceLength = AcpiUtGetResourceLength (AmlBuffer);
00493         MinimumAmlResourceLength = AcpiGbl_ResourceAmlSizes[ResourceIndex];
00494 
00495         /*
00496          * Augment the size for descriptors with optional
00497          * and/or variable length fields
00498          */
00499         ExtraStructBytes = 0;
00500         Buffer = AmlBuffer + AcpiUtGetResourceHeaderLength (AmlBuffer);
00501 
00502         switch (AcpiUtGetResourceType (AmlBuffer))
00503         {
00504         case ACPI_RESOURCE_NAME_IRQ:
00505             /*
00506              * IRQ Resource:
00507              * Get the number of bits set in the 16-bit IRQ mask
00508              */
00509             ACPI_MOVE_16_TO_16 (&Temp16, Buffer);
00510             ExtraStructBytes = AcpiRsCountSetBits (Temp16);
00511             break;
00512 
00513 
00514         case ACPI_RESOURCE_NAME_DMA:
00515             /*
00516              * DMA Resource:
00517              * Get the number of bits set in the 8-bit DMA mask
00518              */
00519             ExtraStructBytes = AcpiRsCountSetBits (*Buffer);
00520             break;
00521 
00522 
00523         case ACPI_RESOURCE_NAME_VENDOR_SMALL:
00524         case ACPI_RESOURCE_NAME_VENDOR_LARGE:
00525             /*
00526              * Vendor Resource:
00527              * Get the number of vendor data bytes
00528              */
00529             ExtraStructBytes = ResourceLength;
00530             break;
00531 
00532 
00533         case ACPI_RESOURCE_NAME_END_TAG:
00534             /*
00535              * End Tag:
00536              * This is the normal exit, add size of EndTag
00537              */
00538             *SizeNeeded += ACPI_RS_SIZE_MIN;
00539             return_ACPI_STATUS (AE_OK);
00540 
00541 
00542         case ACPI_RESOURCE_NAME_ADDRESS32:
00543         case ACPI_RESOURCE_NAME_ADDRESS16:
00544         case ACPI_RESOURCE_NAME_ADDRESS64:
00545             /*
00546              * Address Resource:
00547              * Add the size of the optional ResourceSource
00548              */
00549             ExtraStructBytes = AcpiRsStreamOptionLength (
00550                 ResourceLength, MinimumAmlResourceLength);
00551             break;
00552 
00553 
00554         case ACPI_RESOURCE_NAME_EXTENDED_IRQ:
00555             /*
00556              * Extended IRQ Resource:
00557              * Using the InterruptTableLength, add 4 bytes for each additional
00558              * interrupt. Note: at least one interrupt is required and is
00559              * included in the minimum descriptor size (reason for the -1)
00560              */
00561             ExtraStructBytes = (Buffer[1] - 1) * sizeof (UINT32);
00562 
00563             /* Add the size of the optional ResourceSource */
00564 
00565             ExtraStructBytes += AcpiRsStreamOptionLength (
00566                 ResourceLength - ExtraStructBytes, MinimumAmlResourceLength);
00567             break;
00568 
00569 
00570         default:
00571             break;
00572         }
00573 
00574         /*
00575          * Update the required buffer size for the internal descriptor structs
00576          *
00577          * Important: Round the size up for the appropriate alignment. This
00578          * is a requirement on IA64.
00579          */
00580         BufferSize = AcpiGbl_ResourceStructSizes[ResourceIndex] +
00581                         ExtraStructBytes;
00582         BufferSize = (UINT32) ACPI_ROUND_UP_TO_NATIVE_WORD (BufferSize);
00583 
00584         *SizeNeeded += BufferSize;
00585 
00586         ACPI_DEBUG_PRINT ((ACPI_DB_RESOURCES,
00587             "Type %.2X, AmlLength %.2X InternalLength %.2X\n",
00588             AcpiUtGetResourceType (AmlBuffer),
00589             AcpiUtGetDescriptorLength (AmlBuffer), BufferSize));
00590 
00591         /*
00592          * Point to the next resource within the AML stream using the length
00593          * contained in the resource descriptor header
00594          */
00595         AmlBuffer += AcpiUtGetDescriptorLength (AmlBuffer);
00596     }
00597 
00598     /* Did not find an EndTag resource descriptor */
00599 
00600     return_ACPI_STATUS (AE_AML_NO_RESOURCE_END_TAG);
00601 }
00602 
00603 
00604 /*******************************************************************************
00605  *
00606  * FUNCTION:    AcpiRsGetPciRoutingTableLength
00607  *
00608  * PARAMETERS:  PackageObject           - Pointer to the package object
00609  *              BufferSizeNeeded        - UINT32 pointer of the size buffer
00610  *                                        needed to properly return the
00611  *                                        parsed data
00612  *
00613  * RETURN:      Status
00614  *
00615  * DESCRIPTION: Given a package representing a PCI routing table, this
00616  *              calculates the size of the corresponding linked list of
00617  *              descriptions.
00618  *
00619  ******************************************************************************/
00620 
00621 ACPI_STATUS
00622 AcpiRsGetPciRoutingTableLength (
00623     ACPI_OPERAND_OBJECT     *PackageObject,
00624     ACPI_SIZE               *BufferSizeNeeded)
00625 {
00626     UINT32                  NumberOfElements;
00627     ACPI_SIZE               TempSizeNeeded = 0;
00628     ACPI_OPERAND_OBJECT     **TopObjectList;
00629     UINT32                  Index;
00630     ACPI_OPERAND_OBJECT     *PackageElement;
00631     ACPI_OPERAND_OBJECT     **SubObjectList;
00632     BOOLEAN                 NameFound;
00633     UINT32                  TableIndex;
00634 
00635 
00636     ACPI_FUNCTION_TRACE (RsGetPciRoutingTableLength);
00637 
00638 
00639     NumberOfElements = PackageObject->Package.Count;
00640 
00641     /*
00642      * Calculate the size of the return buffer.
00643      * The base size is the number of elements * the sizes of the
00644      * structures.  Additional space for the strings is added below.
00645      * The minus one is to subtract the size of the UINT8 Source[1]
00646      * member because it is added below.
00647      *
00648      * But each PRT_ENTRY structure has a pointer to a string and
00649      * the size of that string must be found.
00650      */
00651     TopObjectList = PackageObject->Package.Elements;
00652 
00653     for (Index = 0; Index < NumberOfElements; Index++)
00654     {
00655         /* Dereference the sub-package */
00656 
00657         PackageElement = *TopObjectList;
00658 
00659         /* We must have a valid Package object */
00660 
00661         if (!PackageElement ||
00662             (PackageElement->Common.Type != ACPI_TYPE_PACKAGE))
00663         {
00664             return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
00665         }
00666 
00667         /*
00668          * The SubObjectList will now point to an array of the
00669          * four IRQ elements: Address, Pin, Source and SourceIndex
00670          */
00671         SubObjectList = PackageElement->Package.Elements;
00672 
00673         /* Scan the IrqTableElements for the Source Name String */
00674 
00675         NameFound = FALSE;
00676 
00677         for (TableIndex = 0; TableIndex < 4 && !NameFound; TableIndex++)
00678         {
00679             if (*SubObjectList && /* Null object allowed */
00680 
00681                 ((ACPI_TYPE_STRING ==
00682                     (*SubObjectList)->Common.Type) ||
00683 
00684                 ((ACPI_TYPE_LOCAL_REFERENCE ==
00685                     (*SubObjectList)->Common.Type) &&
00686 
00687                     ((*SubObjectList)->Reference.Class ==
00688                         ACPI_REFCLASS_NAME))))
00689             {
00690                 NameFound = TRUE;
00691             }
00692             else
00693             {
00694                 /* Look at the next element */
00695 
00696                 SubObjectList++;
00697             }
00698         }
00699 
00700         TempSizeNeeded += (sizeof (ACPI_PCI_ROUTING_TABLE) - 4);
00701 
00702         /* Was a String type found? */
00703 
00704         if (NameFound)
00705         {
00706             if ((*SubObjectList)->Common.Type == ACPI_TYPE_STRING)
00707             {
00708                 /*
00709                  * The length String.Length field does not include the
00710                  * terminating NULL, add 1
00711                  */
00712                 TempSizeNeeded += ((ACPI_SIZE)
00713                     (*SubObjectList)->String.Length + 1);
00714             }
00715             else
00716             {
00717                 TempSizeNeeded += AcpiNsGetPathnameLength (
00718                                     (*SubObjectList)->Reference.Node);
00719             }
00720         }
00721         else
00722         {
00723             /*
00724              * If no name was found, then this is a NULL, which is
00725              * translated as a UINT32 zero.
00726              */
00727             TempSizeNeeded += sizeof (UINT32);
00728         }
00729 
00730         /* Round up the size since each element must be aligned */
00731 
00732         TempSizeNeeded = ACPI_ROUND_UP_TO_64BIT (TempSizeNeeded);
00733 
00734         /* Point to the next ACPI_OPERAND_OBJECT */
00735 
00736         TopObjectList++;
00737     }
00738 
00739     /*
00740      * Add an extra element to the end of the list, essentially a
00741      * NULL terminator
00742      */
00743     *BufferSizeNeeded = TempSizeNeeded + sizeof (ACPI_PCI_ROUTING_TABLE);
00744     return_ACPI_STATUS (AE_OK);
00745 }

Generated on Sat May 26 2012 04:25:55 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.