162306a36Sopenharmony_ci// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 262306a36Sopenharmony_ci/****************************************************************************** 362306a36Sopenharmony_ci * 462306a36Sopenharmony_ci * Module Name: exconcat - Concatenate-type AML operators 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 "acinterp.h" 1362306a36Sopenharmony_ci#include "amlresrc.h" 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci#define _COMPONENT ACPI_EXECUTER 1662306a36Sopenharmony_ciACPI_MODULE_NAME("exconcat") 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci/* Local Prototypes */ 1962306a36Sopenharmony_cistatic acpi_status 2062306a36Sopenharmony_ciacpi_ex_convert_to_object_type_string(union acpi_operand_object *obj_desc, 2162306a36Sopenharmony_ci union acpi_operand_object **result_desc); 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_ci/******************************************************************************* 2462306a36Sopenharmony_ci * 2562306a36Sopenharmony_ci * FUNCTION: acpi_ex_do_concatenate 2662306a36Sopenharmony_ci * 2762306a36Sopenharmony_ci * PARAMETERS: operand0 - First source object 2862306a36Sopenharmony_ci * operand1 - Second source object 2962306a36Sopenharmony_ci * actual_return_desc - Where to place the return object 3062306a36Sopenharmony_ci * walk_state - Current walk state 3162306a36Sopenharmony_ci * 3262306a36Sopenharmony_ci * RETURN: Status 3362306a36Sopenharmony_ci * 3462306a36Sopenharmony_ci * DESCRIPTION: Concatenate two objects with the ACPI-defined conversion 3562306a36Sopenharmony_ci * rules as necessary. 3662306a36Sopenharmony_ci * NOTE: 3762306a36Sopenharmony_ci * Per the ACPI spec (up to 6.1), Concatenate only supports Integer, 3862306a36Sopenharmony_ci * String, and Buffer objects. However, we support all objects here 3962306a36Sopenharmony_ci * as an extension. This improves the usefulness of both Concatenate 4062306a36Sopenharmony_ci * and the Printf/Fprintf macros. The extension returns a string 4162306a36Sopenharmony_ci * describing the object type for the other objects. 4262306a36Sopenharmony_ci * 02/2016. 4362306a36Sopenharmony_ci * 4462306a36Sopenharmony_ci ******************************************************************************/ 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ciacpi_status 4762306a36Sopenharmony_ciacpi_ex_do_concatenate(union acpi_operand_object *operand0, 4862306a36Sopenharmony_ci union acpi_operand_object *operand1, 4962306a36Sopenharmony_ci union acpi_operand_object **actual_return_desc, 5062306a36Sopenharmony_ci struct acpi_walk_state *walk_state) 5162306a36Sopenharmony_ci{ 5262306a36Sopenharmony_ci union acpi_operand_object *local_operand0 = operand0; 5362306a36Sopenharmony_ci union acpi_operand_object *local_operand1 = operand1; 5462306a36Sopenharmony_ci union acpi_operand_object *temp_operand1 = NULL; 5562306a36Sopenharmony_ci union acpi_operand_object *return_desc; 5662306a36Sopenharmony_ci char *buffer; 5762306a36Sopenharmony_ci acpi_object_type operand0_type; 5862306a36Sopenharmony_ci acpi_object_type operand1_type; 5962306a36Sopenharmony_ci acpi_status status; 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci ACPI_FUNCTION_TRACE(ex_do_concatenate); 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ci /* Operand 0 preprocessing */ 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ci switch (operand0->common.type) { 6662306a36Sopenharmony_ci case ACPI_TYPE_INTEGER: 6762306a36Sopenharmony_ci case ACPI_TYPE_STRING: 6862306a36Sopenharmony_ci case ACPI_TYPE_BUFFER: 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_ci operand0_type = operand0->common.type; 7162306a36Sopenharmony_ci break; 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_ci default: 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_ci /* For all other types, get the "object type" string */ 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_ci status = 7862306a36Sopenharmony_ci acpi_ex_convert_to_object_type_string(operand0, 7962306a36Sopenharmony_ci &local_operand0); 8062306a36Sopenharmony_ci if (ACPI_FAILURE(status)) { 8162306a36Sopenharmony_ci goto cleanup; 8262306a36Sopenharmony_ci } 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_ci operand0_type = ACPI_TYPE_STRING; 8562306a36Sopenharmony_ci break; 8662306a36Sopenharmony_ci } 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_ci /* Operand 1 preprocessing */ 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_ci switch (operand1->common.type) { 9162306a36Sopenharmony_ci case ACPI_TYPE_INTEGER: 9262306a36Sopenharmony_ci case ACPI_TYPE_STRING: 9362306a36Sopenharmony_ci case ACPI_TYPE_BUFFER: 9462306a36Sopenharmony_ci 9562306a36Sopenharmony_ci operand1_type = operand1->common.type; 9662306a36Sopenharmony_ci break; 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_ci default: 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_ci /* For all other types, get the "object type" string */ 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_ci status = 10362306a36Sopenharmony_ci acpi_ex_convert_to_object_type_string(operand1, 10462306a36Sopenharmony_ci &local_operand1); 10562306a36Sopenharmony_ci if (ACPI_FAILURE(status)) { 10662306a36Sopenharmony_ci goto cleanup; 10762306a36Sopenharmony_ci } 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_ci operand1_type = ACPI_TYPE_STRING; 11062306a36Sopenharmony_ci break; 11162306a36Sopenharmony_ci } 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_ci /* 11462306a36Sopenharmony_ci * Convert the second operand if necessary. The first operand (0) 11562306a36Sopenharmony_ci * determines the type of the second operand (1) (See the Data Types 11662306a36Sopenharmony_ci * section of the ACPI specification). Both object types are 11762306a36Sopenharmony_ci * guaranteed to be either Integer/String/Buffer by the operand 11862306a36Sopenharmony_ci * resolution mechanism. 11962306a36Sopenharmony_ci */ 12062306a36Sopenharmony_ci switch (operand0_type) { 12162306a36Sopenharmony_ci case ACPI_TYPE_INTEGER: 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_ci status = 12462306a36Sopenharmony_ci acpi_ex_convert_to_integer(local_operand1, &temp_operand1, 12562306a36Sopenharmony_ci ACPI_IMPLICIT_CONVERSION); 12662306a36Sopenharmony_ci break; 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_ci case ACPI_TYPE_BUFFER: 12962306a36Sopenharmony_ci 13062306a36Sopenharmony_ci status = 13162306a36Sopenharmony_ci acpi_ex_convert_to_buffer(local_operand1, &temp_operand1); 13262306a36Sopenharmony_ci break; 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_ci case ACPI_TYPE_STRING: 13562306a36Sopenharmony_ci 13662306a36Sopenharmony_ci switch (operand1_type) { 13762306a36Sopenharmony_ci case ACPI_TYPE_INTEGER: 13862306a36Sopenharmony_ci case ACPI_TYPE_STRING: 13962306a36Sopenharmony_ci case ACPI_TYPE_BUFFER: 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_ci /* Other types have already been converted to string */ 14262306a36Sopenharmony_ci 14362306a36Sopenharmony_ci status = 14462306a36Sopenharmony_ci acpi_ex_convert_to_string(local_operand1, 14562306a36Sopenharmony_ci &temp_operand1, 14662306a36Sopenharmony_ci ACPI_IMPLICIT_CONVERT_HEX); 14762306a36Sopenharmony_ci break; 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_ci default: 15062306a36Sopenharmony_ci 15162306a36Sopenharmony_ci status = AE_OK; 15262306a36Sopenharmony_ci break; 15362306a36Sopenharmony_ci } 15462306a36Sopenharmony_ci break; 15562306a36Sopenharmony_ci 15662306a36Sopenharmony_ci default: 15762306a36Sopenharmony_ci 15862306a36Sopenharmony_ci ACPI_ERROR((AE_INFO, "Invalid object type: 0x%X", 15962306a36Sopenharmony_ci operand0->common.type)); 16062306a36Sopenharmony_ci status = AE_AML_INTERNAL; 16162306a36Sopenharmony_ci } 16262306a36Sopenharmony_ci 16362306a36Sopenharmony_ci if (ACPI_FAILURE(status)) { 16462306a36Sopenharmony_ci goto cleanup; 16562306a36Sopenharmony_ci } 16662306a36Sopenharmony_ci 16762306a36Sopenharmony_ci /* Take care with any newly created operand objects */ 16862306a36Sopenharmony_ci 16962306a36Sopenharmony_ci if ((local_operand1 != operand1) && (local_operand1 != temp_operand1)) { 17062306a36Sopenharmony_ci acpi_ut_remove_reference(local_operand1); 17162306a36Sopenharmony_ci } 17262306a36Sopenharmony_ci 17362306a36Sopenharmony_ci local_operand1 = temp_operand1; 17462306a36Sopenharmony_ci 17562306a36Sopenharmony_ci /* 17662306a36Sopenharmony_ci * Both operands are now known to be the same object type 17762306a36Sopenharmony_ci * (Both are Integer, String, or Buffer), and we can now perform 17862306a36Sopenharmony_ci * the concatenation. 17962306a36Sopenharmony_ci * 18062306a36Sopenharmony_ci * There are three cases to handle, as per the ACPI spec: 18162306a36Sopenharmony_ci * 18262306a36Sopenharmony_ci * 1) Two Integers concatenated to produce a new Buffer 18362306a36Sopenharmony_ci * 2) Two Strings concatenated to produce a new String 18462306a36Sopenharmony_ci * 3) Two Buffers concatenated to produce a new Buffer 18562306a36Sopenharmony_ci */ 18662306a36Sopenharmony_ci switch (operand0_type) { 18762306a36Sopenharmony_ci case ACPI_TYPE_INTEGER: 18862306a36Sopenharmony_ci 18962306a36Sopenharmony_ci /* Result of two Integers is a Buffer */ 19062306a36Sopenharmony_ci /* Need enough buffer space for two integers */ 19162306a36Sopenharmony_ci 19262306a36Sopenharmony_ci return_desc = acpi_ut_create_buffer_object((acpi_size) 19362306a36Sopenharmony_ci ACPI_MUL_2 19462306a36Sopenharmony_ci (acpi_gbl_integer_byte_width)); 19562306a36Sopenharmony_ci if (!return_desc) { 19662306a36Sopenharmony_ci status = AE_NO_MEMORY; 19762306a36Sopenharmony_ci goto cleanup; 19862306a36Sopenharmony_ci } 19962306a36Sopenharmony_ci 20062306a36Sopenharmony_ci buffer = (char *)return_desc->buffer.pointer; 20162306a36Sopenharmony_ci 20262306a36Sopenharmony_ci /* Copy the first integer, LSB first */ 20362306a36Sopenharmony_ci 20462306a36Sopenharmony_ci memcpy(buffer, &operand0->integer.value, 20562306a36Sopenharmony_ci acpi_gbl_integer_byte_width); 20662306a36Sopenharmony_ci 20762306a36Sopenharmony_ci /* Copy the second integer (LSB first) after the first */ 20862306a36Sopenharmony_ci 20962306a36Sopenharmony_ci memcpy(buffer + acpi_gbl_integer_byte_width, 21062306a36Sopenharmony_ci &local_operand1->integer.value, 21162306a36Sopenharmony_ci acpi_gbl_integer_byte_width); 21262306a36Sopenharmony_ci break; 21362306a36Sopenharmony_ci 21462306a36Sopenharmony_ci case ACPI_TYPE_STRING: 21562306a36Sopenharmony_ci 21662306a36Sopenharmony_ci /* Result of two Strings is a String */ 21762306a36Sopenharmony_ci 21862306a36Sopenharmony_ci return_desc = acpi_ut_create_string_object(((acpi_size) 21962306a36Sopenharmony_ci local_operand0-> 22062306a36Sopenharmony_ci string.length + 22162306a36Sopenharmony_ci local_operand1-> 22262306a36Sopenharmony_ci string.length)); 22362306a36Sopenharmony_ci if (!return_desc) { 22462306a36Sopenharmony_ci status = AE_NO_MEMORY; 22562306a36Sopenharmony_ci goto cleanup; 22662306a36Sopenharmony_ci } 22762306a36Sopenharmony_ci 22862306a36Sopenharmony_ci buffer = return_desc->string.pointer; 22962306a36Sopenharmony_ci 23062306a36Sopenharmony_ci /* Concatenate the strings */ 23162306a36Sopenharmony_ci 23262306a36Sopenharmony_ci strcpy(buffer, local_operand0->string.pointer); 23362306a36Sopenharmony_ci strcat(buffer, local_operand1->string.pointer); 23462306a36Sopenharmony_ci break; 23562306a36Sopenharmony_ci 23662306a36Sopenharmony_ci case ACPI_TYPE_BUFFER: 23762306a36Sopenharmony_ci 23862306a36Sopenharmony_ci /* Result of two Buffers is a Buffer */ 23962306a36Sopenharmony_ci 24062306a36Sopenharmony_ci return_desc = acpi_ut_create_buffer_object(((acpi_size) 24162306a36Sopenharmony_ci operand0->buffer. 24262306a36Sopenharmony_ci length + 24362306a36Sopenharmony_ci local_operand1-> 24462306a36Sopenharmony_ci buffer.length)); 24562306a36Sopenharmony_ci if (!return_desc) { 24662306a36Sopenharmony_ci status = AE_NO_MEMORY; 24762306a36Sopenharmony_ci goto cleanup; 24862306a36Sopenharmony_ci } 24962306a36Sopenharmony_ci 25062306a36Sopenharmony_ci buffer = (char *)return_desc->buffer.pointer; 25162306a36Sopenharmony_ci 25262306a36Sopenharmony_ci /* Concatenate the buffers */ 25362306a36Sopenharmony_ci 25462306a36Sopenharmony_ci memcpy(buffer, operand0->buffer.pointer, 25562306a36Sopenharmony_ci operand0->buffer.length); 25662306a36Sopenharmony_ci memcpy(buffer + operand0->buffer.length, 25762306a36Sopenharmony_ci local_operand1->buffer.pointer, 25862306a36Sopenharmony_ci local_operand1->buffer.length); 25962306a36Sopenharmony_ci break; 26062306a36Sopenharmony_ci 26162306a36Sopenharmony_ci default: 26262306a36Sopenharmony_ci 26362306a36Sopenharmony_ci /* Invalid object type, should not happen here */ 26462306a36Sopenharmony_ci 26562306a36Sopenharmony_ci ACPI_ERROR((AE_INFO, "Invalid object type: 0x%X", 26662306a36Sopenharmony_ci operand0->common.type)); 26762306a36Sopenharmony_ci status = AE_AML_INTERNAL; 26862306a36Sopenharmony_ci goto cleanup; 26962306a36Sopenharmony_ci } 27062306a36Sopenharmony_ci 27162306a36Sopenharmony_ci *actual_return_desc = return_desc; 27262306a36Sopenharmony_ci 27362306a36Sopenharmony_cicleanup: 27462306a36Sopenharmony_ci if (local_operand0 != operand0) { 27562306a36Sopenharmony_ci acpi_ut_remove_reference(local_operand0); 27662306a36Sopenharmony_ci } 27762306a36Sopenharmony_ci 27862306a36Sopenharmony_ci if (local_operand1 != operand1) { 27962306a36Sopenharmony_ci acpi_ut_remove_reference(local_operand1); 28062306a36Sopenharmony_ci } 28162306a36Sopenharmony_ci 28262306a36Sopenharmony_ci return_ACPI_STATUS(status); 28362306a36Sopenharmony_ci} 28462306a36Sopenharmony_ci 28562306a36Sopenharmony_ci/******************************************************************************* 28662306a36Sopenharmony_ci * 28762306a36Sopenharmony_ci * FUNCTION: acpi_ex_convert_to_object_type_string 28862306a36Sopenharmony_ci * 28962306a36Sopenharmony_ci * PARAMETERS: obj_desc - Object to be converted 29062306a36Sopenharmony_ci * return_desc - Where to place the return object 29162306a36Sopenharmony_ci * 29262306a36Sopenharmony_ci * RETURN: Status 29362306a36Sopenharmony_ci * 29462306a36Sopenharmony_ci * DESCRIPTION: Convert an object of arbitrary type to a string object that 29562306a36Sopenharmony_ci * contains the namestring for the object. Used for the 29662306a36Sopenharmony_ci * concatenate operator. 29762306a36Sopenharmony_ci * 29862306a36Sopenharmony_ci ******************************************************************************/ 29962306a36Sopenharmony_ci 30062306a36Sopenharmony_cistatic acpi_status 30162306a36Sopenharmony_ciacpi_ex_convert_to_object_type_string(union acpi_operand_object *obj_desc, 30262306a36Sopenharmony_ci union acpi_operand_object **result_desc) 30362306a36Sopenharmony_ci{ 30462306a36Sopenharmony_ci union acpi_operand_object *return_desc; 30562306a36Sopenharmony_ci const char *type_string; 30662306a36Sopenharmony_ci 30762306a36Sopenharmony_ci type_string = acpi_ut_get_type_name(obj_desc->common.type); 30862306a36Sopenharmony_ci 30962306a36Sopenharmony_ci return_desc = acpi_ut_create_string_object(((acpi_size)strlen(type_string) + 9)); /* 9 For "[ Object]" */ 31062306a36Sopenharmony_ci if (!return_desc) { 31162306a36Sopenharmony_ci return (AE_NO_MEMORY); 31262306a36Sopenharmony_ci } 31362306a36Sopenharmony_ci 31462306a36Sopenharmony_ci strcpy(return_desc->string.pointer, "["); 31562306a36Sopenharmony_ci strcat(return_desc->string.pointer, type_string); 31662306a36Sopenharmony_ci strcat(return_desc->string.pointer, " Object]"); 31762306a36Sopenharmony_ci 31862306a36Sopenharmony_ci *result_desc = return_desc; 31962306a36Sopenharmony_ci return (AE_OK); 32062306a36Sopenharmony_ci} 32162306a36Sopenharmony_ci 32262306a36Sopenharmony_ci/******************************************************************************* 32362306a36Sopenharmony_ci * 32462306a36Sopenharmony_ci * FUNCTION: acpi_ex_concat_template 32562306a36Sopenharmony_ci * 32662306a36Sopenharmony_ci * PARAMETERS: operand0 - First source object 32762306a36Sopenharmony_ci * operand1 - Second source object 32862306a36Sopenharmony_ci * actual_return_desc - Where to place the return object 32962306a36Sopenharmony_ci * walk_state - Current walk state 33062306a36Sopenharmony_ci * 33162306a36Sopenharmony_ci * RETURN: Status 33262306a36Sopenharmony_ci * 33362306a36Sopenharmony_ci * DESCRIPTION: Concatenate two resource templates 33462306a36Sopenharmony_ci * 33562306a36Sopenharmony_ci ******************************************************************************/ 33662306a36Sopenharmony_ci 33762306a36Sopenharmony_ciacpi_status 33862306a36Sopenharmony_ciacpi_ex_concat_template(union acpi_operand_object *operand0, 33962306a36Sopenharmony_ci union acpi_operand_object *operand1, 34062306a36Sopenharmony_ci union acpi_operand_object **actual_return_desc, 34162306a36Sopenharmony_ci struct acpi_walk_state *walk_state) 34262306a36Sopenharmony_ci{ 34362306a36Sopenharmony_ci acpi_status status; 34462306a36Sopenharmony_ci union acpi_operand_object *return_desc; 34562306a36Sopenharmony_ci u8 *new_buf; 34662306a36Sopenharmony_ci u8 *end_tag; 34762306a36Sopenharmony_ci acpi_size length0; 34862306a36Sopenharmony_ci acpi_size length1; 34962306a36Sopenharmony_ci acpi_size new_length; 35062306a36Sopenharmony_ci 35162306a36Sopenharmony_ci ACPI_FUNCTION_TRACE(ex_concat_template); 35262306a36Sopenharmony_ci 35362306a36Sopenharmony_ci /* 35462306a36Sopenharmony_ci * Find the end_tag descriptor in each resource template. 35562306a36Sopenharmony_ci * Note1: returned pointers point TO the end_tag, not past it. 35662306a36Sopenharmony_ci * Note2: zero-length buffers are allowed; treated like one end_tag 35762306a36Sopenharmony_ci */ 35862306a36Sopenharmony_ci 35962306a36Sopenharmony_ci /* Get the length of the first resource template */ 36062306a36Sopenharmony_ci 36162306a36Sopenharmony_ci status = acpi_ut_get_resource_end_tag(operand0, &end_tag); 36262306a36Sopenharmony_ci if (ACPI_FAILURE(status)) { 36362306a36Sopenharmony_ci return_ACPI_STATUS(status); 36462306a36Sopenharmony_ci } 36562306a36Sopenharmony_ci 36662306a36Sopenharmony_ci length0 = ACPI_PTR_DIFF(end_tag, operand0->buffer.pointer); 36762306a36Sopenharmony_ci 36862306a36Sopenharmony_ci /* Get the length of the second resource template */ 36962306a36Sopenharmony_ci 37062306a36Sopenharmony_ci status = acpi_ut_get_resource_end_tag(operand1, &end_tag); 37162306a36Sopenharmony_ci if (ACPI_FAILURE(status)) { 37262306a36Sopenharmony_ci return_ACPI_STATUS(status); 37362306a36Sopenharmony_ci } 37462306a36Sopenharmony_ci 37562306a36Sopenharmony_ci length1 = ACPI_PTR_DIFF(end_tag, operand1->buffer.pointer); 37662306a36Sopenharmony_ci 37762306a36Sopenharmony_ci /* Combine both lengths, minimum size will be 2 for end_tag */ 37862306a36Sopenharmony_ci 37962306a36Sopenharmony_ci new_length = length0 + length1 + sizeof(struct aml_resource_end_tag); 38062306a36Sopenharmony_ci 38162306a36Sopenharmony_ci /* Create a new buffer object for the result (with one end_tag) */ 38262306a36Sopenharmony_ci 38362306a36Sopenharmony_ci return_desc = acpi_ut_create_buffer_object(new_length); 38462306a36Sopenharmony_ci if (!return_desc) { 38562306a36Sopenharmony_ci return_ACPI_STATUS(AE_NO_MEMORY); 38662306a36Sopenharmony_ci } 38762306a36Sopenharmony_ci 38862306a36Sopenharmony_ci /* 38962306a36Sopenharmony_ci * Copy the templates to the new buffer, 0 first, then 1 follows. One 39062306a36Sopenharmony_ci * end_tag descriptor is copied from Operand1. 39162306a36Sopenharmony_ci */ 39262306a36Sopenharmony_ci new_buf = return_desc->buffer.pointer; 39362306a36Sopenharmony_ci memcpy(new_buf, operand0->buffer.pointer, length0); 39462306a36Sopenharmony_ci memcpy(new_buf + length0, operand1->buffer.pointer, length1); 39562306a36Sopenharmony_ci 39662306a36Sopenharmony_ci /* Insert end_tag and set the checksum to zero, means "ignore checksum" */ 39762306a36Sopenharmony_ci 39862306a36Sopenharmony_ci new_buf[new_length - 1] = 0; 39962306a36Sopenharmony_ci new_buf[new_length - 2] = ACPI_RESOURCE_NAME_END_TAG | 1; 40062306a36Sopenharmony_ci 40162306a36Sopenharmony_ci /* Return the completed resource template */ 40262306a36Sopenharmony_ci 40362306a36Sopenharmony_ci *actual_return_desc = return_desc; 40462306a36Sopenharmony_ci return_ACPI_STATUS(AE_OK); 40562306a36Sopenharmony_ci} 406