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