1238367Sjkim/****************************************************************************** 2238367Sjkim * 3238367Sjkim * Module Name: tbxfload - Table load/unload external interfaces 4238367Sjkim * 5238367Sjkim *****************************************************************************/ 6238367Sjkim 7238367Sjkim/* 8306536Sjkim * Copyright (C) 2000 - 2016, Intel Corp. 9238367Sjkim * All rights reserved. 10238367Sjkim * 11238367Sjkim * Redistribution and use in source and binary forms, with or without 12238367Sjkim * modification, are permitted provided that the following conditions 13238367Sjkim * are met: 14238367Sjkim * 1. Redistributions of source code must retain the above copyright 15238367Sjkim * notice, this list of conditions, and the following disclaimer, 16238367Sjkim * without modification. 17238367Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18238367Sjkim * substantially similar to the "NO WARRANTY" disclaimer below 19238367Sjkim * ("Disclaimer") and any redistribution must be conditioned upon 20238367Sjkim * including a substantially similar Disclaimer requirement for further 21238367Sjkim * binary redistribution. 22238367Sjkim * 3. Neither the names of the above-listed copyright holders nor the names 23238367Sjkim * of any contributors may be used to endorse or promote products derived 24238367Sjkim * from this software without specific prior written permission. 25238367Sjkim * 26238367Sjkim * Alternatively, this software may be distributed under the terms of the 27238367Sjkim * GNU General Public License ("GPL") version 2 as published by the Free 28238367Sjkim * Software Foundation. 29238367Sjkim * 30238367Sjkim * NO WARRANTY 31238367Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32238367Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33238367Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34238367Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35238367Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36238367Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37238367Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38238367Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39238367Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40238367Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41238367Sjkim * POSSIBILITY OF SUCH DAMAGES. 42238367Sjkim */ 43238367Sjkim 44281075Sdim#define EXPORT_ACPI_INTERFACES 45238367Sjkim 46238381Sjkim#include <contrib/dev/acpica/include/acpi.h> 47238381Sjkim#include <contrib/dev/acpica/include/accommon.h> 48238381Sjkim#include <contrib/dev/acpica/include/acnamesp.h> 49238381Sjkim#include <contrib/dev/acpica/include/actables.h> 50306536Sjkim#include <contrib/dev/acpica/include/acevents.h> 51238367Sjkim 52238367Sjkim#define _COMPONENT ACPI_TABLES 53238367Sjkim ACPI_MODULE_NAME ("tbxfload") 54238367Sjkim 55238367Sjkim 56238367Sjkim/******************************************************************************* 57238367Sjkim * 58238367Sjkim * FUNCTION: AcpiLoadTables 59238367Sjkim * 60238367Sjkim * PARAMETERS: None 61238367Sjkim * 62238367Sjkim * RETURN: Status 63238367Sjkim * 64238367Sjkim * DESCRIPTION: Load the ACPI tables from the RSDT/XSDT 65238367Sjkim * 66238367Sjkim ******************************************************************************/ 67238367Sjkim 68238367SjkimACPI_STATUS 69238367SjkimAcpiLoadTables ( 70238367Sjkim void) 71238367Sjkim{ 72238367Sjkim ACPI_STATUS Status; 73238367Sjkim 74238367Sjkim 75238367Sjkim ACPI_FUNCTION_TRACE (AcpiLoadTables); 76238367Sjkim 77238367Sjkim 78306536Sjkim /* 79306536Sjkim * Install the default operation region handlers. These are the 80306536Sjkim * handlers that are defined by the ACPI specification to be 81306536Sjkim * "always accessible" -- namely, SystemMemory, SystemIO, and 82306536Sjkim * PCI_Config. This also means that no _REG methods need to be 83306536Sjkim * run for these address spaces. We need to have these handlers 84306536Sjkim * installed before any AML code can be executed, especially any 85306536Sjkim * module-level code (11/2015). 86306536Sjkim * Note that we allow OSPMs to install their own region handlers 87306536Sjkim * between AcpiInitializeSubsystem() and AcpiLoadTables() to use 88306536Sjkim * their customized default region handlers. 89306536Sjkim */ 90306536Sjkim Status = AcpiEvInstallRegionHandlers (); 91306536Sjkim if (ACPI_FAILURE (Status)) 92306536Sjkim { 93306536Sjkim ACPI_EXCEPTION ((AE_INFO, Status, "During Region initialization")); 94306536Sjkim return_ACPI_STATUS (Status); 95306536Sjkim } 96306536Sjkim 97238367Sjkim /* Load the namespace from the tables */ 98238367Sjkim 99238367Sjkim Status = AcpiTbLoadNamespace (); 100306536Sjkim 101306536Sjkim /* Don't let single failures abort the load */ 102306536Sjkim 103306536Sjkim if (Status == AE_CTRL_TERMINATE) 104306536Sjkim { 105306536Sjkim Status = AE_OK; 106306536Sjkim } 107306536Sjkim 108238367Sjkim if (ACPI_FAILURE (Status)) 109238367Sjkim { 110238367Sjkim ACPI_EXCEPTION ((AE_INFO, Status, 111238367Sjkim "While loading namespace from ACPI tables")); 112238367Sjkim } 113238367Sjkim 114306536Sjkim if (!AcpiGbl_GroupModuleLevelCode) 115306536Sjkim { 116306536Sjkim /* 117306536Sjkim * Initialize the objects that remain uninitialized. This 118306536Sjkim * runs the executable AML that may be part of the 119306536Sjkim * declaration of these objects: 120306536Sjkim * OperationRegions, BufferFields, Buffers, and Packages. 121306536Sjkim */ 122306536Sjkim Status = AcpiNsInitializeObjects (); 123306536Sjkim if (ACPI_FAILURE (Status)) 124306536Sjkim { 125306536Sjkim return_ACPI_STATUS (Status); 126306536Sjkim } 127306536Sjkim } 128306536Sjkim 129306536Sjkim AcpiGbl_NamespaceInitialized = TRUE; 130238367Sjkim return_ACPI_STATUS (Status); 131238367Sjkim} 132238367Sjkim 133281075SdimACPI_EXPORT_SYMBOL_INIT (AcpiLoadTables) 134238367Sjkim 135238367Sjkim 136238367Sjkim/******************************************************************************* 137238367Sjkim * 138238367Sjkim * FUNCTION: AcpiTbLoadNamespace 139238367Sjkim * 140238367Sjkim * PARAMETERS: None 141238367Sjkim * 142238367Sjkim * RETURN: Status 143238367Sjkim * 144238367Sjkim * DESCRIPTION: Load the namespace from the DSDT and all SSDTs/PSDTs found in 145238367Sjkim * the RSDT/XSDT. 146238367Sjkim * 147238367Sjkim ******************************************************************************/ 148238367Sjkim 149306536SjkimACPI_STATUS 150238367SjkimAcpiTbLoadNamespace ( 151238367Sjkim void) 152238367Sjkim{ 153238367Sjkim ACPI_STATUS Status; 154238367Sjkim UINT32 i; 155238367Sjkim ACPI_TABLE_HEADER *NewDsdt; 156306536Sjkim ACPI_TABLE_DESC *Table; 157306536Sjkim UINT32 TablesLoaded = 0; 158306536Sjkim UINT32 TablesFailed = 0; 159238367Sjkim 160238367Sjkim 161238367Sjkim ACPI_FUNCTION_TRACE (TbLoadNamespace); 162238367Sjkim 163238367Sjkim 164238367Sjkim (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 165238367Sjkim 166238367Sjkim /* 167238367Sjkim * Load the namespace. The DSDT is required, but any SSDT and 168238367Sjkim * PSDT tables are optional. Verify the DSDT. 169238367Sjkim */ 170306536Sjkim Table = &AcpiGbl_RootTableList.Tables[AcpiGbl_DsdtIndex]; 171306536Sjkim 172238367Sjkim if (!AcpiGbl_RootTableList.CurrentTableCount || 173306536Sjkim !ACPI_COMPARE_NAME (Table->Signature.Ascii, ACPI_SIG_DSDT) || 174306536Sjkim ACPI_FAILURE (AcpiTbValidateTable (Table))) 175238367Sjkim { 176238367Sjkim Status = AE_NO_ACPI_TABLES; 177238367Sjkim goto UnlockAndExit; 178238367Sjkim } 179238367Sjkim 180238367Sjkim /* 181238367Sjkim * Save the DSDT pointer for simple access. This is the mapped memory 182238367Sjkim * address. We must take care here because the address of the .Tables 183238367Sjkim * array can change dynamically as tables are loaded at run-time. Note: 184281075Sdim * .Pointer field is not validated until after call to AcpiTbValidateTable. 185238367Sjkim */ 186306536Sjkim AcpiGbl_DSDT = Table->Pointer; 187238367Sjkim 188238367Sjkim /* 189238367Sjkim * Optionally copy the entire DSDT to local memory (instead of simply 190238367Sjkim * mapping it.) There are some BIOSs that corrupt or replace the original 191238367Sjkim * DSDT, creating the need for this option. Default is FALSE, do not copy 192238367Sjkim * the DSDT. 193238367Sjkim */ 194238367Sjkim if (AcpiGbl_CopyDsdtLocally) 195238367Sjkim { 196306536Sjkim NewDsdt = AcpiTbCopyDsdt (AcpiGbl_DsdtIndex); 197238367Sjkim if (NewDsdt) 198238367Sjkim { 199238367Sjkim AcpiGbl_DSDT = NewDsdt; 200238367Sjkim } 201238367Sjkim } 202238367Sjkim 203238367Sjkim /* 204238367Sjkim * Save the original DSDT header for detection of table corruption 205238367Sjkim * and/or replacement of the DSDT from outside the OS. 206238367Sjkim */ 207306536Sjkim memcpy (&AcpiGbl_OriginalDsdtHeader, AcpiGbl_DSDT, 208238367Sjkim sizeof (ACPI_TABLE_HEADER)); 209238367Sjkim 210238367Sjkim (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 211238367Sjkim 212238367Sjkim /* Load and parse tables */ 213238367Sjkim 214306536Sjkim Status = AcpiNsLoadTable (AcpiGbl_DsdtIndex, AcpiGbl_RootNode); 215238367Sjkim if (ACPI_FAILURE (Status)) 216238367Sjkim { 217306536Sjkim ACPI_EXCEPTION ((AE_INFO, Status, "[DSDT] table load failed")); 218306536Sjkim TablesFailed++; 219238367Sjkim } 220306536Sjkim else 221306536Sjkim { 222306536Sjkim TablesLoaded++; 223306536Sjkim } 224238367Sjkim 225238367Sjkim /* Load any SSDT or PSDT tables. Note: Loop leaves tables locked */ 226238367Sjkim 227238367Sjkim (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 228250838Sjkim for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; ++i) 229238367Sjkim { 230306536Sjkim Table = &AcpiGbl_RootTableList.Tables[i]; 231306536Sjkim 232306536Sjkim if (!AcpiGbl_RootTableList.Tables[i].Address || 233306536Sjkim (!ACPI_COMPARE_NAME (Table->Signature.Ascii, ACPI_SIG_SSDT) && 234306536Sjkim !ACPI_COMPARE_NAME (Table->Signature.Ascii, ACPI_SIG_PSDT) && 235306536Sjkim !ACPI_COMPARE_NAME (Table->Signature.Ascii, ACPI_SIG_OSDT)) || 236306536Sjkim ACPI_FAILURE (AcpiTbValidateTable (Table))) 237238367Sjkim { 238238367Sjkim continue; 239238367Sjkim } 240238367Sjkim 241238367Sjkim /* Ignore errors while loading tables, get as many as possible */ 242238367Sjkim 243238367Sjkim (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 244306536Sjkim Status = AcpiNsLoadTable (i, AcpiGbl_RootNode); 245306536Sjkim if (ACPI_FAILURE (Status)) 246306536Sjkim { 247306536Sjkim ACPI_EXCEPTION ((AE_INFO, Status, "(%4.4s:%8.8s) while loading table", 248306536Sjkim Table->Signature.Ascii, Table->Pointer->OemTableId)); 249306536Sjkim 250306536Sjkim TablesFailed++; 251306536Sjkim 252306536Sjkim ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, 253306536Sjkim "Table [%4.4s:%8.8s] (id FF) - Table namespace load failed\n\n", 254306536Sjkim Table->Signature.Ascii, Table->Pointer->OemTableId)); 255306536Sjkim } 256306536Sjkim else 257306536Sjkim { 258306536Sjkim TablesLoaded++; 259306536Sjkim } 260306536Sjkim 261238367Sjkim (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 262238367Sjkim } 263238367Sjkim 264306536Sjkim if (!TablesFailed) 265306536Sjkim { 266306536Sjkim ACPI_INFO (( 267306536Sjkim "%u ACPI AML tables successfully acquired and loaded\n", 268306536Sjkim TablesLoaded)); 269306536Sjkim } 270306536Sjkim else 271306536Sjkim { 272306536Sjkim ACPI_ERROR ((AE_INFO, 273306536Sjkim "%u table load failures, %u successful", 274306536Sjkim TablesFailed, TablesLoaded)); 275238367Sjkim 276306536Sjkim /* Indicate at least one failure */ 277306536Sjkim 278306536Sjkim Status = AE_CTRL_TERMINATE; 279306536Sjkim } 280306536Sjkim 281238367SjkimUnlockAndExit: 282238367Sjkim (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 283238367Sjkim return_ACPI_STATUS (Status); 284238367Sjkim} 285238367Sjkim 286238367Sjkim 287238367Sjkim/******************************************************************************* 288238367Sjkim * 289281075Sdim * FUNCTION: AcpiInstallTable 290281075Sdim * 291281075Sdim * PARAMETERS: Address - Address of the ACPI table to be installed. 292281075Sdim * Physical - Whether the address is a physical table 293281075Sdim * address or not 294281075Sdim * 295281075Sdim * RETURN: Status 296281075Sdim * 297281075Sdim * DESCRIPTION: Dynamically install an ACPI table. 298281075Sdim * Note: This function should only be invoked after 299281075Sdim * AcpiInitializeTables() and before AcpiLoadTables(). 300281075Sdim * 301281075Sdim ******************************************************************************/ 302281075Sdim 303281075SdimACPI_STATUS 304281075SdimAcpiInstallTable ( 305281075Sdim ACPI_PHYSICAL_ADDRESS Address, 306281075Sdim BOOLEAN Physical) 307281075Sdim{ 308281075Sdim ACPI_STATUS Status; 309281075Sdim UINT8 Flags; 310281075Sdim UINT32 TableIndex; 311281075Sdim 312281075Sdim 313281075Sdim ACPI_FUNCTION_TRACE (AcpiInstallTable); 314281075Sdim 315281075Sdim 316281075Sdim if (Physical) 317281075Sdim { 318306536Sjkim Flags = ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL; 319281075Sdim } 320281075Sdim else 321281075Sdim { 322306536Sjkim Flags = ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL; 323281075Sdim } 324281075Sdim 325281075Sdim Status = AcpiTbInstallStandardTable (Address, Flags, 326281075Sdim FALSE, FALSE, &TableIndex); 327281075Sdim 328281075Sdim return_ACPI_STATUS (Status); 329281075Sdim} 330281075Sdim 331281075SdimACPI_EXPORT_SYMBOL_INIT (AcpiInstallTable) 332281075Sdim 333281075Sdim 334281075Sdim/******************************************************************************* 335281075Sdim * 336238367Sjkim * FUNCTION: AcpiLoadTable 337238367Sjkim * 338238367Sjkim * PARAMETERS: Table - Pointer to a buffer containing the ACPI 339238367Sjkim * table to be loaded. 340238367Sjkim * 341238367Sjkim * RETURN: Status 342238367Sjkim * 343238367Sjkim * DESCRIPTION: Dynamically load an ACPI table from the caller's buffer. Must 344238367Sjkim * be a valid ACPI table with a valid ACPI table header. 345238367Sjkim * Note1: Mainly intended to support hotplug addition of SSDTs. 346241973Sjkim * Note2: Does not copy the incoming table. User is responsible 347238367Sjkim * to ensure that the table is not deleted or unmapped. 348238367Sjkim * 349238367Sjkim ******************************************************************************/ 350238367Sjkim 351238367SjkimACPI_STATUS 352238367SjkimAcpiLoadTable ( 353238367Sjkim ACPI_TABLE_HEADER *Table) 354238367Sjkim{ 355238367Sjkim ACPI_STATUS Status; 356238367Sjkim UINT32 TableIndex; 357238367Sjkim 358238367Sjkim 359238367Sjkim ACPI_FUNCTION_TRACE (AcpiLoadTable); 360238367Sjkim 361238367Sjkim 362238367Sjkim /* Parameter validation */ 363238367Sjkim 364238367Sjkim if (!Table) 365238367Sjkim { 366238367Sjkim return_ACPI_STATUS (AE_BAD_PARAMETER); 367238367Sjkim } 368238367Sjkim 369238367Sjkim /* Must acquire the interpreter lock during this operation */ 370238367Sjkim 371238367Sjkim Status = AcpiUtAcquireMutex (ACPI_MTX_INTERPRETER); 372238367Sjkim if (ACPI_FAILURE (Status)) 373238367Sjkim { 374238367Sjkim return_ACPI_STATUS (Status); 375238367Sjkim } 376238367Sjkim 377238367Sjkim /* Install the table and load it into the namespace */ 378238367Sjkim 379306536Sjkim ACPI_INFO (("Host-directed Dynamic ACPI Table Load:")); 380281075Sdim (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 381281075Sdim 382281075Sdim Status = AcpiTbInstallStandardTable (ACPI_PTR_TO_PHYSADDR (Table), 383306536Sjkim ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL, TRUE, FALSE, 384306536Sjkim &TableIndex); 385281075Sdim 386281075Sdim (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 387238367Sjkim if (ACPI_FAILURE (Status)) 388238367Sjkim { 389238367Sjkim goto UnlockAndExit; 390238367Sjkim } 391238367Sjkim 392281075Sdim /* 393281075Sdim * Note: Now table is "INSTALLED", it must be validated before 394281075Sdim * using. 395281075Sdim */ 396306536Sjkim Status = AcpiTbValidateTable ( 397306536Sjkim &AcpiGbl_RootTableList.Tables[TableIndex]); 398281075Sdim if (ACPI_FAILURE (Status)) 399281075Sdim { 400281075Sdim goto UnlockAndExit; 401281075Sdim } 402281075Sdim 403238367Sjkim Status = AcpiNsLoadTable (TableIndex, AcpiGbl_RootNode); 404238367Sjkim 405238367Sjkim /* Invoke table handler if present */ 406238367Sjkim 407238367Sjkim if (AcpiGbl_TableHandler) 408238367Sjkim { 409238367Sjkim (void) AcpiGbl_TableHandler (ACPI_TABLE_EVENT_LOAD, Table, 410306536Sjkim AcpiGbl_TableHandlerContext); 411238367Sjkim } 412238367Sjkim 413238367SjkimUnlockAndExit: 414238367Sjkim (void) AcpiUtReleaseMutex (ACPI_MTX_INTERPRETER); 415238367Sjkim return_ACPI_STATUS (Status); 416238367Sjkim} 417238367Sjkim 418238367SjkimACPI_EXPORT_SYMBOL (AcpiLoadTable) 419238367Sjkim 420238367Sjkim 421238367Sjkim/******************************************************************************* 422238367Sjkim * 423238367Sjkim * FUNCTION: AcpiUnloadParentTable 424238367Sjkim * 425238367Sjkim * PARAMETERS: Object - Handle to any namespace object owned by 426238367Sjkim * the table to be unloaded 427238367Sjkim * 428238367Sjkim * RETURN: Status 429238367Sjkim * 430238367Sjkim * DESCRIPTION: Via any namespace object within an SSDT or OEMx table, unloads 431238367Sjkim * the table and deletes all namespace objects associated with 432238367Sjkim * that table. Unloading of the DSDT is not allowed. 433238367Sjkim * Note: Mainly intended to support hotplug removal of SSDTs. 434238367Sjkim * 435238367Sjkim ******************************************************************************/ 436238367Sjkim 437238367SjkimACPI_STATUS 438238367SjkimAcpiUnloadParentTable ( 439238367Sjkim ACPI_HANDLE Object) 440238367Sjkim{ 441238367Sjkim ACPI_NAMESPACE_NODE *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Object); 442238367Sjkim ACPI_STATUS Status = AE_NOT_EXIST; 443238367Sjkim ACPI_OWNER_ID OwnerId; 444238367Sjkim UINT32 i; 445238367Sjkim 446238367Sjkim 447238367Sjkim ACPI_FUNCTION_TRACE (AcpiUnloadParentTable); 448238367Sjkim 449238367Sjkim 450238367Sjkim /* Parameter validation */ 451238367Sjkim 452238367Sjkim if (!Object) 453238367Sjkim { 454238367Sjkim return_ACPI_STATUS (AE_BAD_PARAMETER); 455238367Sjkim } 456238367Sjkim 457238367Sjkim /* 458238367Sjkim * The node OwnerId is currently the same as the parent table ID. 459238367Sjkim * However, this could change in the future. 460238367Sjkim */ 461238367Sjkim OwnerId = Node->OwnerId; 462238367Sjkim if (!OwnerId) 463238367Sjkim { 464238367Sjkim /* OwnerId==0 means DSDT is the owner. DSDT cannot be unloaded */ 465238367Sjkim 466238367Sjkim return_ACPI_STATUS (AE_TYPE); 467238367Sjkim } 468238367Sjkim 469238367Sjkim /* Must acquire the interpreter lock during this operation */ 470238367Sjkim 471238367Sjkim Status = AcpiUtAcquireMutex (ACPI_MTX_INTERPRETER); 472238367Sjkim if (ACPI_FAILURE (Status)) 473238367Sjkim { 474238367Sjkim return_ACPI_STATUS (Status); 475238367Sjkim } 476238367Sjkim 477238367Sjkim /* Find the table in the global table list */ 478238367Sjkim 479238367Sjkim for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++) 480238367Sjkim { 481238367Sjkim if (OwnerId != AcpiGbl_RootTableList.Tables[i].OwnerId) 482238367Sjkim { 483238367Sjkim continue; 484238367Sjkim } 485238367Sjkim 486238367Sjkim /* 487238367Sjkim * Allow unload of SSDT and OEMx tables only. Do not allow unload 488238367Sjkim * of the DSDT. No other types of tables should get here, since 489238367Sjkim * only these types can contain AML and thus are the only types 490238367Sjkim * that can create namespace objects. 491238367Sjkim */ 492238367Sjkim if (ACPI_COMPARE_NAME ( 493306536Sjkim AcpiGbl_RootTableList.Tables[i].Signature.Ascii, 494306536Sjkim ACPI_SIG_DSDT)) 495238367Sjkim { 496238367Sjkim Status = AE_TYPE; 497238367Sjkim break; 498238367Sjkim } 499238367Sjkim 500238367Sjkim /* Ensure the table is actually loaded */ 501238367Sjkim 502238367Sjkim if (!AcpiTbIsTableLoaded (i)) 503238367Sjkim { 504238367Sjkim Status = AE_NOT_EXIST; 505238367Sjkim break; 506238367Sjkim } 507238367Sjkim 508238367Sjkim /* Invoke table handler if present */ 509238367Sjkim 510238367Sjkim if (AcpiGbl_TableHandler) 511238367Sjkim { 512238367Sjkim (void) AcpiGbl_TableHandler (ACPI_TABLE_EVENT_UNLOAD, 513306536Sjkim AcpiGbl_RootTableList.Tables[i].Pointer, 514306536Sjkim AcpiGbl_TableHandlerContext); 515238367Sjkim } 516238367Sjkim 517238367Sjkim /* 518238367Sjkim * Delete all namespace objects owned by this table. Note that 519238367Sjkim * these objects can appear anywhere in the namespace by virtue 520238367Sjkim * of the AML "Scope" operator. Thus, we need to track ownership 521238367Sjkim * by an ID, not simply a position within the hierarchy. 522238367Sjkim */ 523238367Sjkim Status = AcpiTbDeleteNamespaceByOwner (i); 524238367Sjkim if (ACPI_FAILURE (Status)) 525238367Sjkim { 526238367Sjkim break; 527238367Sjkim } 528238367Sjkim 529238367Sjkim Status = AcpiTbReleaseOwnerId (i); 530238367Sjkim AcpiTbSetTableLoadedFlag (i, FALSE); 531238367Sjkim break; 532238367Sjkim } 533238367Sjkim 534238367Sjkim (void) AcpiUtReleaseMutex (ACPI_MTX_INTERPRETER); 535238367Sjkim return_ACPI_STATUS (Status); 536238367Sjkim} 537238367Sjkim 538238367SjkimACPI_EXPORT_SYMBOL (AcpiUnloadParentTable) 539