Home | History | Annotate | Line # | Download | only in utilities
utcopy.c revision 1.1
      1 /******************************************************************************
      2  *
      3  * Module Name: utcopy - Internal to external object translation utilities
      4  *
      5  *****************************************************************************/
      6 
      7 /******************************************************************************
      8  *
      9  * 1. Copyright Notice
     10  *
     11  * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp.
     12  * All rights reserved.
     13  *
     14  * 2. License
     15  *
     16  * 2.1. This is your license from Intel Corp. under its intellectual property
     17  * rights.  You may have additional license terms from the party that provided
     18  * you this software, covering your right to use that party's intellectual
     19  * property rights.
     20  *
     21  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
     22  * copy of the source code appearing in this file ("Covered Code") an
     23  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
     24  * base code distributed originally by Intel ("Original Intel Code") to copy,
     25  * make derivatives, distribute, use and display any portion of the Covered
     26  * Code in any form, with the right to sublicense such rights; and
     27  *
     28  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
     29  * license (with the right to sublicense), under only those claims of Intel
     30  * patents that are infringed by the Original Intel Code, to make, use, sell,
     31  * offer to sell, and import the Covered Code and derivative works thereof
     32  * solely to the minimum extent necessary to exercise the above copyright
     33  * license, and in no event shall the patent license extend to any additions
     34  * to or modifications of the Original Intel Code.  No other license or right
     35  * is granted directly or by implication, estoppel or otherwise;
     36  *
     37  * The above copyright and patent license is granted only if the following
     38  * conditions are met:
     39  *
     40  * 3. Conditions
     41  *
     42  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
     43  * Redistribution of source code of any substantial portion of the Covered
     44  * Code or modification with rights to further distribute source must include
     45  * the above Copyright Notice, the above License, this list of Conditions,
     46  * and the following Disclaimer and Export Compliance provision.  In addition,
     47  * Licensee must cause all Covered Code to which Licensee contributes to
     48  * contain a file documenting the changes Licensee made to create that Covered
     49  * Code and the date of any change.  Licensee must include in that file the
     50  * documentation of any changes made by any predecessor Licensee.  Licensee
     51  * must include a prominent statement that the modification is derived,
     52  * directly or indirectly, from Original Intel Code.
     53  *
     54  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
     55  * Redistribution of source code of any substantial portion of the Covered
     56  * Code or modification without rights to further distribute source must
     57  * include the following Disclaimer and Export Compliance provision in the
     58  * documentation and/or other materials provided with distribution.  In
     59  * addition, Licensee may not authorize further sublicense of source of any
     60  * portion of the Covered Code, and must include terms to the effect that the
     61  * license from Licensee to its licensee is limited to the intellectual
     62  * property embodied in the software Licensee provides to its licensee, and
     63  * not to intellectual property embodied in modifications its licensee may
     64  * make.
     65  *
     66  * 3.3. Redistribution of Executable. Redistribution in executable form of any
     67  * substantial portion of the Covered Code or modification must reproduce the
     68  * above Copyright Notice, and the following Disclaimer and Export Compliance
     69  * provision in the documentation and/or other materials provided with the
     70  * distribution.
     71  *
     72  * 3.4. Intel retains all right, title, and interest in and to the Original
     73  * Intel Code.
     74  *
     75  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
     76  * Intel shall be used in advertising or otherwise to promote the sale, use or
     77  * other dealings in products derived from or relating to the Covered Code
     78  * without prior written authorization from Intel.
     79  *
     80  * 4. Disclaimer and Export Compliance
     81  *
     82  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
     83  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
     84  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
     85  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
     86  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
     87  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
     88  * PARTICULAR PURPOSE.
     89  *
     90  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
     91  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
     92  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
     93  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
     94  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
     95  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
     96  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
     97  * LIMITED REMEDY.
     98  *
     99  * 4.3. Licensee shall not export, either directly or indirectly, any of this
    100  * software or system incorporating such software without first obtaining any
    101  * required license or other approval from the U. S. Department of Commerce or
    102  * any other agency or department of the United States Government.  In the
    103  * event Licensee exports any such software from the United States or
    104  * re-exports any such software from a foreign destination, Licensee shall
    105  * ensure that the distribution and export/re-export of the software is in
    106  * compliance with all laws, regulations, orders, or other restrictions of the
    107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
    108  * any of its subsidiaries will export/re-export any technical data, process,
    109  * software, or service, directly or indirectly, to any country for which the
    110  * United States government or any agency thereof requires an export license,
    111  * other governmental approval, or letter of assurance, without first obtaining
    112  * such license, approval or letter.
    113  *
    114  *****************************************************************************/
    115 
    116 #define __UTCOPY_C__
    117 
    118 #include "acpi.h"
    119 #include "accommon.h"
    120 #include "acnamesp.h"
    121 
    122 
    123 #define _COMPONENT          ACPI_UTILITIES
    124         ACPI_MODULE_NAME    ("utcopy")
    125 
    126 /* Local prototypes */
    127 
    128 static ACPI_STATUS
    129 AcpiUtCopyIsimpleToEsimple (
    130     ACPI_OPERAND_OBJECT     *InternalObject,
    131     ACPI_OBJECT             *ExternalObject,
    132     UINT8                   *DataSpace,
    133     ACPI_SIZE               *BufferSpaceUsed);
    134 
    135 static ACPI_STATUS
    136 AcpiUtCopyIelementToIelement (
    137     UINT8                   ObjectType,
    138     ACPI_OPERAND_OBJECT     *SourceObject,
    139     ACPI_GENERIC_STATE      *State,
    140     void                    *Context);
    141 
    142 static ACPI_STATUS
    143 AcpiUtCopyIpackageToEpackage (
    144     ACPI_OPERAND_OBJECT     *InternalObject,
    145     UINT8                   *Buffer,
    146     ACPI_SIZE               *SpaceUsed);
    147 
    148 static ACPI_STATUS
    149 AcpiUtCopyEsimpleToIsimple(
    150     ACPI_OBJECT             *UserObj,
    151     ACPI_OPERAND_OBJECT     **ReturnObj);
    152 
    153 static ACPI_STATUS
    154 AcpiUtCopyEpackageToIpackage (
    155     ACPI_OBJECT             *ExternalObject,
    156     ACPI_OPERAND_OBJECT     **InternalObject);
    157 
    158 static ACPI_STATUS
    159 AcpiUtCopySimpleObject (
    160     ACPI_OPERAND_OBJECT     *SourceDesc,
    161     ACPI_OPERAND_OBJECT     *DestDesc);
    162 
    163 static ACPI_STATUS
    164 AcpiUtCopyIelementToEelement (
    165     UINT8                   ObjectType,
    166     ACPI_OPERAND_OBJECT     *SourceObject,
    167     ACPI_GENERIC_STATE      *State,
    168     void                    *Context);
    169 
    170 static ACPI_STATUS
    171 AcpiUtCopyIpackageToIpackage (
    172     ACPI_OPERAND_OBJECT     *SourceObj,
    173     ACPI_OPERAND_OBJECT     *DestObj,
    174     ACPI_WALK_STATE         *WalkState);
    175 
    176 
    177 /*******************************************************************************
    178  *
    179  * FUNCTION:    AcpiUtCopyIsimpleToEsimple
    180  *
    181  * PARAMETERS:  InternalObject      - Source object to be copied
    182  *              ExternalObject      - Where to return the copied object
    183  *              DataSpace           - Where object data is returned (such as
    184  *                                    buffer and string data)
    185  *              BufferSpaceUsed     - Length of DataSpace that was used
    186  *
    187  * RETURN:      Status
    188  *
    189  * DESCRIPTION: This function is called to copy a simple internal object to
    190  *              an external object.
    191  *
    192  *              The DataSpace buffer is assumed to have sufficient space for
    193  *              the object.
    194  *
    195  ******************************************************************************/
    196 
    197 static ACPI_STATUS
    198 AcpiUtCopyIsimpleToEsimple (
    199     ACPI_OPERAND_OBJECT     *InternalObject,
    200     ACPI_OBJECT             *ExternalObject,
    201     UINT8                   *DataSpace,
    202     ACPI_SIZE               *BufferSpaceUsed)
    203 {
    204     ACPI_STATUS             Status = AE_OK;
    205 
    206 
    207     ACPI_FUNCTION_TRACE (UtCopyIsimpleToEsimple);
    208 
    209 
    210     *BufferSpaceUsed = 0;
    211 
    212     /*
    213      * Check for NULL object case (could be an uninitialized
    214      * package element)
    215      */
    216     if (!InternalObject)
    217     {
    218         return_ACPI_STATUS (AE_OK);
    219     }
    220 
    221     /* Always clear the external object */
    222 
    223     ACPI_MEMSET (ExternalObject, 0, sizeof (ACPI_OBJECT));
    224 
    225     /*
    226      * In general, the external object will be the same type as
    227      * the internal object
    228      */
    229     ExternalObject->Type = InternalObject->Common.Type;
    230 
    231     /* However, only a limited number of external types are supported */
    232 
    233     switch (InternalObject->Common.Type)
    234     {
    235     case ACPI_TYPE_STRING:
    236 
    237         ExternalObject->String.Pointer = (char *) DataSpace;
    238         ExternalObject->String.Length  = InternalObject->String.Length;
    239         *BufferSpaceUsed = ACPI_ROUND_UP_TO_NATIVE_WORD (
    240                             (ACPI_SIZE) InternalObject->String.Length + 1);
    241 
    242         ACPI_MEMCPY ((void *) DataSpace,
    243             (void *) InternalObject->String.Pointer,
    244             (ACPI_SIZE) InternalObject->String.Length + 1);
    245         break;
    246 
    247 
    248     case ACPI_TYPE_BUFFER:
    249 
    250         ExternalObject->Buffer.Pointer = DataSpace;
    251         ExternalObject->Buffer.Length  = InternalObject->Buffer.Length;
    252         *BufferSpaceUsed = ACPI_ROUND_UP_TO_NATIVE_WORD (
    253                             InternalObject->String.Length);
    254 
    255         ACPI_MEMCPY ((void *) DataSpace,
    256             (void *) InternalObject->Buffer.Pointer,
    257             InternalObject->Buffer.Length);
    258         break;
    259 
    260 
    261     case ACPI_TYPE_INTEGER:
    262 
    263         ExternalObject->Integer.Value = InternalObject->Integer.Value;
    264         break;
    265 
    266 
    267     case ACPI_TYPE_LOCAL_REFERENCE:
    268 
    269         /* This is an object reference. */
    270 
    271         switch (InternalObject->Reference.Class)
    272         {
    273         case ACPI_REFCLASS_NAME:
    274 
    275             /*
    276              * For namepath, return the object handle ("reference")
    277              * We are referring to the namespace node
    278              */
    279             ExternalObject->Reference.Handle =
    280                 InternalObject->Reference.Node;
    281             ExternalObject->Reference.ActualType =
    282                 AcpiNsGetType (InternalObject->Reference.Node);
    283             break;
    284 
    285         default:
    286 
    287             /* All other reference types are unsupported */
    288 
    289             return_ACPI_STATUS (AE_TYPE);
    290         }
    291         break;
    292 
    293 
    294     case ACPI_TYPE_PROCESSOR:
    295 
    296         ExternalObject->Processor.ProcId =
    297             InternalObject->Processor.ProcId;
    298         ExternalObject->Processor.PblkAddress =
    299             InternalObject->Processor.Address;
    300         ExternalObject->Processor.PblkLength =
    301             InternalObject->Processor.Length;
    302         break;
    303 
    304 
    305     case ACPI_TYPE_POWER:
    306 
    307         ExternalObject->PowerResource.SystemLevel =
    308             InternalObject->PowerResource.SystemLevel;
    309 
    310         ExternalObject->PowerResource.ResourceOrder =
    311             InternalObject->PowerResource.ResourceOrder;
    312         break;
    313 
    314 
    315     default:
    316         /*
    317          * There is no corresponding external object type
    318          */
    319         ACPI_ERROR ((AE_INFO,
    320             "Unsupported object type, cannot convert to external object: %s",
    321             AcpiUtGetTypeName (InternalObject->Common.Type)));
    322 
    323         return_ACPI_STATUS (AE_SUPPORT);
    324     }
    325 
    326     return_ACPI_STATUS (Status);
    327 }
    328 
    329 
    330 /*******************************************************************************
    331  *
    332  * FUNCTION:    AcpiUtCopyIelementToEelement
    333  *
    334  * PARAMETERS:  ACPI_PKG_CALLBACK
    335  *
    336  * RETURN:      Status
    337  *
    338  * DESCRIPTION: Copy one package element to another package element
    339  *
    340  ******************************************************************************/
    341 
    342 static ACPI_STATUS
    343 AcpiUtCopyIelementToEelement (
    344     UINT8                   ObjectType,
    345     ACPI_OPERAND_OBJECT     *SourceObject,
    346     ACPI_GENERIC_STATE      *State,
    347     void                    *Context)
    348 {
    349     ACPI_STATUS             Status = AE_OK;
    350     ACPI_PKG_INFO           *Info = (ACPI_PKG_INFO *) Context;
    351     ACPI_SIZE               ObjectSpace;
    352     UINT32                  ThisIndex;
    353     ACPI_OBJECT             *TargetObject;
    354 
    355 
    356     ACPI_FUNCTION_ENTRY ();
    357 
    358 
    359     ThisIndex    = State->Pkg.Index;
    360     TargetObject = (ACPI_OBJECT *)
    361         &((ACPI_OBJECT *)(State->Pkg.DestObject))->Package.Elements[ThisIndex];
    362 
    363     switch (ObjectType)
    364     {
    365     case ACPI_COPY_TYPE_SIMPLE:
    366 
    367         /*
    368          * This is a simple or null object
    369          */
    370         Status = AcpiUtCopyIsimpleToEsimple (SourceObject,
    371                         TargetObject, Info->FreeSpace, &ObjectSpace);
    372         if (ACPI_FAILURE (Status))
    373         {
    374             return (Status);
    375         }
    376         break;
    377 
    378 
    379     case ACPI_COPY_TYPE_PACKAGE:
    380 
    381         /*
    382          * Build the package object
    383          */
    384         TargetObject->Type              = ACPI_TYPE_PACKAGE;
    385         TargetObject->Package.Count     = SourceObject->Package.Count;
    386         TargetObject->Package.Elements  =
    387             ACPI_CAST_PTR (ACPI_OBJECT, Info->FreeSpace);
    388 
    389         /*
    390          * Pass the new package object back to the package walk routine
    391          */
    392         State->Pkg.ThisTargetObj = TargetObject;
    393 
    394         /*
    395          * Save space for the array of objects (Package elements)
    396          * update the buffer length counter
    397          */
    398         ObjectSpace = ACPI_ROUND_UP_TO_NATIVE_WORD (
    399                             (ACPI_SIZE) TargetObject->Package.Count *
    400                             sizeof (ACPI_OBJECT));
    401         break;
    402 
    403 
    404     default:
    405         return (AE_BAD_PARAMETER);
    406     }
    407 
    408     Info->FreeSpace   += ObjectSpace;
    409     Info->Length      += ObjectSpace;
    410     return (Status);
    411 }
    412 
    413 
    414 /*******************************************************************************
    415  *
    416  * FUNCTION:    AcpiUtCopyIpackageToEpackage
    417  *
    418  * PARAMETERS:  InternalObject      - Pointer to the object we are returning
    419  *              Buffer              - Where the object is returned
    420  *              SpaceUsed           - Where the object length is returned
    421  *
    422  * RETURN:      Status
    423  *
    424  * DESCRIPTION: This function is called to place a package object in a user
    425  *              buffer. A package object by definition contains other objects.
    426  *
    427  *              The buffer is assumed to have sufficient space for the object.
    428  *              The caller must have verified the buffer length needed using
    429  *              the AcpiUtGetObjectSize function before calling this function.
    430  *
    431  ******************************************************************************/
    432 
    433 static ACPI_STATUS
    434 AcpiUtCopyIpackageToEpackage (
    435     ACPI_OPERAND_OBJECT     *InternalObject,
    436     UINT8                   *Buffer,
    437     ACPI_SIZE               *SpaceUsed)
    438 {
    439     ACPI_OBJECT             *ExternalObject;
    440     ACPI_STATUS             Status;
    441     ACPI_PKG_INFO           Info;
    442 
    443 
    444     ACPI_FUNCTION_TRACE (UtCopyIpackageToEpackage);
    445 
    446 
    447     /*
    448      * First package at head of the buffer
    449      */
    450     ExternalObject = ACPI_CAST_PTR (ACPI_OBJECT, Buffer);
    451 
    452     /*
    453      * Free space begins right after the first package
    454      */
    455     Info.Length      = ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (ACPI_OBJECT));
    456     Info.FreeSpace   = Buffer + ACPI_ROUND_UP_TO_NATIVE_WORD (
    457                                     sizeof (ACPI_OBJECT));
    458     Info.ObjectSpace = 0;
    459     Info.NumPackages = 1;
    460 
    461     ExternalObject->Type             = InternalObject->Common.Type;
    462     ExternalObject->Package.Count    = InternalObject->Package.Count;
    463     ExternalObject->Package.Elements = ACPI_CAST_PTR (ACPI_OBJECT,
    464                                             Info.FreeSpace);
    465 
    466     /*
    467      * Leave room for an array of ACPI_OBJECTS in the buffer
    468      * and move the free space past it
    469      */
    470     Info.Length    += (ACPI_SIZE) ExternalObject->Package.Count *
    471                             ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (ACPI_OBJECT));
    472     Info.FreeSpace += ExternalObject->Package.Count *
    473                             ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (ACPI_OBJECT));
    474 
    475     Status = AcpiUtWalkPackageTree (InternalObject, ExternalObject,
    476                 AcpiUtCopyIelementToEelement, &Info);
    477 
    478     *SpaceUsed = Info.Length;
    479     return_ACPI_STATUS (Status);
    480 }
    481 
    482 
    483 /*******************************************************************************
    484  *
    485  * FUNCTION:    AcpiUtCopyIobjectToEobject
    486  *
    487  * PARAMETERS:  InternalObject      - The internal object to be converted
    488  *              RetBuffer           - Where the object is returned
    489  *
    490  * RETURN:      Status
    491  *
    492  * DESCRIPTION: This function is called to build an API object to be returned
    493  *              to the caller.
    494  *
    495  ******************************************************************************/
    496 
    497 ACPI_STATUS
    498 AcpiUtCopyIobjectToEobject (
    499     ACPI_OPERAND_OBJECT     *InternalObject,
    500     ACPI_BUFFER             *RetBuffer)
    501 {
    502     ACPI_STATUS             Status;
    503 
    504 
    505     ACPI_FUNCTION_TRACE (UtCopyIobjectToEobject);
    506 
    507 
    508     if (InternalObject->Common.Type == ACPI_TYPE_PACKAGE)
    509     {
    510         /*
    511          * Package object:  Copy all subobjects (including
    512          * nested packages)
    513          */
    514         Status = AcpiUtCopyIpackageToEpackage (InternalObject,
    515                         RetBuffer->Pointer, &RetBuffer->Length);
    516     }
    517     else
    518     {
    519         /*
    520          * Build a simple object (no nested objects)
    521          */
    522         Status = AcpiUtCopyIsimpleToEsimple (InternalObject,
    523                     ACPI_CAST_PTR (ACPI_OBJECT, RetBuffer->Pointer),
    524                     ACPI_ADD_PTR (UINT8, RetBuffer->Pointer,
    525                         ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (ACPI_OBJECT))),
    526                     &RetBuffer->Length);
    527         /*
    528          * build simple does not include the object size in the length
    529          * so we add it in here
    530          */
    531         RetBuffer->Length += sizeof (ACPI_OBJECT);
    532     }
    533 
    534     return_ACPI_STATUS (Status);
    535 }
    536 
    537 
    538 /*******************************************************************************
    539  *
    540  * FUNCTION:    AcpiUtCopyEsimpleToIsimple
    541  *
    542  * PARAMETERS:  ExternalObject      - The external object to be converted
    543  *              RetInternalObject   - Where the internal object is returned
    544  *
    545  * RETURN:      Status
    546  *
    547  * DESCRIPTION: This function copies an external object to an internal one.
    548  *              NOTE: Pointers can be copied, we don't need to copy data.
    549  *              (The pointers have to be valid in our address space no matter
    550  *              what we do with them!)
    551  *
    552  ******************************************************************************/
    553 
    554 static ACPI_STATUS
    555 AcpiUtCopyEsimpleToIsimple (
    556     ACPI_OBJECT             *ExternalObject,
    557     ACPI_OPERAND_OBJECT     **RetInternalObject)
    558 {
    559     ACPI_OPERAND_OBJECT     *InternalObject;
    560 
    561 
    562     ACPI_FUNCTION_TRACE (UtCopyEsimpleToIsimple);
    563 
    564 
    565     /*
    566      * Simple types supported are: String, Buffer, Integer
    567      */
    568     switch (ExternalObject->Type)
    569     {
    570     case ACPI_TYPE_STRING:
    571     case ACPI_TYPE_BUFFER:
    572     case ACPI_TYPE_INTEGER:
    573     case ACPI_TYPE_LOCAL_REFERENCE:
    574 
    575         InternalObject = AcpiUtCreateInternalObject (
    576                             (UINT8) ExternalObject->Type);
    577         if (!InternalObject)
    578         {
    579             return_ACPI_STATUS (AE_NO_MEMORY);
    580         }
    581         break;
    582 
    583     case ACPI_TYPE_ANY: /* This is the case for a NULL object */
    584 
    585         *RetInternalObject = NULL;
    586         return_ACPI_STATUS (AE_OK);
    587 
    588     default:
    589         /* All other types are not supported */
    590 
    591         ACPI_ERROR ((AE_INFO,
    592             "Unsupported object type, cannot convert to internal object: %s",
    593             AcpiUtGetTypeName (ExternalObject->Type)));
    594 
    595         return_ACPI_STATUS (AE_SUPPORT);
    596     }
    597 
    598 
    599     /* Must COPY string and buffer contents */
    600 
    601     switch (ExternalObject->Type)
    602     {
    603     case ACPI_TYPE_STRING:
    604 
    605         InternalObject->String.Pointer =
    606             ACPI_ALLOCATE_ZEROED ((ACPI_SIZE)
    607                 ExternalObject->String.Length + 1);
    608 
    609         if (!InternalObject->String.Pointer)
    610         {
    611             goto ErrorExit;
    612         }
    613 
    614         ACPI_MEMCPY (InternalObject->String.Pointer,
    615                      ExternalObject->String.Pointer,
    616                      ExternalObject->String.Length);
    617 
    618         InternalObject->String.Length  = ExternalObject->String.Length;
    619         break;
    620 
    621 
    622     case ACPI_TYPE_BUFFER:
    623 
    624         InternalObject->Buffer.Pointer =
    625             ACPI_ALLOCATE_ZEROED (ExternalObject->Buffer.Length);
    626         if (!InternalObject->Buffer.Pointer)
    627         {
    628             goto ErrorExit;
    629         }
    630 
    631         ACPI_MEMCPY (InternalObject->Buffer.Pointer,
    632                      ExternalObject->Buffer.Pointer,
    633                      ExternalObject->Buffer.Length);
    634 
    635         InternalObject->Buffer.Length  = ExternalObject->Buffer.Length;
    636 
    637         /* Mark buffer data valid */
    638 
    639         InternalObject->Buffer.Flags |= AOPOBJ_DATA_VALID;
    640         break;
    641 
    642 
    643     case ACPI_TYPE_INTEGER:
    644 
    645         InternalObject->Integer.Value   = ExternalObject->Integer.Value;
    646         break;
    647 
    648     case ACPI_TYPE_LOCAL_REFERENCE:
    649 
    650         /* TBD: should validate incoming handle */
    651 
    652         InternalObject->Reference.Class = ACPI_REFCLASS_NAME;
    653         InternalObject->Reference.Node = ExternalObject->Reference.Handle;
    654         break;
    655 
    656     default:
    657         /* Other types can't get here */
    658         break;
    659     }
    660 
    661     *RetInternalObject = InternalObject;
    662     return_ACPI_STATUS (AE_OK);
    663 
    664 
    665 ErrorExit:
    666     AcpiUtRemoveReference (InternalObject);
    667     return_ACPI_STATUS (AE_NO_MEMORY);
    668 }
    669 
    670 
    671 /*******************************************************************************
    672  *
    673  * FUNCTION:    AcpiUtCopyEpackageToIpackage
    674  *
    675  * PARAMETERS:  ExternalObject      - The external object to be converted
    676  *              InternalObject      - Where the internal object is returned
    677  *
    678  * RETURN:      Status
    679  *
    680  * DESCRIPTION: Copy an external package object to an internal package.
    681  *              Handles nested packages.
    682  *
    683  ******************************************************************************/
    684 
    685 static ACPI_STATUS
    686 AcpiUtCopyEpackageToIpackage (
    687     ACPI_OBJECT             *ExternalObject,
    688     ACPI_OPERAND_OBJECT     **InternalObject)
    689 {
    690     ACPI_STATUS             Status = AE_OK;
    691     ACPI_OPERAND_OBJECT     *PackageObject;
    692     ACPI_OPERAND_OBJECT     **PackageElements;
    693     UINT32                  i;
    694 
    695 
    696     ACPI_FUNCTION_TRACE (UtCopyEpackageToIpackage);
    697 
    698 
    699     /* Create the package object */
    700 
    701     PackageObject = AcpiUtCreatePackageObject (ExternalObject->Package.Count);
    702     if (!PackageObject)
    703     {
    704         return_ACPI_STATUS (AE_NO_MEMORY);
    705     }
    706 
    707     PackageElements = PackageObject->Package.Elements;
    708 
    709     /*
    710      * Recursive implementation. Probably ok, since nested external packages
    711      * as parameters should be very rare.
    712      */
    713     for (i = 0; i < ExternalObject->Package.Count; i++)
    714     {
    715         Status = AcpiUtCopyEobjectToIobject (
    716                     &ExternalObject->Package.Elements[i],
    717                     &PackageElements[i]);
    718         if (ACPI_FAILURE (Status))
    719         {
    720             /* Truncate package and delete it */
    721 
    722             PackageObject->Package.Count = i;
    723             PackageElements[i] = NULL;
    724             AcpiUtRemoveReference (PackageObject);
    725             return_ACPI_STATUS (Status);
    726         }
    727     }
    728 
    729     /* Mark package data valid */
    730 
    731     PackageObject->Package.Flags |= AOPOBJ_DATA_VALID;
    732 
    733     *InternalObject = PackageObject;
    734     return_ACPI_STATUS (Status);
    735 }
    736 
    737 
    738 /*******************************************************************************
    739  *
    740  * FUNCTION:    AcpiUtCopyEobjectToIobject
    741  *
    742  * PARAMETERS:  ExternalObject      - The external object to be converted
    743  *              InternalObject      - Where the internal object is returned
    744  *
    745  * RETURN:      Status
    746  *
    747  * DESCRIPTION: Converts an external object to an internal object.
    748  *
    749  ******************************************************************************/
    750 
    751 ACPI_STATUS
    752 AcpiUtCopyEobjectToIobject (
    753     ACPI_OBJECT             *ExternalObject,
    754     ACPI_OPERAND_OBJECT     **InternalObject)
    755 {
    756     ACPI_STATUS             Status;
    757 
    758 
    759     ACPI_FUNCTION_TRACE (UtCopyEobjectToIobject);
    760 
    761 
    762     if (ExternalObject->Type == ACPI_TYPE_PACKAGE)
    763     {
    764         Status = AcpiUtCopyEpackageToIpackage (ExternalObject, InternalObject);
    765     }
    766     else
    767     {
    768         /*
    769          * Build a simple object (no nested objects)
    770          */
    771         Status = AcpiUtCopyEsimpleToIsimple (ExternalObject, InternalObject);
    772     }
    773 
    774     return_ACPI_STATUS (Status);
    775 }
    776 
    777 
    778 /*******************************************************************************
    779  *
    780  * FUNCTION:    AcpiUtCopySimpleObject
    781  *
    782  * PARAMETERS:  SourceDesc          - The internal object to be copied
    783  *              DestDesc            - New target object
    784  *
    785  * RETURN:      Status
    786  *
    787  * DESCRIPTION: Simple copy of one internal object to another. Reference count
    788  *              of the destination object is preserved.
    789  *
    790  ******************************************************************************/
    791 
    792 static ACPI_STATUS
    793 AcpiUtCopySimpleObject (
    794     ACPI_OPERAND_OBJECT     *SourceDesc,
    795     ACPI_OPERAND_OBJECT     *DestDesc)
    796 {
    797     UINT16                  ReferenceCount;
    798     ACPI_OPERAND_OBJECT     *NextObject;
    799     ACPI_STATUS             Status;
    800     ACPI_SIZE               CopySize;
    801 
    802 
    803     /* Save fields from destination that we don't want to overwrite */
    804 
    805     ReferenceCount = DestDesc->Common.ReferenceCount;
    806     NextObject = DestDesc->Common.NextObject;
    807 
    808     /*
    809      * Copy the entire source object over the destination object.
    810      * Note: Source can be either an operand object or namespace node.
    811      */
    812     CopySize = sizeof (ACPI_OPERAND_OBJECT);
    813     if (ACPI_GET_DESCRIPTOR_TYPE (SourceDesc) == ACPI_DESC_TYPE_NAMED)
    814     {
    815         CopySize = sizeof (ACPI_NAMESPACE_NODE);
    816     }
    817 
    818     ACPI_MEMCPY (ACPI_CAST_PTR (char, DestDesc),
    819         ACPI_CAST_PTR (char, SourceDesc), CopySize);
    820 
    821     /* Restore the saved fields */
    822 
    823     DestDesc->Common.ReferenceCount = ReferenceCount;
    824     DestDesc->Common.NextObject = NextObject;
    825 
    826     /* New object is not static, regardless of source */
    827 
    828     DestDesc->Common.Flags &= ~AOPOBJ_STATIC_POINTER;
    829 
    830     /* Handle the objects with extra data */
    831 
    832     switch (DestDesc->Common.Type)
    833     {
    834     case ACPI_TYPE_BUFFER:
    835         /*
    836          * Allocate and copy the actual buffer if and only if:
    837          * 1) There is a valid buffer pointer
    838          * 2) The buffer has a length > 0
    839          */
    840         if ((SourceDesc->Buffer.Pointer) &&
    841             (SourceDesc->Buffer.Length))
    842         {
    843             DestDesc->Buffer.Pointer =
    844                 ACPI_ALLOCATE (SourceDesc->Buffer.Length);
    845             if (!DestDesc->Buffer.Pointer)
    846             {
    847                 return (AE_NO_MEMORY);
    848             }
    849 
    850             /* Copy the actual buffer data */
    851 
    852             ACPI_MEMCPY (DestDesc->Buffer.Pointer,
    853                 SourceDesc->Buffer.Pointer, SourceDesc->Buffer.Length);
    854         }
    855         break;
    856 
    857     case ACPI_TYPE_STRING:
    858         /*
    859          * Allocate and copy the actual string if and only if:
    860          * 1) There is a valid string pointer
    861          * (Pointer to a NULL string is allowed)
    862          */
    863         if (SourceDesc->String.Pointer)
    864         {
    865             DestDesc->String.Pointer =
    866                 ACPI_ALLOCATE ((ACPI_SIZE) SourceDesc->String.Length + 1);
    867             if (!DestDesc->String.Pointer)
    868             {
    869                 return (AE_NO_MEMORY);
    870             }
    871 
    872             /* Copy the actual string data */
    873 
    874             ACPI_MEMCPY (DestDesc->String.Pointer, SourceDesc->String.Pointer,
    875                 (ACPI_SIZE) SourceDesc->String.Length + 1);
    876         }
    877         break;
    878 
    879     case ACPI_TYPE_LOCAL_REFERENCE:
    880         /*
    881          * We copied the reference object, so we now must add a reference
    882          * to the object pointed to by the reference
    883          *
    884          * DDBHandle reference (from Load/LoadTable) is a special reference,
    885          * it does not have a Reference.Object, so does not need to
    886          * increase the reference count
    887          */
    888         if (SourceDesc->Reference.Class == ACPI_REFCLASS_TABLE)
    889         {
    890             break;
    891         }
    892 
    893         AcpiUtAddReference (SourceDesc->Reference.Object);
    894         break;
    895 
    896     case ACPI_TYPE_REGION:
    897         /*
    898          * We copied the Region Handler, so we now must add a reference
    899          */
    900         if (DestDesc->Region.Handler)
    901         {
    902             AcpiUtAddReference (DestDesc->Region.Handler);
    903         }
    904         break;
    905 
    906     /*
    907      * For Mutex and Event objects, we cannot simply copy the underlying
    908      * OS object. We must create a new one.
    909      */
    910     case ACPI_TYPE_MUTEX:
    911 
    912         Status = AcpiOsCreateMutex (&DestDesc->Mutex.OsMutex);
    913         if (ACPI_FAILURE (Status))
    914         {
    915             return (Status);
    916         }
    917         break;
    918 
    919     case ACPI_TYPE_EVENT:
    920 
    921         Status = AcpiOsCreateSemaphore (ACPI_NO_UNIT_LIMIT, 0,
    922                     &DestDesc->Event.OsSemaphore);
    923         if (ACPI_FAILURE (Status))
    924         {
    925             return (Status);
    926         }
    927         break;
    928 
    929     default:
    930         /* Nothing to do for other simple objects */
    931         break;
    932     }
    933 
    934     return (AE_OK);
    935 }
    936 
    937 
    938 /*******************************************************************************
    939  *
    940  * FUNCTION:    AcpiUtCopyIelementToIelement
    941  *
    942  * PARAMETERS:  ACPI_PKG_CALLBACK
    943  *
    944  * RETURN:      Status
    945  *
    946  * DESCRIPTION: Copy one package element to another package element
    947  *
    948  ******************************************************************************/
    949 
    950 static ACPI_STATUS
    951 AcpiUtCopyIelementToIelement (
    952     UINT8                   ObjectType,
    953     ACPI_OPERAND_OBJECT     *SourceObject,
    954     ACPI_GENERIC_STATE      *State,
    955     void                    *Context)
    956 {
    957     ACPI_STATUS             Status = AE_OK;
    958     UINT32                  ThisIndex;
    959     ACPI_OPERAND_OBJECT     **ThisTargetPtr;
    960     ACPI_OPERAND_OBJECT     *TargetObject;
    961 
    962 
    963     ACPI_FUNCTION_ENTRY ();
    964 
    965 
    966     ThisIndex     = State->Pkg.Index;
    967     ThisTargetPtr = (ACPI_OPERAND_OBJECT **)
    968                         &State->Pkg.DestObject->Package.Elements[ThisIndex];
    969 
    970     switch (ObjectType)
    971     {
    972     case ACPI_COPY_TYPE_SIMPLE:
    973 
    974         /* A null source object indicates a (legal) null package element */
    975 
    976         if (SourceObject)
    977         {
    978             /*
    979              * This is a simple object, just copy it
    980              */
    981             TargetObject = AcpiUtCreateInternalObject (
    982                                 SourceObject->Common.Type);
    983             if (!TargetObject)
    984             {
    985                 return (AE_NO_MEMORY);
    986             }
    987 
    988             Status = AcpiUtCopySimpleObject (SourceObject, TargetObject);
    989             if (ACPI_FAILURE (Status))
    990             {
    991                 goto ErrorExit;
    992             }
    993 
    994             *ThisTargetPtr = TargetObject;
    995         }
    996         else
    997         {
    998             /* Pass through a null element */
    999 
   1000             *ThisTargetPtr = NULL;
   1001         }
   1002         break;
   1003 
   1004 
   1005     case ACPI_COPY_TYPE_PACKAGE:
   1006 
   1007         /*
   1008          * This object is a package - go down another nesting level
   1009          * Create and build the package object
   1010          */
   1011         TargetObject = AcpiUtCreatePackageObject (SourceObject->Package.Count);
   1012         if (!TargetObject)
   1013         {
   1014             return (AE_NO_MEMORY);
   1015         }
   1016 
   1017         TargetObject->Common.Flags = SourceObject->Common.Flags;
   1018 
   1019         /* Pass the new package object back to the package walk routine */
   1020 
   1021         State->Pkg.ThisTargetObj = TargetObject;
   1022 
   1023         /* Store the object pointer in the parent package object */
   1024 
   1025         *ThisTargetPtr = TargetObject;
   1026         break;
   1027 
   1028 
   1029     default:
   1030         return (AE_BAD_PARAMETER);
   1031     }
   1032 
   1033     return (Status);
   1034 
   1035 ErrorExit:
   1036     AcpiUtRemoveReference (TargetObject);
   1037     return (Status);
   1038 }
   1039 
   1040 
   1041 /*******************************************************************************
   1042  *
   1043  * FUNCTION:    AcpiUtCopyIpackageToIpackage
   1044  *
   1045  * PARAMETERS:  SourceObj       - Pointer to the source package object
   1046  *              DestObj         - Where the internal object is returned
   1047  *              WalkState       - Current Walk state descriptor
   1048  *
   1049  * RETURN:      Status
   1050  *
   1051  * DESCRIPTION: This function is called to copy an internal package object
   1052  *              into another internal package object.
   1053  *
   1054  ******************************************************************************/
   1055 
   1056 static ACPI_STATUS
   1057 AcpiUtCopyIpackageToIpackage (
   1058     ACPI_OPERAND_OBJECT     *SourceObj,
   1059     ACPI_OPERAND_OBJECT     *DestObj,
   1060     ACPI_WALK_STATE         *WalkState)
   1061 {
   1062     ACPI_STATUS             Status = AE_OK;
   1063 
   1064 
   1065     ACPI_FUNCTION_TRACE (UtCopyIpackageToIpackage);
   1066 
   1067 
   1068     DestObj->Common.Type    = SourceObj->Common.Type;
   1069     DestObj->Common.Flags   = SourceObj->Common.Flags;
   1070     DestObj->Package.Count  = SourceObj->Package.Count;
   1071 
   1072     /*
   1073      * Create the object array and walk the source package tree
   1074      */
   1075     DestObj->Package.Elements = ACPI_ALLOCATE_ZEROED (
   1076                                     ((ACPI_SIZE) SourceObj->Package.Count + 1) *
   1077                                     sizeof (void *));
   1078     if (!DestObj->Package.Elements)
   1079     {
   1080         ACPI_ERROR ((AE_INFO, "Package allocation failure"));
   1081         return_ACPI_STATUS (AE_NO_MEMORY);
   1082     }
   1083 
   1084     /*
   1085      * Copy the package element-by-element by walking the package "tree".
   1086      * This handles nested packages of arbitrary depth.
   1087      */
   1088     Status = AcpiUtWalkPackageTree (SourceObj, DestObj,
   1089                 AcpiUtCopyIelementToIelement, WalkState);
   1090     if (ACPI_FAILURE (Status))
   1091     {
   1092         /* On failure, delete the destination package object */
   1093 
   1094         AcpiUtRemoveReference (DestObj);
   1095     }
   1096 
   1097     return_ACPI_STATUS (Status);
   1098 }
   1099 
   1100 
   1101 /*******************************************************************************
   1102  *
   1103  * FUNCTION:    AcpiUtCopyIobjectToIobject
   1104  *
   1105  * PARAMETERS:  SourceDesc          - The internal object to be copied
   1106  *              DestDesc            - Where the copied object is returned
   1107  *              WalkState           - Current walk state
   1108  *
   1109  * RETURN:      Status
   1110  *
   1111  * DESCRIPTION: Copy an internal object to a new internal object
   1112  *
   1113  ******************************************************************************/
   1114 
   1115 ACPI_STATUS
   1116 AcpiUtCopyIobjectToIobject (
   1117     ACPI_OPERAND_OBJECT     *SourceDesc,
   1118     ACPI_OPERAND_OBJECT     **DestDesc,
   1119     ACPI_WALK_STATE         *WalkState)
   1120 {
   1121     ACPI_STATUS             Status = AE_OK;
   1122 
   1123 
   1124     ACPI_FUNCTION_TRACE (UtCopyIobjectToIobject);
   1125 
   1126 
   1127     /* Create the top level object */
   1128 
   1129     *DestDesc = AcpiUtCreateInternalObject (SourceDesc->Common.Type);
   1130     if (!*DestDesc)
   1131     {
   1132         return_ACPI_STATUS (AE_NO_MEMORY);
   1133     }
   1134 
   1135     /* Copy the object and possible subobjects */
   1136 
   1137     if (SourceDesc->Common.Type == ACPI_TYPE_PACKAGE)
   1138     {
   1139         Status = AcpiUtCopyIpackageToIpackage (SourceDesc, *DestDesc,
   1140                         WalkState);
   1141     }
   1142     else
   1143     {
   1144         Status = AcpiUtCopySimpleObject (SourceDesc, *DestDesc);
   1145     }
   1146 
   1147     return_ACPI_STATUS (Status);
   1148 }
   1149 
   1150 
   1151