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
45#include <acpi/acpi.h>
46
47#define _COMPONENT ACPI_UTILITIES
48 ACPI_MODULE_NAME ("utalloc")
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65void
66acpi_ut_release_to_cache (
67 u32 list_id,
68 void *object)
69{
70 struct acpi_memory_list *cache_info;
71
72
73 ACPI_FUNCTION_ENTRY ();
74
75
76
77
78 cache_info = &acpi_gbl_memory_lists[list_id];
79 if (cache_info->cache_depth >= cache_info->max_cache_depth) {
80 ACPI_MEM_FREE (object);
81 ACPI_MEM_TRACKING (cache_info->total_freed++);
82 }
83
84
85
86 else {
87 if (ACPI_FAILURE (acpi_ut_acquire_mutex (ACPI_MTX_CACHES))) {
88 return;
89 }
90
91
92
93 ACPI_MEMSET (object, 0xCA, cache_info->object_size);
94 ACPI_SET_DESCRIPTOR_TYPE (object, ACPI_DESC_TYPE_CACHED);
95
96
97
98 * (ACPI_CAST_INDIRECT_PTR (char, &(((char *) object)[cache_info->link_offset]))) = cache_info->list_head;
99 cache_info->list_head = object;
100 cache_info->cache_depth++;
101
102 (void) acpi_ut_release_mutex (ACPI_MTX_CACHES);
103 }
104}
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121void *
122acpi_ut_acquire_from_cache (
123 u32 list_id)
124{
125 struct acpi_memory_list *cache_info;
126 void *object;
127
128
129 ACPI_FUNCTION_NAME ("ut_acquire_from_cache");
130
131
132 cache_info = &acpi_gbl_memory_lists[list_id];
133 if (ACPI_FAILURE (acpi_ut_acquire_mutex (ACPI_MTX_CACHES))) {
134 return (NULL);
135 }
136
137 ACPI_MEM_TRACKING (cache_info->cache_requests++);
138
139
140
141 if (cache_info->list_head) {
142
143
144 object = cache_info->list_head;
145 cache_info->list_head = *(ACPI_CAST_INDIRECT_PTR (char, &(((char *) object)[cache_info->link_offset])));
146
147 ACPI_MEM_TRACKING (cache_info->cache_hits++);
148 cache_info->cache_depth--;
149
150#ifdef ACPI_DBG_TRACK_ALLOCATIONS
151 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Object %p from %s\n",
152 object, acpi_gbl_memory_lists[list_id].list_name));
153#endif
154
155 if (ACPI_FAILURE (acpi_ut_release_mutex (ACPI_MTX_CACHES))) {
156 return (NULL);
157 }
158
159
160
161 ACPI_MEMSET (object, 0, cache_info->object_size);
162 }
163
164 else {
165
166
167
168
169 if (ACPI_FAILURE (acpi_ut_release_mutex (ACPI_MTX_CACHES))) {
170 return (NULL);
171 }
172
173 object = ACPI_MEM_CALLOCATE (cache_info->object_size);
174 ACPI_MEM_TRACKING (cache_info->total_allocated++);
175 }
176
177 return (object);
178}
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193void
194acpi_ut_delete_generic_cache (
195 u32 list_id)
196{
197 struct acpi_memory_list *cache_info;
198 char *next;
199
200
201 ACPI_FUNCTION_ENTRY ();
202
203
204 cache_info = &acpi_gbl_memory_lists[list_id];
205 while (cache_info->list_head) {
206
207
208 next = *(ACPI_CAST_INDIRECT_PTR (char, &(((char *) cache_info->list_head)[cache_info->link_offset])));
209 ACPI_MEM_FREE (cache_info->list_head);
210
211 cache_info->list_head = next;
212 cache_info->cache_depth--;
213 }
214}
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229acpi_status
230acpi_ut_validate_buffer (
231 struct acpi_buffer *buffer)
232{
233
234
235
236 if (!buffer) {
237 return (AE_BAD_PARAMETER);
238 }
239
240
241
242 if ((buffer->length == ACPI_NO_BUFFER) ||
243 (buffer->length == ACPI_ALLOCATE_BUFFER) ||
244 (buffer->length == ACPI_ALLOCATE_LOCAL_BUFFER)) {
245 return (AE_OK);
246 }
247
248
249
250 if (!buffer->pointer) {
251 return (AE_BAD_PARAMETER);
252 }
253
254 return (AE_OK);
255}
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272acpi_status
273acpi_ut_initialize_buffer (
274 struct acpi_buffer *buffer,
275 acpi_size required_length)
276{
277 acpi_status status = AE_OK;
278
279
280 switch (buffer->length) {
281 case ACPI_NO_BUFFER:
282
283
284
285 status = AE_BUFFER_OVERFLOW;
286 break;
287
288
289 case ACPI_ALLOCATE_BUFFER:
290
291
292
293 buffer->pointer = acpi_os_allocate (required_length);
294 if (!buffer->pointer) {
295 return (AE_NO_MEMORY);
296 }
297
298
299
300 ACPI_MEMSET (buffer->pointer, 0, required_length);
301 break;
302
303
304 case ACPI_ALLOCATE_LOCAL_BUFFER:
305
306
307
308 buffer->pointer = ACPI_MEM_ALLOCATE (required_length);
309 if (!buffer->pointer) {
310 return (AE_NO_MEMORY);
311 }
312
313
314
315 ACPI_MEMSET (buffer->pointer, 0, required_length);
316 break;
317
318
319 default:
320
321
322
323 if (buffer->length < required_length) {
324 status = AE_BUFFER_OVERFLOW;
325 }
326 break;
327 }
328
329 buffer->length = required_length;
330 return (status);
331}
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349void *
350acpi_ut_allocate (
351 acpi_size size,
352 u32 component,
353 char *module,
354 u32 line)
355{
356 void *allocation;
357
358
359 ACPI_FUNCTION_TRACE_U32 ("ut_allocate", size);
360
361
362
363
364 if (!size) {
365 _ACPI_REPORT_ERROR (module, line, component,
366 ("ut_allocate: Attempt to allocate zero bytes\n"));
367 size = 1;
368 }
369
370 allocation = acpi_os_allocate (size);
371 if (!allocation) {
372
373
374 _ACPI_REPORT_ERROR (module, line, component,
375 ("ut_allocate: Could not allocate size %X\n", (u32) size));
376
377 return_PTR (NULL);
378 }
379
380 return_PTR (allocation);
381}
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399void *
400acpi_ut_callocate (
401 acpi_size size,
402 u32 component,
403 char *module,
404 u32 line)
405{
406 void *allocation;
407
408
409 ACPI_FUNCTION_TRACE_U32 ("ut_callocate", size);
410
411
412
413
414 if (!size) {
415 _ACPI_REPORT_ERROR (module, line, component,
416 ("ut_callocate: Attempt to allocate zero bytes\n"));
417 return_PTR (NULL);
418 }
419
420 allocation = acpi_os_allocate (size);
421 if (!allocation) {
422
423
424 _ACPI_REPORT_ERROR (module, line, component,
425 ("ut_callocate: Could not allocate size %X\n", (u32) size));
426 return_PTR (NULL);
427 }
428
429
430
431 ACPI_MEMSET (allocation, 0, size);
432 return_PTR (allocation);
433}
434
435
436#ifdef ACPI_DBG_TRACK_ALLOCATIONS
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464void *
465acpi_ut_allocate_and_track (
466 acpi_size size,
467 u32 component,
468 char *module,
469 u32 line)
470{
471 struct acpi_debug_mem_block *allocation;
472 acpi_status status;
473
474
475 allocation = acpi_ut_allocate (size + sizeof (struct acpi_debug_mem_block), component,
476 module, line);
477 if (!allocation) {
478 return (NULL);
479 }
480
481 status = acpi_ut_track_allocation (ACPI_MEM_LIST_GLOBAL, allocation, size,
482 ACPI_MEM_MALLOC, component, module, line);
483 if (ACPI_FAILURE (status)) {
484 acpi_os_free (allocation);
485 return (NULL);
486 }
487
488 acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].total_allocated++;
489 acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].current_total_size += (u32) size;
490
491 return ((void *) &allocation->user_space);
492}
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510void *
511acpi_ut_callocate_and_track (
512 acpi_size size,
513 u32 component,
514 char *module,
515 u32 line)
516{
517 struct acpi_debug_mem_block *allocation;
518 acpi_status status;
519
520
521 allocation = acpi_ut_callocate (size + sizeof (struct acpi_debug_mem_block), component,
522 module, line);
523 if (!allocation) {
524
525
526 _ACPI_REPORT_ERROR (module, line, component,
527 ("ut_callocate: Could not allocate size %X\n", (u32) size));
528 return (NULL);
529 }
530
531 status = acpi_ut_track_allocation (ACPI_MEM_LIST_GLOBAL, allocation, size,
532 ACPI_MEM_CALLOC, component, module, line);
533 if (ACPI_FAILURE (status)) {
534 acpi_os_free (allocation);
535 return (NULL);
536 }
537
538 acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].total_allocated++;
539 acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].current_total_size += (u32) size;
540
541 return ((void *) &allocation->user_space);
542}
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560void
561acpi_ut_free_and_track (
562 void *allocation,
563 u32 component,
564 char *module,
565 u32 line)
566{
567 struct acpi_debug_mem_block *debug_block;
568 acpi_status status;
569
570
571 ACPI_FUNCTION_TRACE_PTR ("ut_free", allocation);
572
573
574 if (NULL == allocation) {
575 _ACPI_REPORT_ERROR (module, line, component,
576 ("acpi_ut_free: Attempt to delete a NULL address\n"));
577
578 return_VOID;
579 }
580
581 debug_block = ACPI_CAST_PTR (struct acpi_debug_mem_block,
582 (((char *) allocation) - sizeof (struct acpi_debug_mem_header)));
583
584 acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].total_freed++;
585 acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].current_total_size -= debug_block->size;
586
587 status = acpi_ut_remove_allocation (ACPI_MEM_LIST_GLOBAL, debug_block,
588 component, module, line);
589 if (ACPI_FAILURE (status)) {
590 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not free memory, %s\n",
591 acpi_format_exception (status)));
592 }
593
594 acpi_os_free (debug_block);
595
596 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "%p freed\n", allocation));
597
598 return_VOID;
599}
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614struct acpi_debug_mem_block *
615acpi_ut_find_allocation (
616 u32 list_id,
617 void *allocation)
618{
619 struct acpi_debug_mem_block *element;
620
621
622 ACPI_FUNCTION_ENTRY ();
623
624
625 if (list_id > ACPI_MEM_LIST_MAX) {
626 return (NULL);
627 }
628
629 element = acpi_gbl_memory_lists[list_id].list_head;
630
631
632
633 while (element) {
634 if (element == allocation) {
635 return (element);
636 }
637
638 element = element->next;
639 }
640
641 return (NULL);
642}
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662acpi_status
663acpi_ut_track_allocation (
664 u32 list_id,
665 struct acpi_debug_mem_block *allocation,
666 acpi_size size,
667 u8 alloc_type,
668 u32 component,
669 char *module,
670 u32 line)
671{
672 struct acpi_memory_list *mem_list;
673 struct acpi_debug_mem_block *element;
674 acpi_status status = AE_OK;
675
676
677 ACPI_FUNCTION_TRACE_PTR ("ut_track_allocation", allocation);
678
679
680 if (list_id > ACPI_MEM_LIST_MAX) {
681 return_ACPI_STATUS (AE_BAD_PARAMETER);
682 }
683
684 mem_list = &acpi_gbl_memory_lists[list_id];
685 status = acpi_ut_acquire_mutex (ACPI_MTX_MEMORY);
686 if (ACPI_FAILURE (status)) {
687 return_ACPI_STATUS (status);
688 }
689
690
691
692
693
694
695 element = acpi_ut_find_allocation (list_id, allocation);
696 if (element) {
697 ACPI_REPORT_ERROR (("ut_track_allocation: Allocation already present in list! (%p)\n",
698 allocation));
699
700 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Element %p Address %p\n", element, allocation));
701
702 goto unlock_and_exit;
703 }
704
705
706
707 allocation->size = (u32) size;
708 allocation->alloc_type = alloc_type;
709 allocation->component = component;
710 allocation->line = line;
711
712 ACPI_STRNCPY (allocation->module, module, ACPI_MAX_MODULE_NAME);
713
714
715
716 if (mem_list->list_head) {
717 ((struct acpi_debug_mem_block *)(mem_list->list_head))->previous = allocation;
718 }
719
720 allocation->next = mem_list->list_head;
721 allocation->previous = NULL;
722
723 mem_list->list_head = allocation;
724
725
726unlock_and_exit:
727 status = acpi_ut_release_mutex (ACPI_MTX_MEMORY);
728 return_ACPI_STATUS (status);
729}
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747acpi_status
748acpi_ut_remove_allocation (
749 u32 list_id,
750 struct acpi_debug_mem_block *allocation,
751 u32 component,
752 char *module,
753 u32 line)
754{
755 struct acpi_memory_list *mem_list;
756 acpi_status status;
757
758
759 ACPI_FUNCTION_TRACE ("ut_remove_allocation");
760
761
762 if (list_id > ACPI_MEM_LIST_MAX) {
763 return_ACPI_STATUS (AE_BAD_PARAMETER);
764 }
765
766 mem_list = &acpi_gbl_memory_lists[list_id];
767 if (NULL == mem_list->list_head) {
768
769
770 _ACPI_REPORT_ERROR (module, line, component,
771 ("ut_remove_allocation: Empty allocation list, nothing to free!\n"));
772
773 return_ACPI_STATUS (AE_OK);
774 }
775
776 status = acpi_ut_acquire_mutex (ACPI_MTX_MEMORY);
777 if (ACPI_FAILURE (status)) {
778 return_ACPI_STATUS (status);
779 }
780
781
782
783 if (allocation->previous) {
784 (allocation->previous)->next = allocation->next;
785 }
786 else {
787 mem_list->list_head = allocation->next;
788 }
789
790 if (allocation->next) {
791 (allocation->next)->previous = allocation->previous;
792 }
793
794
795
796 ACPI_MEMSET (&allocation->user_space, 0xEA, allocation->size);
797
798 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Freeing size 0%X\n", allocation->size));
799
800 status = acpi_ut_release_mutex (ACPI_MTX_MEMORY);
801 return_ACPI_STATUS (status);
802}
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817void
818acpi_ut_dump_allocation_info (
819 void)
820{
821
822
823
824
825 ACPI_FUNCTION_TRACE ("ut_dump_allocation_info");
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860 return_VOID;
861}
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877void
878acpi_ut_dump_allocations (
879 u32 component,
880 char *module)
881{
882 struct acpi_debug_mem_block *element;
883 union acpi_descriptor *descriptor;
884 u32 num_outstanding = 0;
885
886
887 ACPI_FUNCTION_TRACE ("ut_dump_allocations");
888
889
890
891
892
893 if (ACPI_FAILURE (acpi_ut_acquire_mutex (ACPI_MTX_MEMORY))) {
894 return;
895 }
896
897 element = acpi_gbl_memory_lists[0].list_head;
898 while (element) {
899 if ((element->component & component) &&
900 ((module == NULL) || (0 == ACPI_STRCMP (module, element->module)))) {
901
902
903 descriptor = ACPI_CAST_PTR (union acpi_descriptor, &element->user_space);
904 if (descriptor->descriptor_id != ACPI_DESC_TYPE_CACHED) {
905 acpi_os_printf ("%p Len %04X %9.9s-%d [%s] ",
906 descriptor, element->size, element->module,
907 element->line, acpi_ut_get_descriptor_name (descriptor));
908
909
910
911 switch (ACPI_GET_DESCRIPTOR_TYPE (descriptor)) {
912 case ACPI_DESC_TYPE_OPERAND:
913 acpi_os_printf ("%12.12s R%hd",
914 acpi_ut_get_type_name (descriptor->object.common.type),
915 descriptor->object.common.reference_count);
916 break;
917
918 case ACPI_DESC_TYPE_PARSER:
919 acpi_os_printf ("aml_opcode %04hX",
920 descriptor->op.asl.aml_opcode);
921 break;
922
923 case ACPI_DESC_TYPE_NAMED:
924 acpi_os_printf ("%4.4s",
925 acpi_ut_get_node_name (&descriptor->node));
926 break;
927
928 default:
929 break;
930 }
931
932 acpi_os_printf ( "\n");
933 num_outstanding++;
934 }
935 }
936 element = element->next;
937 }
938
939 (void) acpi_ut_release_mutex (ACPI_MTX_MEMORY);
940
941
942
943 if (!num_outstanding) {
944 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
945 "No outstanding allocations.\n"));
946 }
947 else {
948 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
949 "%d(%X) Outstanding allocations\n",
950 num_outstanding, num_outstanding));
951 }
952
953 return_VOID;
954}
955
956
957#endif
958
959