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