blob: 099e678edcb26013c64401ba1f0945daf2e74e17 [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) {
89 case ACPI_TABLE_ORIGIN_MAPPED:
90
91 table =
92 acpi_os_map_memory(table_desc->address, table_desc->length);
93 break;
94
95 case ACPI_TABLE_ORIGIN_ALLOCATED:
96 case ACPI_TABLE_ORIGIN_UNKNOWN:
97 case ACPI_TABLE_ORIGIN_OVERRIDE:
98
99 table =
100 ACPI_CAST_PTR(struct acpi_table_header,
101 table_desc->address);
102 break;
103
104 default:
105
106 break;
107 }
108
109 /* Table is not valid yet */
110
111 if (!table) {
112 return (AE_NO_MEMORY);
113 }
114
115 /* Fill the return values */
116
117 *table_ptr = table;
118 *table_length = table_desc->length;
119 *table_flags = table_desc->flags;
120
121 return (AE_OK);
122}
123
124/*******************************************************************************
125 *
126 * FUNCTION: acpi_tb_release_table
127 *
128 * PARAMETERS: table - Pointer for the table
129 * table_length - Length for the table
130 * table_flags - Allocation flags for the table
131 *
132 * RETURN: None
133 *
134 * DESCRIPTION: Release a table. The reversal of acpi_tb_acquire_table().
135 *
136 ******************************************************************************/
137
138void
139acpi_tb_release_table(struct acpi_table_header *table,
140 u32 table_length, u8 table_flags)
141{
142 switch (table_flags & ACPI_TABLE_ORIGIN_MASK) {
143 case ACPI_TABLE_ORIGIN_MAPPED:
144
145 acpi_os_unmap_memory(table, table_length);
146 break;
147
148 case ACPI_TABLE_ORIGIN_ALLOCATED:
149 case ACPI_TABLE_ORIGIN_UNKNOWN:
150 case ACPI_TABLE_ORIGIN_OVERRIDE:
151 default:
152
153 break;
154 }
155}
156
157/******************************************************************************
158 *
159 * FUNCTION: acpi_tb_validate_table
160 *
161 * PARAMETERS: table_desc - Table descriptor
162 *
163 * RETURN: Status
164 *
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800165 * DESCRIPTION: This function is called to validate the table, the returned
166 * table descriptor is in "VALIDATED" state.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700167 *
Bob Mooref3d2e782007-02-02 19:48:18 +0300168 *****************************************************************************/
Lv Zheng7f9fc992014-04-04 12:38:42 +0800169
170acpi_status acpi_tb_validate_table(struct acpi_table_desc *table_desc)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700171{
Alexey Starikovskiy428f2112007-02-02 19:48:22 +0300172 acpi_status status = AE_OK;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700173
Lv Zheng7f9fc992014-04-04 12:38:42 +0800174 ACPI_FUNCTION_TRACE(tb_validate_table);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700175
Lv Zheng7f9fc992014-04-04 12:38:42 +0800176 /* Validate the table if necessary */
Robert Moore44f6c012005-04-18 22:49:35 -0400177
Bob Mooref3d2e782007-02-02 19:48:18 +0300178 if (!table_desc->pointer) {
Lv Zheng7f9fc992014-04-04 12:38:42 +0800179 status = acpi_tb_acquire_table(table_desc, &table_desc->pointer,
180 &table_desc->length,
181 &table_desc->flags);
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800182 if (!table_desc->pointer) {
183 status = AE_NO_MEMORY;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700184 }
185 }
186
Bob Moorec5fc42a2007-02-02 19:48:19 +0300187 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700188}
189
Linus Torvalds1da177e2005-04-16 15:20:36 -0700190/*******************************************************************************
191 *
Lv Zheng7f9fc992014-04-04 12:38:42 +0800192 * FUNCTION: acpi_tb_invalidate_table
193 *
194 * PARAMETERS: table_desc - Table descriptor
195 *
196 * RETURN: None
197 *
198 * DESCRIPTION: Invalidate one internal ACPI table, this is reversal of
199 * acpi_tb_validate_table().
200 *
201 ******************************************************************************/
202
203void acpi_tb_invalidate_table(struct acpi_table_desc *table_desc)
204{
205
206 ACPI_FUNCTION_TRACE(tb_invalidate_table);
207
208 /* Table must be validated */
209
210 if (!table_desc->pointer) {
211 return_VOID;
212 }
213
214 acpi_tb_release_table(table_desc->pointer, table_desc->length,
215 table_desc->flags);
216 table_desc->pointer = NULL;
217
218 return_VOID;
219}
220
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800221/******************************************************************************
Lv Zheng7f9fc992014-04-04 12:38:42 +0800222 *
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800223 * FUNCTION: acpi_tb_verify_table
Linus Torvalds1da177e2005-04-16 15:20:36 -0700224 *
Alexey Starikovskiy428f2112007-02-02 19:48:22 +0300225 * PARAMETERS: table_desc - Table descriptor
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800226 * signature - Table signature to verify
Linus Torvalds1da177e2005-04-16 15:20:36 -0700227 *
228 * RETURN: Status
229 *
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800230 * DESCRIPTION: This function is called to validate and verify the table, the
231 * returned table descriptor is in "VALIDATED" state.
232 *
233 *****************************************************************************/
234
235acpi_status
236acpi_tb_verify_table(struct acpi_table_desc *table_desc, char *signature)
237{
238 acpi_status status = AE_OK;
239
240 ACPI_FUNCTION_TRACE(tb_verify_table);
241
242 /* Validate the table */
243
244 status = acpi_tb_validate_table(table_desc);
245 if (ACPI_FAILURE(status)) {
246 return_ACPI_STATUS(AE_NO_MEMORY);
247 }
248
249 /* If a particular signature is expected (DSDT/FACS), it must match */
250
251 if (signature && !ACPI_COMPARE_NAME(&table_desc->signature, signature)) {
252 ACPI_BIOS_ERROR((AE_INFO,
253 "Invalid signature 0x%X for ACPI table, expected [%s]",
254 table_desc->signature.integer, signature));
255 status = AE_BAD_SIGNATURE;
256 goto invalidate_and_exit;
257 }
258
259 /* Verify the checksum */
260
261 status =
262 acpi_tb_verify_checksum(table_desc->pointer, table_desc->length);
263 if (ACPI_FAILURE(status)) {
264 ACPI_EXCEPTION((AE_INFO, AE_NO_MEMORY,
265 "%4.4s " ACPI_PRINTF_UINT
266 " Attempted table install failed",
267 acpi_ut_valid_acpi_name(table_desc->signature.
268 ascii) ? table_desc->
269 signature.ascii : "????",
270 ACPI_FORMAT_TO_UINT(table_desc->address)));
271 goto invalidate_and_exit;
272 }
273
274 return_ACPI_STATUS(AE_OK);
275
276invalidate_and_exit:
277 acpi_tb_invalidate_table(table_desc);
278 return_ACPI_STATUS(status);
279}
280
281/*******************************************************************************
282 *
283 * FUNCTION: acpi_tb_install_table
284 *
285 * PARAMETERS: table_desc - Table descriptor
286 * address - Physical address of the table
287 * flags - Allocation flags of the table
288 * table - Pointer to the table
289 *
290 * RETURN: None
291 *
292 * DESCRIPTION: Install an ACPI table into the global data structure.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700293 *
294 ******************************************************************************/
295
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800296void
297acpi_tb_install_table(struct acpi_table_desc *table_desc,
298 acpi_physical_address address,
299 u8 flags, struct acpi_table_header *table)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700300{
Bob Moorebc45b1d2008-06-10 14:12:50 +0800301 /*
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800302 * Initialize the table entry. Set the pointer to NULL, since the
303 * table is not fully mapped at this time.
Bob Moorebc45b1d2008-06-10 14:12:50 +0800304 */
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800305 ACPI_MEMSET(table_desc, 0, sizeof(struct acpi_table_desc));
306 table_desc->address = address;
307 table_desc->length = table->length;
308 table_desc->flags = flags;
309 ACPI_MOVE_32_TO_32(table_desc->signature.ascii, table->signature);
310}
Bob Moorec8cefe32011-06-14 10:42:53 +0800311
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800312/*******************************************************************************
313 *
314 * FUNCTION: acpi_tb_acquire_temporal_table
315 *
316 * PARAMETERS: table_desc - Table descriptor to be acquired
317 * address - Address of the table
318 * flags - Allocation flags of the table
319 *
320 * RETURN: Status
321 *
322 * DESCRIPTION: This function validates the table header to obtain the length
323 * of a table and fills the table descriptor to make its state as
324 * "INSTALLED". Such table descriptor is only used for verified
325 * installation.
326 *
327 ******************************************************************************/
328
329static acpi_status
330acpi_tb_acquire_temporal_table(struct acpi_table_desc *table_desc,
331 acpi_physical_address address, u8 flags)
332{
333 struct acpi_table_header *table_header;
334
335 switch (flags & ACPI_TABLE_ORIGIN_MASK) {
336 case ACPI_TABLE_ORIGIN_MAPPED:
337
338 /* Try to obtain the length of the table */
339
340 table_header =
341 acpi_os_map_memory(address,
342 sizeof(struct acpi_table_header));
343 if (!table_header) {
344 return (AE_NO_MEMORY);
345 }
346 acpi_tb_install_table(table_desc, address, flags, table_header);
347 acpi_os_unmap_memory(table_header,
348 sizeof(struct acpi_table_header));
349 return (AE_OK);
350
351 case ACPI_TABLE_ORIGIN_ALLOCATED:
352 case ACPI_TABLE_ORIGIN_UNKNOWN:
353 case ACPI_TABLE_ORIGIN_OVERRIDE:
354
355 table_header = ACPI_CAST_PTR(struct acpi_table_header, address);
356 if (!table_header) {
357 return (AE_NO_MEMORY);
358 }
359 acpi_tb_install_table(table_desc, address, flags, table_header);
360 return (AE_OK);
361
362 default:
363
364 break;
Bob Moorec8cefe32011-06-14 10:42:53 +0800365 }
Alexey Starikovskiy428f2112007-02-02 19:48:22 +0300366
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800367 /* Table is not valid yet */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700368
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800369 return (AE_NO_MEMORY);
370}
Bob Mooref3d2e782007-02-02 19:48:18 +0300371
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800372/*******************************************************************************
373 *
374 * FUNCTION: acpi_tb_release_temporal_table
375 *
376 * PARAMETERS: table_desc - Table descriptor to be released
377 *
378 * RETURN: Status
379 *
380 * DESCRIPTION: The reversal of acpi_tb_acquire_temporal_table().
381 *
382 ******************************************************************************/
Bob Mooref3d2e782007-02-02 19:48:18 +0300383
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800384static void acpi_tb_release_temporal_table(struct acpi_table_desc *table_desc)
385{
386 /*
387 * Note that the .Address is maintained by the callers of
388 * acpi_tb_acquire_temporal_table(), thus do not invoke acpi_tb_uninstall_table()
389 * where .Address will be freed.
390 */
391 acpi_tb_invalidate_table(table_desc);
392}
Bob Mooree56f5612008-07-04 10:48:43 +0800393
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800394/*******************************************************************************
395 *
396 * FUNCTION: acpi_tb_install_and_override_table
397 *
398 * PARAMETERS: table_index - Index into root table array
399 * new_table_desc - New table descriptor to install
400 *
401 * RETURN: None
402 *
403 * DESCRIPTION: Install an ACPI table into the global data structure. The
404 * table override mechanism is called to allow the host
405 * OS to replace any table before it is installed in the root
406 * table array.
407 *
408 ******************************************************************************/
Bob Mooref3d2e782007-02-02 19:48:18 +0300409
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800410void
411acpi_tb_install_and_override_table(u32 table_index,
412 struct acpi_table_desc *new_table_desc)
413{
414 if (table_index >= acpi_gbl_root_table_list.current_table_count) {
415 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700416 }
417
Bob Moored3ccaff2009-02-03 14:43:04 +0800418 /*
419 * ACPI Table Override:
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800420 *
421 * Before we install the table, let the host OS override it with a new
422 * one if desired. Any table within the RSDT/XSDT can be replaced,
423 * including the DSDT which is pointed to by the FADT.
Bob Moored3ccaff2009-02-03 14:43:04 +0800424 */
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800425 acpi_tb_override_table(new_table_desc);
Lv Zheng7f9fc992014-04-04 12:38:42 +0800426
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800427 acpi_tb_install_table(&acpi_gbl_root_table_list.tables[table_index],
428 new_table_desc->address, new_table_desc->flags,
429 new_table_desc->pointer);
Lv Zheng7f9fc992014-04-04 12:38:42 +0800430
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800431 acpi_tb_print_table_header(new_table_desc->address,
432 new_table_desc->pointer);
433
434 /* Set the global integer width (based upon revision of the DSDT) */
435
436 if (table_index == ACPI_TABLE_INDEX_DSDT) {
437 acpi_ut_set_integer_width(new_table_desc->pointer->revision);
438 }
439}
440
441/*******************************************************************************
442 *
443 * FUNCTION: acpi_tb_install_fixed_table
444 *
445 * PARAMETERS: address - Physical address of DSDT or FACS
446 * signature - Table signature, NULL if no need to
447 * match
448 * table_index - Index into root table array
449 *
450 * RETURN: Status
451 *
452 * DESCRIPTION: Install a fixed ACPI table (DSDT/FACS) into the global data
453 * structure.
454 *
455 ******************************************************************************/
456
457acpi_status
458acpi_tb_install_fixed_table(acpi_physical_address address,
459 char *signature, u32 table_index)
460{
461 struct acpi_table_desc new_table_desc;
462 acpi_status status;
463
464 ACPI_FUNCTION_TRACE(tb_install_fixed_table);
465
466 if (!address) {
467 ACPI_ERROR((AE_INFO,
468 "Null physical address for ACPI table [%s]",
469 signature));
470 return (AE_NO_MEMORY);
471 }
472
473 /* Fill a table descriptor for validation */
474
475 status = acpi_tb_acquire_temporal_table(&new_table_desc, address,
476 ACPI_TABLE_ORIGIN_MAPPED);
477 if (ACPI_FAILURE(status)) {
478 ACPI_ERROR((AE_INFO, "Could not acquire table length at %p",
479 ACPI_CAST_PTR(void, address)));
480 return_ACPI_STATUS(status);
481 }
482
483 /* Validate and verify a table before installation */
484
485 status = acpi_tb_verify_table(&new_table_desc, signature);
486 if (ACPI_FAILURE(status)) {
487 goto release_and_exit;
488 }
489
490 acpi_tb_install_and_override_table(table_index, &new_table_desc);
491
492release_and_exit:
493
494 /* Release the temporal table descriptor */
495
496 acpi_tb_release_temporal_table(&new_table_desc);
497 return_ACPI_STATUS(status);
498}
499
500/*******************************************************************************
501 *
502 * FUNCTION: acpi_tb_is_equivalent_table
503 *
504 * PARAMETERS: table_desc - Table 1 descriptor to be compared
505 * table_index - Index of table 2 to be compared
506 *
507 * RETURN: TRUE if 2 tables are equivalent
508 *
509 * DESCRIPTION: This function is called to compare a table with what have
510 * already been installed in the root table list.
511 *
512 ******************************************************************************/
513
514static u8
515acpi_tb_is_equivalent_table(struct acpi_table_desc *table_desc, u32 table_index)
516{
517 acpi_status status = AE_OK;
518 u8 is_equivalent;
519 struct acpi_table_header *table;
520 u32 table_length;
521 u8 table_flags;
522
523 status =
524 acpi_tb_acquire_table(&acpi_gbl_root_table_list.tables[table_index],
525 &table, &table_length, &table_flags);
526 if (ACPI_FAILURE(status)) {
527 return (FALSE);
528 }
529
530 /*
531 * Check for a table match on the entire table length,
532 * not just the header.
533 */
534 is_equivalent = (u8)((table_desc->length != table_length ||
535 ACPI_MEMCMP(table_desc->pointer, table,
536 table_length)) ? FALSE : TRUE);
537
538 /* Release the acquired table */
539
540 acpi_tb_release_table(table, table_length, table_flags);
541
542 return (is_equivalent);
543}
544
545/*******************************************************************************
546 *
547 * FUNCTION: acpi_tb_install_non_fixed_table
548 *
549 * PARAMETERS: address - Address of the table (might be a logical
550 * address depending on the table_flags)
551 * flags - Flags for the table
552 * reload - Whether reload should be performed
553 * table_index - Where the table index is returned
554 *
555 * RETURN: Status
556 *
557 * DESCRIPTION: This function is called to install an ACPI table that is
558 * neither DSDT nor FACS.
559 * When this function is called by "Load" or "LoadTable" opcodes,
560 * or by acpi_load_table() API, the "Reload" parameter is set.
561 * After sucessfully returning from this function, table is
562 * "INSTALLED" but not "VALIDATED".
563 *
564 ******************************************************************************/
565
566acpi_status
567acpi_tb_install_non_fixed_table(acpi_physical_address address,
568 u8 flags, u8 reload, u32 *table_index)
569{
570 u32 i;
571 acpi_status status = AE_OK;
572 struct acpi_table_desc new_table_desc;
573
574 ACPI_FUNCTION_TRACE(tb_install_non_fixed_table);
575
576 /* Acquire a temporal table descriptor for validation */
577
578 status =
579 acpi_tb_acquire_temporal_table(&new_table_desc, address, flags);
580 if (ACPI_FAILURE(status)) {
581 ACPI_ERROR((AE_INFO, "Could not acquire table length at %p",
582 ACPI_CAST_PTR(void, address)));
583 return_ACPI_STATUS(status);
584 }
585
586 /* Validate and verify a table before installation */
587
588 status = acpi_tb_verify_table(&new_table_desc, NULL);
589 if (ACPI_FAILURE(status)) {
590 goto release_and_exit;
591 }
592
593 if (reload) {
594 /*
595 * Validate the incoming table signature.
596 *
597 * 1) Originally, we checked the table signature for "SSDT" or "PSDT".
598 * 2) We added support for OEMx tables, signature "OEM".
599 * 3) Valid tables were encountered with a null signature, so we just
600 * gave up on validating the signature, (05/2008).
601 * 4) We encountered non-AML tables such as the MADT, which caused
602 * interpreter errors and kernel faults. So now, we once again allow
603 * only "SSDT", "OEMx", and now, also a null signature. (05/2011).
604 */
605 if ((new_table_desc.signature.ascii[0] != 0x00) &&
606 (!ACPI_COMPARE_NAME
607 (&new_table_desc.signature, ACPI_SIG_SSDT))
608 && (ACPI_STRNCMP(new_table_desc.signature.ascii, "OEM", 3)))
609 {
610 ACPI_BIOS_ERROR((AE_INFO,
611 "Table has invalid signature [%4.4s] (0x%8.8X), "
612 "must be SSDT or OEMx",
613 acpi_ut_valid_acpi_name(new_table_desc.
614 signature.
615 ascii) ?
616 new_table_desc.signature.
617 ascii : "????",
618 new_table_desc.signature.integer));
619
620 status = AE_BAD_SIGNATURE;
621 goto release_and_exit;
622 }
623
624 /* Check if table is already registered */
625
626 for (i = 0; i < acpi_gbl_root_table_list.current_table_count;
627 ++i) {
628 /*
629 * Check for a table match on the entire table length,
630 * not just the header.
631 */
632 if (!acpi_tb_is_equivalent_table(&new_table_desc, i)) {
633 continue;
634 }
635
636 /*
637 * Note: the current mechanism does not unregister a table if it is
638 * dynamically unloaded. The related namespace entries are deleted,
639 * but the table remains in the root table list.
640 *
641 * The assumption here is that the number of different tables that
642 * will be loaded is actually small, and there is minimal overhead
643 * in just keeping the table in case it is needed again.
644 *
645 * If this assumption changes in the future (perhaps on large
646 * machines with many table load/unload operations), tables will
647 * need to be unregistered when they are unloaded, and slots in the
648 * root table list should be reused when empty.
649 */
650 if (acpi_gbl_root_table_list.tables[i].
651 flags & ACPI_TABLE_IS_LOADED) {
652
653 /* Table is still loaded, this is an error */
654
655 status = AE_ALREADY_EXISTS;
656 goto release_and_exit;
657 } else {
658 /*
659 * Table was unloaded, allow it to be reloaded.
660 * As we are going to return AE_OK to the caller, we should
661 * take the responsibility of freeing the input descriptor.
662 * Refill the input descriptor to ensure
663 * acpi_tb_install_and_override_table() can be called again to
664 * indicate the re-installation.
665 */
666 acpi_tb_uninstall_table(&new_table_desc);
667 *table_index = i;
668 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
669 return_ACPI_STATUS(AE_OK);
670 }
671 }
Lv Zheng7f9fc992014-04-04 12:38:42 +0800672 }
Bob Moored3ccaff2009-02-03 14:43:04 +0800673
Bob Mooree56f5612008-07-04 10:48:43 +0800674 /* Add the table to the global root table list */
675
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800676 status = acpi_tb_acquire_root_table_entry(&i);
Len Brown4be44fc2005-08-05 00:44:28 -0400677 if (ACPI_FAILURE(status)) {
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800678 goto release_and_exit;
Robert Moore0c9938c2005-07-29 15:15:00 -0700679 }
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800680 *table_index = i;
681 acpi_tb_install_and_override_table(i, &new_table_desc);
Robert Moore0c9938c2005-07-29 15:15:00 -0700682
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800683release_and_exit:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700684
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800685 /* Release the temporal table descriptor */
686
687 acpi_tb_release_temporal_table(&new_table_desc);
Len Brown4be44fc2005-08-05 00:44:28 -0400688 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700689}
690
Linus Torvalds1da177e2005-04-16 15:20:36 -0700691/*******************************************************************************
692 *
Lv Zheng7f9fc992014-04-04 12:38:42 +0800693 * FUNCTION: acpi_tb_override_table
Bob Mooref7b004a2012-02-14 18:31:56 +0800694 *
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800695 * PARAMETERS: old_table_desc - Validated table descriptor to be
696 * overridden
Bob Mooref7b004a2012-02-14 18:31:56 +0800697 *
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800698 * RETURN: None
Bob Mooref7b004a2012-02-14 18:31:56 +0800699 *
700 * DESCRIPTION: Attempt table override by calling the OSL override functions.
701 * Note: If the table is overridden, then the entire new table
Lv Zheng7f9fc992014-04-04 12:38:42 +0800702 * is acquired and returned by this function.
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800703 * Before/after invocation, the table descriptor is in a state
704 * that is "VALIDATED".
Bob Mooref7b004a2012-02-14 18:31:56 +0800705 *
706 ******************************************************************************/
707
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800708void acpi_tb_override_table(struct acpi_table_desc *old_table_desc)
Bob Mooref7b004a2012-02-14 18:31:56 +0800709{
710 acpi_status status;
Bob Mooref7b004a2012-02-14 18:31:56 +0800711 char *override_type;
Lv Zheng7f9fc992014-04-04 12:38:42 +0800712 struct acpi_table_desc new_table_desc;
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800713 struct acpi_table_header *table;
714 acpi_physical_address address;
715 u32 length;
Bob Mooref7b004a2012-02-14 18:31:56 +0800716
717 /* (1) Attempt logical override (returns a logical address) */
718
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800719 status = acpi_os_table_override(old_table_desc->pointer, &table);
720 if (ACPI_SUCCESS(status) && table) {
721 acpi_tb_acquire_temporal_table(&new_table_desc,
722 ACPI_PTR_TO_PHYSADDR(table),
723 ACPI_TABLE_ORIGIN_OVERRIDE);
Bob Mooref7b004a2012-02-14 18:31:56 +0800724 override_type = "Logical";
725 goto finish_override;
726 }
727
728 /* (2) Attempt physical override (returns a physical address) */
729
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800730 status = acpi_os_physical_table_override(old_table_desc->pointer,
731 &address, &length);
732 if (ACPI_SUCCESS(status) && address && length) {
733 acpi_tb_acquire_temporal_table(&new_table_desc, address,
734 ACPI_TABLE_ORIGIN_MAPPED);
Bob Mooref7b004a2012-02-14 18:31:56 +0800735 override_type = "Physical";
Bob Mooref7b004a2012-02-14 18:31:56 +0800736 goto finish_override;
737 }
738
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800739 return; /* There was no override */
Bob Mooref7b004a2012-02-14 18:31:56 +0800740
Lv Zheng10622bf2013-10-29 09:30:02 +0800741finish_override:
Bob Mooref7b004a2012-02-14 18:31:56 +0800742
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800743 /* Validate and verify a table before overriding */
744
745 status = acpi_tb_verify_table(&new_table_desc, NULL);
Lv Zheng7f9fc992014-04-04 12:38:42 +0800746 if (ACPI_FAILURE(status)) {
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800747 return;
Lv Zheng7f9fc992014-04-04 12:38:42 +0800748 }
749
Bob Moore2e19f8d2014-02-08 09:42:07 +0800750 ACPI_INFO((AE_INFO, "%4.4s " ACPI_PRINTF_UINT
751 " %s table override, new table: " ACPI_PRINTF_UINT,
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800752 old_table_desc->signature.ascii,
753 ACPI_FORMAT_TO_UINT(old_table_desc->address),
Lv Zheng7f9fc992014-04-04 12:38:42 +0800754 override_type, ACPI_FORMAT_TO_UINT(new_table_desc.address)));
Bob Mooref7b004a2012-02-14 18:31:56 +0800755
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800756 /* We can now uninstall the original table */
Bob Mooref7b004a2012-02-14 18:31:56 +0800757
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800758 acpi_tb_uninstall_table(old_table_desc);
Bob Mooref7b004a2012-02-14 18:31:56 +0800759
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800760 /*
761 * Replace the original table descriptor and keep its state as
762 * "VALIDATED".
763 */
764 acpi_tb_install_table(old_table_desc, new_table_desc.address,
765 new_table_desc.flags, new_table_desc.pointer);
766 acpi_tb_validate_table(old_table_desc);
Bob Mooref7b004a2012-02-14 18:31:56 +0800767
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800768 /* Release the temporal table descriptor */
Bob Mooref7b004a2012-02-14 18:31:56 +0800769
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800770 acpi_tb_release_temporal_table(&new_table_desc);
Bob Mooref7b004a2012-02-14 18:31:56 +0800771}
772
773/*******************************************************************************
774 *
Bob Mooref3d2e782007-02-02 19:48:18 +0300775 * FUNCTION: acpi_tb_resize_root_table_list
Linus Torvalds1da177e2005-04-16 15:20:36 -0700776 *
Bob Mooref3d2e782007-02-02 19:48:18 +0300777 * PARAMETERS: None
Linus Torvalds1da177e2005-04-16 15:20:36 -0700778 *
779 * RETURN: Status
780 *
Bob Mooref3d2e782007-02-02 19:48:18 +0300781 * DESCRIPTION: Expand the size of global table array
Linus Torvalds1da177e2005-04-16 15:20:36 -0700782 *
783 ******************************************************************************/
784
Bob Mooref3d2e782007-02-02 19:48:18 +0300785acpi_status acpi_tb_resize_root_table_list(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700786{
Bob Mooref3d2e782007-02-02 19:48:18 +0300787 struct acpi_table_desc *tables;
Lv Zheng2bc198c2012-09-13 09:29:06 -0700788 u32 table_count;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700789
Bob Mooref3d2e782007-02-02 19:48:18 +0300790 ACPI_FUNCTION_TRACE(tb_resize_root_table_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700791
Bob Mooref3d2e782007-02-02 19:48:18 +0300792 /* allow_resize flag is a parameter to acpi_initialize_tables */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700793
Bob Moorec5fc42a2007-02-02 19:48:19 +0300794 if (!(acpi_gbl_root_table_list.flags & ACPI_ROOT_ALLOW_RESIZE)) {
Bob Mooref3d2e782007-02-02 19:48:18 +0300795 ACPI_ERROR((AE_INFO,
796 "Resize of Root Table Array is not allowed"));
797 return_ACPI_STATUS(AE_SUPPORT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700798 }
799
Bob Mooref3d2e782007-02-02 19:48:18 +0300800 /* Increase the Table Array size */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700801
Lv Zheng2bc198c2012-09-13 09:29:06 -0700802 if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) {
803 table_count = acpi_gbl_root_table_list.max_table_count;
804 } else {
805 table_count = acpi_gbl_root_table_list.current_table_count;
806 }
807
808 tables = ACPI_ALLOCATE_ZEROED(((acpi_size) table_count +
Bob Mooreec41f192009-02-18 15:03:30 +0800809 ACPI_ROOT_TABLE_SIZE_INCREMENT) *
810 sizeof(struct acpi_table_desc));
Bob Mooref3d2e782007-02-02 19:48:18 +0300811 if (!tables) {
812 ACPI_ERROR((AE_INFO,
813 "Could not allocate new root table array"));
Len Brown4be44fc2005-08-05 00:44:28 -0400814 return_ACPI_STATUS(AE_NO_MEMORY);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700815 }
816
Bob Mooref3d2e782007-02-02 19:48:18 +0300817 /* Copy and free the previous table array */
Robert Mooref9f46012005-07-08 00:00:00 -0400818
Bob Mooref3d2e782007-02-02 19:48:18 +0300819 if (acpi_gbl_root_table_list.tables) {
820 ACPI_MEMCPY(tables, acpi_gbl_root_table_list.tables,
Lv Zheng2bc198c2012-09-13 09:29:06 -0700821 (acpi_size) table_count *
822 sizeof(struct acpi_table_desc));
Robert Mooref9f46012005-07-08 00:00:00 -0400823
Bob Moorec5fc42a2007-02-02 19:48:19 +0300824 if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) {
Bob Mooref3d2e782007-02-02 19:48:18 +0300825 ACPI_FREE(acpi_gbl_root_table_list.tables);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700826 }
827 }
828
Bob Mooref3d2e782007-02-02 19:48:18 +0300829 acpi_gbl_root_table_list.tables = tables;
Lv Zheng2bc198c2012-09-13 09:29:06 -0700830 acpi_gbl_root_table_list.max_table_count =
831 table_count + ACPI_ROOT_TABLE_SIZE_INCREMENT;
832 acpi_gbl_root_table_list.flags |= ACPI_ROOT_ORIGIN_ALLOCATED;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700833
Len Brown4be44fc2005-08-05 00:44:28 -0400834 return_ACPI_STATUS(AE_OK);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700835}
836
Linus Torvalds1da177e2005-04-16 15:20:36 -0700837/*******************************************************************************
838 *
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800839 * FUNCTION: acpi_tb_acquire_root_table_entry
840 *
841 * PARAMETERS: table_index - Where table index is returned
842 *
843 * RETURN: Status and table index.
844 *
845 * DESCRIPTION: Allocate a new ACPI table entry to the global table list
846 *
847 ******************************************************************************/
848
849static acpi_status acpi_tb_acquire_root_table_entry(u32 *table_index)
850{
851 acpi_status status;
852
853 /* Ensure that there is room for the table in the Root Table List */
854
855 if (acpi_gbl_root_table_list.current_table_count >=
856 acpi_gbl_root_table_list.max_table_count) {
857 status = acpi_tb_resize_root_table_list();
858 if (ACPI_FAILURE(status)) {
859 return (status);
860 }
861 }
862
863 *table_index = acpi_gbl_root_table_list.current_table_count;
864 acpi_gbl_root_table_list.current_table_count++;
865 return (AE_OK);
866}
867
868/*******************************************************************************
869 *
Bob Mooref3d2e782007-02-02 19:48:18 +0300870 * FUNCTION: acpi_tb_store_table
Linus Torvalds1da177e2005-04-16 15:20:36 -0700871 *
Bob Mooreba494be2012-07-12 09:40:10 +0800872 * PARAMETERS: address - Table address
873 * table - Table header
874 * length - Table length
875 * flags - flags
Linus Torvalds1da177e2005-04-16 15:20:36 -0700876 *
Bob Mooref3d2e782007-02-02 19:48:18 +0300877 * RETURN: Status and table index.
878 *
879 * DESCRIPTION: Add an ACPI table to the global table list
880 *
881 ******************************************************************************/
882
883acpi_status
884acpi_tb_store_table(acpi_physical_address address,
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800885 struct acpi_table_header * table,
Bob Moore67a119f2008-06-10 13:42:13 +0800886 u32 length, u8 flags, u32 *table_index)
Bob Mooref3d2e782007-02-02 19:48:18 +0300887{
Bob Mooreb9ee2042010-04-27 11:16:14 +0800888 acpi_status status;
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800889 struct acpi_table_desc *table_desc;
Bob Mooref3d2e782007-02-02 19:48:18 +0300890
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800891 status = acpi_tb_acquire_root_table_entry(table_index);
892 if (ACPI_FAILURE(status)) {
893 return (status);
Bob Mooref3d2e782007-02-02 19:48:18 +0300894 }
895
896 /* Initialize added table */
897
Lv Zheng86dfc6f32014-04-04 12:38:57 +0800898 table_desc = &acpi_gbl_root_table_list.tables[*table_index];
899 acpi_tb_install_table(table_desc, address, flags, table);
900 table_desc->pointer = table;
Bob Mooref3d2e782007-02-02 19:48:18 +0300901
Bob Mooreb9ee2042010-04-27 11:16:14 +0800902 return (AE_OK);
Bob Mooref3d2e782007-02-02 19:48:18 +0300903}
904
905/*******************************************************************************
906 *
Lv Zheng7f9fc992014-04-04 12:38:42 +0800907 * FUNCTION: acpi_tb_uninstall_table
Bob Mooref3d2e782007-02-02 19:48:18 +0300908 *
Lv Zheng7f9fc992014-04-04 12:38:42 +0800909 * PARAMETERS: table_desc - Table descriptor
Bob Mooref3d2e782007-02-02 19:48:18 +0300910 *
911 * RETURN: None
912 *
913 * DESCRIPTION: Delete one internal ACPI table
914 *
915 ******************************************************************************/
916
Lv Zheng7f9fc992014-04-04 12:38:42 +0800917void acpi_tb_uninstall_table(struct acpi_table_desc *table_desc)
Bob Mooref3d2e782007-02-02 19:48:18 +0300918{
Lv Zheng55829822014-04-04 12:38:18 +0800919
Lv Zheng7f9fc992014-04-04 12:38:42 +0800920 ACPI_FUNCTION_TRACE(tb_uninstall_table);
Lv Zheng55829822014-04-04 12:38:18 +0800921
Lv Zheng7f9fc992014-04-04 12:38:42 +0800922 /* Table must be installed */
923
924 if (!table_desc->address) {
925 return_VOID;
Bob Mooref3d2e782007-02-02 19:48:18 +0300926 }
Lv Zheng55829822014-04-04 12:38:18 +0800927
Lv Zheng7f9fc992014-04-04 12:38:42 +0800928 acpi_tb_invalidate_table(table_desc);
Chao Guan1d1ea1b2013-06-08 00:58:14 +0000929
Lv Zheng7f9fc992014-04-04 12:38:42 +0800930 if ((table_desc->flags & ACPI_TABLE_ORIGIN_MASK) ==
931 ACPI_TABLE_ORIGIN_ALLOCATED) {
932 ACPI_FREE(ACPI_CAST_PTR(void, table_desc->address));
Bob Mooref3d2e782007-02-02 19:48:18 +0300933 }
934
Lv Zheng7f9fc992014-04-04 12:38:42 +0800935 table_desc->address = ACPI_PTR_TO_PHYSADDR(NULL);
936
937 return_VOID;
Bob Mooref3d2e782007-02-02 19:48:18 +0300938}
939
940/*******************************************************************************
941 *
942 * FUNCTION: acpi_tb_terminate
943 *
944 * PARAMETERS: None
945 *
946 * RETURN: None
Linus Torvalds1da177e2005-04-16 15:20:36 -0700947 *
948 * DESCRIPTION: Delete all internal ACPI tables
949 *
950 ******************************************************************************/
951
Bob Mooref3d2e782007-02-02 19:48:18 +0300952void acpi_tb_terminate(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700953{
Bob Moore67a119f2008-06-10 13:42:13 +0800954 u32 i;
Bob Mooref3d2e782007-02-02 19:48:18 +0300955
956 ACPI_FUNCTION_TRACE(tb_terminate);
957
958 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
959
960 /* Delete the individual tables */
961
Bob Mooreb9ee2042010-04-27 11:16:14 +0800962 for (i = 0; i < acpi_gbl_root_table_list.current_table_count; i++) {
Lv Zheng7f9fc992014-04-04 12:38:42 +0800963 acpi_tb_uninstall_table(&acpi_gbl_root_table_list.tables[i]);
Bob Mooref3d2e782007-02-02 19:48:18 +0300964 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700965
966 /*
Bob Mooref3d2e782007-02-02 19:48:18 +0300967 * Delete the root table array if allocated locally. Array cannot be
968 * mapped, so we don't need to check for that flag.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700969 */
Bob Moorec5fc42a2007-02-02 19:48:19 +0300970 if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) {
Bob Mooref3d2e782007-02-02 19:48:18 +0300971 ACPI_FREE(acpi_gbl_root_table_list.tables);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700972 }
Bob Mooref3d2e782007-02-02 19:48:18 +0300973
974 acpi_gbl_root_table_list.tables = NULL;
975 acpi_gbl_root_table_list.flags = 0;
Bob Mooreb9ee2042010-04-27 11:16:14 +0800976 acpi_gbl_root_table_list.current_table_count = 0;
Bob Mooref3d2e782007-02-02 19:48:18 +0300977
978 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "ACPI Tables freed\n"));
979 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
Bob Moore68aafc32012-10-31 02:26:01 +0000980
981 return_VOID;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700982}
983
Linus Torvalds1da177e2005-04-16 15:20:36 -0700984/*******************************************************************************
985 *
Bob Mooref3d2e782007-02-02 19:48:18 +0300986 * FUNCTION: acpi_tb_delete_namespace_by_owner
Linus Torvalds1da177e2005-04-16 15:20:36 -0700987 *
Bob Mooref3d2e782007-02-02 19:48:18 +0300988 * PARAMETERS: table_index - Table index
Linus Torvalds1da177e2005-04-16 15:20:36 -0700989 *
Bob Moore8a335a232009-03-09 16:31:04 +0800990 * RETURN: Status
Linus Torvalds1da177e2005-04-16 15:20:36 -0700991 *
Bob Mooref3d2e782007-02-02 19:48:18 +0300992 * DESCRIPTION: Delete all namespace objects created when this table was loaded.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700993 *
994 ******************************************************************************/
995
Bob Moore8a335a232009-03-09 16:31:04 +0800996acpi_status acpi_tb_delete_namespace_by_owner(u32 table_index)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700997{
Bob Mooref3d2e782007-02-02 19:48:18 +0300998 acpi_owner_id owner_id;
Bob Moore8a335a232009-03-09 16:31:04 +0800999 acpi_status status;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001000
Bob Moore8a335a232009-03-09 16:31:04 +08001001 ACPI_FUNCTION_TRACE(tb_delete_namespace_by_owner);
1002
1003 status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
1004 if (ACPI_FAILURE(status)) {
1005 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001006 }
1007
Bob Mooreb9ee2042010-04-27 11:16:14 +08001008 if (table_index >= acpi_gbl_root_table_list.current_table_count) {
Bob Moore8a335a232009-03-09 16:31:04 +08001009
1010 /* The table index does not exist */
1011
1012 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
1013 return_ACPI_STATUS(AE_NOT_EXIST);
1014 }
1015
1016 /* Get the owner ID for this table, used to delete namespace nodes */
1017
1018 owner_id = acpi_gbl_root_table_list.tables[table_index].owner_id;
Len Brown4be44fc2005-08-05 00:44:28 -04001019 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
Bob Moore8a335a232009-03-09 16:31:04 +08001020
1021 /*
1022 * Need to acquire the namespace writer lock to prevent interference
1023 * with any concurrent namespace walks. The interpreter must be
1024 * released during the deletion since the acquisition of the deletion
1025 * lock may block, and also since the execution of a namespace walk
1026 * must be allowed to use the interpreter.
1027 */
Bob Mooree4c1ebf2009-04-22 13:02:06 +08001028 (void)acpi_ut_release_mutex(ACPI_MTX_INTERPRETER);
Bob Moore8a335a232009-03-09 16:31:04 +08001029 status = acpi_ut_acquire_write_lock(&acpi_gbl_namespace_rw_lock);
1030
Bob Mooref3d2e782007-02-02 19:48:18 +03001031 acpi_ns_delete_namespace_by_owner(owner_id);
Bob Moore8a335a232009-03-09 16:31:04 +08001032 if (ACPI_FAILURE(status)) {
1033 return_ACPI_STATUS(status);
1034 }
1035
1036 acpi_ut_release_write_lock(&acpi_gbl_namespace_rw_lock);
1037
1038 status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER);
1039 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001040}
1041
Linus Torvalds1da177e2005-04-16 15:20:36 -07001042/*******************************************************************************
1043 *
Bob Mooref3d2e782007-02-02 19:48:18 +03001044 * FUNCTION: acpi_tb_allocate_owner_id
Linus Torvalds1da177e2005-04-16 15:20:36 -07001045 *
Bob Mooref3d2e782007-02-02 19:48:18 +03001046 * PARAMETERS: table_index - Table index
Linus Torvalds1da177e2005-04-16 15:20:36 -07001047 *
Bob Mooref3d2e782007-02-02 19:48:18 +03001048 * RETURN: Status
Linus Torvalds1da177e2005-04-16 15:20:36 -07001049 *
Bob Mooref3d2e782007-02-02 19:48:18 +03001050 * DESCRIPTION: Allocates owner_id in table_desc
Linus Torvalds1da177e2005-04-16 15:20:36 -07001051 *
1052 ******************************************************************************/
1053
Bob Moore67a119f2008-06-10 13:42:13 +08001054acpi_status acpi_tb_allocate_owner_id(u32 table_index)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001055{
Bob Mooref3d2e782007-02-02 19:48:18 +03001056 acpi_status status = AE_BAD_PARAMETER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001057
Bob Mooref3d2e782007-02-02 19:48:18 +03001058 ACPI_FUNCTION_TRACE(tb_allocate_owner_id);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001059
Bob Mooref3d2e782007-02-02 19:48:18 +03001060 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
Bob Mooreb9ee2042010-04-27 11:16:14 +08001061 if (table_index < acpi_gbl_root_table_list.current_table_count) {
Bob Mooref3d2e782007-02-02 19:48:18 +03001062 status = acpi_ut_allocate_owner_id
1063 (&(acpi_gbl_root_table_list.tables[table_index].owner_id));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001064 }
1065
Bob Mooref3d2e782007-02-02 19:48:18 +03001066 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
1067 return_ACPI_STATUS(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001068}
1069
Linus Torvalds1da177e2005-04-16 15:20:36 -07001070/*******************************************************************************
1071 *
Bob Mooref3d2e782007-02-02 19:48:18 +03001072 * FUNCTION: acpi_tb_release_owner_id
Linus Torvalds1da177e2005-04-16 15:20:36 -07001073 *
Bob Mooref3d2e782007-02-02 19:48:18 +03001074 * PARAMETERS: table_index - Table index
Linus Torvalds1da177e2005-04-16 15:20:36 -07001075 *
Bob Mooref3d2e782007-02-02 19:48:18 +03001076 * RETURN: Status
Linus Torvalds1da177e2005-04-16 15:20:36 -07001077 *
Bob Mooref3d2e782007-02-02 19:48:18 +03001078 * DESCRIPTION: Releases owner_id in table_desc
Linus Torvalds1da177e2005-04-16 15:20:36 -07001079 *
1080 ******************************************************************************/
1081
Bob Moore67a119f2008-06-10 13:42:13 +08001082acpi_status acpi_tb_release_owner_id(u32 table_index)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001083{
Bob Mooref3d2e782007-02-02 19:48:18 +03001084 acpi_status status = AE_BAD_PARAMETER;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001085
Bob Mooref3d2e782007-02-02 19:48:18 +03001086 ACPI_FUNCTION_TRACE(tb_release_owner_id);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001087
Bob Mooref3d2e782007-02-02 19:48:18 +03001088 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
Bob Mooreb9ee2042010-04-27 11:16:14 +08001089 if (table_index < acpi_gbl_root_table_list.current_table_count) {
Bob Mooref3d2e782007-02-02 19:48:18 +03001090 acpi_ut_release_owner_id(&
1091 (acpi_gbl_root_table_list.
1092 tables[table_index].owner_id));
1093 status = AE_OK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001094 }
1095
Bob Mooref3d2e782007-02-02 19:48:18 +03001096 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
1097 return_ACPI_STATUS(status);
1098}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001099
Bob Mooref3d2e782007-02-02 19:48:18 +03001100/*******************************************************************************
1101 *
1102 * FUNCTION: acpi_tb_get_owner_id
1103 *
1104 * PARAMETERS: table_index - Table index
1105 * owner_id - Where the table owner_id is returned
1106 *
1107 * RETURN: Status
1108 *
1109 * DESCRIPTION: returns owner_id for the ACPI table
1110 *
1111 ******************************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001112
Lv Zheng55829822014-04-04 12:38:18 +08001113acpi_status acpi_tb_get_owner_id(u32 table_index, acpi_owner_id * owner_id)
Bob Mooref3d2e782007-02-02 19:48:18 +03001114{
1115 acpi_status status = AE_BAD_PARAMETER;
1116
1117 ACPI_FUNCTION_TRACE(tb_get_owner_id);
1118
1119 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
Bob Mooreb9ee2042010-04-27 11:16:14 +08001120 if (table_index < acpi_gbl_root_table_list.current_table_count) {
Bob Mooref3d2e782007-02-02 19:48:18 +03001121 *owner_id =
1122 acpi_gbl_root_table_list.tables[table_index].owner_id;
1123 status = AE_OK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001124 }
1125
Bob Mooref3d2e782007-02-02 19:48:18 +03001126 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
1127 return_ACPI_STATUS(status);
1128}
1129
1130/*******************************************************************************
1131 *
1132 * FUNCTION: acpi_tb_is_table_loaded
1133 *
1134 * PARAMETERS: table_index - Table index
1135 *
1136 * RETURN: Table Loaded Flag
1137 *
1138 ******************************************************************************/
1139
Bob Moore67a119f2008-06-10 13:42:13 +08001140u8 acpi_tb_is_table_loaded(u32 table_index)
Bob Mooref3d2e782007-02-02 19:48:18 +03001141{
1142 u8 is_loaded = FALSE;
1143
1144 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
Bob Mooreb9ee2042010-04-27 11:16:14 +08001145 if (table_index < acpi_gbl_root_table_list.current_table_count) {
Bob Mooref3d2e782007-02-02 19:48:18 +03001146 is_loaded = (u8)
Bob Mooreec41f192009-02-18 15:03:30 +08001147 (acpi_gbl_root_table_list.tables[table_index].flags &
1148 ACPI_TABLE_IS_LOADED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001149 }
1150
Bob Mooref3d2e782007-02-02 19:48:18 +03001151 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
1152 return (is_loaded);
1153}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001154
Bob Mooref3d2e782007-02-02 19:48:18 +03001155/*******************************************************************************
1156 *
1157 * FUNCTION: acpi_tb_set_table_loaded_flag
1158 *
1159 * PARAMETERS: table_index - Table index
1160 * is_loaded - TRUE if table is loaded, FALSE otherwise
1161 *
1162 * RETURN: None
1163 *
1164 * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE.
1165 *
1166 ******************************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001167
Bob Moore67a119f2008-06-10 13:42:13 +08001168void acpi_tb_set_table_loaded_flag(u32 table_index, u8 is_loaded)
Bob Mooref3d2e782007-02-02 19:48:18 +03001169{
Bob Mooref6dd9222006-07-07 20:44:38 -04001170
Bob Mooref3d2e782007-02-02 19:48:18 +03001171 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
Bob Mooreb9ee2042010-04-27 11:16:14 +08001172 if (table_index < acpi_gbl_root_table_list.current_table_count) {
Bob Mooref3d2e782007-02-02 19:48:18 +03001173 if (is_loaded) {
1174 acpi_gbl_root_table_list.tables[table_index].flags |=
Bob Moorec5fc42a2007-02-02 19:48:19 +03001175 ACPI_TABLE_IS_LOADED;
Bob Mooref3d2e782007-02-02 19:48:18 +03001176 } else {
1177 acpi_gbl_root_table_list.tables[table_index].flags &=
Bob Moorec5fc42a2007-02-02 19:48:19 +03001178 ~ACPI_TABLE_IS_LOADED;
Bob Mooref3d2e782007-02-02 19:48:18 +03001179 }
1180 }
Bob Mooref6dd9222006-07-07 20:44:38 -04001181
Bob Mooref3d2e782007-02-02 19:48:18 +03001182 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001183}