vserver 1.9.3
[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.
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_ALLOCATE (required_length);
309                 if (!buffer->pointer) {
310                         return (AE_NO_MEMORY);
311                 }
312
313                 /* Clear the buffer */
314
315                 ACPI_MEMSET (buffer->pointer, 0, required_length);
316                 break;
317
318
319         default:
320
321                 /* Validate the size of the buffer */
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  * FUNCTION:    acpi_ut_allocate
337  *
338  * PARAMETERS:  Size                - Size of the allocation
339  *              Component           - Component type of caller
340  *              Module              - Source file name of caller
341  *              Line                - Line number of caller
342  *
343  * RETURN:      Address of the allocated memory on success, NULL on failure.
344  *
345  * DESCRIPTION: The subsystem's equivalent of malloc.
346  *
347  ******************************************************************************/
348
349 void *
350 acpi_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         /* Check for an inadvertent size of zero bytes */
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                 /* Report allocation error */
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  * FUNCTION:    acpi_ut_callocate
387  *
388  * PARAMETERS:  Size                - Size of the allocation
389  *              Component           - Component type of caller
390  *              Module              - Source file name of caller
391  *              Line                - Line number of caller
392  *
393  * RETURN:      Address of the allocated memory on success, NULL on failure.
394  *
395  * DESCRIPTION: Subsystem equivalent of calloc.
396  *
397  ******************************************************************************/
398
399 void *
400 acpi_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         /* Check for an inadvertent size of zero bytes */
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                 /* Report allocation error */
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         /* Clear the memory block */
430
431         ACPI_MEMSET (allocation, 0, size);
432         return_PTR (allocation);
433 }
434
435
436 #ifdef ACPI_DBG_TRACK_ALLOCATIONS
437 /*
438  * These procedures are used for tracking memory leaks in the subsystem, and
439  * they get compiled out when the ACPI_DBG_TRACK_ALLOCATIONS is not set.
440  *
441  * Each memory allocation is tracked via a doubly linked list.  Each
442  * element contains the caller's component, module name, function name, and
443  * line number.  acpi_ut_allocate and acpi_ut_callocate call
444  * acpi_ut_track_allocation to add an element to the list; deletion
445  * occurs in the body of acpi_ut_free.
446  */
447
448
449 /*******************************************************************************
450  *
451  * FUNCTION:    acpi_ut_allocate_and_track
452  *
453  * PARAMETERS:  Size                - Size of the allocation
454  *              Component           - Component type of caller
455  *              Module              - Source file name of caller
456  *              Line                - Line number of caller
457  *
458  * RETURN:      Address of the allocated memory on success, NULL on failure.
459  *
460  * DESCRIPTION: The subsystem's equivalent of malloc.
461  *
462  ******************************************************************************/
463
464 void *
465 acpi_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  * FUNCTION:    acpi_ut_callocate_and_track
498  *
499  * PARAMETERS:  Size                - Size of the allocation
500  *              Component           - Component type of caller
501  *              Module              - Source file name of caller
502  *              Line                - Line number of caller
503  *
504  * RETURN:      Address of the allocated memory on success, NULL on failure.
505  *
506  * DESCRIPTION: Subsystem equivalent of calloc.
507  *
508  ******************************************************************************/
509
510 void *
511 acpi_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                 /* Report allocation error */
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  * FUNCTION:    acpi_ut_free_and_track
548  *
549  * PARAMETERS:  Allocation          - Address of the memory to deallocate
550  *              Component           - Component type of caller
551  *              Module              - Source file name of caller
552  *              Line                - Line number of caller
553  *
554  * RETURN:      None
555  *
556  * DESCRIPTION: Frees the memory at Allocation
557  *
558  ******************************************************************************/
559
560 void
561 acpi_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  * FUNCTION:    acpi_ut_find_allocation
605  *
606  * PARAMETERS:  list_id                 - Memory list to search
607  *              Allocation              - Address of allocated memory
608  *
609  * RETURN:      A list element if found; NULL otherwise.
610  *
611  * DESCRIPTION: Searches for an element in the global allocation tracking list.
612  *
613  ******************************************************************************/
614
615 struct acpi_debug_mem_block *
616 acpi_ut_find_allocation (
617         u32                             list_id,
618         void                            *allocation)
619 {
620         struct acpi_debug_mem_block     *element;
621
622
623         ACPI_FUNCTION_ENTRY ();
624
625
626         if (list_id > ACPI_MEM_LIST_MAX) {
627                 return (NULL);
628         }
629
630         element = acpi_gbl_memory_lists[list_id].list_head;
631
632         /* Search for the address. */
633
634         while (element) {
635                 if (element == allocation) {
636                         return (element);
637                 }
638
639                 element = element->next;
640         }
641
642         return (NULL);
643 }
644
645
646 /*******************************************************************************
647  *
648  * FUNCTION:    acpi_ut_track_allocation
649  *
650  * PARAMETERS:  list_id             - Memory list to search
651  *              Allocation          - Address of allocated memory
652  *              Size                - Size of the allocation
653  *              alloc_type          - MEM_MALLOC or MEM_CALLOC
654  *              Component           - Component type of caller
655  *              Module              - Source file name of caller
656  *              Line                - Line number of caller
657  *
658  * RETURN:      None.
659  *
660  * DESCRIPTION: Inserts an element into the global allocation tracking list.
661  *
662  ******************************************************************************/
663
664 acpi_status
665 acpi_ut_track_allocation (
666         u32                             list_id,
667         struct acpi_debug_mem_block     *allocation,
668         acpi_size                       size,
669         u8                              alloc_type,
670         u32                             component,
671         char                            *module,
672         u32                             line)
673 {
674         struct acpi_memory_list         *mem_list;
675         struct acpi_debug_mem_block     *element;
676         acpi_status                     status = AE_OK;
677
678
679         ACPI_FUNCTION_TRACE_PTR ("ut_track_allocation", allocation);
680
681
682         if (list_id > ACPI_MEM_LIST_MAX) {
683                 return_ACPI_STATUS (AE_BAD_PARAMETER);
684         }
685
686         mem_list = &acpi_gbl_memory_lists[list_id];
687         status = acpi_ut_acquire_mutex (ACPI_MTX_MEMORY);
688         if (ACPI_FAILURE (status)) {
689                 return_ACPI_STATUS (status);
690         }
691
692         /*
693          * Search list for this address to make sure it is not already on the list.
694          * This will catch several kinds of problems.
695          */
696
697         element = acpi_ut_find_allocation (list_id, allocation);
698         if (element) {
699                 ACPI_REPORT_ERROR (("ut_track_allocation: Allocation already present in list! (%p)\n",
700                         allocation));
701
702                 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Element %p Address %p\n", element, allocation));
703
704                 goto unlock_and_exit;
705         }
706
707         /* Fill in the instance data. */
708
709         allocation->size      = (u32) size;
710         allocation->alloc_type = alloc_type;
711         allocation->component = component;
712         allocation->line      = line;
713
714         ACPI_STRNCPY (allocation->module, module, ACPI_MAX_MODULE_NAME);
715
716         /* Insert at list head */
717
718         if (mem_list->list_head) {
719                 ((struct acpi_debug_mem_block *)(mem_list->list_head))->previous = allocation;
720         }
721
722         allocation->next = mem_list->list_head;
723         allocation->previous = NULL;
724
725         mem_list->list_head = allocation;
726
727
728 unlock_and_exit:
729         status = acpi_ut_release_mutex (ACPI_MTX_MEMORY);
730         return_ACPI_STATUS (status);
731 }
732
733
734 /*******************************************************************************
735  *
736  * FUNCTION:    acpi_ut_remove_allocation
737  *
738  * PARAMETERS:  list_id             - Memory list to search
739  *              Allocation          - Address of allocated memory
740  *              Component           - Component type of caller
741  *              Module              - Source file name of caller
742  *              Line                - Line number of caller
743  *
744  * RETURN:
745  *
746  * DESCRIPTION: Deletes an element from the global allocation tracking list.
747  *
748  ******************************************************************************/
749
750 acpi_status
751 acpi_ut_remove_allocation (
752         u32                             list_id,
753         struct acpi_debug_mem_block     *allocation,
754         u32                             component,
755         char                            *module,
756         u32                             line)
757 {
758         struct acpi_memory_list         *mem_list;
759         acpi_status                     status;
760
761
762         ACPI_FUNCTION_TRACE ("ut_remove_allocation");
763
764
765         if (list_id > ACPI_MEM_LIST_MAX) {
766                 return_ACPI_STATUS (AE_BAD_PARAMETER);
767         }
768
769         mem_list = &acpi_gbl_memory_lists[list_id];
770         if (NULL == mem_list->list_head) {
771                 /* No allocations! */
772
773                 _ACPI_REPORT_ERROR (module, line, component,
774                                 ("ut_remove_allocation: Empty allocation list, nothing to free!\n"));
775
776                 return_ACPI_STATUS (AE_OK);
777         }
778
779         status = acpi_ut_acquire_mutex (ACPI_MTX_MEMORY);
780         if (ACPI_FAILURE (status)) {
781                 return_ACPI_STATUS (status);
782         }
783
784         /* Unlink */
785
786         if (allocation->previous) {
787                 (allocation->previous)->next = allocation->next;
788         }
789         else {
790                 mem_list->list_head = allocation->next;
791         }
792
793         if (allocation->next) {
794                 (allocation->next)->previous = allocation->previous;
795         }
796
797         /* Mark the segment as deleted */
798
799         ACPI_MEMSET (&allocation->user_space, 0xEA, allocation->size);
800
801         ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Freeing size 0%X\n", allocation->size));
802
803         status = acpi_ut_release_mutex (ACPI_MTX_MEMORY);
804         return_ACPI_STATUS (status);
805 }
806
807
808 /*******************************************************************************
809  *
810  * FUNCTION:    acpi_ut_dump_allocation_info
811  *
812  * PARAMETERS:
813  *
814  * RETURN:      None
815  *
816  * DESCRIPTION: Print some info about the outstanding allocations.
817  *
818  ******************************************************************************/
819
820 void
821 acpi_ut_dump_allocation_info (
822         void)
823 {
824 /*
825         struct acpi_memory_list         *mem_list;
826 */
827
828         ACPI_FUNCTION_TRACE ("ut_dump_allocation_info");
829
830 /*
831         ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
832                           ("%30s: %4d (%3d Kb)\n", "Current allocations",
833                           mem_list->current_count,
834                           ROUND_UP_TO_1K (mem_list->current_size)));
835
836         ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
837                           ("%30s: %4d (%3d Kb)\n", "Max concurrent allocations",
838                           mem_list->max_concurrent_count,
839                           ROUND_UP_TO_1K (mem_list->max_concurrent_size)));
840
841
842         ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
843                           ("%30s: %4d (%3d Kb)\n", "Total (all) internal objects",
844                           running_object_count,
845                           ROUND_UP_TO_1K (running_object_size)));
846
847         ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
848                           ("%30s: %4d (%3d Kb)\n", "Total (all) allocations",
849                           running_alloc_count,
850                           ROUND_UP_TO_1K (running_alloc_size)));
851
852
853         ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
854                           ("%30s: %4d (%3d Kb)\n", "Current Nodes",
855                           acpi_gbl_current_node_count,
856                           ROUND_UP_TO_1K (acpi_gbl_current_node_size)));
857
858         ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
859                           ("%30s: %4d (%3d Kb)\n", "Max Nodes",
860                           acpi_gbl_max_concurrent_node_count,
861                           ROUND_UP_TO_1K ((acpi_gbl_max_concurrent_node_count * sizeof (struct acpi_namespace_node)))));
862 */
863         return_VOID;
864 }
865
866
867 /*******************************************************************************
868  *
869  * FUNCTION:    acpi_ut_dump_allocations
870  *
871  * PARAMETERS:  Component           - Component(s) to dump info for.
872  *              Module              - Module to dump info for.  NULL means all.
873  *
874  * RETURN:      None
875  *
876  * DESCRIPTION: Print a list of all outstanding allocations.
877  *
878  ******************************************************************************/
879
880 void
881 acpi_ut_dump_allocations (
882         u32                             component,
883         char                            *module)
884 {
885         struct acpi_debug_mem_block     *element;
886         union acpi_descriptor           *descriptor;
887         u32                             num_outstanding = 0;
888
889
890         ACPI_FUNCTION_TRACE ("ut_dump_allocations");
891
892
893         /*
894          * Walk the allocation list.
895          */
896         if (ACPI_FAILURE (acpi_ut_acquire_mutex (ACPI_MTX_MEMORY))) {
897                 return;
898         }
899
900         element = acpi_gbl_memory_lists[0].list_head;
901         while (element) {
902                 if ((element->component & component) &&
903                         ((module == NULL) || (0 == ACPI_STRCMP (module, element->module)))) {
904                         /* Ignore allocated objects that are in a cache */
905
906                         descriptor = ACPI_CAST_PTR (union acpi_descriptor, &element->user_space);
907                         if (descriptor->descriptor_id != ACPI_DESC_TYPE_CACHED) {
908                                 acpi_os_printf ("%p Len %04X %9.9s-%d [%s] ",
909                                                  descriptor, element->size, element->module,
910                                                  element->line, acpi_ut_get_descriptor_name (descriptor));
911
912                                 /* Most of the elements will be Operand objects. */
913
914                                 switch (ACPI_GET_DESCRIPTOR_TYPE (descriptor)) {
915                                 case ACPI_DESC_TYPE_OPERAND:
916                                         acpi_os_printf ("%12.12s R%hd",
917                                                         acpi_ut_get_type_name (descriptor->object.common.type),
918                                                         descriptor->object.common.reference_count);
919                                         break;
920
921                                 case ACPI_DESC_TYPE_PARSER:
922                                         acpi_os_printf ("aml_opcode %04hX",
923                                                         descriptor->op.asl.aml_opcode);
924                                         break;
925
926                                 case ACPI_DESC_TYPE_NAMED:
927                                         acpi_os_printf ("%4.4s",
928                                                         acpi_ut_get_node_name (&descriptor->node));
929                                         break;
930
931                                 default:
932                                         break;
933                                 }
934
935                                 acpi_os_printf ( "\n");
936                                 num_outstanding++;
937                         }
938                 }
939                 element = element->next;
940         }
941
942         (void) acpi_ut_release_mutex (ACPI_MTX_MEMORY);
943
944         /* Print summary */
945
946         if (!num_outstanding) {
947                 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
948                         "No outstanding allocations.\n"));
949         }
950         else {
951                 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
952                         "%d(%X) Outstanding allocations\n",
953                         num_outstanding, num_outstanding));
954         }
955
956         return_VOID;
957 }
958
959
960 #endif  /* #ifdef ACPI_DBG_TRACK_ALLOCATIONS */
961