]>
Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /****************************************************************************** |
2 | * | |
b7ed9a8e | 3 | * Module Name: tbxface - ACPI table-oriented external interfaces |
1da177e4 LT |
4 | * |
5 | *****************************************************************************/ | |
6 | ||
7 | /* | |
7735ca0e | 8 | * Copyright (C) 2000 - 2017, Intel Corp. |
1da177e4 LT |
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 | ||
839e928f LZ |
44 | #define EXPORT_ACPI_INTERFACES |
45 | ||
1da177e4 | 46 | #include <acpi/acpi.h> |
e2f7a777 | 47 | #include "accommon.h" |
e2f7a777 | 48 | #include "actables.h" |
1da177e4 | 49 | |
1da177e4 | 50 | #define _COMPONENT ACPI_TABLES |
4be44fcd | 51 | ACPI_MODULE_NAME("tbxface") |
1da177e4 | 52 | |
77389e12 BM |
53 | /******************************************************************************* |
54 | * | |
55 | * FUNCTION: acpi_allocate_root_table | |
56 | * | |
57 | * PARAMETERS: initial_table_count - Size of initial_table_array, in number of | |
58 | * struct acpi_table_desc structures | |
59 | * | |
60 | * RETURN: Status | |
61 | * | |
ba494bee | 62 | * DESCRIPTION: Allocate a root table array. Used by iASL compiler and |
77389e12 BM |
63 | * acpi_initialize_tables. |
64 | * | |
65 | ******************************************************************************/ | |
77389e12 BM |
66 | acpi_status acpi_allocate_root_table(u32 initial_table_count) |
67 | { | |
68 | ||
b9ee2043 | 69 | acpi_gbl_root_table_list.max_table_count = initial_table_count; |
77389e12 BM |
70 | acpi_gbl_root_table_list.flags = ACPI_ROOT_ALLOW_RESIZE; |
71 | ||
72 | return (acpi_tb_resize_root_table_list()); | |
73 | } | |
74 | ||
1da177e4 LT |
75 | /******************************************************************************* |
76 | * | |
f3d2e786 | 77 | * FUNCTION: acpi_initialize_tables |
1da177e4 | 78 | * |
f3d2e786 BM |
79 | * PARAMETERS: initial_table_array - Pointer to an array of pre-allocated |
80 | * struct acpi_table_desc structures. If NULL, the | |
81 | * array is dynamically allocated. | |
82 | * initial_table_count - Size of initial_table_array, in number of | |
83 | * struct acpi_table_desc structures | |
b7ed9a8e | 84 | * allow_resize - Flag to tell Table Manager if resize of |
f3d2e786 BM |
85 | * pre-allocated array is allowed. Ignored |
86 | * if initial_table_array is NULL. | |
1da177e4 LT |
87 | * |
88 | * RETURN: Status | |
89 | * | |
f3d2e786 BM |
90 | * DESCRIPTION: Initialize the table manager, get the RSDP and RSDT/XSDT. |
91 | * | |
92 | * NOTE: Allows static allocation of the initial table array in order | |
93 | * to avoid the use of dynamic memory in confined environments | |
94 | * such as the kernel boot sequence where it may not be available. | |
95 | * | |
96 | * If the host OS memory managers are initialized, use NULL for | |
97 | * initial_table_array, and the table will be dynamically allocated. | |
1da177e4 LT |
98 | * |
99 | ******************************************************************************/ | |
f3d2e786 | 100 | |
2368b1a1 | 101 | acpi_status ACPI_INIT_FUNCTION |
f5c1e1c5 | 102 | acpi_initialize_tables(struct acpi_table_desc *initial_table_array, |
f3d2e786 | 103 | u32 initial_table_count, u8 allow_resize) |
1da177e4 | 104 | { |
c5fc42ac | 105 | acpi_physical_address rsdp_address; |
4be44fcd | 106 | acpi_status status; |
1da177e4 | 107 | |
f3d2e786 | 108 | ACPI_FUNCTION_TRACE(acpi_initialize_tables); |
1da177e4 | 109 | |
f3d2e786 | 110 | /* |
b7ed9a8e TC |
111 | * Setup the Root Table Array and allocate the table array |
112 | * if requested | |
f3d2e786 BM |
113 | */ |
114 | if (!initial_table_array) { | |
77389e12 | 115 | status = acpi_allocate_root_table(initial_table_count); |
f3d2e786 BM |
116 | if (ACPI_FAILURE(status)) { |
117 | return_ACPI_STATUS(status); | |
118 | } | |
119 | } else { | |
120 | /* Root Table Array has been statically allocated by the host */ | |
121 | ||
4fa4616e | 122 | memset(initial_table_array, 0, |
f5c1e1c5 | 123 | (acpi_size)initial_table_count * |
4fa4616e | 124 | sizeof(struct acpi_table_desc)); |
c5fc42ac | 125 | |
f3d2e786 | 126 | acpi_gbl_root_table_list.tables = initial_table_array; |
b9ee2043 | 127 | acpi_gbl_root_table_list.max_table_count = initial_table_count; |
c5fc42ac | 128 | acpi_gbl_root_table_list.flags = ACPI_ROOT_ORIGIN_UNKNOWN; |
f3d2e786 | 129 | if (allow_resize) { |
c5fc42ac BM |
130 | acpi_gbl_root_table_list.flags |= |
131 | ACPI_ROOT_ALLOW_RESIZE; | |
f3d2e786 | 132 | } |
1da177e4 LT |
133 | } |
134 | ||
c5fc42ac | 135 | /* Get the address of the RSDP */ |
1da177e4 | 136 | |
c5fc42ac BM |
137 | rsdp_address = acpi_os_get_root_pointer(); |
138 | if (!rsdp_address) { | |
f3d2e786 BM |
139 | return_ACPI_STATUS(AE_NOT_FOUND); |
140 | } | |
1da177e4 | 141 | |
f3d2e786 BM |
142 | /* |
143 | * Get the root table (RSDT or XSDT) and extract all entries to the local | |
144 | * Root Table Array. This array contains the information of the RSDT/XSDT | |
145 | * in a common, more useable format. | |
146 | */ | |
97cbb7d1 | 147 | status = acpi_tb_parse_root_table(rsdp_address); |
f3d2e786 BM |
148 | return_ACPI_STATUS(status); |
149 | } | |
1da177e4 | 150 | |
d21f600b LZ |
151 | ACPI_EXPORT_SYMBOL_INIT(acpi_initialize_tables) |
152 | ||
f3d2e786 BM |
153 | /******************************************************************************* |
154 | * | |
155 | * FUNCTION: acpi_reallocate_root_table | |
156 | * | |
157 | * PARAMETERS: None | |
158 | * | |
159 | * RETURN: Status | |
160 | * | |
161 | * DESCRIPTION: Reallocate Root Table List into dynamic memory. Copies the | |
162 | * root list from the previously provided scratch area. Should | |
163 | * be called once dynamic memory allocation is available in the | |
2bc198c1 | 164 | * kernel. |
f3d2e786 BM |
165 | * |
166 | ******************************************************************************/ | |
2368b1a1 | 167 | acpi_status ACPI_INIT_FUNCTION acpi_reallocate_root_table(void) |
f3d2e786 | 168 | { |
2bc198c1 | 169 | acpi_status status; |
173fcf80 | 170 | u32 i; |
f3d2e786 BM |
171 | |
172 | ACPI_FUNCTION_TRACE(acpi_reallocate_root_table); | |
173 | ||
174 | /* | |
175 | * Only reallocate the root table if the host provided a static buffer | |
176 | * for the table array in the call to acpi_initialize_tables. | |
177 | */ | |
c5fc42ac | 178 | if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) { |
f3d2e786 | 179 | return_ACPI_STATUS(AE_SUPPORT); |
1da177e4 LT |
180 | } |
181 | ||
173fcf80 LZ |
182 | /* |
183 | * Ensure OS early boot logic, which is required by some hosts. If the | |
184 | * table state is reported to be wrong, developers should fix the | |
185 | * issue by invoking acpi_put_table() for the reported table during the | |
186 | * early stage. | |
187 | */ | |
188 | for (i = 0; i < acpi_gbl_root_table_list.current_table_count; ++i) { | |
189 | if (acpi_gbl_root_table_list.tables[i].pointer) { | |
190 | ACPI_ERROR((AE_INFO, | |
191 | "Table [%4.4s] is not invalidated during early boot stage", | |
192 | acpi_gbl_root_table_list.tables[i]. | |
193 | signature.ascii)); | |
194 | } | |
195 | } | |
196 | ||
2bc198c1 | 197 | acpi_gbl_root_table_list.flags |= ACPI_ROOT_ALLOW_RESIZE; |
1da177e4 | 198 | |
2bc198c1 LZ |
199 | status = acpi_tb_resize_root_table_list(); |
200 | return_ACPI_STATUS(status); | |
f3d2e786 | 201 | } |
fd350943 | 202 | |
d21f600b LZ |
203 | ACPI_EXPORT_SYMBOL_INIT(acpi_reallocate_root_table) |
204 | ||
ec41f193 | 205 | /******************************************************************************* |
f3d2e786 BM |
206 | * |
207 | * FUNCTION: acpi_get_table_header | |
208 | * | |
ba494bee BM |
209 | * PARAMETERS: signature - ACPI signature of needed table |
210 | * instance - Which instance (for SSDTs) | |
428f2112 | 211 | * out_table_header - The pointer to the table header to fill |
f3d2e786 BM |
212 | * |
213 | * RETURN: Status and pointer to mapped table header | |
214 | * | |
215 | * DESCRIPTION: Finds an ACPI table header. | |
216 | * | |
217 | * NOTE: Caller is responsible in unmapping the header with | |
218 | * acpi_os_unmap_memory | |
219 | * | |
ec41f193 | 220 | ******************************************************************************/ |
f3d2e786 BM |
221 | acpi_status |
222 | acpi_get_table_header(char *signature, | |
67a119f9 | 223 | u32 instance, struct acpi_table_header *out_table_header) |
f3d2e786 | 224 | { |
5582982d LZ |
225 | u32 i; |
226 | u32 j; | |
428f2112 | 227 | struct acpi_table_header *header; |
0c9938cc | 228 | |
c5fc42ac BM |
229 | /* Parameter validation */ |
230 | ||
231 | if (!signature || !out_table_header) { | |
232 | return (AE_BAD_PARAMETER); | |
233 | } | |
234 | ||
ec41f193 BM |
235 | /* Walk the root table list */ |
236 | ||
b9ee2043 BM |
237 | for (i = 0, j = 0; i < acpi_gbl_root_table_list.current_table_count; |
238 | i++) { | |
f3d2e786 BM |
239 | if (!ACPI_COMPARE_NAME |
240 | (&(acpi_gbl_root_table_list.tables[i].signature), | |
241 | signature)) { | |
242 | continue; | |
0c9938cc RM |
243 | } |
244 | ||
f3d2e786 BM |
245 | if (++j < instance) { |
246 | continue; | |
247 | } | |
1da177e4 | 248 | |
428f2112 | 249 | if (!acpi_gbl_root_table_list.tables[i].pointer) { |
ec41f193 BM |
250 | if ((acpi_gbl_root_table_list.tables[i].flags & |
251 | ACPI_TABLE_ORIGIN_MASK) == | |
ed6f1d44 | 252 | ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL) { |
428f2112 AS |
253 | header = |
254 | acpi_os_map_memory(acpi_gbl_root_table_list. | |
255 | tables[i].address, | |
256 | sizeof(struct | |
257 | acpi_table_header)); | |
258 | if (!header) { | |
68aafc35 | 259 | return (AE_NO_MEMORY); |
428f2112 | 260 | } |
52c1d803 | 261 | |
4fa4616e BM |
262 | memcpy(out_table_header, header, |
263 | sizeof(struct acpi_table_header)); | |
428f2112 AS |
264 | acpi_os_unmap_memory(header, |
265 | sizeof(struct | |
266 | acpi_table_header)); | |
267 | } else { | |
68aafc35 | 268 | return (AE_NOT_FOUND); |
428f2112 AS |
269 | } |
270 | } else { | |
4fa4616e BM |
271 | memcpy(out_table_header, |
272 | acpi_gbl_root_table_list.tables[i].pointer, | |
273 | sizeof(struct acpi_table_header)); | |
f3d2e786 | 274 | } |
f3d2e786 | 275 | return (AE_OK); |
1da177e4 LT |
276 | } |
277 | ||
f3d2e786 | 278 | return (AE_NOT_FOUND); |
1da177e4 LT |
279 | } |
280 | ||
f3d2e786 | 281 | ACPI_EXPORT_SYMBOL(acpi_get_table_header) |
8313524a | 282 | |
1da177e4 LT |
283 | /******************************************************************************* |
284 | * | |
174cc718 | 285 | * FUNCTION: acpi_get_table |
1da177e4 | 286 | * |
ba494bee BM |
287 | * PARAMETERS: signature - ACPI signature of needed table |
288 | * instance - Which instance (for SSDTs) | |
f3d2e786 | 289 | * out_table - Where the pointer to the table is returned |
1da177e4 | 290 | * |
b7ed9a8e | 291 | * RETURN: Status and pointer to the requested table |
1da177e4 | 292 | * |
b7ed9a8e TC |
293 | * DESCRIPTION: Finds and verifies an ACPI table. Table must be in the |
294 | * RSDT/XSDT. | |
174cc718 LZ |
295 | * Note that an early stage acpi_get_table() call must be paired |
296 | * with an early stage acpi_put_table() call. otherwise the table | |
297 | * pointer mapped by the early stage mapping implementation may be | |
298 | * erroneously unmapped by the late stage unmapping implementation | |
299 | * in an acpi_put_table() invoked during the late stage. | |
1da177e4 | 300 | * |
ec41f193 | 301 | ******************************************************************************/ |
f3d2e786 | 302 | acpi_status |
174cc718 LZ |
303 | acpi_get_table(char *signature, |
304 | u32 instance, struct acpi_table_header ** out_table) | |
1da177e4 | 305 | { |
5582982d LZ |
306 | u32 i; |
307 | u32 j; | |
174cc718 LZ |
308 | acpi_status status = AE_NOT_FOUND; |
309 | struct acpi_table_desc *table_desc; | |
1da177e4 | 310 | |
c5fc42ac BM |
311 | /* Parameter validation */ |
312 | ||
313 | if (!signature || !out_table) { | |
314 | return (AE_BAD_PARAMETER); | |
315 | } | |
316 | ||
174cc718 LZ |
317 | /* |
318 | * Note that the following line is required by some OSPMs, they only | |
319 | * check if the returned table is NULL instead of the returned status | |
320 | * to determined if this function is succeeded. | |
321 | */ | |
322 | *out_table = NULL; | |
323 | ||
324 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | |
325 | ||
ec41f193 BM |
326 | /* Walk the root table list */ |
327 | ||
b9ee2043 BM |
328 | for (i = 0, j = 0; i < acpi_gbl_root_table_list.current_table_count; |
329 | i++) { | |
174cc718 LZ |
330 | table_desc = &acpi_gbl_root_table_list.tables[i]; |
331 | ||
332 | if (!ACPI_COMPARE_NAME(&table_desc->signature, signature)) { | |
f3d2e786 BM |
333 | continue; |
334 | } | |
1da177e4 | 335 | |
f3d2e786 BM |
336 | if (++j < instance) { |
337 | continue; | |
338 | } | |
1da177e4 | 339 | |
174cc718 LZ |
340 | status = acpi_tb_get_table(table_desc, out_table); |
341 | break; | |
1da177e4 LT |
342 | } |
343 | ||
174cc718 LZ |
344 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); |
345 | return (status); | |
1da177e4 | 346 | } |
d21f600b | 347 | |
174cc718 | 348 | ACPI_EXPORT_SYMBOL(acpi_get_table) |
1da177e4 | 349 | |
174cc718 LZ |
350 | /******************************************************************************* |
351 | * | |
352 | * FUNCTION: acpi_put_table | |
353 | * | |
354 | * PARAMETERS: table - The pointer to the table | |
355 | * | |
356 | * RETURN: None | |
357 | * | |
358 | * DESCRIPTION: Release a table returned by acpi_get_table() and its clones. | |
359 | * Note that it is not safe if this function was invoked after an | |
360 | * uninstallation happened to the original table descriptor. | |
361 | * Currently there is no OSPMs' requirement to handle such | |
362 | * situations. | |
363 | * | |
364 | ******************************************************************************/ | |
365 | void acpi_put_table(struct acpi_table_header *table) | |
7d97277b | 366 | { |
174cc718 LZ |
367 | u32 i; |
368 | struct acpi_table_desc *table_desc; | |
369 | ||
370 | ACPI_FUNCTION_TRACE(acpi_put_table); | |
371 | ||
372 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | |
373 | ||
374 | /* Walk the root table list */ | |
375 | ||
376 | for (i = 0; i < acpi_gbl_root_table_list.current_table_count; i++) { | |
377 | table_desc = &acpi_gbl_root_table_list.tables[i]; | |
7d97277b | 378 | |
174cc718 LZ |
379 | if (table_desc->pointer != table) { |
380 | continue; | |
381 | } | |
382 | ||
383 | acpi_tb_put_table(table_desc); | |
384 | break; | |
385 | } | |
386 | ||
387 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | |
388 | return_VOID; | |
7d97277b | 389 | } |
d21f600b | 390 | |
174cc718 | 391 | ACPI_EXPORT_SYMBOL(acpi_put_table) |
8313524a | 392 | |
1da177e4 LT |
393 | /******************************************************************************* |
394 | * | |
f3d2e786 | 395 | * FUNCTION: acpi_get_table_by_index |
1da177e4 | 396 | * |
f3d2e786 | 397 | * PARAMETERS: table_index - Table index |
174cc718 | 398 | * out_table - Where the pointer to the table is returned |
1da177e4 | 399 | * |
b7ed9a8e | 400 | * RETURN: Status and pointer to the requested table |
1da177e4 | 401 | * |
b7ed9a8e TC |
402 | * DESCRIPTION: Obtain a table by an index into the global table list. Used |
403 | * internally also. | |
1da177e4 LT |
404 | * |
405 | ******************************************************************************/ | |
1da177e4 | 406 | acpi_status |
174cc718 | 407 | acpi_get_table_by_index(u32 table_index, struct acpi_table_header **out_table) |
1da177e4 | 408 | { |
4be44fcd | 409 | acpi_status status; |
1da177e4 | 410 | |
f3d2e786 | 411 | ACPI_FUNCTION_TRACE(acpi_get_table_by_index); |
1da177e4 | 412 | |
c5fc42ac BM |
413 | /* Parameter validation */ |
414 | ||
174cc718 | 415 | if (!out_table) { |
c5fc42ac BM |
416 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
417 | } | |
418 | ||
174cc718 LZ |
419 | /* |
420 | * Note that the following line is required by some OSPMs, they only | |
421 | * check if the returned table is NULL instead of the returned status | |
422 | * to determined if this function is succeeded. | |
423 | */ | |
424 | *out_table = NULL; | |
425 | ||
f3d2e786 | 426 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); |
1da177e4 | 427 | |
f3d2e786 | 428 | /* Validate index */ |
1da177e4 | 429 | |
b9ee2043 | 430 | if (table_index >= acpi_gbl_root_table_list.current_table_count) { |
174cc718 LZ |
431 | status = AE_BAD_PARAMETER; |
432 | goto unlock_and_exit; | |
1da177e4 LT |
433 | } |
434 | ||
174cc718 LZ |
435 | status = |
436 | acpi_tb_get_table(&acpi_gbl_root_table_list.tables[table_index], | |
437 | out_table); | |
1da177e4 | 438 | |
174cc718 | 439 | unlock_and_exit: |
f3d2e786 | 440 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); |
174cc718 | 441 | return_ACPI_STATUS(status); |
1da177e4 LT |
442 | } |
443 | ||
f3d2e786 | 444 | ACPI_EXPORT_SYMBOL(acpi_get_table_by_index) |
1da177e4 | 445 | |
3e08e2d2 LM |
446 | /******************************************************************************* |
447 | * | |
448 | * FUNCTION: acpi_install_table_handler | |
449 | * | |
ba494bee BM |
450 | * PARAMETERS: handler - Table event handler |
451 | * context - Value passed to the handler on each event | |
3e08e2d2 LM |
452 | * |
453 | * RETURN: Status | |
454 | * | |
b7ed9a8e | 455 | * DESCRIPTION: Install a global table event handler. |
3e08e2d2 LM |
456 | * |
457 | ******************************************************************************/ | |
458 | acpi_status | |
b43e1065 | 459 | acpi_install_table_handler(acpi_table_handler handler, void *context) |
3e08e2d2 LM |
460 | { |
461 | acpi_status status; | |
462 | ||
463 | ACPI_FUNCTION_TRACE(acpi_install_table_handler); | |
464 | ||
465 | if (!handler) { | |
466 | return_ACPI_STATUS(AE_BAD_PARAMETER); | |
467 | } | |
468 | ||
469 | status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); | |
470 | if (ACPI_FAILURE(status)) { | |
471 | return_ACPI_STATUS(status); | |
472 | } | |
473 | ||
474 | /* Don't allow more than one handler */ | |
475 | ||
476 | if (acpi_gbl_table_handler) { | |
477 | status = AE_ALREADY_EXISTS; | |
478 | goto cleanup; | |
479 | } | |
480 | ||
481 | /* Install the handler */ | |
482 | ||
483 | acpi_gbl_table_handler = handler; | |
484 | acpi_gbl_table_handler_context = context; | |
485 | ||
10622bf8 | 486 | cleanup: |
3e08e2d2 LM |
487 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); |
488 | return_ACPI_STATUS(status); | |
489 | } | |
490 | ||
491 | ACPI_EXPORT_SYMBOL(acpi_install_table_handler) | |
492 | ||
493 | /******************************************************************************* | |
494 | * | |
495 | * FUNCTION: acpi_remove_table_handler | |
496 | * | |
ba494bee | 497 | * PARAMETERS: handler - Table event handler that was installed |
3e08e2d2 LM |
498 | * previously. |
499 | * | |
500 | * RETURN: Status | |
501 | * | |
b7ed9a8e | 502 | * DESCRIPTION: Remove a table event handler |
3e08e2d2 LM |
503 | * |
504 | ******************************************************************************/ | |
b43e1065 | 505 | acpi_status acpi_remove_table_handler(acpi_table_handler handler) |
3e08e2d2 LM |
506 | { |
507 | acpi_status status; | |
508 | ||
509 | ACPI_FUNCTION_TRACE(acpi_remove_table_handler); | |
510 | ||
511 | status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); | |
512 | if (ACPI_FAILURE(status)) { | |
513 | return_ACPI_STATUS(status); | |
514 | } | |
515 | ||
516 | /* Make sure that the installed handler is the same */ | |
517 | ||
518 | if (!handler || handler != acpi_gbl_table_handler) { | |
519 | status = AE_BAD_PARAMETER; | |
520 | goto cleanup; | |
521 | } | |
522 | ||
523 | /* Remove the handler */ | |
524 | ||
525 | acpi_gbl_table_handler = NULL; | |
526 | ||
10622bf8 | 527 | cleanup: |
3e08e2d2 LM |
528 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); |
529 | return_ACPI_STATUS(status); | |
530 | } | |
531 | ||
532 | ACPI_EXPORT_SYMBOL(acpi_remove_table_handler) |