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