1 /****************************************************************************** 2 * 3 * Module Name: utcopy - Internal to external object translation utilities 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2015, Intel Corp. 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 "accommon.h" 46 #include "acnamesp.h" 47 48 49 #define _COMPONENT ACPI_UTILITIES 50 ACPI_MODULE_NAME("utcopy") 51 52 /* Local prototypes */ 53 static acpi_status 54 acpi_ut_copy_isimple_to_esimple(union acpi_operand_object *internal_object, 55 union acpi_object *external_object, 56 u8 * data_space, acpi_size * buffer_space_used); 57 58 static acpi_status 59 acpi_ut_copy_ielement_to_ielement(u8 object_type, 60 union acpi_operand_object *source_object, 61 union acpi_generic_state *state, 62 void *context); 63 64 static acpi_status 65 acpi_ut_copy_ipackage_to_epackage(union acpi_operand_object *internal_object, 66 u8 * buffer, acpi_size * space_used); 67 68 static acpi_status 69 acpi_ut_copy_esimple_to_isimple(union acpi_object *user_obj, 70 union acpi_operand_object **return_obj); 71 72 static acpi_status 73 acpi_ut_copy_epackage_to_ipackage(union acpi_object *external_object, 74 union acpi_operand_object **internal_object); 75 76 static acpi_status 77 acpi_ut_copy_simple_object(union acpi_operand_object *source_desc, 78 union acpi_operand_object *dest_desc); 79 80 static acpi_status 81 acpi_ut_copy_ielement_to_eelement(u8 object_type, 82 union acpi_operand_object *source_object, 83 union acpi_generic_state *state, 84 void *context); 85 86 static acpi_status 87 acpi_ut_copy_ipackage_to_ipackage(union acpi_operand_object *source_obj, 88 union acpi_operand_object *dest_obj, 89 struct acpi_walk_state *walk_state); 90 91 /******************************************************************************* 92 * 93 * FUNCTION: acpi_ut_copy_isimple_to_esimple 94 * 95 * PARAMETERS: internal_object - Source object to be copied 96 * external_object - Where to return the copied object 97 * data_space - Where object data is returned (such as 98 * buffer and string data) 99 * buffer_space_used - Length of data_space that was used 100 * 101 * RETURN: Status 102 * 103 * DESCRIPTION: This function is called to copy a simple internal object to 104 * an external object. 105 * 106 * The data_space buffer is assumed to have sufficient space for 107 * the object. 108 * 109 ******************************************************************************/ 110 111 static acpi_status 112 acpi_ut_copy_isimple_to_esimple(union acpi_operand_object *internal_object, 113 union acpi_object *external_object, 114 u8 * data_space, acpi_size * buffer_space_used) 115 { 116 acpi_status status = AE_OK; 117 118 ACPI_FUNCTION_TRACE(ut_copy_isimple_to_esimple); 119 120 *buffer_space_used = 0; 121 122 /* 123 * Check for NULL object case (could be an uninitialized 124 * package element) 125 */ 126 if (!internal_object) { 127 return_ACPI_STATUS(AE_OK); 128 } 129 130 /* Always clear the external object */ 131 132 memset(external_object, 0, sizeof(union acpi_object)); 133 134 /* 135 * In general, the external object will be the same type as 136 * the internal object 137 */ 138 external_object->type = internal_object->common.type; 139 140 /* However, only a limited number of external types are supported */ 141 142 switch (internal_object->common.type) { 143 case ACPI_TYPE_STRING: 144 145 external_object->string.pointer = (char *)data_space; 146 external_object->string.length = internal_object->string.length; 147 *buffer_space_used = ACPI_ROUND_UP_TO_NATIVE_WORD((acpi_size) 148 internal_object-> 149 string. 150 length + 1); 151 152 memcpy((void *)data_space, 153 (void *)internal_object->string.pointer, 154 (acpi_size) internal_object->string.length + 1); 155 break; 156 157 case ACPI_TYPE_BUFFER: 158 159 external_object->buffer.pointer = data_space; 160 external_object->buffer.length = internal_object->buffer.length; 161 *buffer_space_used = 162 ACPI_ROUND_UP_TO_NATIVE_WORD(internal_object->string. 163 length); 164 165 memcpy((void *)data_space, 166 (void *)internal_object->buffer.pointer, 167 internal_object->buffer.length); 168 break; 169 170 case ACPI_TYPE_INTEGER: 171 172 external_object->integer.value = internal_object->integer.value; 173 break; 174 175 case ACPI_TYPE_LOCAL_REFERENCE: 176 177 /* This is an object reference. */ 178 179 switch (internal_object->reference.class) { 180 case ACPI_REFCLASS_NAME: 181 /* 182 * For namepath, return the object handle ("reference") 183 * We are referring to the namespace node 184 */ 185 external_object->reference.handle = 186 internal_object->reference.node; 187 external_object->reference.actual_type = 188 acpi_ns_get_type(internal_object->reference.node); 189 break; 190 191 default: 192 193 /* All other reference types are unsupported */ 194 195 return_ACPI_STATUS(AE_TYPE); 196 } 197 break; 198 199 case ACPI_TYPE_PROCESSOR: 200 201 external_object->processor.proc_id = 202 internal_object->processor.proc_id; 203 external_object->processor.pblk_address = 204 internal_object->processor.address; 205 external_object->processor.pblk_length = 206 internal_object->processor.length; 207 break; 208 209 case ACPI_TYPE_POWER: 210 211 external_object->power_resource.system_level = 212 internal_object->power_resource.system_level; 213 214 external_object->power_resource.resource_order = 215 internal_object->power_resource.resource_order; 216 break; 217 218 default: 219 /* 220 * There is no corresponding external object type 221 */ 222 ACPI_ERROR((AE_INFO, 223 "Unsupported object type, cannot convert to external object: %s", 224 acpi_ut_get_type_name(internal_object->common. 225 type))); 226 227 return_ACPI_STATUS(AE_SUPPORT); 228 } 229 230 return_ACPI_STATUS(status); 231 } 232 233 /******************************************************************************* 234 * 235 * FUNCTION: acpi_ut_copy_ielement_to_eelement 236 * 237 * PARAMETERS: acpi_pkg_callback 238 * 239 * RETURN: Status 240 * 241 * DESCRIPTION: Copy one package element to another package element 242 * 243 ******************************************************************************/ 244 245 static acpi_status 246 acpi_ut_copy_ielement_to_eelement(u8 object_type, 247 union acpi_operand_object *source_object, 248 union acpi_generic_state *state, 249 void *context) 250 { 251 acpi_status status = AE_OK; 252 struct acpi_pkg_info *info = (struct acpi_pkg_info *)context; 253 acpi_size object_space; 254 u32 this_index; 255 union acpi_object *target_object; 256 257 ACPI_FUNCTION_ENTRY(); 258 259 this_index = state->pkg.index; 260 target_object = (union acpi_object *) 261 &((union acpi_object *)(state->pkg.dest_object))->package. 262 elements[this_index]; 263 264 switch (object_type) { 265 case ACPI_COPY_TYPE_SIMPLE: 266 /* 267 * This is a simple or null object 268 */ 269 status = acpi_ut_copy_isimple_to_esimple(source_object, 270 target_object, 271 info->free_space, 272 &object_space); 273 if (ACPI_FAILURE(status)) { 274 return (status); 275 } 276 break; 277 278 case ACPI_COPY_TYPE_PACKAGE: 279 /* 280 * Build the package object 281 */ 282 target_object->type = ACPI_TYPE_PACKAGE; 283 target_object->package.count = source_object->package.count; 284 target_object->package.elements = 285 ACPI_CAST_PTR(union acpi_object, info->free_space); 286 287 /* 288 * Pass the new package object back to the package walk routine 289 */ 290 state->pkg.this_target_obj = target_object; 291 292 /* 293 * Save space for the array of objects (Package elements) 294 * update the buffer length counter 295 */ 296 object_space = ACPI_ROUND_UP_TO_NATIVE_WORD((acpi_size) 297 target_object-> 298 package.count * 299 sizeof(union 300 acpi_object)); 301 break; 302 303 default: 304 305 return (AE_BAD_PARAMETER); 306 } 307 308 info->free_space += object_space; 309 info->length += object_space; 310 return (status); 311 } 312 313 /******************************************************************************* 314 * 315 * FUNCTION: acpi_ut_copy_ipackage_to_epackage 316 * 317 * PARAMETERS: internal_object - Pointer to the object we are returning 318 * buffer - Where the object is returned 319 * space_used - Where the object length is returned 320 * 321 * RETURN: Status 322 * 323 * DESCRIPTION: This function is called to place a package object in a user 324 * buffer. A package object by definition contains other objects. 325 * 326 * The buffer is assumed to have sufficient space for the object. 327 * The caller must have verified the buffer length needed using 328 * the acpi_ut_get_object_size function before calling this function. 329 * 330 ******************************************************************************/ 331 332 static acpi_status 333 acpi_ut_copy_ipackage_to_epackage(union acpi_operand_object *internal_object, 334 u8 * buffer, acpi_size * space_used) 335 { 336 union acpi_object *external_object; 337 acpi_status status; 338 struct acpi_pkg_info info; 339 340 ACPI_FUNCTION_TRACE(ut_copy_ipackage_to_epackage); 341 342 /* 343 * First package at head of the buffer 344 */ 345 external_object = ACPI_CAST_PTR(union acpi_object, buffer); 346 347 /* 348 * Free space begins right after the first package 349 */ 350 info.length = ACPI_ROUND_UP_TO_NATIVE_WORD(sizeof(union acpi_object)); 351 info.free_space = 352 buffer + ACPI_ROUND_UP_TO_NATIVE_WORD(sizeof(union acpi_object)); 353 info.object_space = 0; 354 info.num_packages = 1; 355 356 external_object->type = internal_object->common.type; 357 external_object->package.count = internal_object->package.count; 358 external_object->package.elements = ACPI_CAST_PTR(union acpi_object, 359 info.free_space); 360 361 /* 362 * Leave room for an array of ACPI_OBJECTS in the buffer 363 * and move the free space past it 364 */ 365 info.length += (acpi_size) external_object->package.count * 366 ACPI_ROUND_UP_TO_NATIVE_WORD(sizeof(union acpi_object)); 367 info.free_space += external_object->package.count * 368 ACPI_ROUND_UP_TO_NATIVE_WORD(sizeof(union acpi_object)); 369 370 status = acpi_ut_walk_package_tree(internal_object, external_object, 371 acpi_ut_copy_ielement_to_eelement, 372 &info); 373 374 *space_used = info.length; 375 return_ACPI_STATUS(status); 376 } 377 378 /******************************************************************************* 379 * 380 * FUNCTION: acpi_ut_copy_iobject_to_eobject 381 * 382 * PARAMETERS: internal_object - The internal object to be converted 383 * ret_buffer - Where the object is returned 384 * 385 * RETURN: Status 386 * 387 * DESCRIPTION: This function is called to build an API object to be returned 388 * to the caller. 389 * 390 ******************************************************************************/ 391 392 acpi_status 393 acpi_ut_copy_iobject_to_eobject(union acpi_operand_object *internal_object, 394 struct acpi_buffer *ret_buffer) 395 { 396 acpi_status status; 397 398 ACPI_FUNCTION_TRACE(ut_copy_iobject_to_eobject); 399 400 if (internal_object->common.type == ACPI_TYPE_PACKAGE) { 401 /* 402 * Package object: Copy all subobjects (including 403 * nested packages) 404 */ 405 status = acpi_ut_copy_ipackage_to_epackage(internal_object, 406 ret_buffer->pointer, 407 &ret_buffer->length); 408 } else { 409 /* 410 * Build a simple object (no nested objects) 411 */ 412 status = acpi_ut_copy_isimple_to_esimple(internal_object, 413 ACPI_CAST_PTR(union 414 acpi_object, 415 ret_buffer-> 416 pointer), 417 ACPI_ADD_PTR(u8, 418 ret_buffer-> 419 pointer, 420 ACPI_ROUND_UP_TO_NATIVE_WORD 421 (sizeof 422 (union 423 acpi_object))), 424 &ret_buffer->length); 425 /* 426 * build simple does not include the object size in the length 427 * so we add it in here 428 */ 429 ret_buffer->length += sizeof(union acpi_object); 430 } 431 432 return_ACPI_STATUS(status); 433 } 434 435 /******************************************************************************* 436 * 437 * FUNCTION: acpi_ut_copy_esimple_to_isimple 438 * 439 * PARAMETERS: external_object - The external object to be converted 440 * ret_internal_object - Where the internal object is returned 441 * 442 * RETURN: Status 443 * 444 * DESCRIPTION: This function copies an external object to an internal one. 445 * NOTE: Pointers can be copied, we don't need to copy data. 446 * (The pointers have to be valid in our address space no matter 447 * what we do with them!) 448 * 449 ******************************************************************************/ 450 451 static acpi_status 452 acpi_ut_copy_esimple_to_isimple(union acpi_object *external_object, 453 union acpi_operand_object **ret_internal_object) 454 { 455 union acpi_operand_object *internal_object; 456 457 ACPI_FUNCTION_TRACE(ut_copy_esimple_to_isimple); 458 459 /* 460 * Simple types supported are: String, Buffer, Integer 461 */ 462 switch (external_object->type) { 463 case ACPI_TYPE_STRING: 464 case ACPI_TYPE_BUFFER: 465 case ACPI_TYPE_INTEGER: 466 case ACPI_TYPE_LOCAL_REFERENCE: 467 468 internal_object = acpi_ut_create_internal_object((u8) 469 external_object-> 470 type); 471 if (!internal_object) { 472 return_ACPI_STATUS(AE_NO_MEMORY); 473 } 474 break; 475 476 case ACPI_TYPE_ANY: /* This is the case for a NULL object */ 477 478 *ret_internal_object = NULL; 479 return_ACPI_STATUS(AE_OK); 480 481 default: 482 483 /* All other types are not supported */ 484 485 ACPI_ERROR((AE_INFO, 486 "Unsupported object type, cannot convert to internal object: %s", 487 acpi_ut_get_type_name(external_object->type))); 488 489 return_ACPI_STATUS(AE_SUPPORT); 490 } 491 492 /* Must COPY string and buffer contents */ 493 494 switch (external_object->type) { 495 case ACPI_TYPE_STRING: 496 497 internal_object->string.pointer = 498 ACPI_ALLOCATE_ZEROED((acpi_size) 499 external_object->string.length + 1); 500 501 if (!internal_object->string.pointer) { 502 goto error_exit; 503 } 504 505 memcpy(internal_object->string.pointer, 506 external_object->string.pointer, 507 external_object->string.length); 508 509 internal_object->string.length = external_object->string.length; 510 break; 511 512 case ACPI_TYPE_BUFFER: 513 514 internal_object->buffer.pointer = 515 ACPI_ALLOCATE_ZEROED(external_object->buffer.length); 516 if (!internal_object->buffer.pointer) { 517 goto error_exit; 518 } 519 520 memcpy(internal_object->buffer.pointer, 521 external_object->buffer.pointer, 522 external_object->buffer.length); 523 524 internal_object->buffer.length = external_object->buffer.length; 525 526 /* Mark buffer data valid */ 527 528 internal_object->buffer.flags |= AOPOBJ_DATA_VALID; 529 break; 530 531 case ACPI_TYPE_INTEGER: 532 533 internal_object->integer.value = external_object->integer.value; 534 break; 535 536 case ACPI_TYPE_LOCAL_REFERENCE: 537 538 /* An incoming reference is defined to be a namespace node */ 539 540 internal_object->reference.class = ACPI_REFCLASS_REFOF; 541 internal_object->reference.object = 542 external_object->reference.handle; 543 break; 544 545 default: 546 547 /* Other types can't get here */ 548 549 break; 550 } 551 552 *ret_internal_object = internal_object; 553 return_ACPI_STATUS(AE_OK); 554 555 error_exit: 556 acpi_ut_remove_reference(internal_object); 557 return_ACPI_STATUS(AE_NO_MEMORY); 558 } 559 560 /******************************************************************************* 561 * 562 * FUNCTION: acpi_ut_copy_epackage_to_ipackage 563 * 564 * PARAMETERS: external_object - The external object to be converted 565 * internal_object - Where the internal object is returned 566 * 567 * RETURN: Status 568 * 569 * DESCRIPTION: Copy an external package object to an internal package. 570 * Handles nested packages. 571 * 572 ******************************************************************************/ 573 574 static acpi_status 575 acpi_ut_copy_epackage_to_ipackage(union acpi_object *external_object, 576 union acpi_operand_object **internal_object) 577 { 578 acpi_status status = AE_OK; 579 union acpi_operand_object *package_object; 580 union acpi_operand_object **package_elements; 581 u32 i; 582 583 ACPI_FUNCTION_TRACE(ut_copy_epackage_to_ipackage); 584 585 /* Create the package object */ 586 587 package_object = 588 acpi_ut_create_package_object(external_object->package.count); 589 if (!package_object) { 590 return_ACPI_STATUS(AE_NO_MEMORY); 591 } 592 593 package_elements = package_object->package.elements; 594 595 /* 596 * Recursive implementation. Probably ok, since nested external packages 597 * as parameters should be very rare. 598 */ 599 for (i = 0; i < external_object->package.count; i++) { 600 status = 601 acpi_ut_copy_eobject_to_iobject(&external_object->package. 602 elements[i], 603 &package_elements[i]); 604 if (ACPI_FAILURE(status)) { 605 606 /* Truncate package and delete it */ 607 608 package_object->package.count = i; 609 package_elements[i] = NULL; 610 acpi_ut_remove_reference(package_object); 611 return_ACPI_STATUS(status); 612 } 613 } 614 615 /* Mark package data valid */ 616 617 package_object->package.flags |= AOPOBJ_DATA_VALID; 618 619 *internal_object = package_object; 620 return_ACPI_STATUS(status); 621 } 622 623 /******************************************************************************* 624 * 625 * FUNCTION: acpi_ut_copy_eobject_to_iobject 626 * 627 * PARAMETERS: external_object - The external object to be converted 628 * internal_object - Where the internal object is returned 629 * 630 * RETURN: Status 631 * 632 * DESCRIPTION: Converts an external object to an internal object. 633 * 634 ******************************************************************************/ 635 636 acpi_status 637 acpi_ut_copy_eobject_to_iobject(union acpi_object *external_object, 638 union acpi_operand_object **internal_object) 639 { 640 acpi_status status; 641 642 ACPI_FUNCTION_TRACE(ut_copy_eobject_to_iobject); 643 644 if (external_object->type == ACPI_TYPE_PACKAGE) { 645 status = 646 acpi_ut_copy_epackage_to_ipackage(external_object, 647 internal_object); 648 } else { 649 /* 650 * Build a simple object (no nested objects) 651 */ 652 status = 653 acpi_ut_copy_esimple_to_isimple(external_object, 654 internal_object); 655 } 656 657 return_ACPI_STATUS(status); 658 } 659 660 /******************************************************************************* 661 * 662 * FUNCTION: acpi_ut_copy_simple_object 663 * 664 * PARAMETERS: source_desc - The internal object to be copied 665 * dest_desc - New target object 666 * 667 * RETURN: Status 668 * 669 * DESCRIPTION: Simple copy of one internal object to another. Reference count 670 * of the destination object is preserved. 671 * 672 ******************************************************************************/ 673 674 static acpi_status 675 acpi_ut_copy_simple_object(union acpi_operand_object *source_desc, 676 union acpi_operand_object *dest_desc) 677 { 678 u16 reference_count; 679 union acpi_operand_object *next_object; 680 acpi_status status; 681 acpi_size copy_size; 682 683 /* Save fields from destination that we don't want to overwrite */ 684 685 reference_count = dest_desc->common.reference_count; 686 next_object = dest_desc->common.next_object; 687 688 /* 689 * Copy the entire source object over the destination object. 690 * Note: Source can be either an operand object or namespace node. 691 */ 692 copy_size = sizeof(union acpi_operand_object); 693 if (ACPI_GET_DESCRIPTOR_TYPE(source_desc) == ACPI_DESC_TYPE_NAMED) { 694 copy_size = sizeof(struct acpi_namespace_node); 695 } 696 697 memcpy(ACPI_CAST_PTR(char, dest_desc), 698 ACPI_CAST_PTR(char, source_desc), copy_size); 699 700 /* Restore the saved fields */ 701 702 dest_desc->common.reference_count = reference_count; 703 dest_desc->common.next_object = next_object; 704 705 /* New object is not static, regardless of source */ 706 707 dest_desc->common.flags &= ~AOPOBJ_STATIC_POINTER; 708 709 /* Handle the objects with extra data */ 710 711 switch (dest_desc->common.type) { 712 case ACPI_TYPE_BUFFER: 713 /* 714 * Allocate and copy the actual buffer if and only if: 715 * 1) There is a valid buffer pointer 716 * 2) The buffer has a length > 0 717 */ 718 if ((source_desc->buffer.pointer) && 719 (source_desc->buffer.length)) { 720 dest_desc->buffer.pointer = 721 ACPI_ALLOCATE(source_desc->buffer.length); 722 if (!dest_desc->buffer.pointer) { 723 return (AE_NO_MEMORY); 724 } 725 726 /* Copy the actual buffer data */ 727 728 memcpy(dest_desc->buffer.pointer, 729 source_desc->buffer.pointer, 730 source_desc->buffer.length); 731 } 732 break; 733 734 case ACPI_TYPE_STRING: 735 /* 736 * Allocate and copy the actual string if and only if: 737 * 1) There is a valid string pointer 738 * (Pointer to a NULL string is allowed) 739 */ 740 if (source_desc->string.pointer) { 741 dest_desc->string.pointer = 742 ACPI_ALLOCATE((acpi_size) source_desc->string. 743 length + 1); 744 if (!dest_desc->string.pointer) { 745 return (AE_NO_MEMORY); 746 } 747 748 /* Copy the actual string data */ 749 750 memcpy(dest_desc->string.pointer, 751 source_desc->string.pointer, 752 (acpi_size) source_desc->string.length + 1); 753 } 754 break; 755 756 case ACPI_TYPE_LOCAL_REFERENCE: 757 /* 758 * We copied the reference object, so we now must add a reference 759 * to the object pointed to by the reference 760 * 761 * DDBHandle reference (from Load/load_table) is a special reference, 762 * it does not have a Reference.Object, so does not need to 763 * increase the reference count 764 */ 765 if (source_desc->reference.class == ACPI_REFCLASS_TABLE) { 766 break; 767 } 768 769 acpi_ut_add_reference(source_desc->reference.object); 770 break; 771 772 case ACPI_TYPE_REGION: 773 /* 774 * We copied the Region Handler, so we now must add a reference 775 */ 776 if (dest_desc->region.handler) { 777 acpi_ut_add_reference(dest_desc->region.handler); 778 } 779 break; 780 781 /* 782 * For Mutex and Event objects, we cannot simply copy the underlying 783 * OS object. We must create a new one. 784 */ 785 case ACPI_TYPE_MUTEX: 786 787 status = acpi_os_create_mutex(&dest_desc->mutex.os_mutex); 788 if (ACPI_FAILURE(status)) { 789 return (status); 790 } 791 break; 792 793 case ACPI_TYPE_EVENT: 794 795 status = acpi_os_create_semaphore(ACPI_NO_UNIT_LIMIT, 0, 796 &dest_desc->event. 797 os_semaphore); 798 if (ACPI_FAILURE(status)) { 799 return (status); 800 } 801 break; 802 803 default: 804 805 /* Nothing to do for other simple objects */ 806 807 break; 808 } 809 810 return (AE_OK); 811 } 812 813 /******************************************************************************* 814 * 815 * FUNCTION: acpi_ut_copy_ielement_to_ielement 816 * 817 * PARAMETERS: acpi_pkg_callback 818 * 819 * RETURN: Status 820 * 821 * DESCRIPTION: Copy one package element to another package element 822 * 823 ******************************************************************************/ 824 825 static acpi_status 826 acpi_ut_copy_ielement_to_ielement(u8 object_type, 827 union acpi_operand_object *source_object, 828 union acpi_generic_state *state, 829 void *context) 830 { 831 acpi_status status = AE_OK; 832 u32 this_index; 833 union acpi_operand_object **this_target_ptr; 834 union acpi_operand_object *target_object; 835 836 ACPI_FUNCTION_ENTRY(); 837 838 this_index = state->pkg.index; 839 this_target_ptr = (union acpi_operand_object **) 840 &state->pkg.dest_object->package.elements[this_index]; 841 842 switch (object_type) { 843 case ACPI_COPY_TYPE_SIMPLE: 844 845 /* A null source object indicates a (legal) null package element */ 846 847 if (source_object) { 848 /* 849 * This is a simple object, just copy it 850 */ 851 target_object = 852 acpi_ut_create_internal_object(source_object-> 853 common.type); 854 if (!target_object) { 855 return (AE_NO_MEMORY); 856 } 857 858 status = 859 acpi_ut_copy_simple_object(source_object, 860 target_object); 861 if (ACPI_FAILURE(status)) { 862 goto error_exit; 863 } 864 865 *this_target_ptr = target_object; 866 } else { 867 /* Pass through a null element */ 868 869 *this_target_ptr = NULL; 870 } 871 break; 872 873 case ACPI_COPY_TYPE_PACKAGE: 874 /* 875 * This object is a package - go down another nesting level 876 * Create and build the package object 877 */ 878 target_object = 879 acpi_ut_create_package_object(source_object->package.count); 880 if (!target_object) { 881 return (AE_NO_MEMORY); 882 } 883 884 target_object->common.flags = source_object->common.flags; 885 886 /* Pass the new package object back to the package walk routine */ 887 888 state->pkg.this_target_obj = target_object; 889 890 /* Store the object pointer in the parent package object */ 891 892 *this_target_ptr = target_object; 893 break; 894 895 default: 896 897 return (AE_BAD_PARAMETER); 898 } 899 900 return (status); 901 902 error_exit: 903 acpi_ut_remove_reference(target_object); 904 return (status); 905 } 906 907 /******************************************************************************* 908 * 909 * FUNCTION: acpi_ut_copy_ipackage_to_ipackage 910 * 911 * PARAMETERS: source_obj - Pointer to the source package object 912 * dest_obj - Where the internal object is returned 913 * walk_state - Current Walk state descriptor 914 * 915 * RETURN: Status 916 * 917 * DESCRIPTION: This function is called to copy an internal package object 918 * into another internal package object. 919 * 920 ******************************************************************************/ 921 922 static acpi_status 923 acpi_ut_copy_ipackage_to_ipackage(union acpi_operand_object *source_obj, 924 union acpi_operand_object *dest_obj, 925 struct acpi_walk_state *walk_state) 926 { 927 acpi_status status = AE_OK; 928 929 ACPI_FUNCTION_TRACE(ut_copy_ipackage_to_ipackage); 930 931 dest_obj->common.type = source_obj->common.type; 932 dest_obj->common.flags = source_obj->common.flags; 933 dest_obj->package.count = source_obj->package.count; 934 935 /* 936 * Create the object array and walk the source package tree 937 */ 938 dest_obj->package.elements = ACPI_ALLOCATE_ZEROED(((acpi_size) 939 source_obj->package. 940 count + 941 1) * sizeof(void *)); 942 if (!dest_obj->package.elements) { 943 ACPI_ERROR((AE_INFO, "Package allocation failure")); 944 return_ACPI_STATUS(AE_NO_MEMORY); 945 } 946 947 /* 948 * Copy the package element-by-element by walking the package "tree". 949 * This handles nested packages of arbitrary depth. 950 */ 951 status = acpi_ut_walk_package_tree(source_obj, dest_obj, 952 acpi_ut_copy_ielement_to_ielement, 953 walk_state); 954 if (ACPI_FAILURE(status)) { 955 956 /* On failure, delete the destination package object */ 957 958 acpi_ut_remove_reference(dest_obj); 959 } 960 961 return_ACPI_STATUS(status); 962 } 963 964 /******************************************************************************* 965 * 966 * FUNCTION: acpi_ut_copy_iobject_to_iobject 967 * 968 * PARAMETERS: source_desc - The internal object to be copied 969 * dest_desc - Where the copied object is returned 970 * walk_state - Current walk state 971 * 972 * RETURN: Status 973 * 974 * DESCRIPTION: Copy an internal object to a new internal object 975 * 976 ******************************************************************************/ 977 978 acpi_status 979 acpi_ut_copy_iobject_to_iobject(union acpi_operand_object *source_desc, 980 union acpi_operand_object **dest_desc, 981 struct acpi_walk_state *walk_state) 982 { 983 acpi_status status = AE_OK; 984 985 ACPI_FUNCTION_TRACE(ut_copy_iobject_to_iobject); 986 987 /* Create the top level object */ 988 989 *dest_desc = acpi_ut_create_internal_object(source_desc->common.type); 990 if (!*dest_desc) { 991 return_ACPI_STATUS(AE_NO_MEMORY); 992 } 993 994 /* Copy the object and possible subobjects */ 995 996 if (source_desc->common.type == ACPI_TYPE_PACKAGE) { 997 status = 998 acpi_ut_copy_ipackage_to_ipackage(source_desc, *dest_desc, 999 walk_state); 1000 } else { 1001 status = acpi_ut_copy_simple_object(source_desc, *dest_desc); 1002 } 1003 1004 /* Delete the allocated object if copy failed */ 1005 1006 if (ACPI_FAILURE(status)) { 1007 acpi_ut_remove_reference(*dest_desc); 1008 } 1009 1010 return_ACPI_STATUS(status); 1011 } 1012