Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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