1 /******************************************************************************
   2  *
   3  * Module Name: utobject - ACPI object create/delete/size/cache routines
   4  *
   5  *****************************************************************************/
   6 
   7 /*
   8  * Copyright (C) 2000 - 2011, 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 __UTOBJECT_C__
  45 
  46 #include "acpi.h"
  47 #include "accommon.h"
  48 #include "acnamesp.h"
  49 
  50 
  51 #define _COMPONENT          ACPI_UTILITIES
  52         ACPI_MODULE_NAME    ("utobject")
  53 
  54 /* Local prototypes */
  55 
  56 static ACPI_STATUS
  57 AcpiUtGetSimpleObjectSize (
  58     ACPI_OPERAND_OBJECT     *Obj,
  59     ACPI_SIZE               *ObjLength);
  60 
  61 static ACPI_STATUS
  62 AcpiUtGetPackageObjectSize (
  63     ACPI_OPERAND_OBJECT     *Obj,
  64     ACPI_SIZE               *ObjLength);
  65 
  66 static ACPI_STATUS
  67 AcpiUtGetElementLength (
  68     UINT8                   ObjectType,
  69     ACPI_OPERAND_OBJECT     *SourceObject,
  70     ACPI_GENERIC_STATE      *State,
  71     void                    *Context);
  72 
  73 
  74 /*******************************************************************************
  75  *
  76  * FUNCTION:    AcpiUtCreateInternalObjectDbg
  77  *
  78  * PARAMETERS:  ModuleName          - Source file name of caller
  79  *              LineNumber          - Line number of caller
  80  *              ComponentId         - Component type of caller
  81  *              Type                - ACPI Type of the new object
  82  *
  83  * RETURN:      A new internal object, null on failure
  84  *
  85  * DESCRIPTION: Create and initialize a new internal object.
  86  *
  87  * NOTE:        We always allocate the worst-case object descriptor because
  88  *              these objects are cached, and we want them to be
  89  *              one-size-satisifies-any-request.  This in itself may not be
  90  *              the most memory efficient, but the efficiency of the object
  91  *              cache should more than make up for this!
  92  *
  93  ******************************************************************************/
  94 
  95 ACPI_OPERAND_OBJECT  *
  96 AcpiUtCreateInternalObjectDbg (
  97     const char              *ModuleName,
  98     UINT32                  LineNumber,
  99     UINT32                  ComponentId,
 100     ACPI_OBJECT_TYPE        Type)
 101 {
 102     ACPI_OPERAND_OBJECT     *Object;
 103     ACPI_OPERAND_OBJECT     *SecondObject;
 104 
 105 
 106     ACPI_FUNCTION_TRACE_STR (UtCreateInternalObjectDbg,
 107         AcpiUtGetTypeName (Type));
 108 
 109 
 110     /* Allocate the raw object descriptor */
 111 
 112     Object = AcpiUtAllocateObjectDescDbg (ModuleName, LineNumber, ComponentId);
 113     if (!Object)
 114     {
 115         return_PTR (NULL);
 116     }
 117 
 118     switch (Type)
 119     {
 120     case ACPI_TYPE_REGION:
 121     case ACPI_TYPE_BUFFER_FIELD:
 122     case ACPI_TYPE_LOCAL_BANK_FIELD:
 123 
 124         /* These types require a secondary object */
 125 
 126         SecondObject = AcpiUtAllocateObjectDescDbg (ModuleName,
 127                             LineNumber, ComponentId);
 128         if (!SecondObject)
 129         {
 130             AcpiUtDeleteObjectDesc (Object);
 131             return_PTR (NULL);
 132         }
 133 
 134         SecondObject->Common.Type = ACPI_TYPE_LOCAL_EXTRA;
 135         SecondObject->Common.ReferenceCount = 1;
 136 
 137         /* Link the second object to the first */
 138 
 139         Object->Common.NextObject = SecondObject;
 140         break;
 141 
 142     default:
 143         /* All others have no secondary object */
 144         break;
 145     }
 146 
 147     /* Save the object type in the object descriptor */
 148 
 149     Object->Common.Type = (UINT8) Type;
 150 
 151     /* Init the reference count */
 152 
 153     Object->Common.ReferenceCount = 1;
 154 
 155     /* Any per-type initialization should go here */
 156 
 157     return_PTR (Object);
 158 }
 159 
 160 
 161 /*******************************************************************************
 162  *
 163  * FUNCTION:    AcpiUtCreatePackageObject
 164  *
 165  * PARAMETERS:  Count               - Number of package elements
 166  *
 167  * RETURN:      Pointer to a new Package object, null on failure
 168  *
 169  * DESCRIPTION: Create a fully initialized package object
 170  *
 171  ******************************************************************************/
 172 
 173 ACPI_OPERAND_OBJECT *
 174 AcpiUtCreatePackageObject (
 175     UINT32                  Count)
 176 {
 177     ACPI_OPERAND_OBJECT     *PackageDesc;
 178     ACPI_OPERAND_OBJECT     **PackageElements;
 179 
 180 
 181     ACPI_FUNCTION_TRACE_U32 (UtCreatePackageObject, Count);
 182 
 183 
 184     /* Create a new Package object */
 185 
 186     PackageDesc = AcpiUtCreateInternalObject (ACPI_TYPE_PACKAGE);
 187     if (!PackageDesc)
 188     {
 189         return_PTR (NULL);
 190     }
 191 
 192     /*
 193      * Create the element array. Count+1 allows the array to be null
 194      * terminated.
 195      */
 196     PackageElements = ACPI_ALLOCATE_ZEROED (
 197                         ((ACPI_SIZE) Count + 1) * sizeof (void *));
 198     if (!PackageElements)
 199     {
 200         ACPI_FREE (PackageDesc);
 201         return_PTR (NULL);
 202     }
 203 
 204     PackageDesc->Package.Count = Count;
 205     PackageDesc->Package.Elements = PackageElements;
 206     return_PTR (PackageDesc);
 207 }
 208 
 209 
 210 /*******************************************************************************
 211  *
 212  * FUNCTION:    AcpiUtCreateIntegerObject
 213  *
 214  * PARAMETERS:  InitialValue        - Initial value for the integer
 215  *
 216  * RETURN:      Pointer to a new Integer object, null on failure
 217  *
 218  * DESCRIPTION: Create an initialized integer object
 219  *
 220  ******************************************************************************/
 221 
 222 ACPI_OPERAND_OBJECT *
 223 AcpiUtCreateIntegerObject (
 224     UINT64                  InitialValue)
 225 {
 226     ACPI_OPERAND_OBJECT     *IntegerDesc;
 227 
 228 
 229     ACPI_FUNCTION_TRACE (UtCreateIntegerObject);
 230 
 231 
 232     /* Create and initialize a new integer object */
 233 
 234     IntegerDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER);
 235     if (!IntegerDesc)
 236     {
 237         return_PTR (NULL);
 238     }
 239 
 240     IntegerDesc->Integer.Value = InitialValue;
 241     return_PTR (IntegerDesc);
 242 }
 243 
 244 
 245 /*******************************************************************************
 246  *
 247  * FUNCTION:    AcpiUtCreateBufferObject
 248  *
 249  * PARAMETERS:  BufferSize             - Size of buffer to be created
 250  *
 251  * RETURN:      Pointer to a new Buffer object, null on failure
 252  *
 253  * DESCRIPTION: Create a fully initialized buffer object
 254  *
 255  ******************************************************************************/
 256 
 257 ACPI_OPERAND_OBJECT *
 258 AcpiUtCreateBufferObject (
 259     ACPI_SIZE               BufferSize)
 260 {
 261     ACPI_OPERAND_OBJECT     *BufferDesc;
 262     UINT8                   *Buffer = NULL;
 263 
 264 
 265     ACPI_FUNCTION_TRACE_U32 (UtCreateBufferObject, BufferSize);
 266 
 267 
 268     /* Create a new Buffer object */
 269 
 270     BufferDesc = AcpiUtCreateInternalObject (ACPI_TYPE_BUFFER);
 271     if (!BufferDesc)
 272     {
 273         return_PTR (NULL);
 274     }
 275 
 276     /* Create an actual buffer only if size > 0 */
 277 
 278     if (BufferSize > 0)
 279     {
 280         /* Allocate the actual buffer */
 281 
 282         Buffer = ACPI_ALLOCATE_ZEROED (BufferSize);
 283         if (!Buffer)
 284         {
 285             ACPI_ERROR ((AE_INFO, "Could not allocate size %u",
 286                 (UINT32) BufferSize));
 287             AcpiUtRemoveReference (BufferDesc);
 288             return_PTR (NULL);
 289         }
 290     }
 291 
 292     /* Complete buffer object initialization */
 293 
 294     BufferDesc->Buffer.Flags |= AOPOBJ_DATA_VALID;
 295     BufferDesc->Buffer.Pointer = Buffer;
 296     BufferDesc->Buffer.Length = (UINT32) BufferSize;
 297 
 298     /* Return the new buffer descriptor */
 299 
 300     return_PTR (BufferDesc);
 301 }
 302 
 303 
 304 /*******************************************************************************
 305  *
 306  * FUNCTION:    AcpiUtCreateStringObject
 307  *
 308  * PARAMETERS:  StringSize          - Size of string to be created. Does not
 309  *                                    include NULL terminator, this is added
 310  *                                    automatically.
 311  *
 312  * RETURN:      Pointer to a new String object
 313  *
 314  * DESCRIPTION: Create a fully initialized string object
 315  *
 316  ******************************************************************************/
 317 
 318 ACPI_OPERAND_OBJECT *
 319 AcpiUtCreateStringObject (
 320     ACPI_SIZE               StringSize)
 321 {
 322     ACPI_OPERAND_OBJECT     *StringDesc;
 323     char                    *String;
 324 
 325 
 326     ACPI_FUNCTION_TRACE_U32 (UtCreateStringObject, StringSize);
 327 
 328 
 329     /* Create a new String object */
 330 
 331     StringDesc = AcpiUtCreateInternalObject (ACPI_TYPE_STRING);
 332     if (!StringDesc)
 333     {
 334         return_PTR (NULL);
 335     }
 336 
 337     /*
 338      * Allocate the actual string buffer -- (Size + 1) for NULL terminator.
 339      * NOTE: Zero-length strings are NULL terminated
 340      */
 341     String = ACPI_ALLOCATE_ZEROED (StringSize + 1);
 342     if (!String)
 343     {
 344         ACPI_ERROR ((AE_INFO, "Could not allocate size %u",
 345             (UINT32) StringSize));
 346         AcpiUtRemoveReference (StringDesc);
 347         return_PTR (NULL);
 348     }
 349 
 350     /* Complete string object initialization */
 351 
 352     StringDesc->String.Pointer = String;
 353     StringDesc->String.Length = (UINT32) StringSize;
 354 
 355     /* Return the new string descriptor */
 356 
 357     return_PTR (StringDesc);
 358 }
 359 
 360 
 361 /*******************************************************************************
 362  *
 363  * FUNCTION:    AcpiUtValidInternalObject
 364  *
 365  * PARAMETERS:  Object              - Object to be validated
 366  *
 367  * RETURN:      TRUE if object is valid, FALSE otherwise
 368  *
 369  * DESCRIPTION: Validate a pointer to be an ACPI_OPERAND_OBJECT
 370  *
 371  ******************************************************************************/
 372 
 373 BOOLEAN
 374 AcpiUtValidInternalObject (
 375     void                    *Object)
 376 {
 377 
 378     ACPI_FUNCTION_NAME (UtValidInternalObject);
 379 
 380 
 381     /* Check for a null pointer */
 382 
 383     if (!Object)
 384     {
 385         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "**** Null Object Ptr\n"));
 386         return (FALSE);
 387     }
 388 
 389     /* Check the descriptor type field */
 390 
 391     switch (ACPI_GET_DESCRIPTOR_TYPE (Object))
 392     {
 393     case ACPI_DESC_TYPE_OPERAND:
 394 
 395         /* The object appears to be a valid ACPI_OPERAND_OBJECT  */
 396 
 397         return (TRUE);
 398 
 399     default:
 400         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
 401                 "%p is not 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 an 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 
 560     case ACPI_TYPE_BUFFER:
 561 
 562         Length += (ACPI_SIZE) InternalObject->Buffer.Length;
 563         break;
 564 
 565 
 566     case ACPI_TYPE_INTEGER:
 567     case ACPI_TYPE_PROCESSOR:
 568     case ACPI_TYPE_POWER:
 569 
 570         /* No extra data for these types */
 571 
 572         break;
 573 
 574 
 575     case ACPI_TYPE_LOCAL_REFERENCE:
 576 
 577         switch (InternalObject->Reference.Class)
 578         {
 579         case ACPI_REFCLASS_NAME:
 580 
 581             /*
 582              * Get the actual length of the full pathname to this object.
 583              * The reference will be converted to the pathname to the object
 584              */
 585             Size = AcpiNsGetPathnameLength (InternalObject->Reference.Node);
 586             if (!Size)
 587             {
 588                 return_ACPI_STATUS (AE_BAD_PARAMETER);
 589             }
 590 
 591             Length += ACPI_ROUND_UP_TO_NATIVE_WORD (Size);
 592             break;
 593 
 594         default:
 595 
 596             /*
 597              * No other reference opcodes are supported.
 598              * Notably, Locals and Args are not supported, but this may be
 599              * required eventually.
 600              */
 601             ACPI_ERROR ((AE_INFO, "Cannot convert to external object - "
 602                 "unsupported Reference Class [%s] 0x%X in object %p",
 603                 AcpiUtGetReferenceName (InternalObject),
 604                 InternalObject->Reference.Class, InternalObject));
 605             Status = AE_TYPE;
 606             break;
 607         }
 608         break;
 609 
 610 
 611     default:
 612 
 613         ACPI_ERROR ((AE_INFO, "Cannot convert to external object - "
 614             "unsupported type [%s] 0x%X in object %p",
 615             AcpiUtGetObjectTypeName (InternalObject),
 616             InternalObject->Common.Type, InternalObject));
 617         Status = AE_TYPE;
 618         break;
 619     }
 620 
 621     /*
 622      * Account for the space required by the object rounded up to the next
 623      * multiple of the machine word size.  This keeps each object aligned
 624      * on a machine word boundary. (preventing alignment faults on some
 625      * machines.)
 626      */
 627     *ObjLength = ACPI_ROUND_UP_TO_NATIVE_WORD (Length);
 628     return_ACPI_STATUS (Status);
 629 }
 630 
 631 
 632 /*******************************************************************************
 633  *
 634  * FUNCTION:    AcpiUtGetElementLength
 635  *
 636  * PARAMETERS:  ACPI_PKG_CALLBACK
 637  *
 638  * RETURN:      Status
 639  *
 640  * DESCRIPTION: Get the length of one package element.
 641  *
 642  ******************************************************************************/
 643 
 644 static ACPI_STATUS
 645 AcpiUtGetElementLength (
 646     UINT8                   ObjectType,
 647     ACPI_OPERAND_OBJECT     *SourceObject,
 648     ACPI_GENERIC_STATE      *State,
 649     void                    *Context)
 650 {
 651     ACPI_STATUS             Status = AE_OK;
 652     ACPI_PKG_INFO           *Info = (ACPI_PKG_INFO *) Context;
 653     ACPI_SIZE               ObjectSpace;
 654 
 655 
 656     switch (ObjectType)
 657     {
 658     case ACPI_COPY_TYPE_SIMPLE:
 659 
 660         /*
 661          * Simple object - just get the size (Null object/entry is handled
 662          * here also) and sum it into the running package length
 663          */
 664         Status = AcpiUtGetSimpleObjectSize (SourceObject, &ObjectSpace);
 665         if (ACPI_FAILURE (Status))
 666         {
 667             return (Status);
 668         }
 669 
 670         Info->Length += ObjectSpace;
 671         break;
 672 
 673 
 674     case ACPI_COPY_TYPE_PACKAGE:
 675 
 676         /* Package object - nothing much to do here, let the walk handle it */
 677 
 678         Info->NumPackages++;
 679         State->Pkg.ThisTargetObj = NULL;
 680         break;
 681 
 682 
 683     default:
 684 
 685         /* No other types allowed */
 686 
 687         return (AE_BAD_PARAMETER);
 688     }
 689 
 690     return (Status);
 691 }
 692 
 693 
 694 /*******************************************************************************
 695  *
 696  * FUNCTION:    AcpiUtGetPackageObjectSize
 697  *
 698  * PARAMETERS:  InternalObject      - An ACPI internal object
 699  *              ObjLength           - Where the length is returned
 700  *
 701  * RETURN:      Status
 702  *
 703  * DESCRIPTION: This function is called to determine the space required to
 704  *              contain a package object for return to an external user.
 705  *
 706  *              This is moderately complex since a package contains other
 707  *              objects including packages.
 708  *
 709  ******************************************************************************/
 710 
 711 static ACPI_STATUS
 712 AcpiUtGetPackageObjectSize (
 713     ACPI_OPERAND_OBJECT     *InternalObject,
 714     ACPI_SIZE               *ObjLength)
 715 {
 716     ACPI_STATUS             Status;
 717     ACPI_PKG_INFO           Info;
 718 
 719 
 720     ACPI_FUNCTION_TRACE_PTR (UtGetPackageObjectSize, InternalObject);
 721 
 722 
 723     Info.Length      = 0;
 724     Info.ObjectSpace = 0;
 725     Info.NumPackages = 1;
 726 
 727     Status = AcpiUtWalkPackageTree (InternalObject, NULL,
 728                             AcpiUtGetElementLength, &Info);
 729     if (ACPI_FAILURE (Status))
 730     {
 731         return_ACPI_STATUS (Status);
 732     }
 733 
 734     /*
 735      * We have handled all of the objects in all levels of the package.
 736      * just add the length of the package objects themselves.
 737      * Round up to the next machine word.
 738      */
 739     Info.Length += ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (ACPI_OBJECT)) *
 740                     (ACPI_SIZE) Info.NumPackages;
 741 
 742     /* Return the total package length */
 743 
 744     *ObjLength = Info.Length;
 745     return_ACPI_STATUS (Status);
 746 }
 747 
 748 
 749 /*******************************************************************************
 750  *
 751  * FUNCTION:    AcpiUtGetObjectSize
 752  *
 753  * PARAMETERS:  InternalObject      - An ACPI internal object
 754  *              ObjLength           - Where the length will be returned
 755  *
 756  * RETURN:      Status
 757  *
 758  * DESCRIPTION: This function is called to determine the space required to
 759  *              contain an object for return to an API user.
 760  *
 761  ******************************************************************************/
 762 
 763 ACPI_STATUS
 764 AcpiUtGetObjectSize (
 765     ACPI_OPERAND_OBJECT     *InternalObject,
 766     ACPI_SIZE               *ObjLength)
 767 {
 768     ACPI_STATUS             Status;
 769 
 770 
 771     ACPI_FUNCTION_ENTRY ();
 772 
 773 
 774     if ((ACPI_GET_DESCRIPTOR_TYPE (InternalObject) == ACPI_DESC_TYPE_OPERAND) &&
 775         (InternalObject->Common.Type == ACPI_TYPE_PACKAGE))
 776     {
 777         Status = AcpiUtGetPackageObjectSize (InternalObject, ObjLength);
 778     }
 779     else
 780     {
 781         Status = AcpiUtGetSimpleObjectSize (InternalObject, ObjLength);
 782     }
 783 
 784     return (Status);
 785 }
 786 
 787