kernel: Sync ACPICA with Intel's version 20140627.
[dragonfly.git] / sys / contrib / dev / acpica / source / components / utilities / utcopy.c
1 /******************************************************************************
2  *
3  * Module Name: utcopy - Internal to external object translation utilities
4  *
5  *****************************************************************************/
6
7 /*
8  * Copyright (C) 2000 - 2014, Intel Corp.
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions, and the following disclaimer,
16  *    without modification.
17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18  *    substantially similar to the "NO WARRANTY" disclaimer below
19  *    ("Disclaimer") and any redistribution must be conditioned upon
20  *    including a substantially similar Disclaimer requirement for further
21  *    binary redistribution.
22  * 3. Neither the names of the above-listed copyright holders nor the names
23  *    of any contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * Alternatively, this software may be distributed under the terms of the
27  * GNU General Public License ("GPL") version 2 as published by the Free
28  * Software Foundation.
29  *
30  * NO WARRANTY
31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41  * POSSIBILITY OF SUCH DAMAGES.
42  */
43
44 #define __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         /* An incoming reference is defined to be a namespace node */
568
569         InternalObject->Reference.Class = ACPI_REFCLASS_REFOF;
570         InternalObject->Reference.Object = 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     /* Delete the allocated object if copy failed */
1067
1068     if (ACPI_FAILURE (Status))
1069     {
1070         AcpiUtRemoveReference(*DestDesc);
1071     }
1072
1073     return_ACPI_STATUS (Status);
1074 }