ACPICA 20050617-0624 from Bob Moore <robert.moore@intel.com>
[sfrench/cifs-2.6.git] / drivers / acpi / utilities / utalloc.c
1 /******************************************************************************
2  *
3  * Module Name: utalloc - local memory allocation routines
4  *
5  *****************************************************************************/
6
7 /*
8  * Copyright (C) 2000 - 2005, R. Byron Moore
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions, and the following disclaimer,
16  *    without modification.
17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18  *    substantially similar to the "NO WARRANTY" disclaimer below
19  *    ("Disclaimer") and any redistribution must be conditioned upon
20  *    including a substantially similar Disclaimer requirement for further
21  *    binary redistribution.
22  * 3. Neither the names of the above-listed copyright holders nor the names
23  *    of any contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * Alternatively, this software may be distributed under the terms of the
27  * GNU General Public License ("GPL") version 2 as published by the Free
28  * Software Foundation.
29  *
30  * NO WARRANTY
31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41  * POSSIBILITY OF SUCH DAMAGES.
42  */
43
44
45 #include <acpi/acpi.h>
46
47 #define _COMPONENT          ACPI_UTILITIES
48          ACPI_MODULE_NAME    ("utalloc")
49
50 /* Local prototypes */
51
52 #ifdef  ACPI_DBG_TRACK_ALLOCATIONS
53 static struct acpi_debug_mem_block *
54 acpi_ut_find_allocation (
55         void                            *allocation);
56
57 static acpi_status
58 acpi_ut_track_allocation (
59         struct acpi_debug_mem_block     *address,
60         acpi_size                       size,
61         u8                              alloc_type,
62         u32                             component,
63         char                            *module,
64         u32                             line);
65
66 static acpi_status
67 acpi_ut_remove_allocation (
68         struct acpi_debug_mem_block     *address,
69         u32                             component,
70         char                            *module,
71         u32                             line);
72 #endif  /* ACPI_DBG_TRACK_ALLOCATIONS */
73
74 #ifdef ACPI_DBG_TRACK_ALLOCATIONS
75 static acpi_status
76 acpi_ut_create_list (
77         char                            *list_name,
78         u16                             object_size,
79         acpi_handle                     *return_cache);
80 #endif
81
82
83 /*******************************************************************************
84  *
85  * FUNCTION:    acpi_ut_create_caches
86  *
87  * PARAMETERS:  None
88  *
89  * RETURN:      Status
90  *
91  * DESCRIPTION: Create all local caches
92  *
93  ******************************************************************************/
94
95 acpi_status
96 acpi_ut_create_caches (
97         void)
98 {
99         acpi_status                     status;
100
101
102 #ifdef ACPI_DBG_TRACK_ALLOCATIONS
103
104         /* Memory allocation lists */
105
106         status = acpi_ut_create_list ("Acpi-Global", 0,
107                          &acpi_gbl_global_list);
108         if (ACPI_FAILURE (status)) {
109                 return (status);
110         }
111
112         status = acpi_ut_create_list ("Acpi-Namespace", sizeof (struct acpi_namespace_node),
113                          &acpi_gbl_ns_node_list);
114         if (ACPI_FAILURE (status)) {
115                 return (status);
116         }
117 #endif
118
119         /* Object Caches, for frequently used objects */
120
121         status = acpi_os_create_cache ("acpi_state", sizeof (union acpi_generic_state),
122                          ACPI_MAX_STATE_CACHE_DEPTH, &acpi_gbl_state_cache);
123         if (ACPI_FAILURE (status)) {
124                 return (status);
125         }
126
127         status = acpi_os_create_cache ("acpi_parse", sizeof (struct acpi_parse_obj_common),
128                          ACPI_MAX_PARSE_CACHE_DEPTH, &acpi_gbl_ps_node_cache);
129         if (ACPI_FAILURE (status)) {
130                 return (status);
131         }
132
133         status = acpi_os_create_cache ("acpi_parse_ext", sizeof (struct acpi_parse_obj_named),
134                          ACPI_MAX_EXTPARSE_CACHE_DEPTH, &acpi_gbl_ps_node_ext_cache);
135         if (ACPI_FAILURE (status)) {
136                 return (status);
137         }
138
139         status = acpi_os_create_cache ("acpi_operand", sizeof (union acpi_operand_object),
140                          ACPI_MAX_OBJECT_CACHE_DEPTH, &acpi_gbl_operand_cache);
141         if (ACPI_FAILURE (status)) {
142                 return (status);
143         }
144
145         return (AE_OK);
146 }
147
148
149 /*******************************************************************************
150  *
151  * FUNCTION:    acpi_ut_delete_caches
152  *
153  * PARAMETERS:  None
154  *
155  * RETURN:      Status
156  *
157  * DESCRIPTION: Purge and delete all local caches
158  *
159  ******************************************************************************/
160
161 acpi_status
162 acpi_ut_delete_caches (
163         void)
164 {
165
166         (void) acpi_os_delete_cache (acpi_gbl_state_cache);
167         acpi_gbl_state_cache = NULL;
168
169         (void) acpi_os_delete_cache (acpi_gbl_operand_cache);
170         acpi_gbl_operand_cache = NULL;
171
172         (void) acpi_os_delete_cache (acpi_gbl_ps_node_cache);
173         acpi_gbl_ps_node_cache = NULL;
174
175         (void) acpi_os_delete_cache (acpi_gbl_ps_node_ext_cache);
176         acpi_gbl_ps_node_ext_cache = NULL;
177
178         return (AE_OK);
179 }
180
181 /*******************************************************************************
182  *
183  * FUNCTION:    acpi_ut_validate_buffer
184  *
185  * PARAMETERS:  Buffer              - Buffer descriptor to be validated
186  *
187  * RETURN:      Status
188  *
189  * DESCRIPTION: Perform parameter validation checks on an struct acpi_buffer
190  *
191  ******************************************************************************/
192
193 acpi_status
194 acpi_ut_validate_buffer (
195         struct acpi_buffer              *buffer)
196 {
197
198         /* Obviously, the structure pointer must be valid */
199
200         if (!buffer) {
201                 return (AE_BAD_PARAMETER);
202         }
203
204         /* Special semantics for the length */
205
206         if ((buffer->length == ACPI_NO_BUFFER)              ||
207                 (buffer->length == ACPI_ALLOCATE_BUFFER)        ||
208                 (buffer->length == ACPI_ALLOCATE_LOCAL_BUFFER)) {
209                 return (AE_OK);
210         }
211
212         /* Length is valid, the buffer pointer must be also */
213
214         if (!buffer->pointer) {
215                 return (AE_BAD_PARAMETER);
216         }
217
218         return (AE_OK);
219 }
220
221
222 /*******************************************************************************
223  *
224  * FUNCTION:    acpi_ut_initialize_buffer
225  *
226  * PARAMETERS:  Buffer              - Buffer to be validated
227  *              required_length     - Length needed
228  *
229  * RETURN:      Status
230  *
231  * DESCRIPTION: Validate that the buffer is of the required length or
232  *              allocate a new buffer.  Returned buffer is always zeroed.
233  *
234  ******************************************************************************/
235
236 acpi_status
237 acpi_ut_initialize_buffer (
238         struct acpi_buffer              *buffer,
239         acpi_size                       required_length)
240 {
241         acpi_status                     status = AE_OK;
242
243
244         switch (buffer->length) {
245         case ACPI_NO_BUFFER:
246
247                 /* Set the exception and returned the required length */
248
249                 status = AE_BUFFER_OVERFLOW;
250                 break;
251
252
253         case ACPI_ALLOCATE_BUFFER:
254
255                 /* Allocate a new buffer */
256
257                 buffer->pointer = acpi_os_allocate (required_length);
258                 if (!buffer->pointer) {
259                         return (AE_NO_MEMORY);
260                 }
261
262                 /* Clear the buffer */
263
264                 ACPI_MEMSET (buffer->pointer, 0, required_length);
265                 break;
266
267
268         case ACPI_ALLOCATE_LOCAL_BUFFER:
269
270                 /* Allocate a new buffer with local interface to allow tracking */
271
272                 buffer->pointer = ACPI_MEM_CALLOCATE (required_length);
273                 if (!buffer->pointer) {
274                         return (AE_NO_MEMORY);
275                 }
276                 break;
277
278
279         default:
280
281                 /* Existing buffer: Validate the size of the buffer */
282
283                 if (buffer->length < required_length) {
284                         status = AE_BUFFER_OVERFLOW;
285                         break;
286                 }
287
288                 /* Clear the buffer */
289
290                 ACPI_MEMSET (buffer->pointer, 0, required_length);
291                 break;
292         }
293
294         buffer->length = required_length;
295         return (status);
296 }
297
298
299 /*******************************************************************************
300  *
301  * FUNCTION:    acpi_ut_allocate
302  *
303  * PARAMETERS:  Size                - Size of the allocation
304  *              Component           - Component type of caller
305  *              Module              - Source file name of caller
306  *              Line                - Line number of caller
307  *
308  * RETURN:      Address of the allocated memory on success, NULL on failure.
309  *
310  * DESCRIPTION: The subsystem's equivalent of malloc.
311  *
312  ******************************************************************************/
313
314 void *
315 acpi_ut_allocate (
316         acpi_size                       size,
317         u32                             component,
318         char                            *module,
319         u32                             line)
320 {
321         void                            *allocation;
322
323
324         ACPI_FUNCTION_TRACE_U32 ("ut_allocate", size);
325
326
327         /* Check for an inadvertent size of zero bytes */
328
329         if (!size) {
330                 _ACPI_REPORT_ERROR (module, line, component,
331                                 ("ut_allocate: Attempt to allocate zero bytes\n"));
332                 size = 1;
333         }
334
335         allocation = acpi_os_allocate (size);
336         if (!allocation) {
337                 /* Report allocation error */
338
339                 _ACPI_REPORT_ERROR (module, line, component,
340                                 ("ut_allocate: Could not allocate size %X\n", (u32) size));
341
342                 return_PTR (NULL);
343         }
344
345         return_PTR (allocation);
346 }
347
348
349 /*******************************************************************************
350  *
351  * FUNCTION:    acpi_ut_callocate
352  *
353  * PARAMETERS:  Size                - Size of the allocation
354  *              Component           - Component type of caller
355  *              Module              - Source file name of caller
356  *              Line                - Line number of caller
357  *
358  * RETURN:      Address of the allocated memory on success, NULL on failure.
359  *
360  * DESCRIPTION: Subsystem equivalent of calloc.
361  *
362  ******************************************************************************/
363
364 void *
365 acpi_ut_callocate (
366         acpi_size                       size,
367         u32                             component,
368         char                            *module,
369         u32                             line)
370 {
371         void                            *allocation;
372
373
374         ACPI_FUNCTION_TRACE_U32 ("ut_callocate", size);
375
376
377         /* Check for an inadvertent size of zero bytes */
378
379         if (!size) {
380                 _ACPI_REPORT_ERROR (module, line, component,
381                                 ("ut_callocate: Attempt to allocate zero bytes\n"));
382                 return_PTR (NULL);
383         }
384
385         allocation = acpi_os_allocate (size);
386         if (!allocation) {
387                 /* Report allocation error */
388
389                 _ACPI_REPORT_ERROR (module, line, component,
390                                 ("ut_callocate: Could not allocate size %X\n", (u32) size));
391                 return_PTR (NULL);
392         }
393
394         /* Clear the memory block */
395
396         ACPI_MEMSET (allocation, 0, size);
397         return_PTR (allocation);
398 }
399
400
401 #ifdef ACPI_DBG_TRACK_ALLOCATIONS
402 /*
403  * These procedures are used for tracking memory leaks in the subsystem, and
404  * they get compiled out when the ACPI_DBG_TRACK_ALLOCATIONS is not set.
405  *
406  * Each memory allocation is tracked via a doubly linked list.  Each
407  * element contains the caller's component, module name, function name, and
408  * line number.  acpi_ut_allocate and acpi_ut_callocate call
409  * acpi_ut_track_allocation to add an element to the list; deletion
410  * occurs in the body of acpi_ut_free.
411  */
412
413 /*******************************************************************************
414  *
415  * FUNCTION:    acpi_ut_create_list
416  *
417  * PARAMETERS:  cache_name      - Ascii name for the cache
418  *              object_size     - Size of each cached object
419  *              return_cache    - Where the new cache object is returned
420  *
421  * RETURN:      Status
422  *
423  * DESCRIPTION: Create a local memory list for tracking purposed
424  *
425  ******************************************************************************/
426
427 static acpi_status
428 acpi_ut_create_list (
429         char                            *list_name,
430         u16                             object_size,
431         acpi_handle                     *return_cache)
432 {
433         struct acpi_memory_list         *cache;
434
435
436         cache = acpi_os_allocate (sizeof (struct acpi_memory_list));
437         if (!cache) {
438                 return (AE_NO_MEMORY);
439         }
440
441         ACPI_MEMSET (cache, 0, sizeof (struct acpi_memory_list));
442
443         cache->list_name  = list_name;
444         cache->object_size = object_size;
445
446         *return_cache = cache;
447         return (AE_OK);
448 }
449
450
451 /*******************************************************************************
452  *
453  * FUNCTION:    acpi_ut_allocate_and_track
454  *
455  * PARAMETERS:  Size                - Size of the allocation
456  *              Component           - Component type of caller
457  *              Module              - Source file name of caller
458  *              Line                - Line number of caller
459  *
460  * RETURN:      Address of the allocated memory on success, NULL on failure.
461  *
462  * DESCRIPTION: The subsystem's equivalent of malloc.
463  *
464  ******************************************************************************/
465
466 void *
467 acpi_ut_allocate_and_track (
468         acpi_size                       size,
469         u32                             component,
470         char                            *module,
471         u32                             line)
472 {
473         struct acpi_debug_mem_block     *allocation;
474         acpi_status                     status;
475
476
477         allocation = acpi_ut_allocate (size + sizeof (struct acpi_debug_mem_header),
478                           component, module, line);
479         if (!allocation) {
480                 return (NULL);
481         }
482
483         status = acpi_ut_track_allocation (allocation, size,
484                           ACPI_MEM_MALLOC, component, module, line);
485         if (ACPI_FAILURE (status)) {
486                 acpi_os_free (allocation);
487                 return (NULL);
488         }
489
490         acpi_gbl_global_list->total_allocated++;
491         acpi_gbl_global_list->current_total_size += (u32) size;
492
493         return ((void *) &allocation->user_space);
494 }
495
496
497 /*******************************************************************************
498  *
499  * FUNCTION:    acpi_ut_callocate_and_track
500  *
501  * PARAMETERS:  Size                - Size of the allocation
502  *              Component           - Component type of caller
503  *              Module              - Source file name of caller
504  *              Line                - Line number of caller
505  *
506  * RETURN:      Address of the allocated memory on success, NULL on failure.
507  *
508  * DESCRIPTION: Subsystem equivalent of calloc.
509  *
510  ******************************************************************************/
511
512 void *
513 acpi_ut_callocate_and_track (
514         acpi_size                       size,
515         u32                             component,
516         char                            *module,
517         u32                             line)
518 {
519         struct acpi_debug_mem_block     *allocation;
520         acpi_status                     status;
521
522
523         allocation = acpi_ut_callocate (size + sizeof (struct acpi_debug_mem_header),
524                           component, module, line);
525         if (!allocation) {
526                 /* Report allocation error */
527
528                 _ACPI_REPORT_ERROR (module, line, component,
529                                 ("ut_callocate: Could not allocate size %X\n", (u32) size));
530                 return (NULL);
531         }
532
533         status = acpi_ut_track_allocation (allocation, size,
534                            ACPI_MEM_CALLOC, component, module, line);
535         if (ACPI_FAILURE (status)) {
536                 acpi_os_free (allocation);
537                 return (NULL);
538         }
539
540         acpi_gbl_global_list->total_allocated++;
541         acpi_gbl_global_list->current_total_size += (u32) size;
542
543         return ((void *) &allocation->user_space);
544 }
545
546
547 /*******************************************************************************
548  *
549  * FUNCTION:    acpi_ut_free_and_track
550  *
551  * PARAMETERS:  Allocation          - Address of the memory to deallocate
552  *              Component           - Component type of caller
553  *              Module              - Source file name of caller
554  *              Line                - Line number of caller
555  *
556  * RETURN:      None
557  *
558  * DESCRIPTION: Frees the memory at Allocation
559  *
560  ******************************************************************************/
561
562 void
563 acpi_ut_free_and_track (
564         void                            *allocation,
565         u32                             component,
566         char                            *module,
567         u32                             line)
568 {
569         struct acpi_debug_mem_block     *debug_block;
570         acpi_status                     status;
571
572
573         ACPI_FUNCTION_TRACE_PTR ("ut_free", allocation);
574
575
576         if (NULL == allocation) {
577                 _ACPI_REPORT_ERROR (module, line, component,
578                         ("acpi_ut_free: Attempt to delete a NULL address\n"));
579
580                 return_VOID;
581         }
582
583         debug_block = ACPI_CAST_PTR (struct acpi_debug_mem_block,
584                           (((char *) allocation) - sizeof (struct acpi_debug_mem_header)));
585
586         acpi_gbl_global_list->total_freed++;
587         acpi_gbl_global_list->current_total_size -= debug_block->size;
588
589         status = acpi_ut_remove_allocation (debug_block,
590                           component, module, line);
591         if (ACPI_FAILURE (status)) {
592                 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not free memory, %s\n",
593                         acpi_format_exception (status)));
594         }
595
596         acpi_os_free (debug_block);
597
598         ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "%p freed\n", allocation));
599
600         return_VOID;
601 }
602
603
604 /*******************************************************************************
605  *
606  * FUNCTION:    acpi_ut_find_allocation
607  *
608  * PARAMETERS:  Allocation              - Address of allocated memory
609  *
610  * RETURN:      A list element if found; NULL otherwise.
611  *
612  * DESCRIPTION: Searches for an element in the global allocation tracking list.
613  *
614  ******************************************************************************/
615
616 static struct acpi_debug_mem_block *
617 acpi_ut_find_allocation (
618         void                            *allocation)
619 {
620         struct acpi_debug_mem_block     *element;
621
622
623         ACPI_FUNCTION_ENTRY ();
624
625
626         element = acpi_gbl_global_list->list_head;
627
628         /* Search for the address. */
629
630         while (element) {
631                 if (element == allocation) {
632                         return (element);
633                 }
634
635                 element = element->next;
636         }
637
638         return (NULL);
639 }
640
641
642 /*******************************************************************************
643  *
644  * FUNCTION:    acpi_ut_track_allocation
645  *
646  * PARAMETERS:  Allocation          - Address of allocated memory
647  *              Size                - Size of the allocation
648  *              alloc_type          - MEM_MALLOC or MEM_CALLOC
649  *              Component           - Component type of caller
650  *              Module              - Source file name of caller
651  *              Line                - Line number of caller
652  *
653  * RETURN:      None.
654  *
655  * DESCRIPTION: Inserts an element into the global allocation tracking list.
656  *
657  ******************************************************************************/
658
659 static acpi_status
660 acpi_ut_track_allocation (
661         struct acpi_debug_mem_block     *allocation,
662         acpi_size                       size,
663         u8                              alloc_type,
664         u32                             component,
665         char                            *module,
666         u32                             line)
667 {
668         struct acpi_memory_list         *mem_list;
669         struct acpi_debug_mem_block     *element;
670         acpi_status                     status = AE_OK;
671
672
673         ACPI_FUNCTION_TRACE_PTR ("ut_track_allocation", allocation);
674
675
676         mem_list = acpi_gbl_global_list;
677         status = acpi_ut_acquire_mutex (ACPI_MTX_MEMORY);
678         if (ACPI_FAILURE (status)) {
679                 return_ACPI_STATUS (status);
680         }
681
682         /*
683          * Search list for this address to make sure it is not already on the list.
684          * This will catch several kinds of problems.
685          */
686         element = acpi_ut_find_allocation (allocation);
687         if (element) {
688                 ACPI_REPORT_ERROR ((
689                         "ut_track_allocation: Allocation already present in list! (%p)\n",
690                         allocation));
691
692                 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Element %p Address %p\n",
693                         element, allocation));
694
695                 goto unlock_and_exit;
696         }
697
698         /* Fill in the instance data. */
699
700         allocation->size      = (u32) size;
701         allocation->alloc_type = alloc_type;
702         allocation->component = component;
703         allocation->line      = line;
704
705         ACPI_STRNCPY (allocation->module, module, ACPI_MAX_MODULE_NAME);
706         allocation->module[ACPI_MAX_MODULE_NAME-1] = 0;
707
708         /* Insert at list head */
709
710         if (mem_list->list_head) {
711                 ((struct acpi_debug_mem_block *)(mem_list->list_head))->previous = allocation;
712         }
713
714         allocation->next = mem_list->list_head;
715         allocation->previous = NULL;
716
717         mem_list->list_head = allocation;
718
719
720 unlock_and_exit:
721         status = acpi_ut_release_mutex (ACPI_MTX_MEMORY);
722         return_ACPI_STATUS (status);
723 }
724
725
726 /*******************************************************************************
727  *
728  * FUNCTION:    acpi_ut_remove_allocation
729  *
730  * PARAMETERS:  Allocation          - Address of allocated memory
731  *              Component           - Component type of caller
732  *              Module              - Source file name of caller
733  *              Line                - Line number of caller
734  *
735  * RETURN:
736  *
737  * DESCRIPTION: Deletes an element from the global allocation tracking list.
738  *
739  ******************************************************************************/
740
741 static acpi_status
742 acpi_ut_remove_allocation (
743         struct acpi_debug_mem_block     *allocation,
744         u32                             component,
745         char                            *module,
746         u32                             line)
747 {
748         struct acpi_memory_list         *mem_list;
749         acpi_status                     status;
750
751
752         ACPI_FUNCTION_TRACE ("ut_remove_allocation");
753
754
755         mem_list = acpi_gbl_global_list;
756         if (NULL == mem_list->list_head) {
757                 /* No allocations! */
758
759                 _ACPI_REPORT_ERROR (module, line, component,
760                         ("ut_remove_allocation: Empty allocation list, nothing to free!\n"));
761
762                 return_ACPI_STATUS (AE_OK);
763         }
764
765         status = acpi_ut_acquire_mutex (ACPI_MTX_MEMORY);
766         if (ACPI_FAILURE (status)) {
767                 return_ACPI_STATUS (status);
768         }
769
770         /* Unlink */
771
772         if (allocation->previous) {
773                 (allocation->previous)->next = allocation->next;
774         }
775         else {
776                 mem_list->list_head = allocation->next;
777         }
778
779         if (allocation->next) {
780                 (allocation->next)->previous = allocation->previous;
781         }
782
783         /* Mark the segment as deleted */
784
785         ACPI_MEMSET (&allocation->user_space, 0xEA, allocation->size);
786
787         ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Freeing size 0%X\n",
788                 allocation->size));
789
790         status = acpi_ut_release_mutex (ACPI_MTX_MEMORY);
791         return_ACPI_STATUS (status);
792 }
793
794
795 /*******************************************************************************
796  *
797  * FUNCTION:    acpi_ut_dump_allocation_info
798  *
799  * PARAMETERS:
800  *
801  * RETURN:      None
802  *
803  * DESCRIPTION: Print some info about the outstanding allocations.
804  *
805  ******************************************************************************/
806
807 #ifdef ACPI_FUTURE_USAGE
808 void
809 acpi_ut_dump_allocation_info (
810         void)
811 {
812 /*
813         struct acpi_memory_list         *mem_list;
814 */
815
816         ACPI_FUNCTION_TRACE ("ut_dump_allocation_info");
817
818 /*
819         ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
820                           ("%30s: %4d (%3d Kb)\n", "Current allocations",
821                           mem_list->current_count,
822                           ROUND_UP_TO_1K (mem_list->current_size)));
823
824         ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
825                           ("%30s: %4d (%3d Kb)\n", "Max concurrent allocations",
826                           mem_list->max_concurrent_count,
827                           ROUND_UP_TO_1K (mem_list->max_concurrent_size)));
828
829
830         ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
831                           ("%30s: %4d (%3d Kb)\n", "Total (all) internal objects",
832                           running_object_count,
833                           ROUND_UP_TO_1K (running_object_size)));
834
835         ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
836                           ("%30s: %4d (%3d Kb)\n", "Total (all) allocations",
837                           running_alloc_count,
838                           ROUND_UP_TO_1K (running_alloc_size)));
839
840
841         ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
842                           ("%30s: %4d (%3d Kb)\n", "Current Nodes",
843                           acpi_gbl_current_node_count,
844                           ROUND_UP_TO_1K (acpi_gbl_current_node_size)));
845
846         ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
847                           ("%30s: %4d (%3d Kb)\n", "Max Nodes",
848                           acpi_gbl_max_concurrent_node_count,
849                           ROUND_UP_TO_1K ((acpi_gbl_max_concurrent_node_count *
850                                          sizeof (struct acpi_namespace_node)))));
851 */
852         return_VOID;
853 }
854 #endif  /*  ACPI_FUTURE_USAGE  */
855
856
857 /*******************************************************************************
858  *
859  * FUNCTION:    acpi_ut_dump_allocations
860  *
861  * PARAMETERS:  Component           - Component(s) to dump info for.
862  *              Module              - Module to dump info for.  NULL means all.
863  *
864  * RETURN:      None
865  *
866  * DESCRIPTION: Print a list of all outstanding allocations.
867  *
868  ******************************************************************************/
869
870 void
871 acpi_ut_dump_allocations (
872         u32                             component,
873         char                            *module)
874 {
875         struct acpi_debug_mem_block     *element;
876         union acpi_descriptor           *descriptor;
877         u32                             num_outstanding = 0;
878
879
880         ACPI_FUNCTION_TRACE ("ut_dump_allocations");
881
882
883         /*
884          * Walk the allocation list.
885          */
886         if (ACPI_FAILURE (acpi_ut_acquire_mutex (ACPI_MTX_MEMORY))) {
887                 return;
888         }
889
890         element = acpi_gbl_global_list->list_head;
891         while (element) {
892                 if ((element->component & component) &&
893                         ((module == NULL) || (0 == ACPI_STRCMP (module, element->module)))) {
894                         /* Ignore allocated objects that are in a cache */
895
896                         descriptor = ACPI_CAST_PTR (union acpi_descriptor, &element->user_space);
897                         if (descriptor->descriptor_id != ACPI_DESC_TYPE_CACHED) {
898                                 acpi_os_printf ("%p Len %04X %9.9s-%d [%s] ",
899                                         descriptor, element->size, element->module,
900                                         element->line, acpi_ut_get_descriptor_name (descriptor));
901
902                                 /* Most of the elements will be Operand objects. */
903
904                                 switch (ACPI_GET_DESCRIPTOR_TYPE (descriptor)) {
905                                 case ACPI_DESC_TYPE_OPERAND:
906                                         acpi_os_printf ("%12.12s R%hd",
907                                                 acpi_ut_get_type_name (descriptor->object.common.type),
908                                                 descriptor->object.common.reference_count);
909                                         break;
910
911                                 case ACPI_DESC_TYPE_PARSER:
912                                         acpi_os_printf ("aml_opcode %04hX",
913                                                 descriptor->op.asl.aml_opcode);
914                                         break;
915
916                                 case ACPI_DESC_TYPE_NAMED:
917                                         acpi_os_printf ("%4.4s",
918                                                 acpi_ut_get_node_name (&descriptor->node));
919                                         break;
920
921                                 default:
922                                         break;
923                                 }
924
925                                 acpi_os_printf ( "\n");
926                                 num_outstanding++;
927                         }
928                 }
929                 element = element->next;
930         }
931
932         (void) acpi_ut_release_mutex (ACPI_MTX_MEMORY);
933
934         /* Print summary */
935
936         if (!num_outstanding) {
937                 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
938                         "No outstanding allocations.\n"));
939         }
940         else {
941                 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
942                         "%d(%X) Outstanding allocations\n",
943                         num_outstanding, num_outstanding));
944         }
945
946         return_VOID;
947 }
948
949 #endif  /* #ifdef ACPI_DBG_TRACK_ALLOCATIONS */
950