Home | History | Annotate | Line # | Download | only in utilities
utcopy.c revision 1.1.1.3
      1 /******************************************************************************
      2  *
      3  * Module Name: utcopy - Internal to external object translation utilities
      4  *
      5  *****************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2013, 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 __UTCOPY_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    ("utcopy")
     53 
     54 /* Local prototypes */
     55 
     56 static ACPI_STATUS
     57 AcpiUtCopyIsimpleToEsimple (
     58     ACPI_OPERAND_OBJECT     *InternalObject,
     59     ACPI_OBJECT             *ExternalObject,
     60     UINT8                   *DataSpace,
     61     ACPI_SIZE               *BufferSpaceUsed);
     62 
     63 static ACPI_STATUS
     64 AcpiUtCopyIelementToIelement (
     65     UINT8                   ObjectType,
     66     ACPI_OPERAND_OBJECT     *SourceObject,
     67     ACPI_GENERIC_STATE      *State,
     68     void                    *Context);
     69 
     70 static ACPI_STATUS
     71 AcpiUtCopyIpackageToEpackage (
     72     ACPI_OPERAND_OBJECT     *InternalObject,
     73     UINT8                   *Buffer,
     74     ACPI_SIZE               *SpaceUsed);
     75 
     76 static ACPI_STATUS
     77 AcpiUtCopyEsimpleToIsimple(
     78     ACPI_OBJECT             *UserObj,
     79     ACPI_OPERAND_OBJECT     **ReturnObj);
     80 
     81 static ACPI_STATUS
     82 AcpiUtCopyEpackageToIpackage (
     83     ACPI_OBJECT             *ExternalObject,
     84     ACPI_OPERAND_OBJECT     **InternalObject);
     85 
     86 static ACPI_STATUS
     87 AcpiUtCopySimpleObject (
     88     ACPI_OPERAND_OBJECT     *SourceDesc,
     89     ACPI_OPERAND_OBJECT     *DestDesc);
     90 
     91 static ACPI_STATUS
     92 AcpiUtCopyIelementToEelement (
     93     UINT8                   ObjectType,
     94     ACPI_OPERAND_OBJECT     *SourceObject,
     95     ACPI_GENERIC_STATE      *State,
     96     void                    *Context);
     97 
     98 static ACPI_STATUS
     99 AcpiUtCopyIpackageToIpackage (
    100     ACPI_OPERAND_OBJECT     *SourceObj,
    101     ACPI_OPERAND_OBJECT     *DestObj,
    102     ACPI_WALK_STATE         *WalkState);
    103 
    104 
    105 /*******************************************************************************
    106  *
    107  * FUNCTION:    AcpiUtCopyIsimpleToEsimple
    108  *
    109  * PARAMETERS:  InternalObject      - Source object to be copied
    110  *              ExternalObject      - Where to return the copied object
    111  *              DataSpace           - Where object data is returned (such as
    112  *                                    buffer and string data)
    113  *              BufferSpaceUsed     - Length of DataSpace that was used
    114  *
    115  * RETURN:      Status
    116  *
    117  * DESCRIPTION: This function is called to copy a simple internal object to
    118  *              an external object.
    119  *
    120  *              The DataSpace buffer is assumed to have sufficient space for
    121  *              the object.
    122  *
    123  ******************************************************************************/
    124 
    125 static ACPI_STATUS
    126 AcpiUtCopyIsimpleToEsimple (
    127     ACPI_OPERAND_OBJECT     *InternalObject,
    128     ACPI_OBJECT             *ExternalObject,
    129     UINT8                   *DataSpace,
    130     ACPI_SIZE               *BufferSpaceUsed)
    131 {
    132     ACPI_STATUS             Status = AE_OK;
    133 
    134 
    135     ACPI_FUNCTION_TRACE (UtCopyIsimpleToEsimple);
    136 
    137 
    138     *BufferSpaceUsed = 0;
    139 
    140     /*
    141      * Check for NULL object case (could be an uninitialized
    142      * package element)
    143      */
    144     if (!InternalObject)
    145     {
    146         return_ACPI_STATUS (AE_OK);
    147     }
    148 
    149     /* Always clear the external object */
    150 
    151     ACPI_MEMSET (ExternalObject, 0, sizeof (ACPI_OBJECT));
    152 
    153     /*
    154      * In general, the external object will be the same type as
    155      * the internal object
    156      */
    157     ExternalObject->Type = InternalObject->Common.Type;
    158 
    159     /* However, only a limited number of external types are supported */
    160 
    161     switch (InternalObject->Common.Type)
    162     {
    163     case ACPI_TYPE_STRING:
    164 
    165         ExternalObject->String.Pointer = (char *) DataSpace;
    166         ExternalObject->String.Length  = InternalObject->String.Length;
    167         *BufferSpaceUsed = ACPI_ROUND_UP_TO_NATIVE_WORD (
    168                             (ACPI_SIZE) InternalObject->String.Length + 1);
    169 
    170         ACPI_MEMCPY ((void *) DataSpace,
    171             (void *) InternalObject->String.Pointer,
    172             (ACPI_SIZE) InternalObject->String.Length + 1);
    173         break;
    174 
    175     case ACPI_TYPE_BUFFER:
    176 
    177         ExternalObject->Buffer.Pointer = DataSpace;
    178         ExternalObject->Buffer.Length  = InternalObject->Buffer.Length;
    179         *BufferSpaceUsed = ACPI_ROUND_UP_TO_NATIVE_WORD (
    180                             InternalObject->String.Length);
    181 
    182         ACPI_MEMCPY ((void *) DataSpace,
    183             (void *) InternalObject->Buffer.Pointer,
    184             InternalObject->Buffer.Length);
    185         break;
    186 
    187     case ACPI_TYPE_INTEGER:
    188 
    189         ExternalObject->Integer.Value = InternalObject->Integer.Value;
    190         break;
    191 
    192     case ACPI_TYPE_LOCAL_REFERENCE:
    193 
    194         /* This is an object reference. */
    195 
    196         switch (InternalObject->Reference.Class)
    197         {
    198         case ACPI_REFCLASS_NAME:
    199             /*
    200              * For namepath, return the object handle ("reference")
    201              * We are referring to the namespace node
    202              */
    203             ExternalObject->Reference.Handle =
    204                 InternalObject->Reference.Node;
    205             ExternalObject->Reference.ActualType =
    206                 AcpiNsGetType (InternalObject->Reference.Node);
    207             break;
    208 
    209         default:
    210 
    211             /* All other reference types are unsupported */
    212 
    213             return_ACPI_STATUS (AE_TYPE);
    214         }
    215         break;
    216 
    217     case ACPI_TYPE_PROCESSOR:
    218 
    219         ExternalObject->Processor.ProcId =
    220             InternalObject->Processor.ProcId;
    221         ExternalObject->Processor.PblkAddress =
    222             InternalObject->Processor.Address;
    223         ExternalObject->Processor.PblkLength =
    224             InternalObject->Processor.Length;
    225         break;
    226 
    227     case ACPI_TYPE_POWER:
    228 
    229         ExternalObject->PowerResource.SystemLevel =
    230             InternalObject->PowerResource.SystemLevel;
    231 
    232         ExternalObject->PowerResource.ResourceOrder =
    233             InternalObject->PowerResource.ResourceOrder;
    234         break;
    235 
    236     default:
    237         /*
    238          * There is no corresponding external object type
    239          */
    240         ACPI_ERROR ((AE_INFO,
    241             "Unsupported object type, cannot convert to external object: %s",
    242             AcpiUtGetTypeName (InternalObject->Common.Type)));
    243 
    244         return_ACPI_STATUS (AE_SUPPORT);
    245     }
    246 
    247     return_ACPI_STATUS (Status);
    248 }
    249 
    250 
    251 /*******************************************************************************
    252  *
    253  * FUNCTION:    AcpiUtCopyIelementToEelement
    254  *
    255  * PARAMETERS:  ACPI_PKG_CALLBACK
    256  *
    257  * RETURN:      Status
    258  *
    259  * DESCRIPTION: Copy one package element to another package element
    260  *
    261  ******************************************************************************/
    262 
    263 static ACPI_STATUS
    264 AcpiUtCopyIelementToEelement (
    265     UINT8                   ObjectType,
    266     ACPI_OPERAND_OBJECT     *SourceObject,
    267     ACPI_GENERIC_STATE      *State,
    268     void                    *Context)
    269 {
    270     ACPI_STATUS             Status = AE_OK;
    271     ACPI_PKG_INFO           *Info = (ACPI_PKG_INFO *) Context;
    272     ACPI_SIZE               ObjectSpace;
    273     UINT32                  ThisIndex;
    274     ACPI_OBJECT             *TargetObject;
    275 
    276 
    277     ACPI_FUNCTION_ENTRY ();
    278 
    279 
    280     ThisIndex    = State->Pkg.Index;
    281     TargetObject = (ACPI_OBJECT *)
    282         &((ACPI_OBJECT *)(State->Pkg.DestObject))->Package.Elements[ThisIndex];
    283 
    284     switch (ObjectType)
    285     {
    286     case ACPI_COPY_TYPE_SIMPLE:
    287         /*
    288          * This is a simple or null object
    289          */
    290         Status = AcpiUtCopyIsimpleToEsimple (SourceObject,
    291                         TargetObject, Info->FreeSpace, &ObjectSpace);
    292         if (ACPI_FAILURE (Status))
    293         {
    294             return (Status);
    295         }
    296         break;
    297 
    298     case ACPI_COPY_TYPE_PACKAGE:
    299         /*
    300          * Build the package object
    301          */
    302         TargetObject->Type              = ACPI_TYPE_PACKAGE;
    303         TargetObject->Package.Count     = SourceObject->Package.Count;
    304         TargetObject->Package.Elements  =
    305             ACPI_CAST_PTR (ACPI_OBJECT, Info->FreeSpace);
    306 
    307         /*
    308          * Pass the new package object back to the package walk routine
    309          */
    310         State->Pkg.ThisTargetObj = TargetObject;
    311 
    312         /*
    313          * Save space for the array of objects (Package elements)
    314          * update the buffer length counter
    315          */
    316         ObjectSpace = ACPI_ROUND_UP_TO_NATIVE_WORD (
    317                             (ACPI_SIZE) TargetObject->Package.Count *
    318                             sizeof (ACPI_OBJECT));
    319         break;
    320 
    321     default:
    322 
    323         return (AE_BAD_PARAMETER);
    324     }
    325 
    326     Info->FreeSpace   += ObjectSpace;
    327     Info->Length      += ObjectSpace;
    328     return (Status);
    329 }
    330 
    331 
    332 /*******************************************************************************
    333  *
    334  * FUNCTION:    AcpiUtCopyIpackageToEpackage
    335  *
    336  * PARAMETERS:  InternalObject      - Pointer to the object we are returning
    337  *              Buffer              - Where the object is returned
    338  *              SpaceUsed           - Where the object length is returned
    339  *
    340  * RETURN:      Status
    341  *
    342  * DESCRIPTION: This function is called to place a package object in a user
    343  *              buffer. A package object by definition contains other objects.
    344  *
    345  *              The buffer is assumed to have sufficient space for the object.
    346  *              The caller must have verified the buffer length needed using
    347  *              the AcpiUtGetObjectSize function before calling this function.
    348  *
    349  ******************************************************************************/
    350 
    351 static ACPI_STATUS
    352 AcpiUtCopyIpackageToEpackage (
    353     ACPI_OPERAND_OBJECT     *InternalObject,
    354     UINT8                   *Buffer,
    355     ACPI_SIZE               *SpaceUsed)
    356 {
    357     ACPI_OBJECT             *ExternalObject;
    358     ACPI_STATUS             Status;
    359     ACPI_PKG_INFO           Info;
    360 
    361 
    362     ACPI_FUNCTION_TRACE (UtCopyIpackageToEpackage);
    363 
    364 
    365     /*
    366      * First package at head of the buffer
    367      */
    368     ExternalObject = ACPI_CAST_PTR (ACPI_OBJECT, Buffer);
    369 
    370     /*
    371      * Free space begins right after the first package
    372      */
    373     Info.Length      = ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (ACPI_OBJECT));
    374     Info.FreeSpace   = Buffer + ACPI_ROUND_UP_TO_NATIVE_WORD (
    375                                     sizeof (ACPI_OBJECT));
    376     Info.ObjectSpace = 0;
    377     Info.NumPackages = 1;
    378 
    379     ExternalObject->Type             = InternalObject->Common.Type;
    380     ExternalObject->Package.Count    = InternalObject->Package.Count;
    381     ExternalObject->Package.Elements = ACPI_CAST_PTR (ACPI_OBJECT,
    382                                             Info.FreeSpace);
    383 
    384     /*
    385      * Leave room for an array of ACPI_OBJECTS in the buffer
    386      * and move the free space past it
    387      */
    388     Info.Length    += (ACPI_SIZE) ExternalObject->Package.Count *
    389                             ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (ACPI_OBJECT));
    390     Info.FreeSpace += ExternalObject->Package.Count *
    391                             ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (ACPI_OBJECT));
    392 
    393     Status = AcpiUtWalkPackageTree (InternalObject, ExternalObject,
    394                 AcpiUtCopyIelementToEelement, &Info);
    395 
    396     *SpaceUsed = Info.Length;
    397     return_ACPI_STATUS (Status);
    398 }
    399 
    400 
    401 /*******************************************************************************
    402  *
    403  * FUNCTION:    AcpiUtCopyIobjectToEobject
    404  *
    405  * PARAMETERS:  InternalObject      - The internal object to be converted
    406  *              RetBuffer           - Where the object is returned
    407  *
    408  * RETURN:      Status
    409  *
    410  * DESCRIPTION: This function is called to build an API object to be returned
    411  *              to the caller.
    412  *
    413  ******************************************************************************/
    414 
    415 ACPI_STATUS
    416 AcpiUtCopyIobjectToEobject (
    417     ACPI_OPERAND_OBJECT     *InternalObject,
    418     ACPI_BUFFER             *RetBuffer)
    419 {
    420     ACPI_STATUS             Status;
    421 
    422 
    423     ACPI_FUNCTION_TRACE (UtCopyIobjectToEobject);
    424 
    425 
    426     if (InternalObject->Common.Type == ACPI_TYPE_PACKAGE)
    427     {
    428         /*
    429          * Package object:  Copy all subobjects (including
    430          * nested packages)
    431          */
    432         Status = AcpiUtCopyIpackageToEpackage (InternalObject,
    433                         RetBuffer->Pointer, &RetBuffer->Length);
    434     }
    435     else
    436     {
    437         /*
    438          * Build a simple object (no nested objects)
    439          */
    440         Status = AcpiUtCopyIsimpleToEsimple (InternalObject,
    441                     ACPI_CAST_PTR (ACPI_OBJECT, RetBuffer->Pointer),
    442                     ACPI_ADD_PTR (UINT8, RetBuffer->Pointer,
    443                         ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (ACPI_OBJECT))),
    444                     &RetBuffer->Length);
    445         /*
    446          * build simple does not include the object size in the length
    447          * so we add it in here
    448          */
    449         RetBuffer->Length += sizeof (ACPI_OBJECT);
    450     }
    451 
    452     return_ACPI_STATUS (Status);
    453 }
    454 
    455 
    456 /*******************************************************************************
    457  *
    458  * FUNCTION:    AcpiUtCopyEsimpleToIsimple
    459  *
    460  * PARAMETERS:  ExternalObject      - The external object to be converted
    461  *              RetInternalObject   - Where the internal object is returned
    462  *
    463  * RETURN:      Status
    464  *
    465  * DESCRIPTION: This function copies an external object to an internal one.
    466  *              NOTE: Pointers can be copied, we don't need to copy data.
    467  *              (The pointers have to be valid in our address space no matter
    468  *              what we do with them!)
    469  *
    470  ******************************************************************************/
    471 
    472 static ACPI_STATUS
    473 AcpiUtCopyEsimpleToIsimple (
    474     ACPI_OBJECT             *ExternalObject,
    475     ACPI_OPERAND_OBJECT     **RetInternalObject)
    476 {
    477     ACPI_OPERAND_OBJECT     *InternalObject;
    478 
    479 
    480     ACPI_FUNCTION_TRACE (UtCopyEsimpleToIsimple);
    481 
    482 
    483     /*
    484      * Simple types supported are: String, Buffer, Integer
    485      */
    486     switch (ExternalObject->Type)
    487     {
    488     case ACPI_TYPE_STRING:
    489     case ACPI_TYPE_BUFFER:
    490     case ACPI_TYPE_INTEGER:
    491     case ACPI_TYPE_LOCAL_REFERENCE:
    492 
    493         InternalObject = AcpiUtCreateInternalObject (
    494                             (UINT8) ExternalObject->Type);
    495         if (!InternalObject)
    496         {
    497             return_ACPI_STATUS (AE_NO_MEMORY);
    498         }
    499         break;
    500 
    501     case ACPI_TYPE_ANY: /* This is the case for a NULL object */
    502 
    503         *RetInternalObject = NULL;
    504         return_ACPI_STATUS (AE_OK);
    505 
    506     default:
    507 
    508         /* All other types are not supported */
    509 
    510         ACPI_ERROR ((AE_INFO,
    511             "Unsupported object type, cannot convert to internal object: %s",
    512             AcpiUtGetTypeName (ExternalObject->Type)));
    513 
    514         return_ACPI_STATUS (AE_SUPPORT);
    515     }
    516 
    517 
    518     /* Must COPY string and buffer contents */
    519 
    520     switch (ExternalObject->Type)
    521     {
    522     case ACPI_TYPE_STRING:
    523 
    524         InternalObject->String.Pointer =
    525             ACPI_ALLOCATE_ZEROED ((ACPI_SIZE)
    526                 ExternalObject->String.Length + 1);
    527 
    528         if (!InternalObject->String.Pointer)
    529         {
    530             goto ErrorExit;
    531         }
    532 
    533         ACPI_MEMCPY (InternalObject->String.Pointer,
    534                      ExternalObject->String.Pointer,
    535                      ExternalObject->String.Length);
    536 
    537         InternalObject->String.Length  = ExternalObject->String.Length;
    538         break;
    539 
    540     case ACPI_TYPE_BUFFER:
    541 
    542         InternalObject->Buffer.Pointer =
    543             ACPI_ALLOCATE_ZEROED (ExternalObject->Buffer.Length);
    544         if (!InternalObject->Buffer.Pointer)
    545         {
    546             goto ErrorExit;
    547         }
    548 
    549         ACPI_MEMCPY (InternalObject->Buffer.Pointer,
    550                      ExternalObject->Buffer.Pointer,
    551                      ExternalObject->Buffer.Length);
    552 
    553         InternalObject->Buffer.Length  = ExternalObject->Buffer.Length;
    554 
    555         /* Mark buffer data valid */
    556 
    557         InternalObject->Buffer.Flags |= AOPOBJ_DATA_VALID;
    558         break;
    559 
    560     case ACPI_TYPE_INTEGER:
    561 
    562         InternalObject->Integer.Value   = ExternalObject->Integer.Value;
    563         break;
    564 
    565     case ACPI_TYPE_LOCAL_REFERENCE:
    566 
    567         /* TBD: should validate incoming handle */
    568 
    569         InternalObject->Reference.Class = ACPI_REFCLASS_NAME;
    570         InternalObject->Reference.Node = ExternalObject->Reference.Handle;
    571         break;
    572 
    573     default:
    574 
    575         /* Other types can't get here */
    576 
    577         break;
    578     }
    579 
    580     *RetInternalObject = InternalObject;
    581     return_ACPI_STATUS (AE_OK);
    582 
    583 
    584 ErrorExit:
    585     AcpiUtRemoveReference (InternalObject);
    586     return_ACPI_STATUS (AE_NO_MEMORY);
    587 }
    588 
    589 
    590 /*******************************************************************************
    591  *
    592  * FUNCTION:    AcpiUtCopyEpackageToIpackage
    593  *
    594  * PARAMETERS:  ExternalObject      - The external object to be converted
    595  *              InternalObject      - Where the internal object is returned
    596  *
    597  * RETURN:      Status
    598  *
    599  * DESCRIPTION: Copy an external package object to an internal package.
    600  *              Handles nested packages.
    601  *
    602  ******************************************************************************/
    603 
    604 static ACPI_STATUS
    605 AcpiUtCopyEpackageToIpackage (
    606     ACPI_OBJECT             *ExternalObject,
    607     ACPI_OPERAND_OBJECT     **InternalObject)
    608 {
    609     ACPI_STATUS             Status = AE_OK;
    610     ACPI_OPERAND_OBJECT     *PackageObject;
    611     ACPI_OPERAND_OBJECT     **PackageElements;
    612     UINT32                  i;
    613 
    614 
    615     ACPI_FUNCTION_TRACE (UtCopyEpackageToIpackage);
    616 
    617 
    618     /* Create the package object */
    619 
    620     PackageObject = AcpiUtCreatePackageObject (ExternalObject->Package.Count);
    621     if (!PackageObject)
    622     {
    623         return_ACPI_STATUS (AE_NO_MEMORY);
    624     }
    625 
    626     PackageElements = PackageObject->Package.Elements;
    627 
    628     /*
    629      * Recursive implementation. Probably ok, since nested external packages
    630      * as parameters should be very rare.
    631      */
    632     for (i = 0; i < ExternalObject->Package.Count; i++)
    633     {
    634         Status = AcpiUtCopyEobjectToIobject (
    635                     &ExternalObject->Package.Elements[i],
    636                     &PackageElements[i]);
    637         if (ACPI_FAILURE (Status))
    638         {
    639             /* Truncate package and delete it */
    640 
    641             PackageObject->Package.Count = i;
    642             PackageElements[i] = NULL;
    643             AcpiUtRemoveReference (PackageObject);
    644             return_ACPI_STATUS (Status);
    645         }
    646     }
    647 
    648     /* Mark package data valid */
    649 
    650     PackageObject->Package.Flags |= AOPOBJ_DATA_VALID;
    651 
    652     *InternalObject = PackageObject;
    653     return_ACPI_STATUS (Status);
    654 }
    655 
    656 
    657 /*******************************************************************************
    658  *
    659  * FUNCTION:    AcpiUtCopyEobjectToIobject
    660  *
    661  * PARAMETERS:  ExternalObject      - The external object to be converted
    662  *              InternalObject      - Where the internal object is returned
    663  *
    664  * RETURN:      Status
    665  *
    666  * DESCRIPTION: Converts an external object to an internal object.
    667  *
    668  ******************************************************************************/
    669 
    670 ACPI_STATUS
    671 AcpiUtCopyEobjectToIobject (
    672     ACPI_OBJECT             *ExternalObject,
    673     ACPI_OPERAND_OBJECT     **InternalObject)
    674 {
    675     ACPI_STATUS             Status;
    676 
    677 
    678     ACPI_FUNCTION_TRACE (UtCopyEobjectToIobject);
    679 
    680 
    681     if (ExternalObject->Type == ACPI_TYPE_PACKAGE)
    682     {
    683         Status = AcpiUtCopyEpackageToIpackage (ExternalObject, InternalObject);
    684     }
    685     else
    686     {
    687         /*
    688          * Build a simple object (no nested objects)
    689          */
    690         Status = AcpiUtCopyEsimpleToIsimple (ExternalObject, InternalObject);
    691     }
    692 
    693     return_ACPI_STATUS (Status);
    694 }
    695 
    696 
    697 /*******************************************************************************
    698  *
    699  * FUNCTION:    AcpiUtCopySimpleObject
    700  *
    701  * PARAMETERS:  SourceDesc          - The internal object to be copied
    702  *              DestDesc            - New target object
    703  *
    704  * RETURN:      Status
    705  *
    706  * DESCRIPTION: Simple copy of one internal object to another. Reference count
    707  *              of the destination object is preserved.
    708  *
    709  ******************************************************************************/
    710 
    711 static ACPI_STATUS
    712 AcpiUtCopySimpleObject (
    713     ACPI_OPERAND_OBJECT     *SourceDesc,
    714     ACPI_OPERAND_OBJECT     *DestDesc)
    715 {
    716     UINT16                  ReferenceCount;
    717     ACPI_OPERAND_OBJECT     *NextObject;
    718     ACPI_STATUS             Status;
    719     ACPI_SIZE               CopySize;
    720 
    721 
    722     /* Save fields from destination that we don't want to overwrite */
    723 
    724     ReferenceCount = DestDesc->Common.ReferenceCount;
    725     NextObject = DestDesc->Common.NextObject;
    726 
    727     /*
    728      * Copy the entire source object over the destination object.
    729      * Note: Source can be either an operand object or namespace node.
    730      */
    731     CopySize = sizeof (ACPI_OPERAND_OBJECT);
    732     if (ACPI_GET_DESCRIPTOR_TYPE (SourceDesc) == ACPI_DESC_TYPE_NAMED)
    733     {
    734         CopySize = sizeof (ACPI_NAMESPACE_NODE);
    735     }
    736 
    737     ACPI_MEMCPY (ACPI_CAST_PTR (char, DestDesc),
    738         ACPI_CAST_PTR (char, SourceDesc), CopySize);
    739 
    740     /* Restore the saved fields */
    741 
    742     DestDesc->Common.ReferenceCount = ReferenceCount;
    743     DestDesc->Common.NextObject = NextObject;
    744 
    745     /* New object is not static, regardless of source */
    746 
    747     DestDesc->Common.Flags &= ~AOPOBJ_STATIC_POINTER;
    748 
    749     /* Handle the objects with extra data */
    750 
    751     switch (DestDesc->Common.Type)
    752     {
    753     case ACPI_TYPE_BUFFER:
    754         /*
    755          * Allocate and copy the actual buffer if and only if:
    756          * 1) There is a valid buffer pointer
    757          * 2) The buffer has a length > 0
    758          */
    759         if ((SourceDesc->Buffer.Pointer) &&
    760             (SourceDesc->Buffer.Length))
    761         {
    762             DestDesc->Buffer.Pointer =
    763                 ACPI_ALLOCATE (SourceDesc->Buffer.Length);
    764             if (!DestDesc->Buffer.Pointer)
    765             {
    766                 return (AE_NO_MEMORY);
    767             }
    768 
    769             /* Copy the actual buffer data */
    770 
    771             ACPI_MEMCPY (DestDesc->Buffer.Pointer,
    772                 SourceDesc->Buffer.Pointer, SourceDesc->Buffer.Length);
    773         }
    774         break;
    775 
    776     case ACPI_TYPE_STRING:
    777         /*
    778          * Allocate and copy the actual string if and only if:
    779          * 1) There is a valid string pointer
    780          * (Pointer to a NULL string is allowed)
    781          */
    782         if (SourceDesc->String.Pointer)
    783         {
    784             DestDesc->String.Pointer =
    785                 ACPI_ALLOCATE ((ACPI_SIZE) SourceDesc->String.Length + 1);
    786             if (!DestDesc->String.Pointer)
    787             {
    788                 return (AE_NO_MEMORY);
    789             }
    790 
    791             /* Copy the actual string data */
    792 
    793             ACPI_MEMCPY (DestDesc->String.Pointer, SourceDesc->String.Pointer,
    794                 (ACPI_SIZE) SourceDesc->String.Length + 1);
    795         }
    796         break;
    797 
    798     case ACPI_TYPE_LOCAL_REFERENCE:
    799         /*
    800          * We copied the reference object, so we now must add a reference
    801          * to the object pointed to by the reference
    802          *
    803          * DDBHandle reference (from Load/LoadTable) is a special reference,
    804          * it does not have a Reference.Object, so does not need to
    805          * increase the reference count
    806          */
    807         if (SourceDesc->Reference.Class == ACPI_REFCLASS_TABLE)
    808         {
    809             break;
    810         }
    811 
    812         AcpiUtAddReference (SourceDesc->Reference.Object);
    813         break;
    814 
    815     case ACPI_TYPE_REGION:
    816         /*
    817          * We copied the Region Handler, so we now must add a reference
    818          */
    819         if (DestDesc->Region.Handler)
    820         {
    821             AcpiUtAddReference (DestDesc->Region.Handler);
    822         }
    823         break;
    824 
    825     /*
    826      * For Mutex and Event objects, we cannot simply copy the underlying
    827      * OS object. We must create a new one.
    828      */
    829     case ACPI_TYPE_MUTEX:
    830 
    831         Status = AcpiOsCreateMutex (&DestDesc->Mutex.OsMutex);
    832         if (ACPI_FAILURE (Status))
    833         {
    834             return (Status);
    835         }
    836         break;
    837 
    838     case ACPI_TYPE_EVENT:
    839 
    840         Status = AcpiOsCreateSemaphore (ACPI_NO_UNIT_LIMIT, 0,
    841                     &DestDesc->Event.OsSemaphore);
    842         if (ACPI_FAILURE (Status))
    843         {
    844             return (Status);
    845         }
    846         break;
    847 
    848     default:
    849 
    850         /* Nothing to do for other simple objects */
    851 
    852         break;
    853     }
    854 
    855     return (AE_OK);
    856 }
    857 
    858 
    859 /*******************************************************************************
    860  *
    861  * FUNCTION:    AcpiUtCopyIelementToIelement
    862  *
    863  * PARAMETERS:  ACPI_PKG_CALLBACK
    864  *
    865  * RETURN:      Status
    866  *
    867  * DESCRIPTION: Copy one package element to another package element
    868  *
    869  ******************************************************************************/
    870 
    871 static ACPI_STATUS
    872 AcpiUtCopyIelementToIelement (
    873     UINT8                   ObjectType,
    874     ACPI_OPERAND_OBJECT     *SourceObject,
    875     ACPI_GENERIC_STATE      *State,
    876     void                    *Context)
    877 {
    878     ACPI_STATUS             Status = AE_OK;
    879     UINT32                  ThisIndex;
    880     ACPI_OPERAND_OBJECT     **ThisTargetPtr;
    881     ACPI_OPERAND_OBJECT     *TargetObject;
    882 
    883 
    884     ACPI_FUNCTION_ENTRY ();
    885 
    886 
    887     ThisIndex     = State->Pkg.Index;
    888     ThisTargetPtr = (ACPI_OPERAND_OBJECT **)
    889                         &State->Pkg.DestObject->Package.Elements[ThisIndex];
    890 
    891     switch (ObjectType)
    892     {
    893     case ACPI_COPY_TYPE_SIMPLE:
    894 
    895         /* A null source object indicates a (legal) null package element */
    896 
    897         if (SourceObject)
    898         {
    899             /*
    900              * This is a simple object, just copy it
    901              */
    902             TargetObject = AcpiUtCreateInternalObject (
    903                                 SourceObject->Common.Type);
    904             if (!TargetObject)
    905             {
    906                 return (AE_NO_MEMORY);
    907             }
    908 
    909             Status = AcpiUtCopySimpleObject (SourceObject, TargetObject);
    910             if (ACPI_FAILURE (Status))
    911             {
    912                 goto ErrorExit;
    913             }
    914 
    915             *ThisTargetPtr = TargetObject;
    916         }
    917         else
    918         {
    919             /* Pass through a null element */
    920 
    921             *ThisTargetPtr = NULL;
    922         }
    923         break;
    924 
    925     case ACPI_COPY_TYPE_PACKAGE:
    926         /*
    927          * This object is a package - go down another nesting level
    928          * Create and build the package object
    929          */
    930         TargetObject = AcpiUtCreatePackageObject (SourceObject->Package.Count);
    931         if (!TargetObject)
    932         {
    933             return (AE_NO_MEMORY);
    934         }
    935 
    936         TargetObject->Common.Flags = SourceObject->Common.Flags;
    937 
    938         /* Pass the new package object back to the package walk routine */
    939 
    940         State->Pkg.ThisTargetObj = TargetObject;
    941 
    942         /* Store the object pointer in the parent package object */
    943 
    944         *ThisTargetPtr = TargetObject;
    945         break;
    946 
    947     default:
    948 
    949         return (AE_BAD_PARAMETER);
    950     }
    951 
    952     return (Status);
    953 
    954 ErrorExit:
    955     AcpiUtRemoveReference (TargetObject);
    956     return (Status);
    957 }
    958 
    959 
    960 /*******************************************************************************
    961  *
    962  * FUNCTION:    AcpiUtCopyIpackageToIpackage
    963  *
    964  * PARAMETERS:  SourceObj       - Pointer to the source package object
    965  *              DestObj         - Where the internal object is returned
    966  *              WalkState       - Current Walk state descriptor
    967  *
    968  * RETURN:      Status
    969  *
    970  * DESCRIPTION: This function is called to copy an internal package object
    971  *              into another internal package object.
    972  *
    973  ******************************************************************************/
    974 
    975 static ACPI_STATUS
    976 AcpiUtCopyIpackageToIpackage (
    977     ACPI_OPERAND_OBJECT     *SourceObj,
    978     ACPI_OPERAND_OBJECT     *DestObj,
    979     ACPI_WALK_STATE         *WalkState)
    980 {
    981     ACPI_STATUS             Status = AE_OK;
    982 
    983 
    984     ACPI_FUNCTION_TRACE (UtCopyIpackageToIpackage);
    985 
    986 
    987     DestObj->Common.Type    = SourceObj->Common.Type;
    988     DestObj->Common.Flags   = SourceObj->Common.Flags;
    989     DestObj->Package.Count  = SourceObj->Package.Count;
    990 
    991     /*
    992      * Create the object array and walk the source package tree
    993      */
    994     DestObj->Package.Elements = ACPI_ALLOCATE_ZEROED (
    995                                     ((ACPI_SIZE) SourceObj->Package.Count + 1) *
    996                                     sizeof (void *));
    997     if (!DestObj->Package.Elements)
    998     {
    999         ACPI_ERROR ((AE_INFO, "Package allocation failure"));
   1000         return_ACPI_STATUS (AE_NO_MEMORY);
   1001     }
   1002 
   1003     /*
   1004      * Copy the package element-by-element by walking the package "tree".
   1005      * This handles nested packages of arbitrary depth.
   1006      */
   1007     Status = AcpiUtWalkPackageTree (SourceObj, DestObj,
   1008                 AcpiUtCopyIelementToIelement, WalkState);
   1009     if (ACPI_FAILURE (Status))
   1010     {
   1011         /* On failure, delete the destination package object */
   1012 
   1013         AcpiUtRemoveReference (DestObj);
   1014     }
   1015 
   1016     return_ACPI_STATUS (Status);
   1017 }
   1018 
   1019 
   1020 /*******************************************************************************
   1021  *
   1022  * FUNCTION:    AcpiUtCopyIobjectToIobject
   1023  *
   1024  * PARAMETERS:  SourceDesc          - The internal object to be copied
   1025  *              DestDesc            - Where the copied object is returned
   1026  *              WalkState           - Current walk state
   1027  *
   1028  * RETURN:      Status
   1029  *
   1030  * DESCRIPTION: Copy an internal object to a new internal object
   1031  *
   1032  ******************************************************************************/
   1033 
   1034 ACPI_STATUS
   1035 AcpiUtCopyIobjectToIobject (
   1036     ACPI_OPERAND_OBJECT     *SourceDesc,
   1037     ACPI_OPERAND_OBJECT     **DestDesc,
   1038     ACPI_WALK_STATE         *WalkState)
   1039 {
   1040     ACPI_STATUS             Status = AE_OK;
   1041 
   1042 
   1043     ACPI_FUNCTION_TRACE (UtCopyIobjectToIobject);
   1044 
   1045 
   1046     /* Create the top level object */
   1047 
   1048     *DestDesc = AcpiUtCreateInternalObject (SourceDesc->Common.Type);
   1049     if (!*DestDesc)
   1050     {
   1051         return_ACPI_STATUS (AE_NO_MEMORY);
   1052     }
   1053 
   1054     /* Copy the object and possible subobjects */
   1055 
   1056     if (SourceDesc->Common.Type == ACPI_TYPE_PACKAGE)
   1057     {
   1058         Status = AcpiUtCopyIpackageToIpackage (SourceDesc, *DestDesc,
   1059                         WalkState);
   1060     }
   1061     else
   1062     {
   1063         Status = AcpiUtCopySimpleObject (SourceDesc, *DestDesc);
   1064     }
   1065 
   1066     return_ACPI_STATUS (Status);
   1067 }
   1068