blob: 634357d51fe9b4a30103f5cb1169a97d1da72b7f [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 Moore25f044e2013-01-25 05:38:56 +00008 * Copyright (C) 2000 - 2013, 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
Bob Mooref3d2e782007-02-02 19:48:18 +030052/******************************************************************************
Linus Torvalds1da177e2005-04-16 15:20:36 -070053 *
Bob Mooref3d2e782007-02-02 19:48:18 +030054 * FUNCTION: acpi_tb_verify_table
Linus Torvalds1da177e2005-04-16 15:20:36 -070055 *
Bob Mooref3d2e782007-02-02 19:48:18 +030056 * PARAMETERS: table_desc - table
Linus Torvalds1da177e2005-04-16 15:20:36 -070057 *
58 * RETURN: Status
59 *
Bob Mooref3d2e782007-02-02 19:48:18 +030060 * DESCRIPTION: this function is called to verify and map table
Linus Torvalds1da177e2005-04-16 15:20:36 -070061 *
Bob Mooref3d2e782007-02-02 19:48:18 +030062 *****************************************************************************/
63acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc)
Linus Torvalds1da177e2005-04-16 15:20:36 -070064{
Alexey Starikovskiy428f2112007-02-02 19:48:22 +030065 acpi_status status = AE_OK;
Linus Torvalds1da177e2005-04-16 15:20:36 -070066
Bob Mooref3d2e782007-02-02 19:48:18 +030067 ACPI_FUNCTION_TRACE(tb_verify_table);
Linus Torvalds1da177e2005-04-16 15:20:36 -070068
Bob Mooref3d2e782007-02-02 19:48:18 +030069 /* Map the table if necessary */
Robert Moore44f6c012005-04-18 22:49:35 -040070
Bob Mooref3d2e782007-02-02 19:48:18 +030071 if (!table_desc->pointer) {
Alexey Starikovskiy428f2112007-02-02 19:48:22 +030072 if ((table_desc->flags & ACPI_TABLE_ORIGIN_MASK) ==
73 ACPI_TABLE_ORIGIN_MAPPED) {
74 table_desc->pointer =
75 acpi_os_map_memory(table_desc->address,
76 table_desc->length);
77 }
Bob Mooref3d2e782007-02-02 19:48:18 +030078 if (!table_desc->pointer) {
79 return_ACPI_STATUS(AE_NO_MEMORY);
Linus Torvalds1da177e2005-04-16 15:20:36 -070080 }
81 }
82
Lv Zheng94d4be62013-09-23 09:52:29 +080083 /* Always calculate checksum, ignore bad checksum if requested */
Linus Torvalds1da177e2005-04-16 15:20:36 -070084
Lv Zheng94d4be62013-09-23 09:52:29 +080085 status =
86 acpi_tb_verify_checksum(table_desc->pointer, table_desc->length);
Bob Mooref3d2e782007-02-02 19:48:18 +030087
Bob Moorec5fc42a2007-02-02 19:48:19 +030088 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070089}
90
Linus Torvalds1da177e2005-04-16 15:20:36 -070091/*******************************************************************************
92 *
Bob Mooref3d2e782007-02-02 19:48:18 +030093 * FUNCTION: acpi_tb_add_table
Linus Torvalds1da177e2005-04-16 15:20:36 -070094 *
Alexey Starikovskiy428f2112007-02-02 19:48:22 +030095 * PARAMETERS: table_desc - Table descriptor
Bob Mooref3d2e782007-02-02 19:48:18 +030096 * table_index - Where the table index is returned
Linus Torvalds1da177e2005-04-16 15:20:36 -070097 *
98 * RETURN: Status
99 *
Bob Moored3ccaff2009-02-03 14:43:04 +0800100 * DESCRIPTION: This function is called to add an ACPI table. It is used to
101 * dynamically load tables via the Load and load_table AML
102 * operators.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700103 *
104 ******************************************************************************/
105
Bob Mooref3d2e782007-02-02 19:48:18 +0300106acpi_status
Bob Moore67a119f2008-06-10 13:42:13 +0800107acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700108{
Bob Moore67a119f2008-06-10 13:42:13 +0800109 u32 i;
Bob Mooref3d2e782007-02-02 19:48:18 +0300110 acpi_status status = AE_OK;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700111
Bob Mooref3d2e782007-02-02 19:48:18 +0300112 ACPI_FUNCTION_TRACE(tb_add_table);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700113
Alexey Starikovskiy428f2112007-02-02 19:48:22 +0300114 if (!table_desc->pointer) {
115 status = acpi_tb_verify_table(table_desc);
116 if (ACPI_FAILURE(status) || !table_desc->pointer) {
117 return_ACPI_STATUS(status);
118 }
119 }
120
Bob Moorebc45b1d2008-06-10 14:12:50 +0800121 /*
Bob Moorec8cefe32011-06-14 10:42:53 +0800122 * Validate the incoming table signature.
123 *
124 * 1) Originally, we checked the table signature for "SSDT" or "PSDT".
125 * 2) We added support for OEMx tables, signature "OEM".
126 * 3) Valid tables were encountered with a null signature, so we just
127 * gave up on validating the signature, (05/2008).
128 * 4) We encountered non-AML tables such as the MADT, which caused
129 * interpreter errors and kernel faults. So now, we once again allow
130 * only "SSDT", "OEMx", and now, also a null signature. (05/2011).
Bob Moorebc45b1d2008-06-10 14:12:50 +0800131 */
Bob Moorec8cefe32011-06-14 10:42:53 +0800132 if ((table_desc->pointer->signature[0] != 0x00) &&
133 (!ACPI_COMPARE_NAME(table_desc->pointer->signature, ACPI_SIG_SSDT))
134 && (ACPI_STRNCMP(table_desc->pointer->signature, "OEM", 3))) {
Bob Moore3b3ea772012-07-16 09:39:54 +0800135 ACPI_BIOS_ERROR((AE_INFO,
136 "Table has invalid signature [%4.4s] (0x%8.8X), "
137 "must be SSDT or OEMx",
Bob Moorede8e7db2013-06-08 00:59:44 +0000138 acpi_ut_valid_acpi_name(table_desc->pointer->
Bob Moore3b3ea772012-07-16 09:39:54 +0800139 signature) ?
140 table_desc->pointer->signature : "????",
141 *(u32 *)table_desc->pointer->signature));
Bob Moorec8cefe32011-06-14 10:42:53 +0800142
143 return_ACPI_STATUS(AE_BAD_SIGNATURE);
144 }
Alexey Starikovskiy428f2112007-02-02 19:48:22 +0300145
Bob Mooref3d2e782007-02-02 19:48:18 +0300146 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700147
Bob Mooref3d2e782007-02-02 19:48:18 +0300148 /* Check if table is already registered */
149
Bob Mooreb9ee2042010-04-27 11:16:14 +0800150 for (i = 0; i < acpi_gbl_root_table_list.current_table_count; ++i) {
Bob Mooref3d2e782007-02-02 19:48:18 +0300151 if (!acpi_gbl_root_table_list.tables[i].pointer) {
152 status =
153 acpi_tb_verify_table(&acpi_gbl_root_table_list.
154 tables[i]);
155 if (ACPI_FAILURE(status)
156 || !acpi_gbl_root_table_list.tables[i].pointer) {
157 continue;
158 }
159 }
160
Bob Moorea6f30532008-07-04 10:57:51 +0800161 /*
162 * Check for a table match on the entire table length,
163 * not just the header.
164 */
165 if (table_desc->length !=
166 acpi_gbl_root_table_list.tables[i].length) {
167 continue;
168 }
Bob Mooree56f5612008-07-04 10:48:43 +0800169
Alexey Starikovskiy428f2112007-02-02 19:48:22 +0300170 if (ACPI_MEMCMP(table_desc->pointer,
171 acpi_gbl_root_table_list.tables[i].pointer,
Bob Moorea6f30532008-07-04 10:57:51 +0800172 acpi_gbl_root_table_list.tables[i].length)) {
Bob Mooref3d2e782007-02-02 19:48:18 +0300173 continue;
174 }
175
Bob Mooree56f5612008-07-04 10:48:43 +0800176 /*
177 * Note: the current mechanism does not unregister a table if it is
178 * dynamically unloaded. The related namespace entries are deleted,
179 * but the table remains in the root table list.
180 *
181 * The assumption here is that the number of different tables that
182 * will be loaded is actually small, and there is minimal overhead
183 * in just keeping the table in case it is needed again.
184 *
185 * If this assumption changes in the future (perhaps on large
186 * machines with many table load/unload operations), tables will
187 * need to be unregistered when they are unloaded, and slots in the
188 * root table list should be reused when empty.
189 */
Bob Mooref3d2e782007-02-02 19:48:18 +0300190
Bob Mooree56f5612008-07-04 10:48:43 +0800191 /*
192 * Table is already registered.
193 * We can delete the table that was passed as a parameter.
194 */
Alexey Starikovskiy428f2112007-02-02 19:48:22 +0300195 acpi_tb_delete_table(table_desc);
Bob Mooref3d2e782007-02-02 19:48:18 +0300196 *table_index = i;
Bob Mooree56f5612008-07-04 10:48:43 +0800197
198 if (acpi_gbl_root_table_list.tables[i].
199 flags & ACPI_TABLE_IS_LOADED) {
200
201 /* Table is still loaded, this is an error */
202
203 status = AE_ALREADY_EXISTS;
204 goto release;
205 } else {
206 /* Table was unloaded, allow it to be reloaded */
207
208 table_desc->pointer =
209 acpi_gbl_root_table_list.tables[i].pointer;
210 table_desc->address =
211 acpi_gbl_root_table_list.tables[i].address;
212 status = AE_OK;
213 goto print_header;
214 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700215 }
216
Bob Moored3ccaff2009-02-03 14:43:04 +0800217 /*
218 * ACPI Table Override:
219 * Allow the host to override dynamically loaded tables.
Bob Mooref7b004a2012-02-14 18:31:56 +0800220 * NOTE: the table is fully mapped at this point, and the mapping will
221 * be deleted by tb_table_override if the table is actually overridden.
Bob Moored3ccaff2009-02-03 14:43:04 +0800222 */
Bob Mooref7b004a2012-02-14 18:31:56 +0800223 (void)acpi_tb_table_override(table_desc->pointer, table_desc);
Bob Moored3ccaff2009-02-03 14:43:04 +0800224
Bob Mooree56f5612008-07-04 10:48:43 +0800225 /* Add the table to the global root table list */
226
Alexey Starikovskiy428f2112007-02-02 19:48:22 +0300227 status = acpi_tb_store_table(table_desc->address, table_desc->pointer,
228 table_desc->length, table_desc->flags,
229 table_index);
Len Brown4be44fc2005-08-05 00:44:28 -0400230 if (ACPI_FAILURE(status)) {
Bob Mooref3d2e782007-02-02 19:48:18 +0300231 goto release;
Robert Moore0c9938c2005-07-29 15:15:00 -0700232 }
233
Lv Zheng10622bf2013-10-29 09:30:02 +0800234print_header:
Alexey Starikovskiy428f2112007-02-02 19:48:22 +0300235 acpi_tb_print_table_header(table_desc->address, table_desc->pointer);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700236
Lv Zheng10622bf2013-10-29 09:30:02 +0800237release:
Len Brown4be44fc2005-08-05 00:44:28 -0400238 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
239 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700240}
241
Linus Torvalds1da177e2005-04-16 15:20:36 -0700242/*******************************************************************************
243 *
Bob Mooref7b004a2012-02-14 18:31:56 +0800244 * FUNCTION: acpi_tb_table_override
245 *
246 * PARAMETERS: table_header - Header for the original table
247 * table_desc - Table descriptor initialized for the
248 * original table. May or may not be mapped.
249 *
250 * RETURN: Pointer to the entire new table. NULL if table not overridden.
251 * If overridden, installs the new table within the input table
252 * descriptor.
253 *
254 * DESCRIPTION: Attempt table override by calling the OSL override functions.
255 * Note: If the table is overridden, then the entire new table
256 * is mapped and returned by this function.
257 *
258 ******************************************************************************/
259
260struct acpi_table_header *acpi_tb_table_override(struct acpi_table_header
261 *table_header,
262 struct acpi_table_desc
263 *table_desc)
264{
265 acpi_status status;
266 struct acpi_table_header *new_table = NULL;
267 acpi_physical_address new_address = 0;
268 u32 new_table_length = 0;
269 u8 new_flags;
270 char *override_type;
271
272 /* (1) Attempt logical override (returns a logical address) */
273
274 status = acpi_os_table_override(table_header, &new_table);
275 if (ACPI_SUCCESS(status) && new_table) {
276 new_address = ACPI_PTR_TO_PHYSADDR(new_table);
277 new_table_length = new_table->length;
278 new_flags = ACPI_TABLE_ORIGIN_OVERRIDE;
279 override_type = "Logical";
280 goto finish_override;
281 }
282
283 /* (2) Attempt physical override (returns a physical address) */
284
285 status = acpi_os_physical_table_override(table_header,
286 &new_address,
287 &new_table_length);
288 if (ACPI_SUCCESS(status) && new_address && new_table_length) {
289
290 /* Map the entire new table */
291
292 new_table = acpi_os_map_memory(new_address, new_table_length);
293 if (!new_table) {
294 ACPI_EXCEPTION((AE_INFO, AE_NO_MEMORY,
295 "%4.4s %p Attempted physical table override failed",
296 table_header->signature,
297 ACPI_CAST_PTR(void,
298 table_desc->address)));
299 return (NULL);
300 }
301
302 override_type = "Physical";
303 new_flags = ACPI_TABLE_ORIGIN_MAPPED;
304 goto finish_override;
305 }
306
307 return (NULL); /* There was no override */
308
Lv Zheng10622bf2013-10-29 09:30:02 +0800309finish_override:
Bob Mooref7b004a2012-02-14 18:31:56 +0800310
311 ACPI_INFO((AE_INFO,
312 "%4.4s %p %s table override, new table: %p",
313 table_header->signature,
314 ACPI_CAST_PTR(void, table_desc->address),
315 override_type, new_table));
316
317 /* We can now unmap/delete the original table (if fully mapped) */
318
319 acpi_tb_delete_table(table_desc);
320
321 /* Setup descriptor for the new table */
322
323 table_desc->address = new_address;
324 table_desc->pointer = new_table;
325 table_desc->length = new_table_length;
326 table_desc->flags = new_flags;
327
328 return (new_table);
329}
330
331/*******************************************************************************
332 *
Bob Mooref3d2e782007-02-02 19:48:18 +0300333 * FUNCTION: acpi_tb_resize_root_table_list
Linus Torvalds1da177e2005-04-16 15:20:36 -0700334 *
Bob Mooref3d2e782007-02-02 19:48:18 +0300335 * PARAMETERS: None
Linus Torvalds1da177e2005-04-16 15:20:36 -0700336 *
337 * RETURN: Status
338 *
Bob Mooref3d2e782007-02-02 19:48:18 +0300339 * DESCRIPTION: Expand the size of global table array
Linus Torvalds1da177e2005-04-16 15:20:36 -0700340 *
341 ******************************************************************************/
342
Bob Mooref3d2e782007-02-02 19:48:18 +0300343acpi_status acpi_tb_resize_root_table_list(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700344{
Bob Mooref3d2e782007-02-02 19:48:18 +0300345 struct acpi_table_desc *tables;
Lv Zheng2bc198c2012-09-13 09:29:06 -0700346 u32 table_count;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700347
Bob Mooref3d2e782007-02-02 19:48:18 +0300348 ACPI_FUNCTION_TRACE(tb_resize_root_table_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700349
Bob Mooref3d2e782007-02-02 19:48:18 +0300350 /* allow_resize flag is a parameter to acpi_initialize_tables */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700351
Bob Moorec5fc42a2007-02-02 19:48:19 +0300352 if (!(acpi_gbl_root_table_list.flags & ACPI_ROOT_ALLOW_RESIZE)) {
Bob Mooref3d2e782007-02-02 19:48:18 +0300353 ACPI_ERROR((AE_INFO,
354 "Resize of Root Table Array is not allowed"));
355 return_ACPI_STATUS(AE_SUPPORT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700356 }
357
Bob Mooref3d2e782007-02-02 19:48:18 +0300358 /* Increase the Table Array size */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700359
Lv Zheng2bc198c2012-09-13 09:29:06 -0700360 if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) {
361 table_count = acpi_gbl_root_table_list.max_table_count;
362 } else {
363 table_count = acpi_gbl_root_table_list.current_table_count;
364 }
365
366 tables = ACPI_ALLOCATE_ZEROED(((acpi_size) table_count +
Bob Mooreec41f192009-02-18 15:03:30 +0800367 ACPI_ROOT_TABLE_SIZE_INCREMENT) *
368 sizeof(struct acpi_table_desc));
Bob Mooref3d2e782007-02-02 19:48:18 +0300369 if (!tables) {
370 ACPI_ERROR((AE_INFO,
371 "Could not allocate new root table array"));
Len Brown4be44fc2005-08-05 00:44:28 -0400372 return_ACPI_STATUS(AE_NO_MEMORY);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700373 }
374
Bob Mooref3d2e782007-02-02 19:48:18 +0300375 /* Copy and free the previous table array */
Robert Mooref9f46012005-07-08 00:00:00 -0400376
Bob Mooref3d2e782007-02-02 19:48:18 +0300377 if (acpi_gbl_root_table_list.tables) {
378 ACPI_MEMCPY(tables, acpi_gbl_root_table_list.tables,
Lv Zheng2bc198c2012-09-13 09:29:06 -0700379 (acpi_size) table_count *
380 sizeof(struct acpi_table_desc));
Robert Mooref9f46012005-07-08 00:00:00 -0400381
Bob Moorec5fc42a2007-02-02 19:48:19 +0300382 if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) {
Bob Mooref3d2e782007-02-02 19:48:18 +0300383 ACPI_FREE(acpi_gbl_root_table_list.tables);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700384 }
385 }
386
Bob Mooref3d2e782007-02-02 19:48:18 +0300387 acpi_gbl_root_table_list.tables = tables;
Lv Zheng2bc198c2012-09-13 09:29:06 -0700388 acpi_gbl_root_table_list.max_table_count =
389 table_count + ACPI_ROOT_TABLE_SIZE_INCREMENT;
390 acpi_gbl_root_table_list.flags |= ACPI_ROOT_ORIGIN_ALLOCATED;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700391
Len Brown4be44fc2005-08-05 00:44:28 -0400392 return_ACPI_STATUS(AE_OK);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700393}
394
Linus Torvalds1da177e2005-04-16 15:20:36 -0700395/*******************************************************************************
396 *
Bob Mooref3d2e782007-02-02 19:48:18 +0300397 * FUNCTION: acpi_tb_store_table
Linus Torvalds1da177e2005-04-16 15:20:36 -0700398 *
Bob Mooreba494be2012-07-12 09:40:10 +0800399 * PARAMETERS: address - Table address
400 * table - Table header
401 * length - Table length
402 * flags - flags
Linus Torvalds1da177e2005-04-16 15:20:36 -0700403 *
Bob Mooref3d2e782007-02-02 19:48:18 +0300404 * RETURN: Status and table index.
405 *
406 * DESCRIPTION: Add an ACPI table to the global table list
407 *
408 ******************************************************************************/
409
410acpi_status
411acpi_tb_store_table(acpi_physical_address address,
412 struct acpi_table_header *table,
Bob Moore67a119f2008-06-10 13:42:13 +0800413 u32 length, u8 flags, u32 *table_index)
Bob Mooref3d2e782007-02-02 19:48:18 +0300414{
Bob Mooreb9ee2042010-04-27 11:16:14 +0800415 acpi_status status;
416 struct acpi_table_desc *new_table;
Bob Mooref3d2e782007-02-02 19:48:18 +0300417
418 /* Ensure that there is room for the table in the Root Table List */
419
Bob Mooreb9ee2042010-04-27 11:16:14 +0800420 if (acpi_gbl_root_table_list.current_table_count >=
421 acpi_gbl_root_table_list.max_table_count) {
Bob Mooref3d2e782007-02-02 19:48:18 +0300422 status = acpi_tb_resize_root_table_list();
423 if (ACPI_FAILURE(status)) {
424 return (status);
425 }
426 }
427
Bob Mooreb9ee2042010-04-27 11:16:14 +0800428 new_table =
429 &acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.
430 current_table_count];
431
Bob Mooref3d2e782007-02-02 19:48:18 +0300432 /* Initialize added table */
433
Bob Mooreb9ee2042010-04-27 11:16:14 +0800434 new_table->address = address;
435 new_table->pointer = table;
436 new_table->length = length;
437 new_table->owner_id = 0;
438 new_table->flags = flags;
Bob Mooref3d2e782007-02-02 19:48:18 +0300439
Bob Mooreb9ee2042010-04-27 11:16:14 +0800440 ACPI_MOVE_32_TO_32(&new_table->signature, table->signature);
Bob Mooref3d2e782007-02-02 19:48:18 +0300441
Bob Mooreb9ee2042010-04-27 11:16:14 +0800442 *table_index = acpi_gbl_root_table_list.current_table_count;
443 acpi_gbl_root_table_list.current_table_count++;
444 return (AE_OK);
Bob Mooref3d2e782007-02-02 19:48:18 +0300445}
446
447/*******************************************************************************
448 *
449 * FUNCTION: acpi_tb_delete_table
450 *
451 * PARAMETERS: table_index - Table index
452 *
453 * RETURN: None
454 *
455 * DESCRIPTION: Delete one internal ACPI table
456 *
457 ******************************************************************************/
458
Alexey Starikovskiy428f2112007-02-02 19:48:22 +0300459void acpi_tb_delete_table(struct acpi_table_desc *table_desc)
Bob Mooref3d2e782007-02-02 19:48:18 +0300460{
Bob Mooref3d2e782007-02-02 19:48:18 +0300461 /* Table must be mapped or allocated */
Bob Mooref3d2e782007-02-02 19:48:18 +0300462 if (!table_desc->pointer) {
463 return;
464 }
Alexey Starikovskiy428f2112007-02-02 19:48:22 +0300465 switch (table_desc->flags & ACPI_TABLE_ORIGIN_MASK) {
466 case ACPI_TABLE_ORIGIN_MAPPED:
Chao Guan1d1ea1b2013-06-08 00:58:14 +0000467
Alexey Starikovskiy428f2112007-02-02 19:48:22 +0300468 acpi_os_unmap_memory(table_desc->pointer, table_desc->length);
469 break;
Chao Guan1d1ea1b2013-06-08 00:58:14 +0000470
Alexey Starikovskiy428f2112007-02-02 19:48:22 +0300471 case ACPI_TABLE_ORIGIN_ALLOCATED:
Chao Guan1d1ea1b2013-06-08 00:58:14 +0000472
Bob Mooref3d2e782007-02-02 19:48:18 +0300473 ACPI_FREE(table_desc->pointer);
Alexey Starikovskiy428f2112007-02-02 19:48:22 +0300474 break;
Bob Mooref7b004a2012-02-14 18:31:56 +0800475
476 /* Not mapped or allocated, there is nothing we can do */
477
478 default:
Chao Guan1d1ea1b2013-06-08 00:58:14 +0000479
Bob Mooref7b004a2012-02-14 18:31:56 +0800480 return;
Bob Mooref3d2e782007-02-02 19:48:18 +0300481 }
482
483 table_desc->pointer = NULL;
484}
485
486/*******************************************************************************
487 *
488 * FUNCTION: acpi_tb_terminate
489 *
490 * PARAMETERS: None
491 *
492 * RETURN: None
Linus Torvalds1da177e2005-04-16 15:20:36 -0700493 *
494 * DESCRIPTION: Delete all internal ACPI tables
495 *
496 ******************************************************************************/
497
Bob Mooref3d2e782007-02-02 19:48:18 +0300498void acpi_tb_terminate(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700499{
Bob Moore67a119f2008-06-10 13:42:13 +0800500 u32 i;
Bob Mooref3d2e782007-02-02 19:48:18 +0300501
502 ACPI_FUNCTION_TRACE(tb_terminate);
503
504 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
505
506 /* Delete the individual tables */
507
Bob Mooreb9ee2042010-04-27 11:16:14 +0800508 for (i = 0; i < acpi_gbl_root_table_list.current_table_count; i++) {
Alexey Starikovskiy428f2112007-02-02 19:48:22 +0300509 acpi_tb_delete_table(&acpi_gbl_root_table_list.tables[i]);
Bob Mooref3d2e782007-02-02 19:48:18 +0300510 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700511
512 /*
Bob Mooref3d2e782007-02-02 19:48:18 +0300513 * Delete the root table array if allocated locally. Array cannot be
514 * mapped, so we don't need to check for that flag.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700515 */
Bob Moorec5fc42a2007-02-02 19:48:19 +0300516 if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) {
Bob Mooref3d2e782007-02-02 19:48:18 +0300517 ACPI_FREE(acpi_gbl_root_table_list.tables);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700518 }
Bob Mooref3d2e782007-02-02 19:48:18 +0300519
520 acpi_gbl_root_table_list.tables = NULL;
521 acpi_gbl_root_table_list.flags = 0;
Bob Mooreb9ee2042010-04-27 11:16:14 +0800522 acpi_gbl_root_table_list.current_table_count = 0;
Bob Mooref3d2e782007-02-02 19:48:18 +0300523
524 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "ACPI Tables freed\n"));
525 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
Bob Moore68aafc32012-10-31 02:26:01 +0000526
527 return_VOID;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700528}
529
Linus Torvalds1da177e2005-04-16 15:20:36 -0700530/*******************************************************************************
531 *
Bob Mooref3d2e782007-02-02 19:48:18 +0300532 * FUNCTION: acpi_tb_delete_namespace_by_owner
Linus Torvalds1da177e2005-04-16 15:20:36 -0700533 *
Bob Mooref3d2e782007-02-02 19:48:18 +0300534 * PARAMETERS: table_index - Table index
Linus Torvalds1da177e2005-04-16 15:20:36 -0700535 *
Bob Moore8a335a232009-03-09 16:31:04 +0800536 * RETURN: Status
Linus Torvalds1da177e2005-04-16 15:20:36 -0700537 *
Bob Mooref3d2e782007-02-02 19:48:18 +0300538 * DESCRIPTION: Delete all namespace objects created when this table was loaded.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700539 *
540 ******************************************************************************/
541
Bob Moore8a335a232009-03-09 16:31:04 +0800542acpi_status acpi_tb_delete_namespace_by_owner(u32 table_index)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700543{
Bob Mooref3d2e782007-02-02 19:48:18 +0300544 acpi_owner_id owner_id;
Bob Moore8a335a232009-03-09 16:31:04 +0800545 acpi_status status;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700546
Bob Moore8a335a232009-03-09 16:31:04 +0800547 ACPI_FUNCTION_TRACE(tb_delete_namespace_by_owner);
548
549 status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
550 if (ACPI_FAILURE(status)) {
551 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700552 }
553
Bob Mooreb9ee2042010-04-27 11:16:14 +0800554 if (table_index >= acpi_gbl_root_table_list.current_table_count) {
Bob Moore8a335a232009-03-09 16:31:04 +0800555
556 /* The table index does not exist */
557
558 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
559 return_ACPI_STATUS(AE_NOT_EXIST);
560 }
561
562 /* Get the owner ID for this table, used to delete namespace nodes */
563
564 owner_id = acpi_gbl_root_table_list.tables[table_index].owner_id;
Len Brown4be44fc2005-08-05 00:44:28 -0400565 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
Bob Moore8a335a232009-03-09 16:31:04 +0800566
567 /*
568 * Need to acquire the namespace writer lock to prevent interference
569 * with any concurrent namespace walks. The interpreter must be
570 * released during the deletion since the acquisition of the deletion
571 * lock may block, and also since the execution of a namespace walk
572 * must be allowed to use the interpreter.
573 */
Bob Mooree4c1ebf2009-04-22 13:02:06 +0800574 (void)acpi_ut_release_mutex(ACPI_MTX_INTERPRETER);
Bob Moore8a335a232009-03-09 16:31:04 +0800575 status = acpi_ut_acquire_write_lock(&acpi_gbl_namespace_rw_lock);
576
Bob Mooref3d2e782007-02-02 19:48:18 +0300577 acpi_ns_delete_namespace_by_owner(owner_id);
Bob Moore8a335a232009-03-09 16:31:04 +0800578 if (ACPI_FAILURE(status)) {
579 return_ACPI_STATUS(status);
580 }
581
582 acpi_ut_release_write_lock(&acpi_gbl_namespace_rw_lock);
583
584 status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER);
585 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700586}
587
Linus Torvalds1da177e2005-04-16 15:20:36 -0700588/*******************************************************************************
589 *
Bob Mooref3d2e782007-02-02 19:48:18 +0300590 * FUNCTION: acpi_tb_allocate_owner_id
Linus Torvalds1da177e2005-04-16 15:20:36 -0700591 *
Bob Mooref3d2e782007-02-02 19:48:18 +0300592 * PARAMETERS: table_index - Table index
Linus Torvalds1da177e2005-04-16 15:20:36 -0700593 *
Bob Mooref3d2e782007-02-02 19:48:18 +0300594 * RETURN: Status
Linus Torvalds1da177e2005-04-16 15:20:36 -0700595 *
Bob Mooref3d2e782007-02-02 19:48:18 +0300596 * DESCRIPTION: Allocates owner_id in table_desc
Linus Torvalds1da177e2005-04-16 15:20:36 -0700597 *
598 ******************************************************************************/
599
Bob Moore67a119f2008-06-10 13:42:13 +0800600acpi_status acpi_tb_allocate_owner_id(u32 table_index)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700601{
Bob Mooref3d2e782007-02-02 19:48:18 +0300602 acpi_status status = AE_BAD_PARAMETER;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700603
Bob Mooref3d2e782007-02-02 19:48:18 +0300604 ACPI_FUNCTION_TRACE(tb_allocate_owner_id);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700605
Bob Mooref3d2e782007-02-02 19:48:18 +0300606 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
Bob Mooreb9ee2042010-04-27 11:16:14 +0800607 if (table_index < acpi_gbl_root_table_list.current_table_count) {
Bob Mooref3d2e782007-02-02 19:48:18 +0300608 status = acpi_ut_allocate_owner_id
609 (&(acpi_gbl_root_table_list.tables[table_index].owner_id));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700610 }
611
Bob Mooref3d2e782007-02-02 19:48:18 +0300612 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
613 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700614}
615
Linus Torvalds1da177e2005-04-16 15:20:36 -0700616/*******************************************************************************
617 *
Bob Mooref3d2e782007-02-02 19:48:18 +0300618 * FUNCTION: acpi_tb_release_owner_id
Linus Torvalds1da177e2005-04-16 15:20:36 -0700619 *
Bob Mooref3d2e782007-02-02 19:48:18 +0300620 * PARAMETERS: table_index - Table index
Linus Torvalds1da177e2005-04-16 15:20:36 -0700621 *
Bob Mooref3d2e782007-02-02 19:48:18 +0300622 * RETURN: Status
Linus Torvalds1da177e2005-04-16 15:20:36 -0700623 *
Bob Mooref3d2e782007-02-02 19:48:18 +0300624 * DESCRIPTION: Releases owner_id in table_desc
Linus Torvalds1da177e2005-04-16 15:20:36 -0700625 *
626 ******************************************************************************/
627
Bob Moore67a119f2008-06-10 13:42:13 +0800628acpi_status acpi_tb_release_owner_id(u32 table_index)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700629{
Bob Mooref3d2e782007-02-02 19:48:18 +0300630 acpi_status status = AE_BAD_PARAMETER;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700631
Bob Mooref3d2e782007-02-02 19:48:18 +0300632 ACPI_FUNCTION_TRACE(tb_release_owner_id);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700633
Bob Mooref3d2e782007-02-02 19:48:18 +0300634 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
Bob Mooreb9ee2042010-04-27 11:16:14 +0800635 if (table_index < acpi_gbl_root_table_list.current_table_count) {
Bob Mooref3d2e782007-02-02 19:48:18 +0300636 acpi_ut_release_owner_id(&
637 (acpi_gbl_root_table_list.
638 tables[table_index].owner_id));
639 status = AE_OK;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700640 }
641
Bob Mooref3d2e782007-02-02 19:48:18 +0300642 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
643 return_ACPI_STATUS(status);
644}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700645
Bob Mooref3d2e782007-02-02 19:48:18 +0300646/*******************************************************************************
647 *
648 * FUNCTION: acpi_tb_get_owner_id
649 *
650 * PARAMETERS: table_index - Table index
651 * owner_id - Where the table owner_id is returned
652 *
653 * RETURN: Status
654 *
655 * DESCRIPTION: returns owner_id for the ACPI table
656 *
657 ******************************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -0700658
Bob Moore67a119f2008-06-10 13:42:13 +0800659acpi_status acpi_tb_get_owner_id(u32 table_index, acpi_owner_id *owner_id)
Bob Mooref3d2e782007-02-02 19:48:18 +0300660{
661 acpi_status status = AE_BAD_PARAMETER;
662
663 ACPI_FUNCTION_TRACE(tb_get_owner_id);
664
665 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
Bob Mooreb9ee2042010-04-27 11:16:14 +0800666 if (table_index < acpi_gbl_root_table_list.current_table_count) {
Bob Mooref3d2e782007-02-02 19:48:18 +0300667 *owner_id =
668 acpi_gbl_root_table_list.tables[table_index].owner_id;
669 status = AE_OK;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700670 }
671
Bob Mooref3d2e782007-02-02 19:48:18 +0300672 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
673 return_ACPI_STATUS(status);
674}
675
676/*******************************************************************************
677 *
678 * FUNCTION: acpi_tb_is_table_loaded
679 *
680 * PARAMETERS: table_index - Table index
681 *
682 * RETURN: Table Loaded Flag
683 *
684 ******************************************************************************/
685
Bob Moore67a119f2008-06-10 13:42:13 +0800686u8 acpi_tb_is_table_loaded(u32 table_index)
Bob Mooref3d2e782007-02-02 19:48:18 +0300687{
688 u8 is_loaded = FALSE;
689
690 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
Bob Mooreb9ee2042010-04-27 11:16:14 +0800691 if (table_index < acpi_gbl_root_table_list.current_table_count) {
Bob Mooref3d2e782007-02-02 19:48:18 +0300692 is_loaded = (u8)
Bob Mooreec41f192009-02-18 15:03:30 +0800693 (acpi_gbl_root_table_list.tables[table_index].flags &
694 ACPI_TABLE_IS_LOADED);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700695 }
696
Bob Mooref3d2e782007-02-02 19:48:18 +0300697 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
698 return (is_loaded);
699}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700700
Bob Mooref3d2e782007-02-02 19:48:18 +0300701/*******************************************************************************
702 *
703 * FUNCTION: acpi_tb_set_table_loaded_flag
704 *
705 * PARAMETERS: table_index - Table index
706 * is_loaded - TRUE if table is loaded, FALSE otherwise
707 *
708 * RETURN: None
709 *
710 * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE.
711 *
712 ******************************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -0700713
Bob Moore67a119f2008-06-10 13:42:13 +0800714void acpi_tb_set_table_loaded_flag(u32 table_index, u8 is_loaded)
Bob Mooref3d2e782007-02-02 19:48:18 +0300715{
Bob Mooref6dd9222006-07-07 20:44:38 -0400716
Bob Mooref3d2e782007-02-02 19:48:18 +0300717 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
Bob Mooreb9ee2042010-04-27 11:16:14 +0800718 if (table_index < acpi_gbl_root_table_list.current_table_count) {
Bob Mooref3d2e782007-02-02 19:48:18 +0300719 if (is_loaded) {
720 acpi_gbl_root_table_list.tables[table_index].flags |=
Bob Moorec5fc42a2007-02-02 19:48:19 +0300721 ACPI_TABLE_IS_LOADED;
Bob Mooref3d2e782007-02-02 19:48:18 +0300722 } else {
723 acpi_gbl_root_table_list.tables[table_index].flags &=
Bob Moorec5fc42a2007-02-02 19:48:19 +0300724 ~ACPI_TABLE_IS_LOADED;
Bob Mooref3d2e782007-02-02 19:48:18 +0300725 }
726 }
Bob Mooref6dd9222006-07-07 20:44:38 -0400727
Bob Mooref3d2e782007-02-02 19:48:18 +0300728 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700729}