970 lines · c
1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.02/******************************************************************************3 *4 * Module Name: utcopy - Internal to external object translation utilities5 *6 * Copyright (C) 2000 - 2023, Intel Corp.7 *8 *****************************************************************************/9 10#include <acpi/acpi.h>11#include "accommon.h"12#include "acnamesp.h"13 14 15#define _COMPONENT ACPI_UTILITIES16ACPI_MODULE_NAME("utcopy")17 18/* Local prototypes */19static acpi_status20acpi_ut_copy_isimple_to_esimple(union acpi_operand_object *internal_object,21 union acpi_object *external_object,22 u8 *data_space, acpi_size *buffer_space_used);23 24static acpi_status25acpi_ut_copy_ielement_to_ielement(u8 object_type,26 union acpi_operand_object *source_object,27 union acpi_generic_state *state,28 void *context);29 30static acpi_status31acpi_ut_copy_ipackage_to_epackage(union acpi_operand_object *internal_object,32 u8 *buffer, acpi_size *space_used);33 34static acpi_status35acpi_ut_copy_esimple_to_isimple(union acpi_object *user_obj,36 union acpi_operand_object **return_obj);37 38static acpi_status39acpi_ut_copy_epackage_to_ipackage(union acpi_object *external_object,40 union acpi_operand_object **internal_object);41 42static acpi_status43acpi_ut_copy_simple_object(union acpi_operand_object *source_desc,44 union acpi_operand_object *dest_desc);45 46static acpi_status47acpi_ut_copy_ielement_to_eelement(u8 object_type,48 union acpi_operand_object *source_object,49 union acpi_generic_state *state,50 void *context);51 52static acpi_status53acpi_ut_copy_ipackage_to_ipackage(union acpi_operand_object *source_obj,54 union acpi_operand_object *dest_obj,55 struct acpi_walk_state *walk_state);56 57/*******************************************************************************58 *59 * FUNCTION: acpi_ut_copy_isimple_to_esimple60 *61 * PARAMETERS: internal_object - Source object to be copied62 * external_object - Where to return the copied object63 * data_space - Where object data is returned (such as64 * buffer and string data)65 * buffer_space_used - Length of data_space that was used66 *67 * RETURN: Status68 *69 * DESCRIPTION: This function is called to copy a simple internal object to70 * an external object.71 *72 * The data_space buffer is assumed to have sufficient space for73 * the object.74 *75 ******************************************************************************/76 77static acpi_status78acpi_ut_copy_isimple_to_esimple(union acpi_operand_object *internal_object,79 union acpi_object *external_object,80 u8 *data_space, acpi_size *buffer_space_used)81{82 acpi_status status = AE_OK;83 84 ACPI_FUNCTION_TRACE(ut_copy_isimple_to_esimple);85 86 *buffer_space_used = 0;87 88 /*89 * Check for NULL object case (could be an uninitialized90 * package element)91 */92 if (!internal_object) {93 return_ACPI_STATUS(AE_OK);94 }95 96 /* Always clear the external object */97 98 memset(external_object, 0, sizeof(union acpi_object));99 100 /*101 * In general, the external object will be the same type as102 * the internal object103 */104 external_object->type = internal_object->common.type;105 106 /* However, only a limited number of external types are supported */107 108 switch (internal_object->common.type) {109 case ACPI_TYPE_STRING:110 111 external_object->string.pointer = (char *)data_space;112 external_object->string.length = internal_object->string.length;113 *buffer_space_used = ACPI_ROUND_UP_TO_NATIVE_WORD((acpi_size)114 internal_object->115 string.116 length + 1);117 118 memcpy((void *)data_space,119 (void *)internal_object->string.pointer,120 (acpi_size)internal_object->string.length + 1);121 break;122 123 case ACPI_TYPE_BUFFER:124 125 external_object->buffer.pointer = data_space;126 external_object->buffer.length = internal_object->buffer.length;127 *buffer_space_used =128 ACPI_ROUND_UP_TO_NATIVE_WORD(internal_object->string.129 length);130 131 memcpy((void *)data_space,132 (void *)internal_object->buffer.pointer,133 internal_object->buffer.length);134 break;135 136 case ACPI_TYPE_INTEGER:137 138 external_object->integer.value = internal_object->integer.value;139 break;140 141 case ACPI_TYPE_LOCAL_REFERENCE:142 143 /* This is an object reference. */144 145 switch (internal_object->reference.class) {146 case ACPI_REFCLASS_NAME:147 /*148 * For namepath, return the object handle ("reference")149 * We are referring to the namespace node150 */151 external_object->reference.handle =152 internal_object->reference.node;153 external_object->reference.actual_type =154 acpi_ns_get_type(internal_object->reference.node);155 break;156 157 default:158 159 /* All other reference types are unsupported */160 161 return_ACPI_STATUS(AE_TYPE);162 }163 break;164 165 case ACPI_TYPE_PROCESSOR:166 167 external_object->processor.proc_id =168 internal_object->processor.proc_id;169 external_object->processor.pblk_address =170 internal_object->processor.address;171 external_object->processor.pblk_length =172 internal_object->processor.length;173 break;174 175 case ACPI_TYPE_POWER:176 177 external_object->power_resource.system_level =178 internal_object->power_resource.system_level;179 180 external_object->power_resource.resource_order =181 internal_object->power_resource.resource_order;182 break;183 184 default:185 /*186 * There is no corresponding external object type187 */188 ACPI_ERROR((AE_INFO,189 "Unsupported object type, cannot convert to external object: %s",190 acpi_ut_get_type_name(internal_object->common.191 type)));192 193 return_ACPI_STATUS(AE_SUPPORT);194 }195 196 return_ACPI_STATUS(status);197}198 199/*******************************************************************************200 *201 * FUNCTION: acpi_ut_copy_ielement_to_eelement202 *203 * PARAMETERS: acpi_pkg_callback204 *205 * RETURN: Status206 *207 * DESCRIPTION: Copy one package element to another package element208 *209 ******************************************************************************/210 211static acpi_status212acpi_ut_copy_ielement_to_eelement(u8 object_type,213 union acpi_operand_object *source_object,214 union acpi_generic_state *state,215 void *context)216{217 acpi_status status = AE_OK;218 struct acpi_pkg_info *info = (struct acpi_pkg_info *)context;219 acpi_size object_space;220 u32 this_index;221 union acpi_object *target_object;222 223 ACPI_FUNCTION_ENTRY();224 225 this_index = state->pkg.index;226 target_object = (union acpi_object *)&((union acpi_object *)227 (state->pkg.dest_object))->228 package.elements[this_index];229 230 switch (object_type) {231 case ACPI_COPY_TYPE_SIMPLE:232 /*233 * This is a simple or null object234 */235 status = acpi_ut_copy_isimple_to_esimple(source_object,236 target_object,237 info->free_space,238 &object_space);239 if (ACPI_FAILURE(status)) {240 return (status);241 }242 break;243 244 case ACPI_COPY_TYPE_PACKAGE:245 /*246 * Build the package object247 */248 target_object->type = ACPI_TYPE_PACKAGE;249 target_object->package.count = source_object->package.count;250 target_object->package.elements =251 ACPI_CAST_PTR(union acpi_object, info->free_space);252 253 /*254 * Pass the new package object back to the package walk routine255 */256 state->pkg.this_target_obj = target_object;257 258 /*259 * Save space for the array of objects (Package elements)260 * update the buffer length counter261 */262 object_space = ACPI_ROUND_UP_TO_NATIVE_WORD((acpi_size)263 target_object->264 package.count *265 sizeof(union266 acpi_object));267 break;268 269 default:270 271 return (AE_BAD_PARAMETER);272 }273 274 info->free_space += object_space;275 info->length += object_space;276 return (status);277}278 279/*******************************************************************************280 *281 * FUNCTION: acpi_ut_copy_ipackage_to_epackage282 *283 * PARAMETERS: internal_object - Pointer to the object we are returning284 * buffer - Where the object is returned285 * space_used - Where the object length is returned286 *287 * RETURN: Status288 *289 * DESCRIPTION: This function is called to place a package object in a user290 * buffer. A package object by definition contains other objects.291 *292 * The buffer is assumed to have sufficient space for the object.293 * The caller must have verified the buffer length needed using294 * the acpi_ut_get_object_size function before calling this function.295 *296 ******************************************************************************/297 298static acpi_status299acpi_ut_copy_ipackage_to_epackage(union acpi_operand_object *internal_object,300 u8 *buffer, acpi_size *space_used)301{302 union acpi_object *external_object;303 acpi_status status;304 struct acpi_pkg_info info;305 306 ACPI_FUNCTION_TRACE(ut_copy_ipackage_to_epackage);307 308 /*309 * First package at head of the buffer310 */311 external_object = ACPI_CAST_PTR(union acpi_object, buffer);312 313 /*314 * Free space begins right after the first package315 */316 info.length = ACPI_ROUND_UP_TO_NATIVE_WORD(sizeof(union acpi_object));317 info.free_space = buffer +318 ACPI_ROUND_UP_TO_NATIVE_WORD(sizeof(union acpi_object));319 info.object_space = 0;320 info.num_packages = 1;321 322 external_object->type = internal_object->common.type;323 external_object->package.count = internal_object->package.count;324 external_object->package.elements =325 ACPI_CAST_PTR(union acpi_object, info.free_space);326 327 /*328 * Leave room for an array of ACPI_OBJECTS in the buffer329 * and move the free space past it330 */331 info.length += (acpi_size)external_object->package.count *332 ACPI_ROUND_UP_TO_NATIVE_WORD(sizeof(union acpi_object));333 info.free_space += external_object->package.count *334 ACPI_ROUND_UP_TO_NATIVE_WORD(sizeof(union acpi_object));335 336 status = acpi_ut_walk_package_tree(internal_object, external_object,337 acpi_ut_copy_ielement_to_eelement,338 &info);339 340 *space_used = info.length;341 return_ACPI_STATUS(status);342}343 344/*******************************************************************************345 *346 * FUNCTION: acpi_ut_copy_iobject_to_eobject347 *348 * PARAMETERS: internal_object - The internal object to be converted349 * ret_buffer - Where the object is returned350 *351 * RETURN: Status352 *353 * DESCRIPTION: This function is called to build an API object to be returned354 * to the caller.355 *356 ******************************************************************************/357 358acpi_status359acpi_ut_copy_iobject_to_eobject(union acpi_operand_object *internal_object,360 struct acpi_buffer *ret_buffer)361{362 acpi_status status;363 364 ACPI_FUNCTION_TRACE(ut_copy_iobject_to_eobject);365 366 if (internal_object->common.type == ACPI_TYPE_PACKAGE) {367 /*368 * Package object: Copy all subobjects (including369 * nested packages)370 */371 status = acpi_ut_copy_ipackage_to_epackage(internal_object,372 ret_buffer->pointer,373 &ret_buffer->length);374 } else {375 /*376 * Build a simple object (no nested objects)377 */378 status = acpi_ut_copy_isimple_to_esimple(internal_object,379 ACPI_CAST_PTR(union380 acpi_object,381 ret_buffer->382 pointer),383 ACPI_ADD_PTR(u8,384 ret_buffer->385 pointer,386 ACPI_ROUND_UP_TO_NATIVE_WORD387 (sizeof388 (union389 acpi_object))),390 &ret_buffer->length);391 /*392 * build simple does not include the object size in the length393 * so we add it in here394 */395 ret_buffer->length += sizeof(union acpi_object);396 }397 398 return_ACPI_STATUS(status);399}400 401/*******************************************************************************402 *403 * FUNCTION: acpi_ut_copy_esimple_to_isimple404 *405 * PARAMETERS: external_object - The external object to be converted406 * ret_internal_object - Where the internal object is returned407 *408 * RETURN: Status409 *410 * DESCRIPTION: This function copies an external object to an internal one.411 * NOTE: Pointers can be copied, we don't need to copy data.412 * (The pointers have to be valid in our address space no matter413 * what we do with them!)414 *415 ******************************************************************************/416 417static acpi_status418acpi_ut_copy_esimple_to_isimple(union acpi_object *external_object,419 union acpi_operand_object **ret_internal_object)420{421 union acpi_operand_object *internal_object;422 423 ACPI_FUNCTION_TRACE(ut_copy_esimple_to_isimple);424 425 /*426 * Simple types supported are: String, Buffer, Integer427 */428 switch (external_object->type) {429 case ACPI_TYPE_STRING:430 case ACPI_TYPE_BUFFER:431 case ACPI_TYPE_INTEGER:432 case ACPI_TYPE_LOCAL_REFERENCE:433 434 internal_object = acpi_ut_create_internal_object((u8)435 external_object->436 type);437 if (!internal_object) {438 return_ACPI_STATUS(AE_NO_MEMORY);439 }440 break;441 442 case ACPI_TYPE_ANY: /* This is the case for a NULL object */443 444 *ret_internal_object = NULL;445 return_ACPI_STATUS(AE_OK);446 447 default:448 449 /* All other types are not supported */450 451 ACPI_ERROR((AE_INFO,452 "Unsupported object type, cannot convert to internal object: %s",453 acpi_ut_get_type_name(external_object->type)));454 455 return_ACPI_STATUS(AE_SUPPORT);456 }457 458 /* Must COPY string and buffer contents */459 460 switch (external_object->type) {461 case ACPI_TYPE_STRING:462 463 internal_object->string.pointer =464 ACPI_ALLOCATE_ZEROED((acpi_size)465 external_object->string.length + 1);466 467 if (!internal_object->string.pointer) {468 goto error_exit;469 }470 471 memcpy(internal_object->string.pointer,472 external_object->string.pointer,473 external_object->string.length);474 475 internal_object->string.length = external_object->string.length;476 break;477 478 case ACPI_TYPE_BUFFER:479 480 internal_object->buffer.pointer =481 ACPI_ALLOCATE_ZEROED(external_object->buffer.length);482 if (!internal_object->buffer.pointer) {483 goto error_exit;484 }485 486 memcpy(internal_object->buffer.pointer,487 external_object->buffer.pointer,488 external_object->buffer.length);489 490 internal_object->buffer.length = external_object->buffer.length;491 492 /* Mark buffer data valid */493 494 internal_object->buffer.flags |= AOPOBJ_DATA_VALID;495 break;496 497 case ACPI_TYPE_INTEGER:498 499 internal_object->integer.value = external_object->integer.value;500 break;501 502 case ACPI_TYPE_LOCAL_REFERENCE:503 504 /* An incoming reference is defined to be a namespace node */505 506 internal_object->reference.class = ACPI_REFCLASS_REFOF;507 internal_object->reference.object =508 external_object->reference.handle;509 break;510 511 default:512 513 /* Other types can't get here */514 515 break;516 }517 518 *ret_internal_object = internal_object;519 return_ACPI_STATUS(AE_OK);520 521error_exit:522 acpi_ut_remove_reference(internal_object);523 return_ACPI_STATUS(AE_NO_MEMORY);524}525 526/*******************************************************************************527 *528 * FUNCTION: acpi_ut_copy_epackage_to_ipackage529 *530 * PARAMETERS: external_object - The external object to be converted531 * internal_object - Where the internal object is returned532 *533 * RETURN: Status534 *535 * DESCRIPTION: Copy an external package object to an internal package.536 * Handles nested packages.537 *538 ******************************************************************************/539 540static acpi_status541acpi_ut_copy_epackage_to_ipackage(union acpi_object *external_object,542 union acpi_operand_object **internal_object)543{544 acpi_status status = AE_OK;545 union acpi_operand_object *package_object;546 union acpi_operand_object **package_elements;547 u32 i;548 549 ACPI_FUNCTION_TRACE(ut_copy_epackage_to_ipackage);550 551 /* Create the package object */552 553 package_object =554 acpi_ut_create_package_object(external_object->package.count);555 if (!package_object) {556 return_ACPI_STATUS(AE_NO_MEMORY);557 }558 559 package_elements = package_object->package.elements;560 561 /*562 * Recursive implementation. Probably ok, since nested external563 * packages as parameters should be very rare.564 */565 for (i = 0; i < external_object->package.count; i++) {566 status =567 acpi_ut_copy_eobject_to_iobject(&external_object->package.568 elements[i],569 &package_elements[i]);570 if (ACPI_FAILURE(status)) {571 572 /* Truncate package and delete it */573 574 package_object->package.count = i;575 package_elements[i] = NULL;576 acpi_ut_remove_reference(package_object);577 return_ACPI_STATUS(status);578 }579 }580 581 /* Mark package data valid */582 583 package_object->package.flags |= AOPOBJ_DATA_VALID;584 585 *internal_object = package_object;586 return_ACPI_STATUS(status);587}588 589/*******************************************************************************590 *591 * FUNCTION: acpi_ut_copy_eobject_to_iobject592 *593 * PARAMETERS: external_object - The external object to be converted594 * internal_object - Where the internal object is returned595 *596 * RETURN: Status597 *598 * DESCRIPTION: Converts an external object to an internal object.599 *600 ******************************************************************************/601 602acpi_status603acpi_ut_copy_eobject_to_iobject(union acpi_object *external_object,604 union acpi_operand_object **internal_object)605{606 acpi_status status;607 608 ACPI_FUNCTION_TRACE(ut_copy_eobject_to_iobject);609 610 if (external_object->type == ACPI_TYPE_PACKAGE) {611 status =612 acpi_ut_copy_epackage_to_ipackage(external_object,613 internal_object);614 } else {615 /*616 * Build a simple object (no nested objects)617 */618 status = acpi_ut_copy_esimple_to_isimple(external_object,619 internal_object);620 }621 622 return_ACPI_STATUS(status);623}624 625/*******************************************************************************626 *627 * FUNCTION: acpi_ut_copy_simple_object628 *629 * PARAMETERS: source_desc - The internal object to be copied630 * dest_desc - New target object631 *632 * RETURN: Status633 *634 * DESCRIPTION: Simple copy of one internal object to another. Reference count635 * of the destination object is preserved.636 *637 ******************************************************************************/638 639static acpi_status640acpi_ut_copy_simple_object(union acpi_operand_object *source_desc,641 union acpi_operand_object *dest_desc)642{643 u16 reference_count;644 union acpi_operand_object *next_object;645 acpi_status status;646 acpi_size copy_size;647 648 /* Save fields from destination that we don't want to overwrite */649 650 reference_count = dest_desc->common.reference_count;651 next_object = dest_desc->common.next_object;652 653 /*654 * Copy the entire source object over the destination object.655 * Note: Source can be either an operand object or namespace node.656 */657 copy_size = sizeof(union acpi_operand_object);658 if (ACPI_GET_DESCRIPTOR_TYPE(source_desc) == ACPI_DESC_TYPE_NAMED) {659 copy_size = sizeof(struct acpi_namespace_node);660 }661 662 memcpy(ACPI_CAST_PTR(char, dest_desc),663 ACPI_CAST_PTR(char, source_desc), copy_size);664 665 /* Restore the saved fields */666 667 dest_desc->common.reference_count = reference_count;668 dest_desc->common.next_object = next_object;669 670 /* New object is not static, regardless of source */671 672 dest_desc->common.flags &= ~AOPOBJ_STATIC_POINTER;673 674 /* Handle the objects with extra data */675 676 switch (dest_desc->common.type) {677 case ACPI_TYPE_BUFFER:678 /*679 * Allocate and copy the actual buffer if and only if:680 * 1) There is a valid buffer pointer681 * 2) The buffer has a length > 0682 */683 if ((source_desc->buffer.pointer) &&684 (source_desc->buffer.length)) {685 dest_desc->buffer.pointer =686 ACPI_ALLOCATE(source_desc->buffer.length);687 if (!dest_desc->buffer.pointer) {688 return (AE_NO_MEMORY);689 }690 691 /* Copy the actual buffer data */692 693 memcpy(dest_desc->buffer.pointer,694 source_desc->buffer.pointer,695 source_desc->buffer.length);696 }697 break;698 699 case ACPI_TYPE_STRING:700 /*701 * Allocate and copy the actual string if and only if:702 * 1) There is a valid string pointer703 * (Pointer to a NULL string is allowed)704 */705 if (source_desc->string.pointer) {706 dest_desc->string.pointer =707 ACPI_ALLOCATE((acpi_size)source_desc->string.708 length + 1);709 if (!dest_desc->string.pointer) {710 return (AE_NO_MEMORY);711 }712 713 /* Copy the actual string data */714 715 memcpy(dest_desc->string.pointer,716 source_desc->string.pointer,717 (acpi_size)source_desc->string.length + 1);718 }719 break;720 721 case ACPI_TYPE_LOCAL_REFERENCE:722 /*723 * We copied the reference object, so we now must add a reference724 * to the object pointed to by the reference725 *726 * DDBHandle reference (from Load/load_table) is a special reference,727 * it does not have a Reference.Object, so does not need to728 * increase the reference count729 */730 if (source_desc->reference.class == ACPI_REFCLASS_TABLE) {731 break;732 }733 734 acpi_ut_add_reference(source_desc->reference.object);735 break;736 737 case ACPI_TYPE_REGION:738 /*739 * We copied the Region Handler, so we now must add a reference740 */741 if (dest_desc->region.handler) {742 acpi_ut_add_reference(dest_desc->region.handler);743 }744 break;745 746 /*747 * For Mutex and Event objects, we cannot simply copy the underlying748 * OS object. We must create a new one.749 */750 case ACPI_TYPE_MUTEX:751 752 status = acpi_os_create_mutex(&dest_desc->mutex.os_mutex);753 if (ACPI_FAILURE(status)) {754 return (status);755 }756 break;757 758 case ACPI_TYPE_EVENT:759 760 status = acpi_os_create_semaphore(ACPI_NO_UNIT_LIMIT, 0,761 &dest_desc->event.762 os_semaphore);763 if (ACPI_FAILURE(status)) {764 return (status);765 }766 break;767 768 default:769 770 /* Nothing to do for other simple objects */771 772 break;773 }774 775 return (AE_OK);776}777 778/*******************************************************************************779 *780 * FUNCTION: acpi_ut_copy_ielement_to_ielement781 *782 * PARAMETERS: acpi_pkg_callback783 *784 * RETURN: Status785 *786 * DESCRIPTION: Copy one package element to another package element787 *788 ******************************************************************************/789 790static acpi_status791acpi_ut_copy_ielement_to_ielement(u8 object_type,792 union acpi_operand_object *source_object,793 union acpi_generic_state *state,794 void *context)795{796 acpi_status status = AE_OK;797 u32 this_index;798 union acpi_operand_object **this_target_ptr;799 union acpi_operand_object *target_object;800 801 ACPI_FUNCTION_ENTRY();802 803 this_index = state->pkg.index;804 this_target_ptr = (union acpi_operand_object **)805 &state->pkg.dest_object->package.elements[this_index];806 807 switch (object_type) {808 case ACPI_COPY_TYPE_SIMPLE:809 810 /* A null source object indicates a (legal) null package element */811 812 if (source_object) {813 /*814 * This is a simple object, just copy it815 */816 target_object =817 acpi_ut_create_internal_object(source_object->818 common.type);819 if (!target_object) {820 return (AE_NO_MEMORY);821 }822 823 status =824 acpi_ut_copy_simple_object(source_object,825 target_object);826 if (ACPI_FAILURE(status)) {827 goto error_exit;828 }829 830 *this_target_ptr = target_object;831 } else {832 /* Pass through a null element */833 834 *this_target_ptr = NULL;835 }836 break;837 838 case ACPI_COPY_TYPE_PACKAGE:839 /*840 * This object is a package - go down another nesting level841 * Create and build the package object842 */843 target_object =844 acpi_ut_create_package_object(source_object->package.count);845 if (!target_object) {846 return (AE_NO_MEMORY);847 }848 849 target_object->common.flags = source_object->common.flags;850 851 /* Pass the new package object back to the package walk routine */852 853 state->pkg.this_target_obj = target_object;854 855 /* Store the object pointer in the parent package object */856 857 *this_target_ptr = target_object;858 break;859 860 default:861 862 return (AE_BAD_PARAMETER);863 }864 865 return (status);866 867error_exit:868 acpi_ut_remove_reference(target_object);869 return (status);870}871 872/*******************************************************************************873 *874 * FUNCTION: acpi_ut_copy_ipackage_to_ipackage875 *876 * PARAMETERS: source_obj - Pointer to the source package object877 * dest_obj - Where the internal object is returned878 * walk_state - Current Walk state descriptor879 *880 * RETURN: Status881 *882 * DESCRIPTION: This function is called to copy an internal package object883 * into another internal package object.884 *885 ******************************************************************************/886 887static acpi_status888acpi_ut_copy_ipackage_to_ipackage(union acpi_operand_object *source_obj,889 union acpi_operand_object *dest_obj,890 struct acpi_walk_state *walk_state)891{892 acpi_status status = AE_OK;893 894 ACPI_FUNCTION_TRACE(ut_copy_ipackage_to_ipackage);895 896 dest_obj->common.type = source_obj->common.type;897 dest_obj->common.flags = source_obj->common.flags;898 dest_obj->package.count = source_obj->package.count;899 900 /*901 * Create the object array and walk the source package tree902 */903 dest_obj->package.elements = ACPI_ALLOCATE_ZEROED(((acpi_size)904 source_obj->package.905 count +906 1) * sizeof(void *));907 if (!dest_obj->package.elements) {908 ACPI_ERROR((AE_INFO, "Package allocation failure"));909 return_ACPI_STATUS(AE_NO_MEMORY);910 }911 912 /*913 * Copy the package element-by-element by walking the package "tree".914 * This handles nested packages of arbitrary depth.915 */916 status = acpi_ut_walk_package_tree(source_obj, dest_obj,917 acpi_ut_copy_ielement_to_ielement,918 walk_state);919 return_ACPI_STATUS(status);920}921 922/*******************************************************************************923 *924 * FUNCTION: acpi_ut_copy_iobject_to_iobject925 *926 * PARAMETERS: source_desc - The internal object to be copied927 * dest_desc - Where the copied object is returned928 * walk_state - Current walk state929 *930 * RETURN: Status931 *932 * DESCRIPTION: Copy an internal object to a new internal object933 *934 ******************************************************************************/935 936acpi_status937acpi_ut_copy_iobject_to_iobject(union acpi_operand_object *source_desc,938 union acpi_operand_object **dest_desc,939 struct acpi_walk_state *walk_state)940{941 acpi_status status = AE_OK;942 943 ACPI_FUNCTION_TRACE(ut_copy_iobject_to_iobject);944 945 /* Create the top level object */946 947 *dest_desc = acpi_ut_create_internal_object(source_desc->common.type);948 if (!*dest_desc) {949 return_ACPI_STATUS(AE_NO_MEMORY);950 }951 952 /* Copy the object and possible subobjects */953 954 if (source_desc->common.type == ACPI_TYPE_PACKAGE) {955 status =956 acpi_ut_copy_ipackage_to_ipackage(source_desc, *dest_desc,957 walk_state);958 } else {959 status = acpi_ut_copy_simple_object(source_desc, *dest_desc);960 }961 962 /* Delete the allocated object if copy failed */963 964 if (ACPI_FAILURE(status)) {965 acpi_ut_remove_reference(*dest_desc);966 }967 968 return_ACPI_STATUS(status);969}970