Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.5.6.
   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}