tbinstal.c revision 207344
154359Sroberto/****************************************************************************** 254359Sroberto * 3285612Sdelphij * Module Name: tbinstal - ACPI table installation and removal 4285612Sdelphij * 5285612Sdelphij *****************************************************************************/ 6285612Sdelphij 7285612Sdelphij/****************************************************************************** 854359Sroberto * 954359Sroberto * 1. Copyright Notice 1054359Sroberto * 1154359Sroberto * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. 12285612Sdelphij * All rights reserved. 13285612Sdelphij * 14285612Sdelphij * 2. License 15182007Sroberto * 16285612Sdelphij * 2.1. This is your license from Intel Corp. under its intellectual property 17285612Sdelphij * rights. You may have additional license terms from the party that provided 18289997Sglebius * you this software, covering your right to use that party's intellectual 19289997Sglebius * property rights. 20285612Sdelphij * 21285612Sdelphij * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 22285612Sdelphij * copy of the source code appearing in this file ("Covered Code") an 23285612Sdelphij * irrevocable, perpetual, worldwide license under Intel's copyrights in the 24285612Sdelphij * base code distributed originally by Intel ("Original Intel Code") to copy, 25285612Sdelphij * make derivatives, distribute, use and display any portion of the Covered 26285612Sdelphij * Code in any form, with the right to sublicense such rights; and 27285612Sdelphij * 2854359Sroberto * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 2954359Sroberto * license (with the right to sublicense), under only those claims of Intel 3054359Sroberto * patents that are infringed by the Original Intel Code, to make, use, sell, 31285612Sdelphij * offer to sell, and import the Covered Code and derivative works thereof 32285612Sdelphij * solely to the minimum extent necessary to exercise the above copyright 33285612Sdelphij * license, and in no event shall the patent license extend to any additions 34285612Sdelphij * to or modifications of the Original Intel Code. No other license or right 35285612Sdelphij * is granted directly or by implication, estoppel or otherwise; 36285612Sdelphij * 37285612Sdelphij * The above copyright and patent license is granted only if the following 38298770Sdelphij * conditions are met: 39298770Sdelphij * 40298770Sdelphij * 3. Conditions 41298770Sdelphij * 42298770Sdelphij * 3.1. Redistribution of Source with Rights to Further Distribute Source. 43298770Sdelphij * Redistribution of source code of any substantial portion of the Covered 44298770Sdelphij * Code or modification with rights to further distribute source must include 4554359Sroberto * the above Copyright Notice, the above License, this list of Conditions, 4654359Sroberto * and the following Disclaimer and Export Compliance provision. In addition, 4754359Sroberto * Licensee must cause all Covered Code to which Licensee contributes to 4854359Sroberto * contain a file documenting the changes Licensee made to create that Covered 4954359Sroberto * Code and the date of any change. Licensee must include in that file the 5054359Sroberto * documentation of any changes made by any predecessor Licensee. Licensee 5154359Sroberto * must include a prominent statement that the modification is derived, 5254359Sroberto * directly or indirectly, from Original Intel Code. 5354359Sroberto * 5454359Sroberto * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 5554359Sroberto * Redistribution of source code of any substantial portion of the Covered 5654359Sroberto * Code or modification without rights to further distribute source must 5754359Sroberto * include the following Disclaimer and Export Compliance provision in the 58285612Sdelphij * documentation and/or other materials provided with distribution. In 5954359Sroberto * addition, Licensee may not authorize further sublicense of source of any 60285612Sdelphij * portion of the Covered Code, and must include terms to the effect that the 61285612Sdelphij * license from Licensee to its licensee is limited to the intellectual 62285612Sdelphij * property embodied in the software Licensee provides to its licensee, and 63285612Sdelphij * not to intellectual property embodied in modifications its licensee may 64285612Sdelphij * make. 65285612Sdelphij * 6654359Sroberto * 3.3. Redistribution of Executable. Redistribution in executable form of any 6754359Sroberto * substantial portion of the Covered Code or modification must reproduce the 68285612Sdelphij * above Copyright Notice, and the following Disclaimer and Export Compliance 69285612Sdelphij * provision in the documentation and/or other materials provided with the 70285612Sdelphij * distribution. 71285612Sdelphij * 72285612Sdelphij * 3.4. Intel retains all right, title, and interest in and to the Original 7354359Sroberto * Intel Code. 7454359Sroberto * 7554359Sroberto * 3.5. Neither the name Intel nor any other trademark owned or controlled by 7654359Sroberto * Intel shall be used in advertising or otherwise to promote the sale, use or 7754359Sroberto * other dealings in products derived from or relating to the Covered Code 7854359Sroberto * without prior written authorization from Intel. 7954359Sroberto * 8054359Sroberto * 4. Disclaimer and Export Compliance 81285612Sdelphij * 82285612Sdelphij * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 83285612Sdelphij * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 8454359Sroberto * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 85285612Sdelphij * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 86285612Sdelphij * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 87285612Sdelphij * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 88285612Sdelphij * PARTICULAR PURPOSE. 89285612Sdelphij * 9054359Sroberto * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 91285612Sdelphij * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 92285612Sdelphij * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 93285612Sdelphij * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 94285612Sdelphij * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 95285612Sdelphij * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 96285612Sdelphij * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 97285612Sdelphij * LIMITED REMEDY. 98285612Sdelphij * 99285612Sdelphij * 4.3. Licensee shall not export, either directly or indirectly, any of this 100285612Sdelphij * software or system incorporating such software without first obtaining any 101285612Sdelphij * required license or other approval from the U. S. Department of Commerce or 102285612Sdelphij * any other agency or department of the United States Government. In the 103285612Sdelphij * event Licensee exports any such software from the United States or 104285612Sdelphij * re-exports any such software from a foreign destination, Licensee shall 105285612Sdelphij * ensure that the distribution and export/re-export of the software is in 106285612Sdelphij * compliance with all laws, regulations, orders, or other restrictions of the 107285612Sdelphij * U.S. Export Administration Regulations. Licensee agrees that neither it nor 10854359Sroberto * any of its subsidiaries will export/re-export any technical data, process, 109285612Sdelphij * software, or service, directly or indirectly, to any country for which the 110285612Sdelphij * United States government or any agency thereof requires an export license, 111285612Sdelphij * other governmental approval, or letter of assurance, without first obtaining 112285612Sdelphij * such license, approval or letter. 113285612Sdelphij * 114285612Sdelphij *****************************************************************************/ 115285612Sdelphij 116285612Sdelphij 11754359Sroberto#define __TBINSTAL_C__ 118285612Sdelphij 119285612Sdelphij#include <contrib/dev/acpica/include/acpi.h> 120285612Sdelphij#include <contrib/dev/acpica/include/accommon.h> 121285612Sdelphij#include <contrib/dev/acpica/include/acnamesp.h> 122285612Sdelphij#include <contrib/dev/acpica/include/actables.h> 12354359Sroberto 124285612Sdelphij 125285612Sdelphij#define _COMPONENT ACPI_TABLES 126285612Sdelphij ACPI_MODULE_NAME ("tbinstal") 127285612Sdelphij 12854359Sroberto 129285612Sdelphij/****************************************************************************** 130285612Sdelphij * 131285612Sdelphij * FUNCTION: AcpiTbVerifyTable 132182007Sroberto * 133285612Sdelphij * PARAMETERS: TableDesc - table 134285612Sdelphij * 135285612Sdelphij * RETURN: Status 136285612Sdelphij * 137285612Sdelphij * DESCRIPTION: this function is called to verify and map table 138285612Sdelphij * 139285612Sdelphij *****************************************************************************/ 140285612Sdelphij 141285612SdelphijACPI_STATUS 142285612SdelphijAcpiTbVerifyTable ( 143285612Sdelphij ACPI_TABLE_DESC *TableDesc) 144285612Sdelphij{ 145285612Sdelphij ACPI_STATUS Status = AE_OK; 146285612Sdelphij 147285612Sdelphij 148285612Sdelphij ACPI_FUNCTION_TRACE (TbVerifyTable); 149285612Sdelphij 150285612Sdelphij 151285612Sdelphij /* Map the table if necessary */ 152285612Sdelphij 153285612Sdelphij if (!TableDesc->Pointer) 154285612Sdelphij { 155285612Sdelphij if ((TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK) == 156285612Sdelphij ACPI_TABLE_ORIGIN_MAPPED) 157285612Sdelphij { 158285612Sdelphij TableDesc->Pointer = AcpiOsMapMemory ( 159285612Sdelphij TableDesc->Address, TableDesc->Length); 160285612Sdelphij } 161285612Sdelphij 162285612Sdelphij if (!TableDesc->Pointer) 163285612Sdelphij { 164285612Sdelphij return_ACPI_STATUS (AE_NO_MEMORY); 165285612Sdelphij } 166285612Sdelphij } 167285612Sdelphij 168285612Sdelphij /* FACS is the odd table, has no standard ACPI header and no checksum */ 169285612Sdelphij 170285612Sdelphij if (!ACPI_COMPARE_NAME (&TableDesc->Signature, ACPI_SIG_FACS)) 171285612Sdelphij { 172285612Sdelphij /* Always calculate checksum, ignore bad checksum if requested */ 173285612Sdelphij 174285612Sdelphij Status = AcpiTbVerifyChecksum (TableDesc->Pointer, TableDesc->Length); 175285612Sdelphij } 176285612Sdelphij 177285612Sdelphij return_ACPI_STATUS (Status); 178285612Sdelphij} 179285612Sdelphij 180285612Sdelphij 181285612Sdelphij/******************************************************************************* 182285612Sdelphij * 183285612Sdelphij * FUNCTION: AcpiTbAddTable 184285612Sdelphij * 185285612Sdelphij * PARAMETERS: TableDesc - Table descriptor 186285612Sdelphij * TableIndex - Where the table index is returned 187285612Sdelphij * 188285612Sdelphij * RETURN: Status 189285612Sdelphij * 190285612Sdelphij * DESCRIPTION: This function is called to add an ACPI table. It is used to 191285612Sdelphij * dynamically load tables via the Load and LoadTable AML 192285612Sdelphij * operators. 193285612Sdelphij * 194285612Sdelphij ******************************************************************************/ 195285612Sdelphij 196285612SdelphijACPI_STATUS 197285612SdelphijAcpiTbAddTable ( 198285612Sdelphij ACPI_TABLE_DESC *TableDesc, 199285612Sdelphij UINT32 *TableIndex) 200285612Sdelphij{ 201285612Sdelphij UINT32 i; 202285612Sdelphij ACPI_STATUS Status = AE_OK; 203285612Sdelphij ACPI_TABLE_HEADER *OverrideTable = NULL; 204285612Sdelphij 205285612Sdelphij 206285612Sdelphij ACPI_FUNCTION_TRACE (TbAddTable); 207285612Sdelphij 208285612Sdelphij 209285612Sdelphij if (!TableDesc->Pointer) 210285612Sdelphij { 211285612Sdelphij Status = AcpiTbVerifyTable (TableDesc); 212285612Sdelphij if (ACPI_FAILURE (Status) || !TableDesc->Pointer) 213285612Sdelphij { 214285612Sdelphij return_ACPI_STATUS (Status); 215285612Sdelphij } 216285612Sdelphij } 217285612Sdelphij 218285612Sdelphij /* 219285612Sdelphij * Originally, we checked the table signature for "SSDT" or "PSDT" here. 220285612Sdelphij * Next, we added support for OEMx tables, signature "OEM". 221285612Sdelphij * Valid tables were encountered with a null signature, so we've just 222182007Sroberto * given up on validating the signature, since it seems to be a waste 223182007Sroberto * of code. The original code was removed (05/2008). 224285612Sdelphij */ 225285612Sdelphij 22682498Sroberto (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 227285612Sdelphij 228294569Sdelphij /* Check if table is already registered */ 22982498Sroberto 23082498Sroberto for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; ++i) 231285612Sdelphij { 232285612Sdelphij if (!AcpiGbl_RootTableList.Tables[i].Pointer) 233285612Sdelphij { 234285612Sdelphij Status = AcpiTbVerifyTable (&AcpiGbl_RootTableList.Tables[i]); 235285612Sdelphij if (ACPI_FAILURE (Status) || 236285612Sdelphij !AcpiGbl_RootTableList.Tables[i].Pointer) 237285612Sdelphij { 238285612Sdelphij continue; 239285612Sdelphij } 240285612Sdelphij } 24154359Sroberto 242285612Sdelphij /* 243285612Sdelphij * Check for a table match on the entire table length, 244285612Sdelphij * not just the header. 245285612Sdelphij */ 246285612Sdelphij if (TableDesc->Length != AcpiGbl_RootTableList.Tables[i].Length) 247285612Sdelphij { 248285612Sdelphij continue; 249285612Sdelphij } 250285612Sdelphij 251285612Sdelphij if (ACPI_MEMCMP (TableDesc->Pointer, 252285612Sdelphij AcpiGbl_RootTableList.Tables[i].Pointer, 253285612Sdelphij AcpiGbl_RootTableList.Tables[i].Length)) 254285612Sdelphij { 255285612Sdelphij continue; 256285612Sdelphij } 257285612Sdelphij 258285612Sdelphij /* 259285612Sdelphij * Note: the current mechanism does not unregister a table if it is 260285612Sdelphij * dynamically unloaded. The related namespace entries are deleted, 261285612Sdelphij * but the table remains in the root table list. 262285612Sdelphij * 263285612Sdelphij * The assumption here is that the number of different tables that 264285612Sdelphij * will be loaded is actually small, and there is minimal overhead 265285612Sdelphij * in just keeping the table in case it is needed again. 266285612Sdelphij * 267285612Sdelphij * If this assumption changes in the future (perhaps on large 268285612Sdelphij * machines with many table load/unload operations), tables will 269285612Sdelphij * need to be unregistered when they are unloaded, and slots in the 270285612Sdelphij * root table list should be reused when empty. 271285612Sdelphij */ 272285612Sdelphij 273285612Sdelphij /* 274285612Sdelphij * Table is already registered. 275285612Sdelphij * We can delete the table that was passed as a parameter. 276285612Sdelphij */ 277285612Sdelphij AcpiTbDeleteTable (TableDesc); 278285612Sdelphij *TableIndex = i; 279285612Sdelphij 280285612Sdelphij if (AcpiGbl_RootTableList.Tables[i].Flags & ACPI_TABLE_IS_LOADED) 281285612Sdelphij { 282285612Sdelphij /* Table is still loaded, this is an error */ 283285612Sdelphij 284285612Sdelphij Status = AE_ALREADY_EXISTS; 285285612Sdelphij goto Release; 286285612Sdelphij } 287285612Sdelphij else 288285612Sdelphij { 289285612Sdelphij /* Table was unloaded, allow it to be reloaded */ 290285612Sdelphij 291285612Sdelphij TableDesc->Pointer = AcpiGbl_RootTableList.Tables[i].Pointer; 292285612Sdelphij TableDesc->Address = AcpiGbl_RootTableList.Tables[i].Address; 293285612Sdelphij Status = AE_OK; 294285612Sdelphij goto PrintHeader; 295285612Sdelphij } 296285612Sdelphij } 297285612Sdelphij 298285612Sdelphij /* 299285612Sdelphij * ACPI Table Override: 300285612Sdelphij * Allow the host to override dynamically loaded tables. 301285612Sdelphij */ 302285612Sdelphij Status = AcpiOsTableOverride (TableDesc->Pointer, &OverrideTable); 303 if (ACPI_SUCCESS (Status) && OverrideTable) 304 { 305 ACPI_INFO ((AE_INFO, 306 "%4.4s @ 0x%p Table override, replaced with:", 307 TableDesc->Pointer->Signature, 308 ACPI_CAST_PTR (void, TableDesc->Address))); 309 310 /* We can delete the table that was passed as a parameter */ 311 312 AcpiTbDeleteTable (TableDesc); 313 314 /* Setup descriptor for the new table */ 315 316 TableDesc->Address = ACPI_PTR_TO_PHYSADDR (OverrideTable); 317 TableDesc->Pointer = OverrideTable; 318 TableDesc->Length = OverrideTable->Length; 319 TableDesc->Flags = ACPI_TABLE_ORIGIN_OVERRIDE; 320 } 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 331PrintHeader: 332 AcpiTbPrintTableHeader (TableDesc->Address, TableDesc->Pointer); 333 334Release: 335 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 336 return_ACPI_STATUS (Status); 337} 338 339 340/******************************************************************************* 341 * 342 * FUNCTION: AcpiTbResizeRootTableList 343 * 344 * PARAMETERS: None 345 * 346 * RETURN: Status 347 * 348 * DESCRIPTION: Expand the size of global table array 349 * 350 ******************************************************************************/ 351 352ACPI_STATUS 353AcpiTbResizeRootTableList ( 354 void) 355{ 356 ACPI_TABLE_DESC *Tables; 357 358 359 ACPI_FUNCTION_TRACE (TbResizeRootTableList); 360 361 362 /* AllowResize flag is a parameter to AcpiInitializeTables */ 363 364 if (!(AcpiGbl_RootTableList.Flags & ACPI_ROOT_ALLOW_RESIZE)) 365 { 366 ACPI_ERROR ((AE_INFO, "Resize of Root Table Array is not allowed")); 367 return_ACPI_STATUS (AE_SUPPORT); 368 } 369 370 /* Increase the Table Array size */ 371 372 Tables = ACPI_ALLOCATE_ZEROED ( 373 ((ACPI_SIZE) AcpiGbl_RootTableList.MaxTableCount + 374 ACPI_ROOT_TABLE_SIZE_INCREMENT) * 375 sizeof (ACPI_TABLE_DESC)); 376 if (!Tables) 377 { 378 ACPI_ERROR ((AE_INFO, "Could not allocate new root table array")); 379 return_ACPI_STATUS (AE_NO_MEMORY); 380 } 381 382 /* Copy and free the previous table array */ 383 384 if (AcpiGbl_RootTableList.Tables) 385 { 386 ACPI_MEMCPY (Tables, AcpiGbl_RootTableList.Tables, 387 (ACPI_SIZE) AcpiGbl_RootTableList.MaxTableCount * sizeof (ACPI_TABLE_DESC)); 388 389 if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED) 390 { 391 ACPI_FREE (AcpiGbl_RootTableList.Tables); 392 } 393 } 394 395 AcpiGbl_RootTableList.Tables = Tables; 396 AcpiGbl_RootTableList.MaxTableCount += ACPI_ROOT_TABLE_SIZE_INCREMENT; 397 AcpiGbl_RootTableList.Flags |= (UINT8) ACPI_ROOT_ORIGIN_ALLOCATED; 398 399 return_ACPI_STATUS (AE_OK); 400} 401 402 403/******************************************************************************* 404 * 405 * FUNCTION: AcpiTbStoreTable 406 * 407 * PARAMETERS: Address - Table address 408 * Table - Table header 409 * Length - Table length 410 * Flags - flags 411 * 412 * RETURN: Status and table index. 413 * 414 * DESCRIPTION: Add an ACPI table to the global table list 415 * 416 ******************************************************************************/ 417 418ACPI_STATUS 419AcpiTbStoreTable ( 420 ACPI_PHYSICAL_ADDRESS Address, 421 ACPI_TABLE_HEADER *Table, 422 UINT32 Length, 423 UINT8 Flags, 424 UINT32 *TableIndex) 425{ 426 ACPI_STATUS Status; 427 ACPI_TABLE_DESC *NewTable; 428 429 430 /* Ensure that there is room for the table in the Root Table List */ 431 432 if (AcpiGbl_RootTableList.CurrentTableCount >= 433 AcpiGbl_RootTableList.MaxTableCount) 434 { 435 Status = AcpiTbResizeRootTableList(); 436 if (ACPI_FAILURE (Status)) 437 { 438 return (Status); 439 } 440 } 441 442 NewTable = &AcpiGbl_RootTableList.Tables[AcpiGbl_RootTableList.CurrentTableCount]; 443 444 /* Initialize added table */ 445 446 NewTable->Address = Address; 447 NewTable->Pointer = Table; 448 NewTable->Length = Length; 449 NewTable->OwnerId = 0; 450 NewTable->Flags = Flags; 451 452 ACPI_MOVE_32_TO_32 (&NewTable->Signature, Table->Signature); 453 454 *TableIndex = AcpiGbl_RootTableList.CurrentTableCount; 455 AcpiGbl_RootTableList.CurrentTableCount++; 456 return (AE_OK); 457} 458 459 460/******************************************************************************* 461 * 462 * FUNCTION: AcpiTbDeleteTable 463 * 464 * PARAMETERS: TableIndex - Table index 465 * 466 * RETURN: None 467 * 468 * DESCRIPTION: Delete one internal ACPI table 469 * 470 ******************************************************************************/ 471 472void 473AcpiTbDeleteTable ( 474 ACPI_TABLE_DESC *TableDesc) 475{ 476 477 /* Table must be mapped or allocated */ 478 479 if (!TableDesc->Pointer) 480 { 481 return; 482 } 483 484 switch (TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK) 485 { 486 case ACPI_TABLE_ORIGIN_MAPPED: 487 AcpiOsUnmapMemory (TableDesc->Pointer, TableDesc->Length); 488 break; 489 490 case ACPI_TABLE_ORIGIN_ALLOCATED: 491 ACPI_FREE (TableDesc->Pointer); 492 break; 493 494 default: 495 break; 496 } 497 498 TableDesc->Pointer = NULL; 499} 500 501 502/******************************************************************************* 503 * 504 * FUNCTION: AcpiTbTerminate 505 * 506 * PARAMETERS: None 507 * 508 * RETURN: None 509 * 510 * DESCRIPTION: Delete all internal ACPI tables 511 * 512 ******************************************************************************/ 513 514void 515AcpiTbTerminate ( 516 void) 517{ 518 UINT32 i; 519 520 521 ACPI_FUNCTION_TRACE (TbTerminate); 522 523 524 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 525 526 /* Delete the individual tables */ 527 528 for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++) 529 { 530 AcpiTbDeleteTable (&AcpiGbl_RootTableList.Tables[i]); 531 } 532 533 /* 534 * Delete the root table array if allocated locally. Array cannot be 535 * mapped, so we don't need to check for that flag. 536 */ 537 if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED) 538 { 539 ACPI_FREE (AcpiGbl_RootTableList.Tables); 540 } 541 542 AcpiGbl_RootTableList.Tables = NULL; 543 AcpiGbl_RootTableList.Flags = 0; 544 AcpiGbl_RootTableList.CurrentTableCount = 0; 545 546 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "ACPI Tables freed\n")); 547 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 548} 549 550 551/******************************************************************************* 552 * 553 * FUNCTION: AcpiTbDeleteNamespaceByOwner 554 * 555 * PARAMETERS: TableIndex - Table index 556 * 557 * RETURN: Status 558 * 559 * DESCRIPTION: Delete all namespace objects created when this table was loaded. 560 * 561 ******************************************************************************/ 562 563ACPI_STATUS 564AcpiTbDeleteNamespaceByOwner ( 565 UINT32 TableIndex) 566{ 567 ACPI_OWNER_ID OwnerId; 568 ACPI_STATUS Status; 569 570 571 ACPI_FUNCTION_TRACE (TbDeleteNamespaceByOwner); 572 573 574 Status = AcpiUtAcquireMutex (ACPI_MTX_TABLES); 575 if (ACPI_FAILURE (Status)) 576 { 577 return_ACPI_STATUS (Status); 578 } 579 580 if (TableIndex >= AcpiGbl_RootTableList.CurrentTableCount) 581 { 582 /* The table index does not exist */ 583 584 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 585 return_ACPI_STATUS (AE_NOT_EXIST); 586 } 587 588 /* Get the owner ID for this table, used to delete namespace nodes */ 589 590 OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId; 591 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 592 593 /* 594 * Need to acquire the namespace writer lock to prevent interference 595 * with any concurrent namespace walks. The interpreter must be 596 * released during the deletion since the acquisition of the deletion 597 * lock may block, and also since the execution of a namespace walk 598 * must be allowed to use the interpreter. 599 */ 600 (void) AcpiUtReleaseMutex (ACPI_MTX_INTERPRETER); 601 Status = AcpiUtAcquireWriteLock (&AcpiGbl_NamespaceRwLock); 602 603 AcpiNsDeleteNamespaceByOwner (OwnerId); 604 if (ACPI_FAILURE (Status)) 605 { 606 return_ACPI_STATUS (Status); 607 } 608 609 AcpiUtReleaseWriteLock (&AcpiGbl_NamespaceRwLock); 610 611 Status = AcpiUtAcquireMutex (ACPI_MTX_INTERPRETER); 612 return_ACPI_STATUS (Status); 613} 614 615 616/******************************************************************************* 617 * 618 * FUNCTION: AcpiTbAllocateOwnerId 619 * 620 * PARAMETERS: TableIndex - Table index 621 * 622 * RETURN: Status 623 * 624 * DESCRIPTION: Allocates OwnerId in TableDesc 625 * 626 ******************************************************************************/ 627 628ACPI_STATUS 629AcpiTbAllocateOwnerId ( 630 UINT32 TableIndex) 631{ 632 ACPI_STATUS Status = AE_BAD_PARAMETER; 633 634 635 ACPI_FUNCTION_TRACE (TbAllocateOwnerId); 636 637 638 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 639 if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) 640 { 641 Status = AcpiUtAllocateOwnerId 642 (&(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId)); 643 } 644 645 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 646 return_ACPI_STATUS (Status); 647} 648 649 650/******************************************************************************* 651 * 652 * FUNCTION: AcpiTbReleaseOwnerId 653 * 654 * PARAMETERS: TableIndex - Table index 655 * 656 * RETURN: Status 657 * 658 * DESCRIPTION: Releases OwnerId in TableDesc 659 * 660 ******************************************************************************/ 661 662ACPI_STATUS 663AcpiTbReleaseOwnerId ( 664 UINT32 TableIndex) 665{ 666 ACPI_STATUS Status = AE_BAD_PARAMETER; 667 668 669 ACPI_FUNCTION_TRACE (TbReleaseOwnerId); 670 671 672 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 673 if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) 674 { 675 AcpiUtReleaseOwnerId ( 676 &(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId)); 677 Status = AE_OK; 678 } 679 680 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 681 return_ACPI_STATUS (Status); 682} 683 684 685/******************************************************************************* 686 * 687 * FUNCTION: AcpiTbGetOwnerId 688 * 689 * PARAMETERS: TableIndex - Table index 690 * OwnerId - Where the table OwnerId is returned 691 * 692 * RETURN: Status 693 * 694 * DESCRIPTION: returns OwnerId for the ACPI table 695 * 696 ******************************************************************************/ 697 698ACPI_STATUS 699AcpiTbGetOwnerId ( 700 UINT32 TableIndex, 701 ACPI_OWNER_ID *OwnerId) 702{ 703 ACPI_STATUS Status = AE_BAD_PARAMETER; 704 705 706 ACPI_FUNCTION_TRACE (TbGetOwnerId); 707 708 709 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 710 if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) 711 { 712 *OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId; 713 Status = AE_OK; 714 } 715 716 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 717 return_ACPI_STATUS (Status); 718} 719 720 721/******************************************************************************* 722 * 723 * FUNCTION: AcpiTbIsTableLoaded 724 * 725 * PARAMETERS: TableIndex - Table index 726 * 727 * RETURN: Table Loaded Flag 728 * 729 ******************************************************************************/ 730 731BOOLEAN 732AcpiTbIsTableLoaded ( 733 UINT32 TableIndex) 734{ 735 BOOLEAN IsLoaded = FALSE; 736 737 738 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 739 if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) 740 { 741 IsLoaded = (BOOLEAN) 742 (AcpiGbl_RootTableList.Tables[TableIndex].Flags & 743 ACPI_TABLE_IS_LOADED); 744 } 745 746 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 747 return (IsLoaded); 748} 749 750 751/******************************************************************************* 752 * 753 * FUNCTION: AcpiTbSetTableLoadedFlag 754 * 755 * PARAMETERS: TableIndex - Table index 756 * IsLoaded - TRUE if table is loaded, FALSE otherwise 757 * 758 * RETURN: None 759 * 760 * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE. 761 * 762 ******************************************************************************/ 763 764void 765AcpiTbSetTableLoadedFlag ( 766 UINT32 TableIndex, 767 BOOLEAN IsLoaded) 768{ 769 770 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 771 if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) 772 { 773 if (IsLoaded) 774 { 775 AcpiGbl_RootTableList.Tables[TableIndex].Flags |= 776 ACPI_TABLE_IS_LOADED; 777 } 778 else 779 { 780 AcpiGbl_RootTableList.Tables[TableIndex].Flags &= 781 ~ACPI_TABLE_IS_LOADED; 782 } 783 } 784 785 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 786} 787 788