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 450 451 ACPI_FUNCTION_TRACE (TbResizeRootTableList); 452 453 454 /* AllowResize flag is a parameter to AcpiInitializeTables */ 455 456 if (!(AcpiGbl_RootTableList.Flags & ACPI_ROOT_ALLOW_RESIZE)) 457 { 458 ACPI_ERROR ((AE_INFO, "Resize of Root Table Array is not allowed")); 459 return_ACPI_STATUS (AE_SUPPORT); 460 } 461 462 /* Increase the Table Array size */ 463 464 Tables = ACPI_ALLOCATE_ZEROED ( 465 ((ACPI_SIZE) AcpiGbl_RootTableList.MaxTableCount + 466 ACPI_ROOT_TABLE_SIZE_INCREMENT) * 467 sizeof (ACPI_TABLE_DESC)); 468 if (!Tables) 469 { 470 ACPI_ERROR ((AE_INFO, "Could not allocate new root table array")); 471 return_ACPI_STATUS (AE_NO_MEMORY); 472 } 473 474 /* Copy and free the previous table array */ 475 476 if (AcpiGbl_RootTableList.Tables) 477 { 478 ACPI_MEMCPY (Tables, AcpiGbl_RootTableList.Tables, 479 (ACPI_SIZE) AcpiGbl_RootTableList.MaxTableCount * sizeof (ACPI_TABLE_DESC)); 480 481 if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED) 482 { 483 ACPI_FREE (AcpiGbl_RootTableList.Tables); 484 } 485 } 486 487 AcpiGbl_RootTableList.Tables = Tables; 488 AcpiGbl_RootTableList.MaxTableCount += ACPI_ROOT_TABLE_SIZE_INCREMENT; 489 AcpiGbl_RootTableList.Flags |= (UINT8) ACPI_ROOT_ORIGIN_ALLOCATED; 490 491 return_ACPI_STATUS (AE_OK); 492 } 493 494 495 /******************************************************************************* 496 * 497 * FUNCTION: AcpiTbStoreTable 498 * 499 * PARAMETERS: Address - Table address 500 * Table - Table header 501 * Length - Table length 502 * Flags - flags 503 * 504 * RETURN: Status and table index. 505 * 506 * DESCRIPTION: Add an ACPI table to the global table list 507 * 508 ******************************************************************************/ 509 510 ACPI_STATUS 511 AcpiTbStoreTable ( 512 ACPI_PHYSICAL_ADDRESS Address, 513 ACPI_TABLE_HEADER *Table, 514 UINT32 Length, 515 UINT8 Flags, 516 UINT32 *TableIndex) 517 { 518 ACPI_STATUS Status; 519 ACPI_TABLE_DESC *NewTable; 520 521 522 /* Ensure that there is room for the table in the Root Table List */ 523 524 if (AcpiGbl_RootTableList.CurrentTableCount >= 525 AcpiGbl_RootTableList.MaxTableCount) 526 { 527 Status = AcpiTbResizeRootTableList(); 528 if (ACPI_FAILURE (Status)) 529 { 530 return (Status); 531 } 532 } 533 534 NewTable = &AcpiGbl_RootTableList.Tables[AcpiGbl_RootTableList.CurrentTableCount]; 535 536 /* Initialize added table */ 537 538 NewTable->Address = Address; 539 NewTable->Pointer = Table; 540 NewTable->Length = Length; 541 NewTable->OwnerId = 0; 542 NewTable->Flags = Flags; 543 544 ACPI_MOVE_32_TO_32 (&NewTable->Signature, Table->Signature); 545 546 *TableIndex = AcpiGbl_RootTableList.CurrentTableCount; 547 AcpiGbl_RootTableList.CurrentTableCount++; 548 return (AE_OK); 549 } 550 551 552 /******************************************************************************* 553 * 554 * FUNCTION: AcpiTbDeleteTable 555 * 556 * PARAMETERS: TableIndex - Table index 557 * 558 * RETURN: None 559 * 560 * DESCRIPTION: Delete one internal ACPI table 561 * 562 ******************************************************************************/ 563 564 void 565 AcpiTbDeleteTable ( 566 ACPI_TABLE_DESC *TableDesc) 567 { 568 569 /* Table must be mapped or allocated */ 570 571 if (!TableDesc->Pointer) 572 { 573 return; 574 } 575 576 switch (TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK) 577 { 578 case ACPI_TABLE_ORIGIN_MAPPED: 579 AcpiOsUnmapMemory (TableDesc->Pointer, TableDesc->Length); 580 break; 581 582 case ACPI_TABLE_ORIGIN_ALLOCATED: 583 ACPI_FREE (TableDesc->Pointer); 584 break; 585 586 /* Not mapped or allocated, there is nothing we can do */ 587 588 default: 589 return; 590 } 591 592 TableDesc->Pointer = NULL; 593 } 594 595 596 /******************************************************************************* 597 * 598 * FUNCTION: AcpiTbTerminate 599 * 600 * PARAMETERS: None 601 * 602 * RETURN: None 603 * 604 * DESCRIPTION: Delete all internal ACPI tables 605 * 606 ******************************************************************************/ 607 608 void 609 AcpiTbTerminate ( 610 void) 611 { 612 UINT32 i; 613 614 615 ACPI_FUNCTION_TRACE (TbTerminate); 616 617 618 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 619 620 /* Delete the individual tables */ 621 622 for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++) 623 { 624 AcpiTbDeleteTable (&AcpiGbl_RootTableList.Tables[i]); 625 } 626 627 /* 628 * Delete the root table array if allocated locally. Array cannot be 629 * mapped, so we don't need to check for that flag. 630 */ 631 if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED) 632 { 633 ACPI_FREE (AcpiGbl_RootTableList.Tables); 634 } 635 636 AcpiGbl_RootTableList.Tables = NULL; 637 AcpiGbl_RootTableList.Flags = 0; 638 AcpiGbl_RootTableList.CurrentTableCount = 0; 639 640 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "ACPI Tables freed\n")); 641 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 642 } 643 644 645 /******************************************************************************* 646 * 647 * FUNCTION: AcpiTbDeleteNamespaceByOwner 648 * 649 * PARAMETERS: TableIndex - Table index 650 * 651 * RETURN: Status 652 * 653 * DESCRIPTION: Delete all namespace objects created when this table was loaded. 654 * 655 ******************************************************************************/ 656 657 ACPI_STATUS 658 AcpiTbDeleteNamespaceByOwner ( 659 UINT32 TableIndex) 660 { 661 ACPI_OWNER_ID OwnerId; 662 ACPI_STATUS Status; 663 664 665 ACPI_FUNCTION_TRACE (TbDeleteNamespaceByOwner); 666 667 668 Status = AcpiUtAcquireMutex (ACPI_MTX_TABLES); 669 if (ACPI_FAILURE (Status)) 670 { 671 return_ACPI_STATUS (Status); 672 } 673 674 if (TableIndex >= AcpiGbl_RootTableList.CurrentTableCount) 675 { 676 /* The table index does not exist */ 677 678 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 679 return_ACPI_STATUS (AE_NOT_EXIST); 680 } 681 682 /* Get the owner ID for this table, used to delete namespace nodes */ 683 684 OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId; 685 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 686 687 /* 688 * Need to acquire the namespace writer lock to prevent interference 689 * with any concurrent namespace walks. The interpreter must be 690 * released during the deletion since the acquisition of the deletion 691 * lock may block, and also since the execution of a namespace walk 692 * must be allowed to use the interpreter. 693 */ 694 (void) AcpiUtReleaseMutex (ACPI_MTX_INTERPRETER); 695 Status = AcpiUtAcquireWriteLock (&AcpiGbl_NamespaceRwLock); 696 697 AcpiNsDeleteNamespaceByOwner (OwnerId); 698 if (ACPI_FAILURE (Status)) 699 { 700 return_ACPI_STATUS (Status); 701 } 702 703 AcpiUtReleaseWriteLock (&AcpiGbl_NamespaceRwLock); 704 705 Status = AcpiUtAcquireMutex (ACPI_MTX_INTERPRETER); 706 return_ACPI_STATUS (Status); 707 } 708 709 710 /******************************************************************************* 711 * 712 * FUNCTION: AcpiTbAllocateOwnerId 713 * 714 * PARAMETERS: TableIndex - Table index 715 * 716 * RETURN: Status 717 * 718 * DESCRIPTION: Allocates OwnerId in TableDesc 719 * 720 ******************************************************************************/ 721 722 ACPI_STATUS 723 AcpiTbAllocateOwnerId ( 724 UINT32 TableIndex) 725 { 726 ACPI_STATUS Status = AE_BAD_PARAMETER; 727 728 729 ACPI_FUNCTION_TRACE (TbAllocateOwnerId); 730 731 732 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 733 if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) 734 { 735 Status = AcpiUtAllocateOwnerId 736 (&(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId)); 737 } 738 739 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 740 return_ACPI_STATUS (Status); 741 } 742 743 744 /******************************************************************************* 745 * 746 * FUNCTION: AcpiTbReleaseOwnerId 747 * 748 * PARAMETERS: TableIndex - Table index 749 * 750 * RETURN: Status 751 * 752 * DESCRIPTION: Releases OwnerId in TableDesc 753 * 754 ******************************************************************************/ 755 756 ACPI_STATUS 757 AcpiTbReleaseOwnerId ( 758 UINT32 TableIndex) 759 { 760 ACPI_STATUS Status = AE_BAD_PARAMETER; 761 762 763 ACPI_FUNCTION_TRACE (TbReleaseOwnerId); 764 765 766 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 767 if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) 768 { 769 AcpiUtReleaseOwnerId ( 770 &(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId)); 771 Status = AE_OK; 772 } 773 774 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 775 return_ACPI_STATUS (Status); 776 } 777 778 779 /******************************************************************************* 780 * 781 * FUNCTION: AcpiTbGetOwnerId 782 * 783 * PARAMETERS: TableIndex - Table index 784 * OwnerId - Where the table OwnerId is returned 785 * 786 * RETURN: Status 787 * 788 * DESCRIPTION: returns OwnerId for the ACPI table 789 * 790 ******************************************************************************/ 791 792 ACPI_STATUS 793 AcpiTbGetOwnerId ( 794 UINT32 TableIndex, 795 ACPI_OWNER_ID *OwnerId) 796 { 797 ACPI_STATUS Status = AE_BAD_PARAMETER; 798 799 800 ACPI_FUNCTION_TRACE (TbGetOwnerId); 801 802 803 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 804 if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) 805 { 806 *OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId; 807 Status = AE_OK; 808 } 809 810 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 811 return_ACPI_STATUS (Status); 812 } 813 814 815 /******************************************************************************* 816 * 817 * FUNCTION: AcpiTbIsTableLoaded 818 * 819 * PARAMETERS: TableIndex - Table index 820 * 821 * RETURN: Table Loaded Flag 822 * 823 ******************************************************************************/ 824 825 BOOLEAN 826 AcpiTbIsTableLoaded ( 827 UINT32 TableIndex) 828 { 829 BOOLEAN IsLoaded = FALSE; 830 831 832 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 833 if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) 834 { 835 IsLoaded = (BOOLEAN) 836 (AcpiGbl_RootTableList.Tables[TableIndex].Flags & 837 ACPI_TABLE_IS_LOADED); 838 } 839 840 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 841 return (IsLoaded); 842 } 843 844 845 /******************************************************************************* 846 * 847 * FUNCTION: AcpiTbSetTableLoadedFlag 848 * 849 * PARAMETERS: TableIndex - Table index 850 * IsLoaded - TRUE if table is loaded, FALSE otherwise 851 * 852 * RETURN: None 853 * 854 * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE. 855 * 856 ******************************************************************************/ 857 858 void 859 AcpiTbSetTableLoadedFlag ( 860 UINT32 TableIndex, 861 BOOLEAN IsLoaded) 862 { 863 864 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 865 if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) 866 { 867 if (IsLoaded) 868 { 869 AcpiGbl_RootTableList.Tables[TableIndex].Flags |= 870 ACPI_TABLE_IS_LOADED; 871 } 872 else 873 { 874 AcpiGbl_RootTableList.Tables[TableIndex].Flags &= 875 ~ACPI_TABLE_IS_LOADED; 876 } 877 } 878 879 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 880 } 881 882