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