OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [acpi/] [utilities/] [utcopy.c] - Blame information for rev 62

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.