1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2/******************************************************************************
3 *
4 * Module Name: tbdata - Table manager data structure functions
5 *
6 * Copyright (C) 2000 - 2023, Intel Corp.
7 *
8 *****************************************************************************/
9
10#include <acpi/acpi.h>
11#include "accommon.h"
12#include "acnamesp.h"
13#include "actables.h"
14#include "acevents.h"
15
16#define _COMPONENT ACPI_TABLES
17ACPI_MODULE_NAME("tbdata")
18
19/* Local prototypes */
20static acpi_status
21acpi_tb_check_duplication(struct acpi_table_desc *table_desc, u32 *table_index);
22
23static u8
24acpi_tb_compare_tables(struct acpi_table_desc *table_desc, u32 table_index);
25
26/*******************************************************************************
27 *
28 * FUNCTION: acpi_tb_compare_tables
29 *
30 * PARAMETERS: table_desc - Table 1 descriptor to be compared
31 * table_index - Index of table 2 to be compared
32 *
33 * RETURN: TRUE if both tables are identical.
34 *
35 * DESCRIPTION: This function compares a table with another table that has
36 * already been installed in the root table list.
37 *
38 ******************************************************************************/
39
40static u8
41acpi_tb_compare_tables(struct acpi_table_desc *table_desc, u32 table_index)
42{
43 acpi_status status = AE_OK;
44 u8 is_identical;
45 struct acpi_table_header *table;
46 u32 table_length;
47 u8 table_flags;
48
49 status =
50 acpi_tb_acquire_table(table_desc: &acpi_gbl_root_table_list.tables[table_index],
51 table_ptr: &table, table_length: &table_length, table_flags: &table_flags);
52 if (ACPI_FAILURE(status)) {
53 return (FALSE);
54 }
55
56 /*
57 * Check for a table match on the entire table length,
58 * not just the header.
59 */
60 is_identical = (u8)((table_desc->length != table_length ||
61 memcmp(p: table_desc->pointer, q: table, size: table_length)) ?
62 FALSE : TRUE);
63
64 /* Release the acquired table */
65
66 acpi_tb_release_table(table, table_length, table_flags);
67 return (is_identical);
68}
69
70/*******************************************************************************
71 *
72 * FUNCTION: acpi_tb_init_table_descriptor
73 *
74 * PARAMETERS: table_desc - Table descriptor
75 * address - Physical address of the table
76 * flags - Allocation flags of the table
77 * table - Pointer to the table
78 *
79 * RETURN: None
80 *
81 * DESCRIPTION: Initialize a new table descriptor
82 *
83 ******************************************************************************/
84
85void
86acpi_tb_init_table_descriptor(struct acpi_table_desc *table_desc,
87 acpi_physical_address address,
88 u8 flags, struct acpi_table_header *table)
89{
90
91 /*
92 * Initialize the table descriptor. Set the pointer to NULL for external
93 * tables, since the table is not fully mapped at this time.
94 */
95 memset(table_desc, 0, sizeof(struct acpi_table_desc));
96 table_desc->address = address;
97 table_desc->length = table->length;
98 table_desc->flags = flags;
99 ACPI_MOVE_32_TO_32(table_desc->signature.ascii, table->signature);
100
101 switch (table_desc->flags & ACPI_TABLE_ORIGIN_MASK) {
102 case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL:
103 case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL:
104
105 table_desc->pointer = table;
106 break;
107
108 case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL:
109 default:
110
111 break;
112 }
113}
114
115/*******************************************************************************
116 *
117 * FUNCTION: acpi_tb_acquire_table
118 *
119 * PARAMETERS: table_desc - Table descriptor
120 * table_ptr - Where table is returned
121 * table_length - Where table length is returned
122 * table_flags - Where table allocation flags are returned
123 *
124 * RETURN: Status
125 *
126 * DESCRIPTION: Acquire an ACPI table. It can be used for tables not
127 * maintained in the acpi_gbl_root_table_list.
128 *
129 ******************************************************************************/
130
131acpi_status
132acpi_tb_acquire_table(struct acpi_table_desc *table_desc,
133 struct acpi_table_header **table_ptr,
134 u32 *table_length, u8 *table_flags)
135{
136 struct acpi_table_header *table = NULL;
137
138 switch (table_desc->flags & ACPI_TABLE_ORIGIN_MASK) {
139 case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL:
140
141 table =
142 acpi_os_map_memory(where: table_desc->address, length: table_desc->length);
143 break;
144
145 case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL:
146 case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL:
147
148 table = table_desc->pointer;
149 break;
150
151 default:
152
153 break;
154 }
155
156 /* Table is not valid yet */
157
158 if (!table) {
159 return (AE_NO_MEMORY);
160 }
161
162 /* Fill the return values */
163
164 *table_ptr = table;
165 *table_length = table_desc->length;
166 *table_flags = table_desc->flags;
167 return (AE_OK);
168}
169
170/*******************************************************************************
171 *
172 * FUNCTION: acpi_tb_release_table
173 *
174 * PARAMETERS: table - Pointer for the table
175 * table_length - Length for the table
176 * table_flags - Allocation flags for the table
177 *
178 * RETURN: None
179 *
180 * DESCRIPTION: Release a table. The inverse of acpi_tb_acquire_table().
181 *
182 ******************************************************************************/
183
184void
185acpi_tb_release_table(struct acpi_table_header *table,
186 u32 table_length, u8 table_flags)
187{
188
189 switch (table_flags & ACPI_TABLE_ORIGIN_MASK) {
190 case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL:
191
192 acpi_os_unmap_memory(logical_address: table, size: table_length);
193 break;
194
195 case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL:
196 case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL:
197 default:
198
199 break;
200 }
201}
202
203/*******************************************************************************
204 *
205 * FUNCTION: acpi_tb_acquire_temp_table
206 *
207 * PARAMETERS: table_desc - Table descriptor to be acquired
208 * address - Address of the table
209 * flags - Allocation flags of the table
210 * table - Pointer to the table (required for virtual
211 * origins, optional for physical)
212 *
213 * RETURN: Status
214 *
215 * DESCRIPTION: This function validates the table header to obtain the length
216 * of a table and fills the table descriptor to make its state as
217 * "INSTALLED". Such a table descriptor is only used for verified
218 * installation.
219 *
220 ******************************************************************************/
221
222acpi_status
223acpi_tb_acquire_temp_table(struct acpi_table_desc *table_desc,
224 acpi_physical_address address,
225 u8 flags, struct acpi_table_header *table)
226{
227 u8 mapped_table = FALSE;
228
229 switch (flags & ACPI_TABLE_ORIGIN_MASK) {
230 case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL:
231
232 /* Get the length of the full table from the header */
233
234 if (!table) {
235 table =
236 acpi_os_map_memory(where: address,
237 length: sizeof(struct
238 acpi_table_header));
239 if (!table) {
240 return (AE_NO_MEMORY);
241 }
242
243 mapped_table = TRUE;
244 }
245
246 break;
247
248 case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL:
249 case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL:
250
251 if (!table) {
252 return (AE_BAD_PARAMETER);
253 }
254
255 break;
256
257 default:
258
259 /* Table is not valid yet */
260
261 return (AE_NO_MEMORY);
262 }
263
264 acpi_tb_init_table_descriptor(table_desc, address, flags, table);
265 if (mapped_table) {
266 acpi_os_unmap_memory(logical_address: table, size: sizeof(struct acpi_table_header));
267 }
268
269 return (AE_OK);
270}
271
272/*******************************************************************************
273 *
274 * FUNCTION: acpi_tb_release_temp_table
275 *
276 * PARAMETERS: table_desc - Table descriptor to be released
277 *
278 * RETURN: Status
279 *
280 * DESCRIPTION: The inverse of acpi_tb_acquire_temp_table().
281 *
282 *****************************************************************************/
283
284void acpi_tb_release_temp_table(struct acpi_table_desc *table_desc)
285{
286
287 /*
288 * Note that the .Address is maintained by the callers of
289 * acpi_tb_acquire_temp_table(), thus do not invoke acpi_tb_uninstall_table()
290 * where .Address will be freed.
291 */
292 acpi_tb_invalidate_table(table_desc);
293}
294
295/******************************************************************************
296 *
297 * FUNCTION: acpi_tb_validate_table
298 *
299 * PARAMETERS: table_desc - Table descriptor
300 *
301 * RETURN: Status
302 *
303 * DESCRIPTION: This function is called to validate the table, the returned
304 * table descriptor is in "VALIDATED" state.
305 *
306 *****************************************************************************/
307
308acpi_status acpi_tb_validate_table(struct acpi_table_desc *table_desc)
309{
310 acpi_status status = AE_OK;
311
312 ACPI_FUNCTION_TRACE(tb_validate_table);
313
314 /* Validate the table if necessary */
315
316 if (!table_desc->pointer) {
317 status = acpi_tb_acquire_table(table_desc, table_ptr: &table_desc->pointer,
318 table_length: &table_desc->length,
319 table_flags: &table_desc->flags);
320 if (!table_desc->pointer) {
321 status = AE_NO_MEMORY;
322 }
323 }
324
325 return_ACPI_STATUS(status);
326}
327
328/*******************************************************************************
329 *
330 * FUNCTION: acpi_tb_invalidate_table
331 *
332 * PARAMETERS: table_desc - Table descriptor
333 *
334 * RETURN: None
335 *
336 * DESCRIPTION: Invalidate one internal ACPI table, this is the inverse of
337 * acpi_tb_validate_table().
338 *
339 ******************************************************************************/
340
341void acpi_tb_invalidate_table(struct acpi_table_desc *table_desc)
342{
343
344 ACPI_FUNCTION_TRACE(tb_invalidate_table);
345
346 /* Table must be validated */
347
348 if (!table_desc->pointer) {
349 return_VOID;
350 }
351
352 acpi_tb_release_table(table: table_desc->pointer, table_length: table_desc->length,
353 table_flags: table_desc->flags);
354
355 switch (table_desc->flags & ACPI_TABLE_ORIGIN_MASK) {
356 case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL:
357
358 table_desc->pointer = NULL;
359 break;
360
361 case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL:
362 case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL:
363 default:
364
365 break;
366 }
367
368 return_VOID;
369}
370
371/******************************************************************************
372 *
373 * FUNCTION: acpi_tb_validate_temp_table
374 *
375 * PARAMETERS: table_desc - Table descriptor
376 *
377 * RETURN: Status
378 *
379 * DESCRIPTION: This function is called to validate the table, the returned
380 * table descriptor is in "VALIDATED" state.
381 *
382 *****************************************************************************/
383
384acpi_status acpi_tb_validate_temp_table(struct acpi_table_desc *table_desc)
385{
386
387 if (!table_desc->pointer && !acpi_gbl_enable_table_validation) {
388 /*
389 * Only validates the header of the table.
390 * Note that Length contains the size of the mapping after invoking
391 * this work around, this value is required by
392 * acpi_tb_release_temp_table().
393 * We can do this because in acpi_init_table_descriptor(), the Length
394 * field of the installed descriptor is filled with the actual
395 * table length obtaining from the table header.
396 */
397 table_desc->length = sizeof(struct acpi_table_header);
398 }
399
400 return (acpi_tb_validate_table(table_desc));
401}
402
403/*******************************************************************************
404 *
405 * FUNCTION: acpi_tb_check_duplication
406 *
407 * PARAMETERS: table_desc - Table descriptor
408 * table_index - Where the table index is returned
409 *
410 * RETURN: Status
411 *
412 * DESCRIPTION: Avoid installing duplicated tables. However table override and
413 * user aided dynamic table load is allowed, thus comparing the
414 * address of the table is not sufficient, and checking the entire
415 * table content is required.
416 *
417 ******************************************************************************/
418
419static acpi_status
420acpi_tb_check_duplication(struct acpi_table_desc *table_desc, u32 *table_index)
421{
422 u32 i;
423
424 ACPI_FUNCTION_TRACE(tb_check_duplication);
425
426 /* Check if table is already registered */
427
428 for (i = 0; i < acpi_gbl_root_table_list.current_table_count; ++i) {
429
430 /* Do not compare with unverified tables */
431
432 if (!
433 (acpi_gbl_root_table_list.tables[i].
434 flags & ACPI_TABLE_IS_VERIFIED)) {
435 continue;
436 }
437
438 /*
439 * Check for a table match on the entire table length,
440 * not just the header.
441 */
442 if (!acpi_tb_compare_tables(table_desc, table_index: i)) {
443 continue;
444 }
445
446 /*
447 * Note: the current mechanism does not unregister a table if it is
448 * dynamically unloaded. The related namespace entries are deleted,
449 * but the table remains in the root table list.
450 *
451 * The assumption here is that the number of different tables that
452 * will be loaded is actually small, and there is minimal overhead
453 * in just keeping the table in case it is needed again.
454 *
455 * If this assumption changes in the future (perhaps on large
456 * machines with many table load/unload operations), tables will
457 * need to be unregistered when they are unloaded, and slots in the
458 * root table list should be reused when empty.
459 */
460 if (acpi_gbl_root_table_list.tables[i].flags &
461 ACPI_TABLE_IS_LOADED) {
462
463 /* Table is still loaded, this is an error */
464
465 return_ACPI_STATUS(AE_ALREADY_EXISTS);
466 } else {
467 *table_index = i;
468 return_ACPI_STATUS(AE_CTRL_TERMINATE);
469 }
470 }
471
472 /* Indicate no duplication to the caller */
473
474 return_ACPI_STATUS(AE_OK);
475}
476
477/******************************************************************************
478 *
479 * FUNCTION: acpi_tb_verify_temp_table
480 *
481 * PARAMETERS: table_desc - Table descriptor
482 * signature - Table signature to verify
483 * table_index - Where the table index is returned
484 *
485 * RETURN: Status
486 *
487 * DESCRIPTION: This function is called to validate and verify the table, the
488 * returned table descriptor is in "VALIDATED" state.
489 * Note that 'TableIndex' is required to be set to !NULL to
490 * enable duplication check.
491 *
492 *****************************************************************************/
493
494acpi_status
495acpi_tb_verify_temp_table(struct acpi_table_desc *table_desc,
496 char *signature, u32 *table_index)
497{
498 acpi_status status = AE_OK;
499
500 ACPI_FUNCTION_TRACE(tb_verify_temp_table);
501
502 /* Validate the table */
503
504 status = acpi_tb_validate_temp_table(table_desc);
505 if (ACPI_FAILURE(status)) {
506 return_ACPI_STATUS(AE_NO_MEMORY);
507 }
508
509 /* If a particular signature is expected (DSDT/FACS), it must match */
510
511 if (signature &&
512 !ACPI_COMPARE_NAMESEG(&table_desc->signature, signature)) {
513 ACPI_BIOS_ERROR((AE_INFO,
514 "Invalid signature 0x%X for ACPI table, expected [%s]",
515 table_desc->signature.integer, signature));
516 status = AE_BAD_SIGNATURE;
517 goto invalidate_and_exit;
518 }
519
520 if (acpi_gbl_enable_table_validation) {
521
522 /* Verify the checksum */
523
524 status =
525 acpi_ut_verify_checksum(table: table_desc->pointer,
526 length: table_desc->length);
527 if (ACPI_FAILURE(status)) {
528 ACPI_EXCEPTION((AE_INFO, AE_NO_MEMORY,
529 "%4.4s 0x%8.8X%8.8X"
530 " Attempted table install failed",
531 acpi_ut_valid_nameseg(table_desc->
532 signature.
533 ascii) ?
534 table_desc->signature.ascii : "????",
535 ACPI_FORMAT_UINT64(table_desc->
536 address)));
537
538 goto invalidate_and_exit;
539 }
540
541 /* Avoid duplications */
542
543 if (table_index) {
544 status =
545 acpi_tb_check_duplication(table_desc, table_index);
546 if (ACPI_FAILURE(status)) {
547 if (status != AE_CTRL_TERMINATE) {
548 ACPI_EXCEPTION((AE_INFO, status,
549 "%4.4s 0x%8.8X%8.8X"
550 " Table is already loaded",
551 acpi_ut_valid_nameseg
552 (table_desc->signature.
553 ascii) ? table_desc->
554 signature.
555 ascii : "????",
556 ACPI_FORMAT_UINT64
557 (table_desc->address)));
558 }
559
560 goto invalidate_and_exit;
561 }
562 }
563
564 table_desc->flags |= ACPI_TABLE_IS_VERIFIED;
565 }
566
567 return_ACPI_STATUS(status);
568
569invalidate_and_exit:
570 acpi_tb_invalidate_table(table_desc);
571 return_ACPI_STATUS(status);
572}
573
574/*******************************************************************************
575 *
576 * FUNCTION: acpi_tb_resize_root_table_list
577 *
578 * PARAMETERS: None
579 *
580 * RETURN: Status
581 *
582 * DESCRIPTION: Expand the size of global table array
583 *
584 ******************************************************************************/
585
586acpi_status acpi_tb_resize_root_table_list(void)
587{
588 struct acpi_table_desc *tables;
589 u32 table_count;
590 u32 current_table_count, max_table_count;
591 u32 i;
592
593 ACPI_FUNCTION_TRACE(tb_resize_root_table_list);
594
595 /* allow_resize flag is a parameter to acpi_initialize_tables */
596
597 if (!(acpi_gbl_root_table_list.flags & ACPI_ROOT_ALLOW_RESIZE)) {
598 ACPI_ERROR((AE_INFO,
599 "Resize of Root Table Array is not allowed"));
600 return_ACPI_STATUS(AE_SUPPORT);
601 }
602
603 /* Increase the Table Array size */
604
605 if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) {
606 table_count = acpi_gbl_root_table_list.max_table_count;
607 } else {
608 table_count = acpi_gbl_root_table_list.current_table_count;
609 }
610
611 max_table_count = table_count + ACPI_ROOT_TABLE_SIZE_INCREMENT;
612 tables = ACPI_ALLOCATE_ZEROED(((acpi_size)max_table_count) *
613 sizeof(struct acpi_table_desc));
614 if (!tables) {
615 ACPI_ERROR((AE_INFO,
616 "Could not allocate new root table array"));
617 return_ACPI_STATUS(AE_NO_MEMORY);
618 }
619
620 /* Copy and free the previous table array */
621
622 current_table_count = 0;
623 if (acpi_gbl_root_table_list.tables) {
624 for (i = 0; i < table_count; i++) {
625 if (acpi_gbl_root_table_list.tables[i].address) {
626 memcpy(tables + current_table_count,
627 acpi_gbl_root_table_list.tables + i,
628 sizeof(struct acpi_table_desc));
629 current_table_count++;
630 }
631 }
632
633 if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) {
634 ACPI_FREE(acpi_gbl_root_table_list.tables);
635 }
636 }
637
638 acpi_gbl_root_table_list.tables = tables;
639 acpi_gbl_root_table_list.max_table_count = max_table_count;
640 acpi_gbl_root_table_list.current_table_count = current_table_count;
641 acpi_gbl_root_table_list.flags |= ACPI_ROOT_ORIGIN_ALLOCATED;
642
643 return_ACPI_STATUS(AE_OK);
644}
645
646/*******************************************************************************
647 *
648 * FUNCTION: acpi_tb_get_next_table_descriptor
649 *
650 * PARAMETERS: table_index - Where table index is returned
651 * table_desc - Where table descriptor is returned
652 *
653 * RETURN: Status and table index/descriptor.
654 *
655 * DESCRIPTION: Allocate a new ACPI table entry to the global table list
656 *
657 ******************************************************************************/
658
659acpi_status
660acpi_tb_get_next_table_descriptor(u32 *table_index,
661 struct acpi_table_desc **table_desc)
662{
663 acpi_status status;
664 u32 i;
665
666 /* Ensure that there is room for the table in the Root Table List */
667
668 if (acpi_gbl_root_table_list.current_table_count >=
669 acpi_gbl_root_table_list.max_table_count) {
670 status = acpi_tb_resize_root_table_list();
671 if (ACPI_FAILURE(status)) {
672 return (status);
673 }
674 }
675
676 i = acpi_gbl_root_table_list.current_table_count;
677 acpi_gbl_root_table_list.current_table_count++;
678
679 if (table_index) {
680 *table_index = i;
681 }
682 if (table_desc) {
683 *table_desc = &acpi_gbl_root_table_list.tables[i];
684 }
685
686 return (AE_OK);
687}
688
689/*******************************************************************************
690 *
691 * FUNCTION: acpi_tb_terminate
692 *
693 * PARAMETERS: None
694 *
695 * RETURN: None
696 *
697 * DESCRIPTION: Delete all internal ACPI tables
698 *
699 ******************************************************************************/
700
701void acpi_tb_terminate(void)
702{
703 u32 i;
704
705 ACPI_FUNCTION_TRACE(tb_terminate);
706
707 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
708
709 /* Delete the individual tables */
710
711 for (i = 0; i < acpi_gbl_root_table_list.current_table_count; i++) {
712 acpi_tb_uninstall_table(table_desc: &acpi_gbl_root_table_list.tables[i]);
713 }
714
715 /*
716 * Delete the root table array if allocated locally. Array cannot be
717 * mapped, so we don't need to check for that flag.
718 */
719 if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) {
720 ACPI_FREE(acpi_gbl_root_table_list.tables);
721 }
722
723 acpi_gbl_root_table_list.tables = NULL;
724 acpi_gbl_root_table_list.flags = 0;
725 acpi_gbl_root_table_list.current_table_count = 0;
726
727 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "ACPI Tables freed\n"));
728
729 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
730 return_VOID;
731}
732
733/*******************************************************************************
734 *
735 * FUNCTION: acpi_tb_delete_namespace_by_owner
736 *
737 * PARAMETERS: table_index - Table index
738 *
739 * RETURN: Status
740 *
741 * DESCRIPTION: Delete all namespace objects created when this table was loaded.
742 *
743 ******************************************************************************/
744
745acpi_status acpi_tb_delete_namespace_by_owner(u32 table_index)
746{
747 acpi_owner_id owner_id;
748 acpi_status status;
749
750 ACPI_FUNCTION_TRACE(tb_delete_namespace_by_owner);
751
752 status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
753 if (ACPI_FAILURE(status)) {
754 return_ACPI_STATUS(status);
755 }
756
757 if (table_index >= acpi_gbl_root_table_list.current_table_count) {
758
759 /* The table index does not exist */
760
761 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
762 return_ACPI_STATUS(AE_NOT_EXIST);
763 }
764
765 /* Get the owner ID for this table, used to delete namespace nodes */
766
767 owner_id = acpi_gbl_root_table_list.tables[table_index].owner_id;
768 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
769
770 /*
771 * Need to acquire the namespace writer lock to prevent interference
772 * with any concurrent namespace walks. The interpreter must be
773 * released during the deletion since the acquisition of the deletion
774 * lock may block, and also since the execution of a namespace walk
775 * must be allowed to use the interpreter.
776 */
777 status = acpi_ut_acquire_write_lock(lock: &acpi_gbl_namespace_rw_lock);
778 if (ACPI_FAILURE(status)) {
779 return_ACPI_STATUS(status);
780 }
781
782 acpi_ns_delete_namespace_by_owner(owner_id);
783 acpi_ut_release_write_lock(lock: &acpi_gbl_namespace_rw_lock);
784 return_ACPI_STATUS(status);
785}
786
787/*******************************************************************************
788 *
789 * FUNCTION: acpi_tb_allocate_owner_id
790 *
791 * PARAMETERS: table_index - Table index
792 *
793 * RETURN: Status
794 *
795 * DESCRIPTION: Allocates owner_id in table_desc
796 *
797 ******************************************************************************/
798
799acpi_status acpi_tb_allocate_owner_id(u32 table_index)
800{
801 acpi_status status = AE_BAD_PARAMETER;
802
803 ACPI_FUNCTION_TRACE(tb_allocate_owner_id);
804
805 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
806 if (table_index < acpi_gbl_root_table_list.current_table_count) {
807 status =
808 acpi_ut_allocate_owner_id(owner_id: &
809 (acpi_gbl_root_table_list.
810 tables[table_index].owner_id));
811 }
812
813 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
814 return_ACPI_STATUS(status);
815}
816
817/*******************************************************************************
818 *
819 * FUNCTION: acpi_tb_release_owner_id
820 *
821 * PARAMETERS: table_index - Table index
822 *
823 * RETURN: Status
824 *
825 * DESCRIPTION: Releases owner_id in table_desc
826 *
827 ******************************************************************************/
828
829acpi_status acpi_tb_release_owner_id(u32 table_index)
830{
831 acpi_status status = AE_BAD_PARAMETER;
832
833 ACPI_FUNCTION_TRACE(tb_release_owner_id);
834
835 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
836 if (table_index < acpi_gbl_root_table_list.current_table_count) {
837 acpi_ut_release_owner_id(owner_id: &
838 (acpi_gbl_root_table_list.
839 tables[table_index].owner_id));
840 status = AE_OK;
841 }
842
843 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
844 return_ACPI_STATUS(status);
845}
846
847/*******************************************************************************
848 *
849 * FUNCTION: acpi_tb_get_owner_id
850 *
851 * PARAMETERS: table_index - Table index
852 * owner_id - Where the table owner_id is returned
853 *
854 * RETURN: Status
855 *
856 * DESCRIPTION: returns owner_id for the ACPI table
857 *
858 ******************************************************************************/
859
860acpi_status acpi_tb_get_owner_id(u32 table_index, acpi_owner_id *owner_id)
861{
862 acpi_status status = AE_BAD_PARAMETER;
863
864 ACPI_FUNCTION_TRACE(tb_get_owner_id);
865
866 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
867 if (table_index < acpi_gbl_root_table_list.current_table_count) {
868 *owner_id =
869 acpi_gbl_root_table_list.tables[table_index].owner_id;
870 status = AE_OK;
871 }
872
873 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
874 return_ACPI_STATUS(status);
875}
876
877/*******************************************************************************
878 *
879 * FUNCTION: acpi_tb_is_table_loaded
880 *
881 * PARAMETERS: table_index - Index into the root table
882 *
883 * RETURN: Table Loaded Flag
884 *
885 ******************************************************************************/
886
887u8 acpi_tb_is_table_loaded(u32 table_index)
888{
889 u8 is_loaded = FALSE;
890
891 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
892 if (table_index < acpi_gbl_root_table_list.current_table_count) {
893 is_loaded = (u8)
894 (acpi_gbl_root_table_list.tables[table_index].flags &
895 ACPI_TABLE_IS_LOADED);
896 }
897
898 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
899 return (is_loaded);
900}
901
902/*******************************************************************************
903 *
904 * FUNCTION: acpi_tb_set_table_loaded_flag
905 *
906 * PARAMETERS: table_index - Table index
907 * is_loaded - TRUE if table is loaded, FALSE otherwise
908 *
909 * RETURN: None
910 *
911 * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE.
912 *
913 ******************************************************************************/
914
915void acpi_tb_set_table_loaded_flag(u32 table_index, u8 is_loaded)
916{
917
918 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
919 if (table_index < acpi_gbl_root_table_list.current_table_count) {
920 if (is_loaded) {
921 acpi_gbl_root_table_list.tables[table_index].flags |=
922 ACPI_TABLE_IS_LOADED;
923 } else {
924 acpi_gbl_root_table_list.tables[table_index].flags &=
925 ~ACPI_TABLE_IS_LOADED;
926 }
927 }
928
929 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
930}
931
932/*******************************************************************************
933 *
934 * FUNCTION: acpi_tb_load_table
935 *
936 * PARAMETERS: table_index - Table index
937 * parent_node - Where table index is returned
938 *
939 * RETURN: Status
940 *
941 * DESCRIPTION: Load an ACPI table
942 *
943 ******************************************************************************/
944
945acpi_status
946acpi_tb_load_table(u32 table_index, struct acpi_namespace_node *parent_node)
947{
948 struct acpi_table_header *table;
949 acpi_status status;
950 acpi_owner_id owner_id;
951
952 ACPI_FUNCTION_TRACE(tb_load_table);
953
954 /*
955 * Note: Now table is "INSTALLED", it must be validated before
956 * using.
957 */
958 status = acpi_get_table_by_index(table_index, out_table: &table);
959 if (ACPI_FAILURE(status)) {
960 return_ACPI_STATUS(status);
961 }
962
963 status = acpi_ns_load_table(table_index, node: parent_node);
964 if (ACPI_FAILURE(status)) {
965 return_ACPI_STATUS(status);
966 }
967
968 /*
969 * Update GPEs for any new _Lxx/_Exx methods. Ignore errors. The host is
970 * responsible for discovering any new wake GPEs by running _PRW methods
971 * that may have been loaded by this table.
972 */
973 status = acpi_tb_get_owner_id(table_index, owner_id: &owner_id);
974 if (ACPI_SUCCESS(status)) {
975 acpi_ev_update_gpes(table_owner_id: owner_id);
976 }
977
978 /* Invoke table handler */
979
980 acpi_tb_notify_table(ACPI_TABLE_EVENT_LOAD, table);
981 return_ACPI_STATUS(status);
982}
983
984/*******************************************************************************
985 *
986 * FUNCTION: acpi_tb_install_and_load_table
987 *
988 * PARAMETERS: address - Physical address of the table
989 * flags - Allocation flags of the table
990 * table - Pointer to the table (required for
991 * virtual origins, optional for
992 * physical)
993 * override - Whether override should be performed
994 * table_index - Where table index is returned
995 *
996 * RETURN: Status
997 *
998 * DESCRIPTION: Install and load an ACPI table
999 *
1000 ******************************************************************************/
1001
1002acpi_status
1003acpi_tb_install_and_load_table(acpi_physical_address address,
1004 u8 flags,
1005 struct acpi_table_header *table,
1006 u8 override, u32 *table_index)
1007{
1008 acpi_status status;
1009 u32 i;
1010
1011 ACPI_FUNCTION_TRACE(tb_install_and_load_table);
1012
1013 /* Install the table and load it into the namespace */
1014
1015 status = acpi_tb_install_standard_table(address, flags, table, TRUE,
1016 override, table_index: &i);
1017 if (ACPI_FAILURE(status)) {
1018 goto exit;
1019 }
1020
1021 status = acpi_tb_load_table(table_index: i, parent_node: acpi_gbl_root_node);
1022
1023exit:
1024 *table_index = i;
1025 return_ACPI_STATUS(status);
1026}
1027
1028ACPI_EXPORT_SYMBOL(acpi_tb_install_and_load_table)
1029
1030/*******************************************************************************
1031 *
1032 * FUNCTION: acpi_tb_unload_table
1033 *
1034 * PARAMETERS: table_index - Table index
1035 *
1036 * RETURN: Status
1037 *
1038 * DESCRIPTION: Unload an ACPI table
1039 *
1040 ******************************************************************************/
1041
1042acpi_status acpi_tb_unload_table(u32 table_index)
1043{
1044 acpi_status status = AE_OK;
1045 struct acpi_table_header *table;
1046
1047 ACPI_FUNCTION_TRACE(tb_unload_table);
1048
1049 /* Ensure the table is still loaded */
1050
1051 if (!acpi_tb_is_table_loaded(table_index)) {
1052 return_ACPI_STATUS(AE_NOT_EXIST);
1053 }
1054
1055 /* Invoke table handler */
1056
1057 status = acpi_get_table_by_index(table_index, out_table: &table);
1058 if (ACPI_SUCCESS(status)) {
1059 acpi_tb_notify_table(ACPI_TABLE_EVENT_UNLOAD, table);
1060 }
1061
1062 /* Delete the portion of the namespace owned by this table */
1063
1064 status = acpi_tb_delete_namespace_by_owner(table_index);
1065 if (ACPI_FAILURE(status)) {
1066 return_ACPI_STATUS(status);
1067 }
1068
1069 (void)acpi_tb_release_owner_id(table_index);
1070 acpi_tb_set_table_loaded_flag(table_index, FALSE);
1071 return_ACPI_STATUS(status);
1072}
1073
1074ACPI_EXPORT_SYMBOL(acpi_tb_unload_table)
1075
1076/*******************************************************************************
1077 *
1078 * FUNCTION: acpi_tb_notify_table
1079 *
1080 * PARAMETERS: event - Table event
1081 * table - Validated table pointer
1082 *
1083 * RETURN: None
1084 *
1085 * DESCRIPTION: Notify a table event to the users.
1086 *
1087 ******************************************************************************/
1088
1089void acpi_tb_notify_table(u32 event, void *table)
1090{
1091 /* Invoke table handler if present */
1092
1093 if (acpi_gbl_table_handler) {
1094 (void)acpi_gbl_table_handler(event, table,
1095 acpi_gbl_table_handler_context);
1096 }
1097}
1098

source code of linux/drivers/acpi/acpica/tbdata.c