167754Smsmith/****************************************************************************** 267754Smsmith * 367754Smsmith * Module Name: nsload - namespace loading/expanding/contracting procedures 467754Smsmith * 567754Smsmith *****************************************************************************/ 667754Smsmith 7217365Sjkim/* 8306536Sjkim * Copyright (C) 2000 - 2016, Intel Corp. 970243Smsmith * All rights reserved. 1067754Smsmith * 11217365Sjkim * Redistribution and use in source and binary forms, with or without 12217365Sjkim * modification, are permitted provided that the following conditions 13217365Sjkim * are met: 14217365Sjkim * 1. Redistributions of source code must retain the above copyright 15217365Sjkim * notice, this list of conditions, and the following disclaimer, 16217365Sjkim * without modification. 17217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18217365Sjkim * substantially similar to the "NO WARRANTY" disclaimer below 19217365Sjkim * ("Disclaimer") and any redistribution must be conditioned upon 20217365Sjkim * including a substantially similar Disclaimer requirement for further 21217365Sjkim * binary redistribution. 22217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names 23217365Sjkim * of any contributors may be used to endorse or promote products derived 24217365Sjkim * from this software without specific prior written permission. 2567754Smsmith * 26217365Sjkim * Alternatively, this software may be distributed under the terms of the 27217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free 28217365Sjkim * Software Foundation. 2967754Smsmith * 30217365Sjkim * NO WARRANTY 31217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41217365Sjkim * POSSIBILITY OF SUCH DAMAGES. 42217365Sjkim */ 4367754Smsmith 44193341Sjkim#include <contrib/dev/acpica/include/acpi.h> 45193341Sjkim#include <contrib/dev/acpica/include/accommon.h> 46193341Sjkim#include <contrib/dev/acpica/include/acnamesp.h> 47193341Sjkim#include <contrib/dev/acpica/include/acdispat.h> 48193341Sjkim#include <contrib/dev/acpica/include/actables.h> 4967754Smsmith 5067754Smsmith 5177424Smsmith#define _COMPONENT ACPI_NAMESPACE 5291116Smsmith ACPI_MODULE_NAME ("nsload") 5367754Smsmith 54151937Sjkim/* Local prototypes */ 5567754Smsmith 56151937Sjkim#ifdef ACPI_FUTURE_IMPLEMENTATION 57151937SjkimACPI_STATUS 58151937SjkimAcpiNsUnloadNamespace ( 59151937Sjkim ACPI_HANDLE Handle); 60151937Sjkim 61151937Sjkimstatic ACPI_STATUS 62151937SjkimAcpiNsDeleteSubtree ( 63151937Sjkim ACPI_HANDLE StartHandle); 64151937Sjkim#endif 65151937Sjkim 66151937Sjkim 67100966Siwasaki#ifndef ACPI_NO_METHOD_EXECUTION 6877424Smsmith/******************************************************************************* 6967754Smsmith * 7067754Smsmith * FUNCTION: AcpiNsLoadTable 7167754Smsmith * 72167802Sjkim * PARAMETERS: TableIndex - Index for table to be loaded 7387031Smsmith * Node - Owning NS node 7467754Smsmith * 7567754Smsmith * RETURN: Status 7667754Smsmith * 7767754Smsmith * DESCRIPTION: Load one ACPI table into the namespace 7867754Smsmith * 7977424Smsmith ******************************************************************************/ 8067754Smsmith 8167754SmsmithACPI_STATUS 8267754SmsmithAcpiNsLoadTable ( 83193267Sjkim UINT32 TableIndex, 8467754Smsmith ACPI_NAMESPACE_NODE *Node) 8567754Smsmith{ 8667754Smsmith ACPI_STATUS Status; 8767754Smsmith 8867754Smsmith 89167802Sjkim ACPI_FUNCTION_TRACE (NsLoadTable); 9067754Smsmith 9167754Smsmith 9267754Smsmith /* 9367754Smsmith * Parse the table and load the namespace with all named 94241973Sjkim * objects found within. Control methods are NOT parsed 95241973Sjkim * at this time. In fact, the control methods cannot be 9667754Smsmith * parsed until the entire namespace is loaded, because 9767754Smsmith * if a control method makes a forward reference (call) 9867754Smsmith * to another control method, we can't continue parsing 9967754Smsmith * because we don't know how many arguments to parse next! 10067754Smsmith */ 101167802Sjkim Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 102167802Sjkim if (ACPI_FAILURE (Status)) 103167802Sjkim { 104167802Sjkim return_ACPI_STATUS (Status); 105167802Sjkim } 106167802Sjkim 107167802Sjkim /* If table already loaded into namespace, just return */ 108167802Sjkim 109167802Sjkim if (AcpiTbIsTableLoaded (TableIndex)) 110167802Sjkim { 111167802Sjkim Status = AE_ALREADY_EXISTS; 112167802Sjkim goto Unlock; 113167802Sjkim } 114167802Sjkim 115138287Smarks ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 116138287Smarks "**** Loading table into namespace ****\n")); 11767754Smsmith 118167802Sjkim Status = AcpiTbAllocateOwnerId (TableIndex); 11991116Smsmith if (ACPI_FAILURE (Status)) 12091116Smsmith { 121167802Sjkim goto Unlock; 12291116Smsmith } 12391116Smsmith 124193267Sjkim Status = AcpiNsParseTable (TableIndex, Node); 125167802Sjkim if (ACPI_SUCCESS (Status)) 126167802Sjkim { 127167802Sjkim AcpiTbSetTableLoadedFlag (TableIndex, TRUE); 128167802Sjkim } 129167802Sjkim else 130167802Sjkim { 131306536Sjkim /* 132306536Sjkim * On error, delete any namespace objects created by this table. 133306536Sjkim * We cannot initialize these objects, so delete them. There are 134306536Sjkim * a couple of expecially bad cases: 135306536Sjkim * AE_ALREADY_EXISTS - namespace collision. 136306536Sjkim * AE_NOT_FOUND - the target of a Scope operator does not 137306536Sjkim * exist. This target of Scope must already exist in the 138306536Sjkim * namespace, as per the ACPI specification. 139306536Sjkim */ 140306536Sjkim (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 141306536Sjkim AcpiNsDeleteNamespaceByOwner ( 142306536Sjkim AcpiGbl_RootTableList.Tables[TableIndex].OwnerId); 143306536Sjkim 144306536Sjkim AcpiTbReleaseOwnerId (TableIndex); 145306536Sjkim return_ACPI_STATUS (Status); 146167802Sjkim } 147167802Sjkim 148167802SjkimUnlock: 14991116Smsmith (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 15067754Smsmith 15167754Smsmith if (ACPI_FAILURE (Status)) 15267754Smsmith { 15367754Smsmith return_ACPI_STATUS (Status); 15467754Smsmith } 15567754Smsmith 15667754Smsmith /* 157241973Sjkim * Now we can parse the control methods. We always parse 15867754Smsmith * them here for a sanity check, and if configured for 15967754Smsmith * just-in-time parsing, we delete the control method 16067754Smsmith * parse trees. 16167754Smsmith */ 16282367Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 163281075Sdim "**** Begin Table Object Initialization\n")); 16467754Smsmith 165167802Sjkim Status = AcpiDsInitializeObjects (TableIndex, Node); 16667754Smsmith 16782367Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 168281075Sdim "**** Completed Table Object Initialization\n")); 16967754Smsmith 170306536Sjkim /* 171306536Sjkim * Execute any module-level code that was detected during the table load 172306536Sjkim * phase. Although illegal since ACPI 2.0, there are many machines that 173306536Sjkim * contain this type of code. Each block of detected executable AML code 174306536Sjkim * outside of any control method is wrapped with a temporary control 175306536Sjkim * method object and placed on a global list. The methods on this list 176306536Sjkim * are executed below. 177306536Sjkim * 178306536Sjkim * This case executes the module-level code for each table immediately 179306536Sjkim * after the table has been loaded. This provides compatibility with 180306536Sjkim * other ACPI implementations. Optionally, the execution can be deferred 181306536Sjkim * until later, see AcpiInitializeObjects. 182306536Sjkim */ 183306536Sjkim if (!AcpiGbl_GroupModuleLevelCode) 184306536Sjkim { 185306536Sjkim AcpiNsExecModuleCodeList (); 186306536Sjkim } 187306536Sjkim 18867754Smsmith return_ACPI_STATUS (Status); 18967754Smsmith} 19067754Smsmith 19167754Smsmith 192167802Sjkim#ifdef ACPI_OBSOLETE_FUNCTIONS 19377424Smsmith/******************************************************************************* 19467754Smsmith * 195100966Siwasaki * FUNCTION: AcpiLoadNamespace 196100966Siwasaki * 197100966Siwasaki * PARAMETERS: None 198100966Siwasaki * 199100966Siwasaki * RETURN: Status 200100966Siwasaki * 201100966Siwasaki * DESCRIPTION: Load the name space from what ever is pointed to by DSDT. 202100966Siwasaki * (DSDT points to either the BIOS or a buffer.) 203100966Siwasaki * 204100966Siwasaki ******************************************************************************/ 205100966Siwasaki 206100966SiwasakiACPI_STATUS 207100966SiwasakiAcpiNsLoadNamespace ( 208100966Siwasaki void) 209100966Siwasaki{ 210100966Siwasaki ACPI_STATUS Status; 211100966Siwasaki 212100966Siwasaki 213167802Sjkim ACPI_FUNCTION_TRACE (AcpiLoadNameSpace); 214100966Siwasaki 215100966Siwasaki 216100966Siwasaki /* There must be at least a DSDT installed */ 217100966Siwasaki 218100966Siwasaki if (AcpiGbl_DSDT == NULL) 219100966Siwasaki { 220167802Sjkim ACPI_ERROR ((AE_INFO, "DSDT is not in memory")); 221100966Siwasaki return_ACPI_STATUS (AE_NO_ACPI_TABLES); 222100966Siwasaki } 223100966Siwasaki 224100966Siwasaki /* 225241973Sjkim * Load the namespace. The DSDT is required, 226100966Siwasaki * but the SSDT and PSDT tables are optional. 227100966Siwasaki */ 228167802Sjkim Status = AcpiNsLoadTableByType (ACPI_TABLE_ID_DSDT); 229100966Siwasaki if (ACPI_FAILURE (Status)) 230100966Siwasaki { 231100966Siwasaki return_ACPI_STATUS (Status); 232100966Siwasaki } 233100966Siwasaki 234100966Siwasaki /* Ignore exceptions from these */ 235100966Siwasaki 236167802Sjkim (void) AcpiNsLoadTableByType (ACPI_TABLE_ID_SSDT); 237167802Sjkim (void) AcpiNsLoadTableByType (ACPI_TABLE_ID_PSDT); 238100966Siwasaki 239114237Snjl ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, 240100966Siwasaki "ACPI Namespace successfully loaded at root %p\n", 241100966Siwasaki AcpiGbl_RootNode)); 242100966Siwasaki 243100966Siwasaki return_ACPI_STATUS (Status); 244100966Siwasaki} 245167802Sjkim#endif 246100966Siwasaki 247151937Sjkim#ifdef ACPI_FUTURE_IMPLEMENTATION 248100966Siwasaki/******************************************************************************* 249100966Siwasaki * 25067754Smsmith * FUNCTION: AcpiNsDeleteSubtree 25167754Smsmith * 25267754Smsmith * PARAMETERS: StartHandle - Handle in namespace where search begins 25367754Smsmith * 25467754Smsmith * RETURNS Status 25567754Smsmith * 25667754Smsmith * DESCRIPTION: Walks the namespace starting at the given handle and deletes 25767754Smsmith * all objects, entries, and scopes in the entire subtree. 25867754Smsmith * 25991116Smsmith * Namespace/Interpreter should be locked or the subsystem should 26091116Smsmith * be in shutdown before this routine is called. 26167754Smsmith * 26267754Smsmith ******************************************************************************/ 26367754Smsmith 264151937Sjkimstatic ACPI_STATUS 26567754SmsmithAcpiNsDeleteSubtree ( 26667754Smsmith ACPI_HANDLE StartHandle) 26767754Smsmith{ 26867754Smsmith ACPI_STATUS Status; 26967754Smsmith ACPI_HANDLE ChildHandle; 27067754Smsmith ACPI_HANDLE ParentHandle; 27167754Smsmith ACPI_HANDLE NextChildHandle; 27267754Smsmith ACPI_HANDLE Dummy; 27367754Smsmith UINT32 Level; 27467754Smsmith 27567754Smsmith 276167802Sjkim ACPI_FUNCTION_TRACE (NsDeleteSubtree); 27767754Smsmith 27867754Smsmith 27977424Smsmith ParentHandle = StartHandle; 280306536Sjkim ChildHandle = NULL; 281306536Sjkim Level = 1; 28267754Smsmith 28367754Smsmith /* 28467754Smsmith * Traverse the tree of objects until we bubble back up 28567754Smsmith * to where we started. 28667754Smsmith */ 28767754Smsmith while (Level > 0) 28867754Smsmith { 28967754Smsmith /* Attempt to get the next object in this scope */ 29067754Smsmith 29167754Smsmith Status = AcpiGetNextObject (ACPI_TYPE_ANY, ParentHandle, 292306536Sjkim ChildHandle, &NextChildHandle); 29367754Smsmith 29467754Smsmith ChildHandle = NextChildHandle; 29567754Smsmith 29667754Smsmith /* Did we get a new object? */ 29767754Smsmith 29867754Smsmith if (ACPI_SUCCESS (Status)) 29967754Smsmith { 30067754Smsmith /* Check if this object has any children */ 30167754Smsmith 30277424Smsmith if (ACPI_SUCCESS (AcpiGetNextObject (ACPI_TYPE_ANY, ChildHandle, 303306536Sjkim NULL, &Dummy))) 30467754Smsmith { 30567754Smsmith /* 30667754Smsmith * There is at least one child of this object, 30767754Smsmith * visit the object 30867754Smsmith */ 30967754Smsmith Level++; 31077424Smsmith ParentHandle = ChildHandle; 311138287Smarks ChildHandle = NULL; 31267754Smsmith } 31367754Smsmith } 31467754Smsmith else 31567754Smsmith { 31667754Smsmith /* 31767754Smsmith * No more children in this object, go back up to 31867754Smsmith * the object's parent 31967754Smsmith */ 32067754Smsmith Level--; 32167754Smsmith 32267754Smsmith /* Delete all children now */ 32367754Smsmith 32467754Smsmith AcpiNsDeleteChildren (ChildHandle); 32567754Smsmith 32667754Smsmith ChildHandle = ParentHandle; 32799679Siwasaki Status = AcpiGetParent (ParentHandle, &ParentHandle); 32899679Siwasaki if (ACPI_FAILURE (Status)) 32999679Siwasaki { 33099679Siwasaki return_ACPI_STATUS (Status); 33199679Siwasaki } 33267754Smsmith } 33367754Smsmith } 33467754Smsmith 33567754Smsmith /* Now delete the starting object, and we are done */ 33667754Smsmith 337197104Sjkim AcpiNsRemoveNode (ChildHandle); 33867754Smsmith return_ACPI_STATUS (AE_OK); 33967754Smsmith} 34067754Smsmith 34167754Smsmith 34277424Smsmith/******************************************************************************* 34367754Smsmith * 34467754Smsmith * FUNCTION: AcpiNsUnloadNameSpace 34567754Smsmith * 34667754Smsmith * PARAMETERS: Handle - Root of namespace subtree to be deleted 34767754Smsmith * 34867754Smsmith * RETURN: Status 34967754Smsmith * 35067754Smsmith * DESCRIPTION: Shrinks the namespace, typically in response to an undocking 351241973Sjkim * event. Deletes an entire subtree starting from (and 35267754Smsmith * including) the given handle. 35367754Smsmith * 35477424Smsmith ******************************************************************************/ 35567754Smsmith 35667754SmsmithACPI_STATUS 35767754SmsmithAcpiNsUnloadNamespace ( 35867754Smsmith ACPI_HANDLE Handle) 35967754Smsmith{ 36067754Smsmith ACPI_STATUS Status; 36167754Smsmith 36267754Smsmith 363167802Sjkim ACPI_FUNCTION_TRACE (NsUnloadNameSpace); 36467754Smsmith 36567754Smsmith 36667754Smsmith /* Parameter validation */ 36767754Smsmith 36867754Smsmith if (!AcpiGbl_RootNode) 36967754Smsmith { 37067754Smsmith return_ACPI_STATUS (AE_NO_NAMESPACE); 37167754Smsmith } 37267754Smsmith 37367754Smsmith if (!Handle) 37467754Smsmith { 37567754Smsmith return_ACPI_STATUS (AE_BAD_PARAMETER); 37667754Smsmith } 37767754Smsmith 37867754Smsmith /* This function does the real work */ 37967754Smsmith 38067754Smsmith Status = AcpiNsDeleteSubtree (Handle); 38167754Smsmith return_ACPI_STATUS (Status); 38267754Smsmith} 383100966Siwasaki#endif 384151937Sjkim#endif 385