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