1 /****************************************************************************** 2 * 3 * Module Name: tbinstal - ACPI table installation and removal 4 * 5 *****************************************************************************/ 6 7 /****************************************************************************** 8 * 9 * 1. Copyright Notice 10 * 11 * Some or all of this work - Copyright (c) 1999 - 2012, Intel Corp. 12 * All rights reserved. 13 * 14 * 2. License 15 * 16 * 2.1. This is your license from Intel Corp. under its intellectual property 17 * rights. You may have additional license terms from the party that provided 18 * you this software, covering your right to use that party's intellectual 19 * property rights. 20 * 21 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 22 * copy of the source code appearing in this file ("Covered Code") an 23 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 24 * base code distributed originally by Intel ("Original Intel Code") to copy, 25 * make derivatives, distribute, use and display any portion of the Covered 26 * Code in any form, with the right to sublicense such rights; and 27 * 28 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 29 * license (with the right to sublicense), under only those claims of Intel 30 * patents that are infringed by the Original Intel Code, to make, use, sell, 31 * offer to sell, and import the Covered Code and derivative works thereof 32 * solely to the minimum extent necessary to exercise the above copyright 33 * license, and in no event shall the patent license extend to any additions 34 * to or modifications of the Original Intel Code. No other license or right 35 * is granted directly or by implication, estoppel or otherwise; 36 * 37 * The above copyright and patent license is granted only if the following 38 * conditions are met: 39 * 40 * 3. Conditions 41 * 42 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 43 * Redistribution of source code of any substantial portion of the Covered 44 * Code or modification with rights to further distribute source must include 45 * the above Copyright Notice, the above License, this list of Conditions, 46 * and the following Disclaimer and Export Compliance provision. In addition, 47 * Licensee must cause all Covered Code to which Licensee contributes to 48 * contain a file documenting the changes Licensee made to create that Covered 49 * Code and the date of any change. Licensee must include in that file the 50 * documentation of any changes made by any predecessor Licensee. Licensee 51 * must include a prominent statement that the modification is derived, 52 * directly or indirectly, from Original Intel Code. 53 * 54 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 55 * Redistribution of source code of any substantial portion of the Covered 56 * Code or modification without rights to further distribute source must 57 * include the following Disclaimer and Export Compliance provision in the 58 * documentation and/or other materials provided with distribution. In 59 * addition, Licensee may not authorize further sublicense of source of any 60 * portion of the Covered Code, and must include terms to the effect that the 61 * license from Licensee to its licensee is limited to the intellectual 62 * property embodied in the software Licensee provides to its licensee, and 63 * not to intellectual property embodied in modifications its licensee may 64 * make. 65 * 66 * 3.3. Redistribution of Executable. Redistribution in executable form of any 67 * substantial portion of the Covered Code or modification must reproduce the 68 * above Copyright Notice, and the following Disclaimer and Export Compliance 69 * provision in the documentation and/or other materials provided with the 70 * distribution. 71 * 72 * 3.4. Intel retains all right, title, and interest in and to the Original 73 * Intel Code. 74 * 75 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 76 * Intel shall be used in advertising or otherwise to promote the sale, use or 77 * other dealings in products derived from or relating to the Covered Code 78 * without prior written authorization from Intel. 79 * 80 * 4. Disclaimer and Export Compliance 81 * 82 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 83 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 84 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 85 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 86 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 87 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 88 * PARTICULAR PURPOSE. 89 * 90 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 91 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 92 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 93 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 94 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 95 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 96 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 97 * LIMITED REMEDY. 98 * 99 * 4.3. Licensee shall not export, either directly or indirectly, any of this 100 * software or system incorporating such software without first obtaining any 101 * required license or other approval from the U. S. Department of Commerce or 102 * any other agency or department of the United States Government. In the 103 * event Licensee exports any such software from the United States or 104 * re-exports any such software from a foreign destination, Licensee shall 105 * ensure that the distribution and export/re-export of the software is in 106 * compliance with all laws, regulations, orders, or other restrictions of the 107 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 108 * any of its subsidiaries will export/re-export any technical data, process, 109 * software, or service, directly or indirectly, to any country for which the 110 * United States government or any agency thereof requires an export license, 111 * other governmental approval, or letter of assurance, without first obtaining 112 * such license, approval or letter. 113 * 114 *****************************************************************************/ 115 116 117 #define __TBINSTAL_C__ 118 119 #include "acpi.h" 120 #include "accommon.h" 121 #include "acnamesp.h" 122 #include "actables.h" 123 124 125 #define _COMPONENT ACPI_TABLES 126 ACPI_MODULE_NAME ("tbinstal") 127 128 129 /****************************************************************************** 130 * 131 * FUNCTION: AcpiTbVerifyTable 132 * 133 * PARAMETERS: TableDesc - table 134 * 135 * RETURN: Status 136 * 137 * DESCRIPTION: this function is called to verify and map table 138 * 139 *****************************************************************************/ 140 141 ACPI_STATUS 142 AcpiTbVerifyTable ( 143 ACPI_TABLE_DESC *TableDesc) 144 { 145 ACPI_STATUS Status = AE_OK; 146 147 148 ACPI_FUNCTION_TRACE (TbVerifyTable); 149 150 151 /* Map the table if necessary */ 152 153 if (!TableDesc->Pointer) 154 { 155 if ((TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK) == 156 ACPI_TABLE_ORIGIN_MAPPED) 157 { 158 TableDesc->Pointer = AcpiOsMapMemory ( 159 TableDesc->Address, TableDesc->Length); 160 } 161 162 if (!TableDesc->Pointer) 163 { 164 return_ACPI_STATUS (AE_NO_MEMORY); 165 } 166 } 167 168 /* FACS is the odd table, has no standard ACPI header and no checksum */ 169 170 if (!ACPI_COMPARE_NAME (&TableDesc->Signature, ACPI_SIG_FACS)) 171 { 172 /* Always calculate checksum, ignore bad checksum if requested */ 173 174 Status = AcpiTbVerifyChecksum (TableDesc->Pointer, TableDesc->Length); 175 } 176 177 return_ACPI_STATUS (Status); 178 } 179 180 181 /******************************************************************************* 182 * 183 * FUNCTION: AcpiTbAddTable 184 * 185 * PARAMETERS: TableDesc - Table descriptor 186 * TableIndex - Where the table index is returned 187 * 188 * RETURN: Status 189 * 190 * DESCRIPTION: This function is called to add an ACPI table. It is used to 191 * dynamically load tables via the Load and LoadTable AML 192 * operators. 193 * 194 ******************************************************************************/ 195 196 ACPI_STATUS 197 AcpiTbAddTable ( 198 ACPI_TABLE_DESC *TableDesc, 199 UINT32 *TableIndex) 200 { 201 UINT32 i; 202 ACPI_STATUS Status = AE_OK; 203 204 205 ACPI_FUNCTION_TRACE (TbAddTable); 206 207 208 if (!TableDesc->Pointer) 209 { 210 Status = AcpiTbVerifyTable (TableDesc); 211 if (ACPI_FAILURE (Status) || !TableDesc->Pointer) 212 { 213 return_ACPI_STATUS (Status); 214 } 215 } 216 217 /* 218 * Validate the incoming table signature. 219 * 220 * 1) Originally, we checked the table signature for "SSDT" or "PSDT". 221 * 2) We added support for OEMx tables, signature "OEM". 222 * 3) Valid tables were encountered with a null signature, so we just 223 * gave up on validating the signature, (05/2008). 224 * 4) We encountered non-AML tables such as the MADT, which caused 225 * interpreter errors and kernel faults. So now, we once again allow 226 * only "SSDT", "OEMx", and now, also a null signature. (05/2011). 227 */ 228 if ((TableDesc->Pointer->Signature[0] != 0x00) && 229 (!ACPI_COMPARE_NAME (TableDesc->Pointer->Signature, ACPI_SIG_SSDT)) && 230 (ACPI_STRNCMP (TableDesc->Pointer->Signature, "OEM", 3))) 231 { 232 ACPI_BIOS_ERROR ((AE_INFO, 233 "Table has invalid signature [%4.4s] (0x%8.8X), " 234 "must be SSDT or OEMx", 235 AcpiUtValidAcpiName (*(UINT32 *) TableDesc->Pointer->Signature) ? 236 TableDesc->Pointer->Signature : "????", 237 *(UINT32 *) TableDesc->Pointer->Signature)); 238 239 return_ACPI_STATUS (AE_BAD_SIGNATURE); 240 } 241 242 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 243 244 /* Check if table is already registered */ 245 246 for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; ++i) 247 { 248 if (!AcpiGbl_RootTableList.Tables[i].Pointer) 249 { 250 Status = AcpiTbVerifyTable (&AcpiGbl_RootTableList.Tables[i]); 251 if (ACPI_FAILURE (Status) || 252 !AcpiGbl_RootTableList.Tables[i].Pointer) 253 { 254 continue; 255 } 256 } 257 258 /* 259 * Check for a table match on the entire table length, 260 * not just the header. 261 */ 262 if (TableDesc->Length != AcpiGbl_RootTableList.Tables[i].Length) 263 { 264 continue; 265 } 266 267 if (ACPI_MEMCMP (TableDesc->Pointer, 268 AcpiGbl_RootTableList.Tables[i].Pointer, 269 AcpiGbl_RootTableList.Tables[i].Length)) 270 { 271 continue; 272 } 273 274 /* 275 * Note: the current mechanism does not unregister a table if it is 276 * dynamically unloaded. The related namespace entries are deleted, 277 * but the table remains in the root table list. 278 * 279 * The assumption here is that the number of different tables that 280 * will be loaded is actually small, and there is minimal overhead 281 * in just keeping the table in case it is needed again. 282 * 283 * If this assumption changes in the future (perhaps on large 284 * machines with many table load/unload operations), tables will 285 * need to be unregistered when they are unloaded, and slots in the 286 * root table list should be reused when empty. 287 */ 288 289 /* 290 * Table is already registered. 291 * We can delete the table that was passed as a parameter. 292 */ 293 AcpiTbDeleteTable (TableDesc); 294 *TableIndex = i; 295 296 if (AcpiGbl_RootTableList.Tables[i].Flags & ACPI_TABLE_IS_LOADED) 297 { 298 /* Table is still loaded, this is an error */ 299 300 Status = AE_ALREADY_EXISTS; 301 goto Release; 302 } 303 else 304 { 305 /* Table was unloaded, allow it to be reloaded */ 306 307 TableDesc->Pointer = AcpiGbl_RootTableList.Tables[i].Pointer; 308 TableDesc->Address = AcpiGbl_RootTableList.Tables[i].Address; 309 Status = AE_OK; 310 goto PrintHeader; 311 } 312 } 313 314 /* 315 * ACPI Table Override: 316 * Allow the host to override dynamically loaded tables. 317 * NOTE: the table is fully mapped at this point, and the mapping will 318 * be deleted by TbTableOverride if the table is actually overridden. 319 */ 320 (void) AcpiTbTableOverride (TableDesc->Pointer, TableDesc); 321 322 /* Add the table to the global root table list */ 323 324 Status = AcpiTbStoreTable (TableDesc->Address, TableDesc->Pointer, 325 TableDesc->Length, TableDesc->Flags, TableIndex); 326 if (ACPI_FAILURE (Status)) 327 { 328 goto Release; 329 } 330 331 PrintHeader: 332 AcpiTbPrintTableHeader (TableDesc->Address, TableDesc->Pointer); 333 334 Release: 335 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 336 return_ACPI_STATUS (Status); 337 } 338 339 340 /******************************************************************************* 341 * 342 * FUNCTION: AcpiTbTableOverride 343 * 344 * PARAMETERS: TableHeader - Header for the original table 345 * TableDesc - Table descriptor initialized for the 346 * original table. May or may not be mapped. 347 * 348 * RETURN: Pointer to the entire new table. NULL if table not overridden. 349 * If overridden, installs the new table within the input table 350 * descriptor. 351 * 352 * DESCRIPTION: Attempt table override by calling the OSL override functions. 353 * Note: If the table is overridden, then the entire new table 354 * is mapped and returned by this function. 355 * 356 ******************************************************************************/ 357 358 ACPI_TABLE_HEADER * 359 AcpiTbTableOverride ( 360 ACPI_TABLE_HEADER *TableHeader, 361 ACPI_TABLE_DESC *TableDesc) 362 { 363 ACPI_STATUS Status; 364 ACPI_TABLE_HEADER *NewTable = NULL; 365 ACPI_PHYSICAL_ADDRESS NewAddress = 0; 366 UINT32 NewTableLength = 0; 367 UINT8 NewFlags; 368 char *OverrideType; 369 370 371 /* (1) Attempt logical override (returns a logical address) */ 372 373 Status = AcpiOsTableOverride (TableHeader, &NewTable); 374 if (ACPI_SUCCESS (Status) && NewTable) 375 { 376 NewAddress = ACPI_PTR_TO_PHYSADDR (NewTable); 377 NewTableLength = NewTable->Length; 378 NewFlags = ACPI_TABLE_ORIGIN_OVERRIDE; 379 OverrideType = "Logical"; 380 goto FinishOverride; 381 } 382 383 /* (2) Attempt physical override (returns a physical address) */ 384 385 Status = AcpiOsPhysicalTableOverride (TableHeader, 386 &NewAddress, &NewTableLength); 387 if (ACPI_SUCCESS (Status) && NewAddress && NewTableLength) 388 { 389 /* Map the entire new table */ 390 391 NewTable = AcpiOsMapMemory (NewAddress, NewTableLength); 392 if (!NewTable) 393 { 394 ACPI_EXCEPTION ((AE_INFO, AE_NO_MEMORY, 395 "%4.4s %p Attempted physical table override failed", 396 TableHeader->Signature, 397 ACPI_CAST_PTR (void, TableDesc->Address))); 398 return (NULL); 399 } 400 401 OverrideType = "Physical"; 402 NewFlags = ACPI_TABLE_ORIGIN_MAPPED; 403 goto FinishOverride; 404 } 405 406 return (NULL); /* There was no override */ 407 408 409 FinishOverride: 410 411 ACPI_INFO ((AE_INFO, 412 "%4.4s %p %s table override, new table: %p", 413 TableHeader->Signature, 414 ACPI_CAST_PTR (void, TableDesc->Address), 415 OverrideType, NewTable)); 416 417 /* We can now unmap/delete the original table (if fully mapped) */ 418 419 AcpiTbDeleteTable (TableDesc); 420 421 /* Setup descriptor for the new table */ 422 423 TableDesc->Address = NewAddress; 424 TableDesc->Pointer = NewTable; 425 TableDesc->Length = NewTableLength; 426 TableDesc->Flags = NewFlags; 427 428 return (NewTable); 429 } 430 431 432 /******************************************************************************* 433 * 434 * FUNCTION: AcpiTbResizeRootTableList 435 * 436 * PARAMETERS: None 437 * 438 * RETURN: Status 439 * 440 * DESCRIPTION: Expand the size of global table array 441 * 442 ******************************************************************************/ 443 444 ACPI_STATUS 445 AcpiTbResizeRootTableList ( 446 void) 447 { 448 ACPI_TABLE_DESC *Tables; 449 UINT32 TableCount; 450 451 452 ACPI_FUNCTION_TRACE (TbResizeRootTableList); 453 454 455 /* AllowResize flag is a parameter to AcpiInitializeTables */ 456 457 if (!(AcpiGbl_RootTableList.Flags & ACPI_ROOT_ALLOW_RESIZE)) 458 { 459 ACPI_ERROR ((AE_INFO, "Resize of Root Table Array is not allowed")); 460 return_ACPI_STATUS (AE_SUPPORT); 461 } 462 463 /* Increase the Table Array size */ 464 465 if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED) 466 { 467 TableCount = AcpiGbl_RootTableList.MaxTableCount; 468 } 469 else 470 { 471 TableCount = AcpiGbl_RootTableList.CurrentTableCount; 472 } 473 474 Tables = ACPI_ALLOCATE_ZEROED ( 475 ((ACPI_SIZE) TableCount + ACPI_ROOT_TABLE_SIZE_INCREMENT) * 476 sizeof (ACPI_TABLE_DESC)); 477 if (!Tables) 478 { 479 ACPI_ERROR ((AE_INFO, "Could not allocate new root table array")); 480 return_ACPI_STATUS (AE_NO_MEMORY); 481 } 482 483 /* Copy and free the previous table array */ 484 485 if (AcpiGbl_RootTableList.Tables) 486 { 487 ACPI_MEMCPY (Tables, AcpiGbl_RootTableList.Tables, 488 (ACPI_SIZE) TableCount * sizeof (ACPI_TABLE_DESC)); 489 490 if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED) 491 { 492 ACPI_FREE (AcpiGbl_RootTableList.Tables); 493 } 494 } 495 496 AcpiGbl_RootTableList.Tables = Tables; 497 AcpiGbl_RootTableList.MaxTableCount = 498 TableCount + ACPI_ROOT_TABLE_SIZE_INCREMENT; 499 AcpiGbl_RootTableList.Flags |= ACPI_ROOT_ORIGIN_ALLOCATED; 500 501 return_ACPI_STATUS (AE_OK); 502 } 503 504 505 /******************************************************************************* 506 * 507 * FUNCTION: AcpiTbStoreTable 508 * 509 * PARAMETERS: Address - Table address 510 * Table - Table header 511 * Length - Table length 512 * Flags - flags 513 * 514 * RETURN: Status and table index. 515 * 516 * DESCRIPTION: Add an ACPI table to the global table list 517 * 518 ******************************************************************************/ 519 520 ACPI_STATUS 521 AcpiTbStoreTable ( 522 ACPI_PHYSICAL_ADDRESS Address, 523 ACPI_TABLE_HEADER *Table, 524 UINT32 Length, 525 UINT8 Flags, 526 UINT32 *TableIndex) 527 { 528 ACPI_STATUS Status; 529 ACPI_TABLE_DESC *NewTable; 530 531 532 /* Ensure that there is room for the table in the Root Table List */ 533 534 if (AcpiGbl_RootTableList.CurrentTableCount >= 535 AcpiGbl_RootTableList.MaxTableCount) 536 { 537 Status = AcpiTbResizeRootTableList(); 538 if (ACPI_FAILURE (Status)) 539 { 540 return (Status); 541 } 542 } 543 544 NewTable = &AcpiGbl_RootTableList.Tables[AcpiGbl_RootTableList.CurrentTableCount]; 545 546 /* Initialize added table */ 547 548 NewTable->Address = Address; 549 NewTable->Pointer = Table; 550 NewTable->Length = Length; 551 NewTable->OwnerId = 0; 552 NewTable->Flags = Flags; 553 554 ACPI_MOVE_32_TO_32 (&NewTable->Signature, Table->Signature); 555 556 *TableIndex = AcpiGbl_RootTableList.CurrentTableCount; 557 AcpiGbl_RootTableList.CurrentTableCount++; 558 return (AE_OK); 559 } 560 561 562 /******************************************************************************* 563 * 564 * FUNCTION: AcpiTbDeleteTable 565 * 566 * PARAMETERS: TableIndex - Table index 567 * 568 * RETURN: None 569 * 570 * DESCRIPTION: Delete one internal ACPI table 571 * 572 ******************************************************************************/ 573 574 void 575 AcpiTbDeleteTable ( 576 ACPI_TABLE_DESC *TableDesc) 577 { 578 579 /* Table must be mapped or allocated */ 580 581 if (!TableDesc->Pointer) 582 { 583 return; 584 } 585 586 switch (TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK) 587 { 588 case ACPI_TABLE_ORIGIN_MAPPED: 589 AcpiOsUnmapMemory (TableDesc->Pointer, TableDesc->Length); 590 break; 591 592 case ACPI_TABLE_ORIGIN_ALLOCATED: 593 ACPI_FREE (TableDesc->Pointer); 594 break; 595 596 /* Not mapped or allocated, there is nothing we can do */ 597 598 default: 599 return; 600 } 601 602 TableDesc->Pointer = NULL; 603 } 604 605 606 /******************************************************************************* 607 * 608 * FUNCTION: AcpiTbTerminate 609 * 610 * PARAMETERS: None 611 * 612 * RETURN: None 613 * 614 * DESCRIPTION: Delete all internal ACPI tables 615 * 616 ******************************************************************************/ 617 618 void 619 AcpiTbTerminate ( 620 void) 621 { 622 UINT32 i; 623 624 625 ACPI_FUNCTION_TRACE (TbTerminate); 626 627 628 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 629 630 /* Delete the individual tables */ 631 632 for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++) 633 { 634 AcpiTbDeleteTable (&AcpiGbl_RootTableList.Tables[i]); 635 } 636 637 /* 638 * Delete the root table array if allocated locally. Array cannot be 639 * mapped, so we don't need to check for that flag. 640 */ 641 if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED) 642 { 643 ACPI_FREE (AcpiGbl_RootTableList.Tables); 644 } 645 646 AcpiGbl_RootTableList.Tables = NULL; 647 AcpiGbl_RootTableList.Flags = 0; 648 AcpiGbl_RootTableList.CurrentTableCount = 0; 649 650 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "ACPI Tables freed\n")); 651 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 652 653 return_VOID; 654 } 655 656 657 /******************************************************************************* 658 * 659 * FUNCTION: AcpiTbDeleteNamespaceByOwner 660 * 661 * PARAMETERS: TableIndex - Table index 662 * 663 * RETURN: Status 664 * 665 * DESCRIPTION: Delete all namespace objects created when this table was loaded. 666 * 667 ******************************************************************************/ 668 669 ACPI_STATUS 670 AcpiTbDeleteNamespaceByOwner ( 671 UINT32 TableIndex) 672 { 673 ACPI_OWNER_ID OwnerId; 674 ACPI_STATUS Status; 675 676 677 ACPI_FUNCTION_TRACE (TbDeleteNamespaceByOwner); 678 679 680 Status = AcpiUtAcquireMutex (ACPI_MTX_TABLES); 681 if (ACPI_FAILURE (Status)) 682 { 683 return_ACPI_STATUS (Status); 684 } 685 686 if (TableIndex >= AcpiGbl_RootTableList.CurrentTableCount) 687 { 688 /* The table index does not exist */ 689 690 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 691 return_ACPI_STATUS (AE_NOT_EXIST); 692 } 693 694 /* Get the owner ID for this table, used to delete namespace nodes */ 695 696 OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId; 697 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 698 699 /* 700 * Need to acquire the namespace writer lock to prevent interference 701 * with any concurrent namespace walks. The interpreter must be 702 * released during the deletion since the acquisition of the deletion 703 * lock may block, and also since the execution of a namespace walk 704 * must be allowed to use the interpreter. 705 */ 706 (void) AcpiUtReleaseMutex (ACPI_MTX_INTERPRETER); 707 Status = AcpiUtAcquireWriteLock (&AcpiGbl_NamespaceRwLock); 708 709 AcpiNsDeleteNamespaceByOwner (OwnerId); 710 if (ACPI_FAILURE (Status)) 711 { 712 return_ACPI_STATUS (Status); 713 } 714 715 AcpiUtReleaseWriteLock (&AcpiGbl_NamespaceRwLock); 716 717 Status = AcpiUtAcquireMutex (ACPI_MTX_INTERPRETER); 718 return_ACPI_STATUS (Status); 719 } 720 721 722 /******************************************************************************* 723 * 724 * FUNCTION: AcpiTbAllocateOwnerId 725 * 726 * PARAMETERS: TableIndex - Table index 727 * 728 * RETURN: Status 729 * 730 * DESCRIPTION: Allocates OwnerId in TableDesc 731 * 732 ******************************************************************************/ 733 734 ACPI_STATUS 735 AcpiTbAllocateOwnerId ( 736 UINT32 TableIndex) 737 { 738 ACPI_STATUS Status = AE_BAD_PARAMETER; 739 740 741 ACPI_FUNCTION_TRACE (TbAllocateOwnerId); 742 743 744 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 745 if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) 746 { 747 Status = AcpiUtAllocateOwnerId 748 (&(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId)); 749 } 750 751 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 752 return_ACPI_STATUS (Status); 753 } 754 755 756 /******************************************************************************* 757 * 758 * FUNCTION: AcpiTbReleaseOwnerId 759 * 760 * PARAMETERS: TableIndex - Table index 761 * 762 * RETURN: Status 763 * 764 * DESCRIPTION: Releases OwnerId in TableDesc 765 * 766 ******************************************************************************/ 767 768 ACPI_STATUS 769 AcpiTbReleaseOwnerId ( 770 UINT32 TableIndex) 771 { 772 ACPI_STATUS Status = AE_BAD_PARAMETER; 773 774 775 ACPI_FUNCTION_TRACE (TbReleaseOwnerId); 776 777 778 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 779 if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) 780 { 781 AcpiUtReleaseOwnerId ( 782 &(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId)); 783 Status = AE_OK; 784 } 785 786 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 787 return_ACPI_STATUS (Status); 788 } 789 790 791 /******************************************************************************* 792 * 793 * FUNCTION: AcpiTbGetOwnerId 794 * 795 * PARAMETERS: TableIndex - Table index 796 * OwnerId - Where the table OwnerId is returned 797 * 798 * RETURN: Status 799 * 800 * DESCRIPTION: returns OwnerId for the ACPI table 801 * 802 ******************************************************************************/ 803 804 ACPI_STATUS 805 AcpiTbGetOwnerId ( 806 UINT32 TableIndex, 807 ACPI_OWNER_ID *OwnerId) 808 { 809 ACPI_STATUS Status = AE_BAD_PARAMETER; 810 811 812 ACPI_FUNCTION_TRACE (TbGetOwnerId); 813 814 815 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 816 if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) 817 { 818 *OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId; 819 Status = AE_OK; 820 } 821 822 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 823 return_ACPI_STATUS (Status); 824 } 825 826 827 /******************************************************************************* 828 * 829 * FUNCTION: AcpiTbIsTableLoaded 830 * 831 * PARAMETERS: TableIndex - Table index 832 * 833 * RETURN: Table Loaded Flag 834 * 835 ******************************************************************************/ 836 837 BOOLEAN 838 AcpiTbIsTableLoaded ( 839 UINT32 TableIndex) 840 { 841 BOOLEAN IsLoaded = FALSE; 842 843 844 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 845 if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) 846 { 847 IsLoaded = (BOOLEAN) 848 (AcpiGbl_RootTableList.Tables[TableIndex].Flags & 849 ACPI_TABLE_IS_LOADED); 850 } 851 852 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 853 return (IsLoaded); 854 } 855 856 857 /******************************************************************************* 858 * 859 * FUNCTION: AcpiTbSetTableLoadedFlag 860 * 861 * PARAMETERS: TableIndex - Table index 862 * IsLoaded - TRUE if table is loaded, FALSE otherwise 863 * 864 * RETURN: None 865 * 866 * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE. 867 * 868 ******************************************************************************/ 869 870 void 871 AcpiTbSetTableLoadedFlag ( 872 UINT32 TableIndex, 873 BOOLEAN IsLoaded) 874 { 875 876 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 877 if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) 878 { 879 if (IsLoaded) 880 { 881 AcpiGbl_RootTableList.Tables[TableIndex].Flags |= 882 ACPI_TABLE_IS_LOADED; 883 } 884 else 885 { 886 AcpiGbl_RootTableList.Tables[TableIndex].Flags &= 887 ~ACPI_TABLE_IS_LOADED; 888 } 889 } 890 891 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 892 } 893