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(&acpi_gbl_root_table_list.tables[table_index],
51				  &table, &table_length, &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(table_desc->pointer, table, 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(table_desc->address, 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(table, 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(address,
237					       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(table, 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_desc->pointer,
318					       &table_desc->length,
319					       &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_desc->pointer, table_desc->length,
353			      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, 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_desc->pointer,
526					    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(&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(&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(&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(&
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(&
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, &table);
959	if (ACPI_FAILURE(status)) {
960		return_ACPI_STATUS(status);
961	}
962
963	status = acpi_ns_load_table(table_index, 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);
974	if (ACPI_SUCCESS(status)) {
975		acpi_ev_update_gpes(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, &i);
1017	if (ACPI_FAILURE(status)) {
1018		goto exit;
1019	}
1020
1021	status = acpi_tb_load_table(i, 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, &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