ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[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:  required_length     - Length needed
263  *              Buffer              - Buffer to be validated
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:  Allocation             - Address of allocated memory
607  *
608  * RETURN:      A list element if found; NULL otherwise.
609  *
610  * DESCRIPTION: Searches for an element in the global allocation tracking list.
611  *
612  ******************************************************************************/
613
614 struct acpi_debug_mem_block *
615 acpi_ut_find_allocation (
616         u32                             list_id,
617         void                            *allocation)
618 {
619         struct acpi_debug_mem_block     *element;
620
621
622         ACPI_FUNCTION_ENTRY ();
623
624
625         if (list_id > ACPI_MEM_LIST_MAX) {
626                 return (NULL);
627         }
628
629         element = acpi_gbl_memory_lists[list_id].list_head;
630
631         /* Search for the address. */
632
633         while (element) {
634                 if (element == allocation) {
635                         return (element);
636                 }
637
638                 element = element->next;
639         }
640
641         return (NULL);
642 }
643
644
645 /*******************************************************************************
646  *
647  * FUNCTION:    acpi_ut_track_allocation
648  *
649  * PARAMETERS:  Allocation          - Address of allocated memory
650  *              Size                - Size of the allocation
651  *              alloc_type          - MEM_MALLOC or MEM_CALLOC
652  *              Component           - Component type of caller
653  *              Module              - Source file name of caller
654  *              Line                - Line number of caller
655  *
656  * RETURN:      None.
657  *
658  * DESCRIPTION: Inserts an element into the global allocation tracking list.
659  *
660  ******************************************************************************/
661
662 acpi_status
663 acpi_ut_track_allocation (
664         u32                             list_id,
665         struct acpi_debug_mem_block     *allocation,
666         acpi_size                       size,
667         u8                              alloc_type,
668         u32                             component,
669         char                            *module,
670         u32                             line)
671 {
672         struct acpi_memory_list         *mem_list;
673         struct acpi_debug_mem_block     *element;
674         acpi_status                     status = AE_OK;
675
676
677         ACPI_FUNCTION_TRACE_PTR ("ut_track_allocation", allocation);
678
679
680         if (list_id > ACPI_MEM_LIST_MAX) {
681                 return_ACPI_STATUS (AE_BAD_PARAMETER);
682         }
683
684         mem_list = &acpi_gbl_memory_lists[list_id];
685         status = acpi_ut_acquire_mutex (ACPI_MTX_MEMORY);
686         if (ACPI_FAILURE (status)) {
687                 return_ACPI_STATUS (status);
688         }
689
690         /*
691          * Search list for this address to make sure it is not already on the list.
692          * This will catch several kinds of problems.
693          */
694
695         element = acpi_ut_find_allocation (list_id, allocation);
696         if (element) {
697                 ACPI_REPORT_ERROR (("ut_track_allocation: Allocation already present in list! (%p)\n",
698                         allocation));
699
700                 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Element %p Address %p\n", element, allocation));
701
702                 goto unlock_and_exit;
703         }
704
705         /* Fill in the instance data. */
706
707         allocation->size      = (u32) size;
708         allocation->alloc_type = alloc_type;
709         allocation->component = component;
710         allocation->line      = line;
711
712         ACPI_STRNCPY (allocation->module, module, ACPI_MAX_MODULE_NAME);
713
714         /* Insert at list head */
715
716         if (mem_list->list_head) {
717                 ((struct acpi_debug_mem_block *)(mem_list->list_head))->previous = allocation;
718         }
719
720         allocation->next = mem_list->list_head;
721         allocation->previous = NULL;
722
723         mem_list->list_head = allocation;
724
725
726 unlock_and_exit:
727         status = acpi_ut_release_mutex (ACPI_MTX_MEMORY);
728         return_ACPI_STATUS (status);
729 }
730
731
732 /*******************************************************************************
733  *
734  * FUNCTION:    acpi_ut_remove_allocation
735  *
736  * PARAMETERS:  Allocation          - Address of allocated memory
737  *              Component           - Component type of caller
738  *              Module              - Source file name of caller
739  *              Line                - Line number of caller
740  *
741  * RETURN:
742  *
743  * DESCRIPTION: Deletes an element from the global allocation tracking list.
744  *
745  ******************************************************************************/
746
747 acpi_status
748 acpi_ut_remove_allocation (
749         u32                             list_id,
750         struct acpi_debug_mem_block     *allocation,
751         u32                             component,
752         char                            *module,
753         u32                             line)
754 {
755         struct acpi_memory_list         *mem_list;
756         acpi_status                     status;
757
758
759         ACPI_FUNCTION_TRACE ("ut_remove_allocation");
760
761
762         if (list_id > ACPI_MEM_LIST_MAX) {
763                 return_ACPI_STATUS (AE_BAD_PARAMETER);
764         }
765
766         mem_list = &acpi_gbl_memory_lists[list_id];
767         if (NULL == mem_list->list_head) {
768                 /* No allocations! */
769
770                 _ACPI_REPORT_ERROR (module, line, component,
771                                 ("ut_remove_allocation: Empty allocation list, nothing to free!\n"));
772
773                 return_ACPI_STATUS (AE_OK);
774         }
775
776         status = acpi_ut_acquire_mutex (ACPI_MTX_MEMORY);
777         if (ACPI_FAILURE (status)) {
778                 return_ACPI_STATUS (status);
779         }
780
781         /* Unlink */
782
783         if (allocation->previous) {
784                 (allocation->previous)->next = allocation->next;
785         }
786         else {
787                 mem_list->list_head = allocation->next;
788         }
789
790         if (allocation->next) {
791                 (allocation->next)->previous = allocation->previous;
792         }
793
794         /* Mark the segment as deleted */
795
796         ACPI_MEMSET (&allocation->user_space, 0xEA, allocation->size);
797
798         ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Freeing size 0%X\n", allocation->size));
799
800         status = acpi_ut_release_mutex (ACPI_MTX_MEMORY);
801         return_ACPI_STATUS (status);
802 }
803
804
805 /*******************************************************************************
806  *
807  * FUNCTION:    acpi_ut_dump_allocation_info
808  *
809  * PARAMETERS:
810  *
811  * RETURN:      None
812  *
813  * DESCRIPTION: Print some info about the outstanding allocations.
814  *
815  ******************************************************************************/
816
817 void
818 acpi_ut_dump_allocation_info (
819         void)
820 {
821 /*
822         struct acpi_memory_list         *mem_list;
823 */
824
825         ACPI_FUNCTION_TRACE ("ut_dump_allocation_info");
826
827 /*
828         ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
829                           ("%30s: %4d (%3d Kb)\n", "Current allocations",
830                           mem_list->current_count,
831                           ROUND_UP_TO_1K (mem_list->current_size)));
832
833         ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
834                           ("%30s: %4d (%3d Kb)\n", "Max concurrent allocations",
835                           mem_list->max_concurrent_count,
836                           ROUND_UP_TO_1K (mem_list->max_concurrent_size)));
837
838
839         ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
840                           ("%30s: %4d (%3d Kb)\n", "Total (all) internal objects",
841                           running_object_count,
842                           ROUND_UP_TO_1K (running_object_size)));
843
844         ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
845                           ("%30s: %4d (%3d Kb)\n", "Total (all) allocations",
846                           running_alloc_count,
847                           ROUND_UP_TO_1K (running_alloc_size)));
848
849
850         ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
851                           ("%30s: %4d (%3d Kb)\n", "Current Nodes",
852                           acpi_gbl_current_node_count,
853                           ROUND_UP_TO_1K (acpi_gbl_current_node_size)));
854
855         ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
856                           ("%30s: %4d (%3d Kb)\n", "Max Nodes",
857                           acpi_gbl_max_concurrent_node_count,
858                           ROUND_UP_TO_1K ((acpi_gbl_max_concurrent_node_count * sizeof (struct acpi_namespace_node)))));
859 */
860         return_VOID;
861 }
862
863
864 /*******************************************************************************
865  *
866  * FUNCTION:    acpi_ut_dump_allocations
867  *
868  * PARAMETERS:  Component           - Component(s) to dump info for.
869  *              Module              - Module to dump info for.  NULL means all.
870  *
871  * RETURN:      None
872  *
873  * DESCRIPTION: Print a list of all outstanding allocations.
874  *
875  ******************************************************************************/
876
877 void
878 acpi_ut_dump_allocations (
879         u32                             component,
880         char                            *module)
881 {
882         struct acpi_debug_mem_block     *element;
883         union acpi_descriptor           *descriptor;
884         u32                             num_outstanding = 0;
885
886
887         ACPI_FUNCTION_TRACE ("ut_dump_allocations");
888
889
890         /*
891          * Walk the allocation list.
892          */
893         if (ACPI_FAILURE (acpi_ut_acquire_mutex (ACPI_MTX_MEMORY))) {
894                 return;
895         }
896
897         element = acpi_gbl_memory_lists[0].list_head;
898         while (element) {
899                 if ((element->component & component) &&
900                         ((module == NULL) || (0 == ACPI_STRCMP (module, element->module)))) {
901                         /* Ignore allocated objects that are in a cache */
902
903                         descriptor = ACPI_CAST_PTR (union acpi_descriptor, &element->user_space);
904                         if (descriptor->descriptor_id != ACPI_DESC_TYPE_CACHED) {
905                                 acpi_os_printf ("%p Len %04X %9.9s-%d [%s] ",
906                                                  descriptor, element->size, element->module,
907                                                  element->line, acpi_ut_get_descriptor_name (descriptor));
908
909                                 /* Most of the elements will be Operand objects. */
910
911                                 switch (ACPI_GET_DESCRIPTOR_TYPE (descriptor)) {
912                                 case ACPI_DESC_TYPE_OPERAND:
913                                         acpi_os_printf ("%12.12s R%hd",
914                                                         acpi_ut_get_type_name (descriptor->object.common.type),
915                                                         descriptor->object.common.reference_count);
916                                         break;
917
918                                 case ACPI_DESC_TYPE_PARSER:
919                                         acpi_os_printf ("aml_opcode %04hX",
920                                                         descriptor->op.asl.aml_opcode);
921                                         break;
922
923                                 case ACPI_DESC_TYPE_NAMED:
924                                         acpi_os_printf ("%4.4s",
925                                                         acpi_ut_get_node_name (&descriptor->node));
926                                         break;
927
928                                 default:
929                                         break;
930                                 }
931
932                                 acpi_os_printf ( "\n");
933                                 num_outstanding++;
934                         }
935                 }
936                 element = element->next;
937         }
938
939         (void) acpi_ut_release_mutex (ACPI_MTX_MEMORY);
940
941         /* Print summary */
942
943         if (!num_outstanding) {
944                 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
945                         "No outstanding allocations.\n"));
946         }
947         else {
948                 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
949                         "%d(%X) Outstanding allocations\n",
950                         num_outstanding, num_outstanding));
951         }
952
953         return_VOID;
954 }
955
956
957 #endif  /* #ifdef ACPI_DBG_TRACK_ALLOCATIONS */
958