Home | History | Annotate | Line # | Download | only in utilities
utobject.c revision 1.1.1.5
      1 /******************************************************************************
      2  *
      3  * Module Name: utobject - ACPI object create/delete/size/cache routines
      4  *
      5  *****************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2015, Intel Corp.
      9  * All rights reserved.
     10  *
     11  * Redistribution and use in source and binary forms, with or without
     12  * modification, are permitted provided that the following conditions
     13  * are met:
     14  * 1. Redistributions of source code must retain the above copyright
     15  *    notice, this list of conditions, and the following disclaimer,
     16  *    without modification.
     17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
     18  *    substantially similar to the "NO WARRANTY" disclaimer below
     19  *    ("Disclaimer") and any redistribution must be conditioned upon
     20  *    including a substantially similar Disclaimer requirement for further
     21  *    binary redistribution.
     22  * 3. Neither the names of the above-listed copyright holders nor the names
     23  *    of any contributors may be used to endorse or promote products derived
     24  *    from this software without specific prior written permission.
     25  *
     26  * Alternatively, this software may be distributed under the terms of the
     27  * GNU General Public License ("GPL") version 2 as published by the Free
     28  * Software Foundation.
     29  *
     30  * NO WARRANTY
     31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
     34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
     40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     41  * POSSIBILITY OF SUCH DAMAGES.
     42  */
     43 
     44 #include "acpi.h"
     45 #include "accommon.h"
     46 #include "acnamesp.h"
     47 
     48 
     49 #define _COMPONENT          ACPI_UTILITIES
     50         ACPI_MODULE_NAME    ("utobject")
     51 
     52 /* Local prototypes */
     53 
     54 static ACPI_STATUS
     55 AcpiUtGetSimpleObjectSize (
     56     ACPI_OPERAND_OBJECT     *Obj,
     57     ACPI_SIZE               *ObjLength);
     58 
     59 static ACPI_STATUS
     60 AcpiUtGetPackageObjectSize (
     61     ACPI_OPERAND_OBJECT     *Obj,
     62     ACPI_SIZE               *ObjLength);
     63 
     64 static ACPI_STATUS
     65 AcpiUtGetElementLength (
     66     UINT8                   ObjectType,
     67     ACPI_OPERAND_OBJECT     *SourceObject,
     68     ACPI_GENERIC_STATE      *State,
     69     void                    *Context);
     70 
     71 
     72 /*******************************************************************************
     73  *
     74  * FUNCTION:    AcpiUtCreateInternalObjectDbg
     75  *
     76  * PARAMETERS:  ModuleName          - Source file name of caller
     77  *              LineNumber          - Line number of caller
     78  *              ComponentId         - Component type of caller
     79  *              Type                - ACPI Type of the new object
     80  *
     81  * RETURN:      A new internal object, null on failure
     82  *
     83  * DESCRIPTION: Create and initialize a new internal object.
     84  *
     85  * NOTE:        We always allocate the worst-case object descriptor because
     86  *              these objects are cached, and we want them to be
     87  *              one-size-satisifies-any-request. This in itself may not be
     88  *              the most memory efficient, but the efficiency of the object
     89  *              cache should more than make up for this!
     90  *
     91  ******************************************************************************/
     92 
     93 ACPI_OPERAND_OBJECT  *
     94 AcpiUtCreateInternalObjectDbg (
     95     const char              *ModuleName,
     96     UINT32                  LineNumber,
     97     UINT32                  ComponentId,
     98     ACPI_OBJECT_TYPE        Type)
     99 {
    100     ACPI_OPERAND_OBJECT     *Object;
    101     ACPI_OPERAND_OBJECT     *SecondObject;
    102 
    103 
    104     ACPI_FUNCTION_TRACE_STR (UtCreateInternalObjectDbg,
    105         AcpiUtGetTypeName (Type));
    106 
    107 
    108     /* Allocate the raw object descriptor */
    109 
    110     Object = AcpiUtAllocateObjectDescDbg (ModuleName, LineNumber, ComponentId);
    111     if (!Object)
    112     {
    113         return_PTR (NULL);
    114     }
    115 
    116     switch (Type)
    117     {
    118     case ACPI_TYPE_REGION:
    119     case ACPI_TYPE_BUFFER_FIELD:
    120     case ACPI_TYPE_LOCAL_BANK_FIELD:
    121 
    122         /* These types require a secondary object */
    123 
    124         SecondObject = AcpiUtAllocateObjectDescDbg (ModuleName,
    125                             LineNumber, ComponentId);
    126         if (!SecondObject)
    127         {
    128             AcpiUtDeleteObjectDesc (Object);
    129             return_PTR (NULL);
    130         }
    131 
    132         SecondObject->Common.Type = ACPI_TYPE_LOCAL_EXTRA;
    133         SecondObject->Common.ReferenceCount = 1;
    134 
    135         /* Link the second object to the first */
    136 
    137         Object->Common.NextObject = SecondObject;
    138         break;
    139 
    140     default:
    141 
    142         /* All others have no secondary object */
    143         break;
    144     }
    145 
    146     /* Save the object type in the object descriptor */
    147 
    148     Object->Common.Type = (UINT8) Type;
    149 
    150     /* Init the reference count */
    151 
    152     Object->Common.ReferenceCount = 1;
    153 
    154     /* Any per-type initialization should go here */
    155 
    156     return_PTR (Object);
    157 }
    158 
    159 
    160 /*******************************************************************************
    161  *
    162  * FUNCTION:    AcpiUtCreatePackageObject
    163  *
    164  * PARAMETERS:  Count               - Number of package elements
    165  *
    166  * RETURN:      Pointer to a new Package object, null on failure
    167  *
    168  * DESCRIPTION: Create a fully initialized package object
    169  *
    170  ******************************************************************************/
    171 
    172 ACPI_OPERAND_OBJECT *
    173 AcpiUtCreatePackageObject (
    174     UINT32                  Count)
    175 {
    176     ACPI_OPERAND_OBJECT     *PackageDesc;
    177     ACPI_OPERAND_OBJECT     **PackageElements;
    178 
    179 
    180     ACPI_FUNCTION_TRACE_U32 (UtCreatePackageObject, Count);
    181 
    182 
    183     /* Create a new Package object */
    184 
    185     PackageDesc = AcpiUtCreateInternalObject (ACPI_TYPE_PACKAGE);
    186     if (!PackageDesc)
    187     {
    188         return_PTR (NULL);
    189     }
    190 
    191     /*
    192      * Create the element array. Count+1 allows the array to be null
    193      * terminated.
    194      */
    195     PackageElements = ACPI_ALLOCATE_ZEROED (
    196                         ((ACPI_SIZE) Count + 1) * sizeof (void *));
    197     if (!PackageElements)
    198     {
    199         ACPI_FREE (PackageDesc);
    200         return_PTR (NULL);
    201     }
    202 
    203     PackageDesc->Package.Count = Count;
    204     PackageDesc->Package.Elements = PackageElements;
    205     return_PTR (PackageDesc);
    206 }
    207 
    208 
    209 /*******************************************************************************
    210  *
    211  * FUNCTION:    AcpiUtCreateIntegerObject
    212  *
    213  * PARAMETERS:  InitialValue        - Initial value for the integer
    214  *
    215  * RETURN:      Pointer to a new Integer object, null on failure
    216  *
    217  * DESCRIPTION: Create an initialized integer object
    218  *
    219  ******************************************************************************/
    220 
    221 ACPI_OPERAND_OBJECT *
    222 AcpiUtCreateIntegerObject (
    223     UINT64                  InitialValue)
    224 {
    225     ACPI_OPERAND_OBJECT     *IntegerDesc;
    226 
    227 
    228     ACPI_FUNCTION_TRACE (UtCreateIntegerObject);
    229 
    230 
    231     /* Create and initialize a new integer object */
    232 
    233     IntegerDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER);
    234     if (!IntegerDesc)
    235     {
    236         return_PTR (NULL);
    237     }
    238 
    239     IntegerDesc->Integer.Value = InitialValue;
    240     return_PTR (IntegerDesc);
    241 }
    242 
    243 
    244 /*******************************************************************************
    245  *
    246  * FUNCTION:    AcpiUtCreateBufferObject
    247  *
    248  * PARAMETERS:  BufferSize             - Size of buffer to be created
    249  *
    250  * RETURN:      Pointer to a new Buffer object, null on failure
    251  *
    252  * DESCRIPTION: Create a fully initialized buffer object
    253  *
    254  ******************************************************************************/
    255 
    256 ACPI_OPERAND_OBJECT *
    257 AcpiUtCreateBufferObject (
    258     ACPI_SIZE               BufferSize)
    259 {
    260     ACPI_OPERAND_OBJECT     *BufferDesc;
    261     UINT8                   *Buffer = NULL;
    262 
    263 
    264     ACPI_FUNCTION_TRACE_U32 (UtCreateBufferObject, BufferSize);
    265 
    266 
    267     /* Create a new Buffer object */
    268 
    269     BufferDesc = AcpiUtCreateInternalObject (ACPI_TYPE_BUFFER);
    270     if (!BufferDesc)
    271     {
    272         return_PTR (NULL);
    273     }
    274 
    275     /* Create an actual buffer only if size > 0 */
    276 
    277     if (BufferSize > 0)
    278     {
    279         /* Allocate the actual buffer */
    280 
    281         Buffer = ACPI_ALLOCATE_ZEROED (BufferSize);
    282         if (!Buffer)
    283         {
    284             ACPI_ERROR ((AE_INFO, "Could not allocate size %u",
    285                 (UINT32) BufferSize));
    286             AcpiUtRemoveReference (BufferDesc);
    287             return_PTR (NULL);
    288         }
    289     }
    290 
    291     /* Complete buffer object initialization */
    292 
    293     BufferDesc->Buffer.Flags |= AOPOBJ_DATA_VALID;
    294     BufferDesc->Buffer.Pointer = Buffer;
    295     BufferDesc->Buffer.Length = (UINT32) BufferSize;
    296 
    297     /* Return the new buffer descriptor */
    298 
    299     return_PTR (BufferDesc);
    300 }
    301 
    302 
    303 /*******************************************************************************
    304  *
    305  * FUNCTION:    AcpiUtCreateStringObject
    306  *
    307  * PARAMETERS:  StringSize          - Size of string to be created. Does not
    308  *                                    include NULL terminator, this is added
    309  *                                    automatically.
    310  *
    311  * RETURN:      Pointer to a new String object
    312  *
    313  * DESCRIPTION: Create a fully initialized string object
    314  *
    315  ******************************************************************************/
    316 
    317 ACPI_OPERAND_OBJECT *
    318 AcpiUtCreateStringObject (
    319     ACPI_SIZE               StringSize)
    320 {
    321     ACPI_OPERAND_OBJECT     *StringDesc;
    322     char                    *String;
    323 
    324 
    325     ACPI_FUNCTION_TRACE_U32 (UtCreateStringObject, StringSize);
    326 
    327 
    328     /* Create a new String object */
    329 
    330     StringDesc = AcpiUtCreateInternalObject (ACPI_TYPE_STRING);
    331     if (!StringDesc)
    332     {
    333         return_PTR (NULL);
    334     }
    335 
    336     /*
    337      * Allocate the actual string buffer -- (Size + 1) for NULL terminator.
    338      * NOTE: Zero-length strings are NULL terminated
    339      */
    340     String = ACPI_ALLOCATE_ZEROED (StringSize + 1);
    341     if (!String)
    342     {
    343         ACPI_ERROR ((AE_INFO, "Could not allocate size %u",
    344             (UINT32) StringSize));
    345         AcpiUtRemoveReference (StringDesc);
    346         return_PTR (NULL);
    347     }
    348 
    349     /* Complete string object initialization */
    350 
    351     StringDesc->String.Pointer = String;
    352     StringDesc->String.Length = (UINT32) StringSize;
    353 
    354     /* Return the new string descriptor */
    355 
    356     return_PTR (StringDesc);
    357 }
    358 
    359 
    360 /*******************************************************************************
    361  *
    362  * FUNCTION:    AcpiUtValidInternalObject
    363  *
    364  * PARAMETERS:  Object              - Object to be validated
    365  *
    366  * RETURN:      TRUE if object is valid, FALSE otherwise
    367  *
    368  * DESCRIPTION: Validate a pointer to be of type ACPI_OPERAND_OBJECT
    369  *
    370  ******************************************************************************/
    371 
    372 BOOLEAN
    373 AcpiUtValidInternalObject (
    374     void                    *Object)
    375 {
    376 
    377     ACPI_FUNCTION_NAME (UtValidInternalObject);
    378 
    379 
    380     /* Check for a null pointer */
    381 
    382     if (!Object)
    383     {
    384         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "**** Null Object Ptr\n"));
    385         return (FALSE);
    386     }
    387 
    388     /* Check the descriptor type field */
    389 
    390     switch (ACPI_GET_DESCRIPTOR_TYPE (Object))
    391     {
    392     case ACPI_DESC_TYPE_OPERAND:
    393 
    394         /* The object appears to be a valid ACPI_OPERAND_OBJECT */
    395 
    396         return (TRUE);
    397 
    398     default:
    399 
    400         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
    401                 "%p is not an ACPI operand obj [%s]\n",
    402                 Object, AcpiUtGetDescriptorName (Object)));
    403         break;
    404     }
    405 
    406     return (FALSE);
    407 }
    408 
    409 
    410 /*******************************************************************************
    411  *
    412  * FUNCTION:    AcpiUtAllocateObjectDescDbg
    413  *
    414  * PARAMETERS:  ModuleName          - Caller's module name (for error output)
    415  *              LineNumber          - Caller's line number (for error output)
    416  *              ComponentId         - Caller's component ID (for error output)
    417  *
    418  * RETURN:      Pointer to newly allocated object descriptor. Null on error
    419  *
    420  * DESCRIPTION: Allocate a new object descriptor. Gracefully handle
    421  *              error conditions.
    422  *
    423  ******************************************************************************/
    424 
    425 void *
    426 AcpiUtAllocateObjectDescDbg (
    427     const char              *ModuleName,
    428     UINT32                  LineNumber,
    429     UINT32                  ComponentId)
    430 {
    431     ACPI_OPERAND_OBJECT     *Object;
    432 
    433 
    434     ACPI_FUNCTION_TRACE (UtAllocateObjectDescDbg);
    435 
    436 
    437     Object = AcpiOsAcquireObject (AcpiGbl_OperandCache);
    438     if (!Object)
    439     {
    440         ACPI_ERROR ((ModuleName, LineNumber,
    441             "Could not allocate an object descriptor"));
    442 
    443         return_PTR (NULL);
    444     }
    445 
    446     /* Mark the descriptor type */
    447 
    448     ACPI_SET_DESCRIPTOR_TYPE (Object, ACPI_DESC_TYPE_OPERAND);
    449 
    450     ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "%p Size %X\n",
    451             Object, (UINT32) sizeof (ACPI_OPERAND_OBJECT)));
    452 
    453     return_PTR (Object);
    454 }
    455 
    456 
    457 /*******************************************************************************
    458  *
    459  * FUNCTION:    AcpiUtDeleteObjectDesc
    460  *
    461  * PARAMETERS:  Object          - An Acpi internal object to be deleted
    462  *
    463  * RETURN:      None.
    464  *
    465  * DESCRIPTION: Free an ACPI object descriptor or add it to the object cache
    466  *
    467  ******************************************************************************/
    468 
    469 void
    470 AcpiUtDeleteObjectDesc (
    471     ACPI_OPERAND_OBJECT     *Object)
    472 {
    473     ACPI_FUNCTION_TRACE_PTR (UtDeleteObjectDesc, Object);
    474 
    475 
    476     /* Object must be of type ACPI_OPERAND_OBJECT */
    477 
    478     if (ACPI_GET_DESCRIPTOR_TYPE (Object) != ACPI_DESC_TYPE_OPERAND)
    479     {
    480         ACPI_ERROR ((AE_INFO,
    481             "%p is not an ACPI Operand object [%s]", Object,
    482             AcpiUtGetDescriptorName (Object)));
    483         return_VOID;
    484     }
    485 
    486     (void) AcpiOsReleaseObject (AcpiGbl_OperandCache, Object);
    487     return_VOID;
    488 }
    489 
    490 
    491 /*******************************************************************************
    492  *
    493  * FUNCTION:    AcpiUtGetSimpleObjectSize
    494  *
    495  * PARAMETERS:  InternalObject     - An ACPI operand object
    496  *              ObjLength          - Where the length is returned
    497  *
    498  * RETURN:      Status
    499  *
    500  * DESCRIPTION: This function is called to determine the space required to
    501  *              contain a simple object for return to an external user.
    502  *
    503  *              The length includes the object structure plus any additional
    504  *              needed space.
    505  *
    506  ******************************************************************************/
    507 
    508 static ACPI_STATUS
    509 AcpiUtGetSimpleObjectSize (
    510     ACPI_OPERAND_OBJECT     *InternalObject,
    511     ACPI_SIZE               *ObjLength)
    512 {
    513     ACPI_SIZE               Length;
    514     ACPI_SIZE               Size;
    515     ACPI_STATUS             Status = AE_OK;
    516 
    517 
    518     ACPI_FUNCTION_TRACE_PTR (UtGetSimpleObjectSize, InternalObject);
    519 
    520 
    521     /* Start with the length of the (external) Acpi object */
    522 
    523     Length = sizeof (ACPI_OBJECT);
    524 
    525     /* A NULL object is allowed, can be a legal uninitialized package element */
    526 
    527     if (!InternalObject)
    528     {
    529         /*
    530          * Object is NULL, just return the length of ACPI_OBJECT
    531          * (A NULL ACPI_OBJECT is an object of all zeroes.)
    532          */
    533         *ObjLength = ACPI_ROUND_UP_TO_NATIVE_WORD (Length);
    534         return_ACPI_STATUS (AE_OK);
    535     }
    536 
    537     /* A Namespace Node should never appear here */
    538 
    539     if (ACPI_GET_DESCRIPTOR_TYPE (InternalObject) == ACPI_DESC_TYPE_NAMED)
    540     {
    541         /* A namespace node should never get here */
    542 
    543         return_ACPI_STATUS (AE_AML_INTERNAL);
    544     }
    545 
    546     /*
    547      * The final length depends on the object type
    548      * Strings and Buffers are packed right up against the parent object and
    549      * must be accessed bytewise or there may be alignment problems on
    550      * certain processors
    551      */
    552     switch (InternalObject->Common.Type)
    553     {
    554     case ACPI_TYPE_STRING:
    555 
    556         Length += (ACPI_SIZE) InternalObject->String.Length + 1;
    557         break;
    558 
    559     case ACPI_TYPE_BUFFER:
    560 
    561         Length += (ACPI_SIZE) InternalObject->Buffer.Length;
    562         break;
    563 
    564     case ACPI_TYPE_INTEGER:
    565     case ACPI_TYPE_PROCESSOR:
    566     case ACPI_TYPE_POWER:
    567 
    568         /* No extra data for these types */
    569 
    570         break;
    571 
    572     case ACPI_TYPE_LOCAL_REFERENCE:
    573 
    574         switch (InternalObject->Reference.Class)
    575         {
    576         case ACPI_REFCLASS_NAME:
    577             /*
    578              * Get the actual length of the full pathname to this object.
    579              * The reference will be converted to the pathname to the object
    580              */
    581             Size = AcpiNsGetPathnameLength (InternalObject->Reference.Node);
    582             if (!Size)
    583             {
    584                 return_ACPI_STATUS (AE_BAD_PARAMETER);
    585             }
    586 
    587             Length += ACPI_ROUND_UP_TO_NATIVE_WORD (Size);
    588             break;
    589 
    590         default:
    591             /*
    592              * No other reference opcodes are supported.
    593              * Notably, Locals and Args are not supported, but this may be
    594              * required eventually.
    595              */
    596             ACPI_ERROR ((AE_INFO, "Cannot convert to external object - "
    597                 "unsupported Reference Class [%s] 0x%X in object %p",
    598                 AcpiUtGetReferenceName (InternalObject),
    599                 InternalObject->Reference.Class, InternalObject));
    600             Status = AE_TYPE;
    601             break;
    602         }
    603         break;
    604 
    605     default:
    606 
    607         ACPI_ERROR ((AE_INFO, "Cannot convert to external object - "
    608             "unsupported type [%s] 0x%X in object %p",
    609             AcpiUtGetObjectTypeName (InternalObject),
    610             InternalObject->Common.Type, InternalObject));
    611         Status = AE_TYPE;
    612         break;
    613     }
    614 
    615     /*
    616      * Account for the space required by the object rounded up to the next
    617      * multiple of the machine word size. This keeps each object aligned
    618      * on a machine word boundary. (preventing alignment faults on some
    619      * machines.)
    620      */
    621     *ObjLength = ACPI_ROUND_UP_TO_NATIVE_WORD (Length);
    622     return_ACPI_STATUS (Status);
    623 }
    624 
    625 
    626 /*******************************************************************************
    627  *
    628  * FUNCTION:    AcpiUtGetElementLength
    629  *
    630  * PARAMETERS:  ACPI_PKG_CALLBACK
    631  *
    632  * RETURN:      Status
    633  *
    634  * DESCRIPTION: Get the length of one package element.
    635  *
    636  ******************************************************************************/
    637 
    638 static ACPI_STATUS
    639 AcpiUtGetElementLength (
    640     UINT8                   ObjectType,
    641     ACPI_OPERAND_OBJECT     *SourceObject,
    642     ACPI_GENERIC_STATE      *State,
    643     void                    *Context)
    644 {
    645     ACPI_STATUS             Status = AE_OK;
    646     ACPI_PKG_INFO           *Info = (ACPI_PKG_INFO *) Context;
    647     ACPI_SIZE               ObjectSpace;
    648 
    649 
    650     switch (ObjectType)
    651     {
    652     case ACPI_COPY_TYPE_SIMPLE:
    653         /*
    654          * Simple object - just get the size (Null object/entry is handled
    655          * here also) and sum it into the running package length
    656          */
    657         Status = AcpiUtGetSimpleObjectSize (SourceObject, &ObjectSpace);
    658         if (ACPI_FAILURE (Status))
    659         {
    660             return (Status);
    661         }
    662 
    663         Info->Length += ObjectSpace;
    664         break;
    665 
    666     case ACPI_COPY_TYPE_PACKAGE:
    667 
    668         /* Package object - nothing much to do here, let the walk handle it */
    669 
    670         Info->NumPackages++;
    671         State->Pkg.ThisTargetObj = NULL;
    672         break;
    673 
    674     default:
    675 
    676         /* No other types allowed */
    677 
    678         return (AE_BAD_PARAMETER);
    679     }
    680 
    681     return (Status);
    682 }
    683 
    684 
    685 /*******************************************************************************
    686  *
    687  * FUNCTION:    AcpiUtGetPackageObjectSize
    688  *
    689  * PARAMETERS:  InternalObject      - An ACPI internal object
    690  *              ObjLength           - Where the length is returned
    691  *
    692  * RETURN:      Status
    693  *
    694  * DESCRIPTION: This function is called to determine the space required to
    695  *              contain a package object for return to an external user.
    696  *
    697  *              This is moderately complex since a package contains other
    698  *              objects including packages.
    699  *
    700  ******************************************************************************/
    701 
    702 static ACPI_STATUS
    703 AcpiUtGetPackageObjectSize (
    704     ACPI_OPERAND_OBJECT     *InternalObject,
    705     ACPI_SIZE               *ObjLength)
    706 {
    707     ACPI_STATUS             Status;
    708     ACPI_PKG_INFO           Info;
    709 
    710 
    711     ACPI_FUNCTION_TRACE_PTR (UtGetPackageObjectSize, InternalObject);
    712 
    713 
    714     Info.Length      = 0;
    715     Info.ObjectSpace = 0;
    716     Info.NumPackages = 1;
    717 
    718     Status = AcpiUtWalkPackageTree (InternalObject, NULL,
    719         AcpiUtGetElementLength, &Info);
    720     if (ACPI_FAILURE (Status))
    721     {
    722         return_ACPI_STATUS (Status);
    723     }
    724 
    725     /*
    726      * We have handled all of the objects in all levels of the package.
    727      * just add the length of the package objects themselves.
    728      * Round up to the next machine word.
    729      */
    730     Info.Length += ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (ACPI_OBJECT)) *
    731                     (ACPI_SIZE) Info.NumPackages;
    732 
    733     /* Return the total package length */
    734 
    735     *ObjLength = Info.Length;
    736     return_ACPI_STATUS (Status);
    737 }
    738 
    739 
    740 /*******************************************************************************
    741  *
    742  * FUNCTION:    AcpiUtGetObjectSize
    743  *
    744  * PARAMETERS:  InternalObject      - An ACPI internal object
    745  *              ObjLength           - Where the length will be returned
    746  *
    747  * RETURN:      Status
    748  *
    749  * DESCRIPTION: This function is called to determine the space required to
    750  *              contain an object for return to an API user.
    751  *
    752  ******************************************************************************/
    753 
    754 ACPI_STATUS
    755 AcpiUtGetObjectSize (
    756     ACPI_OPERAND_OBJECT     *InternalObject,
    757     ACPI_SIZE               *ObjLength)
    758 {
    759     ACPI_STATUS             Status;
    760 
    761 
    762     ACPI_FUNCTION_ENTRY ();
    763 
    764 
    765     if ((ACPI_GET_DESCRIPTOR_TYPE (InternalObject) == ACPI_DESC_TYPE_OPERAND) &&
    766         (InternalObject->Common.Type == ACPI_TYPE_PACKAGE))
    767     {
    768         Status = AcpiUtGetPackageObjectSize (InternalObject, ObjLength);
    769     }
    770     else
    771     {
    772         Status = AcpiUtGetSimpleObjectSize (InternalObject, ObjLength);
    773     }
    774 
    775     return (Status);
    776 }
    777