195857638SErik Schmauss // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
295b482a8SLen Brown /******************************************************************************
395b482a8SLen Brown *
495b482a8SLen Brown * Module Name: utcopy - Internal to external object translation utilities
595b482a8SLen Brown *
6*612c2932SBob Moore * Copyright (C) 2000 - 2023, Intel Corp.
795b482a8SLen Brown *
895857638SErik Schmauss *****************************************************************************/
995b482a8SLen Brown
1095b482a8SLen Brown #include <acpi/acpi.h>
11e2f7a777SLen Brown #include "accommon.h"
12e2f7a777SLen Brown #include "acnamesp.h"
1395b482a8SLen Brown
1495b482a8SLen Brown
1595b482a8SLen Brown #define _COMPONENT ACPI_UTILITIES
1695b482a8SLen Brown ACPI_MODULE_NAME("utcopy")
1795b482a8SLen Brown
1895b482a8SLen Brown /* Local prototypes */
1995b482a8SLen Brown static acpi_status
2095b482a8SLen Brown acpi_ut_copy_isimple_to_esimple(union acpi_operand_object *internal_object,
2195b482a8SLen Brown union acpi_object *external_object,
2295b482a8SLen Brown u8 *data_space, acpi_size *buffer_space_used);
2395b482a8SLen Brown
2495b482a8SLen Brown static acpi_status
2595b482a8SLen Brown acpi_ut_copy_ielement_to_ielement(u8 object_type,
2695b482a8SLen Brown union acpi_operand_object *source_object,
2795b482a8SLen Brown union acpi_generic_state *state,
2895b482a8SLen Brown void *context);
2995b482a8SLen Brown
3095b482a8SLen Brown static acpi_status
3195b482a8SLen Brown acpi_ut_copy_ipackage_to_epackage(union acpi_operand_object *internal_object,
3295b482a8SLen Brown u8 *buffer, acpi_size *space_used);
3395b482a8SLen Brown
3495b482a8SLen Brown static acpi_status
3595b482a8SLen Brown acpi_ut_copy_esimple_to_isimple(union acpi_object *user_obj,
3695b482a8SLen Brown union acpi_operand_object **return_obj);
3795b482a8SLen Brown
3895b482a8SLen Brown static acpi_status
3995b482a8SLen Brown acpi_ut_copy_epackage_to_ipackage(union acpi_object *external_object,
4095b482a8SLen Brown union acpi_operand_object **internal_object);
4195b482a8SLen Brown
4295b482a8SLen Brown static acpi_status
4395b482a8SLen Brown acpi_ut_copy_simple_object(union acpi_operand_object *source_desc,
4495b482a8SLen Brown union acpi_operand_object *dest_desc);
4595b482a8SLen Brown
4695b482a8SLen Brown static acpi_status
4795b482a8SLen Brown acpi_ut_copy_ielement_to_eelement(u8 object_type,
4895b482a8SLen Brown union acpi_operand_object *source_object,
4995b482a8SLen Brown union acpi_generic_state *state,
5095b482a8SLen Brown void *context);
5195b482a8SLen Brown
5295b482a8SLen Brown static acpi_status
5395b482a8SLen Brown acpi_ut_copy_ipackage_to_ipackage(union acpi_operand_object *source_obj,
5495b482a8SLen Brown union acpi_operand_object *dest_obj,
5595b482a8SLen Brown struct acpi_walk_state *walk_state);
5695b482a8SLen Brown
5795b482a8SLen Brown /*******************************************************************************
5895b482a8SLen Brown *
5995b482a8SLen Brown * FUNCTION: acpi_ut_copy_isimple_to_esimple
6095b482a8SLen Brown *
6195b482a8SLen Brown * PARAMETERS: internal_object - Source object to be copied
6295b482a8SLen Brown * external_object - Where to return the copied object
6395b482a8SLen Brown * data_space - Where object data is returned (such as
6495b482a8SLen Brown * buffer and string data)
6595b482a8SLen Brown * buffer_space_used - Length of data_space that was used
6695b482a8SLen Brown *
6795b482a8SLen Brown * RETURN: Status
6895b482a8SLen Brown *
6995b482a8SLen Brown * DESCRIPTION: This function is called to copy a simple internal object to
7095b482a8SLen Brown * an external object.
7195b482a8SLen Brown *
7295b482a8SLen Brown * The data_space buffer is assumed to have sufficient space for
7395b482a8SLen Brown * the object.
7495b482a8SLen Brown *
7595b482a8SLen Brown ******************************************************************************/
7695b482a8SLen Brown
7795b482a8SLen Brown static acpi_status
acpi_ut_copy_isimple_to_esimple(union acpi_operand_object * internal_object,union acpi_object * external_object,u8 * data_space,acpi_size * buffer_space_used)7895b482a8SLen Brown acpi_ut_copy_isimple_to_esimple(union acpi_operand_object *internal_object,
7995b482a8SLen Brown union acpi_object *external_object,
8095b482a8SLen Brown u8 *data_space, acpi_size *buffer_space_used)
8195b482a8SLen Brown {
8295b482a8SLen Brown acpi_status status = AE_OK;
8395b482a8SLen Brown
8495b482a8SLen Brown ACPI_FUNCTION_TRACE(ut_copy_isimple_to_esimple);
8595b482a8SLen Brown
8695b482a8SLen Brown *buffer_space_used = 0;
8795b482a8SLen Brown
8895b482a8SLen Brown /*
8995b482a8SLen Brown * Check for NULL object case (could be an uninitialized
9095b482a8SLen Brown * package element)
9195b482a8SLen Brown */
9295b482a8SLen Brown if (!internal_object) {
9395b482a8SLen Brown return_ACPI_STATUS(AE_OK);
9495b482a8SLen Brown }
9595b482a8SLen Brown
9695b482a8SLen Brown /* Always clear the external object */
9795b482a8SLen Brown
984fa4616eSBob Moore memset(external_object, 0, sizeof(union acpi_object));
9995b482a8SLen Brown
10095b482a8SLen Brown /*
10195b482a8SLen Brown * In general, the external object will be the same type as
10295b482a8SLen Brown * the internal object
10395b482a8SLen Brown */
1043371c19cSBob Moore external_object->type = internal_object->common.type;
10595b482a8SLen Brown
10695b482a8SLen Brown /* However, only a limited number of external types are supported */
10795b482a8SLen Brown
1083371c19cSBob Moore switch (internal_object->common.type) {
10995b482a8SLen Brown case ACPI_TYPE_STRING:
11095b482a8SLen Brown
11195b482a8SLen Brown external_object->string.pointer = (char *)data_space;
11295b482a8SLen Brown external_object->string.length = internal_object->string.length;
11395b482a8SLen Brown *buffer_space_used = ACPI_ROUND_UP_TO_NATIVE_WORD((acpi_size)
11495b482a8SLen Brown internal_object->
11595b482a8SLen Brown string.
11695b482a8SLen Brown length + 1);
11795b482a8SLen Brown
1184fa4616eSBob Moore memcpy((void *)data_space,
11995b482a8SLen Brown (void *)internal_object->string.pointer,
12095b482a8SLen Brown (acpi_size)internal_object->string.length + 1);
12195b482a8SLen Brown break;
12295b482a8SLen Brown
12395b482a8SLen Brown case ACPI_TYPE_BUFFER:
12495b482a8SLen Brown
12595b482a8SLen Brown external_object->buffer.pointer = data_space;
12695b482a8SLen Brown external_object->buffer.length = internal_object->buffer.length;
12795b482a8SLen Brown *buffer_space_used =
12895b482a8SLen Brown ACPI_ROUND_UP_TO_NATIVE_WORD(internal_object->string.
12995b482a8SLen Brown length);
13095b482a8SLen Brown
1314fa4616eSBob Moore memcpy((void *)data_space,
13295b482a8SLen Brown (void *)internal_object->buffer.pointer,
13395b482a8SLen Brown internal_object->buffer.length);
13495b482a8SLen Brown break;
13595b482a8SLen Brown
13695b482a8SLen Brown case ACPI_TYPE_INTEGER:
13795b482a8SLen Brown
13895b482a8SLen Brown external_object->integer.value = internal_object->integer.value;
13995b482a8SLen Brown break;
14095b482a8SLen Brown
14195b482a8SLen Brown case ACPI_TYPE_LOCAL_REFERENCE:
14295b482a8SLen Brown
14395b482a8SLen Brown /* This is an object reference. */
14495b482a8SLen Brown
14595b482a8SLen Brown switch (internal_object->reference.class) {
14695b482a8SLen Brown case ACPI_REFCLASS_NAME:
14795b482a8SLen Brown /*
14895b482a8SLen Brown * For namepath, return the object handle ("reference")
14995b482a8SLen Brown * We are referring to the namespace node
15095b482a8SLen Brown */
15195b482a8SLen Brown external_object->reference.handle =
15295b482a8SLen Brown internal_object->reference.node;
15395b482a8SLen Brown external_object->reference.actual_type =
15495b482a8SLen Brown acpi_ns_get_type(internal_object->reference.node);
15595b482a8SLen Brown break;
15695b482a8SLen Brown
15795b482a8SLen Brown default:
15895b482a8SLen Brown
15995b482a8SLen Brown /* All other reference types are unsupported */
16095b482a8SLen Brown
16195b482a8SLen Brown return_ACPI_STATUS(AE_TYPE);
16295b482a8SLen Brown }
16395b482a8SLen Brown break;
16495b482a8SLen Brown
16595b482a8SLen Brown case ACPI_TYPE_PROCESSOR:
16695b482a8SLen Brown
16795b482a8SLen Brown external_object->processor.proc_id =
16895b482a8SLen Brown internal_object->processor.proc_id;
16995b482a8SLen Brown external_object->processor.pblk_address =
17095b482a8SLen Brown internal_object->processor.address;
17195b482a8SLen Brown external_object->processor.pblk_length =
17295b482a8SLen Brown internal_object->processor.length;
17395b482a8SLen Brown break;
17495b482a8SLen Brown
17595b482a8SLen Brown case ACPI_TYPE_POWER:
17695b482a8SLen Brown
17795b482a8SLen Brown external_object->power_resource.system_level =
17895b482a8SLen Brown internal_object->power_resource.system_level;
17995b482a8SLen Brown
18095b482a8SLen Brown external_object->power_resource.resource_order =
18195b482a8SLen Brown internal_object->power_resource.resource_order;
18295b482a8SLen Brown break;
18395b482a8SLen Brown
18495b482a8SLen Brown default:
18595b482a8SLen Brown /*
18695b482a8SLen Brown * There is no corresponding external object type
18795b482a8SLen Brown */
18895b482a8SLen Brown ACPI_ERROR((AE_INFO,
18995b482a8SLen Brown "Unsupported object type, cannot convert to external object: %s",
1903371c19cSBob Moore acpi_ut_get_type_name(internal_object->common.
1913371c19cSBob Moore type)));
19295b482a8SLen Brown
19395b482a8SLen Brown return_ACPI_STATUS(AE_SUPPORT);
19495b482a8SLen Brown }
19595b482a8SLen Brown
19695b482a8SLen Brown return_ACPI_STATUS(status);
19795b482a8SLen Brown }
19895b482a8SLen Brown
19995b482a8SLen Brown /*******************************************************************************
20095b482a8SLen Brown *
20195b482a8SLen Brown * FUNCTION: acpi_ut_copy_ielement_to_eelement
20295b482a8SLen Brown *
20395b482a8SLen Brown * PARAMETERS: acpi_pkg_callback
20495b482a8SLen Brown *
20595b482a8SLen Brown * RETURN: Status
20695b482a8SLen Brown *
20795b482a8SLen Brown * DESCRIPTION: Copy one package element to another package element
20895b482a8SLen Brown *
20995b482a8SLen Brown ******************************************************************************/
21095b482a8SLen Brown
21195b482a8SLen Brown static acpi_status
acpi_ut_copy_ielement_to_eelement(u8 object_type,union acpi_operand_object * source_object,union acpi_generic_state * state,void * context)21295b482a8SLen Brown acpi_ut_copy_ielement_to_eelement(u8 object_type,
21395b482a8SLen Brown union acpi_operand_object *source_object,
21495b482a8SLen Brown union acpi_generic_state *state,
21595b482a8SLen Brown void *context)
21695b482a8SLen Brown {
21795b482a8SLen Brown acpi_status status = AE_OK;
21895b482a8SLen Brown struct acpi_pkg_info *info = (struct acpi_pkg_info *)context;
21995b482a8SLen Brown acpi_size object_space;
22095b482a8SLen Brown u32 this_index;
22195b482a8SLen Brown union acpi_object *target_object;
22295b482a8SLen Brown
22395b482a8SLen Brown ACPI_FUNCTION_ENTRY();
22495b482a8SLen Brown
22595b482a8SLen Brown this_index = state->pkg.index;
2261fad8738SBob Moore target_object = (union acpi_object *)&((union acpi_object *)
2271fad8738SBob Moore (state->pkg.dest_object))->
2281fad8738SBob Moore package.elements[this_index];
22995b482a8SLen Brown
23095b482a8SLen Brown switch (object_type) {
23195b482a8SLen Brown case ACPI_COPY_TYPE_SIMPLE:
23295b482a8SLen Brown /*
23395b482a8SLen Brown * This is a simple or null object
23495b482a8SLen Brown */
23595b482a8SLen Brown status = acpi_ut_copy_isimple_to_esimple(source_object,
23695b482a8SLen Brown target_object,
23795b482a8SLen Brown info->free_space,
23895b482a8SLen Brown &object_space);
23995b482a8SLen Brown if (ACPI_FAILURE(status)) {
24095b482a8SLen Brown return (status);
24195b482a8SLen Brown }
24295b482a8SLen Brown break;
24395b482a8SLen Brown
24495b482a8SLen Brown case ACPI_COPY_TYPE_PACKAGE:
24595b482a8SLen Brown /*
24695b482a8SLen Brown * Build the package object
24795b482a8SLen Brown */
24895b482a8SLen Brown target_object->type = ACPI_TYPE_PACKAGE;
24995b482a8SLen Brown target_object->package.count = source_object->package.count;
25095b482a8SLen Brown target_object->package.elements =
25195b482a8SLen Brown ACPI_CAST_PTR(union acpi_object, info->free_space);
25295b482a8SLen Brown
25395b482a8SLen Brown /*
25495b482a8SLen Brown * Pass the new package object back to the package walk routine
25595b482a8SLen Brown */
25695b482a8SLen Brown state->pkg.this_target_obj = target_object;
25795b482a8SLen Brown
25895b482a8SLen Brown /*
25995b482a8SLen Brown * Save space for the array of objects (Package elements)
26095b482a8SLen Brown * update the buffer length counter
26195b482a8SLen Brown */
26295b482a8SLen Brown object_space = ACPI_ROUND_UP_TO_NATIVE_WORD((acpi_size)
26395b482a8SLen Brown target_object->
26495b482a8SLen Brown package.count *
26595b482a8SLen Brown sizeof(union
26695b482a8SLen Brown acpi_object));
26795b482a8SLen Brown break;
26895b482a8SLen Brown
26995b482a8SLen Brown default:
2701d1ea1b7SChao Guan
27195b482a8SLen Brown return (AE_BAD_PARAMETER);
27295b482a8SLen Brown }
27395b482a8SLen Brown
27495b482a8SLen Brown info->free_space += object_space;
27595b482a8SLen Brown info->length += object_space;
27695b482a8SLen Brown return (status);
27795b482a8SLen Brown }
27895b482a8SLen Brown
27995b482a8SLen Brown /*******************************************************************************
28095b482a8SLen Brown *
28195b482a8SLen Brown * FUNCTION: acpi_ut_copy_ipackage_to_epackage
28295b482a8SLen Brown *
28395b482a8SLen Brown * PARAMETERS: internal_object - Pointer to the object we are returning
284ba494beeSBob Moore * buffer - Where the object is returned
28595b482a8SLen Brown * space_used - Where the object length is returned
28695b482a8SLen Brown *
28795b482a8SLen Brown * RETURN: Status
28895b482a8SLen Brown *
28995b482a8SLen Brown * DESCRIPTION: This function is called to place a package object in a user
29095b482a8SLen Brown * buffer. A package object by definition contains other objects.
29195b482a8SLen Brown *
29295b482a8SLen Brown * The buffer is assumed to have sufficient space for the object.
29390434c1cSBob Moore * The caller must have verified the buffer length needed using
29490434c1cSBob Moore * the acpi_ut_get_object_size function before calling this function.
29595b482a8SLen Brown *
29695b482a8SLen Brown ******************************************************************************/
29795b482a8SLen Brown
29895b482a8SLen Brown static acpi_status
acpi_ut_copy_ipackage_to_epackage(union acpi_operand_object * internal_object,u8 * buffer,acpi_size * space_used)29995b482a8SLen Brown acpi_ut_copy_ipackage_to_epackage(union acpi_operand_object *internal_object,
30095b482a8SLen Brown u8 *buffer, acpi_size *space_used)
30195b482a8SLen Brown {
30295b482a8SLen Brown union acpi_object *external_object;
30395b482a8SLen Brown acpi_status status;
30495b482a8SLen Brown struct acpi_pkg_info info;
30595b482a8SLen Brown
30695b482a8SLen Brown ACPI_FUNCTION_TRACE(ut_copy_ipackage_to_epackage);
30795b482a8SLen Brown
30895b482a8SLen Brown /*
30995b482a8SLen Brown * First package at head of the buffer
31095b482a8SLen Brown */
31195b482a8SLen Brown external_object = ACPI_CAST_PTR(union acpi_object, buffer);
31295b482a8SLen Brown
31395b482a8SLen Brown /*
31495b482a8SLen Brown * Free space begins right after the first package
31595b482a8SLen Brown */
31695b482a8SLen Brown info.length = ACPI_ROUND_UP_TO_NATIVE_WORD(sizeof(union acpi_object));
3171fad8738SBob Moore info.free_space = buffer +
3181fad8738SBob Moore ACPI_ROUND_UP_TO_NATIVE_WORD(sizeof(union acpi_object));
31995b482a8SLen Brown info.object_space = 0;
32095b482a8SLen Brown info.num_packages = 1;
32195b482a8SLen Brown
3223371c19cSBob Moore external_object->type = internal_object->common.type;
32395b482a8SLen Brown external_object->package.count = internal_object->package.count;
3241fad8738SBob Moore external_object->package.elements =
3251fad8738SBob Moore ACPI_CAST_PTR(union acpi_object, info.free_space);
32695b482a8SLen Brown
32795b482a8SLen Brown /*
32895b482a8SLen Brown * Leave room for an array of ACPI_OBJECTS in the buffer
32995b482a8SLen Brown * and move the free space past it
33095b482a8SLen Brown */
33195b482a8SLen Brown info.length += (acpi_size)external_object->package.count *
33295b482a8SLen Brown ACPI_ROUND_UP_TO_NATIVE_WORD(sizeof(union acpi_object));
33395b482a8SLen Brown info.free_space += external_object->package.count *
33495b482a8SLen Brown ACPI_ROUND_UP_TO_NATIVE_WORD(sizeof(union acpi_object));
33595b482a8SLen Brown
33695b482a8SLen Brown status = acpi_ut_walk_package_tree(internal_object, external_object,
33795b482a8SLen Brown acpi_ut_copy_ielement_to_eelement,
33895b482a8SLen Brown &info);
33995b482a8SLen Brown
34095b482a8SLen Brown *space_used = info.length;
34195b482a8SLen Brown return_ACPI_STATUS(status);
34295b482a8SLen Brown }
34395b482a8SLen Brown
34495b482a8SLen Brown /*******************************************************************************
34595b482a8SLen Brown *
34695b482a8SLen Brown * FUNCTION: acpi_ut_copy_iobject_to_eobject
34795b482a8SLen Brown *
34895b482a8SLen Brown * PARAMETERS: internal_object - The internal object to be converted
34990434c1cSBob Moore * ret_buffer - Where the object is returned
35095b482a8SLen Brown *
35195b482a8SLen Brown * RETURN: Status
35295b482a8SLen Brown *
35390434c1cSBob Moore * DESCRIPTION: This function is called to build an API object to be returned
35490434c1cSBob Moore * to the caller.
35595b482a8SLen Brown *
35695b482a8SLen Brown ******************************************************************************/
35795b482a8SLen Brown
35895b482a8SLen Brown acpi_status
acpi_ut_copy_iobject_to_eobject(union acpi_operand_object * internal_object,struct acpi_buffer * ret_buffer)35995b482a8SLen Brown acpi_ut_copy_iobject_to_eobject(union acpi_operand_object *internal_object,
36095b482a8SLen Brown struct acpi_buffer *ret_buffer)
36195b482a8SLen Brown {
36295b482a8SLen Brown acpi_status status;
36395b482a8SLen Brown
36495b482a8SLen Brown ACPI_FUNCTION_TRACE(ut_copy_iobject_to_eobject);
36595b482a8SLen Brown
3663371c19cSBob Moore if (internal_object->common.type == ACPI_TYPE_PACKAGE) {
36795b482a8SLen Brown /*
36895b482a8SLen Brown * Package object: Copy all subobjects (including
36995b482a8SLen Brown * nested packages)
37095b482a8SLen Brown */
37195b482a8SLen Brown status = acpi_ut_copy_ipackage_to_epackage(internal_object,
37295b482a8SLen Brown ret_buffer->pointer,
37395b482a8SLen Brown &ret_buffer->length);
37495b482a8SLen Brown } else {
37595b482a8SLen Brown /*
37695b482a8SLen Brown * Build a simple object (no nested objects)
37795b482a8SLen Brown */
37895b482a8SLen Brown status = acpi_ut_copy_isimple_to_esimple(internal_object,
37995b482a8SLen Brown ACPI_CAST_PTR(union
38095b482a8SLen Brown acpi_object,
38195b482a8SLen Brown ret_buffer->
38295b482a8SLen Brown pointer),
38395b482a8SLen Brown ACPI_ADD_PTR(u8,
38495b482a8SLen Brown ret_buffer->
38595b482a8SLen Brown pointer,
38695b482a8SLen Brown ACPI_ROUND_UP_TO_NATIVE_WORD
38795b482a8SLen Brown (sizeof
38895b482a8SLen Brown (union
38995b482a8SLen Brown acpi_object))),
39095b482a8SLen Brown &ret_buffer->length);
39195b482a8SLen Brown /*
39295b482a8SLen Brown * build simple does not include the object size in the length
39395b482a8SLen Brown * so we add it in here
39495b482a8SLen Brown */
39595b482a8SLen Brown ret_buffer->length += sizeof(union acpi_object);
39695b482a8SLen Brown }
39795b482a8SLen Brown
39895b482a8SLen Brown return_ACPI_STATUS(status);
39995b482a8SLen Brown }
40095b482a8SLen Brown
40195b482a8SLen Brown /*******************************************************************************
40295b482a8SLen Brown *
40395b482a8SLen Brown * FUNCTION: acpi_ut_copy_esimple_to_isimple
40495b482a8SLen Brown *
40595b482a8SLen Brown * PARAMETERS: external_object - The external object to be converted
40695b482a8SLen Brown * ret_internal_object - Where the internal object is returned
40795b482a8SLen Brown *
40895b482a8SLen Brown * RETURN: Status
40995b482a8SLen Brown *
41095b482a8SLen Brown * DESCRIPTION: This function copies an external object to an internal one.
41195b482a8SLen Brown * NOTE: Pointers can be copied, we don't need to copy data.
41295b482a8SLen Brown * (The pointers have to be valid in our address space no matter
41395b482a8SLen Brown * what we do with them!)
41495b482a8SLen Brown *
41595b482a8SLen Brown ******************************************************************************/
41695b482a8SLen Brown
41795b482a8SLen Brown static acpi_status
acpi_ut_copy_esimple_to_isimple(union acpi_object * external_object,union acpi_operand_object ** ret_internal_object)41895b482a8SLen Brown acpi_ut_copy_esimple_to_isimple(union acpi_object *external_object,
41995b482a8SLen Brown union acpi_operand_object **ret_internal_object)
42095b482a8SLen Brown {
42195b482a8SLen Brown union acpi_operand_object *internal_object;
42295b482a8SLen Brown
42395b482a8SLen Brown ACPI_FUNCTION_TRACE(ut_copy_esimple_to_isimple);
42495b482a8SLen Brown
42595b482a8SLen Brown /*
42695b482a8SLen Brown * Simple types supported are: String, Buffer, Integer
42795b482a8SLen Brown */
42895b482a8SLen Brown switch (external_object->type) {
42995b482a8SLen Brown case ACPI_TYPE_STRING:
43095b482a8SLen Brown case ACPI_TYPE_BUFFER:
43195b482a8SLen Brown case ACPI_TYPE_INTEGER:
43295b482a8SLen Brown case ACPI_TYPE_LOCAL_REFERENCE:
43395b482a8SLen Brown
43495b482a8SLen Brown internal_object = acpi_ut_create_internal_object((u8)
43595b482a8SLen Brown external_object->
43695b482a8SLen Brown type);
43795b482a8SLen Brown if (!internal_object) {
43895b482a8SLen Brown return_ACPI_STATUS(AE_NO_MEMORY);
43995b482a8SLen Brown }
44095b482a8SLen Brown break;
44195b482a8SLen Brown
44295b482a8SLen Brown case ACPI_TYPE_ANY: /* This is the case for a NULL object */
44395b482a8SLen Brown
44495b482a8SLen Brown *ret_internal_object = NULL;
44595b482a8SLen Brown return_ACPI_STATUS(AE_OK);
44695b482a8SLen Brown
44795b482a8SLen Brown default:
4481d1ea1b7SChao Guan
44995b482a8SLen Brown /* All other types are not supported */
45095b482a8SLen Brown
45195b482a8SLen Brown ACPI_ERROR((AE_INFO,
45295b482a8SLen Brown "Unsupported object type, cannot convert to internal object: %s",
45395b482a8SLen Brown acpi_ut_get_type_name(external_object->type)));
45495b482a8SLen Brown
45595b482a8SLen Brown return_ACPI_STATUS(AE_SUPPORT);
45695b482a8SLen Brown }
45795b482a8SLen Brown
45895b482a8SLen Brown /* Must COPY string and buffer contents */
45995b482a8SLen Brown
46095b482a8SLen Brown switch (external_object->type) {
46195b482a8SLen Brown case ACPI_TYPE_STRING:
46295b482a8SLen Brown
46395b482a8SLen Brown internal_object->string.pointer =
464ec41f193SBob Moore ACPI_ALLOCATE_ZEROED((acpi_size)
465ec41f193SBob Moore external_object->string.length + 1);
466ec41f193SBob Moore
46795b482a8SLen Brown if (!internal_object->string.pointer) {
46895b482a8SLen Brown goto error_exit;
46995b482a8SLen Brown }
47095b482a8SLen Brown
4714fa4616eSBob Moore memcpy(internal_object->string.pointer,
47295b482a8SLen Brown external_object->string.pointer,
47395b482a8SLen Brown external_object->string.length);
47495b482a8SLen Brown
47595b482a8SLen Brown internal_object->string.length = external_object->string.length;
47695b482a8SLen Brown break;
47795b482a8SLen Brown
47895b482a8SLen Brown case ACPI_TYPE_BUFFER:
47995b482a8SLen Brown
48095b482a8SLen Brown internal_object->buffer.pointer =
48195b482a8SLen Brown ACPI_ALLOCATE_ZEROED(external_object->buffer.length);
48295b482a8SLen Brown if (!internal_object->buffer.pointer) {
48395b482a8SLen Brown goto error_exit;
48495b482a8SLen Brown }
48595b482a8SLen Brown
4864fa4616eSBob Moore memcpy(internal_object->buffer.pointer,
48795b482a8SLen Brown external_object->buffer.pointer,
48895b482a8SLen Brown external_object->buffer.length);
48995b482a8SLen Brown
49095b482a8SLen Brown internal_object->buffer.length = external_object->buffer.length;
49195b482a8SLen Brown
49295b482a8SLen Brown /* Mark buffer data valid */
49395b482a8SLen Brown
49495b482a8SLen Brown internal_object->buffer.flags |= AOPOBJ_DATA_VALID;
49595b482a8SLen Brown break;
49695b482a8SLen Brown
49795b482a8SLen Brown case ACPI_TYPE_INTEGER:
49895b482a8SLen Brown
49995b482a8SLen Brown internal_object->integer.value = external_object->integer.value;
50095b482a8SLen Brown break;
50195b482a8SLen Brown
50295b482a8SLen Brown case ACPI_TYPE_LOCAL_REFERENCE:
50395b482a8SLen Brown
504ab85e928SBob Moore /* An incoming reference is defined to be a namespace node */
50595b482a8SLen Brown
506ab85e928SBob Moore internal_object->reference.class = ACPI_REFCLASS_REFOF;
507ab85e928SBob Moore internal_object->reference.object =
50895b482a8SLen Brown external_object->reference.handle;
50995b482a8SLen Brown break;
51095b482a8SLen Brown
51195b482a8SLen Brown default:
5121d1ea1b7SChao Guan
51395b482a8SLen Brown /* Other types can't get here */
5141d1ea1b7SChao Guan
51595b482a8SLen Brown break;
51695b482a8SLen Brown }
51795b482a8SLen Brown
51895b482a8SLen Brown *ret_internal_object = internal_object;
51995b482a8SLen Brown return_ACPI_STATUS(AE_OK);
52095b482a8SLen Brown
52195b482a8SLen Brown error_exit:
52295b482a8SLen Brown acpi_ut_remove_reference(internal_object);
52395b482a8SLen Brown return_ACPI_STATUS(AE_NO_MEMORY);
52495b482a8SLen Brown }
52595b482a8SLen Brown
52695b482a8SLen Brown /*******************************************************************************
52795b482a8SLen Brown *
52895b482a8SLen Brown * FUNCTION: acpi_ut_copy_epackage_to_ipackage
52995b482a8SLen Brown *
53095b482a8SLen Brown * PARAMETERS: external_object - The external object to be converted
53195b482a8SLen Brown * internal_object - Where the internal object is returned
53295b482a8SLen Brown *
53395b482a8SLen Brown * RETURN: Status
53495b482a8SLen Brown *
53595b482a8SLen Brown * DESCRIPTION: Copy an external package object to an internal package.
53695b482a8SLen Brown * Handles nested packages.
53795b482a8SLen Brown *
53895b482a8SLen Brown ******************************************************************************/
53995b482a8SLen Brown
54095b482a8SLen Brown static acpi_status
acpi_ut_copy_epackage_to_ipackage(union acpi_object * external_object,union acpi_operand_object ** internal_object)54195b482a8SLen Brown acpi_ut_copy_epackage_to_ipackage(union acpi_object *external_object,
54295b482a8SLen Brown union acpi_operand_object **internal_object)
54395b482a8SLen Brown {
54495b482a8SLen Brown acpi_status status = AE_OK;
54595b482a8SLen Brown union acpi_operand_object *package_object;
54695b482a8SLen Brown union acpi_operand_object **package_elements;
54795b482a8SLen Brown u32 i;
54895b482a8SLen Brown
54995b482a8SLen Brown ACPI_FUNCTION_TRACE(ut_copy_epackage_to_ipackage);
55095b482a8SLen Brown
55195b482a8SLen Brown /* Create the package object */
55295b482a8SLen Brown
55395b482a8SLen Brown package_object =
55495b482a8SLen Brown acpi_ut_create_package_object(external_object->package.count);
55595b482a8SLen Brown if (!package_object) {
55695b482a8SLen Brown return_ACPI_STATUS(AE_NO_MEMORY);
55795b482a8SLen Brown }
55895b482a8SLen Brown
55995b482a8SLen Brown package_elements = package_object->package.elements;
56095b482a8SLen Brown
56195b482a8SLen Brown /*
5621fad8738SBob Moore * Recursive implementation. Probably ok, since nested external
5631fad8738SBob Moore * packages as parameters should be very rare.
56495b482a8SLen Brown */
56595b482a8SLen Brown for (i = 0; i < external_object->package.count; i++) {
56695b482a8SLen Brown status =
56795b482a8SLen Brown acpi_ut_copy_eobject_to_iobject(&external_object->package.
56895b482a8SLen Brown elements[i],
56995b482a8SLen Brown &package_elements[i]);
57095b482a8SLen Brown if (ACPI_FAILURE(status)) {
57195b482a8SLen Brown
57295b482a8SLen Brown /* Truncate package and delete it */
57395b482a8SLen Brown
57495b482a8SLen Brown package_object->package.count = i;
57595b482a8SLen Brown package_elements[i] = NULL;
57695b482a8SLen Brown acpi_ut_remove_reference(package_object);
57795b482a8SLen Brown return_ACPI_STATUS(status);
57895b482a8SLen Brown }
57995b482a8SLen Brown }
58095b482a8SLen Brown
58195b482a8SLen Brown /* Mark package data valid */
58295b482a8SLen Brown
58395b482a8SLen Brown package_object->package.flags |= AOPOBJ_DATA_VALID;
58495b482a8SLen Brown
58595b482a8SLen Brown *internal_object = package_object;
58695b482a8SLen Brown return_ACPI_STATUS(status);
58795b482a8SLen Brown }
58895b482a8SLen Brown
58995b482a8SLen Brown /*******************************************************************************
59095b482a8SLen Brown *
59195b482a8SLen Brown * FUNCTION: acpi_ut_copy_eobject_to_iobject
59295b482a8SLen Brown *
59395b482a8SLen Brown * PARAMETERS: external_object - The external object to be converted
59495b482a8SLen Brown * internal_object - Where the internal object is returned
59595b482a8SLen Brown *
59690434c1cSBob Moore * RETURN: Status
59795b482a8SLen Brown *
59895b482a8SLen Brown * DESCRIPTION: Converts an external object to an internal object.
59995b482a8SLen Brown *
60095b482a8SLen Brown ******************************************************************************/
60195b482a8SLen Brown
60295b482a8SLen Brown acpi_status
acpi_ut_copy_eobject_to_iobject(union acpi_object * external_object,union acpi_operand_object ** internal_object)60395b482a8SLen Brown acpi_ut_copy_eobject_to_iobject(union acpi_object *external_object,
60495b482a8SLen Brown union acpi_operand_object **internal_object)
60595b482a8SLen Brown {
60695b482a8SLen Brown acpi_status status;
60795b482a8SLen Brown
60895b482a8SLen Brown ACPI_FUNCTION_TRACE(ut_copy_eobject_to_iobject);
60995b482a8SLen Brown
61095b482a8SLen Brown if (external_object->type == ACPI_TYPE_PACKAGE) {
61195b482a8SLen Brown status =
61295b482a8SLen Brown acpi_ut_copy_epackage_to_ipackage(external_object,
61395b482a8SLen Brown internal_object);
61495b482a8SLen Brown } else {
61595b482a8SLen Brown /*
61695b482a8SLen Brown * Build a simple object (no nested objects)
61795b482a8SLen Brown */
6181fad8738SBob Moore status = acpi_ut_copy_esimple_to_isimple(external_object,
61995b482a8SLen Brown internal_object);
62095b482a8SLen Brown }
62195b482a8SLen Brown
62295b482a8SLen Brown return_ACPI_STATUS(status);
62395b482a8SLen Brown }
62495b482a8SLen Brown
62595b482a8SLen Brown /*******************************************************************************
62695b482a8SLen Brown *
62795b482a8SLen Brown * FUNCTION: acpi_ut_copy_simple_object
62895b482a8SLen Brown *
62995b482a8SLen Brown * PARAMETERS: source_desc - The internal object to be copied
63095b482a8SLen Brown * dest_desc - New target object
63195b482a8SLen Brown *
63295b482a8SLen Brown * RETURN: Status
63395b482a8SLen Brown *
63495b482a8SLen Brown * DESCRIPTION: Simple copy of one internal object to another. Reference count
63595b482a8SLen Brown * of the destination object is preserved.
63695b482a8SLen Brown *
63795b482a8SLen Brown ******************************************************************************/
63895b482a8SLen Brown
63995b482a8SLen Brown static acpi_status
acpi_ut_copy_simple_object(union acpi_operand_object * source_desc,union acpi_operand_object * dest_desc)64095b482a8SLen Brown acpi_ut_copy_simple_object(union acpi_operand_object *source_desc,
64195b482a8SLen Brown union acpi_operand_object *dest_desc)
64295b482a8SLen Brown {
64395b482a8SLen Brown u16 reference_count;
64495b482a8SLen Brown union acpi_operand_object *next_object;
64533a1d461SBob Moore acpi_status status;
64617b82327SLin Ming acpi_size copy_size;
64795b482a8SLen Brown
64895b482a8SLen Brown /* Save fields from destination that we don't want to overwrite */
64995b482a8SLen Brown
65095b482a8SLen Brown reference_count = dest_desc->common.reference_count;
65195b482a8SLen Brown next_object = dest_desc->common.next_object;
65295b482a8SLen Brown
65317b82327SLin Ming /*
65417b82327SLin Ming * Copy the entire source object over the destination object.
65517b82327SLin Ming * Note: Source can be either an operand object or namespace node.
65617b82327SLin Ming */
65717b82327SLin Ming copy_size = sizeof(union acpi_operand_object);
65817b82327SLin Ming if (ACPI_GET_DESCRIPTOR_TYPE(source_desc) == ACPI_DESC_TYPE_NAMED) {
65917b82327SLin Ming copy_size = sizeof(struct acpi_namespace_node);
66017b82327SLin Ming }
66195b482a8SLen Brown
6624fa4616eSBob Moore memcpy(ACPI_CAST_PTR(char, dest_desc),
66317b82327SLin Ming ACPI_CAST_PTR(char, source_desc), copy_size);
66495b482a8SLen Brown
66595b482a8SLen Brown /* Restore the saved fields */
66695b482a8SLen Brown
66795b482a8SLen Brown dest_desc->common.reference_count = reference_count;
66895b482a8SLen Brown dest_desc->common.next_object = next_object;
66995b482a8SLen Brown
67095b482a8SLen Brown /* New object is not static, regardless of source */
67195b482a8SLen Brown
67295b482a8SLen Brown dest_desc->common.flags &= ~AOPOBJ_STATIC_POINTER;
67395b482a8SLen Brown
67495b482a8SLen Brown /* Handle the objects with extra data */
67595b482a8SLen Brown
6763371c19cSBob Moore switch (dest_desc->common.type) {
67795b482a8SLen Brown case ACPI_TYPE_BUFFER:
67895b482a8SLen Brown /*
67995b482a8SLen Brown * Allocate and copy the actual buffer if and only if:
68095b482a8SLen Brown * 1) There is a valid buffer pointer
68195b482a8SLen Brown * 2) The buffer has a length > 0
68295b482a8SLen Brown */
68395b482a8SLen Brown if ((source_desc->buffer.pointer) &&
68495b482a8SLen Brown (source_desc->buffer.length)) {
68595b482a8SLen Brown dest_desc->buffer.pointer =
68695b482a8SLen Brown ACPI_ALLOCATE(source_desc->buffer.length);
68795b482a8SLen Brown if (!dest_desc->buffer.pointer) {
68895b482a8SLen Brown return (AE_NO_MEMORY);
68995b482a8SLen Brown }
69095b482a8SLen Brown
69195b482a8SLen Brown /* Copy the actual buffer data */
69295b482a8SLen Brown
6934fa4616eSBob Moore memcpy(dest_desc->buffer.pointer,
69495b482a8SLen Brown source_desc->buffer.pointer,
69595b482a8SLen Brown source_desc->buffer.length);
69695b482a8SLen Brown }
69795b482a8SLen Brown break;
69895b482a8SLen Brown
69995b482a8SLen Brown case ACPI_TYPE_STRING:
70095b482a8SLen Brown /*
70195b482a8SLen Brown * Allocate and copy the actual string if and only if:
70295b482a8SLen Brown * 1) There is a valid string pointer
70395b482a8SLen Brown * (Pointer to a NULL string is allowed)
70495b482a8SLen Brown */
70595b482a8SLen Brown if (source_desc->string.pointer) {
70695b482a8SLen Brown dest_desc->string.pointer =
70795b482a8SLen Brown ACPI_ALLOCATE((acpi_size)source_desc->string.
70895b482a8SLen Brown length + 1);
70995b482a8SLen Brown if (!dest_desc->string.pointer) {
71095b482a8SLen Brown return (AE_NO_MEMORY);
71195b482a8SLen Brown }
71295b482a8SLen Brown
71395b482a8SLen Brown /* Copy the actual string data */
71495b482a8SLen Brown
7154fa4616eSBob Moore memcpy(dest_desc->string.pointer,
71695b482a8SLen Brown source_desc->string.pointer,
71795b482a8SLen Brown (acpi_size)source_desc->string.length + 1);
71895b482a8SLen Brown }
71995b482a8SLen Brown break;
72095b482a8SLen Brown
72195b482a8SLen Brown case ACPI_TYPE_LOCAL_REFERENCE:
72295b482a8SLen Brown /*
72395b482a8SLen Brown * We copied the reference object, so we now must add a reference
72495b482a8SLen Brown * to the object pointed to by the reference
72595b482a8SLen Brown *
72695b482a8SLen Brown * DDBHandle reference (from Load/load_table) is a special reference,
72795b482a8SLen Brown * it does not have a Reference.Object, so does not need to
72895b482a8SLen Brown * increase the reference count
72995b482a8SLen Brown */
73095b482a8SLen Brown if (source_desc->reference.class == ACPI_REFCLASS_TABLE) {
73195b482a8SLen Brown break;
73295b482a8SLen Brown }
73395b482a8SLen Brown
73495b482a8SLen Brown acpi_ut_add_reference(source_desc->reference.object);
73595b482a8SLen Brown break;
73695b482a8SLen Brown
73795b482a8SLen Brown case ACPI_TYPE_REGION:
73895b482a8SLen Brown /*
73995b482a8SLen Brown * We copied the Region Handler, so we now must add a reference
74095b482a8SLen Brown */
74195b482a8SLen Brown if (dest_desc->region.handler) {
74295b482a8SLen Brown acpi_ut_add_reference(dest_desc->region.handler);
74395b482a8SLen Brown }
74495b482a8SLen Brown break;
74595b482a8SLen Brown
74633a1d461SBob Moore /*
74733a1d461SBob Moore * For Mutex and Event objects, we cannot simply copy the underlying
74833a1d461SBob Moore * OS object. We must create a new one.
74933a1d461SBob Moore */
75033a1d461SBob Moore case ACPI_TYPE_MUTEX:
75133a1d461SBob Moore
75233a1d461SBob Moore status = acpi_os_create_mutex(&dest_desc->mutex.os_mutex);
75333a1d461SBob Moore if (ACPI_FAILURE(status)) {
7549c0d7939SLv Zheng return (status);
75533a1d461SBob Moore }
75633a1d461SBob Moore break;
75733a1d461SBob Moore
75833a1d461SBob Moore case ACPI_TYPE_EVENT:
75933a1d461SBob Moore
76033a1d461SBob Moore status = acpi_os_create_semaphore(ACPI_NO_UNIT_LIMIT, 0,
76133a1d461SBob Moore &dest_desc->event.
76233a1d461SBob Moore os_semaphore);
76333a1d461SBob Moore if (ACPI_FAILURE(status)) {
7649c0d7939SLv Zheng return (status);
76533a1d461SBob Moore }
76633a1d461SBob Moore break;
76733a1d461SBob Moore
76895b482a8SLen Brown default:
7691d1ea1b7SChao Guan
77095b482a8SLen Brown /* Nothing to do for other simple objects */
7711d1ea1b7SChao Guan
77295b482a8SLen Brown break;
77395b482a8SLen Brown }
77495b482a8SLen Brown
77595b482a8SLen Brown return (AE_OK);
77695b482a8SLen Brown }
77795b482a8SLen Brown
77895b482a8SLen Brown /*******************************************************************************
77995b482a8SLen Brown *
78095b482a8SLen Brown * FUNCTION: acpi_ut_copy_ielement_to_ielement
78195b482a8SLen Brown *
78295b482a8SLen Brown * PARAMETERS: acpi_pkg_callback
78395b482a8SLen Brown *
78495b482a8SLen Brown * RETURN: Status
78595b482a8SLen Brown *
78695b482a8SLen Brown * DESCRIPTION: Copy one package element to another package element
78795b482a8SLen Brown *
78895b482a8SLen Brown ******************************************************************************/
78995b482a8SLen Brown
79095b482a8SLen Brown static acpi_status
acpi_ut_copy_ielement_to_ielement(u8 object_type,union acpi_operand_object * source_object,union acpi_generic_state * state,void * context)79195b482a8SLen Brown acpi_ut_copy_ielement_to_ielement(u8 object_type,
79295b482a8SLen Brown union acpi_operand_object *source_object,
79395b482a8SLen Brown union acpi_generic_state *state,
79495b482a8SLen Brown void *context)
79595b482a8SLen Brown {
79695b482a8SLen Brown acpi_status status = AE_OK;
79795b482a8SLen Brown u32 this_index;
79895b482a8SLen Brown union acpi_operand_object **this_target_ptr;
79995b482a8SLen Brown union acpi_operand_object *target_object;
80095b482a8SLen Brown
80195b482a8SLen Brown ACPI_FUNCTION_ENTRY();
80295b482a8SLen Brown
80395b482a8SLen Brown this_index = state->pkg.index;
80495b482a8SLen Brown this_target_ptr = (union acpi_operand_object **)
80595b482a8SLen Brown &state->pkg.dest_object->package.elements[this_index];
80695b482a8SLen Brown
80795b482a8SLen Brown switch (object_type) {
80895b482a8SLen Brown case ACPI_COPY_TYPE_SIMPLE:
80995b482a8SLen Brown
81095b482a8SLen Brown /* A null source object indicates a (legal) null package element */
81195b482a8SLen Brown
81295b482a8SLen Brown if (source_object) {
81395b482a8SLen Brown /*
81495b482a8SLen Brown * This is a simple object, just copy it
81595b482a8SLen Brown */
81695b482a8SLen Brown target_object =
8173371c19cSBob Moore acpi_ut_create_internal_object(source_object->
8183371c19cSBob Moore common.type);
81995b482a8SLen Brown if (!target_object) {
82095b482a8SLen Brown return (AE_NO_MEMORY);
82195b482a8SLen Brown }
82295b482a8SLen Brown
82395b482a8SLen Brown status =
82495b482a8SLen Brown acpi_ut_copy_simple_object(source_object,
82595b482a8SLen Brown target_object);
82695b482a8SLen Brown if (ACPI_FAILURE(status)) {
82795b482a8SLen Brown goto error_exit;
82895b482a8SLen Brown }
82995b482a8SLen Brown
83095b482a8SLen Brown *this_target_ptr = target_object;
83195b482a8SLen Brown } else {
83295b482a8SLen Brown /* Pass through a null element */
83395b482a8SLen Brown
83495b482a8SLen Brown *this_target_ptr = NULL;
83595b482a8SLen Brown }
83695b482a8SLen Brown break;
83795b482a8SLen Brown
83895b482a8SLen Brown case ACPI_COPY_TYPE_PACKAGE:
83995b482a8SLen Brown /*
84095b482a8SLen Brown * This object is a package - go down another nesting level
84195b482a8SLen Brown * Create and build the package object
84295b482a8SLen Brown */
84395b482a8SLen Brown target_object =
84495b482a8SLen Brown acpi_ut_create_package_object(source_object->package.count);
84595b482a8SLen Brown if (!target_object) {
84695b482a8SLen Brown return (AE_NO_MEMORY);
84795b482a8SLen Brown }
84895b482a8SLen Brown
84995b482a8SLen Brown target_object->common.flags = source_object->common.flags;
85095b482a8SLen Brown
85195b482a8SLen Brown /* Pass the new package object back to the package walk routine */
85295b482a8SLen Brown
85395b482a8SLen Brown state->pkg.this_target_obj = target_object;
85495b482a8SLen Brown
85595b482a8SLen Brown /* Store the object pointer in the parent package object */
85695b482a8SLen Brown
85795b482a8SLen Brown *this_target_ptr = target_object;
85895b482a8SLen Brown break;
85995b482a8SLen Brown
86095b482a8SLen Brown default:
8611d1ea1b7SChao Guan
86295b482a8SLen Brown return (AE_BAD_PARAMETER);
86395b482a8SLen Brown }
86495b482a8SLen Brown
86595b482a8SLen Brown return (status);
86695b482a8SLen Brown
86795b482a8SLen Brown error_exit:
86895b482a8SLen Brown acpi_ut_remove_reference(target_object);
86995b482a8SLen Brown return (status);
87095b482a8SLen Brown }
87195b482a8SLen Brown
87295b482a8SLen Brown /*******************************************************************************
87395b482a8SLen Brown *
87495b482a8SLen Brown * FUNCTION: acpi_ut_copy_ipackage_to_ipackage
87595b482a8SLen Brown *
87690434c1cSBob Moore * PARAMETERS: source_obj - Pointer to the source package object
87790434c1cSBob Moore * dest_obj - Where the internal object is returned
87890434c1cSBob Moore * walk_state - Current Walk state descriptor
87995b482a8SLen Brown *
88090434c1cSBob Moore * RETURN: Status
88195b482a8SLen Brown *
88295b482a8SLen Brown * DESCRIPTION: This function is called to copy an internal package object
88395b482a8SLen Brown * into another internal package object.
88495b482a8SLen Brown *
88595b482a8SLen Brown ******************************************************************************/
88695b482a8SLen Brown
88795b482a8SLen Brown static acpi_status
acpi_ut_copy_ipackage_to_ipackage(union acpi_operand_object * source_obj,union acpi_operand_object * dest_obj,struct acpi_walk_state * walk_state)88895b482a8SLen Brown acpi_ut_copy_ipackage_to_ipackage(union acpi_operand_object *source_obj,
88995b482a8SLen Brown union acpi_operand_object *dest_obj,
89095b482a8SLen Brown struct acpi_walk_state *walk_state)
89195b482a8SLen Brown {
89295b482a8SLen Brown acpi_status status = AE_OK;
89395b482a8SLen Brown
89495b482a8SLen Brown ACPI_FUNCTION_TRACE(ut_copy_ipackage_to_ipackage);
89595b482a8SLen Brown
8963371c19cSBob Moore dest_obj->common.type = source_obj->common.type;
89795b482a8SLen Brown dest_obj->common.flags = source_obj->common.flags;
89895b482a8SLen Brown dest_obj->package.count = source_obj->package.count;
89995b482a8SLen Brown
90095b482a8SLen Brown /*
90195b482a8SLen Brown * Create the object array and walk the source package tree
90295b482a8SLen Brown */
90395b482a8SLen Brown dest_obj->package.elements = ACPI_ALLOCATE_ZEROED(((acpi_size)
90495b482a8SLen Brown source_obj->package.
90595b482a8SLen Brown count +
90695b482a8SLen Brown 1) * sizeof(void *));
90795b482a8SLen Brown if (!dest_obj->package.elements) {
90895b482a8SLen Brown ACPI_ERROR((AE_INFO, "Package allocation failure"));
90995b482a8SLen Brown return_ACPI_STATUS(AE_NO_MEMORY);
91095b482a8SLen Brown }
91195b482a8SLen Brown
91295b482a8SLen Brown /*
91395b482a8SLen Brown * Copy the package element-by-element by walking the package "tree".
91495b482a8SLen Brown * This handles nested packages of arbitrary depth.
91595b482a8SLen Brown */
91695b482a8SLen Brown status = acpi_ut_walk_package_tree(source_obj, dest_obj,
91795b482a8SLen Brown acpi_ut_copy_ielement_to_ielement,
91895b482a8SLen Brown walk_state);
91995b482a8SLen Brown return_ACPI_STATUS(status);
92095b482a8SLen Brown }
92195b482a8SLen Brown
92295b482a8SLen Brown /*******************************************************************************
92395b482a8SLen Brown *
92495b482a8SLen Brown * FUNCTION: acpi_ut_copy_iobject_to_iobject
92595b482a8SLen Brown *
92690434c1cSBob Moore * PARAMETERS: source_desc - The internal object to be copied
92795b482a8SLen Brown * dest_desc - Where the copied object is returned
92890434c1cSBob Moore * walk_state - Current walk state
92995b482a8SLen Brown *
93095b482a8SLen Brown * RETURN: Status
93195b482a8SLen Brown *
93295b482a8SLen Brown * DESCRIPTION: Copy an internal object to a new internal object
93395b482a8SLen Brown *
93495b482a8SLen Brown ******************************************************************************/
93595b482a8SLen Brown
93695b482a8SLen Brown acpi_status
acpi_ut_copy_iobject_to_iobject(union acpi_operand_object * source_desc,union acpi_operand_object ** dest_desc,struct acpi_walk_state * walk_state)93795b482a8SLen Brown acpi_ut_copy_iobject_to_iobject(union acpi_operand_object *source_desc,
93895b482a8SLen Brown union acpi_operand_object **dest_desc,
93995b482a8SLen Brown struct acpi_walk_state *walk_state)
94095b482a8SLen Brown {
94195b482a8SLen Brown acpi_status status = AE_OK;
94295b482a8SLen Brown
94395b482a8SLen Brown ACPI_FUNCTION_TRACE(ut_copy_iobject_to_iobject);
94495b482a8SLen Brown
94595b482a8SLen Brown /* Create the top level object */
94695b482a8SLen Brown
9473371c19cSBob Moore *dest_desc = acpi_ut_create_internal_object(source_desc->common.type);
94895b482a8SLen Brown if (!*dest_desc) {
94995b482a8SLen Brown return_ACPI_STATUS(AE_NO_MEMORY);
95095b482a8SLen Brown }
95195b482a8SLen Brown
95295b482a8SLen Brown /* Copy the object and possible subobjects */
95395b482a8SLen Brown
9543371c19cSBob Moore if (source_desc->common.type == ACPI_TYPE_PACKAGE) {
95595b482a8SLen Brown status =
95695b482a8SLen Brown acpi_ut_copy_ipackage_to_ipackage(source_desc, *dest_desc,
95795b482a8SLen Brown walk_state);
95895b482a8SLen Brown } else {
95995b482a8SLen Brown status = acpi_ut_copy_simple_object(source_desc, *dest_desc);
96095b482a8SLen Brown }
96195b482a8SLen Brown
9628aa5e56eSDavid E. Box /* Delete the allocated object if copy failed */
9638aa5e56eSDavid E. Box
9648aa5e56eSDavid E. Box if (ACPI_FAILURE(status)) {
9658aa5e56eSDavid E. Box acpi_ut_remove_reference(*dest_desc);
9668aa5e56eSDavid E. Box }
9678aa5e56eSDavid E. Box
96895b482a8SLen Brown return_ACPI_STATUS(status);
96995b482a8SLen Brown }
970