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