162306a36Sopenharmony_ci// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
262306a36Sopenharmony_ci/******************************************************************************
362306a36Sopenharmony_ci *
462306a36Sopenharmony_ci * Module Name: utcopy - Internal to external object translation utilities
562306a36Sopenharmony_ci *
662306a36Sopenharmony_ci * Copyright (C) 2000 - 2023, Intel Corp.
762306a36Sopenharmony_ci *
862306a36Sopenharmony_ci *****************************************************************************/
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci#include <acpi/acpi.h>
1162306a36Sopenharmony_ci#include "accommon.h"
1262306a36Sopenharmony_ci#include "acnamesp.h"
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci#define _COMPONENT          ACPI_UTILITIES
1662306a36Sopenharmony_ciACPI_MODULE_NAME("utcopy")
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ci/* Local prototypes */
1962306a36Sopenharmony_cistatic acpi_status
2062306a36Sopenharmony_ciacpi_ut_copy_isimple_to_esimple(union acpi_operand_object *internal_object,
2162306a36Sopenharmony_ci				union acpi_object *external_object,
2262306a36Sopenharmony_ci				u8 *data_space, acpi_size *buffer_space_used);
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_cistatic acpi_status
2562306a36Sopenharmony_ciacpi_ut_copy_ielement_to_ielement(u8 object_type,
2662306a36Sopenharmony_ci				  union acpi_operand_object *source_object,
2762306a36Sopenharmony_ci				  union acpi_generic_state *state,
2862306a36Sopenharmony_ci				  void *context);
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_cistatic acpi_status
3162306a36Sopenharmony_ciacpi_ut_copy_ipackage_to_epackage(union acpi_operand_object *internal_object,
3262306a36Sopenharmony_ci				  u8 *buffer, acpi_size *space_used);
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_cistatic acpi_status
3562306a36Sopenharmony_ciacpi_ut_copy_esimple_to_isimple(union acpi_object *user_obj,
3662306a36Sopenharmony_ci				union acpi_operand_object **return_obj);
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_cistatic acpi_status
3962306a36Sopenharmony_ciacpi_ut_copy_epackage_to_ipackage(union acpi_object *external_object,
4062306a36Sopenharmony_ci				  union acpi_operand_object **internal_object);
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_cistatic acpi_status
4362306a36Sopenharmony_ciacpi_ut_copy_simple_object(union acpi_operand_object *source_desc,
4462306a36Sopenharmony_ci			   union acpi_operand_object *dest_desc);
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_cistatic acpi_status
4762306a36Sopenharmony_ciacpi_ut_copy_ielement_to_eelement(u8 object_type,
4862306a36Sopenharmony_ci				  union acpi_operand_object *source_object,
4962306a36Sopenharmony_ci				  union acpi_generic_state *state,
5062306a36Sopenharmony_ci				  void *context);
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_cistatic acpi_status
5362306a36Sopenharmony_ciacpi_ut_copy_ipackage_to_ipackage(union acpi_operand_object *source_obj,
5462306a36Sopenharmony_ci				  union acpi_operand_object *dest_obj,
5562306a36Sopenharmony_ci				  struct acpi_walk_state *walk_state);
5662306a36Sopenharmony_ci
5762306a36Sopenharmony_ci/*******************************************************************************
5862306a36Sopenharmony_ci *
5962306a36Sopenharmony_ci * FUNCTION:    acpi_ut_copy_isimple_to_esimple
6062306a36Sopenharmony_ci *
6162306a36Sopenharmony_ci * PARAMETERS:  internal_object     - Source object to be copied
6262306a36Sopenharmony_ci *              external_object     - Where to return the copied object
6362306a36Sopenharmony_ci *              data_space          - Where object data is returned (such as
6462306a36Sopenharmony_ci *                                    buffer and string data)
6562306a36Sopenharmony_ci *              buffer_space_used   - Length of data_space that was used
6662306a36Sopenharmony_ci *
6762306a36Sopenharmony_ci * RETURN:      Status
6862306a36Sopenharmony_ci *
6962306a36Sopenharmony_ci * DESCRIPTION: This function is called to copy a simple internal object to
7062306a36Sopenharmony_ci *              an external object.
7162306a36Sopenharmony_ci *
7262306a36Sopenharmony_ci *              The data_space buffer is assumed to have sufficient space for
7362306a36Sopenharmony_ci *              the object.
7462306a36Sopenharmony_ci *
7562306a36Sopenharmony_ci ******************************************************************************/
7662306a36Sopenharmony_ci
7762306a36Sopenharmony_cistatic acpi_status
7862306a36Sopenharmony_ciacpi_ut_copy_isimple_to_esimple(union acpi_operand_object *internal_object,
7962306a36Sopenharmony_ci				union acpi_object *external_object,
8062306a36Sopenharmony_ci				u8 *data_space, acpi_size *buffer_space_used)
8162306a36Sopenharmony_ci{
8262306a36Sopenharmony_ci	acpi_status status = AE_OK;
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_ci	ACPI_FUNCTION_TRACE(ut_copy_isimple_to_esimple);
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_ci	*buffer_space_used = 0;
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_ci	/*
8962306a36Sopenharmony_ci	 * Check for NULL object case (could be an uninitialized
9062306a36Sopenharmony_ci	 * package element)
9162306a36Sopenharmony_ci	 */
9262306a36Sopenharmony_ci	if (!internal_object) {
9362306a36Sopenharmony_ci		return_ACPI_STATUS(AE_OK);
9462306a36Sopenharmony_ci	}
9562306a36Sopenharmony_ci
9662306a36Sopenharmony_ci	/* Always clear the external object */
9762306a36Sopenharmony_ci
9862306a36Sopenharmony_ci	memset(external_object, 0, sizeof(union acpi_object));
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_ci	/*
10162306a36Sopenharmony_ci	 * In general, the external object will be the same type as
10262306a36Sopenharmony_ci	 * the internal object
10362306a36Sopenharmony_ci	 */
10462306a36Sopenharmony_ci	external_object->type = internal_object->common.type;
10562306a36Sopenharmony_ci
10662306a36Sopenharmony_ci	/* However, only a limited number of external types are supported */
10762306a36Sopenharmony_ci
10862306a36Sopenharmony_ci	switch (internal_object->common.type) {
10962306a36Sopenharmony_ci	case ACPI_TYPE_STRING:
11062306a36Sopenharmony_ci
11162306a36Sopenharmony_ci		external_object->string.pointer = (char *)data_space;
11262306a36Sopenharmony_ci		external_object->string.length = internal_object->string.length;
11362306a36Sopenharmony_ci		*buffer_space_used = ACPI_ROUND_UP_TO_NATIVE_WORD((acpi_size)
11462306a36Sopenharmony_ci								  internal_object->
11562306a36Sopenharmony_ci								  string.
11662306a36Sopenharmony_ci								  length + 1);
11762306a36Sopenharmony_ci
11862306a36Sopenharmony_ci		memcpy((void *)data_space,
11962306a36Sopenharmony_ci		       (void *)internal_object->string.pointer,
12062306a36Sopenharmony_ci		       (acpi_size)internal_object->string.length + 1);
12162306a36Sopenharmony_ci		break;
12262306a36Sopenharmony_ci
12362306a36Sopenharmony_ci	case ACPI_TYPE_BUFFER:
12462306a36Sopenharmony_ci
12562306a36Sopenharmony_ci		external_object->buffer.pointer = data_space;
12662306a36Sopenharmony_ci		external_object->buffer.length = internal_object->buffer.length;
12762306a36Sopenharmony_ci		*buffer_space_used =
12862306a36Sopenharmony_ci		    ACPI_ROUND_UP_TO_NATIVE_WORD(internal_object->string.
12962306a36Sopenharmony_ci						 length);
13062306a36Sopenharmony_ci
13162306a36Sopenharmony_ci		memcpy((void *)data_space,
13262306a36Sopenharmony_ci		       (void *)internal_object->buffer.pointer,
13362306a36Sopenharmony_ci		       internal_object->buffer.length);
13462306a36Sopenharmony_ci		break;
13562306a36Sopenharmony_ci
13662306a36Sopenharmony_ci	case ACPI_TYPE_INTEGER:
13762306a36Sopenharmony_ci
13862306a36Sopenharmony_ci		external_object->integer.value = internal_object->integer.value;
13962306a36Sopenharmony_ci		break;
14062306a36Sopenharmony_ci
14162306a36Sopenharmony_ci	case ACPI_TYPE_LOCAL_REFERENCE:
14262306a36Sopenharmony_ci
14362306a36Sopenharmony_ci		/* This is an object reference. */
14462306a36Sopenharmony_ci
14562306a36Sopenharmony_ci		switch (internal_object->reference.class) {
14662306a36Sopenharmony_ci		case ACPI_REFCLASS_NAME:
14762306a36Sopenharmony_ci			/*
14862306a36Sopenharmony_ci			 * For namepath, return the object handle ("reference")
14962306a36Sopenharmony_ci			 * We are referring to the namespace node
15062306a36Sopenharmony_ci			 */
15162306a36Sopenharmony_ci			external_object->reference.handle =
15262306a36Sopenharmony_ci			    internal_object->reference.node;
15362306a36Sopenharmony_ci			external_object->reference.actual_type =
15462306a36Sopenharmony_ci			    acpi_ns_get_type(internal_object->reference.node);
15562306a36Sopenharmony_ci			break;
15662306a36Sopenharmony_ci
15762306a36Sopenharmony_ci		default:
15862306a36Sopenharmony_ci
15962306a36Sopenharmony_ci			/* All other reference types are unsupported */
16062306a36Sopenharmony_ci
16162306a36Sopenharmony_ci			return_ACPI_STATUS(AE_TYPE);
16262306a36Sopenharmony_ci		}
16362306a36Sopenharmony_ci		break;
16462306a36Sopenharmony_ci
16562306a36Sopenharmony_ci	case ACPI_TYPE_PROCESSOR:
16662306a36Sopenharmony_ci
16762306a36Sopenharmony_ci		external_object->processor.proc_id =
16862306a36Sopenharmony_ci		    internal_object->processor.proc_id;
16962306a36Sopenharmony_ci		external_object->processor.pblk_address =
17062306a36Sopenharmony_ci		    internal_object->processor.address;
17162306a36Sopenharmony_ci		external_object->processor.pblk_length =
17262306a36Sopenharmony_ci		    internal_object->processor.length;
17362306a36Sopenharmony_ci		break;
17462306a36Sopenharmony_ci
17562306a36Sopenharmony_ci	case ACPI_TYPE_POWER:
17662306a36Sopenharmony_ci
17762306a36Sopenharmony_ci		external_object->power_resource.system_level =
17862306a36Sopenharmony_ci		    internal_object->power_resource.system_level;
17962306a36Sopenharmony_ci
18062306a36Sopenharmony_ci		external_object->power_resource.resource_order =
18162306a36Sopenharmony_ci		    internal_object->power_resource.resource_order;
18262306a36Sopenharmony_ci		break;
18362306a36Sopenharmony_ci
18462306a36Sopenharmony_ci	default:
18562306a36Sopenharmony_ci		/*
18662306a36Sopenharmony_ci		 * There is no corresponding external object type
18762306a36Sopenharmony_ci		 */
18862306a36Sopenharmony_ci		ACPI_ERROR((AE_INFO,
18962306a36Sopenharmony_ci			    "Unsupported object type, cannot convert to external object: %s",
19062306a36Sopenharmony_ci			    acpi_ut_get_type_name(internal_object->common.
19162306a36Sopenharmony_ci						  type)));
19262306a36Sopenharmony_ci
19362306a36Sopenharmony_ci		return_ACPI_STATUS(AE_SUPPORT);
19462306a36Sopenharmony_ci	}
19562306a36Sopenharmony_ci
19662306a36Sopenharmony_ci	return_ACPI_STATUS(status);
19762306a36Sopenharmony_ci}
19862306a36Sopenharmony_ci
19962306a36Sopenharmony_ci/*******************************************************************************
20062306a36Sopenharmony_ci *
20162306a36Sopenharmony_ci * FUNCTION:    acpi_ut_copy_ielement_to_eelement
20262306a36Sopenharmony_ci *
20362306a36Sopenharmony_ci * PARAMETERS:  acpi_pkg_callback
20462306a36Sopenharmony_ci *
20562306a36Sopenharmony_ci * RETURN:      Status
20662306a36Sopenharmony_ci *
20762306a36Sopenharmony_ci * DESCRIPTION: Copy one package element to another package element
20862306a36Sopenharmony_ci *
20962306a36Sopenharmony_ci ******************************************************************************/
21062306a36Sopenharmony_ci
21162306a36Sopenharmony_cistatic acpi_status
21262306a36Sopenharmony_ciacpi_ut_copy_ielement_to_eelement(u8 object_type,
21362306a36Sopenharmony_ci				  union acpi_operand_object *source_object,
21462306a36Sopenharmony_ci				  union acpi_generic_state *state,
21562306a36Sopenharmony_ci				  void *context)
21662306a36Sopenharmony_ci{
21762306a36Sopenharmony_ci	acpi_status status = AE_OK;
21862306a36Sopenharmony_ci	struct acpi_pkg_info *info = (struct acpi_pkg_info *)context;
21962306a36Sopenharmony_ci	acpi_size object_space;
22062306a36Sopenharmony_ci	u32 this_index;
22162306a36Sopenharmony_ci	union acpi_object *target_object;
22262306a36Sopenharmony_ci
22362306a36Sopenharmony_ci	ACPI_FUNCTION_ENTRY();
22462306a36Sopenharmony_ci
22562306a36Sopenharmony_ci	this_index = state->pkg.index;
22662306a36Sopenharmony_ci	target_object = (union acpi_object *)&((union acpi_object *)
22762306a36Sopenharmony_ci					       (state->pkg.dest_object))->
22862306a36Sopenharmony_ci	    package.elements[this_index];
22962306a36Sopenharmony_ci
23062306a36Sopenharmony_ci	switch (object_type) {
23162306a36Sopenharmony_ci	case ACPI_COPY_TYPE_SIMPLE:
23262306a36Sopenharmony_ci		/*
23362306a36Sopenharmony_ci		 * This is a simple or null object
23462306a36Sopenharmony_ci		 */
23562306a36Sopenharmony_ci		status = acpi_ut_copy_isimple_to_esimple(source_object,
23662306a36Sopenharmony_ci							 target_object,
23762306a36Sopenharmony_ci							 info->free_space,
23862306a36Sopenharmony_ci							 &object_space);
23962306a36Sopenharmony_ci		if (ACPI_FAILURE(status)) {
24062306a36Sopenharmony_ci			return (status);
24162306a36Sopenharmony_ci		}
24262306a36Sopenharmony_ci		break;
24362306a36Sopenharmony_ci
24462306a36Sopenharmony_ci	case ACPI_COPY_TYPE_PACKAGE:
24562306a36Sopenharmony_ci		/*
24662306a36Sopenharmony_ci		 * Build the package object
24762306a36Sopenharmony_ci		 */
24862306a36Sopenharmony_ci		target_object->type = ACPI_TYPE_PACKAGE;
24962306a36Sopenharmony_ci		target_object->package.count = source_object->package.count;
25062306a36Sopenharmony_ci		target_object->package.elements =
25162306a36Sopenharmony_ci		    ACPI_CAST_PTR(union acpi_object, info->free_space);
25262306a36Sopenharmony_ci
25362306a36Sopenharmony_ci		/*
25462306a36Sopenharmony_ci		 * Pass the new package object back to the package walk routine
25562306a36Sopenharmony_ci		 */
25662306a36Sopenharmony_ci		state->pkg.this_target_obj = target_object;
25762306a36Sopenharmony_ci
25862306a36Sopenharmony_ci		/*
25962306a36Sopenharmony_ci		 * Save space for the array of objects (Package elements)
26062306a36Sopenharmony_ci		 * update the buffer length counter
26162306a36Sopenharmony_ci		 */
26262306a36Sopenharmony_ci		object_space = ACPI_ROUND_UP_TO_NATIVE_WORD((acpi_size)
26362306a36Sopenharmony_ci							    target_object->
26462306a36Sopenharmony_ci							    package.count *
26562306a36Sopenharmony_ci							    sizeof(union
26662306a36Sopenharmony_ci								   acpi_object));
26762306a36Sopenharmony_ci		break;
26862306a36Sopenharmony_ci
26962306a36Sopenharmony_ci	default:
27062306a36Sopenharmony_ci
27162306a36Sopenharmony_ci		return (AE_BAD_PARAMETER);
27262306a36Sopenharmony_ci	}
27362306a36Sopenharmony_ci
27462306a36Sopenharmony_ci	info->free_space += object_space;
27562306a36Sopenharmony_ci	info->length += object_space;
27662306a36Sopenharmony_ci	return (status);
27762306a36Sopenharmony_ci}
27862306a36Sopenharmony_ci
27962306a36Sopenharmony_ci/*******************************************************************************
28062306a36Sopenharmony_ci *
28162306a36Sopenharmony_ci * FUNCTION:    acpi_ut_copy_ipackage_to_epackage
28262306a36Sopenharmony_ci *
28362306a36Sopenharmony_ci * PARAMETERS:  internal_object     - Pointer to the object we are returning
28462306a36Sopenharmony_ci *              buffer              - Where the object is returned
28562306a36Sopenharmony_ci *              space_used          - Where the object length is returned
28662306a36Sopenharmony_ci *
28762306a36Sopenharmony_ci * RETURN:      Status
28862306a36Sopenharmony_ci *
28962306a36Sopenharmony_ci * DESCRIPTION: This function is called to place a package object in a user
29062306a36Sopenharmony_ci *              buffer. A package object by definition contains other objects.
29162306a36Sopenharmony_ci *
29262306a36Sopenharmony_ci *              The buffer is assumed to have sufficient space for the object.
29362306a36Sopenharmony_ci *              The caller must have verified the buffer length needed using
29462306a36Sopenharmony_ci *              the acpi_ut_get_object_size function before calling this function.
29562306a36Sopenharmony_ci *
29662306a36Sopenharmony_ci ******************************************************************************/
29762306a36Sopenharmony_ci
29862306a36Sopenharmony_cistatic acpi_status
29962306a36Sopenharmony_ciacpi_ut_copy_ipackage_to_epackage(union acpi_operand_object *internal_object,
30062306a36Sopenharmony_ci				  u8 *buffer, acpi_size *space_used)
30162306a36Sopenharmony_ci{
30262306a36Sopenharmony_ci	union acpi_object *external_object;
30362306a36Sopenharmony_ci	acpi_status status;
30462306a36Sopenharmony_ci	struct acpi_pkg_info info;
30562306a36Sopenharmony_ci
30662306a36Sopenharmony_ci	ACPI_FUNCTION_TRACE(ut_copy_ipackage_to_epackage);
30762306a36Sopenharmony_ci
30862306a36Sopenharmony_ci	/*
30962306a36Sopenharmony_ci	 * First package at head of the buffer
31062306a36Sopenharmony_ci	 */
31162306a36Sopenharmony_ci	external_object = ACPI_CAST_PTR(union acpi_object, buffer);
31262306a36Sopenharmony_ci
31362306a36Sopenharmony_ci	/*
31462306a36Sopenharmony_ci	 * Free space begins right after the first package
31562306a36Sopenharmony_ci	 */
31662306a36Sopenharmony_ci	info.length = ACPI_ROUND_UP_TO_NATIVE_WORD(sizeof(union acpi_object));
31762306a36Sopenharmony_ci	info.free_space = buffer +
31862306a36Sopenharmony_ci	    ACPI_ROUND_UP_TO_NATIVE_WORD(sizeof(union acpi_object));
31962306a36Sopenharmony_ci	info.object_space = 0;
32062306a36Sopenharmony_ci	info.num_packages = 1;
32162306a36Sopenharmony_ci
32262306a36Sopenharmony_ci	external_object->type = internal_object->common.type;
32362306a36Sopenharmony_ci	external_object->package.count = internal_object->package.count;
32462306a36Sopenharmony_ci	external_object->package.elements =
32562306a36Sopenharmony_ci	    ACPI_CAST_PTR(union acpi_object, info.free_space);
32662306a36Sopenharmony_ci
32762306a36Sopenharmony_ci	/*
32862306a36Sopenharmony_ci	 * Leave room for an array of ACPI_OBJECTS in the buffer
32962306a36Sopenharmony_ci	 * and move the free space past it
33062306a36Sopenharmony_ci	 */
33162306a36Sopenharmony_ci	info.length += (acpi_size)external_object->package.count *
33262306a36Sopenharmony_ci	    ACPI_ROUND_UP_TO_NATIVE_WORD(sizeof(union acpi_object));
33362306a36Sopenharmony_ci	info.free_space += external_object->package.count *
33462306a36Sopenharmony_ci	    ACPI_ROUND_UP_TO_NATIVE_WORD(sizeof(union acpi_object));
33562306a36Sopenharmony_ci
33662306a36Sopenharmony_ci	status = acpi_ut_walk_package_tree(internal_object, external_object,
33762306a36Sopenharmony_ci					   acpi_ut_copy_ielement_to_eelement,
33862306a36Sopenharmony_ci					   &info);
33962306a36Sopenharmony_ci
34062306a36Sopenharmony_ci	*space_used = info.length;
34162306a36Sopenharmony_ci	return_ACPI_STATUS(status);
34262306a36Sopenharmony_ci}
34362306a36Sopenharmony_ci
34462306a36Sopenharmony_ci/*******************************************************************************
34562306a36Sopenharmony_ci *
34662306a36Sopenharmony_ci * FUNCTION:    acpi_ut_copy_iobject_to_eobject
34762306a36Sopenharmony_ci *
34862306a36Sopenharmony_ci * PARAMETERS:  internal_object     - The internal object to be converted
34962306a36Sopenharmony_ci *              ret_buffer          - Where the object is returned
35062306a36Sopenharmony_ci *
35162306a36Sopenharmony_ci * RETURN:      Status
35262306a36Sopenharmony_ci *
35362306a36Sopenharmony_ci * DESCRIPTION: This function is called to build an API object to be returned
35462306a36Sopenharmony_ci *              to the caller.
35562306a36Sopenharmony_ci *
35662306a36Sopenharmony_ci ******************************************************************************/
35762306a36Sopenharmony_ci
35862306a36Sopenharmony_ciacpi_status
35962306a36Sopenharmony_ciacpi_ut_copy_iobject_to_eobject(union acpi_operand_object *internal_object,
36062306a36Sopenharmony_ci				struct acpi_buffer *ret_buffer)
36162306a36Sopenharmony_ci{
36262306a36Sopenharmony_ci	acpi_status status;
36362306a36Sopenharmony_ci
36462306a36Sopenharmony_ci	ACPI_FUNCTION_TRACE(ut_copy_iobject_to_eobject);
36562306a36Sopenharmony_ci
36662306a36Sopenharmony_ci	if (internal_object->common.type == ACPI_TYPE_PACKAGE) {
36762306a36Sopenharmony_ci		/*
36862306a36Sopenharmony_ci		 * Package object:  Copy all subobjects (including
36962306a36Sopenharmony_ci		 * nested packages)
37062306a36Sopenharmony_ci		 */
37162306a36Sopenharmony_ci		status = acpi_ut_copy_ipackage_to_epackage(internal_object,
37262306a36Sopenharmony_ci							   ret_buffer->pointer,
37362306a36Sopenharmony_ci							   &ret_buffer->length);
37462306a36Sopenharmony_ci	} else {
37562306a36Sopenharmony_ci		/*
37662306a36Sopenharmony_ci		 * Build a simple object (no nested objects)
37762306a36Sopenharmony_ci		 */
37862306a36Sopenharmony_ci		status = acpi_ut_copy_isimple_to_esimple(internal_object,
37962306a36Sopenharmony_ci							 ACPI_CAST_PTR(union
38062306a36Sopenharmony_ci								       acpi_object,
38162306a36Sopenharmony_ci								       ret_buffer->
38262306a36Sopenharmony_ci								       pointer),
38362306a36Sopenharmony_ci							 ACPI_ADD_PTR(u8,
38462306a36Sopenharmony_ci								      ret_buffer->
38562306a36Sopenharmony_ci								      pointer,
38662306a36Sopenharmony_ci								      ACPI_ROUND_UP_TO_NATIVE_WORD
38762306a36Sopenharmony_ci								      (sizeof
38862306a36Sopenharmony_ci								       (union
38962306a36Sopenharmony_ci									acpi_object))),
39062306a36Sopenharmony_ci							 &ret_buffer->length);
39162306a36Sopenharmony_ci		/*
39262306a36Sopenharmony_ci		 * build simple does not include the object size in the length
39362306a36Sopenharmony_ci		 * so we add it in here
39462306a36Sopenharmony_ci		 */
39562306a36Sopenharmony_ci		ret_buffer->length += sizeof(union acpi_object);
39662306a36Sopenharmony_ci	}
39762306a36Sopenharmony_ci
39862306a36Sopenharmony_ci	return_ACPI_STATUS(status);
39962306a36Sopenharmony_ci}
40062306a36Sopenharmony_ci
40162306a36Sopenharmony_ci/*******************************************************************************
40262306a36Sopenharmony_ci *
40362306a36Sopenharmony_ci * FUNCTION:    acpi_ut_copy_esimple_to_isimple
40462306a36Sopenharmony_ci *
40562306a36Sopenharmony_ci * PARAMETERS:  external_object     - The external object to be converted
40662306a36Sopenharmony_ci *              ret_internal_object - Where the internal object is returned
40762306a36Sopenharmony_ci *
40862306a36Sopenharmony_ci * RETURN:      Status
40962306a36Sopenharmony_ci *
41062306a36Sopenharmony_ci * DESCRIPTION: This function copies an external object to an internal one.
41162306a36Sopenharmony_ci *              NOTE: Pointers can be copied, we don't need to copy data.
41262306a36Sopenharmony_ci *              (The pointers have to be valid in our address space no matter
41362306a36Sopenharmony_ci *              what we do with them!)
41462306a36Sopenharmony_ci *
41562306a36Sopenharmony_ci ******************************************************************************/
41662306a36Sopenharmony_ci
41762306a36Sopenharmony_cistatic acpi_status
41862306a36Sopenharmony_ciacpi_ut_copy_esimple_to_isimple(union acpi_object *external_object,
41962306a36Sopenharmony_ci				union acpi_operand_object **ret_internal_object)
42062306a36Sopenharmony_ci{
42162306a36Sopenharmony_ci	union acpi_operand_object *internal_object;
42262306a36Sopenharmony_ci
42362306a36Sopenharmony_ci	ACPI_FUNCTION_TRACE(ut_copy_esimple_to_isimple);
42462306a36Sopenharmony_ci
42562306a36Sopenharmony_ci	/*
42662306a36Sopenharmony_ci	 * Simple types supported are: String, Buffer, Integer
42762306a36Sopenharmony_ci	 */
42862306a36Sopenharmony_ci	switch (external_object->type) {
42962306a36Sopenharmony_ci	case ACPI_TYPE_STRING:
43062306a36Sopenharmony_ci	case ACPI_TYPE_BUFFER:
43162306a36Sopenharmony_ci	case ACPI_TYPE_INTEGER:
43262306a36Sopenharmony_ci	case ACPI_TYPE_LOCAL_REFERENCE:
43362306a36Sopenharmony_ci
43462306a36Sopenharmony_ci		internal_object = acpi_ut_create_internal_object((u8)
43562306a36Sopenharmony_ci								 external_object->
43662306a36Sopenharmony_ci								 type);
43762306a36Sopenharmony_ci		if (!internal_object) {
43862306a36Sopenharmony_ci			return_ACPI_STATUS(AE_NO_MEMORY);
43962306a36Sopenharmony_ci		}
44062306a36Sopenharmony_ci		break;
44162306a36Sopenharmony_ci
44262306a36Sopenharmony_ci	case ACPI_TYPE_ANY:	/* This is the case for a NULL object */
44362306a36Sopenharmony_ci
44462306a36Sopenharmony_ci		*ret_internal_object = NULL;
44562306a36Sopenharmony_ci		return_ACPI_STATUS(AE_OK);
44662306a36Sopenharmony_ci
44762306a36Sopenharmony_ci	default:
44862306a36Sopenharmony_ci
44962306a36Sopenharmony_ci		/* All other types are not supported */
45062306a36Sopenharmony_ci
45162306a36Sopenharmony_ci		ACPI_ERROR((AE_INFO,
45262306a36Sopenharmony_ci			    "Unsupported object type, cannot convert to internal object: %s",
45362306a36Sopenharmony_ci			    acpi_ut_get_type_name(external_object->type)));
45462306a36Sopenharmony_ci
45562306a36Sopenharmony_ci		return_ACPI_STATUS(AE_SUPPORT);
45662306a36Sopenharmony_ci	}
45762306a36Sopenharmony_ci
45862306a36Sopenharmony_ci	/* Must COPY string and buffer contents */
45962306a36Sopenharmony_ci
46062306a36Sopenharmony_ci	switch (external_object->type) {
46162306a36Sopenharmony_ci	case ACPI_TYPE_STRING:
46262306a36Sopenharmony_ci
46362306a36Sopenharmony_ci		internal_object->string.pointer =
46462306a36Sopenharmony_ci		    ACPI_ALLOCATE_ZEROED((acpi_size)
46562306a36Sopenharmony_ci					 external_object->string.length + 1);
46662306a36Sopenharmony_ci
46762306a36Sopenharmony_ci		if (!internal_object->string.pointer) {
46862306a36Sopenharmony_ci			goto error_exit;
46962306a36Sopenharmony_ci		}
47062306a36Sopenharmony_ci
47162306a36Sopenharmony_ci		memcpy(internal_object->string.pointer,
47262306a36Sopenharmony_ci		       external_object->string.pointer,
47362306a36Sopenharmony_ci		       external_object->string.length);
47462306a36Sopenharmony_ci
47562306a36Sopenharmony_ci		internal_object->string.length = external_object->string.length;
47662306a36Sopenharmony_ci		break;
47762306a36Sopenharmony_ci
47862306a36Sopenharmony_ci	case ACPI_TYPE_BUFFER:
47962306a36Sopenharmony_ci
48062306a36Sopenharmony_ci		internal_object->buffer.pointer =
48162306a36Sopenharmony_ci		    ACPI_ALLOCATE_ZEROED(external_object->buffer.length);
48262306a36Sopenharmony_ci		if (!internal_object->buffer.pointer) {
48362306a36Sopenharmony_ci			goto error_exit;
48462306a36Sopenharmony_ci		}
48562306a36Sopenharmony_ci
48662306a36Sopenharmony_ci		memcpy(internal_object->buffer.pointer,
48762306a36Sopenharmony_ci		       external_object->buffer.pointer,
48862306a36Sopenharmony_ci		       external_object->buffer.length);
48962306a36Sopenharmony_ci
49062306a36Sopenharmony_ci		internal_object->buffer.length = external_object->buffer.length;
49162306a36Sopenharmony_ci
49262306a36Sopenharmony_ci		/* Mark buffer data valid */
49362306a36Sopenharmony_ci
49462306a36Sopenharmony_ci		internal_object->buffer.flags |= AOPOBJ_DATA_VALID;
49562306a36Sopenharmony_ci		break;
49662306a36Sopenharmony_ci
49762306a36Sopenharmony_ci	case ACPI_TYPE_INTEGER:
49862306a36Sopenharmony_ci
49962306a36Sopenharmony_ci		internal_object->integer.value = external_object->integer.value;
50062306a36Sopenharmony_ci		break;
50162306a36Sopenharmony_ci
50262306a36Sopenharmony_ci	case ACPI_TYPE_LOCAL_REFERENCE:
50362306a36Sopenharmony_ci
50462306a36Sopenharmony_ci		/* An incoming reference is defined to be a namespace node */
50562306a36Sopenharmony_ci
50662306a36Sopenharmony_ci		internal_object->reference.class = ACPI_REFCLASS_REFOF;
50762306a36Sopenharmony_ci		internal_object->reference.object =
50862306a36Sopenharmony_ci		    external_object->reference.handle;
50962306a36Sopenharmony_ci		break;
51062306a36Sopenharmony_ci
51162306a36Sopenharmony_ci	default:
51262306a36Sopenharmony_ci
51362306a36Sopenharmony_ci		/* Other types can't get here */
51462306a36Sopenharmony_ci
51562306a36Sopenharmony_ci		break;
51662306a36Sopenharmony_ci	}
51762306a36Sopenharmony_ci
51862306a36Sopenharmony_ci	*ret_internal_object = internal_object;
51962306a36Sopenharmony_ci	return_ACPI_STATUS(AE_OK);
52062306a36Sopenharmony_ci
52162306a36Sopenharmony_cierror_exit:
52262306a36Sopenharmony_ci	acpi_ut_remove_reference(internal_object);
52362306a36Sopenharmony_ci	return_ACPI_STATUS(AE_NO_MEMORY);
52462306a36Sopenharmony_ci}
52562306a36Sopenharmony_ci
52662306a36Sopenharmony_ci/*******************************************************************************
52762306a36Sopenharmony_ci *
52862306a36Sopenharmony_ci * FUNCTION:    acpi_ut_copy_epackage_to_ipackage
52962306a36Sopenharmony_ci *
53062306a36Sopenharmony_ci * PARAMETERS:  external_object     - The external object to be converted
53162306a36Sopenharmony_ci *              internal_object     - Where the internal object is returned
53262306a36Sopenharmony_ci *
53362306a36Sopenharmony_ci * RETURN:      Status
53462306a36Sopenharmony_ci *
53562306a36Sopenharmony_ci * DESCRIPTION: Copy an external package object to an internal package.
53662306a36Sopenharmony_ci *              Handles nested packages.
53762306a36Sopenharmony_ci *
53862306a36Sopenharmony_ci ******************************************************************************/
53962306a36Sopenharmony_ci
54062306a36Sopenharmony_cistatic acpi_status
54162306a36Sopenharmony_ciacpi_ut_copy_epackage_to_ipackage(union acpi_object *external_object,
54262306a36Sopenharmony_ci				  union acpi_operand_object **internal_object)
54362306a36Sopenharmony_ci{
54462306a36Sopenharmony_ci	acpi_status status = AE_OK;
54562306a36Sopenharmony_ci	union acpi_operand_object *package_object;
54662306a36Sopenharmony_ci	union acpi_operand_object **package_elements;
54762306a36Sopenharmony_ci	u32 i;
54862306a36Sopenharmony_ci
54962306a36Sopenharmony_ci	ACPI_FUNCTION_TRACE(ut_copy_epackage_to_ipackage);
55062306a36Sopenharmony_ci
55162306a36Sopenharmony_ci	/* Create the package object */
55262306a36Sopenharmony_ci
55362306a36Sopenharmony_ci	package_object =
55462306a36Sopenharmony_ci	    acpi_ut_create_package_object(external_object->package.count);
55562306a36Sopenharmony_ci	if (!package_object) {
55662306a36Sopenharmony_ci		return_ACPI_STATUS(AE_NO_MEMORY);
55762306a36Sopenharmony_ci	}
55862306a36Sopenharmony_ci
55962306a36Sopenharmony_ci	package_elements = package_object->package.elements;
56062306a36Sopenharmony_ci
56162306a36Sopenharmony_ci	/*
56262306a36Sopenharmony_ci	 * Recursive implementation. Probably ok, since nested external
56362306a36Sopenharmony_ci	 * packages as parameters should be very rare.
56462306a36Sopenharmony_ci	 */
56562306a36Sopenharmony_ci	for (i = 0; i < external_object->package.count; i++) {
56662306a36Sopenharmony_ci		status =
56762306a36Sopenharmony_ci		    acpi_ut_copy_eobject_to_iobject(&external_object->package.
56862306a36Sopenharmony_ci						    elements[i],
56962306a36Sopenharmony_ci						    &package_elements[i]);
57062306a36Sopenharmony_ci		if (ACPI_FAILURE(status)) {
57162306a36Sopenharmony_ci
57262306a36Sopenharmony_ci			/* Truncate package and delete it */
57362306a36Sopenharmony_ci
57462306a36Sopenharmony_ci			package_object->package.count = i;
57562306a36Sopenharmony_ci			package_elements[i] = NULL;
57662306a36Sopenharmony_ci			acpi_ut_remove_reference(package_object);
57762306a36Sopenharmony_ci			return_ACPI_STATUS(status);
57862306a36Sopenharmony_ci		}
57962306a36Sopenharmony_ci	}
58062306a36Sopenharmony_ci
58162306a36Sopenharmony_ci	/* Mark package data valid */
58262306a36Sopenharmony_ci
58362306a36Sopenharmony_ci	package_object->package.flags |= AOPOBJ_DATA_VALID;
58462306a36Sopenharmony_ci
58562306a36Sopenharmony_ci	*internal_object = package_object;
58662306a36Sopenharmony_ci	return_ACPI_STATUS(status);
58762306a36Sopenharmony_ci}
58862306a36Sopenharmony_ci
58962306a36Sopenharmony_ci/*******************************************************************************
59062306a36Sopenharmony_ci *
59162306a36Sopenharmony_ci * FUNCTION:    acpi_ut_copy_eobject_to_iobject
59262306a36Sopenharmony_ci *
59362306a36Sopenharmony_ci * PARAMETERS:  external_object     - The external object to be converted
59462306a36Sopenharmony_ci *              internal_object     - Where the internal object is returned
59562306a36Sopenharmony_ci *
59662306a36Sopenharmony_ci * RETURN:      Status
59762306a36Sopenharmony_ci *
59862306a36Sopenharmony_ci * DESCRIPTION: Converts an external object to an internal object.
59962306a36Sopenharmony_ci *
60062306a36Sopenharmony_ci ******************************************************************************/
60162306a36Sopenharmony_ci
60262306a36Sopenharmony_ciacpi_status
60362306a36Sopenharmony_ciacpi_ut_copy_eobject_to_iobject(union acpi_object *external_object,
60462306a36Sopenharmony_ci				union acpi_operand_object **internal_object)
60562306a36Sopenharmony_ci{
60662306a36Sopenharmony_ci	acpi_status status;
60762306a36Sopenharmony_ci
60862306a36Sopenharmony_ci	ACPI_FUNCTION_TRACE(ut_copy_eobject_to_iobject);
60962306a36Sopenharmony_ci
61062306a36Sopenharmony_ci	if (external_object->type == ACPI_TYPE_PACKAGE) {
61162306a36Sopenharmony_ci		status =
61262306a36Sopenharmony_ci		    acpi_ut_copy_epackage_to_ipackage(external_object,
61362306a36Sopenharmony_ci						      internal_object);
61462306a36Sopenharmony_ci	} else {
61562306a36Sopenharmony_ci		/*
61662306a36Sopenharmony_ci		 * Build a simple object (no nested objects)
61762306a36Sopenharmony_ci		 */
61862306a36Sopenharmony_ci		status = acpi_ut_copy_esimple_to_isimple(external_object,
61962306a36Sopenharmony_ci							 internal_object);
62062306a36Sopenharmony_ci	}
62162306a36Sopenharmony_ci
62262306a36Sopenharmony_ci	return_ACPI_STATUS(status);
62362306a36Sopenharmony_ci}
62462306a36Sopenharmony_ci
62562306a36Sopenharmony_ci/*******************************************************************************
62662306a36Sopenharmony_ci *
62762306a36Sopenharmony_ci * FUNCTION:    acpi_ut_copy_simple_object
62862306a36Sopenharmony_ci *
62962306a36Sopenharmony_ci * PARAMETERS:  source_desc         - The internal object to be copied
63062306a36Sopenharmony_ci *              dest_desc           - New target object
63162306a36Sopenharmony_ci *
63262306a36Sopenharmony_ci * RETURN:      Status
63362306a36Sopenharmony_ci *
63462306a36Sopenharmony_ci * DESCRIPTION: Simple copy of one internal object to another. Reference count
63562306a36Sopenharmony_ci *              of the destination object is preserved.
63662306a36Sopenharmony_ci *
63762306a36Sopenharmony_ci ******************************************************************************/
63862306a36Sopenharmony_ci
63962306a36Sopenharmony_cistatic acpi_status
64062306a36Sopenharmony_ciacpi_ut_copy_simple_object(union acpi_operand_object *source_desc,
64162306a36Sopenharmony_ci			   union acpi_operand_object *dest_desc)
64262306a36Sopenharmony_ci{
64362306a36Sopenharmony_ci	u16 reference_count;
64462306a36Sopenharmony_ci	union acpi_operand_object *next_object;
64562306a36Sopenharmony_ci	acpi_status status;
64662306a36Sopenharmony_ci	acpi_size copy_size;
64762306a36Sopenharmony_ci
64862306a36Sopenharmony_ci	/* Save fields from destination that we don't want to overwrite */
64962306a36Sopenharmony_ci
65062306a36Sopenharmony_ci	reference_count = dest_desc->common.reference_count;
65162306a36Sopenharmony_ci	next_object = dest_desc->common.next_object;
65262306a36Sopenharmony_ci
65362306a36Sopenharmony_ci	/*
65462306a36Sopenharmony_ci	 * Copy the entire source object over the destination object.
65562306a36Sopenharmony_ci	 * Note: Source can be either an operand object or namespace node.
65662306a36Sopenharmony_ci	 */
65762306a36Sopenharmony_ci	copy_size = sizeof(union acpi_operand_object);
65862306a36Sopenharmony_ci	if (ACPI_GET_DESCRIPTOR_TYPE(source_desc) == ACPI_DESC_TYPE_NAMED) {
65962306a36Sopenharmony_ci		copy_size = sizeof(struct acpi_namespace_node);
66062306a36Sopenharmony_ci	}
66162306a36Sopenharmony_ci
66262306a36Sopenharmony_ci	memcpy(ACPI_CAST_PTR(char, dest_desc),
66362306a36Sopenharmony_ci	       ACPI_CAST_PTR(char, source_desc), copy_size);
66462306a36Sopenharmony_ci
66562306a36Sopenharmony_ci	/* Restore the saved fields */
66662306a36Sopenharmony_ci
66762306a36Sopenharmony_ci	dest_desc->common.reference_count = reference_count;
66862306a36Sopenharmony_ci	dest_desc->common.next_object = next_object;
66962306a36Sopenharmony_ci
67062306a36Sopenharmony_ci	/* New object is not static, regardless of source */
67162306a36Sopenharmony_ci
67262306a36Sopenharmony_ci	dest_desc->common.flags &= ~AOPOBJ_STATIC_POINTER;
67362306a36Sopenharmony_ci
67462306a36Sopenharmony_ci	/* Handle the objects with extra data */
67562306a36Sopenharmony_ci
67662306a36Sopenharmony_ci	switch (dest_desc->common.type) {
67762306a36Sopenharmony_ci	case ACPI_TYPE_BUFFER:
67862306a36Sopenharmony_ci		/*
67962306a36Sopenharmony_ci		 * Allocate and copy the actual buffer if and only if:
68062306a36Sopenharmony_ci		 * 1) There is a valid buffer pointer
68162306a36Sopenharmony_ci		 * 2) The buffer has a length > 0
68262306a36Sopenharmony_ci		 */
68362306a36Sopenharmony_ci		if ((source_desc->buffer.pointer) &&
68462306a36Sopenharmony_ci		    (source_desc->buffer.length)) {
68562306a36Sopenharmony_ci			dest_desc->buffer.pointer =
68662306a36Sopenharmony_ci			    ACPI_ALLOCATE(source_desc->buffer.length);
68762306a36Sopenharmony_ci			if (!dest_desc->buffer.pointer) {
68862306a36Sopenharmony_ci				return (AE_NO_MEMORY);
68962306a36Sopenharmony_ci			}
69062306a36Sopenharmony_ci
69162306a36Sopenharmony_ci			/* Copy the actual buffer data */
69262306a36Sopenharmony_ci
69362306a36Sopenharmony_ci			memcpy(dest_desc->buffer.pointer,
69462306a36Sopenharmony_ci			       source_desc->buffer.pointer,
69562306a36Sopenharmony_ci			       source_desc->buffer.length);
69662306a36Sopenharmony_ci		}
69762306a36Sopenharmony_ci		break;
69862306a36Sopenharmony_ci
69962306a36Sopenharmony_ci	case ACPI_TYPE_STRING:
70062306a36Sopenharmony_ci		/*
70162306a36Sopenharmony_ci		 * Allocate and copy the actual string if and only if:
70262306a36Sopenharmony_ci		 * 1) There is a valid string pointer
70362306a36Sopenharmony_ci		 * (Pointer to a NULL string is allowed)
70462306a36Sopenharmony_ci		 */
70562306a36Sopenharmony_ci		if (source_desc->string.pointer) {
70662306a36Sopenharmony_ci			dest_desc->string.pointer =
70762306a36Sopenharmony_ci			    ACPI_ALLOCATE((acpi_size)source_desc->string.
70862306a36Sopenharmony_ci					  length + 1);
70962306a36Sopenharmony_ci			if (!dest_desc->string.pointer) {
71062306a36Sopenharmony_ci				return (AE_NO_MEMORY);
71162306a36Sopenharmony_ci			}
71262306a36Sopenharmony_ci
71362306a36Sopenharmony_ci			/* Copy the actual string data */
71462306a36Sopenharmony_ci
71562306a36Sopenharmony_ci			memcpy(dest_desc->string.pointer,
71662306a36Sopenharmony_ci			       source_desc->string.pointer,
71762306a36Sopenharmony_ci			       (acpi_size)source_desc->string.length + 1);
71862306a36Sopenharmony_ci		}
71962306a36Sopenharmony_ci		break;
72062306a36Sopenharmony_ci
72162306a36Sopenharmony_ci	case ACPI_TYPE_LOCAL_REFERENCE:
72262306a36Sopenharmony_ci		/*
72362306a36Sopenharmony_ci		 * We copied the reference object, so we now must add a reference
72462306a36Sopenharmony_ci		 * to the object pointed to by the reference
72562306a36Sopenharmony_ci		 *
72662306a36Sopenharmony_ci		 * DDBHandle reference (from Load/load_table) is a special reference,
72762306a36Sopenharmony_ci		 * it does not have a Reference.Object, so does not need to
72862306a36Sopenharmony_ci		 * increase the reference count
72962306a36Sopenharmony_ci		 */
73062306a36Sopenharmony_ci		if (source_desc->reference.class == ACPI_REFCLASS_TABLE) {
73162306a36Sopenharmony_ci			break;
73262306a36Sopenharmony_ci		}
73362306a36Sopenharmony_ci
73462306a36Sopenharmony_ci		acpi_ut_add_reference(source_desc->reference.object);
73562306a36Sopenharmony_ci		break;
73662306a36Sopenharmony_ci
73762306a36Sopenharmony_ci	case ACPI_TYPE_REGION:
73862306a36Sopenharmony_ci		/*
73962306a36Sopenharmony_ci		 * We copied the Region Handler, so we now must add a reference
74062306a36Sopenharmony_ci		 */
74162306a36Sopenharmony_ci		if (dest_desc->region.handler) {
74262306a36Sopenharmony_ci			acpi_ut_add_reference(dest_desc->region.handler);
74362306a36Sopenharmony_ci		}
74462306a36Sopenharmony_ci		break;
74562306a36Sopenharmony_ci
74662306a36Sopenharmony_ci		/*
74762306a36Sopenharmony_ci		 * For Mutex and Event objects, we cannot simply copy the underlying
74862306a36Sopenharmony_ci		 * OS object. We must create a new one.
74962306a36Sopenharmony_ci		 */
75062306a36Sopenharmony_ci	case ACPI_TYPE_MUTEX:
75162306a36Sopenharmony_ci
75262306a36Sopenharmony_ci		status = acpi_os_create_mutex(&dest_desc->mutex.os_mutex);
75362306a36Sopenharmony_ci		if (ACPI_FAILURE(status)) {
75462306a36Sopenharmony_ci			return (status);
75562306a36Sopenharmony_ci		}
75662306a36Sopenharmony_ci		break;
75762306a36Sopenharmony_ci
75862306a36Sopenharmony_ci	case ACPI_TYPE_EVENT:
75962306a36Sopenharmony_ci
76062306a36Sopenharmony_ci		status = acpi_os_create_semaphore(ACPI_NO_UNIT_LIMIT, 0,
76162306a36Sopenharmony_ci						  &dest_desc->event.
76262306a36Sopenharmony_ci						  os_semaphore);
76362306a36Sopenharmony_ci		if (ACPI_FAILURE(status)) {
76462306a36Sopenharmony_ci			return (status);
76562306a36Sopenharmony_ci		}
76662306a36Sopenharmony_ci		break;
76762306a36Sopenharmony_ci
76862306a36Sopenharmony_ci	default:
76962306a36Sopenharmony_ci
77062306a36Sopenharmony_ci		/* Nothing to do for other simple objects */
77162306a36Sopenharmony_ci
77262306a36Sopenharmony_ci		break;
77362306a36Sopenharmony_ci	}
77462306a36Sopenharmony_ci
77562306a36Sopenharmony_ci	return (AE_OK);
77662306a36Sopenharmony_ci}
77762306a36Sopenharmony_ci
77862306a36Sopenharmony_ci/*******************************************************************************
77962306a36Sopenharmony_ci *
78062306a36Sopenharmony_ci * FUNCTION:    acpi_ut_copy_ielement_to_ielement
78162306a36Sopenharmony_ci *
78262306a36Sopenharmony_ci * PARAMETERS:  acpi_pkg_callback
78362306a36Sopenharmony_ci *
78462306a36Sopenharmony_ci * RETURN:      Status
78562306a36Sopenharmony_ci *
78662306a36Sopenharmony_ci * DESCRIPTION: Copy one package element to another package element
78762306a36Sopenharmony_ci *
78862306a36Sopenharmony_ci ******************************************************************************/
78962306a36Sopenharmony_ci
79062306a36Sopenharmony_cistatic acpi_status
79162306a36Sopenharmony_ciacpi_ut_copy_ielement_to_ielement(u8 object_type,
79262306a36Sopenharmony_ci				  union acpi_operand_object *source_object,
79362306a36Sopenharmony_ci				  union acpi_generic_state *state,
79462306a36Sopenharmony_ci				  void *context)
79562306a36Sopenharmony_ci{
79662306a36Sopenharmony_ci	acpi_status status = AE_OK;
79762306a36Sopenharmony_ci	u32 this_index;
79862306a36Sopenharmony_ci	union acpi_operand_object **this_target_ptr;
79962306a36Sopenharmony_ci	union acpi_operand_object *target_object;
80062306a36Sopenharmony_ci
80162306a36Sopenharmony_ci	ACPI_FUNCTION_ENTRY();
80262306a36Sopenharmony_ci
80362306a36Sopenharmony_ci	this_index = state->pkg.index;
80462306a36Sopenharmony_ci	this_target_ptr = (union acpi_operand_object **)
80562306a36Sopenharmony_ci	    &state->pkg.dest_object->package.elements[this_index];
80662306a36Sopenharmony_ci
80762306a36Sopenharmony_ci	switch (object_type) {
80862306a36Sopenharmony_ci	case ACPI_COPY_TYPE_SIMPLE:
80962306a36Sopenharmony_ci
81062306a36Sopenharmony_ci		/* A null source object indicates a (legal) null package element */
81162306a36Sopenharmony_ci
81262306a36Sopenharmony_ci		if (source_object) {
81362306a36Sopenharmony_ci			/*
81462306a36Sopenharmony_ci			 * This is a simple object, just copy it
81562306a36Sopenharmony_ci			 */
81662306a36Sopenharmony_ci			target_object =
81762306a36Sopenharmony_ci			    acpi_ut_create_internal_object(source_object->
81862306a36Sopenharmony_ci							   common.type);
81962306a36Sopenharmony_ci			if (!target_object) {
82062306a36Sopenharmony_ci				return (AE_NO_MEMORY);
82162306a36Sopenharmony_ci			}
82262306a36Sopenharmony_ci
82362306a36Sopenharmony_ci			status =
82462306a36Sopenharmony_ci			    acpi_ut_copy_simple_object(source_object,
82562306a36Sopenharmony_ci						       target_object);
82662306a36Sopenharmony_ci			if (ACPI_FAILURE(status)) {
82762306a36Sopenharmony_ci				goto error_exit;
82862306a36Sopenharmony_ci			}
82962306a36Sopenharmony_ci
83062306a36Sopenharmony_ci			*this_target_ptr = target_object;
83162306a36Sopenharmony_ci		} else {
83262306a36Sopenharmony_ci			/* Pass through a null element */
83362306a36Sopenharmony_ci
83462306a36Sopenharmony_ci			*this_target_ptr = NULL;
83562306a36Sopenharmony_ci		}
83662306a36Sopenharmony_ci		break;
83762306a36Sopenharmony_ci
83862306a36Sopenharmony_ci	case ACPI_COPY_TYPE_PACKAGE:
83962306a36Sopenharmony_ci		/*
84062306a36Sopenharmony_ci		 * This object is a package - go down another nesting level
84162306a36Sopenharmony_ci		 * Create and build the package object
84262306a36Sopenharmony_ci		 */
84362306a36Sopenharmony_ci		target_object =
84462306a36Sopenharmony_ci		    acpi_ut_create_package_object(source_object->package.count);
84562306a36Sopenharmony_ci		if (!target_object) {
84662306a36Sopenharmony_ci			return (AE_NO_MEMORY);
84762306a36Sopenharmony_ci		}
84862306a36Sopenharmony_ci
84962306a36Sopenharmony_ci		target_object->common.flags = source_object->common.flags;
85062306a36Sopenharmony_ci
85162306a36Sopenharmony_ci		/* Pass the new package object back to the package walk routine */
85262306a36Sopenharmony_ci
85362306a36Sopenharmony_ci		state->pkg.this_target_obj = target_object;
85462306a36Sopenharmony_ci
85562306a36Sopenharmony_ci		/* Store the object pointer in the parent package object */
85662306a36Sopenharmony_ci
85762306a36Sopenharmony_ci		*this_target_ptr = target_object;
85862306a36Sopenharmony_ci		break;
85962306a36Sopenharmony_ci
86062306a36Sopenharmony_ci	default:
86162306a36Sopenharmony_ci
86262306a36Sopenharmony_ci		return (AE_BAD_PARAMETER);
86362306a36Sopenharmony_ci	}
86462306a36Sopenharmony_ci
86562306a36Sopenharmony_ci	return (status);
86662306a36Sopenharmony_ci
86762306a36Sopenharmony_cierror_exit:
86862306a36Sopenharmony_ci	acpi_ut_remove_reference(target_object);
86962306a36Sopenharmony_ci	return (status);
87062306a36Sopenharmony_ci}
87162306a36Sopenharmony_ci
87262306a36Sopenharmony_ci/*******************************************************************************
87362306a36Sopenharmony_ci *
87462306a36Sopenharmony_ci * FUNCTION:    acpi_ut_copy_ipackage_to_ipackage
87562306a36Sopenharmony_ci *
87662306a36Sopenharmony_ci * PARAMETERS:  source_obj      - Pointer to the source package object
87762306a36Sopenharmony_ci *              dest_obj        - Where the internal object is returned
87862306a36Sopenharmony_ci *              walk_state      - Current Walk state descriptor
87962306a36Sopenharmony_ci *
88062306a36Sopenharmony_ci * RETURN:      Status
88162306a36Sopenharmony_ci *
88262306a36Sopenharmony_ci * DESCRIPTION: This function is called to copy an internal package object
88362306a36Sopenharmony_ci *              into another internal package object.
88462306a36Sopenharmony_ci *
88562306a36Sopenharmony_ci ******************************************************************************/
88662306a36Sopenharmony_ci
88762306a36Sopenharmony_cistatic acpi_status
88862306a36Sopenharmony_ciacpi_ut_copy_ipackage_to_ipackage(union acpi_operand_object *source_obj,
88962306a36Sopenharmony_ci				  union acpi_operand_object *dest_obj,
89062306a36Sopenharmony_ci				  struct acpi_walk_state *walk_state)
89162306a36Sopenharmony_ci{
89262306a36Sopenharmony_ci	acpi_status status = AE_OK;
89362306a36Sopenharmony_ci
89462306a36Sopenharmony_ci	ACPI_FUNCTION_TRACE(ut_copy_ipackage_to_ipackage);
89562306a36Sopenharmony_ci
89662306a36Sopenharmony_ci	dest_obj->common.type = source_obj->common.type;
89762306a36Sopenharmony_ci	dest_obj->common.flags = source_obj->common.flags;
89862306a36Sopenharmony_ci	dest_obj->package.count = source_obj->package.count;
89962306a36Sopenharmony_ci
90062306a36Sopenharmony_ci	/*
90162306a36Sopenharmony_ci	 * Create the object array and walk the source package tree
90262306a36Sopenharmony_ci	 */
90362306a36Sopenharmony_ci	dest_obj->package.elements = ACPI_ALLOCATE_ZEROED(((acpi_size)
90462306a36Sopenharmony_ci							   source_obj->package.
90562306a36Sopenharmony_ci							   count +
90662306a36Sopenharmony_ci							   1) * sizeof(void *));
90762306a36Sopenharmony_ci	if (!dest_obj->package.elements) {
90862306a36Sopenharmony_ci		ACPI_ERROR((AE_INFO, "Package allocation failure"));
90962306a36Sopenharmony_ci		return_ACPI_STATUS(AE_NO_MEMORY);
91062306a36Sopenharmony_ci	}
91162306a36Sopenharmony_ci
91262306a36Sopenharmony_ci	/*
91362306a36Sopenharmony_ci	 * Copy the package element-by-element by walking the package "tree".
91462306a36Sopenharmony_ci	 * This handles nested packages of arbitrary depth.
91562306a36Sopenharmony_ci	 */
91662306a36Sopenharmony_ci	status = acpi_ut_walk_package_tree(source_obj, dest_obj,
91762306a36Sopenharmony_ci					   acpi_ut_copy_ielement_to_ielement,
91862306a36Sopenharmony_ci					   walk_state);
91962306a36Sopenharmony_ci	return_ACPI_STATUS(status);
92062306a36Sopenharmony_ci}
92162306a36Sopenharmony_ci
92262306a36Sopenharmony_ci/*******************************************************************************
92362306a36Sopenharmony_ci *
92462306a36Sopenharmony_ci * FUNCTION:    acpi_ut_copy_iobject_to_iobject
92562306a36Sopenharmony_ci *
92662306a36Sopenharmony_ci * PARAMETERS:  source_desc         - The internal object to be copied
92762306a36Sopenharmony_ci *              dest_desc           - Where the copied object is returned
92862306a36Sopenharmony_ci *              walk_state          - Current walk state
92962306a36Sopenharmony_ci *
93062306a36Sopenharmony_ci * RETURN:      Status
93162306a36Sopenharmony_ci *
93262306a36Sopenharmony_ci * DESCRIPTION: Copy an internal object to a new internal object
93362306a36Sopenharmony_ci *
93462306a36Sopenharmony_ci ******************************************************************************/
93562306a36Sopenharmony_ci
93662306a36Sopenharmony_ciacpi_status
93762306a36Sopenharmony_ciacpi_ut_copy_iobject_to_iobject(union acpi_operand_object *source_desc,
93862306a36Sopenharmony_ci				union acpi_operand_object **dest_desc,
93962306a36Sopenharmony_ci				struct acpi_walk_state *walk_state)
94062306a36Sopenharmony_ci{
94162306a36Sopenharmony_ci	acpi_status status = AE_OK;
94262306a36Sopenharmony_ci
94362306a36Sopenharmony_ci	ACPI_FUNCTION_TRACE(ut_copy_iobject_to_iobject);
94462306a36Sopenharmony_ci
94562306a36Sopenharmony_ci	/* Create the top level object */
94662306a36Sopenharmony_ci
94762306a36Sopenharmony_ci	*dest_desc = acpi_ut_create_internal_object(source_desc->common.type);
94862306a36Sopenharmony_ci	if (!*dest_desc) {
94962306a36Sopenharmony_ci		return_ACPI_STATUS(AE_NO_MEMORY);
95062306a36Sopenharmony_ci	}
95162306a36Sopenharmony_ci
95262306a36Sopenharmony_ci	/* Copy the object and possible subobjects */
95362306a36Sopenharmony_ci
95462306a36Sopenharmony_ci	if (source_desc->common.type == ACPI_TYPE_PACKAGE) {
95562306a36Sopenharmony_ci		status =
95662306a36Sopenharmony_ci		    acpi_ut_copy_ipackage_to_ipackage(source_desc, *dest_desc,
95762306a36Sopenharmony_ci						      walk_state);
95862306a36Sopenharmony_ci	} else {
95962306a36Sopenharmony_ci		status = acpi_ut_copy_simple_object(source_desc, *dest_desc);
96062306a36Sopenharmony_ci	}
96162306a36Sopenharmony_ci
96262306a36Sopenharmony_ci	/* Delete the allocated object if copy failed */
96362306a36Sopenharmony_ci
96462306a36Sopenharmony_ci	if (ACPI_FAILURE(status)) {
96562306a36Sopenharmony_ci		acpi_ut_remove_reference(*dest_desc);
96662306a36Sopenharmony_ci	}
96762306a36Sopenharmony_ci
96862306a36Sopenharmony_ci	return_ACPI_STATUS(status);
96962306a36Sopenharmony_ci}
970