diff options
Diffstat (limited to 'drivers/acpi/utilities')
-rw-r--r-- | drivers/acpi/utilities/Makefile | 2 | ||||
-rw-r--r-- | drivers/acpi/utilities/utalloc.c | 304 | ||||
-rw-r--r-- | drivers/acpi/utilities/utcache.c | 322 | ||||
-rw-r--r-- | drivers/acpi/utilities/utdebug.c | 4 | ||||
-rw-r--r-- | drivers/acpi/utilities/utglobal.c | 38 | ||||
-rw-r--r-- | drivers/acpi/utilities/utinit.c | 2 | ||||
-rw-r--r-- | drivers/acpi/utilities/utmisc.c | 689 | ||||
-rw-r--r-- | drivers/acpi/utilities/utmutex.c | 380 | ||||
-rw-r--r-- | drivers/acpi/utilities/utobject.c | 34 | ||||
-rw-r--r-- | drivers/acpi/utilities/utstate.c | 376 | ||||
-rw-r--r-- | drivers/acpi/utilities/utxface.c | 23 |
11 files changed, 1221 insertions, 953 deletions
diff --git a/drivers/acpi/utilities/Makefile b/drivers/acpi/utilities/Makefile index 939c447dd52a..e87108b7338a 100644 --- a/drivers/acpi/utilities/Makefile +++ b/drivers/acpi/utilities/Makefile | |||
@@ -3,6 +3,6 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y := utalloc.o utdebug.o uteval.o utinit.o utmisc.o utxface.o \ | 5 | obj-y := utalloc.o utdebug.o uteval.o utinit.o utmisc.o utxface.o \ |
6 | utcopy.o utdelete.o utglobal.o utmath.o utobject.o | 6 | utcopy.o utdelete.o utglobal.o utmath.o utobject.o utstate.o utmutex.o utobject.o utcache.o |
7 | 7 | ||
8 | EXTRA_CFLAGS += $(ACPI_CFLAGS) | 8 | EXTRA_CFLAGS += $(ACPI_CFLAGS) |
diff --git a/drivers/acpi/utilities/utalloc.c b/drivers/acpi/utilities/utalloc.c index c4e7f989a2bd..5061c6f0ee66 100644 --- a/drivers/acpi/utilities/utalloc.c +++ b/drivers/acpi/utilities/utalloc.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Module Name: utalloc - local cache and memory allocation routines | 3 | * Module Name: utalloc - local memory allocation routines |
4 | * | 4 | * |
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
@@ -52,12 +52,10 @@ | |||
52 | #ifdef ACPI_DBG_TRACK_ALLOCATIONS | 52 | #ifdef ACPI_DBG_TRACK_ALLOCATIONS |
53 | static struct acpi_debug_mem_block * | 53 | static struct acpi_debug_mem_block * |
54 | acpi_ut_find_allocation ( | 54 | acpi_ut_find_allocation ( |
55 | u32 list_id, | ||
56 | void *allocation); | 55 | void *allocation); |
57 | 56 | ||
58 | static acpi_status | 57 | static acpi_status |
59 | acpi_ut_track_allocation ( | 58 | acpi_ut_track_allocation ( |
60 | u32 list_id, | ||
61 | struct acpi_debug_mem_block *address, | 59 | struct acpi_debug_mem_block *address, |
62 | acpi_size size, | 60 | acpi_size size, |
63 | u8 alloc_type, | 61 | u8 alloc_type, |
@@ -67,206 +65,118 @@ acpi_ut_track_allocation ( | |||
67 | 65 | ||
68 | static acpi_status | 66 | static acpi_status |
69 | acpi_ut_remove_allocation ( | 67 | acpi_ut_remove_allocation ( |
70 | u32 list_id, | ||
71 | struct acpi_debug_mem_block *address, | 68 | struct acpi_debug_mem_block *address, |
72 | u32 component, | 69 | u32 component, |
73 | char *module, | 70 | char *module, |
74 | u32 line); | 71 | u32 line); |
75 | #endif /* ACPI_DBG_TRACK_ALLOCATIONS */ | 72 | #endif /* ACPI_DBG_TRACK_ALLOCATIONS */ |
76 | 73 | ||
77 | 74 | #ifdef ACPI_DBG_TRACK_ALLOCATIONS | |
78 | /******************************************************************************* | 75 | static acpi_status |
79 | * | 76 | acpi_ut_create_list ( |
80 | * FUNCTION: acpi_ut_release_to_cache | 77 | char *list_name, |
81 | * | 78 | u16 object_size, |
82 | * PARAMETERS: list_id - Memory list/cache ID | 79 | acpi_handle *return_cache); |
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 | 80 | #endif |
143 | } | ||
144 | 81 | ||
145 | 82 | ||
146 | /******************************************************************************* | 83 | /******************************************************************************* |
147 | * | 84 | * |
148 | * FUNCTION: acpi_ut_acquire_from_cache | 85 | * FUNCTION: acpi_ut_create_caches |
149 | * | 86 | * |
150 | * PARAMETERS: list_id - Memory list ID | 87 | * PARAMETERS: None |
151 | * | 88 | * |
152 | * RETURN: A requested object. NULL if the object could not be | 89 | * RETURN: Status |
153 | * allocated. | ||
154 | * | 90 | * |
155 | * DESCRIPTION: Get an object from the specified cache. If cache is empty, | 91 | * DESCRIPTION: Create all local caches |
156 | * the object is allocated. | ||
157 | * | 92 | * |
158 | ******************************************************************************/ | 93 | ******************************************************************************/ |
159 | 94 | ||
160 | void * | 95 | acpi_status |
161 | acpi_ut_acquire_from_cache ( | 96 | acpi_ut_create_caches ( |
162 | u32 list_id) | 97 | void) |
163 | { | 98 | { |
164 | struct acpi_memory_list *cache_info; | 99 | acpi_status status; |
165 | void *object; | ||
166 | |||
167 | |||
168 | ACPI_FUNCTION_NAME ("ut_acquire_from_cache"); | ||
169 | 100 | ||
170 | 101 | ||
171 | cache_info = &acpi_gbl_memory_lists[list_id]; | 102 | #ifdef ACPI_DBG_TRACK_ALLOCATIONS |
172 | 103 | ||
173 | #ifdef ACPI_ENABLE_OBJECT_CACHE | 104 | /* Memory allocation lists */ |
174 | 105 | ||
175 | if (ACPI_FAILURE (acpi_ut_acquire_mutex (ACPI_MTX_CACHES))) { | 106 | status = acpi_ut_create_list ("Acpi-Global", 0, |
176 | return (NULL); | 107 | &acpi_gbl_global_list); |
108 | if (ACPI_FAILURE (status)) { | ||
109 | return (status); | ||
177 | } | 110 | } |
178 | 111 | ||
179 | ACPI_MEM_TRACKING (cache_info->cache_requests++); | 112 | status = acpi_ut_create_list ("Acpi-Namespace", sizeof (struct acpi_namespace_node), |
180 | 113 | &acpi_gbl_ns_node_list); | |
181 | /* Check the cache first */ | 114 | if (ACPI_FAILURE (status)) { |
182 | 115 | return (status); | |
183 | if (cache_info->list_head) { | 116 | } |
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 | 117 | #endif |
197 | 118 | ||
198 | if (ACPI_FAILURE (acpi_ut_release_mutex (ACPI_MTX_CACHES))) { | 119 | /* Object Caches, for frequently used objects */ |
199 | return (NULL); | ||
200 | } | ||
201 | |||
202 | /* Clear (zero) the previously used Object */ | ||
203 | 120 | ||
204 | ACPI_MEMSET (object, 0, cache_info->object_size); | 121 | status = acpi_os_create_cache ("acpi_state", sizeof (union acpi_generic_state), |
122 | ACPI_MAX_STATE_CACHE_DEPTH, &acpi_gbl_state_cache); | ||
123 | if (ACPI_FAILURE (status)) { | ||
124 | return (status); | ||
205 | } | 125 | } |
206 | 126 | ||
207 | else { | 127 | status = acpi_os_create_cache ("acpi_parse", sizeof (struct acpi_parse_obj_common), |
208 | /* The cache is empty, create a new object */ | 128 | ACPI_MAX_PARSE_CACHE_DEPTH, &acpi_gbl_ps_node_cache); |
209 | 129 | if (ACPI_FAILURE (status)) { | |
210 | /* Avoid deadlock with ACPI_MEM_CALLOCATE */ | 130 | return (status); |
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 | } | 131 | } |
219 | 132 | ||
220 | #else | 133 | status = acpi_os_create_cache ("acpi_parse_ext", sizeof (struct acpi_parse_obj_named), |
221 | 134 | ACPI_MAX_EXTPARSE_CACHE_DEPTH, &acpi_gbl_ps_node_ext_cache); | |
222 | /* Object cache is disabled; just allocate the object */ | 135 | if (ACPI_FAILURE (status)) { |
136 | return (status); | ||
137 | } | ||
223 | 138 | ||
224 | object = ACPI_MEM_CALLOCATE (cache_info->object_size); | 139 | status = acpi_os_create_cache ("acpi_operand", sizeof (union acpi_operand_object), |
225 | ACPI_MEM_TRACKING (cache_info->total_allocated++); | 140 | ACPI_MAX_OBJECT_CACHE_DEPTH, &acpi_gbl_operand_cache); |
226 | #endif | 141 | if (ACPI_FAILURE (status)) { |
142 | return (status); | ||
143 | } | ||
227 | 144 | ||
228 | return (object); | 145 | return (AE_OK); |
229 | } | 146 | } |
230 | 147 | ||
231 | 148 | ||
232 | #ifdef ACPI_ENABLE_OBJECT_CACHE | ||
233 | /******************************************************************************* | 149 | /******************************************************************************* |
234 | * | 150 | * |
235 | * FUNCTION: acpi_ut_delete_generic_cache | 151 | * FUNCTION: acpi_ut_delete_caches |
236 | * | 152 | * |
237 | * PARAMETERS: list_id - Memory list ID | 153 | * PARAMETERS: None |
238 | * | 154 | * |
239 | * RETURN: None | 155 | * RETURN: Status |
240 | * | 156 | * |
241 | * DESCRIPTION: Free all objects within the requested cache. | 157 | * DESCRIPTION: Purge and delete all local caches |
242 | * | 158 | * |
243 | ******************************************************************************/ | 159 | ******************************************************************************/ |
244 | 160 | ||
245 | void | 161 | acpi_status |
246 | acpi_ut_delete_generic_cache ( | 162 | acpi_ut_delete_caches ( |
247 | u32 list_id) | 163 | void) |
248 | { | 164 | { |
249 | struct acpi_memory_list *cache_info; | ||
250 | char *next; | ||
251 | 165 | ||
166 | (void) acpi_os_delete_cache (acpi_gbl_state_cache); | ||
167 | acpi_gbl_state_cache = NULL; | ||
252 | 168 | ||
253 | ACPI_FUNCTION_ENTRY (); | 169 | (void) acpi_os_delete_cache (acpi_gbl_operand_cache); |
254 | 170 | acpi_gbl_operand_cache = NULL; | |
255 | 171 | ||
256 | cache_info = &acpi_gbl_memory_lists[list_id]; | 172 | (void) acpi_os_delete_cache (acpi_gbl_ps_node_cache); |
257 | while (cache_info->list_head) { | 173 | acpi_gbl_ps_node_cache = NULL; |
258 | /* Delete one cached state object */ | ||
259 | 174 | ||
260 | next = *(ACPI_CAST_INDIRECT_PTR (char, | 175 | (void) acpi_os_delete_cache (acpi_gbl_ps_node_ext_cache); |
261 | &(((char *) cache_info->list_head)[cache_info->link_offset]))); | 176 | acpi_gbl_ps_node_ext_cache = NULL; |
262 | ACPI_MEM_FREE (cache_info->list_head); | ||
263 | 177 | ||
264 | cache_info->list_head = next; | 178 | return (AE_OK); |
265 | cache_info->cache_depth--; | ||
266 | } | ||
267 | } | 179 | } |
268 | #endif | ||
269 | |||
270 | 180 | ||
271 | /******************************************************************************* | 181 | /******************************************************************************* |
272 | * | 182 | * |
@@ -500,6 +410,43 @@ acpi_ut_callocate ( | |||
500 | * occurs in the body of acpi_ut_free. | 410 | * occurs in the body of acpi_ut_free. |
501 | */ | 411 | */ |
502 | 412 | ||
413 | /******************************************************************************* | ||
414 | * | ||
415 | * FUNCTION: acpi_ut_create_list | ||
416 | * | ||
417 | * PARAMETERS: cache_name - Ascii name for the cache | ||
418 | * object_size - Size of each cached object | ||
419 | * return_cache - Where the new cache object is returned | ||
420 | * | ||
421 | * RETURN: Status | ||
422 | * | ||
423 | * DESCRIPTION: Create a local memory list for tracking purposed | ||
424 | * | ||
425 | ******************************************************************************/ | ||
426 | |||
427 | static acpi_status | ||
428 | acpi_ut_create_list ( | ||
429 | char *list_name, | ||
430 | u16 object_size, | ||
431 | acpi_handle *return_cache) | ||
432 | { | ||
433 | struct acpi_memory_list *cache; | ||
434 | |||
435 | |||
436 | cache = acpi_os_allocate (sizeof (struct acpi_memory_list)); | ||
437 | if (!cache) { | ||
438 | return (AE_NO_MEMORY); | ||
439 | } | ||
440 | |||
441 | ACPI_MEMSET (cache, 0, sizeof (struct acpi_memory_list)); | ||
442 | |||
443 | cache->list_name = list_name; | ||
444 | cache->object_size = object_size; | ||
445 | |||
446 | *return_cache = cache; | ||
447 | return (AE_OK); | ||
448 | } | ||
449 | |||
503 | 450 | ||
504 | /******************************************************************************* | 451 | /******************************************************************************* |
505 | * | 452 | * |
@@ -533,15 +480,15 @@ acpi_ut_allocate_and_track ( | |||
533 | return (NULL); | 480 | return (NULL); |
534 | } | 481 | } |
535 | 482 | ||
536 | status = acpi_ut_track_allocation (ACPI_MEM_LIST_GLOBAL, allocation, size, | 483 | status = acpi_ut_track_allocation (allocation, size, |
537 | ACPI_MEM_MALLOC, component, module, line); | 484 | ACPI_MEM_MALLOC, component, module, line); |
538 | if (ACPI_FAILURE (status)) { | 485 | if (ACPI_FAILURE (status)) { |
539 | acpi_os_free (allocation); | 486 | acpi_os_free (allocation); |
540 | return (NULL); | 487 | return (NULL); |
541 | } | 488 | } |
542 | 489 | ||
543 | acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].total_allocated++; | 490 | acpi_gbl_global_list->total_allocated++; |
544 | acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].current_total_size += (u32) size; | 491 | acpi_gbl_global_list->current_total_size += (u32) size; |
545 | 492 | ||
546 | return ((void *) &allocation->user_space); | 493 | return ((void *) &allocation->user_space); |
547 | } | 494 | } |
@@ -583,15 +530,15 @@ acpi_ut_callocate_and_track ( | |||
583 | return (NULL); | 530 | return (NULL); |
584 | } | 531 | } |
585 | 532 | ||
586 | status = acpi_ut_track_allocation (ACPI_MEM_LIST_GLOBAL, allocation, size, | 533 | status = acpi_ut_track_allocation (allocation, size, |
587 | ACPI_MEM_CALLOC, component, module, line); | 534 | ACPI_MEM_CALLOC, component, module, line); |
588 | if (ACPI_FAILURE (status)) { | 535 | if (ACPI_FAILURE (status)) { |
589 | acpi_os_free (allocation); | 536 | acpi_os_free (allocation); |
590 | return (NULL); | 537 | return (NULL); |
591 | } | 538 | } |
592 | 539 | ||
593 | acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].total_allocated++; | 540 | acpi_gbl_global_list->total_allocated++; |
594 | acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].current_total_size += (u32) size; | 541 | acpi_gbl_global_list->current_total_size += (u32) size; |
595 | 542 | ||
596 | return ((void *) &allocation->user_space); | 543 | return ((void *) &allocation->user_space); |
597 | } | 544 | } |
@@ -636,10 +583,10 @@ acpi_ut_free_and_track ( | |||
636 | debug_block = ACPI_CAST_PTR (struct acpi_debug_mem_block, | 583 | debug_block = ACPI_CAST_PTR (struct acpi_debug_mem_block, |
637 | (((char *) allocation) - sizeof (struct acpi_debug_mem_header))); | 584 | (((char *) allocation) - sizeof (struct acpi_debug_mem_header))); |
638 | 585 | ||
639 | acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].total_freed++; | 586 | acpi_gbl_global_list->total_freed++; |
640 | acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].current_total_size -= debug_block->size; | 587 | acpi_gbl_global_list->current_total_size -= debug_block->size; |
641 | 588 | ||
642 | status = acpi_ut_remove_allocation (ACPI_MEM_LIST_GLOBAL, debug_block, | 589 | status = acpi_ut_remove_allocation (debug_block, |
643 | component, module, line); | 590 | component, module, line); |
644 | if (ACPI_FAILURE (status)) { | 591 | if (ACPI_FAILURE (status)) { |
645 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not free memory, %s\n", | 592 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not free memory, %s\n", |
@@ -658,8 +605,7 @@ acpi_ut_free_and_track ( | |||
658 | * | 605 | * |
659 | * FUNCTION: acpi_ut_find_allocation | 606 | * FUNCTION: acpi_ut_find_allocation |
660 | * | 607 | * |
661 | * PARAMETERS: list_id - Memory list to search | 608 | * PARAMETERS: Allocation - Address of allocated memory |
662 | * Allocation - Address of allocated memory | ||
663 | * | 609 | * |
664 | * RETURN: A list element if found; NULL otherwise. | 610 | * RETURN: A list element if found; NULL otherwise. |
665 | * | 611 | * |
@@ -669,7 +615,6 @@ acpi_ut_free_and_track ( | |||
669 | 615 | ||
670 | static struct acpi_debug_mem_block * | 616 | static struct acpi_debug_mem_block * |
671 | acpi_ut_find_allocation ( | 617 | acpi_ut_find_allocation ( |
672 | u32 list_id, | ||
673 | void *allocation) | 618 | void *allocation) |
674 | { | 619 | { |
675 | struct acpi_debug_mem_block *element; | 620 | struct acpi_debug_mem_block *element; |
@@ -678,11 +623,7 @@ acpi_ut_find_allocation ( | |||
678 | ACPI_FUNCTION_ENTRY (); | 623 | ACPI_FUNCTION_ENTRY (); |
679 | 624 | ||
680 | 625 | ||
681 | if (list_id > ACPI_MEM_LIST_MAX) { | 626 | element = acpi_gbl_global_list->list_head; |
682 | return (NULL); | ||
683 | } | ||
684 | |||
685 | element = acpi_gbl_memory_lists[list_id].list_head; | ||
686 | 627 | ||
687 | /* Search for the address. */ | 628 | /* Search for the address. */ |
688 | 629 | ||
@@ -702,8 +643,7 @@ acpi_ut_find_allocation ( | |||
702 | * | 643 | * |
703 | * FUNCTION: acpi_ut_track_allocation | 644 | * FUNCTION: acpi_ut_track_allocation |
704 | * | 645 | * |
705 | * PARAMETERS: list_id - Memory list to search | 646 | * PARAMETERS: Allocation - Address of allocated memory |
706 | * Allocation - Address of allocated memory | ||
707 | * Size - Size of the allocation | 647 | * Size - Size of the allocation |
708 | * alloc_type - MEM_MALLOC or MEM_CALLOC | 648 | * alloc_type - MEM_MALLOC or MEM_CALLOC |
709 | * Component - Component type of caller | 649 | * Component - Component type of caller |
@@ -718,7 +658,6 @@ acpi_ut_find_allocation ( | |||
718 | 658 | ||
719 | static acpi_status | 659 | static acpi_status |
720 | acpi_ut_track_allocation ( | 660 | acpi_ut_track_allocation ( |
721 | u32 list_id, | ||
722 | struct acpi_debug_mem_block *allocation, | 661 | struct acpi_debug_mem_block *allocation, |
723 | acpi_size size, | 662 | acpi_size size, |
724 | u8 alloc_type, | 663 | u8 alloc_type, |
@@ -734,11 +673,7 @@ acpi_ut_track_allocation ( | |||
734 | ACPI_FUNCTION_TRACE_PTR ("ut_track_allocation", allocation); | 673 | ACPI_FUNCTION_TRACE_PTR ("ut_track_allocation", allocation); |
735 | 674 | ||
736 | 675 | ||
737 | if (list_id > ACPI_MEM_LIST_MAX) { | 676 | mem_list = acpi_gbl_global_list; |
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); | 677 | status = acpi_ut_acquire_mutex (ACPI_MTX_MEMORY); |
743 | if (ACPI_FAILURE (status)) { | 678 | if (ACPI_FAILURE (status)) { |
744 | return_ACPI_STATUS (status); | 679 | return_ACPI_STATUS (status); |
@@ -748,8 +683,7 @@ acpi_ut_track_allocation ( | |||
748 | * Search list for this address to make sure it is not already on the list. | 683 | * Search list for this address to make sure it is not already on the list. |
749 | * This will catch several kinds of problems. | 684 | * This will catch several kinds of problems. |
750 | */ | 685 | */ |
751 | 686 | element = acpi_ut_find_allocation (allocation); | |
752 | element = acpi_ut_find_allocation (list_id, allocation); | ||
753 | if (element) { | 687 | if (element) { |
754 | ACPI_REPORT_ERROR (( | 688 | ACPI_REPORT_ERROR (( |
755 | "ut_track_allocation: Allocation already present in list! (%p)\n", | 689 | "ut_track_allocation: Allocation already present in list! (%p)\n", |
@@ -793,8 +727,7 @@ unlock_and_exit: | |||
793 | * | 727 | * |
794 | * FUNCTION: acpi_ut_remove_allocation | 728 | * FUNCTION: acpi_ut_remove_allocation |
795 | * | 729 | * |
796 | * PARAMETERS: list_id - Memory list to search | 730 | * PARAMETERS: Allocation - Address of allocated memory |
797 | * Allocation - Address of allocated memory | ||
798 | * Component - Component type of caller | 731 | * Component - Component type of caller |
799 | * Module - Source file name of caller | 732 | * Module - Source file name of caller |
800 | * Line - Line number of caller | 733 | * Line - Line number of caller |
@@ -807,7 +740,6 @@ unlock_and_exit: | |||
807 | 740 | ||
808 | static acpi_status | 741 | static acpi_status |
809 | acpi_ut_remove_allocation ( | 742 | acpi_ut_remove_allocation ( |
810 | u32 list_id, | ||
811 | struct acpi_debug_mem_block *allocation, | 743 | struct acpi_debug_mem_block *allocation, |
812 | u32 component, | 744 | u32 component, |
813 | char *module, | 745 | char *module, |
@@ -820,11 +752,7 @@ acpi_ut_remove_allocation ( | |||
820 | ACPI_FUNCTION_TRACE ("ut_remove_allocation"); | 752 | ACPI_FUNCTION_TRACE ("ut_remove_allocation"); |
821 | 753 | ||
822 | 754 | ||
823 | if (list_id > ACPI_MEM_LIST_MAX) { | 755 | mem_list = acpi_gbl_global_list; |
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) { | 756 | if (NULL == mem_list->list_head) { |
829 | /* No allocations! */ | 757 | /* No allocations! */ |
830 | 758 | ||
@@ -959,7 +887,7 @@ acpi_ut_dump_allocations ( | |||
959 | return; | 887 | return; |
960 | } | 888 | } |
961 | 889 | ||
962 | element = acpi_gbl_memory_lists[0].list_head; | 890 | element = acpi_gbl_global_list->list_head; |
963 | while (element) { | 891 | while (element) { |
964 | if ((element->component & component) && | 892 | if ((element->component & component) && |
965 | ((module == NULL) || (0 == ACPI_STRCMP (module, element->module)))) { | 893 | ((module == NULL) || (0 == ACPI_STRCMP (module, element->module)))) { |
diff --git a/drivers/acpi/utilities/utcache.c b/drivers/acpi/utilities/utcache.c new file mode 100644 index 000000000000..07588812e72d --- /dev/null +++ b/drivers/acpi/utilities/utcache.c | |||
@@ -0,0 +1,322 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Module Name: utcache - local cache 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 ("utcache") | ||
49 | |||
50 | |||
51 | #ifdef ACPI_USE_LOCAL_CACHE | ||
52 | /******************************************************************************* | ||
53 | * | ||
54 | * FUNCTION: acpi_os_create_cache | ||
55 | * | ||
56 | * PARAMETERS: cache_name - Ascii name for the cache | ||
57 | * object_size - Size of each cached object | ||
58 | * max_depth - Maximum depth of the cache (in objects) | ||
59 | * return_cache - Where the new cache object is returned | ||
60 | * | ||
61 | * RETURN: Status | ||
62 | * | ||
63 | * DESCRIPTION: Create a cache object | ||
64 | * | ||
65 | ******************************************************************************/ | ||
66 | |||
67 | acpi_status | ||
68 | acpi_os_create_cache ( | ||
69 | char *cache_name, | ||
70 | u16 object_size, | ||
71 | u16 max_depth, | ||
72 | struct acpi_memory_list **return_cache) | ||
73 | { | ||
74 | struct acpi_memory_list *cache; | ||
75 | |||
76 | |||
77 | if (!cache_name || !return_cache || (object_size < 16)) { | ||
78 | return (AE_BAD_PARAMETER); | ||
79 | } | ||
80 | |||
81 | /* Create the cache object */ | ||
82 | |||
83 | cache = acpi_os_allocate (sizeof (struct acpi_memory_list)); | ||
84 | if (!cache) { | ||
85 | return (AE_NO_MEMORY); | ||
86 | } | ||
87 | |||
88 | /* Populate the cache object and return it */ | ||
89 | |||
90 | ACPI_MEMSET (cache, 0, sizeof (struct acpi_memory_list)); | ||
91 | cache->link_offset = 8; | ||
92 | cache->list_name = cache_name; | ||
93 | cache->object_size = object_size; | ||
94 | cache->max_depth = max_depth; | ||
95 | |||
96 | *return_cache = cache; | ||
97 | return (AE_OK); | ||
98 | } | ||
99 | |||
100 | |||
101 | /******************************************************************************* | ||
102 | * | ||
103 | * FUNCTION: acpi_os_purge_cache | ||
104 | * | ||
105 | * PARAMETERS: Cache - Handle to cache object | ||
106 | * | ||
107 | * RETURN: Status | ||
108 | * | ||
109 | * DESCRIPTION: Free all objects within the requested cache. | ||
110 | * | ||
111 | ******************************************************************************/ | ||
112 | |||
113 | acpi_status | ||
114 | acpi_os_purge_cache ( | ||
115 | struct acpi_memory_list *cache) | ||
116 | { | ||
117 | char *next; | ||
118 | |||
119 | |||
120 | ACPI_FUNCTION_ENTRY (); | ||
121 | |||
122 | |||
123 | if (!cache) { | ||
124 | return (AE_BAD_PARAMETER); | ||
125 | } | ||
126 | |||
127 | /* Walk the list of objects in this cache */ | ||
128 | |||
129 | while (cache->list_head) { | ||
130 | /* Delete and unlink one cached state object */ | ||
131 | |||
132 | next = *(ACPI_CAST_INDIRECT_PTR (char, | ||
133 | &(((char *) cache->list_head)[cache->link_offset]))); | ||
134 | ACPI_MEM_FREE (cache->list_head); | ||
135 | |||
136 | cache->list_head = next; | ||
137 | cache->current_depth--; | ||
138 | } | ||
139 | |||
140 | return (AE_OK); | ||
141 | } | ||
142 | |||
143 | |||
144 | /******************************************************************************* | ||
145 | * | ||
146 | * FUNCTION: acpi_os_delete_cache | ||
147 | * | ||
148 | * PARAMETERS: Cache - Handle to cache object | ||
149 | * | ||
150 | * RETURN: Status | ||
151 | * | ||
152 | * DESCRIPTION: Free all objects within the requested cache and delete the | ||
153 | * cache object. | ||
154 | * | ||
155 | ******************************************************************************/ | ||
156 | |||
157 | acpi_status | ||
158 | acpi_os_delete_cache ( | ||
159 | struct acpi_memory_list *cache) | ||
160 | { | ||
161 | acpi_status status; | ||
162 | |||
163 | |||
164 | /* Purge all objects in the cache */ | ||
165 | |||
166 | status = acpi_os_purge_cache (cache); | ||
167 | if (ACPI_FAILURE (status)) { | ||
168 | return (status); | ||
169 | } | ||
170 | |||
171 | /* Now we can delete the cache object */ | ||
172 | |||
173 | acpi_os_free (cache); | ||
174 | return (AE_OK); | ||
175 | } | ||
176 | |||
177 | |||
178 | /******************************************************************************* | ||
179 | * | ||
180 | * FUNCTION: acpi_os_release_object | ||
181 | * | ||
182 | * PARAMETERS: Cache - Handle to cache object | ||
183 | * Object - The object to be released | ||
184 | * | ||
185 | * RETURN: None | ||
186 | * | ||
187 | * DESCRIPTION: Release an object to the specified cache. If cache is full, | ||
188 | * the object is deleted. | ||
189 | * | ||
190 | ******************************************************************************/ | ||
191 | |||
192 | acpi_status | ||
193 | acpi_os_release_object ( | ||
194 | struct acpi_memory_list *cache, | ||
195 | void *object) | ||
196 | { | ||
197 | acpi_status status; | ||
198 | |||
199 | |||
200 | ACPI_FUNCTION_ENTRY (); | ||
201 | |||
202 | |||
203 | if (!cache || !object) { | ||
204 | return (AE_BAD_PARAMETER); | ||
205 | } | ||
206 | |||
207 | /* If cache is full, just free this object */ | ||
208 | |||
209 | if (cache->current_depth >= cache->max_depth) { | ||
210 | ACPI_MEM_FREE (object); | ||
211 | ACPI_MEM_TRACKING (cache->total_freed++); | ||
212 | } | ||
213 | |||
214 | /* Otherwise put this object back into the cache */ | ||
215 | |||
216 | else { | ||
217 | status = acpi_ut_acquire_mutex (ACPI_MTX_CACHES); | ||
218 | if (ACPI_FAILURE (status)) { | ||
219 | return (status); | ||
220 | } | ||
221 | |||
222 | /* Mark the object as cached */ | ||
223 | |||
224 | ACPI_MEMSET (object, 0xCA, cache->object_size); | ||
225 | ACPI_SET_DESCRIPTOR_TYPE (object, ACPI_DESC_TYPE_CACHED); | ||
226 | |||
227 | /* Put the object at the head of the cache list */ | ||
228 | |||
229 | * (ACPI_CAST_INDIRECT_PTR (char, | ||
230 | &(((char *) object)[cache->link_offset]))) = cache->list_head; | ||
231 | cache->list_head = object; | ||
232 | cache->current_depth++; | ||
233 | |||
234 | (void) acpi_ut_release_mutex (ACPI_MTX_CACHES); | ||
235 | } | ||
236 | |||
237 | return (AE_OK); | ||
238 | } | ||
239 | |||
240 | |||
241 | /******************************************************************************* | ||
242 | * | ||
243 | * FUNCTION: acpi_os_acquire_object | ||
244 | * | ||
245 | * PARAMETERS: Cache - Handle to cache object | ||
246 | * | ||
247 | * RETURN: the acquired object. NULL on error | ||
248 | * | ||
249 | * DESCRIPTION: Get an object from the specified cache. If cache is empty, | ||
250 | * the object is allocated. | ||
251 | * | ||
252 | ******************************************************************************/ | ||
253 | |||
254 | void * | ||
255 | acpi_os_acquire_object ( | ||
256 | struct acpi_memory_list *cache) | ||
257 | { | ||
258 | acpi_status status; | ||
259 | void *object; | ||
260 | |||
261 | |||
262 | ACPI_FUNCTION_NAME ("ut_acquire_from_cache"); | ||
263 | |||
264 | |||
265 | if (!cache) { | ||
266 | return (NULL); | ||
267 | } | ||
268 | |||
269 | status = acpi_ut_acquire_mutex (ACPI_MTX_CACHES); | ||
270 | if (ACPI_FAILURE (status)) { | ||
271 | return (NULL); | ||
272 | } | ||
273 | |||
274 | ACPI_MEM_TRACKING (cache->requests++); | ||
275 | |||
276 | /* Check the cache first */ | ||
277 | |||
278 | if (cache->list_head) { | ||
279 | /* There is an object available, use it */ | ||
280 | |||
281 | object = cache->list_head; | ||
282 | cache->list_head = *(ACPI_CAST_INDIRECT_PTR (char, | ||
283 | &(((char *) object)[cache->link_offset]))); | ||
284 | |||
285 | cache->current_depth--; | ||
286 | |||
287 | ACPI_MEM_TRACKING (cache->hits++); | ||
288 | ACPI_MEM_TRACKING (ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, | ||
289 | "Object %p from %s\n", object, cache->list_name))); | ||
290 | |||
291 | status = acpi_ut_release_mutex (ACPI_MTX_CACHES); | ||
292 | if (ACPI_FAILURE (status)) { | ||
293 | return (NULL); | ||
294 | } | ||
295 | |||
296 | /* Clear (zero) the previously used Object */ | ||
297 | |||
298 | ACPI_MEMSET (object, 0, cache->object_size); | ||
299 | } | ||
300 | else { | ||
301 | /* The cache is empty, create a new object */ | ||
302 | |||
303 | ACPI_MEM_TRACKING (cache->total_allocated++); | ||
304 | |||
305 | /* Avoid deadlock with ACPI_MEM_CALLOCATE */ | ||
306 | |||
307 | status = acpi_ut_release_mutex (ACPI_MTX_CACHES); | ||
308 | if (ACPI_FAILURE (status)) { | ||
309 | return (NULL); | ||
310 | } | ||
311 | |||
312 | object = ACPI_MEM_CALLOCATE (cache->object_size); | ||
313 | if (!object) { | ||
314 | return (NULL); | ||
315 | } | ||
316 | } | ||
317 | |||
318 | return (object); | ||
319 | } | ||
320 | #endif /* ACPI_USE_LOCAL_CACHE */ | ||
321 | |||
322 | |||
diff --git a/drivers/acpi/utilities/utdebug.c b/drivers/acpi/utilities/utdebug.c index 794c7df3f2ad..08362f686ec1 100644 --- a/drivers/acpi/utilities/utdebug.c +++ b/drivers/acpi/utilities/utdebug.c | |||
@@ -549,7 +549,7 @@ acpi_ut_dump_buffer ( | |||
549 | /* Dump fill spaces */ | 549 | /* Dump fill spaces */ |
550 | 550 | ||
551 | acpi_os_printf ("%*s", ((display * 2) + 1), " "); | 551 | acpi_os_printf ("%*s", ((display * 2) + 1), " "); |
552 | j += display; | 552 | j += (acpi_native_uint) display; |
553 | continue; | 553 | continue; |
554 | } | 554 | } |
555 | 555 | ||
@@ -584,7 +584,7 @@ acpi_ut_dump_buffer ( | |||
584 | break; | 584 | break; |
585 | } | 585 | } |
586 | 586 | ||
587 | j += display; | 587 | j += (acpi_native_uint) display; |
588 | } | 588 | } |
589 | 589 | ||
590 | /* | 590 | /* |
diff --git a/drivers/acpi/utilities/utglobal.c b/drivers/acpi/utilities/utglobal.c index 4146019b543f..8653dda4f813 100644 --- a/drivers/acpi/utilities/utglobal.c +++ b/drivers/acpi/utilities/utglobal.c | |||
@@ -820,42 +820,20 @@ void | |||
820 | acpi_ut_init_globals ( | 820 | acpi_ut_init_globals ( |
821 | void) | 821 | void) |
822 | { | 822 | { |
823 | acpi_status status; | ||
823 | u32 i; | 824 | u32 i; |
824 | 825 | ||
825 | 826 | ||
826 | ACPI_FUNCTION_TRACE ("ut_init_globals"); | 827 | ACPI_FUNCTION_TRACE ("ut_init_globals"); |
827 | 828 | ||
828 | 829 | ||
829 | /* Memory allocation and cache lists */ | 830 | /* Create all memory caches */ |
830 | 831 | ||
831 | ACPI_MEMSET (acpi_gbl_memory_lists, 0, sizeof (struct acpi_memory_list) * ACPI_NUM_MEM_LISTS); | 832 | status = acpi_ut_create_caches (); |
832 | 833 | if (ACPI_FAILURE (status)) | |
833 | acpi_gbl_memory_lists[ACPI_MEM_LIST_STATE].link_offset = (u16) ACPI_PTR_DIFF (&(((union acpi_generic_state *) NULL)->common.next), NULL); | 834 | { |
834 | acpi_gbl_memory_lists[ACPI_MEM_LIST_PSNODE].link_offset = (u16) ACPI_PTR_DIFF (&(((union acpi_parse_object *) NULL)->common.next), NULL); | 835 | return; |
835 | acpi_gbl_memory_lists[ACPI_MEM_LIST_PSNODE_EXT].link_offset = (u16) ACPI_PTR_DIFF (&(((union acpi_parse_object *) NULL)->common.next), NULL); | 836 | } |
836 | acpi_gbl_memory_lists[ACPI_MEM_LIST_OPERAND].link_offset = (u16) ACPI_PTR_DIFF (&(((union acpi_operand_object *) NULL)->cache.next), NULL); | ||
837 | acpi_gbl_memory_lists[ACPI_MEM_LIST_WALK].link_offset = (u16) ACPI_PTR_DIFF (&(((struct acpi_walk_state *) NULL)->next), NULL); | ||
838 | |||
839 | acpi_gbl_memory_lists[ACPI_MEM_LIST_NSNODE].object_size = sizeof (struct acpi_namespace_node); | ||
840 | acpi_gbl_memory_lists[ACPI_MEM_LIST_STATE].object_size = sizeof (union acpi_generic_state); | ||
841 | acpi_gbl_memory_lists[ACPI_MEM_LIST_PSNODE].object_size = sizeof (struct acpi_parse_obj_common); | ||
842 | acpi_gbl_memory_lists[ACPI_MEM_LIST_PSNODE_EXT].object_size = sizeof (struct acpi_parse_obj_named); | ||
843 | acpi_gbl_memory_lists[ACPI_MEM_LIST_OPERAND].object_size = sizeof (union acpi_operand_object); | ||
844 | acpi_gbl_memory_lists[ACPI_MEM_LIST_WALK].object_size = sizeof (struct acpi_walk_state); | ||
845 | |||
846 | acpi_gbl_memory_lists[ACPI_MEM_LIST_STATE].max_cache_depth = ACPI_MAX_STATE_CACHE_DEPTH; | ||
847 | acpi_gbl_memory_lists[ACPI_MEM_LIST_PSNODE].max_cache_depth = ACPI_MAX_PARSE_CACHE_DEPTH; | ||
848 | acpi_gbl_memory_lists[ACPI_MEM_LIST_PSNODE_EXT].max_cache_depth = ACPI_MAX_EXTPARSE_CACHE_DEPTH; | ||
849 | acpi_gbl_memory_lists[ACPI_MEM_LIST_OPERAND].max_cache_depth = ACPI_MAX_OBJECT_CACHE_DEPTH; | ||
850 | acpi_gbl_memory_lists[ACPI_MEM_LIST_WALK].max_cache_depth = ACPI_MAX_WALK_CACHE_DEPTH; | ||
851 | |||
852 | ACPI_MEM_TRACKING (acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].list_name = "Global Memory Allocation"); | ||
853 | ACPI_MEM_TRACKING (acpi_gbl_memory_lists[ACPI_MEM_LIST_NSNODE].list_name = "Namespace Nodes"); | ||
854 | ACPI_MEM_TRACKING (acpi_gbl_memory_lists[ACPI_MEM_LIST_STATE].list_name = "State Object Cache"); | ||
855 | ACPI_MEM_TRACKING (acpi_gbl_memory_lists[ACPI_MEM_LIST_PSNODE].list_name = "Parse Node Cache"); | ||
856 | ACPI_MEM_TRACKING (acpi_gbl_memory_lists[ACPI_MEM_LIST_PSNODE_EXT].list_name = "Extended Parse Node Cache"); | ||
857 | ACPI_MEM_TRACKING (acpi_gbl_memory_lists[ACPI_MEM_LIST_OPERAND].list_name = "Operand Object Cache"); | ||
858 | ACPI_MEM_TRACKING (acpi_gbl_memory_lists[ACPI_MEM_LIST_WALK].list_name = "Tree Walk Node Cache"); | ||
859 | 837 | ||
860 | /* ACPI table structure */ | 838 | /* ACPI table structure */ |
861 | 839 | ||
diff --git a/drivers/acpi/utilities/utinit.c b/drivers/acpi/utilities/utinit.c index 7f3713889ff0..fd7ceba83229 100644 --- a/drivers/acpi/utilities/utinit.c +++ b/drivers/acpi/utilities/utinit.c | |||
@@ -264,7 +264,7 @@ acpi_ut_subsystem_shutdown ( | |||
264 | 264 | ||
265 | /* Purge the local caches */ | 265 | /* Purge the local caches */ |
266 | 266 | ||
267 | (void) acpi_purge_cached_objects (); | 267 | (void) acpi_ut_delete_caches (); |
268 | 268 | ||
269 | /* Debug only - display leftover memory allocation, if any */ | 269 | /* Debug only - display leftover memory allocation, if any */ |
270 | 270 | ||
diff --git a/drivers/acpi/utilities/utmisc.c b/drivers/acpi/utilities/utmisc.c index bb658777fa88..207c836aec64 100644 --- a/drivers/acpi/utilities/utmisc.c +++ b/drivers/acpi/utilities/utmisc.c | |||
@@ -49,16 +49,6 @@ | |||
49 | #define _COMPONENT ACPI_UTILITIES | 49 | #define _COMPONENT ACPI_UTILITIES |
50 | ACPI_MODULE_NAME ("utmisc") | 50 | ACPI_MODULE_NAME ("utmisc") |
51 | 51 | ||
52 | /* Local prototypes */ | ||
53 | |||
54 | static acpi_status | ||
55 | acpi_ut_create_mutex ( | ||
56 | acpi_mutex_handle mutex_id); | ||
57 | |||
58 | static acpi_status | ||
59 | acpi_ut_delete_mutex ( | ||
60 | acpi_mutex_handle mutex_id); | ||
61 | |||
62 | 52 | ||
63 | /******************************************************************************* | 53 | /******************************************************************************* |
64 | * | 54 | * |
@@ -84,6 +74,10 @@ acpi_ut_strupr ( | |||
84 | ACPI_FUNCTION_ENTRY (); | 74 | ACPI_FUNCTION_ENTRY (); |
85 | 75 | ||
86 | 76 | ||
77 | if (!src_string) { | ||
78 | return (NULL); | ||
79 | } | ||
80 | |||
87 | /* Walk entire string, uppercasing the letters */ | 81 | /* Walk entire string, uppercasing the letters */ |
88 | 82 | ||
89 | for (string = src_string; *string; string++) { | 83 | for (string = src_string; *string; string++) { |
@@ -543,326 +537,6 @@ error_exit: | |||
543 | 537 | ||
544 | /******************************************************************************* | 538 | /******************************************************************************* |
545 | * | 539 | * |
546 | * FUNCTION: acpi_ut_mutex_initialize | ||
547 | * | ||
548 | * PARAMETERS: None. | ||
549 | * | ||
550 | * RETURN: Status | ||
551 | * | ||
552 | * DESCRIPTION: Create the system mutex objects. | ||
553 | * | ||
554 | ******************************************************************************/ | ||
555 | |||
556 | acpi_status | ||
557 | acpi_ut_mutex_initialize ( | ||
558 | void) | ||
559 | { | ||
560 | u32 i; | ||
561 | acpi_status status; | ||
562 | |||
563 | |||
564 | ACPI_FUNCTION_TRACE ("ut_mutex_initialize"); | ||
565 | |||
566 | |||
567 | /* | ||
568 | * Create each of the predefined mutex objects | ||
569 | */ | ||
570 | for (i = 0; i < NUM_MUTEX; i++) { | ||
571 | status = acpi_ut_create_mutex (i); | ||
572 | if (ACPI_FAILURE (status)) { | ||
573 | return_ACPI_STATUS (status); | ||
574 | } | ||
575 | } | ||
576 | |||
577 | status = acpi_os_create_lock (&acpi_gbl_gpe_lock); | ||
578 | return_ACPI_STATUS (status); | ||
579 | } | ||
580 | |||
581 | |||
582 | /******************************************************************************* | ||
583 | * | ||
584 | * FUNCTION: acpi_ut_mutex_terminate | ||
585 | * | ||
586 | * PARAMETERS: None. | ||
587 | * | ||
588 | * RETURN: None. | ||
589 | * | ||
590 | * DESCRIPTION: Delete all of the system mutex objects. | ||
591 | * | ||
592 | ******************************************************************************/ | ||
593 | |||
594 | void | ||
595 | acpi_ut_mutex_terminate ( | ||
596 | void) | ||
597 | { | ||
598 | u32 i; | ||
599 | |||
600 | |||
601 | ACPI_FUNCTION_TRACE ("ut_mutex_terminate"); | ||
602 | |||
603 | |||
604 | /* | ||
605 | * Delete each predefined mutex object | ||
606 | */ | ||
607 | for (i = 0; i < NUM_MUTEX; i++) { | ||
608 | (void) acpi_ut_delete_mutex (i); | ||
609 | } | ||
610 | |||
611 | acpi_os_delete_lock (acpi_gbl_gpe_lock); | ||
612 | return_VOID; | ||
613 | } | ||
614 | |||
615 | |||
616 | /******************************************************************************* | ||
617 | * | ||
618 | * FUNCTION: acpi_ut_create_mutex | ||
619 | * | ||
620 | * PARAMETERS: mutex_iD - ID of the mutex to be created | ||
621 | * | ||
622 | * RETURN: Status | ||
623 | * | ||
624 | * DESCRIPTION: Create a mutex object. | ||
625 | * | ||
626 | ******************************************************************************/ | ||
627 | |||
628 | static acpi_status | ||
629 | acpi_ut_create_mutex ( | ||
630 | acpi_mutex_handle mutex_id) | ||
631 | { | ||
632 | acpi_status status = AE_OK; | ||
633 | |||
634 | |||
635 | ACPI_FUNCTION_TRACE_U32 ("ut_create_mutex", mutex_id); | ||
636 | |||
637 | |||
638 | if (mutex_id > MAX_MUTEX) { | ||
639 | return_ACPI_STATUS (AE_BAD_PARAMETER); | ||
640 | } | ||
641 | |||
642 | if (!acpi_gbl_mutex_info[mutex_id].mutex) { | ||
643 | status = acpi_os_create_semaphore (1, 1, | ||
644 | &acpi_gbl_mutex_info[mutex_id].mutex); | ||
645 | acpi_gbl_mutex_info[mutex_id].owner_id = ACPI_MUTEX_NOT_ACQUIRED; | ||
646 | acpi_gbl_mutex_info[mutex_id].use_count = 0; | ||
647 | } | ||
648 | |||
649 | return_ACPI_STATUS (status); | ||
650 | } | ||
651 | |||
652 | |||
653 | /******************************************************************************* | ||
654 | * | ||
655 | * FUNCTION: acpi_ut_delete_mutex | ||
656 | * | ||
657 | * PARAMETERS: mutex_iD - ID of the mutex to be deleted | ||
658 | * | ||
659 | * RETURN: Status | ||
660 | * | ||
661 | * DESCRIPTION: Delete a mutex object. | ||
662 | * | ||
663 | ******************************************************************************/ | ||
664 | |||
665 | static acpi_status | ||
666 | acpi_ut_delete_mutex ( | ||
667 | acpi_mutex_handle mutex_id) | ||
668 | { | ||
669 | acpi_status status; | ||
670 | |||
671 | |||
672 | ACPI_FUNCTION_TRACE_U32 ("ut_delete_mutex", mutex_id); | ||
673 | |||
674 | |||
675 | if (mutex_id > MAX_MUTEX) { | ||
676 | return_ACPI_STATUS (AE_BAD_PARAMETER); | ||
677 | } | ||
678 | |||
679 | status = acpi_os_delete_semaphore (acpi_gbl_mutex_info[mutex_id].mutex); | ||
680 | |||
681 | acpi_gbl_mutex_info[mutex_id].mutex = NULL; | ||
682 | acpi_gbl_mutex_info[mutex_id].owner_id = ACPI_MUTEX_NOT_ACQUIRED; | ||
683 | |||
684 | return_ACPI_STATUS (status); | ||
685 | } | ||
686 | |||
687 | |||
688 | /******************************************************************************* | ||
689 | * | ||
690 | * FUNCTION: acpi_ut_acquire_mutex | ||
691 | * | ||
692 | * PARAMETERS: mutex_iD - ID of the mutex to be acquired | ||
693 | * | ||
694 | * RETURN: Status | ||
695 | * | ||
696 | * DESCRIPTION: Acquire a mutex object. | ||
697 | * | ||
698 | ******************************************************************************/ | ||
699 | |||
700 | acpi_status | ||
701 | acpi_ut_acquire_mutex ( | ||
702 | acpi_mutex_handle mutex_id) | ||
703 | { | ||
704 | acpi_status status; | ||
705 | u32 this_thread_id; | ||
706 | |||
707 | |||
708 | ACPI_FUNCTION_NAME ("ut_acquire_mutex"); | ||
709 | |||
710 | |||
711 | if (mutex_id > MAX_MUTEX) { | ||
712 | return (AE_BAD_PARAMETER); | ||
713 | } | ||
714 | |||
715 | this_thread_id = acpi_os_get_thread_id (); | ||
716 | |||
717 | #ifdef ACPI_MUTEX_DEBUG | ||
718 | { | ||
719 | u32 i; | ||
720 | /* | ||
721 | * Mutex debug code, for internal debugging only. | ||
722 | * | ||
723 | * Deadlock prevention. Check if this thread owns any mutexes of value | ||
724 | * greater than or equal to this one. If so, the thread has violated | ||
725 | * the mutex ordering rule. This indicates a coding error somewhere in | ||
726 | * the ACPI subsystem code. | ||
727 | */ | ||
728 | for (i = mutex_id; i < MAX_MUTEX; i++) { | ||
729 | if (acpi_gbl_mutex_info[i].owner_id == this_thread_id) { | ||
730 | if (i == mutex_id) { | ||
731 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, | ||
732 | "Mutex [%s] already acquired by this thread [%X]\n", | ||
733 | acpi_ut_get_mutex_name (mutex_id), this_thread_id)); | ||
734 | |||
735 | return (AE_ALREADY_ACQUIRED); | ||
736 | } | ||
737 | |||
738 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, | ||
739 | "Invalid acquire order: Thread %X owns [%s], wants [%s]\n", | ||
740 | this_thread_id, acpi_ut_get_mutex_name (i), | ||
741 | acpi_ut_get_mutex_name (mutex_id))); | ||
742 | |||
743 | return (AE_ACQUIRE_DEADLOCK); | ||
744 | } | ||
745 | } | ||
746 | } | ||
747 | #endif | ||
748 | |||
749 | ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, | ||
750 | "Thread %X attempting to acquire Mutex [%s]\n", | ||
751 | this_thread_id, acpi_ut_get_mutex_name (mutex_id))); | ||
752 | |||
753 | status = acpi_os_wait_semaphore (acpi_gbl_mutex_info[mutex_id].mutex, | ||
754 | 1, ACPI_WAIT_FOREVER); | ||
755 | if (ACPI_SUCCESS (status)) { | ||
756 | ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Thread %X acquired Mutex [%s]\n", | ||
757 | this_thread_id, acpi_ut_get_mutex_name (mutex_id))); | ||
758 | |||
759 | acpi_gbl_mutex_info[mutex_id].use_count++; | ||
760 | acpi_gbl_mutex_info[mutex_id].owner_id = this_thread_id; | ||
761 | } | ||
762 | else { | ||
763 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, | ||
764 | "Thread %X could not acquire Mutex [%s] %s\n", | ||
765 | this_thread_id, acpi_ut_get_mutex_name (mutex_id), | ||
766 | acpi_format_exception (status))); | ||
767 | } | ||
768 | |||
769 | return (status); | ||
770 | } | ||
771 | |||
772 | |||
773 | /******************************************************************************* | ||
774 | * | ||
775 | * FUNCTION: acpi_ut_release_mutex | ||
776 | * | ||
777 | * PARAMETERS: mutex_iD - ID of the mutex to be released | ||
778 | * | ||
779 | * RETURN: Status | ||
780 | * | ||
781 | * DESCRIPTION: Release a mutex object. | ||
782 | * | ||
783 | ******************************************************************************/ | ||
784 | |||
785 | acpi_status | ||
786 | acpi_ut_release_mutex ( | ||
787 | acpi_mutex_handle mutex_id) | ||
788 | { | ||
789 | acpi_status status; | ||
790 | u32 this_thread_id; | ||
791 | |||
792 | |||
793 | ACPI_FUNCTION_NAME ("ut_release_mutex"); | ||
794 | |||
795 | |||
796 | this_thread_id = acpi_os_get_thread_id (); | ||
797 | ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, | ||
798 | "Thread %X releasing Mutex [%s]\n", this_thread_id, | ||
799 | acpi_ut_get_mutex_name (mutex_id))); | ||
800 | |||
801 | if (mutex_id > MAX_MUTEX) { | ||
802 | return (AE_BAD_PARAMETER); | ||
803 | } | ||
804 | |||
805 | /* | ||
806 | * Mutex must be acquired in order to release it! | ||
807 | */ | ||
808 | if (acpi_gbl_mutex_info[mutex_id].owner_id == ACPI_MUTEX_NOT_ACQUIRED) { | ||
809 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, | ||
810 | "Mutex [%s] is not acquired, cannot release\n", | ||
811 | acpi_ut_get_mutex_name (mutex_id))); | ||
812 | |||
813 | return (AE_NOT_ACQUIRED); | ||
814 | } | ||
815 | |||
816 | #ifdef ACPI_MUTEX_DEBUG | ||
817 | { | ||
818 | u32 i; | ||
819 | /* | ||
820 | * Mutex debug code, for internal debugging only. | ||
821 | * | ||
822 | * Deadlock prevention. Check if this thread owns any mutexes of value | ||
823 | * greater than this one. If so, the thread has violated the mutex | ||
824 | * ordering rule. This indicates a coding error somewhere in | ||
825 | * the ACPI subsystem code. | ||
826 | */ | ||
827 | for (i = mutex_id; i < MAX_MUTEX; i++) { | ||
828 | if (acpi_gbl_mutex_info[i].owner_id == this_thread_id) { | ||
829 | if (i == mutex_id) { | ||
830 | continue; | ||
831 | } | ||
832 | |||
833 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, | ||
834 | "Invalid release order: owns [%s], releasing [%s]\n", | ||
835 | acpi_ut_get_mutex_name (i), acpi_ut_get_mutex_name (mutex_id))); | ||
836 | |||
837 | return (AE_RELEASE_DEADLOCK); | ||
838 | } | ||
839 | } | ||
840 | } | ||
841 | #endif | ||
842 | |||
843 | /* Mark unlocked FIRST */ | ||
844 | |||
845 | acpi_gbl_mutex_info[mutex_id].owner_id = ACPI_MUTEX_NOT_ACQUIRED; | ||
846 | |||
847 | status = acpi_os_signal_semaphore (acpi_gbl_mutex_info[mutex_id].mutex, 1); | ||
848 | |||
849 | if (ACPI_FAILURE (status)) { | ||
850 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, | ||
851 | "Thread %X could not release Mutex [%s] %s\n", | ||
852 | this_thread_id, acpi_ut_get_mutex_name (mutex_id), | ||
853 | acpi_format_exception (status))); | ||
854 | } | ||
855 | else { | ||
856 | ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Thread %X released Mutex [%s]\n", | ||
857 | this_thread_id, acpi_ut_get_mutex_name (mutex_id))); | ||
858 | } | ||
859 | |||
860 | return (status); | ||
861 | } | ||
862 | |||
863 | |||
864 | /******************************************************************************* | ||
865 | * | ||
866 | * FUNCTION: acpi_ut_create_update_state_and_push | 540 | * FUNCTION: acpi_ut_create_update_state_and_push |
867 | * | 541 | * |
868 | * PARAMETERS: Object - Object to be added to the new state | 542 | * PARAMETERS: Object - Object to be added to the new state |
@@ -905,361 +579,6 @@ acpi_ut_create_update_state_and_push ( | |||
905 | 579 | ||
906 | /******************************************************************************* | 580 | /******************************************************************************* |
907 | * | 581 | * |
908 | * FUNCTION: acpi_ut_create_pkg_state_and_push | ||
909 | * | ||
910 | * PARAMETERS: Object - Object to be added to the new state | ||
911 | * Action - Increment/Decrement | ||
912 | * state_list - List the state will be added to | ||
913 | * | ||
914 | * RETURN: Status | ||
915 | * | ||
916 | * DESCRIPTION: Create a new state and push it | ||
917 | * | ||
918 | ******************************************************************************/ | ||
919 | |||
920 | #ifdef ACPI_FUTURE_USAGE | ||
921 | acpi_status | ||
922 | acpi_ut_create_pkg_state_and_push ( | ||
923 | void *internal_object, | ||
924 | void *external_object, | ||
925 | u16 index, | ||
926 | union acpi_generic_state **state_list) | ||
927 | { | ||
928 | union acpi_generic_state *state; | ||
929 | |||
930 | |||
931 | ACPI_FUNCTION_ENTRY (); | ||
932 | |||
933 | |||
934 | state = acpi_ut_create_pkg_state (internal_object, external_object, index); | ||
935 | if (!state) { | ||
936 | return (AE_NO_MEMORY); | ||
937 | } | ||
938 | |||
939 | acpi_ut_push_generic_state (state_list, state); | ||
940 | return (AE_OK); | ||
941 | } | ||
942 | #endif /* ACPI_FUTURE_USAGE */ | ||
943 | |||
944 | /******************************************************************************* | ||
945 | * | ||
946 | * FUNCTION: acpi_ut_push_generic_state | ||
947 | * | ||
948 | * PARAMETERS: list_head - Head of the state stack | ||
949 | * State - State object to push | ||
950 | * | ||
951 | * RETURN: None | ||
952 | * | ||
953 | * DESCRIPTION: Push a state object onto a state stack | ||
954 | * | ||
955 | ******************************************************************************/ | ||
956 | |||
957 | void | ||
958 | acpi_ut_push_generic_state ( | ||
959 | union acpi_generic_state **list_head, | ||
960 | union acpi_generic_state *state) | ||
961 | { | ||
962 | ACPI_FUNCTION_TRACE ("ut_push_generic_state"); | ||
963 | |||
964 | |||
965 | /* Push the state object onto the front of the list (stack) */ | ||
966 | |||
967 | state->common.next = *list_head; | ||
968 | *list_head = state; | ||
969 | |||
970 | return_VOID; | ||
971 | } | ||
972 | |||
973 | |||
974 | /******************************************************************************* | ||
975 | * | ||
976 | * FUNCTION: acpi_ut_pop_generic_state | ||
977 | * | ||
978 | * PARAMETERS: list_head - Head of the state stack | ||
979 | * | ||
980 | * RETURN: The popped state object | ||
981 | * | ||
982 | * DESCRIPTION: Pop a state object from a state stack | ||
983 | * | ||
984 | ******************************************************************************/ | ||
985 | |||
986 | union acpi_generic_state * | ||
987 | acpi_ut_pop_generic_state ( | ||
988 | union acpi_generic_state **list_head) | ||
989 | { | ||
990 | union acpi_generic_state *state; | ||
991 | |||
992 | |||
993 | ACPI_FUNCTION_TRACE ("ut_pop_generic_state"); | ||
994 | |||
995 | |||
996 | /* Remove the state object at the head of the list (stack) */ | ||
997 | |||
998 | state = *list_head; | ||
999 | if (state) { | ||
1000 | /* Update the list head */ | ||
1001 | |||
1002 | *list_head = state->common.next; | ||
1003 | } | ||
1004 | |||
1005 | return_PTR (state); | ||
1006 | } | ||
1007 | |||
1008 | |||
1009 | /******************************************************************************* | ||
1010 | * | ||
1011 | * FUNCTION: acpi_ut_create_generic_state | ||
1012 | * | ||
1013 | * PARAMETERS: None | ||
1014 | * | ||
1015 | * RETURN: The new state object. NULL on failure. | ||
1016 | * | ||
1017 | * DESCRIPTION: Create a generic state object. Attempt to obtain one from | ||
1018 | * the global state cache; If none available, create a new one. | ||
1019 | * | ||
1020 | ******************************************************************************/ | ||
1021 | |||
1022 | union acpi_generic_state * | ||
1023 | acpi_ut_create_generic_state ( | ||
1024 | void) | ||
1025 | { | ||
1026 | union acpi_generic_state *state; | ||
1027 | |||
1028 | |||
1029 | ACPI_FUNCTION_ENTRY (); | ||
1030 | |||
1031 | |||
1032 | state = acpi_ut_acquire_from_cache (ACPI_MEM_LIST_STATE); | ||
1033 | |||
1034 | /* Initialize */ | ||
1035 | |||
1036 | if (state) { | ||
1037 | state->common.data_type = ACPI_DESC_TYPE_STATE; | ||
1038 | } | ||
1039 | |||
1040 | return (state); | ||
1041 | } | ||
1042 | |||
1043 | |||
1044 | /******************************************************************************* | ||
1045 | * | ||
1046 | * FUNCTION: acpi_ut_create_thread_state | ||
1047 | * | ||
1048 | * PARAMETERS: None | ||
1049 | * | ||
1050 | * RETURN: New Thread State. NULL on failure | ||
1051 | * | ||
1052 | * DESCRIPTION: Create a "Thread State" - a flavor of the generic state used | ||
1053 | * to track per-thread info during method execution | ||
1054 | * | ||
1055 | ******************************************************************************/ | ||
1056 | |||
1057 | struct acpi_thread_state * | ||
1058 | acpi_ut_create_thread_state ( | ||
1059 | void) | ||
1060 | { | ||
1061 | union acpi_generic_state *state; | ||
1062 | |||
1063 | |||
1064 | ACPI_FUNCTION_TRACE ("ut_create_thread_state"); | ||
1065 | |||
1066 | |||
1067 | /* Create the generic state object */ | ||
1068 | |||
1069 | state = acpi_ut_create_generic_state (); | ||
1070 | if (!state) { | ||
1071 | return_PTR (NULL); | ||
1072 | } | ||
1073 | |||
1074 | /* Init fields specific to the update struct */ | ||
1075 | |||
1076 | state->common.data_type = ACPI_DESC_TYPE_STATE_THREAD; | ||
1077 | state->thread.thread_id = acpi_os_get_thread_id (); | ||
1078 | |||
1079 | return_PTR ((struct acpi_thread_state *) state); | ||
1080 | } | ||
1081 | |||
1082 | |||
1083 | /******************************************************************************* | ||
1084 | * | ||
1085 | * FUNCTION: acpi_ut_create_update_state | ||
1086 | * | ||
1087 | * PARAMETERS: Object - Initial Object to be installed in the state | ||
1088 | * Action - Update action to be performed | ||
1089 | * | ||
1090 | * RETURN: New state object, null on failure | ||
1091 | * | ||
1092 | * DESCRIPTION: Create an "Update State" - a flavor of the generic state used | ||
1093 | * to update reference counts and delete complex objects such | ||
1094 | * as packages. | ||
1095 | * | ||
1096 | ******************************************************************************/ | ||
1097 | |||
1098 | union acpi_generic_state * | ||
1099 | acpi_ut_create_update_state ( | ||
1100 | union acpi_operand_object *object, | ||
1101 | u16 action) | ||
1102 | { | ||
1103 | union acpi_generic_state *state; | ||
1104 | |||
1105 | |||
1106 | ACPI_FUNCTION_TRACE_PTR ("ut_create_update_state", object); | ||
1107 | |||
1108 | |||
1109 | /* Create the generic state object */ | ||
1110 | |||
1111 | state = acpi_ut_create_generic_state (); | ||
1112 | if (!state) { | ||
1113 | return_PTR (NULL); | ||
1114 | } | ||
1115 | |||
1116 | /* Init fields specific to the update struct */ | ||
1117 | |||
1118 | state->common.data_type = ACPI_DESC_TYPE_STATE_UPDATE; | ||
1119 | state->update.object = object; | ||
1120 | state->update.value = action; | ||
1121 | |||
1122 | return_PTR (state); | ||
1123 | } | ||
1124 | |||
1125 | |||
1126 | /******************************************************************************* | ||
1127 | * | ||
1128 | * FUNCTION: acpi_ut_create_pkg_state | ||
1129 | * | ||
1130 | * PARAMETERS: Object - Initial Object to be installed in the state | ||
1131 | * Action - Update action to be performed | ||
1132 | * | ||
1133 | * RETURN: New state object, null on failure | ||
1134 | * | ||
1135 | * DESCRIPTION: Create a "Package State" | ||
1136 | * | ||
1137 | ******************************************************************************/ | ||
1138 | |||
1139 | union acpi_generic_state * | ||
1140 | acpi_ut_create_pkg_state ( | ||
1141 | void *internal_object, | ||
1142 | void *external_object, | ||
1143 | u16 index) | ||
1144 | { | ||
1145 | union acpi_generic_state *state; | ||
1146 | |||
1147 | |||
1148 | ACPI_FUNCTION_TRACE_PTR ("ut_create_pkg_state", internal_object); | ||
1149 | |||
1150 | |||
1151 | /* Create the generic state object */ | ||
1152 | |||
1153 | state = acpi_ut_create_generic_state (); | ||
1154 | if (!state) { | ||
1155 | return_PTR (NULL); | ||
1156 | } | ||
1157 | |||
1158 | /* Init fields specific to the update struct */ | ||
1159 | |||
1160 | state->common.data_type = ACPI_DESC_TYPE_STATE_PACKAGE; | ||
1161 | state->pkg.source_object = (union acpi_operand_object *) internal_object; | ||
1162 | state->pkg.dest_object = external_object; | ||
1163 | state->pkg.index = index; | ||
1164 | state->pkg.num_packages = 1; | ||
1165 | |||
1166 | return_PTR (state); | ||
1167 | } | ||
1168 | |||
1169 | |||
1170 | /******************************************************************************* | ||
1171 | * | ||
1172 | * FUNCTION: acpi_ut_create_control_state | ||
1173 | * | ||
1174 | * PARAMETERS: None | ||
1175 | * | ||
1176 | * RETURN: New state object, null on failure | ||
1177 | * | ||
1178 | * DESCRIPTION: Create a "Control State" - a flavor of the generic state used | ||
1179 | * to support nested IF/WHILE constructs in the AML. | ||
1180 | * | ||
1181 | ******************************************************************************/ | ||
1182 | |||
1183 | union acpi_generic_state * | ||
1184 | acpi_ut_create_control_state ( | ||
1185 | void) | ||
1186 | { | ||
1187 | union acpi_generic_state *state; | ||
1188 | |||
1189 | |||
1190 | ACPI_FUNCTION_TRACE ("ut_create_control_state"); | ||
1191 | |||
1192 | |||
1193 | /* Create the generic state object */ | ||
1194 | |||
1195 | state = acpi_ut_create_generic_state (); | ||
1196 | if (!state) { | ||
1197 | return_PTR (NULL); | ||
1198 | } | ||
1199 | |||
1200 | /* Init fields specific to the control struct */ | ||
1201 | |||
1202 | state->common.data_type = ACPI_DESC_TYPE_STATE_CONTROL; | ||
1203 | state->common.state = ACPI_CONTROL_CONDITIONAL_EXECUTING; | ||
1204 | |||
1205 | return_PTR (state); | ||
1206 | } | ||
1207 | |||
1208 | |||
1209 | /******************************************************************************* | ||
1210 | * | ||
1211 | * FUNCTION: acpi_ut_delete_generic_state | ||
1212 | * | ||
1213 | * PARAMETERS: State - The state object to be deleted | ||
1214 | * | ||
1215 | * RETURN: None | ||
1216 | * | ||
1217 | * DESCRIPTION: Put a state object back into the global state cache. The object | ||
1218 | * is not actually freed at this time. | ||
1219 | * | ||
1220 | ******************************************************************************/ | ||
1221 | |||
1222 | void | ||
1223 | acpi_ut_delete_generic_state ( | ||
1224 | union acpi_generic_state *state) | ||
1225 | { | ||
1226 | ACPI_FUNCTION_TRACE ("ut_delete_generic_state"); | ||
1227 | |||
1228 | |||
1229 | acpi_ut_release_to_cache (ACPI_MEM_LIST_STATE, state); | ||
1230 | return_VOID; | ||
1231 | } | ||
1232 | |||
1233 | |||
1234 | #ifdef ACPI_ENABLE_OBJECT_CACHE | ||
1235 | /******************************************************************************* | ||
1236 | * | ||
1237 | * FUNCTION: acpi_ut_delete_generic_state_cache | ||
1238 | * | ||
1239 | * PARAMETERS: None | ||
1240 | * | ||
1241 | * RETURN: None | ||
1242 | * | ||
1243 | * DESCRIPTION: Purge the global state object cache. Used during subsystem | ||
1244 | * termination. | ||
1245 | * | ||
1246 | ******************************************************************************/ | ||
1247 | |||
1248 | void | ||
1249 | acpi_ut_delete_generic_state_cache ( | ||
1250 | void) | ||
1251 | { | ||
1252 | ACPI_FUNCTION_TRACE ("ut_delete_generic_state_cache"); | ||
1253 | |||
1254 | |||
1255 | acpi_ut_delete_generic_cache (ACPI_MEM_LIST_STATE); | ||
1256 | return_VOID; | ||
1257 | } | ||
1258 | #endif | ||
1259 | |||
1260 | |||
1261 | /******************************************************************************* | ||
1262 | * | ||
1263 | * FUNCTION: acpi_ut_walk_package_tree | 582 | * FUNCTION: acpi_ut_walk_package_tree |
1264 | * | 583 | * |
1265 | * PARAMETERS: source_object - The package to walk | 584 | * PARAMETERS: source_object - The package to walk |
diff --git a/drivers/acpi/utilities/utmutex.c b/drivers/acpi/utilities/utmutex.c new file mode 100644 index 000000000000..a80b97cb2e56 --- /dev/null +++ b/drivers/acpi/utilities/utmutex.c | |||
@@ -0,0 +1,380 @@ | |||
1 | /******************************************************************************* | ||
2 | * | ||
3 | * Module Name: utmutex - local mutex support | ||
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 ("utmutex") | ||
49 | |||
50 | /* Local prototypes */ | ||
51 | |||
52 | static acpi_status | ||
53 | acpi_ut_create_mutex ( | ||
54 | acpi_mutex_handle mutex_id); | ||
55 | |||
56 | static acpi_status | ||
57 | acpi_ut_delete_mutex ( | ||
58 | acpi_mutex_handle mutex_id); | ||
59 | |||
60 | |||
61 | /******************************************************************************* | ||
62 | * | ||
63 | * FUNCTION: acpi_ut_mutex_initialize | ||
64 | * | ||
65 | * PARAMETERS: None. | ||
66 | * | ||
67 | * RETURN: Status | ||
68 | * | ||
69 | * DESCRIPTION: Create the system mutex objects. | ||
70 | * | ||
71 | ******************************************************************************/ | ||
72 | |||
73 | acpi_status | ||
74 | acpi_ut_mutex_initialize ( | ||
75 | void) | ||
76 | { | ||
77 | u32 i; | ||
78 | acpi_status status; | ||
79 | |||
80 | |||
81 | ACPI_FUNCTION_TRACE ("ut_mutex_initialize"); | ||
82 | |||
83 | |||
84 | /* | ||
85 | * Create each of the predefined mutex objects | ||
86 | */ | ||
87 | for (i = 0; i < NUM_MUTEX; i++) { | ||
88 | status = acpi_ut_create_mutex (i); | ||
89 | if (ACPI_FAILURE (status)) { | ||
90 | return_ACPI_STATUS (status); | ||
91 | } | ||
92 | } | ||
93 | |||
94 | status = acpi_os_create_lock (&acpi_gbl_gpe_lock); | ||
95 | return_ACPI_STATUS (status); | ||
96 | } | ||
97 | |||
98 | |||
99 | /******************************************************************************* | ||
100 | * | ||
101 | * FUNCTION: acpi_ut_mutex_terminate | ||
102 | * | ||
103 | * PARAMETERS: None. | ||
104 | * | ||
105 | * RETURN: None. | ||
106 | * | ||
107 | * DESCRIPTION: Delete all of the system mutex objects. | ||
108 | * | ||
109 | ******************************************************************************/ | ||
110 | |||
111 | void | ||
112 | acpi_ut_mutex_terminate ( | ||
113 | void) | ||
114 | { | ||
115 | u32 i; | ||
116 | |||
117 | |||
118 | ACPI_FUNCTION_TRACE ("ut_mutex_terminate"); | ||
119 | |||
120 | |||
121 | /* | ||
122 | * Delete each predefined mutex object | ||
123 | */ | ||
124 | for (i = 0; i < NUM_MUTEX; i++) { | ||
125 | (void) acpi_ut_delete_mutex (i); | ||
126 | } | ||
127 | |||
128 | acpi_os_delete_lock (acpi_gbl_gpe_lock); | ||
129 | return_VOID; | ||
130 | } | ||
131 | |||
132 | |||
133 | /******************************************************************************* | ||
134 | * | ||
135 | * FUNCTION: acpi_ut_create_mutex | ||
136 | * | ||
137 | * PARAMETERS: mutex_iD - ID of the mutex to be created | ||
138 | * | ||
139 | * RETURN: Status | ||
140 | * | ||
141 | * DESCRIPTION: Create a mutex object. | ||
142 | * | ||
143 | ******************************************************************************/ | ||
144 | |||
145 | static acpi_status | ||
146 | acpi_ut_create_mutex ( | ||
147 | acpi_mutex_handle mutex_id) | ||
148 | { | ||
149 | acpi_status status = AE_OK; | ||
150 | |||
151 | |||
152 | ACPI_FUNCTION_TRACE_U32 ("ut_create_mutex", mutex_id); | ||
153 | |||
154 | |||
155 | if (mutex_id > MAX_MUTEX) { | ||
156 | return_ACPI_STATUS (AE_BAD_PARAMETER); | ||
157 | } | ||
158 | |||
159 | if (!acpi_gbl_mutex_info[mutex_id].mutex) { | ||
160 | status = acpi_os_create_semaphore (1, 1, | ||
161 | &acpi_gbl_mutex_info[mutex_id].mutex); | ||
162 | acpi_gbl_mutex_info[mutex_id].owner_id = ACPI_MUTEX_NOT_ACQUIRED; | ||
163 | acpi_gbl_mutex_info[mutex_id].use_count = 0; | ||
164 | } | ||
165 | |||
166 | return_ACPI_STATUS (status); | ||
167 | } | ||
168 | |||
169 | |||
170 | /******************************************************************************* | ||
171 | * | ||
172 | * FUNCTION: acpi_ut_delete_mutex | ||
173 | * | ||
174 | * PARAMETERS: mutex_iD - ID of the mutex to be deleted | ||
175 | * | ||
176 | * RETURN: Status | ||
177 | * | ||
178 | * DESCRIPTION: Delete a mutex object. | ||
179 | * | ||
180 | ******************************************************************************/ | ||
181 | |||
182 | static acpi_status | ||
183 | acpi_ut_delete_mutex ( | ||
184 | acpi_mutex_handle mutex_id) | ||
185 | { | ||
186 | acpi_status status; | ||
187 | |||
188 | |||
189 | ACPI_FUNCTION_TRACE_U32 ("ut_delete_mutex", mutex_id); | ||
190 | |||
191 | |||
192 | if (mutex_id > MAX_MUTEX) { | ||
193 | return_ACPI_STATUS (AE_BAD_PARAMETER); | ||
194 | } | ||
195 | |||
196 | status = acpi_os_delete_semaphore (acpi_gbl_mutex_info[mutex_id].mutex); | ||
197 | |||
198 | acpi_gbl_mutex_info[mutex_id].mutex = NULL; | ||
199 | acpi_gbl_mutex_info[mutex_id].owner_id = ACPI_MUTEX_NOT_ACQUIRED; | ||
200 | |||
201 | return_ACPI_STATUS (status); | ||
202 | } | ||
203 | |||
204 | |||
205 | /******************************************************************************* | ||
206 | * | ||
207 | * FUNCTION: acpi_ut_acquire_mutex | ||
208 | * | ||
209 | * PARAMETERS: mutex_iD - ID of the mutex to be acquired | ||
210 | * | ||
211 | * RETURN: Status | ||
212 | * | ||
213 | * DESCRIPTION: Acquire a mutex object. | ||
214 | * | ||
215 | ******************************************************************************/ | ||
216 | |||
217 | acpi_status | ||
218 | acpi_ut_acquire_mutex ( | ||
219 | acpi_mutex_handle mutex_id) | ||
220 | { | ||
221 | acpi_status status; | ||
222 | u32 this_thread_id; | ||
223 | |||
224 | |||
225 | ACPI_FUNCTION_NAME ("ut_acquire_mutex"); | ||
226 | |||
227 | |||
228 | if (mutex_id > MAX_MUTEX) { | ||
229 | return (AE_BAD_PARAMETER); | ||
230 | } | ||
231 | |||
232 | this_thread_id = acpi_os_get_thread_id (); | ||
233 | |||
234 | #ifdef ACPI_MUTEX_DEBUG | ||
235 | { | ||
236 | u32 i; | ||
237 | /* | ||
238 | * Mutex debug code, for internal debugging only. | ||
239 | * | ||
240 | * Deadlock prevention. Check if this thread owns any mutexes of value | ||
241 | * greater than or equal to this one. If so, the thread has violated | ||
242 | * the mutex ordering rule. This indicates a coding error somewhere in | ||
243 | * the ACPI subsystem code. | ||
244 | */ | ||
245 | for (i = mutex_id; i < MAX_MUTEX; i++) { | ||
246 | if (acpi_gbl_mutex_info[i].owner_id == this_thread_id) { | ||
247 | if (i == mutex_id) { | ||
248 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, | ||
249 | "Mutex [%s] already acquired by this thread [%X]\n", | ||
250 | acpi_ut_get_mutex_name (mutex_id), this_thread_id)); | ||
251 | |||
252 | return (AE_ALREADY_ACQUIRED); | ||
253 | } | ||
254 | |||
255 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, | ||
256 | "Invalid acquire order: Thread %X owns [%s], wants [%s]\n", | ||
257 | this_thread_id, acpi_ut_get_mutex_name (i), | ||
258 | acpi_ut_get_mutex_name (mutex_id))); | ||
259 | |||
260 | return (AE_ACQUIRE_DEADLOCK); | ||
261 | } | ||
262 | } | ||
263 | } | ||
264 | #endif | ||
265 | |||
266 | ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, | ||
267 | "Thread %X attempting to acquire Mutex [%s]\n", | ||
268 | this_thread_id, acpi_ut_get_mutex_name (mutex_id))); | ||
269 | |||
270 | status = acpi_os_wait_semaphore (acpi_gbl_mutex_info[mutex_id].mutex, | ||
271 | 1, ACPI_WAIT_FOREVER); | ||
272 | if (ACPI_SUCCESS (status)) { | ||
273 | ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Thread %X acquired Mutex [%s]\n", | ||
274 | this_thread_id, acpi_ut_get_mutex_name (mutex_id))); | ||
275 | |||
276 | acpi_gbl_mutex_info[mutex_id].use_count++; | ||
277 | acpi_gbl_mutex_info[mutex_id].owner_id = this_thread_id; | ||
278 | } | ||
279 | else { | ||
280 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, | ||
281 | "Thread %X could not acquire Mutex [%s] %s\n", | ||
282 | this_thread_id, acpi_ut_get_mutex_name (mutex_id), | ||
283 | acpi_format_exception (status))); | ||
284 | } | ||
285 | |||
286 | return (status); | ||
287 | } | ||
288 | |||
289 | |||
290 | /******************************************************************************* | ||
291 | * | ||
292 | * FUNCTION: acpi_ut_release_mutex | ||
293 | * | ||
294 | * PARAMETERS: mutex_iD - ID of the mutex to be released | ||
295 | * | ||
296 | * RETURN: Status | ||
297 | * | ||
298 | * DESCRIPTION: Release a mutex object. | ||
299 | * | ||
300 | ******************************************************************************/ | ||
301 | |||
302 | acpi_status | ||
303 | acpi_ut_release_mutex ( | ||
304 | acpi_mutex_handle mutex_id) | ||
305 | { | ||
306 | acpi_status status; | ||
307 | u32 this_thread_id; | ||
308 | |||
309 | |||
310 | ACPI_FUNCTION_NAME ("ut_release_mutex"); | ||
311 | |||
312 | |||
313 | this_thread_id = acpi_os_get_thread_id (); | ||
314 | ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, | ||
315 | "Thread %X releasing Mutex [%s]\n", this_thread_id, | ||
316 | acpi_ut_get_mutex_name (mutex_id))); | ||
317 | |||
318 | if (mutex_id > MAX_MUTEX) { | ||
319 | return (AE_BAD_PARAMETER); | ||
320 | } | ||
321 | |||
322 | /* | ||
323 | * Mutex must be acquired in order to release it! | ||
324 | */ | ||
325 | if (acpi_gbl_mutex_info[mutex_id].owner_id == ACPI_MUTEX_NOT_ACQUIRED) { | ||
326 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, | ||
327 | "Mutex [%s] is not acquired, cannot release\n", | ||
328 | acpi_ut_get_mutex_name (mutex_id))); | ||
329 | |||
330 | return (AE_NOT_ACQUIRED); | ||
331 | } | ||
332 | |||
333 | #ifdef ACPI_MUTEX_DEBUG | ||
334 | { | ||
335 | u32 i; | ||
336 | /* | ||
337 | * Mutex debug code, for internal debugging only. | ||
338 | * | ||
339 | * Deadlock prevention. Check if this thread owns any mutexes of value | ||
340 | * greater than this one. If so, the thread has violated the mutex | ||
341 | * ordering rule. This indicates a coding error somewhere in | ||
342 | * the ACPI subsystem code. | ||
343 | */ | ||
344 | for (i = mutex_id; i < MAX_MUTEX; i++) { | ||
345 | if (acpi_gbl_mutex_info[i].owner_id == this_thread_id) { | ||
346 | if (i == mutex_id) { | ||
347 | continue; | ||
348 | } | ||
349 | |||
350 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, | ||
351 | "Invalid release order: owns [%s], releasing [%s]\n", | ||
352 | acpi_ut_get_mutex_name (i), acpi_ut_get_mutex_name (mutex_id))); | ||
353 | |||
354 | return (AE_RELEASE_DEADLOCK); | ||
355 | } | ||
356 | } | ||
357 | } | ||
358 | #endif | ||
359 | |||
360 | /* Mark unlocked FIRST */ | ||
361 | |||
362 | acpi_gbl_mutex_info[mutex_id].owner_id = ACPI_MUTEX_NOT_ACQUIRED; | ||
363 | |||
364 | status = acpi_os_signal_semaphore (acpi_gbl_mutex_info[mutex_id].mutex, 1); | ||
365 | |||
366 | if (ACPI_FAILURE (status)) { | ||
367 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, | ||
368 | "Thread %X could not release Mutex [%s] %s\n", | ||
369 | this_thread_id, acpi_ut_get_mutex_name (mutex_id), | ||
370 | acpi_format_exception (status))); | ||
371 | } | ||
372 | else { | ||
373 | ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Thread %X released Mutex [%s]\n", | ||
374 | this_thread_id, acpi_ut_get_mutex_name (mutex_id))); | ||
375 | } | ||
376 | |||
377 | return (status); | ||
378 | } | ||
379 | |||
380 | |||
diff --git a/drivers/acpi/utilities/utobject.c b/drivers/acpi/utilities/utobject.c index cd3899b9cc5a..19178e142951 100644 --- a/drivers/acpi/utilities/utobject.c +++ b/drivers/acpi/utilities/utobject.c | |||
@@ -338,7 +338,7 @@ acpi_ut_allocate_object_desc_dbg ( | |||
338 | ACPI_FUNCTION_TRACE ("ut_allocate_object_desc_dbg"); | 338 | ACPI_FUNCTION_TRACE ("ut_allocate_object_desc_dbg"); |
339 | 339 | ||
340 | 340 | ||
341 | object = acpi_ut_acquire_from_cache (ACPI_MEM_LIST_OPERAND); | 341 | object = acpi_os_acquire_object (acpi_gbl_operand_cache); |
342 | if (!object) { | 342 | if (!object) { |
343 | _ACPI_REPORT_ERROR (module_name, line_number, component_id, | 343 | _ACPI_REPORT_ERROR (module_name, line_number, component_id, |
344 | ("Could not allocate an object descriptor\n")); | 344 | ("Could not allocate an object descriptor\n")); |
@@ -347,7 +347,7 @@ acpi_ut_allocate_object_desc_dbg ( | |||
347 | } | 347 | } |
348 | 348 | ||
349 | /* Mark the descriptor type */ | 349 | /* Mark the descriptor type */ |
350 | 350 | memset(object, 0, sizeof(union acpi_operand_object)); | |
351 | ACPI_SET_DESCRIPTOR_TYPE (object, ACPI_DESC_TYPE_OPERAND); | 351 | ACPI_SET_DESCRIPTOR_TYPE (object, ACPI_DESC_TYPE_OPERAND); |
352 | 352 | ||
353 | ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "%p Size %X\n", | 353 | ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "%p Size %X\n", |
@@ -385,37 +385,9 @@ acpi_ut_delete_object_desc ( | |||
385 | return_VOID; | 385 | return_VOID; |
386 | } | 386 | } |
387 | 387 | ||
388 | acpi_ut_release_to_cache (ACPI_MEM_LIST_OPERAND, object); | 388 | (void) acpi_os_release_object (acpi_gbl_operand_cache, object); |
389 | |||
390 | return_VOID; | ||
391 | } | ||
392 | |||
393 | |||
394 | #ifdef ACPI_ENABLE_OBJECT_CACHE | ||
395 | /******************************************************************************* | ||
396 | * | ||
397 | * FUNCTION: acpi_ut_delete_object_cache | ||
398 | * | ||
399 | * PARAMETERS: None | ||
400 | * | ||
401 | * RETURN: None | ||
402 | * | ||
403 | * DESCRIPTION: Purge the global state object cache. Used during subsystem | ||
404 | * termination. | ||
405 | * | ||
406 | ******************************************************************************/ | ||
407 | |||
408 | void | ||
409 | acpi_ut_delete_object_cache ( | ||
410 | void) | ||
411 | { | ||
412 | ACPI_FUNCTION_TRACE ("ut_delete_object_cache"); | ||
413 | |||
414 | |||
415 | acpi_ut_delete_generic_cache (ACPI_MEM_LIST_OPERAND); | ||
416 | return_VOID; | 389 | return_VOID; |
417 | } | 390 | } |
418 | #endif | ||
419 | 391 | ||
420 | 392 | ||
421 | /******************************************************************************* | 393 | /******************************************************************************* |
diff --git a/drivers/acpi/utilities/utstate.c b/drivers/acpi/utilities/utstate.c new file mode 100644 index 000000000000..192e7ac95690 --- /dev/null +++ b/drivers/acpi/utilities/utstate.c | |||
@@ -0,0 +1,376 @@ | |||
1 | /******************************************************************************* | ||
2 | * | ||
3 | * Module Name: utstate - state object support procedures | ||
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 ("utstate") | ||
49 | |||
50 | |||
51 | /******************************************************************************* | ||
52 | * | ||
53 | * FUNCTION: acpi_ut_create_pkg_state_and_push | ||
54 | * | ||
55 | * PARAMETERS: Object - Object to be added to the new state | ||
56 | * Action - Increment/Decrement | ||
57 | * state_list - List the state will be added to | ||
58 | * | ||
59 | * RETURN: Status | ||
60 | * | ||
61 | * DESCRIPTION: Create a new state and push it | ||
62 | * | ||
63 | ******************************************************************************/ | ||
64 | |||
65 | acpi_status | ||
66 | acpi_ut_create_pkg_state_and_push ( | ||
67 | void *internal_object, | ||
68 | void *external_object, | ||
69 | u16 index, | ||
70 | union acpi_generic_state **state_list) | ||
71 | { | ||
72 | union acpi_generic_state *state; | ||
73 | |||
74 | |||
75 | ACPI_FUNCTION_ENTRY (); | ||
76 | |||
77 | |||
78 | state = acpi_ut_create_pkg_state (internal_object, external_object, index); | ||
79 | if (!state) { | ||
80 | return (AE_NO_MEMORY); | ||
81 | } | ||
82 | |||
83 | acpi_ut_push_generic_state (state_list, state); | ||
84 | return (AE_OK); | ||
85 | } | ||
86 | |||
87 | |||
88 | /******************************************************************************* | ||
89 | * | ||
90 | * FUNCTION: acpi_ut_push_generic_state | ||
91 | * | ||
92 | * PARAMETERS: list_head - Head of the state stack | ||
93 | * State - State object to push | ||
94 | * | ||
95 | * RETURN: None | ||
96 | * | ||
97 | * DESCRIPTION: Push a state object onto a state stack | ||
98 | * | ||
99 | ******************************************************************************/ | ||
100 | |||
101 | void | ||
102 | acpi_ut_push_generic_state ( | ||
103 | union acpi_generic_state **list_head, | ||
104 | union acpi_generic_state *state) | ||
105 | { | ||
106 | ACPI_FUNCTION_TRACE ("ut_push_generic_state"); | ||
107 | |||
108 | |||
109 | /* Push the state object onto the front of the list (stack) */ | ||
110 | |||
111 | state->common.next = *list_head; | ||
112 | *list_head = state; | ||
113 | |||
114 | return_VOID; | ||
115 | } | ||
116 | |||
117 | |||
118 | /******************************************************************************* | ||
119 | * | ||
120 | * FUNCTION: acpi_ut_pop_generic_state | ||
121 | * | ||
122 | * PARAMETERS: list_head - Head of the state stack | ||
123 | * | ||
124 | * RETURN: The popped state object | ||
125 | * | ||
126 | * DESCRIPTION: Pop a state object from a state stack | ||
127 | * | ||
128 | ******************************************************************************/ | ||
129 | |||
130 | union acpi_generic_state * | ||
131 | acpi_ut_pop_generic_state ( | ||
132 | union acpi_generic_state **list_head) | ||
133 | { | ||
134 | union acpi_generic_state *state; | ||
135 | |||
136 | |||
137 | ACPI_FUNCTION_TRACE ("ut_pop_generic_state"); | ||
138 | |||
139 | |||
140 | /* Remove the state object at the head of the list (stack) */ | ||
141 | |||
142 | state = *list_head; | ||
143 | if (state) { | ||
144 | /* Update the list head */ | ||
145 | |||
146 | *list_head = state->common.next; | ||
147 | } | ||
148 | |||
149 | return_PTR (state); | ||
150 | } | ||
151 | |||
152 | |||
153 | /******************************************************************************* | ||
154 | * | ||
155 | * FUNCTION: acpi_ut_create_generic_state | ||
156 | * | ||
157 | * PARAMETERS: None | ||
158 | * | ||
159 | * RETURN: The new state object. NULL on failure. | ||
160 | * | ||
161 | * DESCRIPTION: Create a generic state object. Attempt to obtain one from | ||
162 | * the global state cache; If none available, create a new one. | ||
163 | * | ||
164 | ******************************************************************************/ | ||
165 | |||
166 | union acpi_generic_state * | ||
167 | acpi_ut_create_generic_state ( | ||
168 | void) | ||
169 | { | ||
170 | union acpi_generic_state *state; | ||
171 | |||
172 | |||
173 | ACPI_FUNCTION_ENTRY (); | ||
174 | |||
175 | |||
176 | state = acpi_os_acquire_object (acpi_gbl_state_cache); | ||
177 | if (state) { | ||
178 | /* Initialize */ | ||
179 | memset(state, 0, sizeof(union acpi_generic_state)); | ||
180 | state->common.data_type = ACPI_DESC_TYPE_STATE; | ||
181 | } | ||
182 | |||
183 | return (state); | ||
184 | } | ||
185 | |||
186 | |||
187 | /******************************************************************************* | ||
188 | * | ||
189 | * FUNCTION: acpi_ut_create_thread_state | ||
190 | * | ||
191 | * PARAMETERS: None | ||
192 | * | ||
193 | * RETURN: New Thread State. NULL on failure | ||
194 | * | ||
195 | * DESCRIPTION: Create a "Thread State" - a flavor of the generic state used | ||
196 | * to track per-thread info during method execution | ||
197 | * | ||
198 | ******************************************************************************/ | ||
199 | |||
200 | struct acpi_thread_state * | ||
201 | acpi_ut_create_thread_state ( | ||
202 | void) | ||
203 | { | ||
204 | union acpi_generic_state *state; | ||
205 | |||
206 | |||
207 | ACPI_FUNCTION_TRACE ("ut_create_thread_state"); | ||
208 | |||
209 | |||
210 | /* Create the generic state object */ | ||
211 | |||
212 | state = acpi_ut_create_generic_state (); | ||
213 | if (!state) { | ||
214 | return_PTR (NULL); | ||
215 | } | ||
216 | |||
217 | /* Init fields specific to the update struct */ | ||
218 | |||
219 | state->common.data_type = ACPI_DESC_TYPE_STATE_THREAD; | ||
220 | state->thread.thread_id = acpi_os_get_thread_id (); | ||
221 | |||
222 | return_PTR ((struct acpi_thread_state *) state); | ||
223 | } | ||
224 | |||
225 | |||
226 | /******************************************************************************* | ||
227 | * | ||
228 | * FUNCTION: acpi_ut_create_update_state | ||
229 | * | ||
230 | * PARAMETERS: Object - Initial Object to be installed in the state | ||
231 | * Action - Update action to be performed | ||
232 | * | ||
233 | * RETURN: New state object, null on failure | ||
234 | * | ||
235 | * DESCRIPTION: Create an "Update State" - a flavor of the generic state used | ||
236 | * to update reference counts and delete complex objects such | ||
237 | * as packages. | ||
238 | * | ||
239 | ******************************************************************************/ | ||
240 | |||
241 | union acpi_generic_state * | ||
242 | acpi_ut_create_update_state ( | ||
243 | union acpi_operand_object *object, | ||
244 | u16 action) | ||
245 | { | ||
246 | union acpi_generic_state *state; | ||
247 | |||
248 | |||
249 | ACPI_FUNCTION_TRACE_PTR ("ut_create_update_state", object); | ||
250 | |||
251 | |||
252 | /* Create the generic state object */ | ||
253 | |||
254 | state = acpi_ut_create_generic_state (); | ||
255 | if (!state) { | ||
256 | return_PTR (NULL); | ||
257 | } | ||
258 | |||
259 | /* Init fields specific to the update struct */ | ||
260 | |||
261 | state->common.data_type = ACPI_DESC_TYPE_STATE_UPDATE; | ||
262 | state->update.object = object; | ||
263 | state->update.value = action; | ||
264 | |||
265 | return_PTR (state); | ||
266 | } | ||
267 | |||
268 | |||
269 | /******************************************************************************* | ||
270 | * | ||
271 | * FUNCTION: acpi_ut_create_pkg_state | ||
272 | * | ||
273 | * PARAMETERS: Object - Initial Object to be installed in the state | ||
274 | * Action - Update action to be performed | ||
275 | * | ||
276 | * RETURN: New state object, null on failure | ||
277 | * | ||
278 | * DESCRIPTION: Create a "Package State" | ||
279 | * | ||
280 | ******************************************************************************/ | ||
281 | |||
282 | union acpi_generic_state * | ||
283 | acpi_ut_create_pkg_state ( | ||
284 | void *internal_object, | ||
285 | void *external_object, | ||
286 | u16 index) | ||
287 | { | ||
288 | union acpi_generic_state *state; | ||
289 | |||
290 | |||
291 | ACPI_FUNCTION_TRACE_PTR ("ut_create_pkg_state", internal_object); | ||
292 | |||
293 | |||
294 | /* Create the generic state object */ | ||
295 | |||
296 | state = acpi_ut_create_generic_state (); | ||
297 | if (!state) { | ||
298 | return_PTR (NULL); | ||
299 | } | ||
300 | |||
301 | /* Init fields specific to the update struct */ | ||
302 | |||
303 | state->common.data_type = ACPI_DESC_TYPE_STATE_PACKAGE; | ||
304 | state->pkg.source_object = (union acpi_operand_object *) internal_object; | ||
305 | state->pkg.dest_object = external_object; | ||
306 | state->pkg.index = index; | ||
307 | state->pkg.num_packages = 1; | ||
308 | |||
309 | return_PTR (state); | ||
310 | } | ||
311 | |||
312 | |||
313 | /******************************************************************************* | ||
314 | * | ||
315 | * FUNCTION: acpi_ut_create_control_state | ||
316 | * | ||
317 | * PARAMETERS: None | ||
318 | * | ||
319 | * RETURN: New state object, null on failure | ||
320 | * | ||
321 | * DESCRIPTION: Create a "Control State" - a flavor of the generic state used | ||
322 | * to support nested IF/WHILE constructs in the AML. | ||
323 | * | ||
324 | ******************************************************************************/ | ||
325 | |||
326 | union acpi_generic_state * | ||
327 | acpi_ut_create_control_state ( | ||
328 | void) | ||
329 | { | ||
330 | union acpi_generic_state *state; | ||
331 | |||
332 | |||
333 | ACPI_FUNCTION_TRACE ("ut_create_control_state"); | ||
334 | |||
335 | |||
336 | /* Create the generic state object */ | ||
337 | |||
338 | state = acpi_ut_create_generic_state (); | ||
339 | if (!state) { | ||
340 | return_PTR (NULL); | ||
341 | } | ||
342 | |||
343 | /* Init fields specific to the control struct */ | ||
344 | |||
345 | state->common.data_type = ACPI_DESC_TYPE_STATE_CONTROL; | ||
346 | state->common.state = ACPI_CONTROL_CONDITIONAL_EXECUTING; | ||
347 | |||
348 | return_PTR (state); | ||
349 | } | ||
350 | |||
351 | |||
352 | /******************************************************************************* | ||
353 | * | ||
354 | * FUNCTION: acpi_ut_delete_generic_state | ||
355 | * | ||
356 | * PARAMETERS: State - The state object to be deleted | ||
357 | * | ||
358 | * RETURN: None | ||
359 | * | ||
360 | * DESCRIPTION: Put a state object back into the global state cache. The object | ||
361 | * is not actually freed at this time. | ||
362 | * | ||
363 | ******************************************************************************/ | ||
364 | |||
365 | void | ||
366 | acpi_ut_delete_generic_state ( | ||
367 | union acpi_generic_state *state) | ||
368 | { | ||
369 | ACPI_FUNCTION_TRACE ("ut_delete_generic_state"); | ||
370 | |||
371 | |||
372 | (void) acpi_os_release_object (acpi_gbl_state_cache, state); | ||
373 | return_VOID; | ||
374 | } | ||
375 | |||
376 | |||
diff --git a/drivers/acpi/utilities/utxface.c b/drivers/acpi/utilities/utxface.c index e8803d810656..850da6817423 100644 --- a/drivers/acpi/utilities/utxface.c +++ b/drivers/acpi/utilities/utxface.c | |||
@@ -46,8 +46,6 @@ | |||
46 | #include <acpi/acpi.h> | 46 | #include <acpi/acpi.h> |
47 | #include <acpi/acevents.h> | 47 | #include <acpi/acevents.h> |
48 | #include <acpi/acnamesp.h> | 48 | #include <acpi/acnamesp.h> |
49 | #include <acpi/acparser.h> | ||
50 | #include <acpi/acdispat.h> | ||
51 | #include <acpi/acdebug.h> | 49 | #include <acpi/acdebug.h> |
52 | 50 | ||
53 | #define _COMPONENT ACPI_UTILITIES | 51 | #define _COMPONENT ACPI_UTILITIES |
@@ -79,11 +77,6 @@ acpi_initialize_subsystem ( | |||
79 | 77 | ||
80 | ACPI_DEBUG_EXEC (acpi_ut_init_stack_ptr_trace ()); | 78 | ACPI_DEBUG_EXEC (acpi_ut_init_stack_ptr_trace ()); |
81 | 79 | ||
82 | |||
83 | /* Initialize all globals used by the subsystem */ | ||
84 | |||
85 | acpi_ut_init_globals (); | ||
86 | |||
87 | /* Initialize the OS-Dependent layer */ | 80 | /* Initialize the OS-Dependent layer */ |
88 | 81 | ||
89 | status = acpi_os_initialize (); | 82 | status = acpi_os_initialize (); |
@@ -93,6 +86,10 @@ acpi_initialize_subsystem ( | |||
93 | return_ACPI_STATUS (status); | 86 | return_ACPI_STATUS (status); |
94 | } | 87 | } |
95 | 88 | ||
89 | /* Initialize all globals used by the subsystem */ | ||
90 | |||
91 | acpi_ut_init_globals (); | ||
92 | |||
96 | /* Create the default mutex objects */ | 93 | /* Create the default mutex objects */ |
97 | 94 | ||
98 | status = acpi_ut_mutex_initialize (); | 95 | status = acpi_ut_mutex_initialize (); |
@@ -522,13 +519,9 @@ acpi_purge_cached_objects ( | |||
522 | { | 519 | { |
523 | ACPI_FUNCTION_TRACE ("acpi_purge_cached_objects"); | 520 | ACPI_FUNCTION_TRACE ("acpi_purge_cached_objects"); |
524 | 521 | ||
525 | 522 | (void) acpi_os_purge_cache (acpi_gbl_state_cache); | |
526 | #ifdef ACPI_ENABLE_OBJECT_CACHE | 523 | (void) acpi_os_purge_cache (acpi_gbl_operand_cache); |
527 | acpi_ut_delete_generic_state_cache (); | 524 | (void) acpi_os_purge_cache (acpi_gbl_ps_node_cache); |
528 | acpi_ut_delete_object_cache (); | 525 | (void) acpi_os_purge_cache (acpi_gbl_ps_node_ext_cache); |
529 | acpi_ds_delete_walk_state_cache (); | ||
530 | acpi_ps_delete_parse_cache (); | ||
531 | #endif | ||
532 | |||
533 | return_ACPI_STATUS (AE_OK); | 526 | return_ACPI_STATUS (AE_OK); |
534 | } | 527 | } |