aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/utilities
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/utilities')
-rw-r--r--drivers/acpi/utilities/Makefile2
-rw-r--r--drivers/acpi/utilities/utalloc.c304
-rw-r--r--drivers/acpi/utilities/utcache.c322
-rw-r--r--drivers/acpi/utilities/utdebug.c4
-rw-r--r--drivers/acpi/utilities/utglobal.c38
-rw-r--r--drivers/acpi/utilities/utinit.c2
-rw-r--r--drivers/acpi/utilities/utmisc.c689
-rw-r--r--drivers/acpi/utilities/utmutex.c380
-rw-r--r--drivers/acpi/utilities/utobject.c34
-rw-r--r--drivers/acpi/utilities/utstate.c376
-rw-r--r--drivers/acpi/utilities/utxface.c23
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
5obj-y := utalloc.o utdebug.o uteval.o utinit.o utmisc.o utxface.o \ 5obj-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
8EXTRA_CFLAGS += $(ACPI_CFLAGS) 8EXTRA_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
53static struct acpi_debug_mem_block * 53static struct acpi_debug_mem_block *
54acpi_ut_find_allocation ( 54acpi_ut_find_allocation (
55 u32 list_id,
56 void *allocation); 55 void *allocation);
57 56
58static acpi_status 57static acpi_status
59acpi_ut_track_allocation ( 58acpi_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
68static acpi_status 66static acpi_status
69acpi_ut_remove_allocation ( 67acpi_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/******************************************************************************* 75static acpi_status
79 * 76acpi_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
92void
93acpi_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
160void * 95acpi_status
161acpi_ut_acquire_from_cache ( 96acpi_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
245void 161acpi_status
246acpi_ut_delete_generic_cache ( 162acpi_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
427static acpi_status
428acpi_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
670static struct acpi_debug_mem_block * 616static struct acpi_debug_mem_block *
671acpi_ut_find_allocation ( 617acpi_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
719static acpi_status 659static acpi_status
720acpi_ut_track_allocation ( 660acpi_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
808static acpi_status 741static acpi_status
809acpi_ut_remove_allocation ( 742acpi_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
67acpi_status
68acpi_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
113acpi_status
114acpi_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
157acpi_status
158acpi_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
192acpi_status
193acpi_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
254void *
255acpi_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
820acpi_ut_init_globals ( 820acpi_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
54static acpi_status
55acpi_ut_create_mutex (
56 acpi_mutex_handle mutex_id);
57
58static acpi_status
59acpi_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
556acpi_status
557acpi_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
594void
595acpi_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
628static acpi_status
629acpi_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
665static acpi_status
666acpi_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
700acpi_status
701acpi_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
785acpi_status
786acpi_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
921acpi_status
922acpi_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
957void
958acpi_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
986union acpi_generic_state *
987acpi_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
1022union acpi_generic_state *
1023acpi_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
1057struct acpi_thread_state *
1058acpi_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
1098union acpi_generic_state *
1099acpi_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
1139union acpi_generic_state *
1140acpi_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
1183union acpi_generic_state *
1184acpi_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
1222void
1223acpi_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
1248void
1249acpi_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
52static acpi_status
53acpi_ut_create_mutex (
54 acpi_mutex_handle mutex_id);
55
56static acpi_status
57acpi_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
73acpi_status
74acpi_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
111void
112acpi_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
145static acpi_status
146acpi_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
182static acpi_status
183acpi_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
217acpi_status
218acpi_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
302acpi_status
303acpi_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
408void
409acpi_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
65acpi_status
66acpi_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
101void
102acpi_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
130union acpi_generic_state *
131acpi_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
166union acpi_generic_state *
167acpi_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
200struct acpi_thread_state *
201acpi_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
241union acpi_generic_state *
242acpi_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
282union acpi_generic_state *
283acpi_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
326union acpi_generic_state *
327acpi_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
365void
366acpi_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}