blob: 93a99ef0342584920422c191fd684150f061a822 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/******************************************************************************
2 *
3 * Module Name: tbinstal - ACPI table installation and removal
4 *
5 *****************************************************************************/
6
7/*
Bob Moorefbb7a2d2014-02-08 09:42:25 +08008 * Copyright (C) 2000 - 2014, Intel Corp.
Linus Torvalds1da177e2005-04-16 15:20:36 -07009 * 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
Linus Torvalds1da177e2005-04-16 15:20:36 -070044#include <acpi/acpi.h>
Len Browne2f7a772009-01-09 00:30:03 -050045#include "accommon.h"
46#include "acnamesp.h"
47#include "actables.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070048
Linus Torvalds1da177e2005-04-16 15:20:36 -070049#define _COMPONENT ACPI_TABLES
Len Brown4be44fc2005-08-05 00:44:28 -040050ACPI_MODULE_NAME("tbinstal")
Linus Torvalds1da177e2005-04-16 15:20:36 -070051
Lv Zheng7f9fc992014-04-04 12:38:42 +080052/*******************************************************************************
Linus Torvalds1da177e2005-04-16 15:20:36 -070053 *
Lv Zheng7f9fc992014-04-04 12:38:42 +080054 * FUNCTION: acpi_tb_acquire_table
Linus Torvalds1da177e2005-04-16 15:20:36 -070055 *
Lv Zheng7f9fc992014-04-04 12:38:42 +080056 * PARAMETERS: table_desc - Table descriptor
57 * table_ptr - Where table is returned
58 * table_length - Where table length is returned
59 * table_flags - Where table allocation flags are returned
Linus Torvalds1da177e2005-04-16 15:20:36 -070060 *
61 * RETURN: Status
62 *
Lv Zheng7f9fc992014-04-04 12:38:42 +080063 * DESCRIPTION: Acquire a table. It can be used for tables not maintained in
64 * acpi_gbl_root_table_list.
65 *
66 ******************************************************************************/
67acpi_status
68acpi_tb_acquire_table(struct acpi_table_desc *table_desc,
69 struct acpi_table_header **table_ptr,
70 u32 *table_length, u8 *table_flags)
71{
72 struct acpi_table_header *table = NULL;
73
74 switch (table_desc->flags & ACPI_TABLE_ORIGIN_MASK) {
75 case ACPI_TABLE_ORIGIN_MAPPED:
76
77 table =
78 acpi_os_map_memory(table_desc->address, table_desc->length);
79 break;
80
81 case ACPI_TABLE_ORIGIN_ALLOCATED:
82 case ACPI_TABLE_ORIGIN_UNKNOWN:
83 case ACPI_TABLE_ORIGIN_OVERRIDE:
84
85 table =
86 ACPI_CAST_PTR(struct acpi_table_header,
87 table_desc->address);
88 break;
89
90 default:
91
92 break;
93 }
94
95 /* Table is not valid yet */
96
97 if (!table) {
98 return (AE_NO_MEMORY);
99 }
100
101 /* Fill the return values */
102
103 *table_ptr = table;
104 *table_length = table_desc->length;
105 *table_flags = table_desc->flags;
106
107 return (AE_OK);
108}
109
110/*******************************************************************************
111 *
112 * FUNCTION: acpi_tb_release_table
113 *
114 * PARAMETERS: table - Pointer for the table
115 * table_length - Length for the table
116 * table_flags - Allocation flags for the table
117 *
118 * RETURN: None
119 *
120 * DESCRIPTION: Release a table. The reversal of acpi_tb_acquire_table().
121 *
122 ******************************************************************************/
123
124void
125acpi_tb_release_table(struct acpi_table_header *table,
126 u32 table_length, u8 table_flags)
127{
128 switch (table_flags & ACPI_TABLE_ORIGIN_MASK) {
129 case ACPI_TABLE_ORIGIN_MAPPED:
130
131 acpi_os_unmap_memory(table, table_length);
132 break;
133
134 case ACPI_TABLE_ORIGIN_ALLOCATED:
135 case ACPI_TABLE_ORIGIN_UNKNOWN:
136 case ACPI_TABLE_ORIGIN_OVERRIDE:
137 default:
138
139 break;
140 }
141}
142
143/******************************************************************************
144 *
145 * FUNCTION: acpi_tb_validate_table
146 *
147 * PARAMETERS: table_desc - Table descriptor
148 *
149 * RETURN: Status
150 *
151 * DESCRIPTION: This function is called to validate (ensure Pointer is valid)
152 * and verify the table.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700153 *
Bob Mooref3d2e782007-02-02 19:48:18 +0300154 *****************************************************************************/
Lv Zheng7f9fc992014-04-04 12:38:42 +0800155
156acpi_status acpi_tb_validate_table(struct acpi_table_desc *table_desc)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700157{
Alexey Starikovskiy428f2112007-02-02 19:48:22 +0300158 acpi_status status = AE_OK;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700159
Lv Zheng7f9fc992014-04-04 12:38:42 +0800160 ACPI_FUNCTION_TRACE(tb_validate_table);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700161
Lv Zheng7f9fc992014-04-04 12:38:42 +0800162 /* Validate the table if necessary */
Robert Moore44f6c012005-04-18 22:49:35 -0400163
Bob Mooref3d2e782007-02-02 19:48:18 +0300164 if (!table_desc->pointer) {
Lv Zheng7f9fc992014-04-04 12:38:42 +0800165 status = acpi_tb_acquire_table(table_desc, &table_desc->pointer,
166 &table_desc->length,
167 &table_desc->flags);
168 if (ACPI_FAILURE(status) || !table_desc->pointer) {
Bob Mooref3d2e782007-02-02 19:48:18 +0300169 return_ACPI_STATUS(AE_NO_MEMORY);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700170 }
171 }
172
Lv Zheng94d4be62013-09-23 09:52:29 +0800173 /* Always calculate checksum, ignore bad checksum if requested */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700174
Lv Zheng94d4be62013-09-23 09:52:29 +0800175 status =
176 acpi_tb_verify_checksum(table_desc->pointer, table_desc->length);
Bob Mooref3d2e782007-02-02 19:48:18 +0300177
Bob Moorec5fc42a2007-02-02 19:48:19 +0300178 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700179}
180
Linus Torvalds1da177e2005-04-16 15:20:36 -0700181/*******************************************************************************
182 *
Lv Zheng7f9fc992014-04-04 12:38:42 +0800183 * FUNCTION: acpi_tb_invalidate_table
184 *
185 * PARAMETERS: table_desc - Table descriptor
186 *
187 * RETURN: None
188 *
189 * DESCRIPTION: Invalidate one internal ACPI table, this is reversal of
190 * acpi_tb_validate_table().
191 *
192 ******************************************************************************/
193
194void acpi_tb_invalidate_table(struct acpi_table_desc *table_desc)
195{
196
197 ACPI_FUNCTION_TRACE(tb_invalidate_table);
198
199 /* Table must be validated */
200
201 if (!table_desc->pointer) {
202 return_VOID;
203 }
204
205 acpi_tb_release_table(table_desc->pointer, table_desc->length,
206 table_desc->flags);
207 table_desc->pointer = NULL;
208
209 return_VOID;
210}
211
212/*******************************************************************************
213 *
Bob Mooref3d2e782007-02-02 19:48:18 +0300214 * FUNCTION: acpi_tb_add_table
Linus Torvalds1da177e2005-04-16 15:20:36 -0700215 *
Alexey Starikovskiy428f2112007-02-02 19:48:22 +0300216 * PARAMETERS: table_desc - Table descriptor
Bob Mooref3d2e782007-02-02 19:48:18 +0300217 * table_index - Where the table index is returned
Linus Torvalds1da177e2005-04-16 15:20:36 -0700218 *
219 * RETURN: Status
220 *
Bob Moored3ccaff2009-02-03 14:43:04 +0800221 * DESCRIPTION: This function is called to add an ACPI table. It is used to
222 * dynamically load tables via the Load and load_table AML
223 * operators.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700224 *
225 ******************************************************************************/
226
Bob Mooref3d2e782007-02-02 19:48:18 +0300227acpi_status
Bob Moore67a119f2008-06-10 13:42:13 +0800228acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700229{
Bob Moore67a119f2008-06-10 13:42:13 +0800230 u32 i;
Bob Mooref3d2e782007-02-02 19:48:18 +0300231 acpi_status status = AE_OK;
Lv Zheng7f9fc992014-04-04 12:38:42 +0800232 struct acpi_table_header *final_table;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700233
Bob Mooref3d2e782007-02-02 19:48:18 +0300234 ACPI_FUNCTION_TRACE(tb_add_table);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700235
Alexey Starikovskiy428f2112007-02-02 19:48:22 +0300236 if (!table_desc->pointer) {
Lv Zheng7f9fc992014-04-04 12:38:42 +0800237 status = acpi_tb_validate_table(table_desc);
Alexey Starikovskiy428f2112007-02-02 19:48:22 +0300238 if (ACPI_FAILURE(status) || !table_desc->pointer) {
239 return_ACPI_STATUS(status);
240 }
241 }
242
Bob Moorebc45b1d2008-06-10 14:12:50 +0800243 /*
Bob Moorec8cefe32011-06-14 10:42:53 +0800244 * Validate the incoming table signature.
245 *
246 * 1) Originally, we checked the table signature for "SSDT" or "PSDT".
247 * 2) We added support for OEMx tables, signature "OEM".
248 * 3) Valid tables were encountered with a null signature, so we just
249 * gave up on validating the signature, (05/2008).
250 * 4) We encountered non-AML tables such as the MADT, which caused
251 * interpreter errors and kernel faults. So now, we once again allow
252 * only "SSDT", "OEMx", and now, also a null signature. (05/2011).
Bob Moorebc45b1d2008-06-10 14:12:50 +0800253 */
Bob Moorec8cefe32011-06-14 10:42:53 +0800254 if ((table_desc->pointer->signature[0] != 0x00) &&
255 (!ACPI_COMPARE_NAME(table_desc->pointer->signature, ACPI_SIG_SSDT))
256 && (ACPI_STRNCMP(table_desc->pointer->signature, "OEM", 3))) {
Bob Moore3b3ea772012-07-16 09:39:54 +0800257 ACPI_BIOS_ERROR((AE_INFO,
258 "Table has invalid signature [%4.4s] (0x%8.8X), "
259 "must be SSDT or OEMx",
Bob Moorede8e7db2013-06-08 00:59:44 +0000260 acpi_ut_valid_acpi_name(table_desc->pointer->
Bob Moore3b3ea772012-07-16 09:39:54 +0800261 signature) ?
262 table_desc->pointer->signature : "????",
263 *(u32 *)table_desc->pointer->signature));
Bob Moorec8cefe32011-06-14 10:42:53 +0800264
265 return_ACPI_STATUS(AE_BAD_SIGNATURE);
266 }
Alexey Starikovskiy428f2112007-02-02 19:48:22 +0300267
Bob Mooref3d2e782007-02-02 19:48:18 +0300268 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700269
Bob Mooref3d2e782007-02-02 19:48:18 +0300270 /* Check if table is already registered */
271
Bob Mooreb9ee2042010-04-27 11:16:14 +0800272 for (i = 0; i < acpi_gbl_root_table_list.current_table_count; ++i) {
Bob Mooref3d2e782007-02-02 19:48:18 +0300273 if (!acpi_gbl_root_table_list.tables[i].pointer) {
274 status =
Lv Zheng7f9fc992014-04-04 12:38:42 +0800275 acpi_tb_validate_table(&acpi_gbl_root_table_list.
276 tables[i]);
Bob Mooref3d2e782007-02-02 19:48:18 +0300277 if (ACPI_FAILURE(status)
278 || !acpi_gbl_root_table_list.tables[i].pointer) {
279 continue;
280 }
281 }
282
Bob Moorea6f30532008-07-04 10:57:51 +0800283 /*
284 * Check for a table match on the entire table length,
285 * not just the header.
286 */
287 if (table_desc->length !=
288 acpi_gbl_root_table_list.tables[i].length) {
289 continue;
290 }
Bob Mooree56f5612008-07-04 10:48:43 +0800291
Alexey Starikovskiy428f2112007-02-02 19:48:22 +0300292 if (ACPI_MEMCMP(table_desc->pointer,
293 acpi_gbl_root_table_list.tables[i].pointer,
Bob Moorea6f30532008-07-04 10:57:51 +0800294 acpi_gbl_root_table_list.tables[i].length)) {
Bob Mooref3d2e782007-02-02 19:48:18 +0300295 continue;
296 }
297
Bob Mooree56f5612008-07-04 10:48:43 +0800298 /*
299 * Note: the current mechanism does not unregister a table if it is
300 * dynamically unloaded. The related namespace entries are deleted,
301 * but the table remains in the root table list.
302 *
303 * The assumption here is that the number of different tables that
304 * will be loaded is actually small, and there is minimal overhead
305 * in just keeping the table in case it is needed again.
306 *
307 * If this assumption changes in the future (perhaps on large
308 * machines with many table load/unload operations), tables will
309 * need to be unregistered when they are unloaded, and slots in the
310 * root table list should be reused when empty.
311 */
Bob Mooref3d2e782007-02-02 19:48:18 +0300312 *table_index = i;
Bob Mooree56f5612008-07-04 10:48:43 +0800313
314 if (acpi_gbl_root_table_list.tables[i].
315 flags & ACPI_TABLE_IS_LOADED) {
316
317 /* Table is still loaded, this is an error */
318
319 status = AE_ALREADY_EXISTS;
320 goto release;
321 } else {
322 /* Table was unloaded, allow it to be reloaded */
323
Lv Zheng7f9fc992014-04-04 12:38:42 +0800324 acpi_tb_uninstall_table(table_desc);
Bob Mooree56f5612008-07-04 10:48:43 +0800325 table_desc->pointer =
326 acpi_gbl_root_table_list.tables[i].pointer;
327 table_desc->address =
328 acpi_gbl_root_table_list.tables[i].address;
329 status = AE_OK;
330 goto print_header;
331 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700332 }
333
Bob Moored3ccaff2009-02-03 14:43:04 +0800334 /*
335 * ACPI Table Override:
336 * Allow the host to override dynamically loaded tables.
Bob Mooref7b004a2012-02-14 18:31:56 +0800337 * NOTE: the table is fully mapped at this point, and the mapping will
Lv Zheng7f9fc992014-04-04 12:38:42 +0800338 * be deleted by acpi_tb_override_table if the table is actually overridden.
Bob Moored3ccaff2009-02-03 14:43:04 +0800339 */
Lv Zheng7f9fc992014-04-04 12:38:42 +0800340 final_table = acpi_tb_override_table(table_desc->pointer, table_desc);
341 if (final_table) {
342
343 /* Ensure table descriptor is in "VALIDATED" state */
344
345 table_desc->pointer = final_table;
346 }
Bob Moored3ccaff2009-02-03 14:43:04 +0800347
Bob Mooree56f5612008-07-04 10:48:43 +0800348 /* Add the table to the global root table list */
349
Alexey Starikovskiy428f2112007-02-02 19:48:22 +0300350 status = acpi_tb_store_table(table_desc->address, table_desc->pointer,
351 table_desc->length, table_desc->flags,
352 table_index);
Len Brown4be44fc2005-08-05 00:44:28 -0400353 if (ACPI_FAILURE(status)) {
Bob Mooref3d2e782007-02-02 19:48:18 +0300354 goto release;
Robert Moore0c9938c2005-07-29 15:15:00 -0700355 }
356
Lv Zheng10622bf2013-10-29 09:30:02 +0800357print_header:
Alexey Starikovskiy428f2112007-02-02 19:48:22 +0300358 acpi_tb_print_table_header(table_desc->address, table_desc->pointer);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700359
Lv Zheng10622bf2013-10-29 09:30:02 +0800360release:
Len Brown4be44fc2005-08-05 00:44:28 -0400361 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
362 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700363}
364
Linus Torvalds1da177e2005-04-16 15:20:36 -0700365/*******************************************************************************
366 *
Lv Zheng7f9fc992014-04-04 12:38:42 +0800367 * FUNCTION: acpi_tb_override_table
Bob Mooref7b004a2012-02-14 18:31:56 +0800368 *
369 * PARAMETERS: table_header - Header for the original table
370 * table_desc - Table descriptor initialized for the
371 * original table. May or may not be mapped.
372 *
373 * RETURN: Pointer to the entire new table. NULL if table not overridden.
374 * If overridden, installs the new table within the input table
375 * descriptor.
376 *
377 * DESCRIPTION: Attempt table override by calling the OSL override functions.
378 * Note: If the table is overridden, then the entire new table
Lv Zheng7f9fc992014-04-04 12:38:42 +0800379 * is acquired and returned by this function.
380 * After invocation, the table descriptor is in a state that is
381 * "INSTALLED" but not "VALIDATED", thus the "Pointer" member is
382 * kept NULL.
Bob Mooref7b004a2012-02-14 18:31:56 +0800383 *
384 ******************************************************************************/
385
Lv Zheng7f9fc992014-04-04 12:38:42 +0800386struct acpi_table_header *acpi_tb_override_table(struct acpi_table_header
Bob Mooref7b004a2012-02-14 18:31:56 +0800387 *table_header,
388 struct acpi_table_desc
389 *table_desc)
390{
391 acpi_status status;
Lv Zheng7f9fc992014-04-04 12:38:42 +0800392 struct acpi_table_header *new_table;
393 u32 new_table_length;
Bob Mooref7b004a2012-02-14 18:31:56 +0800394 u8 new_flags;
395 char *override_type;
Lv Zheng7f9fc992014-04-04 12:38:42 +0800396 struct acpi_table_desc new_table_desc;
397
398 ACPI_MEMSET(&new_table_desc, 0, sizeof(struct acpi_table_desc));
Bob Mooref7b004a2012-02-14 18:31:56 +0800399
400 /* (1) Attempt logical override (returns a logical address) */
401
Lv Zheng7f9fc992014-04-04 12:38:42 +0800402 status = acpi_os_table_override(table_header, &new_table_desc.pointer);
403 if (ACPI_SUCCESS(status) && new_table_desc.pointer) {
404 new_table_desc.address =
405 ACPI_PTR_TO_PHYSADDR(new_table_desc.pointer);
406 new_table_desc.length = new_table_desc.pointer->length;
407 new_table_desc.flags = ACPI_TABLE_ORIGIN_OVERRIDE;
Bob Mooref7b004a2012-02-14 18:31:56 +0800408 override_type = "Logical";
409 goto finish_override;
410 }
411
412 /* (2) Attempt physical override (returns a physical address) */
413
414 status = acpi_os_physical_table_override(table_header,
Lv Zheng7f9fc992014-04-04 12:38:42 +0800415 &new_table_desc.address,
416 &new_table_desc.length);
417 if (ACPI_SUCCESS(status) && new_table_desc.address
418 && new_table_desc.length) {
Bob Mooref7b004a2012-02-14 18:31:56 +0800419 override_type = "Physical";
Lv Zheng7f9fc992014-04-04 12:38:42 +0800420 new_table_desc.flags = ACPI_TABLE_ORIGIN_MAPPED;
Bob Mooref7b004a2012-02-14 18:31:56 +0800421 goto finish_override;
422 }
423
424 return (NULL); /* There was no override */
425
Lv Zheng10622bf2013-10-29 09:30:02 +0800426finish_override:
Bob Mooref7b004a2012-02-14 18:31:56 +0800427
Lv Zheng7f9fc992014-04-04 12:38:42 +0800428 /*
429 * Acquire the entire new table to indicate overridden.
430 * Note that this is required by the callers of this function.
431 */
432 status = acpi_tb_acquire_table(&new_table_desc, &new_table,
433 &new_table_length, &new_flags);
434 if (ACPI_FAILURE(status)) {
435 ACPI_EXCEPTION((AE_INFO, AE_NO_MEMORY,
436 "%4.4s " ACPI_PRINTF_UINT
437 " Attempted table override failed",
438 table_header->signature,
439 ACPI_FORMAT_TO_UINT(table_desc->address)));
440 return (NULL);
441 }
442
Bob Moore2e19f8d2014-02-08 09:42:07 +0800443 ACPI_INFO((AE_INFO, "%4.4s " ACPI_PRINTF_UINT
444 " %s table override, new table: " ACPI_PRINTF_UINT,
Bob Mooref7b004a2012-02-14 18:31:56 +0800445 table_header->signature,
Bob Moore2e19f8d2014-02-08 09:42:07 +0800446 ACPI_FORMAT_TO_UINT(table_desc->address),
Lv Zheng7f9fc992014-04-04 12:38:42 +0800447 override_type, ACPI_FORMAT_TO_UINT(new_table_desc.address)));
Bob Mooref7b004a2012-02-14 18:31:56 +0800448
Lv Zheng7f9fc992014-04-04 12:38:42 +0800449 /* We can now uninstall the original table (if fully mapped) */
Bob Mooref7b004a2012-02-14 18:31:56 +0800450
Lv Zheng7f9fc992014-04-04 12:38:42 +0800451 acpi_tb_uninstall_table(table_desc);
Bob Mooref7b004a2012-02-14 18:31:56 +0800452
Lv Zheng7f9fc992014-04-04 12:38:42 +0800453 /* Install the new table */
Bob Mooref7b004a2012-02-14 18:31:56 +0800454
Lv Zheng7f9fc992014-04-04 12:38:42 +0800455 table_desc->address = new_table_desc.address;
456 table_desc->length = new_table_desc.length;
457 table_desc->flags = new_table_desc.flags;
Bob Mooref7b004a2012-02-14 18:31:56 +0800458
459 return (new_table);
460}
461
462/*******************************************************************************
463 *
Bob Mooref3d2e782007-02-02 19:48:18 +0300464 * FUNCTION: acpi_tb_resize_root_table_list
Linus Torvalds1da177e2005-04-16 15:20:36 -0700465 *
Bob Mooref3d2e782007-02-02 19:48:18 +0300466 * PARAMETERS: None
Linus Torvalds1da177e2005-04-16 15:20:36 -0700467 *
468 * RETURN: Status
469 *
Bob Mooref3d2e782007-02-02 19:48:18 +0300470 * DESCRIPTION: Expand the size of global table array
Linus Torvalds1da177e2005-04-16 15:20:36 -0700471 *
472 ******************************************************************************/
473
Bob Mooref3d2e782007-02-02 19:48:18 +0300474acpi_status acpi_tb_resize_root_table_list(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700475{
Bob Mooref3d2e782007-02-02 19:48:18 +0300476 struct acpi_table_desc *tables;
Lv Zheng2bc198c2012-09-13 09:29:06 -0700477 u32 table_count;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700478
Bob Mooref3d2e782007-02-02 19:48:18 +0300479 ACPI_FUNCTION_TRACE(tb_resize_root_table_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700480
Bob Mooref3d2e782007-02-02 19:48:18 +0300481 /* allow_resize flag is a parameter to acpi_initialize_tables */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700482
Bob Moorec5fc42a2007-02-02 19:48:19 +0300483 if (!(acpi_gbl_root_table_list.flags & ACPI_ROOT_ALLOW_RESIZE)) {
Bob Mooref3d2e782007-02-02 19:48:18 +0300484 ACPI_ERROR((AE_INFO,
485 "Resize of Root Table Array is not allowed"));
486 return_ACPI_STATUS(AE_SUPPORT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700487 }
488
Bob Mooref3d2e782007-02-02 19:48:18 +0300489 /* Increase the Table Array size */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700490
Lv Zheng2bc198c2012-09-13 09:29:06 -0700491 if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) {
492 table_count = acpi_gbl_root_table_list.max_table_count;
493 } else {
494 table_count = acpi_gbl_root_table_list.current_table_count;
495 }
496
497 tables = ACPI_ALLOCATE_ZEROED(((acpi_size) table_count +
Bob Mooreec41f192009-02-18 15:03:30 +0800498 ACPI_ROOT_TABLE_SIZE_INCREMENT) *
499 sizeof(struct acpi_table_desc));
Bob Mooref3d2e782007-02-02 19:48:18 +0300500 if (!tables) {
501 ACPI_ERROR((AE_INFO,
502 "Could not allocate new root table array"));
Len Brown4be44fc2005-08-05 00:44:28 -0400503 return_ACPI_STATUS(AE_NO_MEMORY);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700504 }
505
Bob Mooref3d2e782007-02-02 19:48:18 +0300506 /* Copy and free the previous table array */
Robert Mooref9f46012005-07-08 00:00:00 -0400507
Bob Mooref3d2e782007-02-02 19:48:18 +0300508 if (acpi_gbl_root_table_list.tables) {
509 ACPI_MEMCPY(tables, acpi_gbl_root_table_list.tables,
Lv Zheng2bc198c2012-09-13 09:29:06 -0700510 (acpi_size) table_count *
511 sizeof(struct acpi_table_desc));
Robert Mooref9f46012005-07-08 00:00:00 -0400512
Bob Moorec5fc42a2007-02-02 19:48:19 +0300513 if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) {
Bob Mooref3d2e782007-02-02 19:48:18 +0300514 ACPI_FREE(acpi_gbl_root_table_list.tables);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700515 }
516 }
517
Bob Mooref3d2e782007-02-02 19:48:18 +0300518 acpi_gbl_root_table_list.tables = tables;
Lv Zheng2bc198c2012-09-13 09:29:06 -0700519 acpi_gbl_root_table_list.max_table_count =
520 table_count + ACPI_ROOT_TABLE_SIZE_INCREMENT;
521 acpi_gbl_root_table_list.flags |= ACPI_ROOT_ORIGIN_ALLOCATED;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700522
Len Brown4be44fc2005-08-05 00:44:28 -0400523 return_ACPI_STATUS(AE_OK);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700524}
525
Linus Torvalds1da177e2005-04-16 15:20:36 -0700526/*******************************************************************************
527 *
Bob Mooref3d2e782007-02-02 19:48:18 +0300528 * FUNCTION: acpi_tb_store_table
Linus Torvalds1da177e2005-04-16 15:20:36 -0700529 *
Bob Mooreba494be2012-07-12 09:40:10 +0800530 * PARAMETERS: address - Table address
531 * table - Table header
532 * length - Table length
533 * flags - flags
Linus Torvalds1da177e2005-04-16 15:20:36 -0700534 *
Bob Mooref3d2e782007-02-02 19:48:18 +0300535 * RETURN: Status and table index.
536 *
537 * DESCRIPTION: Add an ACPI table to the global table list
538 *
539 ******************************************************************************/
540
541acpi_status
542acpi_tb_store_table(acpi_physical_address address,
543 struct acpi_table_header *table,
Bob Moore67a119f2008-06-10 13:42:13 +0800544 u32 length, u8 flags, u32 *table_index)
Bob Mooref3d2e782007-02-02 19:48:18 +0300545{
Bob Mooreb9ee2042010-04-27 11:16:14 +0800546 acpi_status status;
547 struct acpi_table_desc *new_table;
Bob Mooref3d2e782007-02-02 19:48:18 +0300548
549 /* Ensure that there is room for the table in the Root Table List */
550
Bob Mooreb9ee2042010-04-27 11:16:14 +0800551 if (acpi_gbl_root_table_list.current_table_count >=
552 acpi_gbl_root_table_list.max_table_count) {
Bob Mooref3d2e782007-02-02 19:48:18 +0300553 status = acpi_tb_resize_root_table_list();
554 if (ACPI_FAILURE(status)) {
555 return (status);
556 }
557 }
558
Bob Mooreb9ee2042010-04-27 11:16:14 +0800559 new_table =
560 &acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.
561 current_table_count];
562
Bob Mooref3d2e782007-02-02 19:48:18 +0300563 /* Initialize added table */
564
Bob Mooreb9ee2042010-04-27 11:16:14 +0800565 new_table->address = address;
566 new_table->pointer = table;
567 new_table->length = length;
568 new_table->owner_id = 0;
569 new_table->flags = flags;
Bob Mooref3d2e782007-02-02 19:48:18 +0300570
Bob Mooreb9ee2042010-04-27 11:16:14 +0800571 ACPI_MOVE_32_TO_32(&new_table->signature, table->signature);
Bob Mooref3d2e782007-02-02 19:48:18 +0300572
Bob Mooreb9ee2042010-04-27 11:16:14 +0800573 *table_index = acpi_gbl_root_table_list.current_table_count;
574 acpi_gbl_root_table_list.current_table_count++;
575 return (AE_OK);
Bob Mooref3d2e782007-02-02 19:48:18 +0300576}
577
578/*******************************************************************************
579 *
Lv Zheng7f9fc992014-04-04 12:38:42 +0800580 * FUNCTION: acpi_tb_uninstall_table
Bob Mooref3d2e782007-02-02 19:48:18 +0300581 *
Lv Zheng7f9fc992014-04-04 12:38:42 +0800582 * PARAMETERS: table_desc - Table descriptor
Bob Mooref3d2e782007-02-02 19:48:18 +0300583 *
584 * RETURN: None
585 *
586 * DESCRIPTION: Delete one internal ACPI table
587 *
588 ******************************************************************************/
589
Lv Zheng7f9fc992014-04-04 12:38:42 +0800590void acpi_tb_uninstall_table(struct acpi_table_desc *table_desc)
Bob Mooref3d2e782007-02-02 19:48:18 +0300591{
Lv Zheng55829822014-04-04 12:38:18 +0800592
Lv Zheng7f9fc992014-04-04 12:38:42 +0800593 ACPI_FUNCTION_TRACE(tb_uninstall_table);
Lv Zheng55829822014-04-04 12:38:18 +0800594
Lv Zheng7f9fc992014-04-04 12:38:42 +0800595 /* Table must be installed */
596
597 if (!table_desc->address) {
598 return_VOID;
Bob Mooref3d2e782007-02-02 19:48:18 +0300599 }
Lv Zheng55829822014-04-04 12:38:18 +0800600
Lv Zheng7f9fc992014-04-04 12:38:42 +0800601 acpi_tb_invalidate_table(table_desc);
Chao Guan1d1ea1b2013-06-08 00:58:14 +0000602
Lv Zheng7f9fc992014-04-04 12:38:42 +0800603 if ((table_desc->flags & ACPI_TABLE_ORIGIN_MASK) ==
604 ACPI_TABLE_ORIGIN_ALLOCATED) {
605 ACPI_FREE(ACPI_CAST_PTR(void, table_desc->address));
Bob Mooref3d2e782007-02-02 19:48:18 +0300606 }
607
Lv Zheng7f9fc992014-04-04 12:38:42 +0800608 table_desc->address = ACPI_PTR_TO_PHYSADDR(NULL);
609
610 return_VOID;
Bob Mooref3d2e782007-02-02 19:48:18 +0300611}
612
613/*******************************************************************************
614 *
615 * FUNCTION: acpi_tb_terminate
616 *
617 * PARAMETERS: None
618 *
619 * RETURN: None
Linus Torvalds1da177e2005-04-16 15:20:36 -0700620 *
621 * DESCRIPTION: Delete all internal ACPI tables
622 *
623 ******************************************************************************/
624
Bob Mooref3d2e782007-02-02 19:48:18 +0300625void acpi_tb_terminate(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700626{
Bob Moore67a119f2008-06-10 13:42:13 +0800627 u32 i;
Bob Mooref3d2e782007-02-02 19:48:18 +0300628
629 ACPI_FUNCTION_TRACE(tb_terminate);
630
631 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
632
633 /* Delete the individual tables */
634
Bob Mooreb9ee2042010-04-27 11:16:14 +0800635 for (i = 0; i < acpi_gbl_root_table_list.current_table_count; i++) {
Lv Zheng7f9fc992014-04-04 12:38:42 +0800636 acpi_tb_uninstall_table(&acpi_gbl_root_table_list.tables[i]);
Bob Mooref3d2e782007-02-02 19:48:18 +0300637 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700638
639 /*
Bob Mooref3d2e782007-02-02 19:48:18 +0300640 * Delete the root table array if allocated locally. Array cannot be
641 * mapped, so we don't need to check for that flag.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700642 */
Bob Moorec5fc42a2007-02-02 19:48:19 +0300643 if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) {
Bob Mooref3d2e782007-02-02 19:48:18 +0300644 ACPI_FREE(acpi_gbl_root_table_list.tables);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700645 }
Bob Mooref3d2e782007-02-02 19:48:18 +0300646
647 acpi_gbl_root_table_list.tables = NULL;
648 acpi_gbl_root_table_list.flags = 0;
Bob Mooreb9ee2042010-04-27 11:16:14 +0800649 acpi_gbl_root_table_list.current_table_count = 0;
Bob Mooref3d2e782007-02-02 19:48:18 +0300650
651 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "ACPI Tables freed\n"));
652 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
Bob Moore68aafc32012-10-31 02:26:01 +0000653
654 return_VOID;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700655}
656
Linus Torvalds1da177e2005-04-16 15:20:36 -0700657/*******************************************************************************
658 *
Bob Mooref3d2e782007-02-02 19:48:18 +0300659 * FUNCTION: acpi_tb_delete_namespace_by_owner
Linus Torvalds1da177e2005-04-16 15:20:36 -0700660 *
Bob Mooref3d2e782007-02-02 19:48:18 +0300661 * PARAMETERS: table_index - Table index
Linus Torvalds1da177e2005-04-16 15:20:36 -0700662 *
Bob Moore8a335a232009-03-09 16:31:04 +0800663 * RETURN: Status
Linus Torvalds1da177e2005-04-16 15:20:36 -0700664 *
Bob Mooref3d2e782007-02-02 19:48:18 +0300665 * DESCRIPTION: Delete all namespace objects created when this table was loaded.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700666 *
667 ******************************************************************************/
668
Bob Moore8a335a232009-03-09 16:31:04 +0800669acpi_status acpi_tb_delete_namespace_by_owner(u32 table_index)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700670{
Bob Mooref3d2e782007-02-02 19:48:18 +0300671 acpi_owner_id owner_id;
Bob Moore8a335a232009-03-09 16:31:04 +0800672 acpi_status status;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700673
Bob Moore8a335a232009-03-09 16:31:04 +0800674 ACPI_FUNCTION_TRACE(tb_delete_namespace_by_owner);
675
676 status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
677 if (ACPI_FAILURE(status)) {
678 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700679 }
680
Bob Mooreb9ee2042010-04-27 11:16:14 +0800681 if (table_index >= acpi_gbl_root_table_list.current_table_count) {
Bob Moore8a335a232009-03-09 16:31:04 +0800682
683 /* The table index does not exist */
684
685 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
686 return_ACPI_STATUS(AE_NOT_EXIST);
687 }
688
689 /* Get the owner ID for this table, used to delete namespace nodes */
690
691 owner_id = acpi_gbl_root_table_list.tables[table_index].owner_id;
Len Brown4be44fc2005-08-05 00:44:28 -0400692 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
Bob Moore8a335a232009-03-09 16:31:04 +0800693
694 /*
695 * Need to acquire the namespace writer lock to prevent interference
696 * with any concurrent namespace walks. The interpreter must be
697 * released during the deletion since the acquisition of the deletion
698 * lock may block, and also since the execution of a namespace walk
699 * must be allowed to use the interpreter.
700 */
Bob Mooree4c1ebf2009-04-22 13:02:06 +0800701 (void)acpi_ut_release_mutex(ACPI_MTX_INTERPRETER);
Bob Moore8a335a232009-03-09 16:31:04 +0800702 status = acpi_ut_acquire_write_lock(&acpi_gbl_namespace_rw_lock);
703
Bob Mooref3d2e782007-02-02 19:48:18 +0300704 acpi_ns_delete_namespace_by_owner(owner_id);
Bob Moore8a335a232009-03-09 16:31:04 +0800705 if (ACPI_FAILURE(status)) {
706 return_ACPI_STATUS(status);
707 }
708
709 acpi_ut_release_write_lock(&acpi_gbl_namespace_rw_lock);
710
711 status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER);
712 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700713}
714
Linus Torvalds1da177e2005-04-16 15:20:36 -0700715/*******************************************************************************
716 *
Bob Mooref3d2e782007-02-02 19:48:18 +0300717 * FUNCTION: acpi_tb_allocate_owner_id
Linus Torvalds1da177e2005-04-16 15:20:36 -0700718 *
Bob Mooref3d2e782007-02-02 19:48:18 +0300719 * PARAMETERS: table_index - Table index
Linus Torvalds1da177e2005-04-16 15:20:36 -0700720 *
Bob Mooref3d2e782007-02-02 19:48:18 +0300721 * RETURN: Status
Linus Torvalds1da177e2005-04-16 15:20:36 -0700722 *
Bob Mooref3d2e782007-02-02 19:48:18 +0300723 * DESCRIPTION: Allocates owner_id in table_desc
Linus Torvalds1da177e2005-04-16 15:20:36 -0700724 *
725 ******************************************************************************/
726
Bob Moore67a119f2008-06-10 13:42:13 +0800727acpi_status acpi_tb_allocate_owner_id(u32 table_index)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700728{
Bob Mooref3d2e782007-02-02 19:48:18 +0300729 acpi_status status = AE_BAD_PARAMETER;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700730
Bob Mooref3d2e782007-02-02 19:48:18 +0300731 ACPI_FUNCTION_TRACE(tb_allocate_owner_id);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700732
Bob Mooref3d2e782007-02-02 19:48:18 +0300733 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
Bob Mooreb9ee2042010-04-27 11:16:14 +0800734 if (table_index < acpi_gbl_root_table_list.current_table_count) {
Bob Mooref3d2e782007-02-02 19:48:18 +0300735 status = acpi_ut_allocate_owner_id
736 (&(acpi_gbl_root_table_list.tables[table_index].owner_id));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700737 }
738
Bob Mooref3d2e782007-02-02 19:48:18 +0300739 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
740 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700741}
742
Linus Torvalds1da177e2005-04-16 15:20:36 -0700743/*******************************************************************************
744 *
Bob Mooref3d2e782007-02-02 19:48:18 +0300745 * FUNCTION: acpi_tb_release_owner_id
Linus Torvalds1da177e2005-04-16 15:20:36 -0700746 *
Bob Mooref3d2e782007-02-02 19:48:18 +0300747 * PARAMETERS: table_index - Table index
Linus Torvalds1da177e2005-04-16 15:20:36 -0700748 *
Bob Mooref3d2e782007-02-02 19:48:18 +0300749 * RETURN: Status
Linus Torvalds1da177e2005-04-16 15:20:36 -0700750 *
Bob Mooref3d2e782007-02-02 19:48:18 +0300751 * DESCRIPTION: Releases owner_id in table_desc
Linus Torvalds1da177e2005-04-16 15:20:36 -0700752 *
753 ******************************************************************************/
754
Bob Moore67a119f2008-06-10 13:42:13 +0800755acpi_status acpi_tb_release_owner_id(u32 table_index)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700756{
Bob Mooref3d2e782007-02-02 19:48:18 +0300757 acpi_status status = AE_BAD_PARAMETER;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700758
Bob Mooref3d2e782007-02-02 19:48:18 +0300759 ACPI_FUNCTION_TRACE(tb_release_owner_id);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700760
Bob Mooref3d2e782007-02-02 19:48:18 +0300761 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
Bob Mooreb9ee2042010-04-27 11:16:14 +0800762 if (table_index < acpi_gbl_root_table_list.current_table_count) {
Bob Mooref3d2e782007-02-02 19:48:18 +0300763 acpi_ut_release_owner_id(&
764 (acpi_gbl_root_table_list.
765 tables[table_index].owner_id));
766 status = AE_OK;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700767 }
768
Bob Mooref3d2e782007-02-02 19:48:18 +0300769 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
770 return_ACPI_STATUS(status);
771}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700772
Bob Mooref3d2e782007-02-02 19:48:18 +0300773/*******************************************************************************
774 *
775 * FUNCTION: acpi_tb_get_owner_id
776 *
777 * PARAMETERS: table_index - Table index
778 * owner_id - Where the table owner_id is returned
779 *
780 * RETURN: Status
781 *
782 * DESCRIPTION: returns owner_id for the ACPI table
783 *
784 ******************************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -0700785
Lv Zheng55829822014-04-04 12:38:18 +0800786acpi_status acpi_tb_get_owner_id(u32 table_index, acpi_owner_id * owner_id)
Bob Mooref3d2e782007-02-02 19:48:18 +0300787{
788 acpi_status status = AE_BAD_PARAMETER;
789
790 ACPI_FUNCTION_TRACE(tb_get_owner_id);
791
792 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
Bob Mooreb9ee2042010-04-27 11:16:14 +0800793 if (table_index < acpi_gbl_root_table_list.current_table_count) {
Bob Mooref3d2e782007-02-02 19:48:18 +0300794 *owner_id =
795 acpi_gbl_root_table_list.tables[table_index].owner_id;
796 status = AE_OK;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700797 }
798
Bob Mooref3d2e782007-02-02 19:48:18 +0300799 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
800 return_ACPI_STATUS(status);
801}
802
803/*******************************************************************************
804 *
805 * FUNCTION: acpi_tb_is_table_loaded
806 *
807 * PARAMETERS: table_index - Table index
808 *
809 * RETURN: Table Loaded Flag
810 *
811 ******************************************************************************/
812
Bob Moore67a119f2008-06-10 13:42:13 +0800813u8 acpi_tb_is_table_loaded(u32 table_index)
Bob Mooref3d2e782007-02-02 19:48:18 +0300814{
815 u8 is_loaded = FALSE;
816
817 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
Bob Mooreb9ee2042010-04-27 11:16:14 +0800818 if (table_index < acpi_gbl_root_table_list.current_table_count) {
Bob Mooref3d2e782007-02-02 19:48:18 +0300819 is_loaded = (u8)
Bob Mooreec41f192009-02-18 15:03:30 +0800820 (acpi_gbl_root_table_list.tables[table_index].flags &
821 ACPI_TABLE_IS_LOADED);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700822 }
823
Bob Mooref3d2e782007-02-02 19:48:18 +0300824 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
825 return (is_loaded);
826}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700827
Bob Mooref3d2e782007-02-02 19:48:18 +0300828/*******************************************************************************
829 *
830 * FUNCTION: acpi_tb_set_table_loaded_flag
831 *
832 * PARAMETERS: table_index - Table index
833 * is_loaded - TRUE if table is loaded, FALSE otherwise
834 *
835 * RETURN: None
836 *
837 * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE.
838 *
839 ******************************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -0700840
Bob Moore67a119f2008-06-10 13:42:13 +0800841void acpi_tb_set_table_loaded_flag(u32 table_index, u8 is_loaded)
Bob Mooref3d2e782007-02-02 19:48:18 +0300842{
Bob Mooref6dd9222006-07-07 20:44:38 -0400843
Bob Mooref3d2e782007-02-02 19:48:18 +0300844 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
Bob Mooreb9ee2042010-04-27 11:16:14 +0800845 if (table_index < acpi_gbl_root_table_list.current_table_count) {
Bob Mooref3d2e782007-02-02 19:48:18 +0300846 if (is_loaded) {
847 acpi_gbl_root_table_list.tables[table_index].flags |=
Bob Moorec5fc42a2007-02-02 19:48:19 +0300848 ACPI_TABLE_IS_LOADED;
Bob Mooref3d2e782007-02-02 19:48:18 +0300849 } else {
850 acpi_gbl_root_table_list.tables[table_index].flags &=
Bob Moorec5fc42a2007-02-02 19:48:19 +0300851 ~ACPI_TABLE_IS_LOADED;
Bob Mooref3d2e782007-02-02 19:48:18 +0300852 }
853 }
Bob Mooref6dd9222006-07-07 20:44:38 -0400854
Bob Mooref3d2e782007-02-02 19:48:18 +0300855 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700856}