1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44#include <acpi/acpi.h>
45#include "accommon.h"
46#include "acnamesp.h"
47
48
49#define _COMPONENT ACPI_UTILITIES
50ACPI_MODULE_NAME("utcopy")
51
52
53static acpi_status
54acpi_ut_copy_isimple_to_esimple(union acpi_operand_object *internal_object,
55 union acpi_object *external_object,
56 u8 * data_space, acpi_size * buffer_space_used);
57
58static acpi_status
59acpi_ut_copy_ielement_to_ielement(u8 object_type,
60 union acpi_operand_object *source_object,
61 union acpi_generic_state *state,
62 void *context);
63
64static acpi_status
65acpi_ut_copy_ipackage_to_epackage(union acpi_operand_object *internal_object,
66 u8 * buffer, acpi_size * space_used);
67
68static acpi_status
69acpi_ut_copy_esimple_to_isimple(union acpi_object *user_obj,
70 union acpi_operand_object **return_obj);
71
72static acpi_status
73acpi_ut_copy_epackage_to_ipackage(union acpi_object *external_object,
74 union acpi_operand_object **internal_object);
75
76static acpi_status
77acpi_ut_copy_simple_object(union acpi_operand_object *source_desc,
78 union acpi_operand_object *dest_desc);
79
80static acpi_status
81acpi_ut_copy_ielement_to_eelement(u8 object_type,
82 union acpi_operand_object *source_object,
83 union acpi_generic_state *state,
84 void *context);
85
86static acpi_status
87acpi_ut_copy_ipackage_to_ipackage(union acpi_operand_object *source_obj,
88 union acpi_operand_object *dest_obj,
89 struct acpi_walk_state *walk_state);
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111static acpi_status
112acpi_ut_copy_isimple_to_esimple(union acpi_operand_object *internal_object,
113 union acpi_object *external_object,
114 u8 * data_space, acpi_size * buffer_space_used)
115{
116 acpi_status status = AE_OK;
117
118 ACPI_FUNCTION_TRACE(ut_copy_isimple_to_esimple);
119
120 *buffer_space_used = 0;
121
122
123
124
125
126 if (!internal_object) {
127 return_ACPI_STATUS(AE_OK);
128 }
129
130
131
132 memset(external_object, 0, sizeof(union acpi_object));
133
134
135
136
137
138 external_object->type = internal_object->common.type;
139
140
141
142 switch (internal_object->common.type) {
143 case ACPI_TYPE_STRING:
144
145 external_object->string.pointer = (char *)data_space;
146 external_object->string.length = internal_object->string.length;
147 *buffer_space_used = ACPI_ROUND_UP_TO_NATIVE_WORD((acpi_size)
148 internal_object->
149 string.
150 length + 1);
151
152 memcpy((void *)data_space,
153 (void *)internal_object->string.pointer,
154 (acpi_size) internal_object->string.length + 1);
155 break;
156
157 case ACPI_TYPE_BUFFER:
158
159 external_object->buffer.pointer = data_space;
160 external_object->buffer.length = internal_object->buffer.length;
161 *buffer_space_used =
162 ACPI_ROUND_UP_TO_NATIVE_WORD(internal_object->string.
163 length);
164
165 memcpy((void *)data_space,
166 (void *)internal_object->buffer.pointer,
167 internal_object->buffer.length);
168 break;
169
170 case ACPI_TYPE_INTEGER:
171
172 external_object->integer.value = internal_object->integer.value;
173 break;
174
175 case ACPI_TYPE_LOCAL_REFERENCE:
176
177
178
179 switch (internal_object->reference.class) {
180 case ACPI_REFCLASS_NAME:
181
182
183
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
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
221
222 ACPI_ERROR((AE_INFO,
223 "Unsupported object type, cannot convert to external object: %s",
224 acpi_ut_get_type_name(internal_object->common.
225 type)));
226
227 return_ACPI_STATUS(AE_SUPPORT);
228 }
229
230 return_ACPI_STATUS(status);
231}
232
233
234
235
236
237
238
239
240
241
242
243
244
245static acpi_status
246acpi_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
269 status = acpi_ut_copy_isimple_to_esimple(source_object,
270 target_object,
271 info->free_space,
272 &object_space);
273 if (ACPI_FAILURE(status)) {
274 return (status);
275 }
276 break;
277
278 case ACPI_COPY_TYPE_PACKAGE:
279
280
281
282 target_object->type = ACPI_TYPE_PACKAGE;
283 target_object->package.count = source_object->package.count;
284 target_object->package.elements =
285 ACPI_CAST_PTR(union acpi_object, info->free_space);
286
287
288
289
290 state->pkg.this_target_obj = target_object;
291
292
293
294
295
296 object_space = ACPI_ROUND_UP_TO_NATIVE_WORD((acpi_size)
297 target_object->
298 package.count *
299 sizeof(union
300 acpi_object));
301 break;
302
303 default:
304
305 return (AE_BAD_PARAMETER);
306 }
307
308 info->free_space += object_space;
309 info->length += object_space;
310 return (status);
311}
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332static acpi_status
333acpi_ut_copy_ipackage_to_epackage(union acpi_operand_object *internal_object,
334 u8 * buffer, acpi_size * space_used)
335{
336 union acpi_object *external_object;
337 acpi_status status;
338 struct acpi_pkg_info info;
339
340 ACPI_FUNCTION_TRACE(ut_copy_ipackage_to_epackage);
341
342
343
344
345 external_object = ACPI_CAST_PTR(union acpi_object, buffer);
346
347
348
349
350 info.length = ACPI_ROUND_UP_TO_NATIVE_WORD(sizeof(union acpi_object));
351 info.free_space =
352 buffer + ACPI_ROUND_UP_TO_NATIVE_WORD(sizeof(union acpi_object));
353 info.object_space = 0;
354 info.num_packages = 1;
355
356 external_object->type = internal_object->common.type;
357 external_object->package.count = internal_object->package.count;
358 external_object->package.elements = ACPI_CAST_PTR(union acpi_object,
359 info.free_space);
360
361
362
363
364
365 info.length += (acpi_size) external_object->package.count *
366 ACPI_ROUND_UP_TO_NATIVE_WORD(sizeof(union acpi_object));
367 info.free_space += external_object->package.count *
368 ACPI_ROUND_UP_TO_NATIVE_WORD(sizeof(union acpi_object));
369
370 status = acpi_ut_walk_package_tree(internal_object, external_object,
371 acpi_ut_copy_ielement_to_eelement,
372 &info);
373
374 *space_used = info.length;
375 return_ACPI_STATUS(status);
376}
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392acpi_status
393acpi_ut_copy_iobject_to_eobject(union acpi_operand_object *internal_object,
394 struct acpi_buffer *ret_buffer)
395{
396 acpi_status status;
397
398 ACPI_FUNCTION_TRACE(ut_copy_iobject_to_eobject);
399
400 if (internal_object->common.type == ACPI_TYPE_PACKAGE) {
401
402
403
404
405 status = acpi_ut_copy_ipackage_to_epackage(internal_object,
406 ret_buffer->pointer,
407 &ret_buffer->length);
408 } else {
409
410
411
412 status = acpi_ut_copy_isimple_to_esimple(internal_object,
413 ACPI_CAST_PTR(union
414 acpi_object,
415 ret_buffer->
416 pointer),
417 ACPI_ADD_PTR(u8,
418 ret_buffer->
419 pointer,
420 ACPI_ROUND_UP_TO_NATIVE_WORD
421 (sizeof
422 (union
423 acpi_object))),
424 &ret_buffer->length);
425
426
427
428
429 ret_buffer->length += sizeof(union acpi_object);
430 }
431
432 return_ACPI_STATUS(status);
433}
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451static acpi_status
452acpi_ut_copy_esimple_to_isimple(union acpi_object *external_object,
453 union acpi_operand_object **ret_internal_object)
454{
455 union acpi_operand_object *internal_object;
456
457 ACPI_FUNCTION_TRACE(ut_copy_esimple_to_isimple);
458
459
460
461
462 switch (external_object->type) {
463 case ACPI_TYPE_STRING:
464 case ACPI_TYPE_BUFFER:
465 case ACPI_TYPE_INTEGER:
466 case ACPI_TYPE_LOCAL_REFERENCE:
467
468 internal_object = acpi_ut_create_internal_object((u8)
469 external_object->
470 type);
471 if (!internal_object) {
472 return_ACPI_STATUS(AE_NO_MEMORY);
473 }
474 break;
475
476 case ACPI_TYPE_ANY:
477
478 *ret_internal_object = NULL;
479 return_ACPI_STATUS(AE_OK);
480
481 default:
482
483
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
493
494 switch (external_object->type) {
495 case ACPI_TYPE_STRING:
496
497 internal_object->string.pointer =
498 ACPI_ALLOCATE_ZEROED((acpi_size)
499 external_object->string.length + 1);
500
501 if (!internal_object->string.pointer) {
502 goto error_exit;
503 }
504
505 memcpy(internal_object->string.pointer,
506 external_object->string.pointer,
507 external_object->string.length);
508
509 internal_object->string.length = external_object->string.length;
510 break;
511
512 case ACPI_TYPE_BUFFER:
513
514 internal_object->buffer.pointer =
515 ACPI_ALLOCATE_ZEROED(external_object->buffer.length);
516 if (!internal_object->buffer.pointer) {
517 goto error_exit;
518 }
519
520 memcpy(internal_object->buffer.pointer,
521 external_object->buffer.pointer,
522 external_object->buffer.length);
523
524 internal_object->buffer.length = external_object->buffer.length;
525
526
527
528 internal_object->buffer.flags |= AOPOBJ_DATA_VALID;
529 break;
530
531 case ACPI_TYPE_INTEGER:
532
533 internal_object->integer.value = external_object->integer.value;
534 break;
535
536 case ACPI_TYPE_LOCAL_REFERENCE:
537
538
539
540 internal_object->reference.class = ACPI_REFCLASS_NAME;
541 internal_object->reference.node =
542 external_object->reference.handle;
543 break;
544
545 default:
546
547
548
549 break;
550 }
551
552 *ret_internal_object = internal_object;
553 return_ACPI_STATUS(AE_OK);
554
555 error_exit:
556 acpi_ut_remove_reference(internal_object);
557 return_ACPI_STATUS(AE_NO_MEMORY);
558}
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574static acpi_status
575acpi_ut_copy_epackage_to_ipackage(union acpi_object *external_object,
576 union acpi_operand_object **internal_object)
577{
578 acpi_status status = AE_OK;
579 union acpi_operand_object *package_object;
580 union acpi_operand_object **package_elements;
581 u32 i;
582
583 ACPI_FUNCTION_TRACE(ut_copy_epackage_to_ipackage);
584
585
586
587 package_object =
588 acpi_ut_create_package_object(external_object->package.count);
589 if (!package_object) {
590 return_ACPI_STATUS(AE_NO_MEMORY);
591 }
592
593 package_elements = package_object->package.elements;
594
595
596
597
598
599 for (i = 0; i < external_object->package.count; i++) {
600 status =
601 acpi_ut_copy_eobject_to_iobject(&external_object->package.
602 elements[i],
603 &package_elements[i]);
604 if (ACPI_FAILURE(status)) {
605
606
607
608 package_object->package.count = i;
609 package_elements[i] = NULL;
610 acpi_ut_remove_reference(package_object);
611 return_ACPI_STATUS(status);
612 }
613 }
614
615
616
617 package_object->package.flags |= AOPOBJ_DATA_VALID;
618
619 *internal_object = package_object;
620 return_ACPI_STATUS(status);
621}
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636acpi_status
637acpi_ut_copy_eobject_to_iobject(union acpi_object *external_object,
638 union acpi_operand_object **internal_object)
639{
640 acpi_status status;
641
642 ACPI_FUNCTION_TRACE(ut_copy_eobject_to_iobject);
643
644 if (external_object->type == ACPI_TYPE_PACKAGE) {
645 status =
646 acpi_ut_copy_epackage_to_ipackage(external_object,
647 internal_object);
648 } else {
649
650
651
652 status =
653 acpi_ut_copy_esimple_to_isimple(external_object,
654 internal_object);
655 }
656
657 return_ACPI_STATUS(status);
658}
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674static acpi_status
675acpi_ut_copy_simple_object(union acpi_operand_object *source_desc,
676 union acpi_operand_object *dest_desc)
677{
678 u16 reference_count;
679 union acpi_operand_object *next_object;
680 acpi_status status;
681 acpi_size copy_size;
682
683
684
685 reference_count = dest_desc->common.reference_count;
686 next_object = dest_desc->common.next_object;
687
688
689
690
691
692 copy_size = sizeof(union acpi_operand_object);
693 if (ACPI_GET_DESCRIPTOR_TYPE(source_desc) == ACPI_DESC_TYPE_NAMED) {
694 copy_size = sizeof(struct acpi_namespace_node);
695 }
696
697 memcpy(ACPI_CAST_PTR(char, dest_desc),
698 ACPI_CAST_PTR(char, source_desc), copy_size);
699
700
701
702 dest_desc->common.reference_count = reference_count;
703 dest_desc->common.next_object = next_object;
704
705
706
707 dest_desc->common.flags &= ~AOPOBJ_STATIC_POINTER;
708
709
710
711 switch (dest_desc->common.type) {
712 case ACPI_TYPE_BUFFER:
713
714
715
716
717
718 if ((source_desc->buffer.pointer) &&
719 (source_desc->buffer.length)) {
720 dest_desc->buffer.pointer =
721 ACPI_ALLOCATE(source_desc->buffer.length);
722 if (!dest_desc->buffer.pointer) {
723 return (AE_NO_MEMORY);
724 }
725
726
727
728 memcpy(dest_desc->buffer.pointer,
729 source_desc->buffer.pointer,
730 source_desc->buffer.length);
731 }
732 break;
733
734 case ACPI_TYPE_STRING:
735
736
737
738
739
740 if (source_desc->string.pointer) {
741 dest_desc->string.pointer =
742 ACPI_ALLOCATE((acpi_size) source_desc->string.
743 length + 1);
744 if (!dest_desc->string.pointer) {
745 return (AE_NO_MEMORY);
746 }
747
748
749
750 memcpy(dest_desc->string.pointer,
751 source_desc->string.pointer,
752 (acpi_size) source_desc->string.length + 1);
753 }
754 break;
755
756 case ACPI_TYPE_LOCAL_REFERENCE:
757
758
759
760
761
762
763
764
765 if (source_desc->reference.class == ACPI_REFCLASS_TABLE) {
766 break;
767 }
768
769 acpi_ut_add_reference(source_desc->reference.object);
770 break;
771
772 case ACPI_TYPE_REGION:
773
774
775
776 if (dest_desc->region.handler) {
777 acpi_ut_add_reference(dest_desc->region.handler);
778 }
779 break;
780
781
782
783
784
785 case ACPI_TYPE_MUTEX:
786
787 status = acpi_os_create_mutex(&dest_desc->mutex.os_mutex);
788 if (ACPI_FAILURE(status)) {
789 return (status);
790 }
791 break;
792
793 case ACPI_TYPE_EVENT:
794
795 status = acpi_os_create_semaphore(ACPI_NO_UNIT_LIMIT, 0,
796 &dest_desc->event.
797 os_semaphore);
798 if (ACPI_FAILURE(status)) {
799 return (status);
800 }
801 break;
802
803 default:
804
805
806
807 break;
808 }
809
810 return (AE_OK);
811}
812
813
814
815
816
817
818
819
820
821
822
823
824
825static acpi_status
826acpi_ut_copy_ielement_to_ielement(u8 object_type,
827 union acpi_operand_object *source_object,
828 union acpi_generic_state *state,
829 void *context)
830{
831 acpi_status status = AE_OK;
832 u32 this_index;
833 union acpi_operand_object **this_target_ptr;
834 union acpi_operand_object *target_object;
835
836 ACPI_FUNCTION_ENTRY();
837
838 this_index = state->pkg.index;
839 this_target_ptr = (union acpi_operand_object **)
840 &state->pkg.dest_object->package.elements[this_index];
841
842 switch (object_type) {
843 case ACPI_COPY_TYPE_SIMPLE:
844
845
846
847 if (source_object) {
848
849
850
851 target_object =
852 acpi_ut_create_internal_object(source_object->
853 common.type);
854 if (!target_object) {
855 return (AE_NO_MEMORY);
856 }
857
858 status =
859 acpi_ut_copy_simple_object(source_object,
860 target_object);
861 if (ACPI_FAILURE(status)) {
862 goto error_exit;
863 }
864
865 *this_target_ptr = target_object;
866 } else {
867
868
869 *this_target_ptr = NULL;
870 }
871 break;
872
873 case ACPI_COPY_TYPE_PACKAGE:
874
875
876
877
878 target_object =
879 acpi_ut_create_package_object(source_object->package.count);
880 if (!target_object) {
881 return (AE_NO_MEMORY);
882 }
883
884 target_object->common.flags = source_object->common.flags;
885
886
887
888 state->pkg.this_target_obj = target_object;
889
890
891
892 *this_target_ptr = target_object;
893 break;
894
895 default:
896
897 return (AE_BAD_PARAMETER);
898 }
899
900 return (status);
901
902 error_exit:
903 acpi_ut_remove_reference(target_object);
904 return (status);
905}
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922static acpi_status
923acpi_ut_copy_ipackage_to_ipackage(union acpi_operand_object *source_obj,
924 union acpi_operand_object *dest_obj,
925 struct acpi_walk_state *walk_state)
926{
927 acpi_status status = AE_OK;
928
929 ACPI_FUNCTION_TRACE(ut_copy_ipackage_to_ipackage);
930
931 dest_obj->common.type = source_obj->common.type;
932 dest_obj->common.flags = source_obj->common.flags;
933 dest_obj->package.count = source_obj->package.count;
934
935
936
937
938 dest_obj->package.elements = ACPI_ALLOCATE_ZEROED(((acpi_size)
939 source_obj->package.
940 count +
941 1) * sizeof(void *));
942 if (!dest_obj->package.elements) {
943 ACPI_ERROR((AE_INFO, "Package allocation failure"));
944 return_ACPI_STATUS(AE_NO_MEMORY);
945 }
946
947
948
949
950
951 status = acpi_ut_walk_package_tree(source_obj, dest_obj,
952 acpi_ut_copy_ielement_to_ielement,
953 walk_state);
954 if (ACPI_FAILURE(status)) {
955
956
957
958 acpi_ut_remove_reference(dest_obj);
959 }
960
961 return_ACPI_STATUS(status);
962}
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978acpi_status
979acpi_ut_copy_iobject_to_iobject(union acpi_operand_object *source_desc,
980 union acpi_operand_object **dest_desc,
981 struct acpi_walk_state *walk_state)
982{
983 acpi_status status = AE_OK;
984
985 ACPI_FUNCTION_TRACE(ut_copy_iobject_to_iobject);
986
987
988
989 *dest_desc = acpi_ut_create_internal_object(source_desc->common.type);
990 if (!*dest_desc) {
991 return_ACPI_STATUS(AE_NO_MEMORY);
992 }
993
994
995
996 if (source_desc->common.type == ACPI_TYPE_PACKAGE) {
997 status =
998 acpi_ut_copy_ipackage_to_ipackage(source_desc, *dest_desc,
999 walk_state);
1000 } else {
1001 status = acpi_ut_copy_simple_object(source_desc, *dest_desc);
1002 }
1003
1004 return_ACPI_STATUS(status);
1005}
1006