1
2
3
4
5
6
7
8#include <acpi/acpi.h>
9#include "accommon.h"
10
11#define _COMPONENT ACPI_UTILITIES
12ACPI_MODULE_NAME("utmutex")
13
14
15static acpi_status acpi_ut_create_mutex(acpi_mutex_handle mutex_id);
16
17static void acpi_ut_delete_mutex(acpi_mutex_handle mutex_id);
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32acpi_status acpi_ut_mutex_initialize(void)
33{
34 u32 i;
35 acpi_status status;
36
37 ACPI_FUNCTION_TRACE(ut_mutex_initialize);
38
39
40
41 for (i = 0; i < ACPI_NUM_MUTEX; i++) {
42 status = acpi_ut_create_mutex(i);
43 if (ACPI_FAILURE(status)) {
44 return_ACPI_STATUS(status);
45 }
46 }
47
48
49
50 status = acpi_os_create_lock (&acpi_gbl_gpe_lock);
51 if (ACPI_FAILURE (status)) {
52 return_ACPI_STATUS (status);
53 }
54
55 status = acpi_os_create_raw_lock(&acpi_gbl_hardware_lock);
56 if (ACPI_FAILURE (status)) {
57 return_ACPI_STATUS (status);
58 }
59
60 status = acpi_os_create_lock(&acpi_gbl_reference_count_lock);
61 if (ACPI_FAILURE(status)) {
62 return_ACPI_STATUS(status);
63 }
64
65
66
67 status = acpi_os_create_mutex(&acpi_gbl_osi_mutex);
68 if (ACPI_FAILURE(status)) {
69 return_ACPI_STATUS(status);
70 }
71
72
73
74 status = acpi_ut_create_rw_lock(&acpi_gbl_namespace_rw_lock);
75 if (ACPI_FAILURE(status)) {
76 return_ACPI_STATUS(status);
77 }
78
79 return_ACPI_STATUS(status);
80}
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95void acpi_ut_mutex_terminate(void)
96{
97 u32 i;
98
99 ACPI_FUNCTION_TRACE(ut_mutex_terminate);
100
101
102
103 for (i = 0; i < ACPI_NUM_MUTEX; i++) {
104 acpi_ut_delete_mutex(i);
105 }
106
107 acpi_os_delete_mutex(acpi_gbl_osi_mutex);
108
109
110
111 acpi_os_delete_lock(acpi_gbl_gpe_lock);
112 acpi_os_delete_raw_lock(acpi_gbl_hardware_lock);
113 acpi_os_delete_lock(acpi_gbl_reference_count_lock);
114
115
116
117 acpi_ut_delete_rw_lock(&acpi_gbl_namespace_rw_lock);
118 return_VOID;
119}
120
121
122
123
124
125
126
127
128
129
130
131
132
133static acpi_status acpi_ut_create_mutex(acpi_mutex_handle mutex_id)
134{
135 acpi_status status = AE_OK;
136
137 ACPI_FUNCTION_TRACE_U32(ut_create_mutex, mutex_id);
138
139 if (!acpi_gbl_mutex_info[mutex_id].mutex) {
140 status =
141 acpi_os_create_mutex(&acpi_gbl_mutex_info[mutex_id].mutex);
142 acpi_gbl_mutex_info[mutex_id].thread_id =
143 ACPI_MUTEX_NOT_ACQUIRED;
144 acpi_gbl_mutex_info[mutex_id].use_count = 0;
145 }
146
147 return_ACPI_STATUS(status);
148}
149
150
151
152
153
154
155
156
157
158
159
160
161
162static void acpi_ut_delete_mutex(acpi_mutex_handle mutex_id)
163{
164
165 ACPI_FUNCTION_TRACE_U32(ut_delete_mutex, mutex_id);
166
167 acpi_os_delete_mutex(acpi_gbl_mutex_info[mutex_id].mutex);
168
169 acpi_gbl_mutex_info[mutex_id].mutex = NULL;
170 acpi_gbl_mutex_info[mutex_id].thread_id = ACPI_MUTEX_NOT_ACQUIRED;
171
172 return_VOID;
173}
174
175
176
177
178
179
180
181
182
183
184
185
186
187acpi_status acpi_ut_acquire_mutex(acpi_mutex_handle mutex_id)
188{
189 acpi_status status;
190 acpi_thread_id this_thread_id;
191
192 ACPI_FUNCTION_NAME(ut_acquire_mutex);
193
194 if (mutex_id > ACPI_MAX_MUTEX) {
195 return (AE_BAD_PARAMETER);
196 }
197
198 this_thread_id = acpi_os_get_thread_id();
199
200#ifdef ACPI_MUTEX_DEBUG
201 {
202 u32 i;
203
204
205
206
207
208
209
210
211 for (i = mutex_id; i < ACPI_NUM_MUTEX; i++) {
212 if (acpi_gbl_mutex_info[i].thread_id == this_thread_id) {
213 if (i == mutex_id) {
214 ACPI_ERROR((AE_INFO,
215 "Mutex [%s] already acquired by this thread [%u]",
216 acpi_ut_get_mutex_name
217 (mutex_id),
218 (u32)this_thread_id));
219
220 return (AE_ALREADY_ACQUIRED);
221 }
222
223 ACPI_ERROR((AE_INFO,
224 "Invalid acquire order: Thread %u owns [%s], wants [%s]",
225 (u32)this_thread_id,
226 acpi_ut_get_mutex_name(i),
227 acpi_ut_get_mutex_name(mutex_id)));
228
229 return (AE_ACQUIRE_DEADLOCK);
230 }
231 }
232 }
233#endif
234
235 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
236 "Thread %u attempting to acquire Mutex [%s]\n",
237 (u32)this_thread_id,
238 acpi_ut_get_mutex_name(mutex_id)));
239
240 status =
241 acpi_os_acquire_mutex(acpi_gbl_mutex_info[mutex_id].mutex,
242 ACPI_WAIT_FOREVER);
243 if (ACPI_SUCCESS(status)) {
244 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
245 "Thread %u acquired Mutex [%s]\n",
246 (u32)this_thread_id,
247 acpi_ut_get_mutex_name(mutex_id)));
248
249 acpi_gbl_mutex_info[mutex_id].use_count++;
250 acpi_gbl_mutex_info[mutex_id].thread_id = this_thread_id;
251 } else {
252 ACPI_EXCEPTION((AE_INFO, status,
253 "Thread %u could not acquire Mutex [%s] (0x%X)",
254 (u32)this_thread_id,
255 acpi_ut_get_mutex_name(mutex_id), mutex_id));
256 }
257
258 return (status);
259}
260
261
262
263
264
265
266
267
268
269
270
271
272
273acpi_status acpi_ut_release_mutex(acpi_mutex_handle mutex_id)
274{
275 ACPI_FUNCTION_NAME(ut_release_mutex);
276
277 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Thread %u releasing Mutex [%s]\n",
278 (u32)acpi_os_get_thread_id(),
279 acpi_ut_get_mutex_name(mutex_id)));
280
281 if (mutex_id > ACPI_MAX_MUTEX) {
282 return (AE_BAD_PARAMETER);
283 }
284
285
286
287
288 if (acpi_gbl_mutex_info[mutex_id].thread_id == ACPI_MUTEX_NOT_ACQUIRED) {
289 ACPI_ERROR((AE_INFO,
290 "Mutex [%s] (0x%X) is not acquired, cannot release",
291 acpi_ut_get_mutex_name(mutex_id), mutex_id));
292
293 return (AE_NOT_ACQUIRED);
294 }
295#ifdef ACPI_MUTEX_DEBUG
296 {
297 u32 i;
298
299
300
301
302
303
304
305
306 for (i = mutex_id; i < ACPI_NUM_MUTEX; i++) {
307 if (acpi_gbl_mutex_info[i].thread_id ==
308 acpi_os_get_thread_id()) {
309 if (i == mutex_id) {
310 continue;
311 }
312
313 ACPI_ERROR((AE_INFO,
314 "Invalid release order: owns [%s], releasing [%s]",
315 acpi_ut_get_mutex_name(i),
316 acpi_ut_get_mutex_name(mutex_id)));
317
318 return (AE_RELEASE_DEADLOCK);
319 }
320 }
321 }
322#endif
323
324
325
326 acpi_gbl_mutex_info[mutex_id].thread_id = ACPI_MUTEX_NOT_ACQUIRED;
327
328 acpi_os_release_mutex(acpi_gbl_mutex_info[mutex_id].mutex);
329 return (AE_OK);
330}
331