blob: de10d3245d9cc80572edb11fed6deed7755dc052 [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 Zheng86dfc6f32014-04-04 12:38:57 +080052/* Local prototypes */
53static acpi_status
54acpi_tb_acquire_temporal_table(struct acpi_table_desc *table_desc,
55 acpi_physical_address address, u8 flags);
56
57static void acpi_tb_release_temporal_table(struct acpi_table_desc *table_desc);
58
59static acpi_status acpi_tb_acquire_root_table_entry(u32 *table_index);
60
61static u8
62acpi_tb_is_equivalent_table(struct acpi_table_desc *table_desc,
63 u32 table_index);
64
Lv Zheng7f9fc992014-04-04 12:38:42 +080065/*******************************************************************************
Linus Torvalds1da177e2005-04-16 15:20:36 -070066 *
Lv Zheng7f9fc992014-04-04 12:38:42 +080067 * FUNCTION: acpi_tb_acquire_table
Linus Torvalds1da177e2005-04-16 15:20:36 -070068 *
Lv Zheng7f9fc992014-04-04 12:38:42 +080069 * PARAMETERS: table_desc - Table descriptor
70 * table_ptr - Where table is returned
71 * table_length - Where table length is returned
72 * table_flags - Where table allocation flags are returned
Linus Torvalds1da177e2005-04-16 15:20:36 -070073 *
74 * RETURN: Status
75 *
Lv Zheng7f9fc992014-04-04 12:38:42 +080076 * DESCRIPTION: Acquire a table. It can be used for tables not maintained in
77 * acpi_gbl_root_table_list.
78 *
79 ******************************************************************************/
Lv Zheng86dfc6f32014-04-04 12:38:57 +080080
Lv Zheng7f9fc992014-04-04 12:38:42 +080081acpi_status
82acpi_tb_acquire_table(struct acpi_table_desc *table_desc,
83 struct acpi_table_header **table_ptr,
84 u32 *table_length, u8 *table_flags)
85{
86 struct acpi_table_header *table = NULL;
87
88 switch (table_desc->flags & ACPI_TABLE_ORIGIN_MASK) {
Lv Zheng8a216d72014-04-04 12:39:04 +080089 case ACPI_TABLE_ORIGIN_INTERN_PHYSICAL:
Lv Zheng7f9fc992014-04-04 12:38:42 +080090
91 table =
92 acpi_os_map_memory(table_desc->address, table_desc->length);
93 break;
94
Lv Zheng8a216d72014-04-04 12:39:04 +080095 case ACPI_TABLE_ORIGIN_INTERN_VIRTUAL:
96 case ACPI_TABLE_ORIGIN_EXTERN_VIRTUAL:
Lv Zheng7f9fc992014-04-04 12:38:42 +080097
98 table =
99 ACPI_CAST_PTR(struct acpi_table_header,
100 table_desc->address);
101 break;
102
103 default:
104
105 break;
106 }
107
108 /* Table is not valid yet */
109
110 if (!table) {
111 return (AE_NO_MEMORY);
112 }
113
114 /* Fill the return values */
115
116 *table_ptr = table;
117 *table_length = table_desc->length;
118 *table_flags = table_desc->flags;
119
120 return (AE_OK);
121}
122
123/*******************************************************************************
124 *
125 * FUNCTION: acpi_tb_release_table
126 *
127 * PARAMETERS: table - Pointer for the table
128 * table_length - Length for the table
129 * table_flags - Allocation flags for the table
130 *
131 * RETURN: None
132 *
133 * DESCRIPTION: Release a table. The reversal of acpi_tb_acquire_table().
134 *
135 ******************************************************************************/
136
137void
138acpi_tb_release_table(struct acpi_table_header *table,
139 u32 table_length, u8 table_flags)
140{
141 switch (table_flags & ACPI_TABLE_ORIGIN_MASK) {
Lv Zheng8a216d72014-04-04 12:39:04 +0800142 case ACPI_TABLE_ORIGIN_INTERN_PHYSICAL:
Lv Zheng7f9fc992014-04-04 12:38:42 +0800143
144 acpi_os_unmap_memory(table, table_length);
145 break;
146
Lv Zheng8a216d72014-04-04 12:39:04 +0800147 case ACPI_TABLE_ORIGIN_INTERN_VIRTUAL:
148 case ACPI_TABLE_ORIGIN_EXTERN_VIRTUAL:
Lv Zheng7f9fc992014-04-04 12:38:42 +0800149 default:
150
151 break;
152 }
153}
154
155/******************************************************************************
156 *
157 * FUNCTION: acpi_tb_validate_table
158 *
159 * PARAMETERS: table_desc - Table descriptor
160 *
161 * RETURN: Status
162 *
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800163 * DESCRIPTION: This function is called to validate the table, the returned
164 * table descriptor is in "VALIDATED" state.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700165 *
Bob Mooref3d2e782007-02-02 19:48:18 +0300166 *****************************************************************************/
Lv Zheng7f9fc992014-04-04 12:38:42 +0800167
168acpi_status acpi_tb_validate_table(struct acpi_table_desc *table_desc)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700169{
Alexey Starikovskiy428f2112007-02-02 19:48:22 +0300170 acpi_status status = AE_OK;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700171
Lv Zheng7f9fc992014-04-04 12:38:42 +0800172 ACPI_FUNCTION_TRACE(tb_validate_table);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700173
Lv Zheng7f9fc992014-04-04 12:38:42 +0800174 /* Validate the table if necessary */
Robert Moore44f6c012005-04-18 22:49:35 -0400175
Bob Mooref3d2e782007-02-02 19:48:18 +0300176 if (!table_desc->pointer) {
Lv Zheng7f9fc992014-04-04 12:38:42 +0800177 status = acpi_tb_acquire_table(table_desc, &table_desc->pointer,
178 &table_desc->length,
179 &table_desc->flags);
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800180 if (!table_desc->pointer) {
181 status = AE_NO_MEMORY;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700182 }
183 }
184
Bob Moorec5fc42a2007-02-02 19:48:19 +0300185 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700186}
187
Linus Torvalds1da177e2005-04-16 15:20:36 -0700188/*******************************************************************************
189 *
Lv Zheng7f9fc992014-04-04 12:38:42 +0800190 * FUNCTION: acpi_tb_invalidate_table
191 *
192 * PARAMETERS: table_desc - Table descriptor
193 *
194 * RETURN: None
195 *
196 * DESCRIPTION: Invalidate one internal ACPI table, this is reversal of
197 * acpi_tb_validate_table().
198 *
199 ******************************************************************************/
200
201void acpi_tb_invalidate_table(struct acpi_table_desc *table_desc)
202{
203
204 ACPI_FUNCTION_TRACE(tb_invalidate_table);
205
206 /* Table must be validated */
207
208 if (!table_desc->pointer) {
209 return_VOID;
210 }
211
212 acpi_tb_release_table(table_desc->pointer, table_desc->length,
213 table_desc->flags);
214 table_desc->pointer = NULL;
215
216 return_VOID;
217}
218
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800219/******************************************************************************
Lv Zheng7f9fc992014-04-04 12:38:42 +0800220 *
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800221 * FUNCTION: acpi_tb_verify_table
Linus Torvalds1da177e2005-04-16 15:20:36 -0700222 *
Alexey Starikovskiy428f2112007-02-02 19:48:22 +0300223 * PARAMETERS: table_desc - Table descriptor
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800224 * signature - Table signature to verify
Linus Torvalds1da177e2005-04-16 15:20:36 -0700225 *
226 * RETURN: Status
227 *
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800228 * DESCRIPTION: This function is called to validate and verify the table, the
229 * returned table descriptor is in "VALIDATED" state.
230 *
231 *****************************************************************************/
232
233acpi_status
234acpi_tb_verify_table(struct acpi_table_desc *table_desc, char *signature)
235{
236 acpi_status status = AE_OK;
237
238 ACPI_FUNCTION_TRACE(tb_verify_table);
239
240 /* Validate the table */
241
242 status = acpi_tb_validate_table(table_desc);
243 if (ACPI_FAILURE(status)) {
244 return_ACPI_STATUS(AE_NO_MEMORY);
245 }
246
247 /* If a particular signature is expected (DSDT/FACS), it must match */
248
249 if (signature && !ACPI_COMPARE_NAME(&table_desc->signature, signature)) {
250 ACPI_BIOS_ERROR((AE_INFO,
251 "Invalid signature 0x%X for ACPI table, expected [%s]",
252 table_desc->signature.integer, signature));
253 status = AE_BAD_SIGNATURE;
254 goto invalidate_and_exit;
255 }
256
257 /* Verify the checksum */
258
259 status =
260 acpi_tb_verify_checksum(table_desc->pointer, table_desc->length);
261 if (ACPI_FAILURE(status)) {
262 ACPI_EXCEPTION((AE_INFO, AE_NO_MEMORY,
263 "%4.4s " ACPI_PRINTF_UINT
264 " Attempted table install failed",
265 acpi_ut_valid_acpi_name(table_desc->signature.
266 ascii) ? table_desc->
267 signature.ascii : "????",
268 ACPI_FORMAT_TO_UINT(table_desc->address)));
269 goto invalidate_and_exit;
270 }
271
272 return_ACPI_STATUS(AE_OK);
273
274invalidate_and_exit:
275 acpi_tb_invalidate_table(table_desc);
276 return_ACPI_STATUS(status);
277}
278
279/*******************************************************************************
280 *
281 * FUNCTION: acpi_tb_install_table
282 *
283 * PARAMETERS: table_desc - Table descriptor
284 * address - Physical address of the table
285 * flags - Allocation flags of the table
286 * table - Pointer to the table
287 *
288 * RETURN: None
289 *
290 * DESCRIPTION: Install an ACPI table into the global data structure.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700291 *
292 ******************************************************************************/
293
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800294void
295acpi_tb_install_table(struct acpi_table_desc *table_desc,
296 acpi_physical_address address,
297 u8 flags, struct acpi_table_header *table)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700298{
Bob Moorebc45b1d2008-06-10 14:12:50 +0800299 /*
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800300 * Initialize the table entry. Set the pointer to NULL, since the
301 * table is not fully mapped at this time.
Bob Moorebc45b1d2008-06-10 14:12:50 +0800302 */
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800303 ACPI_MEMSET(table_desc, 0, sizeof(struct acpi_table_desc));
304 table_desc->address = address;
305 table_desc->length = table->length;
306 table_desc->flags = flags;
307 ACPI_MOVE_32_TO_32(table_desc->signature.ascii, table->signature);
308}
Bob Moorec8cefe32011-06-14 10:42:53 +0800309
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800310/*******************************************************************************
311 *
312 * FUNCTION: acpi_tb_acquire_temporal_table
313 *
314 * PARAMETERS: table_desc - Table descriptor to be acquired
315 * address - Address of the table
316 * flags - Allocation flags of the table
317 *
318 * RETURN: Status
319 *
320 * DESCRIPTION: This function validates the table header to obtain the length
321 * of a table and fills the table descriptor to make its state as
322 * "INSTALLED". Such table descriptor is only used for verified
323 * installation.
324 *
325 ******************************************************************************/
326
327static acpi_status
328acpi_tb_acquire_temporal_table(struct acpi_table_desc *table_desc,
329 acpi_physical_address address, u8 flags)
330{
331 struct acpi_table_header *table_header;
332
333 switch (flags & ACPI_TABLE_ORIGIN_MASK) {
Lv Zheng8a216d72014-04-04 12:39:04 +0800334 case ACPI_TABLE_ORIGIN_INTERN_PHYSICAL:
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800335
336 /* Try to obtain the length of the table */
337
338 table_header =
339 acpi_os_map_memory(address,
340 sizeof(struct acpi_table_header));
341 if (!table_header) {
342 return (AE_NO_MEMORY);
343 }
344 acpi_tb_install_table(table_desc, address, flags, table_header);
345 acpi_os_unmap_memory(table_header,
346 sizeof(struct acpi_table_header));
347 return (AE_OK);
348
Lv Zheng8a216d72014-04-04 12:39:04 +0800349 case ACPI_TABLE_ORIGIN_INTERN_VIRTUAL:
350 case ACPI_TABLE_ORIGIN_EXTERN_VIRTUAL:
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800351
352 table_header = ACPI_CAST_PTR(struct acpi_table_header, address);
353 if (!table_header) {
354 return (AE_NO_MEMORY);
355 }
356 acpi_tb_install_table(table_desc, address, flags, table_header);
357 return (AE_OK);
358
359 default:
360
361 break;
Bob Moorec8cefe32011-06-14 10:42:53 +0800362 }
Alexey Starikovskiy428f2112007-02-02 19:48:22 +0300363
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800364 /* Table is not valid yet */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700365
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800366 return (AE_NO_MEMORY);
367}
Bob Mooref3d2e782007-02-02 19:48:18 +0300368
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800369/*******************************************************************************
370 *
371 * FUNCTION: acpi_tb_release_temporal_table
372 *
373 * PARAMETERS: table_desc - Table descriptor to be released
374 *
375 * RETURN: Status
376 *
377 * DESCRIPTION: The reversal of acpi_tb_acquire_temporal_table().
378 *
379 ******************************************************************************/
Bob Mooref3d2e782007-02-02 19:48:18 +0300380
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800381static void acpi_tb_release_temporal_table(struct acpi_table_desc *table_desc)
382{
383 /*
384 * Note that the .Address is maintained by the callers of
385 * acpi_tb_acquire_temporal_table(), thus do not invoke acpi_tb_uninstall_table()
386 * where .Address will be freed.
387 */
388 acpi_tb_invalidate_table(table_desc);
389}
Bob Mooree56f5612008-07-04 10:48:43 +0800390
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800391/*******************************************************************************
392 *
393 * FUNCTION: acpi_tb_install_and_override_table
394 *
395 * PARAMETERS: table_index - Index into root table array
396 * new_table_desc - New table descriptor to install
397 *
398 * RETURN: None
399 *
400 * DESCRIPTION: Install an ACPI table into the global data structure. The
401 * table override mechanism is called to allow the host
402 * OS to replace any table before it is installed in the root
403 * table array.
404 *
405 ******************************************************************************/
Bob Mooref3d2e782007-02-02 19:48:18 +0300406
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800407void
408acpi_tb_install_and_override_table(u32 table_index,
409 struct acpi_table_desc *new_table_desc)
410{
411 if (table_index >= acpi_gbl_root_table_list.current_table_count) {
412 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700413 }
414
Bob Moored3ccaff2009-02-03 14:43:04 +0800415 /*
416 * ACPI Table Override:
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800417 *
418 * Before we install the table, let the host OS override it with a new
419 * one if desired. Any table within the RSDT/XSDT can be replaced,
420 * including the DSDT which is pointed to by the FADT.
Bob Moored3ccaff2009-02-03 14:43:04 +0800421 */
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800422 acpi_tb_override_table(new_table_desc);
Lv Zheng7f9fc992014-04-04 12:38:42 +0800423
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800424 acpi_tb_install_table(&acpi_gbl_root_table_list.tables[table_index],
425 new_table_desc->address, new_table_desc->flags,
426 new_table_desc->pointer);
Lv Zheng7f9fc992014-04-04 12:38:42 +0800427
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800428 acpi_tb_print_table_header(new_table_desc->address,
429 new_table_desc->pointer);
430
431 /* Set the global integer width (based upon revision of the DSDT) */
432
433 if (table_index == ACPI_TABLE_INDEX_DSDT) {
434 acpi_ut_set_integer_width(new_table_desc->pointer->revision);
435 }
436}
437
438/*******************************************************************************
439 *
440 * FUNCTION: acpi_tb_install_fixed_table
441 *
442 * PARAMETERS: address - Physical address of DSDT or FACS
443 * signature - Table signature, NULL if no need to
444 * match
445 * table_index - Index into root table array
446 *
447 * RETURN: Status
448 *
449 * DESCRIPTION: Install a fixed ACPI table (DSDT/FACS) into the global data
450 * structure.
451 *
452 ******************************************************************************/
453
454acpi_status
455acpi_tb_install_fixed_table(acpi_physical_address address,
456 char *signature, u32 table_index)
457{
458 struct acpi_table_desc new_table_desc;
459 acpi_status status;
460
461 ACPI_FUNCTION_TRACE(tb_install_fixed_table);
462
463 if (!address) {
464 ACPI_ERROR((AE_INFO,
465 "Null physical address for ACPI table [%s]",
466 signature));
467 return (AE_NO_MEMORY);
468 }
469
470 /* Fill a table descriptor for validation */
471
472 status = acpi_tb_acquire_temporal_table(&new_table_desc, address,
Lv Zheng8a216d72014-04-04 12:39:04 +0800473 ACPI_TABLE_ORIGIN_INTERN_PHYSICAL);
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800474 if (ACPI_FAILURE(status)) {
475 ACPI_ERROR((AE_INFO, "Could not acquire table length at %p",
476 ACPI_CAST_PTR(void, address)));
477 return_ACPI_STATUS(status);
478 }
479
480 /* Validate and verify a table before installation */
481
482 status = acpi_tb_verify_table(&new_table_desc, signature);
483 if (ACPI_FAILURE(status)) {
484 goto release_and_exit;
485 }
486
487 acpi_tb_install_and_override_table(table_index, &new_table_desc);
488
489release_and_exit:
490
491 /* Release the temporal table descriptor */
492
493 acpi_tb_release_temporal_table(&new_table_desc);
494 return_ACPI_STATUS(status);
495}
496
497/*******************************************************************************
498 *
499 * FUNCTION: acpi_tb_is_equivalent_table
500 *
501 * PARAMETERS: table_desc - Table 1 descriptor to be compared
502 * table_index - Index of table 2 to be compared
503 *
504 * RETURN: TRUE if 2 tables are equivalent
505 *
506 * DESCRIPTION: This function is called to compare a table with what have
507 * already been installed in the root table list.
508 *
509 ******************************************************************************/
510
511static u8
512acpi_tb_is_equivalent_table(struct acpi_table_desc *table_desc, u32 table_index)
513{
514 acpi_status status = AE_OK;
515 u8 is_equivalent;
516 struct acpi_table_header *table;
517 u32 table_length;
518 u8 table_flags;
519
520 status =
521 acpi_tb_acquire_table(&acpi_gbl_root_table_list.tables[table_index],
522 &table, &table_length, &table_flags);
523 if (ACPI_FAILURE(status)) {
524 return (FALSE);
525 }
526
527 /*
528 * Check for a table match on the entire table length,
529 * not just the header.
530 */
531 is_equivalent = (u8)((table_desc->length != table_length ||
532 ACPI_MEMCMP(table_desc->pointer, table,
533 table_length)) ? FALSE : TRUE);
534
535 /* Release the acquired table */
536
537 acpi_tb_release_table(table, table_length, table_flags);
538
539 return (is_equivalent);
540}
541
542/*******************************************************************************
543 *
544 * FUNCTION: acpi_tb_install_non_fixed_table
545 *
Lv Zheng8a216d72014-04-04 12:39:04 +0800546 * PARAMETERS: address - Address of the table (might be a virtual
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800547 * address depending on the table_flags)
548 * flags - Flags for the table
549 * reload - Whether reload should be performed
550 * table_index - Where the table index is returned
551 *
552 * RETURN: Status
553 *
554 * DESCRIPTION: This function is called to install an ACPI table that is
555 * neither DSDT nor FACS.
556 * When this function is called by "Load" or "LoadTable" opcodes,
557 * or by acpi_load_table() API, the "Reload" parameter is set.
558 * After sucessfully returning from this function, table is
559 * "INSTALLED" but not "VALIDATED".
560 *
561 ******************************************************************************/
562
563acpi_status
564acpi_tb_install_non_fixed_table(acpi_physical_address address,
565 u8 flags, u8 reload, u32 *table_index)
566{
567 u32 i;
568 acpi_status status = AE_OK;
569 struct acpi_table_desc new_table_desc;
570
571 ACPI_FUNCTION_TRACE(tb_install_non_fixed_table);
572
573 /* Acquire a temporal table descriptor for validation */
574
575 status =
576 acpi_tb_acquire_temporal_table(&new_table_desc, address, flags);
577 if (ACPI_FAILURE(status)) {
578 ACPI_ERROR((AE_INFO, "Could not acquire table length at %p",
579 ACPI_CAST_PTR(void, address)));
580 return_ACPI_STATUS(status);
581 }
582
Lv Zhenga94e88c2014-04-04 12:39:11 +0800583 /*
584 * Optionally do not load any SSDTs from the RSDT/XSDT. This can
585 * be useful for debugging ACPI problems on some machines.
586 */
587 if (!reload && acpi_gbl_disable_ssdt_table_install &&
588 ACPI_COMPARE_NAME(&new_table_desc.signature, ACPI_SIG_SSDT)) {
589 ACPI_INFO((AE_INFO, "Ignoring installation of %4.4s at %p",
590 new_table_desc.signature.ascii, ACPI_CAST_PTR(void,
591 address)));
592 goto release_and_exit;
593 }
594
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800595 /* Validate and verify a table before installation */
596
597 status = acpi_tb_verify_table(&new_table_desc, NULL);
598 if (ACPI_FAILURE(status)) {
599 goto release_and_exit;
600 }
601
602 if (reload) {
603 /*
604 * Validate the incoming table signature.
605 *
606 * 1) Originally, we checked the table signature for "SSDT" or "PSDT".
607 * 2) We added support for OEMx tables, signature "OEM".
608 * 3) Valid tables were encountered with a null signature, so we just
609 * gave up on validating the signature, (05/2008).
610 * 4) We encountered non-AML tables such as the MADT, which caused
611 * interpreter errors and kernel faults. So now, we once again allow
612 * only "SSDT", "OEMx", and now, also a null signature. (05/2011).
613 */
614 if ((new_table_desc.signature.ascii[0] != 0x00) &&
615 (!ACPI_COMPARE_NAME
616 (&new_table_desc.signature, ACPI_SIG_SSDT))
617 && (ACPI_STRNCMP(new_table_desc.signature.ascii, "OEM", 3)))
618 {
619 ACPI_BIOS_ERROR((AE_INFO,
620 "Table has invalid signature [%4.4s] (0x%8.8X), "
621 "must be SSDT or OEMx",
622 acpi_ut_valid_acpi_name(new_table_desc.
623 signature.
624 ascii) ?
625 new_table_desc.signature.
626 ascii : "????",
627 new_table_desc.signature.integer));
628
629 status = AE_BAD_SIGNATURE;
630 goto release_and_exit;
631 }
632
633 /* Check if table is already registered */
634
635 for (i = 0; i < acpi_gbl_root_table_list.current_table_count;
636 ++i) {
637 /*
638 * Check for a table match on the entire table length,
639 * not just the header.
640 */
641 if (!acpi_tb_is_equivalent_table(&new_table_desc, i)) {
642 continue;
643 }
644
645 /*
646 * Note: the current mechanism does not unregister a table if it is
647 * dynamically unloaded. The related namespace entries are deleted,
648 * but the table remains in the root table list.
649 *
650 * The assumption here is that the number of different tables that
651 * will be loaded is actually small, and there is minimal overhead
652 * in just keeping the table in case it is needed again.
653 *
654 * If this assumption changes in the future (perhaps on large
655 * machines with many table load/unload operations), tables will
656 * need to be unregistered when they are unloaded, and slots in the
657 * root table list should be reused when empty.
658 */
659 if (acpi_gbl_root_table_list.tables[i].
660 flags & ACPI_TABLE_IS_LOADED) {
661
662 /* Table is still loaded, this is an error */
663
664 status = AE_ALREADY_EXISTS;
665 goto release_and_exit;
666 } else {
667 /*
668 * Table was unloaded, allow it to be reloaded.
669 * As we are going to return AE_OK to the caller, we should
670 * take the responsibility of freeing the input descriptor.
671 * Refill the input descriptor to ensure
672 * acpi_tb_install_and_override_table() can be called again to
673 * indicate the re-installation.
674 */
675 acpi_tb_uninstall_table(&new_table_desc);
676 *table_index = i;
677 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
678 return_ACPI_STATUS(AE_OK);
679 }
680 }
Lv Zheng7f9fc992014-04-04 12:38:42 +0800681 }
Bob Moored3ccaff2009-02-03 14:43:04 +0800682
Bob Mooree56f5612008-07-04 10:48:43 +0800683 /* Add the table to the global root table list */
684
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800685 status = acpi_tb_acquire_root_table_entry(&i);
Len Brown4be44fc2005-08-05 00:44:28 -0400686 if (ACPI_FAILURE(status)) {
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800687 goto release_and_exit;
Robert Moore0c9938c2005-07-29 15:15:00 -0700688 }
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800689 *table_index = i;
690 acpi_tb_install_and_override_table(i, &new_table_desc);
Robert Moore0c9938c2005-07-29 15:15:00 -0700691
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800692release_and_exit:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700693
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800694 /* Release the temporal table descriptor */
695
696 acpi_tb_release_temporal_table(&new_table_desc);
Len Brown4be44fc2005-08-05 00:44:28 -0400697 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700698}
699
Linus Torvalds1da177e2005-04-16 15:20:36 -0700700/*******************************************************************************
701 *
Lv Zheng7f9fc992014-04-04 12:38:42 +0800702 * FUNCTION: acpi_tb_override_table
Bob Mooref7b004a2012-02-14 18:31:56 +0800703 *
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800704 * PARAMETERS: old_table_desc - Validated table descriptor to be
705 * overridden
Bob Mooref7b004a2012-02-14 18:31:56 +0800706 *
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800707 * RETURN: None
Bob Mooref7b004a2012-02-14 18:31:56 +0800708 *
709 * DESCRIPTION: Attempt table override by calling the OSL override functions.
710 * Note: If the table is overridden, then the entire new table
Lv Zheng7f9fc992014-04-04 12:38:42 +0800711 * is acquired and returned by this function.
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800712 * Before/after invocation, the table descriptor is in a state
713 * that is "VALIDATED".
Bob Mooref7b004a2012-02-14 18:31:56 +0800714 *
715 ******************************************************************************/
716
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800717void acpi_tb_override_table(struct acpi_table_desc *old_table_desc)
Bob Mooref7b004a2012-02-14 18:31:56 +0800718{
719 acpi_status status;
Bob Mooref7b004a2012-02-14 18:31:56 +0800720 char *override_type;
Lv Zheng7f9fc992014-04-04 12:38:42 +0800721 struct acpi_table_desc new_table_desc;
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800722 struct acpi_table_header *table;
723 acpi_physical_address address;
724 u32 length;
Bob Mooref7b004a2012-02-14 18:31:56 +0800725
726 /* (1) Attempt logical override (returns a logical address) */
727
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800728 status = acpi_os_table_override(old_table_desc->pointer, &table);
729 if (ACPI_SUCCESS(status) && table) {
730 acpi_tb_acquire_temporal_table(&new_table_desc,
731 ACPI_PTR_TO_PHYSADDR(table),
Lv Zheng8a216d72014-04-04 12:39:04 +0800732 ACPI_TABLE_ORIGIN_EXTERN_VIRTUAL);
Bob Mooref7b004a2012-02-14 18:31:56 +0800733 override_type = "Logical";
734 goto finish_override;
735 }
736
737 /* (2) Attempt physical override (returns a physical address) */
738
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800739 status = acpi_os_physical_table_override(old_table_desc->pointer,
740 &address, &length);
741 if (ACPI_SUCCESS(status) && address && length) {
742 acpi_tb_acquire_temporal_table(&new_table_desc, address,
Lv Zheng8a216d72014-04-04 12:39:04 +0800743 ACPI_TABLE_ORIGIN_INTERN_PHYSICAL);
Bob Mooref7b004a2012-02-14 18:31:56 +0800744 override_type = "Physical";
Bob Mooref7b004a2012-02-14 18:31:56 +0800745 goto finish_override;
746 }
747
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800748 return; /* There was no override */
Bob Mooref7b004a2012-02-14 18:31:56 +0800749
Lv Zheng10622bf2013-10-29 09:30:02 +0800750finish_override:
Bob Mooref7b004a2012-02-14 18:31:56 +0800751
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800752 /* Validate and verify a table before overriding */
753
754 status = acpi_tb_verify_table(&new_table_desc, NULL);
Lv Zheng7f9fc992014-04-04 12:38:42 +0800755 if (ACPI_FAILURE(status)) {
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800756 return;
Lv Zheng7f9fc992014-04-04 12:38:42 +0800757 }
758
Bob Moore2e19f8d2014-02-08 09:42:07 +0800759 ACPI_INFO((AE_INFO, "%4.4s " ACPI_PRINTF_UINT
760 " %s table override, new table: " ACPI_PRINTF_UINT,
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800761 old_table_desc->signature.ascii,
762 ACPI_FORMAT_TO_UINT(old_table_desc->address),
Lv Zheng7f9fc992014-04-04 12:38:42 +0800763 override_type, ACPI_FORMAT_TO_UINT(new_table_desc.address)));
Bob Mooref7b004a2012-02-14 18:31:56 +0800764
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800765 /* We can now uninstall the original table */
Bob Mooref7b004a2012-02-14 18:31:56 +0800766
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800767 acpi_tb_uninstall_table(old_table_desc);
Bob Mooref7b004a2012-02-14 18:31:56 +0800768
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800769 /*
770 * Replace the original table descriptor and keep its state as
771 * "VALIDATED".
772 */
773 acpi_tb_install_table(old_table_desc, new_table_desc.address,
774 new_table_desc.flags, new_table_desc.pointer);
775 acpi_tb_validate_table(old_table_desc);
Bob Mooref7b004a2012-02-14 18:31:56 +0800776
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800777 /* Release the temporal table descriptor */
Bob Mooref7b004a2012-02-14 18:31:56 +0800778
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800779 acpi_tb_release_temporal_table(&new_table_desc);
Bob Mooref7b004a2012-02-14 18:31:56 +0800780}
781
782/*******************************************************************************
783 *
Bob Mooref3d2e782007-02-02 19:48:18 +0300784 * FUNCTION: acpi_tb_resize_root_table_list
Linus Torvalds1da177e2005-04-16 15:20:36 -0700785 *
Bob Mooref3d2e782007-02-02 19:48:18 +0300786 * PARAMETERS: None
Linus Torvalds1da177e2005-04-16 15:20:36 -0700787 *
788 * RETURN: Status
789 *
Bob Mooref3d2e782007-02-02 19:48:18 +0300790 * DESCRIPTION: Expand the size of global table array
Linus Torvalds1da177e2005-04-16 15:20:36 -0700791 *
792 ******************************************************************************/
793
Bob Mooref3d2e782007-02-02 19:48:18 +0300794acpi_status acpi_tb_resize_root_table_list(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700795{
Bob Mooref3d2e782007-02-02 19:48:18 +0300796 struct acpi_table_desc *tables;
Lv Zheng2bc198c2012-09-13 09:29:06 -0700797 u32 table_count;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700798
Bob Mooref3d2e782007-02-02 19:48:18 +0300799 ACPI_FUNCTION_TRACE(tb_resize_root_table_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700800
Bob Mooref3d2e782007-02-02 19:48:18 +0300801 /* allow_resize flag is a parameter to acpi_initialize_tables */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700802
Bob Moorec5fc42a2007-02-02 19:48:19 +0300803 if (!(acpi_gbl_root_table_list.flags & ACPI_ROOT_ALLOW_RESIZE)) {
Bob Mooref3d2e782007-02-02 19:48:18 +0300804 ACPI_ERROR((AE_INFO,
805 "Resize of Root Table Array is not allowed"));
806 return_ACPI_STATUS(AE_SUPPORT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700807 }
808
Bob Mooref3d2e782007-02-02 19:48:18 +0300809 /* Increase the Table Array size */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700810
Lv Zheng2bc198c2012-09-13 09:29:06 -0700811 if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) {
812 table_count = acpi_gbl_root_table_list.max_table_count;
813 } else {
814 table_count = acpi_gbl_root_table_list.current_table_count;
815 }
816
817 tables = ACPI_ALLOCATE_ZEROED(((acpi_size) table_count +
Bob Mooreec41f192009-02-18 15:03:30 +0800818 ACPI_ROOT_TABLE_SIZE_INCREMENT) *
819 sizeof(struct acpi_table_desc));
Bob Mooref3d2e782007-02-02 19:48:18 +0300820 if (!tables) {
821 ACPI_ERROR((AE_INFO,
822 "Could not allocate new root table array"));
Len Brown4be44fc2005-08-05 00:44:28 -0400823 return_ACPI_STATUS(AE_NO_MEMORY);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700824 }
825
Bob Mooref3d2e782007-02-02 19:48:18 +0300826 /* Copy and free the previous table array */
Robert Mooref9f46012005-07-08 00:00:00 -0400827
Bob Mooref3d2e782007-02-02 19:48:18 +0300828 if (acpi_gbl_root_table_list.tables) {
829 ACPI_MEMCPY(tables, acpi_gbl_root_table_list.tables,
Lv Zheng2bc198c2012-09-13 09:29:06 -0700830 (acpi_size) table_count *
831 sizeof(struct acpi_table_desc));
Robert Mooref9f46012005-07-08 00:00:00 -0400832
Bob Moorec5fc42a2007-02-02 19:48:19 +0300833 if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) {
Bob Mooref3d2e782007-02-02 19:48:18 +0300834 ACPI_FREE(acpi_gbl_root_table_list.tables);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700835 }
836 }
837
Bob Mooref3d2e782007-02-02 19:48:18 +0300838 acpi_gbl_root_table_list.tables = tables;
Lv Zheng2bc198c2012-09-13 09:29:06 -0700839 acpi_gbl_root_table_list.max_table_count =
840 table_count + ACPI_ROOT_TABLE_SIZE_INCREMENT;
841 acpi_gbl_root_table_list.flags |= ACPI_ROOT_ORIGIN_ALLOCATED;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700842
Len Brown4be44fc2005-08-05 00:44:28 -0400843 return_ACPI_STATUS(AE_OK);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700844}
845
Linus Torvalds1da177e2005-04-16 15:20:36 -0700846/*******************************************************************************
847 *
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800848 * FUNCTION: acpi_tb_acquire_root_table_entry
849 *
850 * PARAMETERS: table_index - Where table index is returned
851 *
852 * RETURN: Status and table index.
853 *
854 * DESCRIPTION: Allocate a new ACPI table entry to the global table list
855 *
856 ******************************************************************************/
857
858static acpi_status acpi_tb_acquire_root_table_entry(u32 *table_index)
859{
860 acpi_status status;
861
862 /* Ensure that there is room for the table in the Root Table List */
863
864 if (acpi_gbl_root_table_list.current_table_count >=
865 acpi_gbl_root_table_list.max_table_count) {
866 status = acpi_tb_resize_root_table_list();
867 if (ACPI_FAILURE(status)) {
868 return (status);
869 }
870 }
871
872 *table_index = acpi_gbl_root_table_list.current_table_count;
873 acpi_gbl_root_table_list.current_table_count++;
874 return (AE_OK);
875}
876
877/*******************************************************************************
878 *
Bob Mooref3d2e782007-02-02 19:48:18 +0300879 * FUNCTION: acpi_tb_store_table
Linus Torvalds1da177e2005-04-16 15:20:36 -0700880 *
Bob Mooreba494be2012-07-12 09:40:10 +0800881 * PARAMETERS: address - Table address
882 * table - Table header
883 * length - Table length
884 * flags - flags
Linus Torvalds1da177e2005-04-16 15:20:36 -0700885 *
Bob Mooref3d2e782007-02-02 19:48:18 +0300886 * RETURN: Status and table index.
887 *
888 * DESCRIPTION: Add an ACPI table to the global table list
889 *
890 ******************************************************************************/
891
892acpi_status
893acpi_tb_store_table(acpi_physical_address address,
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800894 struct acpi_table_header * table,
Bob Moore67a119f2008-06-10 13:42:13 +0800895 u32 length, u8 flags, u32 *table_index)
Bob Mooref3d2e782007-02-02 19:48:18 +0300896{
Bob Mooreb9ee2042010-04-27 11:16:14 +0800897 acpi_status status;
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800898 struct acpi_table_desc *table_desc;
Bob Mooref3d2e782007-02-02 19:48:18 +0300899
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800900 status = acpi_tb_acquire_root_table_entry(table_index);
901 if (ACPI_FAILURE(status)) {
902 return (status);
Bob Mooref3d2e782007-02-02 19:48:18 +0300903 }
904
905 /* Initialize added table */
906
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800907 table_desc = &acpi_gbl_root_table_list.tables[*table_index];
908 acpi_tb_install_table(table_desc, address, flags, table);
909 table_desc->pointer = table;
Bob Mooref3d2e782007-02-02 19:48:18 +0300910
Bob Mooreb9ee2042010-04-27 11:16:14 +0800911 return (AE_OK);
Bob Mooref3d2e782007-02-02 19:48:18 +0300912}
913
914/*******************************************************************************
915 *
Lv Zheng7f9fc992014-04-04 12:38:42 +0800916 * FUNCTION: acpi_tb_uninstall_table
Bob Mooref3d2e782007-02-02 19:48:18 +0300917 *
Lv Zheng7f9fc992014-04-04 12:38:42 +0800918 * PARAMETERS: table_desc - Table descriptor
Bob Mooref3d2e782007-02-02 19:48:18 +0300919 *
920 * RETURN: None
921 *
922 * DESCRIPTION: Delete one internal ACPI table
923 *
924 ******************************************************************************/
925
Lv Zheng7f9fc992014-04-04 12:38:42 +0800926void acpi_tb_uninstall_table(struct acpi_table_desc *table_desc)
Bob Mooref3d2e782007-02-02 19:48:18 +0300927{
Lv Zheng55829822014-04-04 12:38:18 +0800928
Lv Zheng7f9fc992014-04-04 12:38:42 +0800929 ACPI_FUNCTION_TRACE(tb_uninstall_table);
Lv Zheng55829822014-04-04 12:38:18 +0800930
Lv Zheng7f9fc992014-04-04 12:38:42 +0800931 /* Table must be installed */
932
933 if (!table_desc->address) {
934 return_VOID;
Bob Mooref3d2e782007-02-02 19:48:18 +0300935 }
Lv Zheng55829822014-04-04 12:38:18 +0800936
Lv Zheng7f9fc992014-04-04 12:38:42 +0800937 acpi_tb_invalidate_table(table_desc);
Chao Guan1d1ea1b2013-06-08 00:58:14 +0000938
Lv Zheng7f9fc992014-04-04 12:38:42 +0800939 if ((table_desc->flags & ACPI_TABLE_ORIGIN_MASK) ==
Lv Zheng8a216d72014-04-04 12:39:04 +0800940 ACPI_TABLE_ORIGIN_INTERN_VIRTUAL) {
Lv Zheng7f9fc992014-04-04 12:38:42 +0800941 ACPI_FREE(ACPI_CAST_PTR(void, table_desc->address));
Bob Mooref3d2e782007-02-02 19:48:18 +0300942 }
943
Lv Zheng7f9fc992014-04-04 12:38:42 +0800944 table_desc->address = ACPI_PTR_TO_PHYSADDR(NULL);
945
946 return_VOID;
Bob Mooref3d2e782007-02-02 19:48:18 +0300947}
948
949/*******************************************************************************
950 *
951 * FUNCTION: acpi_tb_terminate
952 *
953 * PARAMETERS: None
954 *
955 * RETURN: None
Linus Torvalds1da177e2005-04-16 15:20:36 -0700956 *
957 * DESCRIPTION: Delete all internal ACPI tables
958 *
959 ******************************************************************************/
960
Bob Mooref3d2e782007-02-02 19:48:18 +0300961void acpi_tb_terminate(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700962{
Bob Moore67a119f2008-06-10 13:42:13 +0800963 u32 i;
Bob Mooref3d2e782007-02-02 19:48:18 +0300964
965 ACPI_FUNCTION_TRACE(tb_terminate);
966
967 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
968
969 /* Delete the individual tables */
970
Bob Mooreb9ee2042010-04-27 11:16:14 +0800971 for (i = 0; i < acpi_gbl_root_table_list.current_table_count; i++) {
Lv Zheng7f9fc992014-04-04 12:38:42 +0800972 acpi_tb_uninstall_table(&acpi_gbl_root_table_list.tables[i]);
Bob Mooref3d2e782007-02-02 19:48:18 +0300973 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700974
975 /*
Bob Mooref3d2e782007-02-02 19:48:18 +0300976 * Delete the root table array if allocated locally. Array cannot be
977 * mapped, so we don't need to check for that flag.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700978 */
Bob Moorec5fc42a2007-02-02 19:48:19 +0300979 if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) {
Bob Mooref3d2e782007-02-02 19:48:18 +0300980 ACPI_FREE(acpi_gbl_root_table_list.tables);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700981 }
Bob Mooref3d2e782007-02-02 19:48:18 +0300982
983 acpi_gbl_root_table_list.tables = NULL;
984 acpi_gbl_root_table_list.flags = 0;
Bob Mooreb9ee2042010-04-27 11:16:14 +0800985 acpi_gbl_root_table_list.current_table_count = 0;
Bob Mooref3d2e782007-02-02 19:48:18 +0300986
987 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "ACPI Tables freed\n"));
988 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
Bob Moore68aafc32012-10-31 02:26:01 +0000989
990 return_VOID;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700991}
992
Linus Torvalds1da177e2005-04-16 15:20:36 -0700993/*******************************************************************************
994 *
Bob Mooref3d2e782007-02-02 19:48:18 +0300995 * FUNCTION: acpi_tb_delete_namespace_by_owner
Linus Torvalds1da177e2005-04-16 15:20:36 -0700996 *
Bob Mooref3d2e782007-02-02 19:48:18 +0300997 * PARAMETERS: table_index - Table index
Linus Torvalds1da177e2005-04-16 15:20:36 -0700998 *
Bob Moore8a335a232009-03-09 16:31:04 +0800999 * RETURN: Status
Linus Torvalds1da177e2005-04-16 15:20:36 -07001000 *
Bob Mooref3d2e782007-02-02 19:48:18 +03001001 * DESCRIPTION: Delete all namespace objects created when this table was loaded.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001002 *
1003 ******************************************************************************/
1004
Bob Moore8a335a232009-03-09 16:31:04 +08001005acpi_status acpi_tb_delete_namespace_by_owner(u32 table_index)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001006{
Bob Mooref3d2e782007-02-02 19:48:18 +03001007 acpi_owner_id owner_id;
Bob Moore8a335a232009-03-09 16:31:04 +08001008 acpi_status status;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001009
Bob Moore8a335a232009-03-09 16:31:04 +08001010 ACPI_FUNCTION_TRACE(tb_delete_namespace_by_owner);
1011
1012 status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
1013 if (ACPI_FAILURE(status)) {
1014 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001015 }
1016
Bob Mooreb9ee2042010-04-27 11:16:14 +08001017 if (table_index >= acpi_gbl_root_table_list.current_table_count) {
Bob Moore8a335a232009-03-09 16:31:04 +08001018
1019 /* The table index does not exist */
1020
1021 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
1022 return_ACPI_STATUS(AE_NOT_EXIST);
1023 }
1024
1025 /* Get the owner ID for this table, used to delete namespace nodes */
1026
1027 owner_id = acpi_gbl_root_table_list.tables[table_index].owner_id;
Len Brown4be44fc2005-08-05 00:44:28 -04001028 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
Bob Moore8a335a232009-03-09 16:31:04 +08001029
1030 /*
1031 * Need to acquire the namespace writer lock to prevent interference
1032 * with any concurrent namespace walks. The interpreter must be
1033 * released during the deletion since the acquisition of the deletion
1034 * lock may block, and also since the execution of a namespace walk
1035 * must be allowed to use the interpreter.
1036 */
Bob Mooree4c1ebf2009-04-22 13:02:06 +08001037 (void)acpi_ut_release_mutex(ACPI_MTX_INTERPRETER);
Bob Moore8a335a232009-03-09 16:31:04 +08001038 status = acpi_ut_acquire_write_lock(&acpi_gbl_namespace_rw_lock);
1039
Bob Mooref3d2e782007-02-02 19:48:18 +03001040 acpi_ns_delete_namespace_by_owner(owner_id);
Bob Moore8a335a232009-03-09 16:31:04 +08001041 if (ACPI_FAILURE(status)) {
1042 return_ACPI_STATUS(status);
1043 }
1044
1045 acpi_ut_release_write_lock(&acpi_gbl_namespace_rw_lock);
1046
1047 status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER);
1048 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001049}
1050
Linus Torvalds1da177e2005-04-16 15:20:36 -07001051/*******************************************************************************
1052 *
Bob Mooref3d2e782007-02-02 19:48:18 +03001053 * FUNCTION: acpi_tb_allocate_owner_id
Linus Torvalds1da177e2005-04-16 15:20:36 -07001054 *
Bob Mooref3d2e782007-02-02 19:48:18 +03001055 * PARAMETERS: table_index - Table index
Linus Torvalds1da177e2005-04-16 15:20:36 -07001056 *
Bob Mooref3d2e782007-02-02 19:48:18 +03001057 * RETURN: Status
Linus Torvalds1da177e2005-04-16 15:20:36 -07001058 *
Bob Mooref3d2e782007-02-02 19:48:18 +03001059 * DESCRIPTION: Allocates owner_id in table_desc
Linus Torvalds1da177e2005-04-16 15:20:36 -07001060 *
1061 ******************************************************************************/
1062
Bob Moore67a119f2008-06-10 13:42:13 +08001063acpi_status acpi_tb_allocate_owner_id(u32 table_index)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001064{
Bob Mooref3d2e782007-02-02 19:48:18 +03001065 acpi_status status = AE_BAD_PARAMETER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001066
Bob Mooref3d2e782007-02-02 19:48:18 +03001067 ACPI_FUNCTION_TRACE(tb_allocate_owner_id);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001068
Bob Mooref3d2e782007-02-02 19:48:18 +03001069 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
Bob Mooreb9ee2042010-04-27 11:16:14 +08001070 if (table_index < acpi_gbl_root_table_list.current_table_count) {
Bob Mooref3d2e782007-02-02 19:48:18 +03001071 status = acpi_ut_allocate_owner_id
1072 (&(acpi_gbl_root_table_list.tables[table_index].owner_id));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001073 }
1074
Bob Mooref3d2e782007-02-02 19:48:18 +03001075 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
1076 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001077}
1078
Linus Torvalds1da177e2005-04-16 15:20:36 -07001079/*******************************************************************************
1080 *
Bob Mooref3d2e782007-02-02 19:48:18 +03001081 * FUNCTION: acpi_tb_release_owner_id
Linus Torvalds1da177e2005-04-16 15:20:36 -07001082 *
Bob Mooref3d2e782007-02-02 19:48:18 +03001083 * PARAMETERS: table_index - Table index
Linus Torvalds1da177e2005-04-16 15:20:36 -07001084 *
Bob Mooref3d2e782007-02-02 19:48:18 +03001085 * RETURN: Status
Linus Torvalds1da177e2005-04-16 15:20:36 -07001086 *
Bob Mooref3d2e782007-02-02 19:48:18 +03001087 * DESCRIPTION: Releases owner_id in table_desc
Linus Torvalds1da177e2005-04-16 15:20:36 -07001088 *
1089 ******************************************************************************/
1090
Bob Moore67a119f2008-06-10 13:42:13 +08001091acpi_status acpi_tb_release_owner_id(u32 table_index)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001092{
Bob Mooref3d2e782007-02-02 19:48:18 +03001093 acpi_status status = AE_BAD_PARAMETER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001094
Bob Mooref3d2e782007-02-02 19:48:18 +03001095 ACPI_FUNCTION_TRACE(tb_release_owner_id);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001096
Bob Mooref3d2e782007-02-02 19:48:18 +03001097 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
Bob Mooreb9ee2042010-04-27 11:16:14 +08001098 if (table_index < acpi_gbl_root_table_list.current_table_count) {
Bob Mooref3d2e782007-02-02 19:48:18 +03001099 acpi_ut_release_owner_id(&
1100 (acpi_gbl_root_table_list.
1101 tables[table_index].owner_id));
1102 status = AE_OK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001103 }
1104
Bob Mooref3d2e782007-02-02 19:48:18 +03001105 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
1106 return_ACPI_STATUS(status);
1107}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001108
Bob Mooref3d2e782007-02-02 19:48:18 +03001109/*******************************************************************************
1110 *
1111 * FUNCTION: acpi_tb_get_owner_id
1112 *
1113 * PARAMETERS: table_index - Table index
1114 * owner_id - Where the table owner_id is returned
1115 *
1116 * RETURN: Status
1117 *
1118 * DESCRIPTION: returns owner_id for the ACPI table
1119 *
1120 ******************************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001121
Lv Zheng55829822014-04-04 12:38:18 +08001122acpi_status acpi_tb_get_owner_id(u32 table_index, acpi_owner_id * owner_id)
Bob Mooref3d2e782007-02-02 19:48:18 +03001123{
1124 acpi_status status = AE_BAD_PARAMETER;
1125
1126 ACPI_FUNCTION_TRACE(tb_get_owner_id);
1127
1128 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
Bob Mooreb9ee2042010-04-27 11:16:14 +08001129 if (table_index < acpi_gbl_root_table_list.current_table_count) {
Bob Mooref3d2e782007-02-02 19:48:18 +03001130 *owner_id =
1131 acpi_gbl_root_table_list.tables[table_index].owner_id;
1132 status = AE_OK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001133 }
1134
Bob Mooref3d2e782007-02-02 19:48:18 +03001135 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
1136 return_ACPI_STATUS(status);
1137}
1138
1139/*******************************************************************************
1140 *
1141 * FUNCTION: acpi_tb_is_table_loaded
1142 *
1143 * PARAMETERS: table_index - Table index
1144 *
1145 * RETURN: Table Loaded Flag
1146 *
1147 ******************************************************************************/
1148
Bob Moore67a119f2008-06-10 13:42:13 +08001149u8 acpi_tb_is_table_loaded(u32 table_index)
Bob Mooref3d2e782007-02-02 19:48:18 +03001150{
1151 u8 is_loaded = FALSE;
1152
1153 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
Bob Mooreb9ee2042010-04-27 11:16:14 +08001154 if (table_index < acpi_gbl_root_table_list.current_table_count) {
Bob Mooref3d2e782007-02-02 19:48:18 +03001155 is_loaded = (u8)
Bob Mooreec41f192009-02-18 15:03:30 +08001156 (acpi_gbl_root_table_list.tables[table_index].flags &
1157 ACPI_TABLE_IS_LOADED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001158 }
1159
Bob Mooref3d2e782007-02-02 19:48:18 +03001160 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
1161 return (is_loaded);
1162}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001163
Bob Mooref3d2e782007-02-02 19:48:18 +03001164/*******************************************************************************
1165 *
1166 * FUNCTION: acpi_tb_set_table_loaded_flag
1167 *
1168 * PARAMETERS: table_index - Table index
1169 * is_loaded - TRUE if table is loaded, FALSE otherwise
1170 *
1171 * RETURN: None
1172 *
1173 * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE.
1174 *
1175 ******************************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001176
Bob Moore67a119f2008-06-10 13:42:13 +08001177void acpi_tb_set_table_loaded_flag(u32 table_index, u8 is_loaded)
Bob Mooref3d2e782007-02-02 19:48:18 +03001178{
Bob Mooref6dd9222006-07-07 20:44:38 -04001179
Bob Mooref3d2e782007-02-02 19:48:18 +03001180 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
Bob Mooreb9ee2042010-04-27 11:16:14 +08001181 if (table_index < acpi_gbl_root_table_list.current_table_count) {
Bob Mooref3d2e782007-02-02 19:48:18 +03001182 if (is_loaded) {
1183 acpi_gbl_root_table_list.tables[table_index].flags |=
Bob Moorec5fc42a2007-02-02 19:48:19 +03001184 ACPI_TABLE_IS_LOADED;
Bob Mooref3d2e782007-02-02 19:48:18 +03001185 } else {
1186 acpi_gbl_root_table_list.tables[table_index].flags &=
Bob Moorec5fc42a2007-02-02 19:48:19 +03001187 ~ACPI_TABLE_IS_LOADED;
Bob Mooref3d2e782007-02-02 19:48:18 +03001188 }
1189 }
Bob Mooref6dd9222006-07-07 20:44:38 -04001190
Bob Mooref3d2e782007-02-02 19:48:18 +03001191 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001192}