Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.28-rc2 734 lines 21 kB view raw
1/****************************************************************************** 2 * 3 * Module Name: tbxface - Public interfaces to the ACPI subsystem 4 * ACPI table oriented interfaces 5 * 6 *****************************************************************************/ 7 8/* 9 * Copyright (C) 2000 - 2008, Intel Corp. 10 * All rights reserved. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions, and the following disclaimer, 17 * without modification. 18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 19 * substantially similar to the "NO WARRANTY" disclaimer below 20 * ("Disclaimer") and any redistribution must be conditioned upon 21 * including a substantially similar Disclaimer requirement for further 22 * binary redistribution. 23 * 3. Neither the names of the above-listed copyright holders nor the names 24 * of any contributors may be used to endorse or promote products derived 25 * from this software without specific prior written permission. 26 * 27 * Alternatively, this software may be distributed under the terms of the 28 * GNU General Public License ("GPL") version 2 as published by the Free 29 * Software Foundation. 30 * 31 * NO WARRANTY 32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 42 * POSSIBILITY OF SUCH DAMAGES. 43 */ 44 45#include <acpi/acpi.h> 46#include <acpi/acnamesp.h> 47#include <acpi/actables.h> 48 49#define _COMPONENT ACPI_TABLES 50ACPI_MODULE_NAME("tbxface") 51 52/* Local prototypes */ 53static acpi_status acpi_tb_load_namespace(void); 54 55static int no_auto_ssdt; 56 57/******************************************************************************* 58 * 59 * FUNCTION: acpi_allocate_root_table 60 * 61 * PARAMETERS: initial_table_count - Size of initial_table_array, in number of 62 * struct acpi_table_desc structures 63 * 64 * RETURN: Status 65 * 66 * DESCRIPTION: Allocate a root table array. Used by i_aSL compiler and 67 * acpi_initialize_tables. 68 * 69 ******************************************************************************/ 70 71acpi_status acpi_allocate_root_table(u32 initial_table_count) 72{ 73 74 acpi_gbl_root_table_list.size = initial_table_count; 75 acpi_gbl_root_table_list.flags = ACPI_ROOT_ALLOW_RESIZE; 76 77 return (acpi_tb_resize_root_table_list()); 78} 79 80/******************************************************************************* 81 * 82 * FUNCTION: acpi_initialize_tables 83 * 84 * PARAMETERS: initial_table_array - Pointer to an array of pre-allocated 85 * struct acpi_table_desc structures. If NULL, the 86 * array is dynamically allocated. 87 * initial_table_count - Size of initial_table_array, in number of 88 * struct acpi_table_desc structures 89 * allow_realloc - Flag to tell Table Manager if resize of 90 * pre-allocated array is allowed. Ignored 91 * if initial_table_array is NULL. 92 * 93 * RETURN: Status 94 * 95 * DESCRIPTION: Initialize the table manager, get the RSDP and RSDT/XSDT. 96 * 97 * NOTE: Allows static allocation of the initial table array in order 98 * to avoid the use of dynamic memory in confined environments 99 * such as the kernel boot sequence where it may not be available. 100 * 101 * If the host OS memory managers are initialized, use NULL for 102 * initial_table_array, and the table will be dynamically allocated. 103 * 104 ******************************************************************************/ 105 106acpi_status __init 107acpi_initialize_tables(struct acpi_table_desc * initial_table_array, 108 u32 initial_table_count, u8 allow_resize) 109{ 110 acpi_physical_address rsdp_address; 111 acpi_status status; 112 113 ACPI_FUNCTION_TRACE(acpi_initialize_tables); 114 115 /* 116 * Set up the Root Table Array 117 * Allocate the table array if requested 118 */ 119 if (!initial_table_array) { 120 status = acpi_allocate_root_table(initial_table_count); 121 if (ACPI_FAILURE(status)) { 122 return_ACPI_STATUS(status); 123 } 124 } else { 125 /* Root Table Array has been statically allocated by the host */ 126 127 ACPI_MEMSET(initial_table_array, 0, 128 (acpi_size) initial_table_count * 129 sizeof(struct acpi_table_desc)); 130 131 acpi_gbl_root_table_list.tables = initial_table_array; 132 acpi_gbl_root_table_list.size = initial_table_count; 133 acpi_gbl_root_table_list.flags = ACPI_ROOT_ORIGIN_UNKNOWN; 134 if (allow_resize) { 135 acpi_gbl_root_table_list.flags |= 136 ACPI_ROOT_ALLOW_RESIZE; 137 } 138 } 139 140 /* Get the address of the RSDP */ 141 142 rsdp_address = acpi_os_get_root_pointer(); 143 if (!rsdp_address) { 144 return_ACPI_STATUS(AE_NOT_FOUND); 145 } 146 147 /* 148 * Get the root table (RSDT or XSDT) and extract all entries to the local 149 * Root Table Array. This array contains the information of the RSDT/XSDT 150 * in a common, more useable format. 151 */ 152 status = 153 acpi_tb_parse_root_table(rsdp_address, ACPI_TABLE_ORIGIN_MAPPED); 154 return_ACPI_STATUS(status); 155} 156 157/******************************************************************************* 158 * 159 * FUNCTION: acpi_reallocate_root_table 160 * 161 * PARAMETERS: None 162 * 163 * RETURN: Status 164 * 165 * DESCRIPTION: Reallocate Root Table List into dynamic memory. Copies the 166 * root list from the previously provided scratch area. Should 167 * be called once dynamic memory allocation is available in the 168 * kernel 169 * 170 ******************************************************************************/ 171acpi_status acpi_reallocate_root_table(void) 172{ 173 struct acpi_table_desc *tables; 174 acpi_size new_size; 175 176 ACPI_FUNCTION_TRACE(acpi_reallocate_root_table); 177 178 /* 179 * Only reallocate the root table if the host provided a static buffer 180 * for the table array in the call to acpi_initialize_tables. 181 */ 182 if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) { 183 return_ACPI_STATUS(AE_SUPPORT); 184 } 185 186 new_size = ((acpi_size) acpi_gbl_root_table_list.count + 187 ACPI_ROOT_TABLE_SIZE_INCREMENT) * 188 sizeof(struct acpi_table_desc); 189 190 /* Create new array and copy the old array */ 191 192 tables = ACPI_ALLOCATE_ZEROED(new_size); 193 if (!tables) { 194 return_ACPI_STATUS(AE_NO_MEMORY); 195 } 196 197 ACPI_MEMCPY(tables, acpi_gbl_root_table_list.tables, new_size); 198 199 acpi_gbl_root_table_list.size = acpi_gbl_root_table_list.count; 200 acpi_gbl_root_table_list.tables = tables; 201 acpi_gbl_root_table_list.flags = 202 ACPI_ROOT_ORIGIN_ALLOCATED | ACPI_ROOT_ALLOW_RESIZE; 203 204 return_ACPI_STATUS(AE_OK); 205} 206 207/******************************************************************************* 208 * 209 * FUNCTION: acpi_load_table 210 * 211 * PARAMETERS: table_ptr - pointer to a buffer containing the entire 212 * table to be loaded 213 * 214 * RETURN: Status 215 * 216 * DESCRIPTION: This function is called to load a table from the caller's 217 * buffer. The buffer must contain an entire ACPI Table including 218 * a valid header. The header fields will be verified, and if it 219 * is determined that the table is invalid, the call will fail. 220 * 221 ******************************************************************************/ 222acpi_status acpi_load_table(struct acpi_table_header *table_ptr) 223{ 224 acpi_status status; 225 u32 table_index; 226 struct acpi_table_desc table_desc; 227 228 if (!table_ptr) 229 return AE_BAD_PARAMETER; 230 231 ACPI_MEMSET(&table_desc, 0, sizeof(struct acpi_table_desc)); 232 table_desc.pointer = table_ptr; 233 table_desc.length = table_ptr->length; 234 table_desc.flags = ACPI_TABLE_ORIGIN_UNKNOWN; 235 236 /* 237 * Install the new table into the local data structures 238 */ 239 status = acpi_tb_add_table(&table_desc, &table_index); 240 if (ACPI_FAILURE(status)) { 241 return status; 242 } 243 status = acpi_ns_load_table(table_index, acpi_gbl_root_node); 244 return status; 245} 246 247ACPI_EXPORT_SYMBOL(acpi_load_table) 248 249/****************************************************************************** 250 * 251 * FUNCTION: acpi_get_table_header 252 * 253 * PARAMETERS: Signature - ACPI signature of needed table 254 * Instance - Which instance (for SSDTs) 255 * out_table_header - The pointer to the table header to fill 256 * 257 * RETURN: Status and pointer to mapped table header 258 * 259 * DESCRIPTION: Finds an ACPI table header. 260 * 261 * NOTE: Caller is responsible in unmapping the header with 262 * acpi_os_unmap_memory 263 * 264 *****************************************************************************/ 265acpi_status 266acpi_get_table_header(char *signature, 267 u32 instance, struct acpi_table_header *out_table_header) 268{ 269 u32 i; 270 u32 j; 271 struct acpi_table_header *header; 272 273 /* Parameter validation */ 274 275 if (!signature || !out_table_header) { 276 return (AE_BAD_PARAMETER); 277 } 278 279 /* 280 * Walk the root table list 281 */ 282 for (i = 0, j = 0; i < acpi_gbl_root_table_list.count; i++) { 283 if (!ACPI_COMPARE_NAME 284 (&(acpi_gbl_root_table_list.tables[i].signature), 285 signature)) { 286 continue; 287 } 288 289 if (++j < instance) { 290 continue; 291 } 292 293 if (!acpi_gbl_root_table_list.tables[i].pointer) { 294 if ((acpi_gbl_root_table_list.tables[i]. 295 flags & ACPI_TABLE_ORIGIN_MASK) == 296 ACPI_TABLE_ORIGIN_MAPPED) { 297 header = 298 acpi_os_map_memory(acpi_gbl_root_table_list. 299 tables[i].address, 300 sizeof(struct 301 acpi_table_header)); 302 if (!header) { 303 return AE_NO_MEMORY; 304 } 305 ACPI_MEMCPY(out_table_header, header, 306 sizeof(struct acpi_table_header)); 307 acpi_os_unmap_memory(header, 308 sizeof(struct 309 acpi_table_header)); 310 } else { 311 return AE_NOT_FOUND; 312 } 313 } else { 314 ACPI_MEMCPY(out_table_header, 315 acpi_gbl_root_table_list.tables[i].pointer, 316 sizeof(struct acpi_table_header)); 317 } 318 return (AE_OK); 319 } 320 321 return (AE_NOT_FOUND); 322} 323 324ACPI_EXPORT_SYMBOL(acpi_get_table_header) 325 326/****************************************************************************** 327 * 328 * FUNCTION: acpi_unload_table_id 329 * 330 * PARAMETERS: id - Owner ID of the table to be removed. 331 * 332 * RETURN: Status 333 * 334 * DESCRIPTION: This routine is used to force the unload of a table (by id) 335 * 336 ******************************************************************************/ 337acpi_status acpi_unload_table_id(acpi_owner_id id) 338{ 339 int i; 340 acpi_status status = AE_NOT_EXIST; 341 342 ACPI_FUNCTION_TRACE(acpi_unload_table_id); 343 344 /* Find table in the global table list */ 345 for (i = 0; i < acpi_gbl_root_table_list.count; ++i) { 346 if (id != acpi_gbl_root_table_list.tables[i].owner_id) { 347 continue; 348 } 349 /* 350 * Delete all namespace objects owned by this table. Note that these 351 * objects can appear anywhere in the namespace by virtue of the AML 352 * "Scope" operator. Thus, we need to track ownership by an ID, not 353 * simply a position within the hierarchy 354 */ 355 acpi_tb_delete_namespace_by_owner(i); 356 status = acpi_tb_release_owner_id(i); 357 acpi_tb_set_table_loaded_flag(i, FALSE); 358 break; 359 } 360 return_ACPI_STATUS(status); 361} 362 363ACPI_EXPORT_SYMBOL(acpi_unload_table_id) 364 365/******************************************************************************* 366 * 367 * FUNCTION: acpi_get_table 368 * 369 * PARAMETERS: Signature - ACPI signature of needed table 370 * Instance - Which instance (for SSDTs) 371 * out_table - Where the pointer to the table is returned 372 * 373 * RETURN: Status and pointer to table 374 * 375 * DESCRIPTION: Finds and verifies an ACPI table. 376 * 377 *****************************************************************************/ 378acpi_status 379acpi_get_table(char *signature, 380 u32 instance, struct acpi_table_header **out_table) 381{ 382 u32 i; 383 u32 j; 384 acpi_status status; 385 386 /* Parameter validation */ 387 388 if (!signature || !out_table) { 389 return (AE_BAD_PARAMETER); 390 } 391 392 /* 393 * Walk the root table list 394 */ 395 for (i = 0, j = 0; i < acpi_gbl_root_table_list.count; i++) { 396 if (!ACPI_COMPARE_NAME 397 (&(acpi_gbl_root_table_list.tables[i].signature), 398 signature)) { 399 continue; 400 } 401 402 if (++j < instance) { 403 continue; 404 } 405 406 status = 407 acpi_tb_verify_table(&acpi_gbl_root_table_list.tables[i]); 408 if (ACPI_SUCCESS(status)) { 409 *out_table = acpi_gbl_root_table_list.tables[i].pointer; 410 } 411 412 if (!acpi_gbl_permanent_mmap) { 413 acpi_gbl_root_table_list.tables[i].pointer = NULL; 414 } 415 416 return (status); 417 } 418 419 return (AE_NOT_FOUND); 420} 421 422ACPI_EXPORT_SYMBOL(acpi_get_table) 423 424/******************************************************************************* 425 * 426 * FUNCTION: acpi_get_table_by_index 427 * 428 * PARAMETERS: table_index - Table index 429 * Table - Where the pointer to the table is returned 430 * 431 * RETURN: Status and pointer to the table 432 * 433 * DESCRIPTION: Obtain a table by an index into the global table list. 434 * 435 ******************************************************************************/ 436acpi_status 437acpi_get_table_by_index(u32 table_index, struct acpi_table_header **table) 438{ 439 acpi_status status; 440 441 ACPI_FUNCTION_TRACE(acpi_get_table_by_index); 442 443 /* Parameter validation */ 444 445 if (!table) { 446 return_ACPI_STATUS(AE_BAD_PARAMETER); 447 } 448 449 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 450 451 /* Validate index */ 452 453 if (table_index >= acpi_gbl_root_table_list.count) { 454 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 455 return_ACPI_STATUS(AE_BAD_PARAMETER); 456 } 457 458 if (!acpi_gbl_root_table_list.tables[table_index].pointer) { 459 460 /* Table is not mapped, map it */ 461 462 status = 463 acpi_tb_verify_table(&acpi_gbl_root_table_list. 464 tables[table_index]); 465 if (ACPI_FAILURE(status)) { 466 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 467 return_ACPI_STATUS(status); 468 } 469 } 470 471 *table = acpi_gbl_root_table_list.tables[table_index].pointer; 472 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 473 return_ACPI_STATUS(AE_OK); 474} 475 476ACPI_EXPORT_SYMBOL(acpi_get_table_by_index) 477 478/******************************************************************************* 479 * 480 * FUNCTION: acpi_tb_load_namespace 481 * 482 * PARAMETERS: None 483 * 484 * RETURN: Status 485 * 486 * DESCRIPTION: Load the namespace from the DSDT and all SSDTs/PSDTs found in 487 * the RSDT/XSDT. 488 * 489 ******************************************************************************/ 490static acpi_status acpi_tb_load_namespace(void) 491{ 492 acpi_status status; 493 struct acpi_table_header *table; 494 u32 i; 495 496 ACPI_FUNCTION_TRACE(tb_load_namespace); 497 498 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 499 500 /* 501 * Load the namespace. The DSDT is required, but any SSDT and PSDT tables 502 * are optional. 503 */ 504 if (!acpi_gbl_root_table_list.count || 505 !ACPI_COMPARE_NAME(& 506 (acpi_gbl_root_table_list. 507 tables[ACPI_TABLE_INDEX_DSDT].signature), 508 ACPI_SIG_DSDT) 509 || 510 ACPI_FAILURE(acpi_tb_verify_table 511 (&acpi_gbl_root_table_list. 512 tables[ACPI_TABLE_INDEX_DSDT]))) { 513 status = AE_NO_ACPI_TABLES; 514 goto unlock_and_exit; 515 } 516 517 /* 518 * Find DSDT table 519 */ 520 status = 521 acpi_os_table_override(acpi_gbl_root_table_list. 522 tables[ACPI_TABLE_INDEX_DSDT].pointer, 523 &table); 524 if (ACPI_SUCCESS(status) && table) { 525 /* 526 * DSDT table has been found 527 */ 528 acpi_tb_delete_table(&acpi_gbl_root_table_list. 529 tables[ACPI_TABLE_INDEX_DSDT]); 530 acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].pointer = 531 table; 532 acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].length = 533 table->length; 534 acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].flags = 535 ACPI_TABLE_ORIGIN_UNKNOWN; 536 537 ACPI_INFO((AE_INFO, "Table DSDT replaced by host OS")); 538 acpi_tb_print_table_header(0, table); 539 540 if (no_auto_ssdt == 0) { 541 printk(KERN_WARNING "ACPI: DSDT override uses original SSDTs unless \"acpi_no_auto_ssdt\"\n"); 542 } 543 } 544 545 status = 546 acpi_tb_verify_table(&acpi_gbl_root_table_list. 547 tables[ACPI_TABLE_INDEX_DSDT]); 548 if (ACPI_FAILURE(status)) { 549 550 /* A valid DSDT is required */ 551 552 status = AE_NO_ACPI_TABLES; 553 goto unlock_and_exit; 554 } 555 556 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 557 558 /* 559 * Load and parse tables. 560 */ 561 status = acpi_ns_load_table(ACPI_TABLE_INDEX_DSDT, acpi_gbl_root_node); 562 if (ACPI_FAILURE(status)) { 563 return_ACPI_STATUS(status); 564 } 565 566 /* 567 * Load any SSDT or PSDT tables. Note: Loop leaves tables locked 568 */ 569 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 570 for (i = 0; i < acpi_gbl_root_table_list.count; ++i) { 571 if ((!ACPI_COMPARE_NAME 572 (&(acpi_gbl_root_table_list.tables[i].signature), 573 ACPI_SIG_SSDT) 574 && 575 !ACPI_COMPARE_NAME(& 576 (acpi_gbl_root_table_list.tables[i]. 577 signature), ACPI_SIG_PSDT)) 578 || 579 ACPI_FAILURE(acpi_tb_verify_table 580 (&acpi_gbl_root_table_list.tables[i]))) { 581 continue; 582 } 583 584 if (no_auto_ssdt) { 585 printk(KERN_WARNING "ACPI: SSDT ignored due to \"acpi_no_auto_ssdt\"\n"); 586 continue; 587 } 588 589 /* Ignore errors while loading tables, get as many as possible */ 590 591 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 592 (void)acpi_ns_load_table(i, acpi_gbl_root_node); 593 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 594 } 595 596 ACPI_DEBUG_PRINT((ACPI_DB_INIT, "ACPI Tables successfully acquired\n")); 597 598 unlock_and_exit: 599 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 600 return_ACPI_STATUS(status); 601} 602 603/******************************************************************************* 604 * 605 * FUNCTION: acpi_load_tables 606 * 607 * PARAMETERS: None 608 * 609 * RETURN: Status 610 * 611 * DESCRIPTION: Load the ACPI tables from the RSDT/XSDT 612 * 613 ******************************************************************************/ 614 615acpi_status acpi_load_tables(void) 616{ 617 acpi_status status; 618 619 ACPI_FUNCTION_TRACE(acpi_load_tables); 620 621 /* 622 * Load the namespace from the tables 623 */ 624 status = acpi_tb_load_namespace(); 625 if (ACPI_FAILURE(status)) { 626 ACPI_EXCEPTION((AE_INFO, status, 627 "While loading namespace from ACPI tables")); 628 } 629 630 return_ACPI_STATUS(status); 631} 632 633ACPI_EXPORT_SYMBOL(acpi_load_tables) 634 635 636/******************************************************************************* 637 * 638 * FUNCTION: acpi_install_table_handler 639 * 640 * PARAMETERS: Handler - Table event handler 641 * Context - Value passed to the handler on each event 642 * 643 * RETURN: Status 644 * 645 * DESCRIPTION: Install table event handler 646 * 647 ******************************************************************************/ 648acpi_status 649acpi_install_table_handler(acpi_tbl_handler handler, void *context) 650{ 651 acpi_status status; 652 653 ACPI_FUNCTION_TRACE(acpi_install_table_handler); 654 655 if (!handler) { 656 return_ACPI_STATUS(AE_BAD_PARAMETER); 657 } 658 659 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); 660 if (ACPI_FAILURE(status)) { 661 return_ACPI_STATUS(status); 662 } 663 664 /* Don't allow more than one handler */ 665 666 if (acpi_gbl_table_handler) { 667 status = AE_ALREADY_EXISTS; 668 goto cleanup; 669 } 670 671 /* Install the handler */ 672 673 acpi_gbl_table_handler = handler; 674 acpi_gbl_table_handler_context = context; 675 676 cleanup: 677 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); 678 return_ACPI_STATUS(status); 679} 680 681ACPI_EXPORT_SYMBOL(acpi_install_table_handler) 682 683/******************************************************************************* 684 * 685 * FUNCTION: acpi_remove_table_handler 686 * 687 * PARAMETERS: Handler - Table event handler that was installed 688 * previously. 689 * 690 * RETURN: Status 691 * 692 * DESCRIPTION: Remove table event handler 693 * 694 ******************************************************************************/ 695acpi_status acpi_remove_table_handler(acpi_tbl_handler handler) 696{ 697 acpi_status status; 698 699 ACPI_FUNCTION_TRACE(acpi_remove_table_handler); 700 701 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); 702 if (ACPI_FAILURE(status)) { 703 return_ACPI_STATUS(status); 704 } 705 706 /* Make sure that the installed handler is the same */ 707 708 if (!handler || handler != acpi_gbl_table_handler) { 709 status = AE_BAD_PARAMETER; 710 goto cleanup; 711 } 712 713 /* Remove the handler */ 714 715 acpi_gbl_table_handler = NULL; 716 717 cleanup: 718 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); 719 return_ACPI_STATUS(status); 720} 721 722ACPI_EXPORT_SYMBOL(acpi_remove_table_handler) 723 724 725static int __init acpi_no_auto_ssdt_setup(char *s) { 726 727 printk(KERN_NOTICE "ACPI: SSDT auto-load disabled\n"); 728 729 no_auto_ssdt = 1; 730 731 return 1; 732} 733 734__setup("acpi_no_auto_ssdt", acpi_no_auto_ssdt_setup);