utcopy.c revision 52fc0b026e99b5d5d585095148d997d5634bbc25
1/****************************************************************************** 2 * 3 * Module Name: utcopy - Internal to external object translation utilities 4 * 5 *****************************************************************************/ 6 7/* 8 * Copyright (C) 2000 - 2006, R. Byron Moore 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions, and the following disclaimer, 16 * without modification. 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18 * substantially similar to the "NO WARRANTY" disclaimer below 19 * ("Disclaimer") and any redistribution must be conditioned upon 20 * including a substantially similar Disclaimer requirement for further 21 * binary redistribution. 22 * 3. Neither the names of the above-listed copyright holders nor the names 23 * of any contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * Alternatively, this software may be distributed under the terms of the 27 * GNU General Public License ("GPL") version 2 as published by the Free 28 * Software Foundation. 29 * 30 * NO WARRANTY 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 * POSSIBILITY OF SUCH DAMAGES. 42 */ 43 44#include <acpi/acpi.h> 45#include <acpi/amlcode.h> 46 47#define _COMPONENT ACPI_UTILITIES 48ACPI_MODULE_NAME("utcopy") 49 50/* Local prototypes */ 51static acpi_status 52acpi_ut_copy_isimple_to_esimple(union acpi_operand_object *internal_object, 53 union acpi_object *external_object, 54 u8 * data_space, acpi_size * buffer_space_used); 55 56static acpi_status 57acpi_ut_copy_ielement_to_ielement(u8 object_type, 58 union acpi_operand_object *source_object, 59 union acpi_generic_state *state, 60 void *context); 61 62static acpi_status 63acpi_ut_copy_ipackage_to_epackage(union acpi_operand_object *internal_object, 64 u8 * buffer, acpi_size * space_used); 65 66static acpi_status 67acpi_ut_copy_esimple_to_isimple(union acpi_object *user_obj, 68 union acpi_operand_object **return_obj); 69 70static acpi_status 71acpi_ut_copy_simple_object(union acpi_operand_object *source_desc, 72 union acpi_operand_object *dest_desc); 73 74static acpi_status 75acpi_ut_copy_ielement_to_eelement(u8 object_type, 76 union acpi_operand_object *source_object, 77 union acpi_generic_state *state, 78 void *context); 79 80static acpi_status 81acpi_ut_copy_ipackage_to_ipackage(union acpi_operand_object *source_obj, 82 union acpi_operand_object *dest_obj, 83 struct acpi_walk_state *walk_state); 84 85/******************************************************************************* 86 * 87 * FUNCTION: acpi_ut_copy_isimple_to_esimple 88 * 89 * PARAMETERS: internal_object - Source object to be copied 90 * external_object - Where to return the copied object 91 * data_space - Where object data is returned (such as 92 * buffer and string data) 93 * buffer_space_used - Length of data_space that was used 94 * 95 * RETURN: Status 96 * 97 * DESCRIPTION: This function is called to copy a simple internal object to 98 * an external object. 99 * 100 * The data_space buffer is assumed to have sufficient space for 101 * the object. 102 * 103 ******************************************************************************/ 104 105static acpi_status 106acpi_ut_copy_isimple_to_esimple(union acpi_operand_object *internal_object, 107 union acpi_object *external_object, 108 u8 * data_space, acpi_size * buffer_space_used) 109{ 110 acpi_status status = AE_OK; 111 112 ACPI_FUNCTION_TRACE("ut_copy_isimple_to_esimple"); 113 114 *buffer_space_used = 0; 115 116 /* 117 * Check for NULL object case (could be an uninitialized 118 * package element) 119 */ 120 if (!internal_object) { 121 return_ACPI_STATUS(AE_OK); 122 } 123 124 /* Always clear the external object */ 125 126 ACPI_MEMSET(external_object, 0, sizeof(union acpi_object)); 127 128 /* 129 * In general, the external object will be the same type as 130 * the internal object 131 */ 132 external_object->type = ACPI_GET_OBJECT_TYPE(internal_object); 133 134 /* However, only a limited number of external types are supported */ 135 136 switch (ACPI_GET_OBJECT_TYPE(internal_object)) { 137 case ACPI_TYPE_STRING: 138 139 external_object->string.pointer = (char *)data_space; 140 external_object->string.length = internal_object->string.length; 141 *buffer_space_used = ACPI_ROUND_UP_TO_NATIVE_WORD((acpi_size) 142 internal_object-> 143 string. 144 length + 1); 145 146 ACPI_MEMCPY((void *)data_space, 147 (void *)internal_object->string.pointer, 148 (acpi_size) internal_object->string.length + 1); 149 break; 150 151 case ACPI_TYPE_BUFFER: 152 153 external_object->buffer.pointer = data_space; 154 external_object->buffer.length = internal_object->buffer.length; 155 *buffer_space_used = 156 ACPI_ROUND_UP_TO_NATIVE_WORD(internal_object->string. 157 length); 158 159 ACPI_MEMCPY((void *)data_space, 160 (void *)internal_object->buffer.pointer, 161 internal_object->buffer.length); 162 break; 163 164 case ACPI_TYPE_INTEGER: 165 166 external_object->integer.value = internal_object->integer.value; 167 break; 168 169 case ACPI_TYPE_LOCAL_REFERENCE: 170 171 /* 172 * This is an object reference. Attempt to dereference it. 173 */ 174 switch (internal_object->reference.opcode) { 175 case AML_INT_NAMEPATH_OP: 176 177 /* For namepath, return the object handle ("reference") */ 178 179 default: 180 /* 181 * Use the object type of "Any" to indicate a reference 182 * to object containing a handle to an ACPI named object. 183 */ 184 external_object->type = ACPI_TYPE_ANY; 185 external_object->reference.handle = 186 internal_object->reference.node; 187 break; 188 } 189 break; 190 191 case ACPI_TYPE_PROCESSOR: 192 193 external_object->processor.proc_id = 194 internal_object->processor.proc_id; 195 external_object->processor.pblk_address = 196 internal_object->processor.address; 197 external_object->processor.pblk_length = 198 internal_object->processor.length; 199 break; 200 201 case ACPI_TYPE_POWER: 202 203 external_object->power_resource.system_level = 204 internal_object->power_resource.system_level; 205 206 external_object->power_resource.resource_order = 207 internal_object->power_resource.resource_order; 208 break; 209 210 default: 211 /* 212 * There is no corresponding external object type 213 */ 214 return_ACPI_STATUS(AE_SUPPORT); 215 } 216 217 return_ACPI_STATUS(status); 218} 219 220/******************************************************************************* 221 * 222 * FUNCTION: acpi_ut_copy_ielement_to_eelement 223 * 224 * PARAMETERS: acpi_pkg_callback 225 * 226 * RETURN: Status 227 * 228 * DESCRIPTION: Copy one package element to another package element 229 * 230 ******************************************************************************/ 231 232static acpi_status 233acpi_ut_copy_ielement_to_eelement(u8 object_type, 234 union acpi_operand_object *source_object, 235 union acpi_generic_state *state, 236 void *context) 237{ 238 acpi_status status = AE_OK; 239 struct acpi_pkg_info *info = (struct acpi_pkg_info *)context; 240 acpi_size object_space; 241 u32 this_index; 242 union acpi_object *target_object; 243 244 ACPI_FUNCTION_ENTRY(); 245 246 this_index = state->pkg.index; 247 target_object = (union acpi_object *) 248 &((union acpi_object *)(state->pkg.dest_object))->package. 249 elements[this_index]; 250 251 switch (object_type) { 252 case ACPI_COPY_TYPE_SIMPLE: 253 254 /* 255 * This is a simple or null object 256 */ 257 status = acpi_ut_copy_isimple_to_esimple(source_object, 258 target_object, 259 info->free_space, 260 &object_space); 261 if (ACPI_FAILURE(status)) { 262 return (status); 263 } 264 break; 265 266 case ACPI_COPY_TYPE_PACKAGE: 267 268 /* 269 * Build the package object 270 */ 271 target_object->type = ACPI_TYPE_PACKAGE; 272 target_object->package.count = source_object->package.count; 273 target_object->package.elements = 274 ACPI_CAST_PTR(union acpi_object, info->free_space); 275 276 /* 277 * Pass the new package object back to the package walk routine 278 */ 279 state->pkg.this_target_obj = target_object; 280 281 /* 282 * Save space for the array of objects (Package elements) 283 * update the buffer length counter 284 */ 285 object_space = ACPI_ROUND_UP_TO_NATIVE_WORD((acpi_size) 286 target_object-> 287 package.count * 288 sizeof(union 289 acpi_object)); 290 break; 291 292 default: 293 return (AE_BAD_PARAMETER); 294 } 295 296 info->free_space += object_space; 297 info->length += object_space; 298 return (status); 299} 300 301/******************************************************************************* 302 * 303 * FUNCTION: acpi_ut_copy_ipackage_to_epackage 304 * 305 * PARAMETERS: internal_object - Pointer to the object we are returning 306 * Buffer - Where the object is returned 307 * space_used - Where the object length is returned 308 * 309 * RETURN: Status 310 * 311 * DESCRIPTION: This function is called to place a package object in a user 312 * buffer. A package object by definition contains other objects. 313 * 314 * The buffer is assumed to have sufficient space for the object. 315 * The caller must have verified the buffer length needed using the 316 * acpi_ut_get_object_size function before calling this function. 317 * 318 ******************************************************************************/ 319 320static acpi_status 321acpi_ut_copy_ipackage_to_epackage(union acpi_operand_object *internal_object, 322 u8 * buffer, acpi_size * space_used) 323{ 324 union acpi_object *external_object; 325 acpi_status status; 326 struct acpi_pkg_info info; 327 328 ACPI_FUNCTION_TRACE("ut_copy_ipackage_to_epackage"); 329 330 /* 331 * First package at head of the buffer 332 */ 333 external_object = ACPI_CAST_PTR(union acpi_object, buffer); 334 335 /* 336 * Free space begins right after the first package 337 */ 338 info.length = ACPI_ROUND_UP_TO_NATIVE_WORD(sizeof(union acpi_object)); 339 info.free_space = 340 buffer + ACPI_ROUND_UP_TO_NATIVE_WORD(sizeof(union acpi_object)); 341 info.object_space = 0; 342 info.num_packages = 1; 343 344 external_object->type = ACPI_GET_OBJECT_TYPE(internal_object); 345 external_object->package.count = internal_object->package.count; 346 external_object->package.elements = ACPI_CAST_PTR(union acpi_object, 347 info.free_space); 348 349 /* 350 * Leave room for an array of ACPI_OBJECTS in the buffer 351 * and move the free space past it 352 */ 353 info.length += (acpi_size) external_object->package.count * 354 ACPI_ROUND_UP_TO_NATIVE_WORD(sizeof(union acpi_object)); 355 info.free_space += external_object->package.count * 356 ACPI_ROUND_UP_TO_NATIVE_WORD(sizeof(union acpi_object)); 357 358 status = acpi_ut_walk_package_tree(internal_object, external_object, 359 acpi_ut_copy_ielement_to_eelement, 360 &info); 361 362 *space_used = info.length; 363 return_ACPI_STATUS(status); 364} 365 366/******************************************************************************* 367 * 368 * FUNCTION: acpi_ut_copy_iobject_to_eobject 369 * 370 * PARAMETERS: internal_object - The internal object to be converted 371 * buffer_ptr - Where the object is returned 372 * 373 * RETURN: Status 374 * 375 * DESCRIPTION: This function is called to build an API object to be returned to 376 * the caller. 377 * 378 ******************************************************************************/ 379 380acpi_status 381acpi_ut_copy_iobject_to_eobject(union acpi_operand_object *internal_object, 382 struct acpi_buffer *ret_buffer) 383{ 384 acpi_status status; 385 386 ACPI_FUNCTION_TRACE("ut_copy_iobject_to_eobject"); 387 388 if (ACPI_GET_OBJECT_TYPE(internal_object) == ACPI_TYPE_PACKAGE) { 389 /* 390 * Package object: Copy all subobjects (including 391 * nested packages) 392 */ 393 status = acpi_ut_copy_ipackage_to_epackage(internal_object, 394 ret_buffer->pointer, 395 &ret_buffer->length); 396 } else { 397 /* 398 * Build a simple object (no nested objects) 399 */ 400 status = acpi_ut_copy_isimple_to_esimple(internal_object, 401 ACPI_CAST_PTR(union 402 acpi_object, 403 ret_buffer-> 404 pointer), 405 ACPI_ADD_PTR(u8, 406 ret_buffer-> 407 pointer, 408 ACPI_ROUND_UP_TO_NATIVE_WORD 409 (sizeof 410 (union 411 acpi_object))), 412 &ret_buffer->length); 413 /* 414 * build simple does not include the object size in the length 415 * so we add it in here 416 */ 417 ret_buffer->length += sizeof(union acpi_object); 418 } 419 420 return_ACPI_STATUS(status); 421} 422 423/******************************************************************************* 424 * 425 * FUNCTION: acpi_ut_copy_esimple_to_isimple 426 * 427 * PARAMETERS: external_object - The external object to be converted 428 * ret_internal_object - Where the internal object is returned 429 * 430 * RETURN: Status 431 * 432 * DESCRIPTION: This function copies an external object to an internal one. 433 * NOTE: Pointers can be copied, we don't need to copy data. 434 * (The pointers have to be valid in our address space no matter 435 * what we do with them!) 436 * 437 ******************************************************************************/ 438 439static acpi_status 440acpi_ut_copy_esimple_to_isimple(union acpi_object *external_object, 441 union acpi_operand_object **ret_internal_object) 442{ 443 union acpi_operand_object *internal_object; 444 445 ACPI_FUNCTION_TRACE("ut_copy_esimple_to_isimple"); 446 447 /* 448 * Simple types supported are: String, Buffer, Integer 449 */ 450 switch (external_object->type) { 451 case ACPI_TYPE_STRING: 452 case ACPI_TYPE_BUFFER: 453 case ACPI_TYPE_INTEGER: 454 455 internal_object = acpi_ut_create_internal_object((u8) 456 external_object-> 457 type); 458 if (!internal_object) { 459 return_ACPI_STATUS(AE_NO_MEMORY); 460 } 461 break; 462 463 default: 464 /* All other types are not supported */ 465 466 return_ACPI_STATUS(AE_SUPPORT); 467 } 468 469 /* Must COPY string and buffer contents */ 470 471 switch (external_object->type) { 472 case ACPI_TYPE_STRING: 473 474 internal_object->string.pointer = 475 ACPI_MEM_CALLOCATE((acpi_size) external_object->string. 476 length + 1); 477 if (!internal_object->string.pointer) { 478 goto error_exit; 479 } 480 481 ACPI_MEMCPY(internal_object->string.pointer, 482 external_object->string.pointer, 483 external_object->string.length); 484 485 internal_object->string.length = external_object->string.length; 486 break; 487 488 case ACPI_TYPE_BUFFER: 489 490 internal_object->buffer.pointer = 491 ACPI_MEM_CALLOCATE(external_object->buffer.length); 492 if (!internal_object->buffer.pointer) { 493 goto error_exit; 494 } 495 496 ACPI_MEMCPY(internal_object->buffer.pointer, 497 external_object->buffer.pointer, 498 external_object->buffer.length); 499 500 internal_object->buffer.length = external_object->buffer.length; 501 break; 502 503 case ACPI_TYPE_INTEGER: 504 505 internal_object->integer.value = external_object->integer.value; 506 break; 507 508 default: 509 /* Other types can't get here */ 510 break; 511 } 512 513 *ret_internal_object = internal_object; 514 return_ACPI_STATUS(AE_OK); 515 516 error_exit: 517 acpi_ut_remove_reference(internal_object); 518 return_ACPI_STATUS(AE_NO_MEMORY); 519} 520 521#ifdef ACPI_FUTURE_IMPLEMENTATION 522/* Code to convert packages that are parameters to control methods */ 523 524/******************************************************************************* 525 * 526 * FUNCTION: acpi_ut_copy_epackage_to_ipackage 527 * 528 * PARAMETERS: *internal_object - Pointer to the object we are returning 529 * *Buffer - Where the object is returned 530 * *space_used - Where the length of the object is returned 531 * 532 * RETURN: Status 533 * 534 * DESCRIPTION: This function is called to place a package object in a user 535 * buffer. A package object by definition contains other objects. 536 * 537 * The buffer is assumed to have sufficient space for the object. 538 * The caller must have verified the buffer length needed using the 539 * acpi_ut_get_object_size function before calling this function. 540 * 541 ******************************************************************************/ 542 543static acpi_status 544acpi_ut_copy_epackage_to_ipackage(union acpi_operand_object *internal_object, 545 u8 * buffer, u32 * space_used) 546{ 547 u8 *free_space; 548 union acpi_object *external_object; 549 u32 length = 0; 550 u32 this_index; 551 u32 object_space = 0; 552 union acpi_operand_object *this_internal_obj; 553 union acpi_object *this_external_obj; 554 555 ACPI_FUNCTION_TRACE("ut_copy_epackage_to_ipackage"); 556 557 /* 558 * First package at head of the buffer 559 */ 560 external_object = (union acpi_object *)buffer; 561 562 /* 563 * Free space begins right after the first package 564 */ 565 free_space = buffer + sizeof(union acpi_object); 566 567 external_object->type = ACPI_GET_OBJECT_TYPE(internal_object); 568 external_object->package.count = internal_object->package.count; 569 external_object->package.elements = (union acpi_object *)free_space; 570 571 /* 572 * Build an array of ACPI_OBJECTS in the buffer 573 * and move the free space past it 574 */ 575 free_space += 576 external_object->package.count * sizeof(union acpi_object); 577 578 /* Call walk_package */ 579 580} 581 582#endif /* Future implementation */ 583 584/******************************************************************************* 585 * 586 * FUNCTION: acpi_ut_copy_eobject_to_iobject 587 * 588 * PARAMETERS: *internal_object - The external object to be converted 589 * *buffer_ptr - Where the internal object is returned 590 * 591 * RETURN: Status - the status of the call 592 * 593 * DESCRIPTION: Converts an external object to an internal object. 594 * 595 ******************************************************************************/ 596 597acpi_status 598acpi_ut_copy_eobject_to_iobject(union acpi_object *external_object, 599 union acpi_operand_object **internal_object) 600{ 601 acpi_status status; 602 603 ACPI_FUNCTION_TRACE("ut_copy_eobject_to_iobject"); 604 605 if (external_object->type == ACPI_TYPE_PACKAGE) { 606 /* 607 * Packages as external input to control methods are not supported, 608 */ 609 ACPI_ERROR((AE_INFO, 610 "Packages as parameters not implemented!")); 611 612 return_ACPI_STATUS(AE_NOT_IMPLEMENTED); 613 } 614 615 else { 616 /* 617 * Build a simple object (no nested objects) 618 */ 619 status = 620 acpi_ut_copy_esimple_to_isimple(external_object, 621 internal_object); 622 } 623 624 return_ACPI_STATUS(status); 625} 626 627/******************************************************************************* 628 * 629 * FUNCTION: acpi_ut_copy_simple_object 630 * 631 * PARAMETERS: source_desc - The internal object to be copied 632 * dest_desc - New target object 633 * 634 * RETURN: Status 635 * 636 * DESCRIPTION: Simple copy of one internal object to another. Reference count 637 * of the destination object is preserved. 638 * 639 ******************************************************************************/ 640 641static acpi_status 642acpi_ut_copy_simple_object(union acpi_operand_object *source_desc, 643 union acpi_operand_object *dest_desc) 644{ 645 u16 reference_count; 646 union acpi_operand_object *next_object; 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 /* Copy the entire source object over the destination object */ 654 655 ACPI_MEMCPY((char *)dest_desc, (char *)source_desc, 656 sizeof(union acpi_operand_object)); 657 658 /* Restore the saved fields */ 659 660 dest_desc->common.reference_count = reference_count; 661 dest_desc->common.next_object = next_object; 662 663 /* New object is not static, regardless of source */ 664 665 dest_desc->common.flags &= ~AOPOBJ_STATIC_POINTER; 666 667 /* Handle the objects with extra data */ 668 669 switch (ACPI_GET_OBJECT_TYPE(dest_desc)) { 670 case ACPI_TYPE_BUFFER: 671 /* 672 * Allocate and copy the actual buffer if and only if: 673 * 1) There is a valid buffer pointer 674 * 2) The buffer has a length > 0 675 */ 676 if ((source_desc->buffer.pointer) && 677 (source_desc->buffer.length)) { 678 dest_desc->buffer.pointer = 679 ACPI_MEM_ALLOCATE(source_desc->buffer.length); 680 if (!dest_desc->buffer.pointer) { 681 return (AE_NO_MEMORY); 682 } 683 684 /* Copy the actual buffer data */ 685 686 ACPI_MEMCPY(dest_desc->buffer.pointer, 687 source_desc->buffer.pointer, 688 source_desc->buffer.length); 689 } 690 break; 691 692 case ACPI_TYPE_STRING: 693 /* 694 * Allocate and copy the actual string if and only if: 695 * 1) There is a valid string pointer 696 * (Pointer to a NULL string is allowed) 697 */ 698 if (source_desc->string.pointer) { 699 dest_desc->string.pointer = 700 ACPI_MEM_ALLOCATE((acpi_size) source_desc->string. 701 length + 1); 702 if (!dest_desc->string.pointer) { 703 return (AE_NO_MEMORY); 704 } 705 706 /* Copy the actual string data */ 707 708 ACPI_MEMCPY(dest_desc->string.pointer, 709 source_desc->string.pointer, 710 (acpi_size) source_desc->string.length + 1); 711 } 712 break; 713 714 case ACPI_TYPE_LOCAL_REFERENCE: 715 /* 716 * We copied the reference object, so we now must add a reference 717 * to the object pointed to by the reference 718 */ 719 acpi_ut_add_reference(source_desc->reference.object); 720 break; 721 722 default: 723 /* Nothing to do for other simple objects */ 724 break; 725 } 726 727 return (AE_OK); 728} 729 730/******************************************************************************* 731 * 732 * FUNCTION: acpi_ut_copy_ielement_to_ielement 733 * 734 * PARAMETERS: acpi_pkg_callback 735 * 736 * RETURN: Status 737 * 738 * DESCRIPTION: Copy one package element to another package element 739 * 740 ******************************************************************************/ 741 742static acpi_status 743acpi_ut_copy_ielement_to_ielement(u8 object_type, 744 union acpi_operand_object *source_object, 745 union acpi_generic_state *state, 746 void *context) 747{ 748 acpi_status status = AE_OK; 749 u32 this_index; 750 union acpi_operand_object **this_target_ptr; 751 union acpi_operand_object *target_object; 752 753 ACPI_FUNCTION_ENTRY(); 754 755 this_index = state->pkg.index; 756 this_target_ptr = (union acpi_operand_object **) 757 &state->pkg.dest_object->package.elements[this_index]; 758 759 switch (object_type) { 760 case ACPI_COPY_TYPE_SIMPLE: 761 762 /* A null source object indicates a (legal) null package element */ 763 764 if (source_object) { 765 /* 766 * This is a simple object, just copy it 767 */ 768 target_object = 769 acpi_ut_create_internal_object(ACPI_GET_OBJECT_TYPE 770 (source_object)); 771 if (!target_object) { 772 return (AE_NO_MEMORY); 773 } 774 775 status = 776 acpi_ut_copy_simple_object(source_object, 777 target_object); 778 if (ACPI_FAILURE(status)) { 779 goto error_exit; 780 } 781 782 *this_target_ptr = target_object; 783 } else { 784 /* Pass through a null element */ 785 786 *this_target_ptr = NULL; 787 } 788 break; 789 790 case ACPI_COPY_TYPE_PACKAGE: 791 792 /* 793 * This object is a package - go down another nesting level 794 * Create and build the package object 795 */ 796 target_object = 797 acpi_ut_create_internal_object(ACPI_TYPE_PACKAGE); 798 if (!target_object) { 799 return (AE_NO_MEMORY); 800 } 801 802 target_object->package.count = source_object->package.count; 803 target_object->common.flags = source_object->common.flags; 804 805 /* 806 * Create the object array 807 */ 808 target_object->package.elements = 809 ACPI_MEM_CALLOCATE(((acpi_size) source_object->package. 810 count + 1) * sizeof(void *)); 811 if (!target_object->package.elements) { 812 status = AE_NO_MEMORY; 813 goto error_exit; 814 } 815 816 /* 817 * Pass the new package object back to the package walk routine 818 */ 819 state->pkg.this_target_obj = target_object; 820 821 /* 822 * Store the object pointer in the parent package object 823 */ 824 *this_target_ptr = target_object; 825 break; 826 827 default: 828 return (AE_BAD_PARAMETER); 829 } 830 831 return (status); 832 833 error_exit: 834 acpi_ut_remove_reference(target_object); 835 return (status); 836} 837 838/******************************************************************************* 839 * 840 * FUNCTION: acpi_ut_copy_ipackage_to_ipackage 841 * 842 * PARAMETERS: *source_obj - Pointer to the source package object 843 * *dest_obj - Where the internal object is returned 844 * 845 * RETURN: Status - the status of the call 846 * 847 * DESCRIPTION: This function is called to copy an internal package object 848 * into another internal package object. 849 * 850 ******************************************************************************/ 851 852static acpi_status 853acpi_ut_copy_ipackage_to_ipackage(union acpi_operand_object *source_obj, 854 union acpi_operand_object *dest_obj, 855 struct acpi_walk_state *walk_state) 856{ 857 acpi_status status = AE_OK; 858 859 ACPI_FUNCTION_TRACE("ut_copy_ipackage_to_ipackage"); 860 861 dest_obj->common.type = ACPI_GET_OBJECT_TYPE(source_obj); 862 dest_obj->common.flags = source_obj->common.flags; 863 dest_obj->package.count = source_obj->package.count; 864 865 /* 866 * Create the object array and walk the source package tree 867 */ 868 dest_obj->package.elements = ACPI_MEM_CALLOCATE(((acpi_size) 869 source_obj->package. 870 count + 871 1) * sizeof(void *)); 872 if (!dest_obj->package.elements) { 873 ACPI_ERROR((AE_INFO, "Package allocation failure")); 874 return_ACPI_STATUS(AE_NO_MEMORY); 875 } 876 877 /* 878 * Copy the package element-by-element by walking the package "tree". 879 * This handles nested packages of arbitrary depth. 880 */ 881 status = acpi_ut_walk_package_tree(source_obj, dest_obj, 882 acpi_ut_copy_ielement_to_ielement, 883 walk_state); 884 if (ACPI_FAILURE(status)) { 885 886 /* On failure, delete the destination package object */ 887 888 acpi_ut_remove_reference(dest_obj); 889 } 890 891 return_ACPI_STATUS(status); 892} 893 894/******************************************************************************* 895 * 896 * FUNCTION: acpi_ut_copy_iobject_to_iobject 897 * 898 * PARAMETERS: walk_state - Current walk state 899 * source_desc - The internal object to be copied 900 * dest_desc - Where the copied object is returned 901 * 902 * RETURN: Status 903 * 904 * DESCRIPTION: Copy an internal object to a new internal object 905 * 906 ******************************************************************************/ 907 908acpi_status 909acpi_ut_copy_iobject_to_iobject(union acpi_operand_object *source_desc, 910 union acpi_operand_object **dest_desc, 911 struct acpi_walk_state *walk_state) 912{ 913 acpi_status status = AE_OK; 914 915 ACPI_FUNCTION_TRACE("ut_copy_iobject_to_iobject"); 916 917 /* Create the top level object */ 918 919 *dest_desc = 920 acpi_ut_create_internal_object(ACPI_GET_OBJECT_TYPE(source_desc)); 921 if (!*dest_desc) { 922 return_ACPI_STATUS(AE_NO_MEMORY); 923 } 924 925 /* Copy the object and possible subobjects */ 926 927 if (ACPI_GET_OBJECT_TYPE(source_desc) == ACPI_TYPE_PACKAGE) { 928 status = 929 acpi_ut_copy_ipackage_to_ipackage(source_desc, *dest_desc, 930 walk_state); 931 } else { 932 status = acpi_ut_copy_simple_object(source_desc, *dest_desc); 933 } 934 935 return_ACPI_STATUS(status); 936} 937