utcopy.c (26888B)
1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 2/****************************************************************************** 3 * 4 * Module Name: utcopy - Internal to external object translation utilities 5 * 6 * Copyright (C) 2000 - 2022, Intel Corp. 7 * 8 *****************************************************************************/ 9 10#include <acpi/acpi.h> 11#include "accommon.h" 12#include "acnamesp.h" 13 14 15#define _COMPONENT ACPI_UTILITIES 16ACPI_MODULE_NAME("utcopy") 17 18/* Local prototypes */ 19static acpi_status 20acpi_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_status 25acpi_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_status 31acpi_ut_copy_ipackage_to_epackage(union acpi_operand_object *internal_object, 32 u8 *buffer, acpi_size *space_used); 33 34static acpi_status 35acpi_ut_copy_esimple_to_isimple(union acpi_object *user_obj, 36 union acpi_operand_object **return_obj); 37 38static acpi_status 39acpi_ut_copy_epackage_to_ipackage(union acpi_object *external_object, 40 union acpi_operand_object **internal_object); 41 42static acpi_status 43acpi_ut_copy_simple_object(union acpi_operand_object *source_desc, 44 union acpi_operand_object *dest_desc); 45 46static acpi_status 47acpi_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_status 53acpi_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_esimple 60 * 61 * PARAMETERS: internal_object - Source object to be copied 62 * external_object - Where to return the copied object 63 * data_space - Where object data is returned (such as 64 * buffer and string data) 65 * buffer_space_used - Length of data_space that was used 66 * 67 * RETURN: Status 68 * 69 * DESCRIPTION: This function is called to copy a simple internal object to 70 * an external object. 71 * 72 * The data_space buffer is assumed to have sufficient space for 73 * the object. 74 * 75 ******************************************************************************/ 76 77static acpi_status 78acpi_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 uninitialized 90 * 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 as 102 * the internal object 103 */ 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 node 150 */ 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 type 187 */ 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_eelement 202 * 203 * PARAMETERS: acpi_pkg_callback 204 * 205 * RETURN: Status 206 * 207 * DESCRIPTION: Copy one package element to another package element 208 * 209 ******************************************************************************/ 210 211static acpi_status 212acpi_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 object 234 */ 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 object 247 */ 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 routine 255 */ 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 counter 261 */ 262 object_space = ACPI_ROUND_UP_TO_NATIVE_WORD((acpi_size) 263 target_object-> 264 package.count * 265 sizeof(union 266 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_epackage 282 * 283 * PARAMETERS: internal_object - Pointer to the object we are returning 284 * buffer - Where the object is returned 285 * space_used - Where the object length is returned 286 * 287 * RETURN: Status 288 * 289 * DESCRIPTION: This function is called to place a package object in a user 290 * 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 using 294 * the acpi_ut_get_object_size function before calling this function. 295 * 296 ******************************************************************************/ 297 298static acpi_status 299acpi_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 buffer 310 */ 311 external_object = ACPI_CAST_PTR(union acpi_object, buffer); 312 313 /* 314 * Free space begins right after the first package 315 */ 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 buffer 329 * and move the free space past it 330 */ 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_eobject 347 * 348 * PARAMETERS: internal_object - The internal object to be converted 349 * ret_buffer - Where the object is returned 350 * 351 * RETURN: Status 352 * 353 * DESCRIPTION: This function is called to build an API object to be returned 354 * to the caller. 355 * 356 ******************************************************************************/ 357 358acpi_status 359acpi_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 (including 369 * 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(union 380 acpi_object, 381 ret_buffer-> 382 pointer), 383 ACPI_ADD_PTR(u8, 384 ret_buffer-> 385 pointer, 386 ACPI_ROUND_UP_TO_NATIVE_WORD 387 (sizeof 388 (union 389 acpi_object))), 390 &ret_buffer->length); 391 /* 392 * build simple does not include the object size in the length 393 * so we add it in here 394 */ 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_isimple 404 * 405 * PARAMETERS: external_object - The external object to be converted 406 * ret_internal_object - Where the internal object is returned 407 * 408 * RETURN: Status 409 * 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 matter 413 * what we do with them!) 414 * 415 ******************************************************************************/ 416 417static acpi_status 418acpi_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, Integer 427 */ 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_ipackage 529 * 530 * PARAMETERS: external_object - The external object to be converted 531 * internal_object - Where the internal object is returned 532 * 533 * RETURN: Status 534 * 535 * DESCRIPTION: Copy an external package object to an internal package. 536 * Handles nested packages. 537 * 538 ******************************************************************************/ 539 540static acpi_status 541acpi_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 external 563 * 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_iobject 592 * 593 * PARAMETERS: external_object - The external object to be converted 594 * internal_object - Where the internal object is returned 595 * 596 * RETURN: Status 597 * 598 * DESCRIPTION: Converts an external object to an internal object. 599 * 600 ******************************************************************************/ 601 602acpi_status 603acpi_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_object 628 * 629 * PARAMETERS: source_desc - The internal object to be copied 630 * dest_desc - New target object 631 * 632 * RETURN: Status 633 * 634 * DESCRIPTION: Simple copy of one internal object to another. Reference count 635 * of the destination object is preserved. 636 * 637 ******************************************************************************/ 638 639static acpi_status 640acpi_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 pointer 681 * 2) The buffer has a length > 0 682 */ 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 pointer 703 * (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 reference 724 * to the object pointed to by the reference 725 * 726 * DDBHandle reference (from Load/load_table) is a special reference, 727 * it does not have a Reference.Object, so does not need to 728 * increase the reference count 729 */ 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 reference 740 */ 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 underlying 748 * 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_ielement 781 * 782 * PARAMETERS: acpi_pkg_callback 783 * 784 * RETURN: Status 785 * 786 * DESCRIPTION: Copy one package element to another package element 787 * 788 ******************************************************************************/ 789 790static acpi_status 791acpi_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 it 815 */ 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 level 841 * Create and build the package object 842 */ 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_ipackage 875 * 876 * PARAMETERS: source_obj - Pointer to the source package object 877 * dest_obj - Where the internal object is returned 878 * walk_state - Current Walk state descriptor 879 * 880 * RETURN: Status 881 * 882 * DESCRIPTION: This function is called to copy an internal package object 883 * into another internal package object. 884 * 885 ******************************************************************************/ 886 887static acpi_status 888acpi_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 tree 902 */ 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 if (ACPI_FAILURE(status)) { 920 921 /* On failure, delete the destination package object */ 922 923 acpi_ut_remove_reference(dest_obj); 924 } 925 926 return_ACPI_STATUS(status); 927} 928 929/******************************************************************************* 930 * 931 * FUNCTION: acpi_ut_copy_iobject_to_iobject 932 * 933 * PARAMETERS: source_desc - The internal object to be copied 934 * dest_desc - Where the copied object is returned 935 * walk_state - Current walk state 936 * 937 * RETURN: Status 938 * 939 * DESCRIPTION: Copy an internal object to a new internal object 940 * 941 ******************************************************************************/ 942 943acpi_status 944acpi_ut_copy_iobject_to_iobject(union acpi_operand_object *source_desc, 945 union acpi_operand_object **dest_desc, 946 struct acpi_walk_state *walk_state) 947{ 948 acpi_status status = AE_OK; 949 950 ACPI_FUNCTION_TRACE(ut_copy_iobject_to_iobject); 951 952 /* Create the top level object */ 953 954 *dest_desc = acpi_ut_create_internal_object(source_desc->common.type); 955 if (!*dest_desc) { 956 return_ACPI_STATUS(AE_NO_MEMORY); 957 } 958 959 /* Copy the object and possible subobjects */ 960 961 if (source_desc->common.type == ACPI_TYPE_PACKAGE) { 962 status = 963 acpi_ut_copy_ipackage_to_ipackage(source_desc, *dest_desc, 964 walk_state); 965 } else { 966 status = acpi_ut_copy_simple_object(source_desc, *dest_desc); 967 } 968 969 /* Delete the allocated object if copy failed */ 970 971 if (ACPI_FAILURE(status)) { 972 acpi_ut_remove_reference(*dest_desc); 973 } 974 975 return_ACPI_STATUS(status); 976}