kernel: Sync ACPICA with Intel's version 20140424.
[dragonfly.git] / sys / contrib / dev / acpica / source / components / utilities / utobject.c
1 /******************************************************************************
2  *
3  * Module Name: utobject - ACPI object create/delete/size/cache routines
4  *
5  *****************************************************************************/
6
7 /*
8  * Copyright (C) 2000 - 2014, 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
144         /* All others have no secondary object */
145         break;
146     }
147
148     /* Save the object type in the object descriptor */
149
150     Object->Common.Type = (UINT8) Type;
151
152     /* Init the reference count */
153
154     Object->Common.ReferenceCount = 1;
155
156     /* Any per-type initialization should go here */
157
158     return_PTR (Object);
159 }
160
161
162 /*******************************************************************************
163  *
164  * FUNCTION:    AcpiUtCreatePackageObject
165  *
166  * PARAMETERS:  Count               - Number of package elements
167  *
168  * RETURN:      Pointer to a new Package object, null on failure
169  *
170  * DESCRIPTION: Create a fully initialized package object
171  *
172  ******************************************************************************/
173
174 ACPI_OPERAND_OBJECT *
175 AcpiUtCreatePackageObject (
176     UINT32                  Count)
177 {
178     ACPI_OPERAND_OBJECT     *PackageDesc;
179     ACPI_OPERAND_OBJECT     **PackageElements;
180
181
182     ACPI_FUNCTION_TRACE_U32 (UtCreatePackageObject, Count);
183
184
185     /* Create a new Package object */
186
187     PackageDesc = AcpiUtCreateInternalObject (ACPI_TYPE_PACKAGE);
188     if (!PackageDesc)
189     {
190         return_PTR (NULL);
191     }
192
193     /*
194      * Create the element array. Count+1 allows the array to be null
195      * terminated.
196      */
197     PackageElements = ACPI_ALLOCATE_ZEROED (
198                         ((ACPI_SIZE) Count + 1) * sizeof (void *));
199     if (!PackageElements)
200     {
201         ACPI_FREE (PackageDesc);
202         return_PTR (NULL);
203     }
204
205     PackageDesc->Package.Count = Count;
206     PackageDesc->Package.Elements = PackageElements;
207     return_PTR (PackageDesc);
208 }
209
210
211 /*******************************************************************************
212  *
213  * FUNCTION:    AcpiUtCreateIntegerObject
214  *
215  * PARAMETERS:  InitialValue        - Initial value for the integer
216  *
217  * RETURN:      Pointer to a new Integer object, null on failure
218  *
219  * DESCRIPTION: Create an initialized integer object
220  *
221  ******************************************************************************/
222
223 ACPI_OPERAND_OBJECT *
224 AcpiUtCreateIntegerObject (
225     UINT64                  InitialValue)
226 {
227     ACPI_OPERAND_OBJECT     *IntegerDesc;
228
229
230     ACPI_FUNCTION_TRACE (UtCreateIntegerObject);
231
232
233     /* Create and initialize a new integer object */
234
235     IntegerDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER);
236     if (!IntegerDesc)
237     {
238         return_PTR (NULL);
239     }
240
241     IntegerDesc->Integer.Value = InitialValue;
242     return_PTR (IntegerDesc);
243 }
244
245
246 /*******************************************************************************
247  *
248  * FUNCTION:    AcpiUtCreateBufferObject
249  *
250  * PARAMETERS:  BufferSize             - Size of buffer to be created
251  *
252  * RETURN:      Pointer to a new Buffer object, null on failure
253  *
254  * DESCRIPTION: Create a fully initialized buffer object
255  *
256  ******************************************************************************/
257
258 ACPI_OPERAND_OBJECT *
259 AcpiUtCreateBufferObject (
260     ACPI_SIZE               BufferSize)
261 {
262     ACPI_OPERAND_OBJECT     *BufferDesc;
263     UINT8                   *Buffer = NULL;
264
265
266     ACPI_FUNCTION_TRACE_U32 (UtCreateBufferObject, BufferSize);
267
268
269     /* Create a new Buffer object */
270
271     BufferDesc = AcpiUtCreateInternalObject (ACPI_TYPE_BUFFER);
272     if (!BufferDesc)
273     {
274         return_PTR (NULL);
275     }
276
277     /* Create an actual buffer only if size > 0 */
278
279     if (BufferSize > 0)
280     {
281         /* Allocate the actual buffer */
282
283         Buffer = ACPI_ALLOCATE_ZEROED (BufferSize);
284         if (!Buffer)
285         {
286             ACPI_ERROR ((AE_INFO, "Could not allocate size %u",
287                 (UINT32) BufferSize));
288             AcpiUtRemoveReference (BufferDesc);
289             return_PTR (NULL);
290         }
291     }
292
293     /* Complete buffer object initialization */
294
295     BufferDesc->Buffer.Flags |= AOPOBJ_DATA_VALID;
296     BufferDesc->Buffer.Pointer = Buffer;
297     BufferDesc->Buffer.Length = (UINT32) BufferSize;
298
299     /* Return the new buffer descriptor */
300
301     return_PTR (BufferDesc);
302 }
303
304
305 /*******************************************************************************
306  *
307  * FUNCTION:    AcpiUtCreateStringObject
308  *
309  * PARAMETERS:  StringSize          - Size of string to be created. Does not
310  *                                    include NULL terminator, this is added
311  *                                    automatically.
312  *
313  * RETURN:      Pointer to a new String object
314  *
315  * DESCRIPTION: Create a fully initialized string object
316  *
317  ******************************************************************************/
318
319 ACPI_OPERAND_OBJECT *
320 AcpiUtCreateStringObject (
321     ACPI_SIZE               StringSize)
322 {
323     ACPI_OPERAND_OBJECT     *StringDesc;
324     char                    *String;
325
326
327     ACPI_FUNCTION_TRACE_U32 (UtCreateStringObject, StringSize);
328
329
330     /* Create a new String object */
331
332     StringDesc = AcpiUtCreateInternalObject (ACPI_TYPE_STRING);
333     if (!StringDesc)
334     {
335         return_PTR (NULL);
336     }
337
338     /*
339      * Allocate the actual string buffer -- (Size + 1) for NULL terminator.
340      * NOTE: Zero-length strings are NULL terminated
341      */
342     String = ACPI_ALLOCATE_ZEROED (StringSize + 1);
343     if (!String)
344     {
345         ACPI_ERROR ((AE_INFO, "Could not allocate size %u",
346             (UINT32) StringSize));
347         AcpiUtRemoveReference (StringDesc);
348         return_PTR (NULL);
349     }
350
351     /* Complete string object initialization */
352
353     StringDesc->String.Pointer = String;
354     StringDesc->String.Length = (UINT32) StringSize;
355
356     /* Return the new string descriptor */
357
358     return_PTR (StringDesc);
359 }
360
361
362 /*******************************************************************************
363  *
364  * FUNCTION:    AcpiUtValidInternalObject
365  *
366  * PARAMETERS:  Object              - Object to be validated
367  *
368  * RETURN:      TRUE if object is valid, FALSE otherwise
369  *
370  * DESCRIPTION: Validate a pointer to be of type ACPI_OPERAND_OBJECT
371  *
372  ******************************************************************************/
373
374 BOOLEAN
375 AcpiUtValidInternalObject (
376     void                    *Object)
377 {
378
379     ACPI_FUNCTION_NAME (UtValidInternalObject);
380
381
382     /* Check for a null pointer */
383
384     if (!Object)
385     {
386         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "**** Null Object Ptr\n"));
387         return (FALSE);
388     }
389
390     /* Check the descriptor type field */
391
392     switch (ACPI_GET_DESCRIPTOR_TYPE (Object))
393     {
394     case ACPI_DESC_TYPE_OPERAND:
395
396         /* The object appears to be a valid ACPI_OPERAND_OBJECT */
397
398         return (TRUE);
399
400     default:
401
402         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
403                 "%p is not an ACPI operand obj [%s]\n",
404                 Object, AcpiUtGetDescriptorName (Object)));
405         break;
406     }
407
408     return (FALSE);
409 }
410
411
412 /*******************************************************************************
413  *
414  * FUNCTION:    AcpiUtAllocateObjectDescDbg
415  *
416  * PARAMETERS:  ModuleName          - Caller's module name (for error output)
417  *              LineNumber          - Caller's line number (for error output)
418  *              ComponentId         - Caller's component ID (for error output)
419  *
420  * RETURN:      Pointer to newly allocated object descriptor. Null on error
421  *
422  * DESCRIPTION: Allocate a new object descriptor. Gracefully handle
423  *              error conditions.
424  *
425  ******************************************************************************/
426
427 void *
428 AcpiUtAllocateObjectDescDbg (
429     const char              *ModuleName,
430     UINT32                  LineNumber,
431     UINT32                  ComponentId)
432 {
433     ACPI_OPERAND_OBJECT     *Object;
434
435
436     ACPI_FUNCTION_TRACE (UtAllocateObjectDescDbg);
437
438
439     Object = AcpiOsAcquireObject (AcpiGbl_OperandCache);
440     if (!Object)
441     {
442         ACPI_ERROR ((ModuleName, LineNumber,
443             "Could not allocate an object descriptor"));
444
445         return_PTR (NULL);
446     }
447
448     /* Mark the descriptor type */
449
450     ACPI_SET_DESCRIPTOR_TYPE (Object, ACPI_DESC_TYPE_OPERAND);
451
452     ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "%p Size %X\n",
453             Object, (UINT32) sizeof (ACPI_OPERAND_OBJECT)));
454
455     return_PTR (Object);
456 }
457
458
459 /*******************************************************************************
460  *
461  * FUNCTION:    AcpiUtDeleteObjectDesc
462  *
463  * PARAMETERS:  Object          - An Acpi internal object to be deleted
464  *
465  * RETURN:      None.
466  *
467  * DESCRIPTION: Free an ACPI object descriptor or add it to the object cache
468  *
469  ******************************************************************************/
470
471 void
472 AcpiUtDeleteObjectDesc (
473     ACPI_OPERAND_OBJECT     *Object)
474 {
475     ACPI_FUNCTION_TRACE_PTR (UtDeleteObjectDesc, Object);
476
477
478     /* Object must be of type ACPI_OPERAND_OBJECT */
479
480     if (ACPI_GET_DESCRIPTOR_TYPE (Object) != ACPI_DESC_TYPE_OPERAND)
481     {
482         ACPI_ERROR ((AE_INFO,
483             "%p is not an ACPI Operand object [%s]", Object,
484             AcpiUtGetDescriptorName (Object)));
485         return_VOID;
486     }
487
488     (void) AcpiOsReleaseObject (AcpiGbl_OperandCache, Object);
489     return_VOID;
490 }
491
492
493 /*******************************************************************************
494  *
495  * FUNCTION:    AcpiUtGetSimpleObjectSize
496  *
497  * PARAMETERS:  InternalObject     - An ACPI operand object
498  *              ObjLength          - Where the length is returned
499  *
500  * RETURN:      Status
501  *
502  * DESCRIPTION: This function is called to determine the space required to
503  *              contain a simple object for return to an external user.
504  *
505  *              The length includes the object structure plus any additional
506  *              needed space.
507  *
508  ******************************************************************************/
509
510 static ACPI_STATUS
511 AcpiUtGetSimpleObjectSize (
512     ACPI_OPERAND_OBJECT     *InternalObject,
513     ACPI_SIZE               *ObjLength)
514 {
515     ACPI_SIZE               Length;
516     ACPI_SIZE               Size;
517     ACPI_STATUS             Status = AE_OK;
518
519
520     ACPI_FUNCTION_TRACE_PTR (UtGetSimpleObjectSize, InternalObject);
521
522
523     /* Start with the length of the (external) Acpi object */
524
525     Length = sizeof (ACPI_OBJECT);
526
527     /* A NULL object is allowed, can be a legal uninitialized package element */
528
529     if (!InternalObject)
530     {
531         /*
532          * Object is NULL, just return the length of ACPI_OBJECT
533          * (A NULL ACPI_OBJECT is an object of all zeroes.)
534          */
535         *ObjLength = ACPI_ROUND_UP_TO_NATIVE_WORD (Length);
536         return_ACPI_STATUS (AE_OK);
537     }
538
539     /* A Namespace Node should never appear here */
540
541     if (ACPI_GET_DESCRIPTOR_TYPE (InternalObject) == ACPI_DESC_TYPE_NAMED)
542     {
543         /* A namespace node should never get here */
544
545         return_ACPI_STATUS (AE_AML_INTERNAL);
546     }
547
548     /*
549      * The final length depends on the object type
550      * Strings and Buffers are packed right up against the parent object and
551      * must be accessed bytewise or there may be alignment problems on
552      * certain processors
553      */
554     switch (InternalObject->Common.Type)
555     {
556     case ACPI_TYPE_STRING:
557
558         Length += (ACPI_SIZE) InternalObject->String.Length + 1;
559         break;
560
561     case ACPI_TYPE_BUFFER:
562
563         Length += (ACPI_SIZE) InternalObject->Buffer.Length;
564         break;
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     case ACPI_TYPE_LOCAL_REFERENCE:
575
576         switch (InternalObject->Reference.Class)
577         {
578         case ACPI_REFCLASS_NAME:
579             /*
580              * Get the actual length of the full pathname to this object.
581              * The reference will be converted to the pathname to the object
582              */
583             Size = AcpiNsGetPathnameLength (InternalObject->Reference.Node);
584             if (!Size)
585             {
586                 return_ACPI_STATUS (AE_BAD_PARAMETER);
587             }
588
589             Length += ACPI_ROUND_UP_TO_NATIVE_WORD (Size);
590             break;
591
592         default:
593             /*
594              * No other reference opcodes are supported.
595              * Notably, Locals and Args are not supported, but this may be
596              * required eventually.
597              */
598             ACPI_ERROR ((AE_INFO, "Cannot convert to external object - "
599                 "unsupported Reference Class [%s] 0x%X in object %p",
600                 AcpiUtGetReferenceName (InternalObject),
601                 InternalObject->Reference.Class, InternalObject));
602             Status = AE_TYPE;
603             break;
604         }
605         break;
606
607     default:
608
609         ACPI_ERROR ((AE_INFO, "Cannot convert to external object - "
610             "unsupported type [%s] 0x%X in object %p",
611             AcpiUtGetObjectTypeName (InternalObject),
612             InternalObject->Common.Type, InternalObject));
613         Status = AE_TYPE;
614         break;
615     }
616
617     /*
618      * Account for the space required by the object rounded up to the next
619      * multiple of the machine word size. This keeps each object aligned
620      * on a machine word boundary. (preventing alignment faults on some
621      * machines.)
622      */
623     *ObjLength = ACPI_ROUND_UP_TO_NATIVE_WORD (Length);
624     return_ACPI_STATUS (Status);
625 }
626
627
628 /*******************************************************************************
629  *
630  * FUNCTION:    AcpiUtGetElementLength
631  *
632  * PARAMETERS:  ACPI_PKG_CALLBACK
633  *
634  * RETURN:      Status
635  *
636  * DESCRIPTION: Get the length of one package element.
637  *
638  ******************************************************************************/
639
640 static ACPI_STATUS
641 AcpiUtGetElementLength (
642     UINT8                   ObjectType,
643     ACPI_OPERAND_OBJECT     *SourceObject,
644     ACPI_GENERIC_STATE      *State,
645     void                    *Context)
646 {
647     ACPI_STATUS             Status = AE_OK;
648     ACPI_PKG_INFO           *Info = (ACPI_PKG_INFO *) Context;
649     ACPI_SIZE               ObjectSpace;
650
651
652     switch (ObjectType)
653     {
654     case ACPI_COPY_TYPE_SIMPLE:
655         /*
656          * Simple object - just get the size (Null object/entry is handled
657          * here also) and sum it into the running package length
658          */
659         Status = AcpiUtGetSimpleObjectSize (SourceObject, &ObjectSpace);
660         if (ACPI_FAILURE (Status))
661         {
662             return (Status);
663         }
664
665         Info->Length += ObjectSpace;
666         break;
667
668     case ACPI_COPY_TYPE_PACKAGE:
669
670         /* Package object - nothing much to do here, let the walk handle it */
671
672         Info->NumPackages++;
673         State->Pkg.ThisTargetObj = NULL;
674         break;
675
676     default:
677
678         /* No other types allowed */
679
680         return (AE_BAD_PARAMETER);
681     }
682
683     return (Status);
684 }
685
686
687 /*******************************************************************************
688  *
689  * FUNCTION:    AcpiUtGetPackageObjectSize
690  *
691  * PARAMETERS:  InternalObject      - An ACPI internal object
692  *              ObjLength           - Where the length is returned
693  *
694  * RETURN:      Status
695  *
696  * DESCRIPTION: This function is called to determine the space required to
697  *              contain a package object for return to an external user.
698  *
699  *              This is moderately complex since a package contains other
700  *              objects including packages.
701  *
702  ******************************************************************************/
703
704 static ACPI_STATUS
705 AcpiUtGetPackageObjectSize (
706     ACPI_OPERAND_OBJECT     *InternalObject,
707     ACPI_SIZE               *ObjLength)
708 {
709     ACPI_STATUS             Status;
710     ACPI_PKG_INFO           Info;
711
712
713     ACPI_FUNCTION_TRACE_PTR (UtGetPackageObjectSize, InternalObject);
714
715
716     Info.Length      = 0;
717     Info.ObjectSpace = 0;
718     Info.NumPackages = 1;
719
720     Status = AcpiUtWalkPackageTree (InternalObject, NULL,
721         AcpiUtGetElementLength, &Info);
722     if (ACPI_FAILURE (Status))
723     {
724         return_ACPI_STATUS (Status);
725     }
726
727     /*
728      * We have handled all of the objects in all levels of the package.
729      * just add the length of the package objects themselves.
730      * Round up to the next machine word.
731      */
732     Info.Length += ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (ACPI_OBJECT)) *
733                     (ACPI_SIZE) Info.NumPackages;
734
735     /* Return the total package length */
736
737     *ObjLength = Info.Length;
738     return_ACPI_STATUS (Status);
739 }
740
741
742 /*******************************************************************************
743  *
744  * FUNCTION:    AcpiUtGetObjectSize
745  *
746  * PARAMETERS:  InternalObject      - An ACPI internal object
747  *              ObjLength           - Where the length will be returned
748  *
749  * RETURN:      Status
750  *
751  * DESCRIPTION: This function is called to determine the space required to
752  *              contain an object for return to an API user.
753  *
754  ******************************************************************************/
755
756 ACPI_STATUS
757 AcpiUtGetObjectSize (
758     ACPI_OPERAND_OBJECT     *InternalObject,
759     ACPI_SIZE               *ObjLength)
760 {
761     ACPI_STATUS             Status;
762
763
764     ACPI_FUNCTION_ENTRY ();
765
766
767     if ((ACPI_GET_DESCRIPTOR_TYPE (InternalObject) == ACPI_DESC_TYPE_OPERAND) &&
768         (InternalObject->Common.Type == ACPI_TYPE_PACKAGE))
769     {
770         Status = AcpiUtGetPackageObjectSize (InternalObject, ObjLength);
771     }
772     else
773     {
774         Status = AcpiUtGetSimpleObjectSize (InternalObject, ObjLength);
775     }
776
777     return (Status);
778 }