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