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