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