This commit was generated by cvs2svn to compensate for changes in r517,
[linux-2.6.git] / drivers / acpi / utilities / utalloc.c
1 /******************************************************************************
2  *
3  * Module Name: utalloc - local cache and memory allocation routines
4  *
5  *****************************************************************************/
6
7 /*
8  * Copyright (C) 2000 - 2004, 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
51 /******************************************************************************
52  *
53  * FUNCTION:    acpi_ut_release_to_cache
54  *
55  * PARAMETERS:  list_id             - Memory list/cache ID
56  *              Object              - The object to be released
57  *
58  * RETURN:      None
59  *
60  * DESCRIPTION: Release an object to the specified cache.  If cache is full,
61  *              the object is deleted.
62  *
63  ******************************************************************************/
64
65 void
66 acpi_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         /* If walk cache is full, just free this wallkstate object */
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         /* Otherwise put this object back into the cache */
85
86         else {
87                 if (ACPI_FAILURE (acpi_ut_acquire_mutex (ACPI_MTX_CACHES))) {
88                         return;
89                 }
90
91                 /* Mark the object as cached */
92
93                 ACPI_MEMSET (object, 0xCA, cache_info->object_size);
94                 ACPI_SET_DESCRIPTOR_TYPE (object, ACPI_DESC_TYPE_CACHED);
95
96                 /* Put the object at the head of the cache list */
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  * FUNCTION:    acpi_ut_acquire_from_cache
110  *
111  * PARAMETERS:  list_id             - Memory list ID
112  *
113  * RETURN:      A requested object.  NULL if the object could not be
114  *              allocated.
115  *
116  * DESCRIPTION: Get an object from the specified cache.  If cache is empty,
117  *              the object is allocated.
118  *
119  ******************************************************************************/
120
121 void *
122 acpi_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         /* Check the cache first */
140
141         if (cache_info->list_head) {
142                 /* There is an object available, use it */
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                 /* Clear (zero) the previously used Object */
160
161                 ACPI_MEMSET (object, 0, cache_info->object_size);
162         }
163
164         else {
165                 /* The cache is empty, create a new object */
166
167                 /* Avoid deadlock with ACPI_MEM_CALLOCATE */
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  * FUNCTION:    acpi_ut_delete_generic_cache
184  *
185  * PARAMETERS:  list_id         - Memory list ID
186  *
187  * RETURN:      None
188  *
189  * DESCRIPTION: Free all objects within the requested cache.
190  *
191  ******************************************************************************/
192
193 void
194 acpi_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                 /* Delete one cached state object */
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  * FUNCTION:    acpi_ut_validate_buffer
220  *
221  * PARAMETERS:  Buffer              - Buffer descriptor to be validated
222  *
223  * RETURN:      Status
224  *
225  * DESCRIPTION: Perform parameter validation checks on an struct acpi_buffer
226  *
227  ******************************************************************************/
228
229 acpi_status
230 acpi_ut_validate_buffer (
231         struct acpi_buffer              *buffer)
232 {
233
234         /* Obviously, the structure pointer must be valid */
235
236         if (!buffer) {
237                 return (AE_BAD_PARAMETER);
238         }
239
240         /* Special semantics for the length */
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         /* Length is valid, the buffer pointer must be also */
249
250         if (!buffer->pointer) {
251                 return (AE_BAD_PARAMETER);
252         }
253
254         return (AE_OK);
255 }
256
257
258 /*******************************************************************************
259  *
260  * FUNCTION:    acpi_ut_initialize_buffer
261  *
262  * PARAMETERS:  Buffer              - Buffer to be validated
263  *              required_length     - Length needed
264  *
265  * RETURN:      Status
266  *
267  * DESCRIPTION: Validate that the buffer is of the required length or
268  *              allocate a new buffer.  Returned buffer is always zeroed.
269  *
270  ******************************************************************************/
271
272 acpi_status
273 acpi_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                 /* Set the exception and returned the required length */
284
285                 status = AE_BUFFER_OVERFLOW;
286                 break;
287
288
289         case ACPI_ALLOCATE_BUFFER:
290
291                 /* Allocate a new buffer */
292
293                 buffer->pointer = acpi_os_allocate (required_length);
294                 if (!buffer->pointer) {
295                         return (AE_NO_MEMORY);
296                 }
297
298                 /* Clear the buffer */
299
300                 ACPI_MEMSET (buffer->pointer, 0, required_length);
301                 break;
302
303
304         case ACPI_ALLOCATE_LOCAL_BUFFER:
305
306                 /* Allocate a new buffer with local interface to allow tracking */
307
308                 buffer->pointer = ACPI_MEM_CALLOCATE (required_length);
309                 if (!buffer->pointer) {
310                         return (AE_NO_MEMORY);
311                 }
312                 break;
313
314
315         default:
316
317                 /* Existing buffer: Validate the size of the buffer */
318
319                 if (buffer->length < required_length) {
320                         status = AE_BUFFER_OVERFLOW;
321                         break;
322                 }
323
324                 /* Clear the buffer */
325
326                 ACPI_MEMSET (buffer->pointer, 0, required_length);
327                 break;
328         }
329
330         buffer->length = required_length;
331         return (status);
332 }
333
334
335 /*******************************************************************************
336  *
337  * FUNCTION:    acpi_ut_allocate
338  *
339  * PARAMETERS:  Size                - Size of the allocation
340  *              Component           - Component type of caller
341  *              Module              - Source file name of caller
342  *              Line                - Line number of caller
343  *
344  * RETURN:      Address of the allocated memory on success, NULL on failure.
345  *
346  * DESCRIPTION: The subsystem's equivalent of malloc.
347  *
348  ******************************************************************************/
349
350 void *
351 acpi_ut_allocate (
352         acpi_size                       size,
353         u32                             component,
354         char                            *module,
355         u32                             line)
356 {
357         void                            *allocation;
358
359
360         ACPI_FUNCTION_TRACE_U32 ("ut_allocate", size);
361
362
363         /* Check for an inadvertent size of zero bytes */
364
365         if (!size) {
366                 _ACPI_REPORT_ERROR (module, line, component,
367                                 ("ut_allocate: Attempt to allocate zero bytes\n"));
368                 size = 1;
369         }
370
371         allocation = acpi_os_allocate (size);
372         if (!allocation) {
373                 /* Report allocation error */
374
375                 _ACPI_REPORT_ERROR (module, line, component,
376                                 ("ut_allocate: Could not allocate size %X\n", (u32) size));
377
378                 return_PTR (NULL);
379         }
380
381         return_PTR (allocation);
382 }
383
384
385 /*******************************************************************************
386  *
387  * FUNCTION:    acpi_ut_callocate
388  *
389  * PARAMETERS:  Size                - Size of the allocation
390  *              Component           - Component type of caller
391  *              Module              - Source file name of caller
392  *              Line                - Line number of caller
393  *
394  * RETURN:      Address of the allocated memory on success, NULL on failure.
395  *
396  * DESCRIPTION: Subsystem equivalent of calloc.
397  *
398  ******************************************************************************/
399
400 void *
401 acpi_ut_callocate (
402         acpi_size                       size,
403         u32                             component,
404         char                            *module,
405         u32                             line)
406 {
407         void                            *allocation;
408
409
410         ACPI_FUNCTION_TRACE_U32 ("ut_callocate", size);
411
412
413         /* Check for an inadvertent size of zero bytes */
414
415         if (!size) {
416                 _ACPI_REPORT_ERROR (module, line, component,
417                                 ("ut_callocate: Attempt to allocate zero bytes\n"));
418                 return_PTR (NULL);
419         }
420
421         allocation = acpi_os_allocate (size);
422         if (!allocation) {
423                 /* Report allocation error */
424
425                 _ACPI_REPORT_ERROR (module, line, component,
426                                 ("ut_callocate: Could not allocate size %X\n", (u32) size));
427                 return_PTR (NULL);
428         }
429
430         /* Clear the memory block */
431
432         ACPI_MEMSET (allocation, 0, size);
433         return_PTR (allocation);
434 }
435
436
437 #ifdef ACPI_DBG_TRACK_ALLOCATIONS
438 /*
439  * These procedures are used for tracking memory leaks in the subsystem, and
440  * they get compiled out when the ACPI_DBG_TRACK_ALLOCATIONS is not set.
441  *
442  * Each memory allocation is tracked via a doubly linked list.  Each
443  * element contains the caller's component, module name, function name, and
444  * line number.  acpi_ut_allocate and acpi_ut_callocate call
445  * acpi_ut_track_allocation to add an element to the list; deletion
446  * occurs in the body of acpi_ut_free.
447  */
448
449
450 /*******************************************************************************
451  *
452  * FUNCTION:    acpi_ut_allocate_and_track
453  *
454  * PARAMETERS:  Size                - Size of the allocation
455  *              Component           - Component type of caller
456  *              Module              - Source file name of caller
457  *              Line                - Line number of caller
458  *
459  * RETURN:      Address of the allocated memory on success, NULL on failure.
460  *
461  * DESCRIPTION: The subsystem's equivalent of malloc.
462  *
463  ******************************************************************************/
464
465 void *
466 acpi_ut_allocate_and_track (
467         acpi_size                       size,
468         u32                             component,
469         char                            *module,
470         u32                             line)
471 {
472         struct acpi_debug_mem_block     *allocation;
473         acpi_status                     status;
474
475
476         allocation = acpi_ut_allocate (size + sizeof (struct acpi_debug_mem_header), component,
477                           module, line);
478         if (!allocation) {
479                 return (NULL);
480         }
481
482         status = acpi_ut_track_allocation (ACPI_MEM_LIST_GLOBAL, allocation, size,
483                           ACPI_MEM_MALLOC, component, module, line);
484         if (ACPI_FAILURE (status)) {
485                 acpi_os_free (allocation);
486                 return (NULL);
487         }
488
489         acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].total_allocated++;
490         acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].current_total_size += (u32) size;
491
492         return ((void *) &allocation->user_space);
493 }
494
495
496 /*******************************************************************************
497  *
498  * FUNCTION:    acpi_ut_callocate_and_track
499  *
500  * PARAMETERS:  Size                - Size of the allocation
501  *              Component           - Component type of caller
502  *              Module              - Source file name of caller
503  *              Line                - Line number of caller
504  *
505  * RETURN:      Address of the allocated memory on success, NULL on failure.
506  *
507  * DESCRIPTION: Subsystem equivalent of calloc.
508  *
509  ******************************************************************************/
510
511 void *
512 acpi_ut_callocate_and_track (
513         acpi_size                       size,
514         u32                             component,
515         char                            *module,
516         u32                             line)
517 {
518         struct acpi_debug_mem_block     *allocation;
519         acpi_status                     status;
520
521
522         allocation = acpi_ut_callocate (size + sizeof (struct acpi_debug_mem_header), component,
523                           module, line);
524         if (!allocation) {
525                 /* Report allocation error */
526
527                 _ACPI_REPORT_ERROR (module, line, component,
528                                 ("ut_callocate: Could not allocate size %X\n", (u32) size));
529                 return (NULL);
530         }
531
532         status = acpi_ut_track_allocation (ACPI_MEM_LIST_GLOBAL, allocation, size,
533                            ACPI_MEM_CALLOC, component, module, line);
534         if (ACPI_FAILURE (status)) {
535                 acpi_os_free (allocation);
536                 return (NULL);
537         }
538
539         acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].total_allocated++;
540         acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].current_total_size += (u32) size;
541
542         return ((void *) &allocation->user_space);
543 }
544
545
546 /*******************************************************************************
547  *
548  * FUNCTION:    acpi_ut_free_and_track
549  *
550  * PARAMETERS:  Allocation          - Address of the memory to deallocate
551  *              Component           - Component type of caller
552  *              Module              - Source file name of caller
553  *              Line                - Line number of caller
554  *
555  * RETURN:      None
556  *
557  * DESCRIPTION: Frees the memory at Allocation
558  *
559  ******************************************************************************/
560
561 void
562 acpi_ut_free_and_track (
563         void                            *allocation,
564         u32                             component,
565         char                            *module,
566         u32                             line)
567 {
568         struct acpi_debug_mem_block     *debug_block;
569         acpi_status                     status;
570
571
572         ACPI_FUNCTION_TRACE_PTR ("ut_free", allocation);
573
574
575         if (NULL == allocation) {
576                 _ACPI_REPORT_ERROR (module, line, component,
577                         ("acpi_ut_free: Attempt to delete a NULL address\n"));
578
579                 return_VOID;
580         }
581
582         debug_block = ACPI_CAST_PTR (struct acpi_debug_mem_block,
583                           (((char *) allocation) - sizeof (struct acpi_debug_mem_header)));
584
585         acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].total_freed++;
586         acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].current_total_size -= debug_block->size;
587
588         status = acpi_ut_remove_allocation (ACPI_MEM_LIST_GLOBAL, debug_block,
589                           component, module, line);
590         if (ACPI_FAILURE (status)) {
591                 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not free memory, %s\n",
592                         acpi_format_exception (status)));
593         }
594
595         acpi_os_free (debug_block);
596
597         ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "%p freed\n", allocation));
598
599         return_VOID;
600 }
601
602
603 /*******************************************************************************
604  *
605  * FUNCTION:    acpi_ut_find_allocation
606  *
607  * PARAMETERS:  list_id                 - Memory list to search
608  *              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 struct acpi_debug_mem_block *
617 acpi_ut_find_allocation (
618         u32                             list_id,
619         void                            *allocation)
620 {
621         struct acpi_debug_mem_block     *element;
622
623
624         ACPI_FUNCTION_ENTRY ();
625
626
627         if (list_id > ACPI_MEM_LIST_MAX) {
628                 return (NULL);
629         }
630
631         element = acpi_gbl_memory_lists[list_id].list_head;
632
633         /* Search for the address. */
634
635         while (element) {
636                 if (element == allocation) {
637                         return (element);
638                 }
639
640                 element = element->next;
641         }
642
643         return (NULL);
644 }
645
646
647 /*******************************************************************************
648  *
649  * FUNCTION:    acpi_ut_track_allocation
650  *
651  * PARAMETERS:  list_id             - Memory list to search
652  *              Allocation          - Address of allocated memory
653  *              Size                - Size of the allocation
654  *              alloc_type          - MEM_MALLOC or MEM_CALLOC
655  *              Component           - Component type of caller
656  *              Module              - Source file name of caller
657  *              Line                - Line number of caller
658  *
659  * RETURN:      None.
660  *
661  * DESCRIPTION: Inserts an element into the global allocation tracking list.
662  *
663  ******************************************************************************/
664
665 acpi_status
666 acpi_ut_track_allocation (
667         u32                             list_id,
668         struct acpi_debug_mem_block     *allocation,
669         acpi_size                       size,
670         u8                              alloc_type,
671         u32                             component,
672         char                            *module,
673         u32                             line)
674 {
675         struct acpi_memory_list         *mem_list;
676         struct acpi_debug_mem_block     *element;
677         acpi_status                     status = AE_OK;
678
679
680         ACPI_FUNCTION_TRACE_PTR ("ut_track_allocation", allocation);
681
682
683         if (list_id > ACPI_MEM_LIST_MAX) {
684                 return_ACPI_STATUS (AE_BAD_PARAMETER);
685         }
686
687         mem_list = &acpi_gbl_memory_lists[list_id];
688         status = acpi_ut_acquire_mutex (ACPI_MTX_MEMORY);
689         if (ACPI_FAILURE (status)) {
690                 return_ACPI_STATUS (status);
691         }
692
693         /*
694          * Search list for this address to make sure it is not already on the list.
695          * This will catch several kinds of problems.
696          */
697
698         element = acpi_ut_find_allocation (list_id, allocation);
699         if (element) {
700                 ACPI_REPORT_ERROR (("ut_track_allocation: Allocation already present in list! (%p)\n",
701                         allocation));
702
703                 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Element %p Address %p\n", element, allocation));
704
705                 goto unlock_and_exit;
706         }
707
708         /* Fill in the instance data. */
709
710         allocation->size      = (u32) size;
711         allocation->alloc_type = alloc_type;
712         allocation->component = component;
713         allocation->line      = line;
714
715         ACPI_STRNCPY (allocation->module, module, ACPI_MAX_MODULE_NAME);
716         allocation->module[ACPI_MAX_MODULE_NAME-1] = 0;
717
718         /* Insert at list head */
719
720         if (mem_list->list_head) {
721                 ((struct acpi_debug_mem_block *)(mem_list->list_head))->previous = allocation;
722         }
723
724         allocation->next = mem_list->list_head;
725         allocation->previous = NULL;
726
727         mem_list->list_head = allocation;
728
729
730 unlock_and_exit:
731         status = acpi_ut_release_mutex (ACPI_MTX_MEMORY);
732         return_ACPI_STATUS (status);
733 }
734
735
736 /*******************************************************************************
737  *
738  * FUNCTION:    acpi_ut_remove_allocation
739  *
740  * PARAMETERS:  list_id             - Memory list to search
741  *              Allocation          - Address of allocated memory
742  *              Component           - Component type of caller
743  *              Module              - Source file name of caller
744  *              Line                - Line number of caller
745  *
746  * RETURN:
747  *
748  * DESCRIPTION: Deletes an element from the global allocation tracking list.
749  *
750  ******************************************************************************/
751
752 acpi_status
753 acpi_ut_remove_allocation (
754         u32                             list_id,
755         struct acpi_debug_mem_block     *allocation,
756         u32                             component,
757         char                            *module,
758         u32                             line)
759 {
760         struct acpi_memory_list         *mem_list;
761         acpi_status                     status;
762
763
764         ACPI_FUNCTION_TRACE ("ut_remove_allocation");
765
766
767         if (list_id > ACPI_MEM_LIST_MAX) {
768                 return_ACPI_STATUS (AE_BAD_PARAMETER);
769         }
770
771         mem_list = &acpi_gbl_memory_lists[list_id];
772         if (NULL == mem_list->list_head) {
773                 /* No allocations! */
774
775                 _ACPI_REPORT_ERROR (module, line, component,
776                                 ("ut_remove_allocation: Empty allocation list, nothing to free!\n"));
777
778                 return_ACPI_STATUS (AE_OK);
779         }
780
781         status = acpi_ut_acquire_mutex (ACPI_MTX_MEMORY);
782         if (ACPI_FAILURE (status)) {
783                 return_ACPI_STATUS (status);
784         }
785
786         /* Unlink */
787
788         if (allocation->previous) {
789                 (allocation->previous)->next = allocation->next;
790         }
791         else {
792                 mem_list->list_head = allocation->next;
793         }
794
795         if (allocation->next) {
796                 (allocation->next)->previous = allocation->previous;
797         }
798
799         /* Mark the segment as deleted */
800
801         ACPI_MEMSET (&allocation->user_space, 0xEA, allocation->size);
802
803         ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Freeing size 0%X\n", allocation->size));
804
805         status = acpi_ut_release_mutex (ACPI_MTX_MEMORY);
806         return_ACPI_STATUS (status);
807 }
808
809
810 /*******************************************************************************
811  *
812  * FUNCTION:    acpi_ut_dump_allocation_info
813  *
814  * PARAMETERS:
815  *
816  * RETURN:      None
817  *
818  * DESCRIPTION: Print some info about the outstanding allocations.
819  *
820  ******************************************************************************/
821 #ifdef ACPI_FUTURE_USAGE
822 void
823 acpi_ut_dump_allocation_info (
824         void)
825 {
826 /*
827         struct acpi_memory_list         *mem_list;
828 */
829
830         ACPI_FUNCTION_TRACE ("ut_dump_allocation_info");
831
832 /*
833         ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
834                           ("%30s: %4d (%3d Kb)\n", "Current allocations",
835                           mem_list->current_count,
836                           ROUND_UP_TO_1K (mem_list->current_size)));
837
838         ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
839                           ("%30s: %4d (%3d Kb)\n", "Max concurrent allocations",
840                           mem_list->max_concurrent_count,
841                           ROUND_UP_TO_1K (mem_list->max_concurrent_size)));
842
843
844         ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
845                           ("%30s: %4d (%3d Kb)\n", "Total (all) internal objects",
846                           running_object_count,
847                           ROUND_UP_TO_1K (running_object_size)));
848
849         ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
850                           ("%30s: %4d (%3d Kb)\n", "Total (all) allocations",
851                           running_alloc_count,
852                           ROUND_UP_TO_1K (running_alloc_size)));
853
854
855         ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
856                           ("%30s: %4d (%3d Kb)\n", "Current Nodes",
857                           acpi_gbl_current_node_count,
858                           ROUND_UP_TO_1K (acpi_gbl_current_node_size)));
859
860         ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
861                           ("%30s: %4d (%3d Kb)\n", "Max Nodes",
862                           acpi_gbl_max_concurrent_node_count,
863                           ROUND_UP_TO_1K ((acpi_gbl_max_concurrent_node_count * sizeof (struct acpi_namespace_node)))));
864 */
865         return_VOID;
866 }
867 #endif  /*  ACPI_FUTURE_USAGE  */
868
869
870 /*******************************************************************************
871  *
872  * FUNCTION:    acpi_ut_dump_allocations
873  *
874  * PARAMETERS:  Component           - Component(s) to dump info for.
875  *              Module              - Module to dump info for.  NULL means all.
876  *
877  * RETURN:      None
878  *
879  * DESCRIPTION: Print a list of all outstanding allocations.
880  *
881  ******************************************************************************/
882
883 void
884 acpi_ut_dump_allocations (
885         u32                             component,
886         char                            *module)
887 {
888         struct acpi_debug_mem_block     *element;
889         union acpi_descriptor           *descriptor;
890         u32                             num_outstanding = 0;
891
892
893         ACPI_FUNCTION_TRACE ("ut_dump_allocations");
894
895
896         /*
897          * Walk the allocation list.
898          */
899         if (ACPI_FAILURE (acpi_ut_acquire_mutex (ACPI_MTX_MEMORY))) {
900                 return;
901         }
902
903         element = acpi_gbl_memory_lists[0].list_head;
904         while (element) {
905                 if ((element->component & component) &&
906                         ((module == NULL) || (0 == ACPI_STRCMP (module, element->module)))) {
907                         /* Ignore allocated objects that are in a cache */
908
909                         descriptor = ACPI_CAST_PTR (union acpi_descriptor, &element->user_space);
910                         if (descriptor->descriptor_id != ACPI_DESC_TYPE_CACHED) {
911                                 acpi_os_printf ("%p Len %04X %9.9s-%d [%s] ",
912                                                  descriptor, element->size, element->module,
913                                                  element->line, acpi_ut_get_descriptor_name (descriptor));
914
915                                 /* Most of the elements will be Operand objects. */
916
917                                 switch (ACPI_GET_DESCRIPTOR_TYPE (descriptor)) {
918                                 case ACPI_DESC_TYPE_OPERAND:
919                                         acpi_os_printf ("%12.12s R%hd",
920                                                         acpi_ut_get_type_name (descriptor->object.common.type),
921                                                         descriptor->object.common.reference_count);
922                                         break;
923
924                                 case ACPI_DESC_TYPE_PARSER:
925                                         acpi_os_printf ("aml_opcode %04hX",
926                                                         descriptor->op.asl.aml_opcode);
927                                         break;
928
929                                 case ACPI_DESC_TYPE_NAMED:
930                                         acpi_os_printf ("%4.4s",
931                                                         acpi_ut_get_node_name (&descriptor->node));
932                                         break;
933
934                                 default:
935                                         break;
936                                 }
937
938                                 acpi_os_printf ( "\n");
939                                 num_outstanding++;
940                         }
941                 }
942                 element = element->next;
943         }
944
945         (void) acpi_ut_release_mutex (ACPI_MTX_MEMORY);
946
947         /* Print summary */
948
949         if (!num_outstanding) {
950                 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
951                         "No outstanding allocations.\n"));
952         }
953         else {
954                 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
955                         "%d(%X) Outstanding allocations\n",
956                         num_outstanding, num_outstanding));
957         }
958
959         return_VOID;
960 }
961
962
963 #endif  /* #ifdef ACPI_DBG_TRACK_ALLOCATIONS */
964