1 /****************************************************************************** 2 * 3 * Module Name: tbxface - Public interfaces to the ACPI subsystem 4 * ACPI table oriented interfaces 5 * $Revision: 1.88 $ 6 * 7 *****************************************************************************/ 8 9 /****************************************************************************** 10 * 11 * 1. Copyright Notice 12 * 13 * Some or all of this work - Copyright (c) 1999 - 2008, Intel Corp. 14 * All rights reserved. 15 * 16 * 2. License 17 * 18 * 2.1. This is your license from Intel Corp. under its intellectual property 19 * rights. You may have additional license terms from the party that provided 20 * you this software, covering your right to use that party's intellectual 21 * property rights. 22 * 23 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 24 * copy of the source code appearing in this file ("Covered Code") an 25 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 26 * base code distributed originally by Intel ("Original Intel Code") to copy, 27 * make derivatives, distribute, use and display any portion of the Covered 28 * Code in any form, with the right to sublicense such rights; and 29 * 30 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 31 * license (with the right to sublicense), under only those claims of Intel 32 * patents that are infringed by the Original Intel Code, to make, use, sell, 33 * offer to sell, and import the Covered Code and derivative works thereof 34 * solely to the minimum extent necessary to exercise the above copyright 35 * license, and in no event shall the patent license extend to any additions 36 * to or modifications of the Original Intel Code. No other license or right 37 * is granted directly or by implication, estoppel or otherwise; 38 * 39 * The above copyright and patent license is granted only if the following 40 * conditions are met: 41 * 42 * 3. Conditions 43 * 44 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 45 * Redistribution of source code of any substantial portion of the Covered 46 * Code or modification with rights to further distribute source must include 47 * the above Copyright Notice, the above License, this list of Conditions, 48 * and the following Disclaimer and Export Compliance provision. In addition, 49 * Licensee must cause all Covered Code to which Licensee contributes to 50 * contain a file documenting the changes Licensee made to create that Covered 51 * Code and the date of any change. Licensee must include in that file the 52 * documentation of any changes made by any predecessor Licensee. Licensee 53 * must include a prominent statement that the modification is derived, 54 * directly or indirectly, from Original Intel Code. 55 * 56 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 57 * Redistribution of source code of any substantial portion of the Covered 58 * Code or modification without rights to further distribute source must 59 * include the following Disclaimer and Export Compliance provision in the 60 * documentation and/or other materials provided with distribution. In 61 * addition, Licensee may not authorize further sublicense of source of any 62 * portion of the Covered Code, and must include terms to the effect that the 63 * license from Licensee to its licensee is limited to the intellectual 64 * property embodied in the software Licensee provides to its licensee, and 65 * not to intellectual property embodied in modifications its licensee may 66 * make. 67 * 68 * 3.3. Redistribution of Executable. Redistribution in executable form of any 69 * substantial portion of the Covered Code or modification must reproduce the 70 * above Copyright Notice, and the following Disclaimer and Export Compliance 71 * provision in the documentation and/or other materials provided with the 72 * distribution. 73 * 74 * 3.4. Intel retains all right, title, and interest in and to the Original 75 * Intel Code. 76 * 77 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 78 * Intel shall be used in advertising or otherwise to promote the sale, use or 79 * other dealings in products derived from or relating to the Covered Code 80 * without prior written authorization from Intel. 81 * 82 * 4. Disclaimer and Export Compliance 83 * 84 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 85 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 86 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 87 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 88 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 89 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 90 * PARTICULAR PURPOSE. 91 * 92 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 93 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 94 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 95 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 96 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 97 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 98 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 99 * LIMITED REMEDY. 100 * 101 * 4.3. Licensee shall not export, either directly or indirectly, any of this 102 * software or system incorporating such software without first obtaining any 103 * required license or other approval from the U. S. Department of Commerce or 104 * any other agency or department of the United States Government. In the 105 * event Licensee exports any such software from the United States or 106 * re-exports any such software from a foreign destination, Licensee shall 107 * ensure that the distribution and export/re-export of the software is in 108 * compliance with all laws, regulations, orders, or other restrictions of the 109 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 110 * any of its subsidiaries will export/re-export any technical data, process, 111 * software, or service, directly or indirectly, to any country for which the 112 * United States government or any agency thereof requires an export license, 113 * other governmental approval, or letter of assurance, without first obtaining 114 * such license, approval or letter. 115 * 116 *****************************************************************************/ 117 118 #define __TBXFACE_C__ 119 120 #include "acpi.h" 121 #include "acnamesp.h" 122 #include "actables.h" 123 124 #define _COMPONENT ACPI_TABLES 125 ACPI_MODULE_NAME ("tbxface") 126 127 /* Local prototypes */ 128 129 static ACPI_STATUS 130 AcpiTbLoadNamespace ( 131 void); 132 133 134 /******************************************************************************* 135 * 136 * FUNCTION: AcpiAllocateRootTable 137 * 138 * PARAMETERS: InitialTableCount - Size of InitialTableArray, in number of 139 * ACPI_TABLE_DESC structures 140 * 141 * RETURN: Status 142 * 143 * DESCRIPTION: Allocate a root table array. Used by iASL compiler and 144 * AcpiInitializeTables. 145 * 146 ******************************************************************************/ 147 148 ACPI_STATUS 149 AcpiAllocateRootTable ( 150 UINT32 InitialTableCount) 151 { 152 153 AcpiGbl_RootTableList.Size = InitialTableCount; 154 AcpiGbl_RootTableList.Flags = ACPI_ROOT_ALLOW_RESIZE; 155 156 return (AcpiTbResizeRootTableList ()); 157 } 158 159 160 /******************************************************************************* 161 * 162 * FUNCTION: AcpiInitializeTables 163 * 164 * PARAMETERS: InitialTableArray - Pointer to an array of pre-allocated 165 * ACPI_TABLE_DESC structures. If NULL, the 166 * array is dynamically allocated. 167 * InitialTableCount - Size of InitialTableArray, in number of 168 * ACPI_TABLE_DESC structures 169 * AllowRealloc - Flag to tell Table Manager if resize of 170 * pre-allocated array is allowed. Ignored 171 * if InitialTableArray is NULL. 172 * 173 * RETURN: Status 174 * 175 * DESCRIPTION: Initialize the table manager, get the RSDP and RSDT/XSDT. 176 * 177 * NOTE: Allows static allocation of the initial table array in order 178 * to avoid the use of dynamic memory in confined environments 179 * such as the kernel boot sequence where it may not be available. 180 * 181 * If the host OS memory managers are initialized, use NULL for 182 * InitialTableArray, and the table will be dynamically allocated. 183 * 184 ******************************************************************************/ 185 186 ACPI_STATUS 187 AcpiInitializeTables ( 188 ACPI_TABLE_DESC *InitialTableArray, 189 UINT32 InitialTableCount, 190 BOOLEAN AllowResize) 191 { 192 ACPI_PHYSICAL_ADDRESS RsdpAddress; 193 ACPI_STATUS Status; 194 195 196 ACPI_FUNCTION_TRACE (AcpiInitializeTables); 197 198 199 /* 200 * Set up the Root Table Array 201 * Allocate the table array if requested 202 */ 203 if (!InitialTableArray) 204 { 205 Status = AcpiAllocateRootTable (InitialTableCount); 206 if (ACPI_FAILURE (Status)) 207 { 208 return_ACPI_STATUS (Status); 209 } 210 } 211 else 212 { 213 /* Root Table Array has been statically allocated by the host */ 214 215 ACPI_MEMSET (InitialTableArray, 0, 216 (ACPI_SIZE) InitialTableCount * sizeof (ACPI_TABLE_DESC)); 217 218 AcpiGbl_RootTableList.Tables = InitialTableArray; 219 AcpiGbl_RootTableList.Size = InitialTableCount; 220 AcpiGbl_RootTableList.Flags = ACPI_ROOT_ORIGIN_UNKNOWN; 221 if (AllowResize) 222 { 223 AcpiGbl_RootTableList.Flags |= ACPI_ROOT_ALLOW_RESIZE; 224 } 225 } 226 227 /* Get the address of the RSDP */ 228 229 RsdpAddress = AcpiOsGetRootPointer (); 230 if (!RsdpAddress) 231 { 232 return_ACPI_STATUS (AE_NOT_FOUND); 233 } 234 235 /* 236 * Get the root table (RSDT or XSDT) and extract all entries to the local 237 * Root Table Array. This array contains the information of the RSDT/XSDT 238 * in a common, more useable format. 239 */ 240 Status = AcpiTbParseRootTable (RsdpAddress, ACPI_TABLE_ORIGIN_MAPPED); 241 return_ACPI_STATUS (Status); 242 } 243 244 ACPI_EXPORT_SYMBOL (AcpiInitializeTables) 245 246 247 /******************************************************************************* 248 * 249 * FUNCTION: AcpiReallocateRootTable 250 * 251 * PARAMETERS: None 252 * 253 * RETURN: Status 254 * 255 * DESCRIPTION: Reallocate Root Table List into dynamic memory. Copies the 256 * root list from the previously provided scratch area. Should 257 * be called once dynamic memory allocation is available in the 258 * kernel 259 * 260 ******************************************************************************/ 261 262 ACPI_STATUS 263 AcpiReallocateRootTable ( 264 void) 265 { 266 ACPI_TABLE_DESC *Tables; 267 ACPI_SIZE NewSize; 268 269 270 ACPI_FUNCTION_TRACE (AcpiReallocateRootTable); 271 272 273 /* 274 * Only reallocate the root table if the host provided a static buffer 275 * for the table array in the call to AcpiInitializeTables. 276 */ 277 if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED) 278 { 279 return_ACPI_STATUS (AE_SUPPORT); 280 } 281 282 NewSize = ((ACPI_SIZE) AcpiGbl_RootTableList.Count + 283 ACPI_ROOT_TABLE_SIZE_INCREMENT) * 284 sizeof (ACPI_TABLE_DESC); 285 286 /* Create new array and copy the old array */ 287 288 Tables = ACPI_ALLOCATE_ZEROED (NewSize); 289 if (!Tables) 290 { 291 return_ACPI_STATUS (AE_NO_MEMORY); 292 } 293 294 ACPI_MEMCPY (Tables, AcpiGbl_RootTableList.Tables, NewSize); 295 296 AcpiGbl_RootTableList.Size = AcpiGbl_RootTableList.Count; 297 AcpiGbl_RootTableList.Tables = Tables; 298 AcpiGbl_RootTableList.Flags = 299 ACPI_ROOT_ORIGIN_ALLOCATED | ACPI_ROOT_ALLOW_RESIZE; 300 301 return_ACPI_STATUS (AE_OK); 302 } 303 304 ACPI_EXPORT_SYMBOL (AcpiReallocateRootTable) 305 306 307 /****************************************************************************** 308 * 309 * FUNCTION: AcpiGetTableHeader 310 * 311 * PARAMETERS: Signature - ACPI signature of needed table 312 * Instance - Which instance (for SSDTs) 313 * OutTableHeader - The pointer to the table header to fill 314 * 315 * RETURN: Status and pointer to mapped table header 316 * 317 * DESCRIPTION: Finds an ACPI table header. 318 * 319 * NOTE: Caller is responsible in unmapping the header with 320 * AcpiOsUnmapMemory 321 * 322 *****************************************************************************/ 323 324 ACPI_STATUS 325 AcpiGetTableHeader ( 326 char *Signature, 327 UINT32 Instance, 328 ACPI_TABLE_HEADER *OutTableHeader) 329 { 330 UINT32 i; 331 UINT32 j; 332 ACPI_TABLE_HEADER *Header; 333 334 335 /* Parameter validation */ 336 337 if (!Signature || !OutTableHeader) 338 { 339 return (AE_BAD_PARAMETER); 340 } 341 342 /* 343 * Walk the root table list 344 */ 345 for (i = 0, j = 0; i < AcpiGbl_RootTableList.Count; i++) 346 { 347 if (!ACPI_COMPARE_NAME (&(AcpiGbl_RootTableList.Tables[i].Signature), 348 Signature)) 349 { 350 continue; 351 } 352 353 if (++j < Instance) 354 { 355 continue; 356 } 357 358 if (!AcpiGbl_RootTableList.Tables[i].Pointer) 359 { 360 if ((AcpiGbl_RootTableList.Tables[i].Flags & ACPI_TABLE_ORIGIN_MASK) == 361 ACPI_TABLE_ORIGIN_MAPPED) 362 { 363 Header = AcpiOsMapMemory (AcpiGbl_RootTableList.Tables[i].Address, 364 sizeof (ACPI_TABLE_HEADER)); 365 if (!Header) 366 { 367 return AE_NO_MEMORY; 368 } 369 370 ACPI_MEMCPY (OutTableHeader, Header, sizeof(ACPI_TABLE_HEADER)); 371 AcpiOsUnmapMemory (Header, sizeof(ACPI_TABLE_HEADER)); 372 } 373 374 else 375 { 376 return AE_NOT_FOUND; 377 } 378 } 379 380 else 381 { 382 ACPI_MEMCPY (OutTableHeader, AcpiGbl_RootTableList.Tables[i].Pointer, 383 sizeof(ACPI_TABLE_HEADER)); 384 } 385 386 return (AE_OK); 387 } 388 389 return (AE_NOT_FOUND); 390 } 391 392 ACPI_EXPORT_SYMBOL (AcpiGetTableHeader) 393 394 395 /****************************************************************************** 396 * 397 * FUNCTION: AcpiGetTable 398 * 399 * PARAMETERS: Signature - ACPI signature of needed table 400 * Instance - Which instance (for SSDTs) 401 * OutTable - Where the pointer to the table is returned 402 * 403 * RETURN: Status and pointer to table 404 * 405 * DESCRIPTION: Finds and verifies an ACPI table. 406 * 407 *****************************************************************************/ 408 409 ACPI_STATUS 410 AcpiGetTable ( 411 char *Signature, 412 UINT32 Instance, 413 ACPI_TABLE_HEADER **OutTable) 414 { 415 UINT32 i; 416 UINT32 j; 417 ACPI_STATUS Status; 418 419 420 /* Parameter validation */ 421 422 if (!Signature || !OutTable) 423 { 424 return (AE_BAD_PARAMETER); 425 } 426 427 /* 428 * Walk the root table list 429 */ 430 for (i = 0, j = 0; i < AcpiGbl_RootTableList.Count; i++) 431 { 432 if (!ACPI_COMPARE_NAME (&(AcpiGbl_RootTableList.Tables[i].Signature), 433 Signature)) 434 { 435 continue; 436 } 437 438 if (++j < Instance) 439 { 440 continue; 441 } 442 443 Status = AcpiTbVerifyTable (&AcpiGbl_RootTableList.Tables[i]); 444 if (ACPI_SUCCESS (Status)) 445 { 446 *OutTable = AcpiGbl_RootTableList.Tables[i].Pointer; 447 } 448 449 return (Status); 450 } 451 452 return (AE_NOT_FOUND); 453 } 454 455 ACPI_EXPORT_SYMBOL (AcpiGetTable) 456 457 458 /******************************************************************************* 459 * 460 * FUNCTION: AcpiGetTableByIndex 461 * 462 * PARAMETERS: TableIndex - Table index 463 * Table - Where the pointer to the table is returned 464 * 465 * RETURN: Status and pointer to the table 466 * 467 * DESCRIPTION: Obtain a table by an index into the global table list. 468 * 469 ******************************************************************************/ 470 471 ACPI_STATUS 472 AcpiGetTableByIndex ( 473 UINT32 TableIndex, 474 ACPI_TABLE_HEADER **Table) 475 { 476 ACPI_STATUS Status; 477 478 479 ACPI_FUNCTION_TRACE (AcpiGetTableByIndex); 480 481 482 /* Parameter validation */ 483 484 if (!Table) 485 { 486 return_ACPI_STATUS (AE_BAD_PARAMETER); 487 } 488 489 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 490 491 /* Validate index */ 492 493 if (TableIndex >= AcpiGbl_RootTableList.Count) 494 { 495 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 496 return_ACPI_STATUS (AE_BAD_PARAMETER); 497 } 498 499 if (!AcpiGbl_RootTableList.Tables[TableIndex].Pointer) 500 { 501 /* Table is not mapped, map it */ 502 503 Status = AcpiTbVerifyTable (&AcpiGbl_RootTableList.Tables[TableIndex]); 504 if (ACPI_FAILURE (Status)) 505 { 506 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 507 return_ACPI_STATUS (Status); 508 } 509 } 510 511 *Table = AcpiGbl_RootTableList.Tables[TableIndex].Pointer; 512 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 513 return_ACPI_STATUS (AE_OK); 514 } 515 516 ACPI_EXPORT_SYMBOL (AcpiGetTableByIndex) 517 518 519 /******************************************************************************* 520 * 521 * FUNCTION: AcpiTbLoadNamespace 522 * 523 * PARAMETERS: None 524 * 525 * RETURN: Status 526 * 527 * DESCRIPTION: Load the namespace from the DSDT and all SSDTs/PSDTs found in 528 * the RSDT/XSDT. 529 * 530 ******************************************************************************/ 531 532 static ACPI_STATUS 533 AcpiTbLoadNamespace ( 534 void) 535 { 536 ACPI_STATUS Status; 537 ACPI_TABLE_HEADER *Table; 538 UINT32 i; 539 540 541 ACPI_FUNCTION_TRACE (TbLoadNamespace); 542 543 544 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 545 546 /* 547 * Load the namespace. The DSDT is required, but any SSDT and PSDT tables 548 * are optional. 549 */ 550 if (!AcpiGbl_RootTableList.Count || 551 !ACPI_COMPARE_NAME (&(AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT].Signature), 552 ACPI_SIG_DSDT) || 553 ACPI_FAILURE (AcpiTbVerifyTable(&AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT]))) 554 { 555 Status = AE_NO_ACPI_TABLES; 556 goto UnlockAndExit; 557 } 558 559 /* 560 * Find DSDT table 561 */ 562 Status = AcpiOsTableOverride ( 563 AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT].Pointer, &Table); 564 if (ACPI_SUCCESS (Status) && Table) 565 { 566 /* 567 * DSDT table has been found 568 */ 569 AcpiTbDeleteTable (&AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT]); 570 AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT].Pointer = Table; 571 AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT].Length = Table->Length; 572 AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT].Flags = ACPI_TABLE_ORIGIN_UNKNOWN; 573 574 ACPI_INFO ((AE_INFO, "Table DSDT replaced by host OS")); 575 AcpiTbPrintTableHeader (0, Table); 576 } 577 578 Status = AcpiTbVerifyTable (&AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT]); 579 if (ACPI_FAILURE (Status)) 580 { 581 /* A valid DSDT is required */ 582 583 Status = AE_NO_ACPI_TABLES; 584 goto UnlockAndExit; 585 } 586 587 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 588 589 /* 590 * Load and parse tables. 591 */ 592 Status = AcpiNsLoadTable (ACPI_TABLE_INDEX_DSDT, AcpiGbl_RootNode); 593 if (ACPI_FAILURE (Status)) 594 { 595 return_ACPI_STATUS (Status); 596 } 597 598 /* 599 * Load any SSDT or PSDT tables. Note: Loop leaves tables locked 600 */ 601 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 602 for (i = 0; i < AcpiGbl_RootTableList.Count; ++i) 603 { 604 if ((!ACPI_COMPARE_NAME (&(AcpiGbl_RootTableList.Tables[i].Signature), 605 ACPI_SIG_SSDT) && 606 !ACPI_COMPARE_NAME (&(AcpiGbl_RootTableList.Tables[i].Signature), 607 ACPI_SIG_PSDT)) || 608 ACPI_FAILURE (AcpiTbVerifyTable (&AcpiGbl_RootTableList.Tables[i]))) 609 { 610 continue; 611 } 612 613 /* Ignore errors while loading tables, get as many as possible */ 614 615 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 616 (void) AcpiNsLoadTable (i, AcpiGbl_RootNode); 617 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 618 } 619 620 ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "ACPI Tables successfully acquired\n")); 621 622 UnlockAndExit: 623 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 624 return_ACPI_STATUS (Status); 625 } 626 627 628 /******************************************************************************* 629 * 630 * FUNCTION: AcpiLoadTables 631 * 632 * PARAMETERS: None 633 * 634 * RETURN: Status 635 * 636 * DESCRIPTION: Load the ACPI tables from the RSDT/XSDT 637 * 638 ******************************************************************************/ 639 640 ACPI_STATUS 641 AcpiLoadTables ( 642 void) 643 { 644 ACPI_STATUS Status; 645 646 647 ACPI_FUNCTION_TRACE (AcpiLoadTables); 648 649 650 /* 651 * Load the namespace from the tables 652 */ 653 Status = AcpiTbLoadNamespace (); 654 if (ACPI_FAILURE (Status)) 655 { 656 ACPI_EXCEPTION ((AE_INFO, Status, "While loading namespace from ACPI tables")); 657 } 658 659 return_ACPI_STATUS (Status); 660 } 661 662 ACPI_EXPORT_SYMBOL (AcpiLoadTables) 663 664 665 /******************************************************************************* 666 * 667 * FUNCTION: AcpiInstallTableHandler 668 * 669 * PARAMETERS: Handler - Table event handler 670 * Context - Value passed to the handler on each event 671 * 672 * RETURN: Status 673 * 674 * DESCRIPTION: Install table event handler 675 * 676 ******************************************************************************/ 677 678 ACPI_STATUS 679 AcpiInstallTableHandler ( 680 ACPI_TABLE_HANDLER Handler, 681 void *Context) 682 { 683 ACPI_STATUS Status; 684 685 686 ACPI_FUNCTION_TRACE (AcpiInstallTableHandler); 687 688 689 if (!Handler) 690 { 691 return_ACPI_STATUS (AE_BAD_PARAMETER); 692 } 693 694 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 695 if (ACPI_FAILURE (Status)) 696 { 697 return_ACPI_STATUS (Status); 698 } 699 700 /* Don't allow more than one handler */ 701 702 if (AcpiGbl_TableHandler) 703 { 704 Status = AE_ALREADY_EXISTS; 705 goto Cleanup; 706 } 707 708 /* Install the handler */ 709 710 AcpiGbl_TableHandler = Handler; 711 AcpiGbl_TableHandlerContext = Context; 712 713 Cleanup: 714 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 715 return_ACPI_STATUS (Status); 716 } 717 718 ACPI_EXPORT_SYMBOL (AcpiInstallTableHandler) 719 720 721 /******************************************************************************* 722 * 723 * FUNCTION: AcpiRemoveTableHandler 724 * 725 * PARAMETERS: Handler - Table event handler that was installed 726 * previously. 727 * 728 * RETURN: Status 729 * 730 * DESCRIPTION: Remove table event handler 731 * 732 ******************************************************************************/ 733 734 ACPI_STATUS 735 AcpiRemoveTableHandler ( 736 ACPI_TABLE_HANDLER Handler) 737 { 738 ACPI_STATUS Status; 739 740 741 ACPI_FUNCTION_TRACE (AcpiRemoveTableHandler); 742 743 744 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 745 if (ACPI_FAILURE (Status)) 746 { 747 return_ACPI_STATUS (Status); 748 } 749 750 /* Make sure that the installed handler is the same */ 751 752 if (!Handler || 753 Handler != AcpiGbl_TableHandler) 754 { 755 Status = AE_BAD_PARAMETER; 756 goto Cleanup; 757 } 758 759 /* Remove the handler */ 760 761 AcpiGbl_TableHandler = NULL; 762 763 Cleanup: 764 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 765 return_ACPI_STATUS (Status); 766 } 767 768 ACPI_EXPORT_SYMBOL (AcpiRemoveTableHandler) 769 770