1*a159c266SJung-uk Kim /****************************************************************************** 2*a159c266SJung-uk Kim * 3*a159c266SJung-uk Kim * Module Name: nsload - namespace loading/expanding/contracting procedures 4*a159c266SJung-uk Kim * 5*a159c266SJung-uk Kim *****************************************************************************/ 6*a159c266SJung-uk Kim 7*a159c266SJung-uk Kim /* 8*a159c266SJung-uk Kim * Copyright (C) 2000 - 2012, Intel Corp. 9*a159c266SJung-uk Kim * All rights reserved. 10*a159c266SJung-uk Kim * 11*a159c266SJung-uk Kim * Redistribution and use in source and binary forms, with or without 12*a159c266SJung-uk Kim * modification, are permitted provided that the following conditions 13*a159c266SJung-uk Kim * are met: 14*a159c266SJung-uk Kim * 1. Redistributions of source code must retain the above copyright 15*a159c266SJung-uk Kim * notice, this list of conditions, and the following disclaimer, 16*a159c266SJung-uk Kim * without modification. 17*a159c266SJung-uk Kim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18*a159c266SJung-uk Kim * substantially similar to the "NO WARRANTY" disclaimer below 19*a159c266SJung-uk Kim * ("Disclaimer") and any redistribution must be conditioned upon 20*a159c266SJung-uk Kim * including a substantially similar Disclaimer requirement for further 21*a159c266SJung-uk Kim * binary redistribution. 22*a159c266SJung-uk Kim * 3. Neither the names of the above-listed copyright holders nor the names 23*a159c266SJung-uk Kim * of any contributors may be used to endorse or promote products derived 24*a159c266SJung-uk Kim * from this software without specific prior written permission. 25*a159c266SJung-uk Kim * 26*a159c266SJung-uk Kim * Alternatively, this software may be distributed under the terms of the 27*a159c266SJung-uk Kim * GNU General Public License ("GPL") version 2 as published by the Free 28*a159c266SJung-uk Kim * Software Foundation. 29*a159c266SJung-uk Kim * 30*a159c266SJung-uk Kim * NO WARRANTY 31*a159c266SJung-uk Kim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32*a159c266SJung-uk Kim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33*a159c266SJung-uk Kim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34*a159c266SJung-uk Kim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35*a159c266SJung-uk Kim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36*a159c266SJung-uk Kim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37*a159c266SJung-uk Kim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38*a159c266SJung-uk Kim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39*a159c266SJung-uk Kim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40*a159c266SJung-uk Kim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41*a159c266SJung-uk Kim * POSSIBILITY OF SUCH DAMAGES. 42*a159c266SJung-uk Kim */ 43*a159c266SJung-uk Kim 44*a159c266SJung-uk Kim #define __NSLOAD_C__ 45*a159c266SJung-uk Kim 46*a159c266SJung-uk Kim #include <contrib/dev/acpica/include/acpi.h> 47*a159c266SJung-uk Kim #include <contrib/dev/acpica/include/accommon.h> 48*a159c266SJung-uk Kim #include <contrib/dev/acpica/include/acnamesp.h> 49*a159c266SJung-uk Kim #include <contrib/dev/acpica/include/acdispat.h> 50*a159c266SJung-uk Kim #include <contrib/dev/acpica/include/actables.h> 51*a159c266SJung-uk Kim 52*a159c266SJung-uk Kim 53*a159c266SJung-uk Kim #define _COMPONENT ACPI_NAMESPACE 54*a159c266SJung-uk Kim ACPI_MODULE_NAME ("nsload") 55*a159c266SJung-uk Kim 56*a159c266SJung-uk Kim /* Local prototypes */ 57*a159c266SJung-uk Kim 58*a159c266SJung-uk Kim #ifdef ACPI_FUTURE_IMPLEMENTATION 59*a159c266SJung-uk Kim ACPI_STATUS 60*a159c266SJung-uk Kim AcpiNsUnloadNamespace ( 61*a159c266SJung-uk Kim ACPI_HANDLE Handle); 62*a159c266SJung-uk Kim 63*a159c266SJung-uk Kim static ACPI_STATUS 64*a159c266SJung-uk Kim AcpiNsDeleteSubtree ( 65*a159c266SJung-uk Kim ACPI_HANDLE StartHandle); 66*a159c266SJung-uk Kim #endif 67*a159c266SJung-uk Kim 68*a159c266SJung-uk Kim 69*a159c266SJung-uk Kim #ifndef ACPI_NO_METHOD_EXECUTION 70*a159c266SJung-uk Kim /******************************************************************************* 71*a159c266SJung-uk Kim * 72*a159c266SJung-uk Kim * FUNCTION: AcpiNsLoadTable 73*a159c266SJung-uk Kim * 74*a159c266SJung-uk Kim * PARAMETERS: TableIndex - Index for table to be loaded 75*a159c266SJung-uk Kim * Node - Owning NS node 76*a159c266SJung-uk Kim * 77*a159c266SJung-uk Kim * RETURN: Status 78*a159c266SJung-uk Kim * 79*a159c266SJung-uk Kim * DESCRIPTION: Load one ACPI table into the namespace 80*a159c266SJung-uk Kim * 81*a159c266SJung-uk Kim ******************************************************************************/ 82*a159c266SJung-uk Kim 83*a159c266SJung-uk Kim ACPI_STATUS 84*a159c266SJung-uk Kim AcpiNsLoadTable ( 85*a159c266SJung-uk Kim UINT32 TableIndex, 86*a159c266SJung-uk Kim ACPI_NAMESPACE_NODE *Node) 87*a159c266SJung-uk Kim { 88*a159c266SJung-uk Kim ACPI_STATUS Status; 89*a159c266SJung-uk Kim 90*a159c266SJung-uk Kim 91*a159c266SJung-uk Kim ACPI_FUNCTION_TRACE (NsLoadTable); 92*a159c266SJung-uk Kim 93*a159c266SJung-uk Kim 94*a159c266SJung-uk Kim /* 95*a159c266SJung-uk Kim * Parse the table and load the namespace with all named 96*a159c266SJung-uk Kim * objects found within. Control methods are NOT parsed 97*a159c266SJung-uk Kim * at this time. In fact, the control methods cannot be 98*a159c266SJung-uk Kim * parsed until the entire namespace is loaded, because 99*a159c266SJung-uk Kim * if a control method makes a forward reference (call) 100*a159c266SJung-uk Kim * to another control method, we can't continue parsing 101*a159c266SJung-uk Kim * because we don't know how many arguments to parse next! 102*a159c266SJung-uk Kim */ 103*a159c266SJung-uk Kim Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 104*a159c266SJung-uk Kim if (ACPI_FAILURE (Status)) 105*a159c266SJung-uk Kim { 106*a159c266SJung-uk Kim return_ACPI_STATUS (Status); 107*a159c266SJung-uk Kim } 108*a159c266SJung-uk Kim 109*a159c266SJung-uk Kim /* If table already loaded into namespace, just return */ 110*a159c266SJung-uk Kim 111*a159c266SJung-uk Kim if (AcpiTbIsTableLoaded (TableIndex)) 112*a159c266SJung-uk Kim { 113*a159c266SJung-uk Kim Status = AE_ALREADY_EXISTS; 114*a159c266SJung-uk Kim goto Unlock; 115*a159c266SJung-uk Kim } 116*a159c266SJung-uk Kim 117*a159c266SJung-uk Kim ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 118*a159c266SJung-uk Kim "**** Loading table into namespace ****\n")); 119*a159c266SJung-uk Kim 120*a159c266SJung-uk Kim Status = AcpiTbAllocateOwnerId (TableIndex); 121*a159c266SJung-uk Kim if (ACPI_FAILURE (Status)) 122*a159c266SJung-uk Kim { 123*a159c266SJung-uk Kim goto Unlock; 124*a159c266SJung-uk Kim } 125*a159c266SJung-uk Kim 126*a159c266SJung-uk Kim Status = AcpiNsParseTable (TableIndex, Node); 127*a159c266SJung-uk Kim if (ACPI_SUCCESS (Status)) 128*a159c266SJung-uk Kim { 129*a159c266SJung-uk Kim AcpiTbSetTableLoadedFlag (TableIndex, TRUE); 130*a159c266SJung-uk Kim } 131*a159c266SJung-uk Kim else 132*a159c266SJung-uk Kim { 133*a159c266SJung-uk Kim (void) AcpiTbReleaseOwnerId (TableIndex); 134*a159c266SJung-uk Kim } 135*a159c266SJung-uk Kim 136*a159c266SJung-uk Kim Unlock: 137*a159c266SJung-uk Kim (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 138*a159c266SJung-uk Kim 139*a159c266SJung-uk Kim if (ACPI_FAILURE (Status)) 140*a159c266SJung-uk Kim { 141*a159c266SJung-uk Kim return_ACPI_STATUS (Status); 142*a159c266SJung-uk Kim } 143*a159c266SJung-uk Kim 144*a159c266SJung-uk Kim /* 145*a159c266SJung-uk Kim * Now we can parse the control methods. We always parse 146*a159c266SJung-uk Kim * them here for a sanity check, and if configured for 147*a159c266SJung-uk Kim * just-in-time parsing, we delete the control method 148*a159c266SJung-uk Kim * parse trees. 149*a159c266SJung-uk Kim */ 150*a159c266SJung-uk Kim ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 151*a159c266SJung-uk Kim "**** Begin Table Method Parsing and Object Initialization\n")); 152*a159c266SJung-uk Kim 153*a159c266SJung-uk Kim Status = AcpiDsInitializeObjects (TableIndex, Node); 154*a159c266SJung-uk Kim 155*a159c266SJung-uk Kim ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 156*a159c266SJung-uk Kim "**** Completed Table Method Parsing and Object Initialization\n")); 157*a159c266SJung-uk Kim 158*a159c266SJung-uk Kim return_ACPI_STATUS (Status); 159*a159c266SJung-uk Kim } 160*a159c266SJung-uk Kim 161*a159c266SJung-uk Kim 162*a159c266SJung-uk Kim #ifdef ACPI_OBSOLETE_FUNCTIONS 163*a159c266SJung-uk Kim /******************************************************************************* 164*a159c266SJung-uk Kim * 165*a159c266SJung-uk Kim * FUNCTION: AcpiLoadNamespace 166*a159c266SJung-uk Kim * 167*a159c266SJung-uk Kim * PARAMETERS: None 168*a159c266SJung-uk Kim * 169*a159c266SJung-uk Kim * RETURN: Status 170*a159c266SJung-uk Kim * 171*a159c266SJung-uk Kim * DESCRIPTION: Load the name space from what ever is pointed to by DSDT. 172*a159c266SJung-uk Kim * (DSDT points to either the BIOS or a buffer.) 173*a159c266SJung-uk Kim * 174*a159c266SJung-uk Kim ******************************************************************************/ 175*a159c266SJung-uk Kim 176*a159c266SJung-uk Kim ACPI_STATUS 177*a159c266SJung-uk Kim AcpiNsLoadNamespace ( 178*a159c266SJung-uk Kim void) 179*a159c266SJung-uk Kim { 180*a159c266SJung-uk Kim ACPI_STATUS Status; 181*a159c266SJung-uk Kim 182*a159c266SJung-uk Kim 183*a159c266SJung-uk Kim ACPI_FUNCTION_TRACE (AcpiLoadNameSpace); 184*a159c266SJung-uk Kim 185*a159c266SJung-uk Kim 186*a159c266SJung-uk Kim /* There must be at least a DSDT installed */ 187*a159c266SJung-uk Kim 188*a159c266SJung-uk Kim if (AcpiGbl_DSDT == NULL) 189*a159c266SJung-uk Kim { 190*a159c266SJung-uk Kim ACPI_ERROR ((AE_INFO, "DSDT is not in memory")); 191*a159c266SJung-uk Kim return_ACPI_STATUS (AE_NO_ACPI_TABLES); 192*a159c266SJung-uk Kim } 193*a159c266SJung-uk Kim 194*a159c266SJung-uk Kim /* 195*a159c266SJung-uk Kim * Load the namespace. The DSDT is required, 196*a159c266SJung-uk Kim * but the SSDT and PSDT tables are optional. 197*a159c266SJung-uk Kim */ 198*a159c266SJung-uk Kim Status = AcpiNsLoadTableByType (ACPI_TABLE_ID_DSDT); 199*a159c266SJung-uk Kim if (ACPI_FAILURE (Status)) 200*a159c266SJung-uk Kim { 201*a159c266SJung-uk Kim return_ACPI_STATUS (Status); 202*a159c266SJung-uk Kim } 203*a159c266SJung-uk Kim 204*a159c266SJung-uk Kim /* Ignore exceptions from these */ 205*a159c266SJung-uk Kim 206*a159c266SJung-uk Kim (void) AcpiNsLoadTableByType (ACPI_TABLE_ID_SSDT); 207*a159c266SJung-uk Kim (void) AcpiNsLoadTableByType (ACPI_TABLE_ID_PSDT); 208*a159c266SJung-uk Kim 209*a159c266SJung-uk Kim ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, 210*a159c266SJung-uk Kim "ACPI Namespace successfully loaded at root %p\n", 211*a159c266SJung-uk Kim AcpiGbl_RootNode)); 212*a159c266SJung-uk Kim 213*a159c266SJung-uk Kim return_ACPI_STATUS (Status); 214*a159c266SJung-uk Kim } 215*a159c266SJung-uk Kim #endif 216*a159c266SJung-uk Kim 217*a159c266SJung-uk Kim #ifdef ACPI_FUTURE_IMPLEMENTATION 218*a159c266SJung-uk Kim /******************************************************************************* 219*a159c266SJung-uk Kim * 220*a159c266SJung-uk Kim * FUNCTION: AcpiNsDeleteSubtree 221*a159c266SJung-uk Kim * 222*a159c266SJung-uk Kim * PARAMETERS: StartHandle - Handle in namespace where search begins 223*a159c266SJung-uk Kim * 224*a159c266SJung-uk Kim * RETURNS Status 225*a159c266SJung-uk Kim * 226*a159c266SJung-uk Kim * DESCRIPTION: Walks the namespace starting at the given handle and deletes 227*a159c266SJung-uk Kim * all objects, entries, and scopes in the entire subtree. 228*a159c266SJung-uk Kim * 229*a159c266SJung-uk Kim * Namespace/Interpreter should be locked or the subsystem should 230*a159c266SJung-uk Kim * be in shutdown before this routine is called. 231*a159c266SJung-uk Kim * 232*a159c266SJung-uk Kim ******************************************************************************/ 233*a159c266SJung-uk Kim 234*a159c266SJung-uk Kim static ACPI_STATUS 235*a159c266SJung-uk Kim AcpiNsDeleteSubtree ( 236*a159c266SJung-uk Kim ACPI_HANDLE StartHandle) 237*a159c266SJung-uk Kim { 238*a159c266SJung-uk Kim ACPI_STATUS Status; 239*a159c266SJung-uk Kim ACPI_HANDLE ChildHandle; 240*a159c266SJung-uk Kim ACPI_HANDLE ParentHandle; 241*a159c266SJung-uk Kim ACPI_HANDLE NextChildHandle; 242*a159c266SJung-uk Kim ACPI_HANDLE Dummy; 243*a159c266SJung-uk Kim UINT32 Level; 244*a159c266SJung-uk Kim 245*a159c266SJung-uk Kim 246*a159c266SJung-uk Kim ACPI_FUNCTION_TRACE (NsDeleteSubtree); 247*a159c266SJung-uk Kim 248*a159c266SJung-uk Kim 249*a159c266SJung-uk Kim ParentHandle = StartHandle; 250*a159c266SJung-uk Kim ChildHandle = NULL; 251*a159c266SJung-uk Kim Level = 1; 252*a159c266SJung-uk Kim 253*a159c266SJung-uk Kim /* 254*a159c266SJung-uk Kim * Traverse the tree of objects until we bubble back up 255*a159c266SJung-uk Kim * to where we started. 256*a159c266SJung-uk Kim */ 257*a159c266SJung-uk Kim while (Level > 0) 258*a159c266SJung-uk Kim { 259*a159c266SJung-uk Kim /* Attempt to get the next object in this scope */ 260*a159c266SJung-uk Kim 261*a159c266SJung-uk Kim Status = AcpiGetNextObject (ACPI_TYPE_ANY, ParentHandle, 262*a159c266SJung-uk Kim ChildHandle, &NextChildHandle); 263*a159c266SJung-uk Kim 264*a159c266SJung-uk Kim ChildHandle = NextChildHandle; 265*a159c266SJung-uk Kim 266*a159c266SJung-uk Kim /* Did we get a new object? */ 267*a159c266SJung-uk Kim 268*a159c266SJung-uk Kim if (ACPI_SUCCESS (Status)) 269*a159c266SJung-uk Kim { 270*a159c266SJung-uk Kim /* Check if this object has any children */ 271*a159c266SJung-uk Kim 272*a159c266SJung-uk Kim if (ACPI_SUCCESS (AcpiGetNextObject (ACPI_TYPE_ANY, ChildHandle, 273*a159c266SJung-uk Kim NULL, &Dummy))) 274*a159c266SJung-uk Kim { 275*a159c266SJung-uk Kim /* 276*a159c266SJung-uk Kim * There is at least one child of this object, 277*a159c266SJung-uk Kim * visit the object 278*a159c266SJung-uk Kim */ 279*a159c266SJung-uk Kim Level++; 280*a159c266SJung-uk Kim ParentHandle = ChildHandle; 281*a159c266SJung-uk Kim ChildHandle = NULL; 282*a159c266SJung-uk Kim } 283*a159c266SJung-uk Kim } 284*a159c266SJung-uk Kim else 285*a159c266SJung-uk Kim { 286*a159c266SJung-uk Kim /* 287*a159c266SJung-uk Kim * No more children in this object, go back up to 288*a159c266SJung-uk Kim * the object's parent 289*a159c266SJung-uk Kim */ 290*a159c266SJung-uk Kim Level--; 291*a159c266SJung-uk Kim 292*a159c266SJung-uk Kim /* Delete all children now */ 293*a159c266SJung-uk Kim 294*a159c266SJung-uk Kim AcpiNsDeleteChildren (ChildHandle); 295*a159c266SJung-uk Kim 296*a159c266SJung-uk Kim ChildHandle = ParentHandle; 297*a159c266SJung-uk Kim Status = AcpiGetParent (ParentHandle, &ParentHandle); 298*a159c266SJung-uk Kim if (ACPI_FAILURE (Status)) 299*a159c266SJung-uk Kim { 300*a159c266SJung-uk Kim return_ACPI_STATUS (Status); 301*a159c266SJung-uk Kim } 302*a159c266SJung-uk Kim } 303*a159c266SJung-uk Kim } 304*a159c266SJung-uk Kim 305*a159c266SJung-uk Kim /* Now delete the starting object, and we are done */ 306*a159c266SJung-uk Kim 307*a159c266SJung-uk Kim AcpiNsRemoveNode (ChildHandle); 308*a159c266SJung-uk Kim return_ACPI_STATUS (AE_OK); 309*a159c266SJung-uk Kim } 310*a159c266SJung-uk Kim 311*a159c266SJung-uk Kim 312*a159c266SJung-uk Kim /******************************************************************************* 313*a159c266SJung-uk Kim * 314*a159c266SJung-uk Kim * FUNCTION: AcpiNsUnloadNameSpace 315*a159c266SJung-uk Kim * 316*a159c266SJung-uk Kim * PARAMETERS: Handle - Root of namespace subtree to be deleted 317*a159c266SJung-uk Kim * 318*a159c266SJung-uk Kim * RETURN: Status 319*a159c266SJung-uk Kim * 320*a159c266SJung-uk Kim * DESCRIPTION: Shrinks the namespace, typically in response to an undocking 321*a159c266SJung-uk Kim * event. Deletes an entire subtree starting from (and 322*a159c266SJung-uk Kim * including) the given handle. 323*a159c266SJung-uk Kim * 324*a159c266SJung-uk Kim ******************************************************************************/ 325*a159c266SJung-uk Kim 326*a159c266SJung-uk Kim ACPI_STATUS 327*a159c266SJung-uk Kim AcpiNsUnloadNamespace ( 328*a159c266SJung-uk Kim ACPI_HANDLE Handle) 329*a159c266SJung-uk Kim { 330*a159c266SJung-uk Kim ACPI_STATUS Status; 331*a159c266SJung-uk Kim 332*a159c266SJung-uk Kim 333*a159c266SJung-uk Kim ACPI_FUNCTION_TRACE (NsUnloadNameSpace); 334*a159c266SJung-uk Kim 335*a159c266SJung-uk Kim 336*a159c266SJung-uk Kim /* Parameter validation */ 337*a159c266SJung-uk Kim 338*a159c266SJung-uk Kim if (!AcpiGbl_RootNode) 339*a159c266SJung-uk Kim { 340*a159c266SJung-uk Kim return_ACPI_STATUS (AE_NO_NAMESPACE); 341*a159c266SJung-uk Kim } 342*a159c266SJung-uk Kim 343*a159c266SJung-uk Kim if (!Handle) 344*a159c266SJung-uk Kim { 345*a159c266SJung-uk Kim return_ACPI_STATUS (AE_BAD_PARAMETER); 346*a159c266SJung-uk Kim } 347*a159c266SJung-uk Kim 348*a159c266SJung-uk Kim /* This function does the real work */ 349*a159c266SJung-uk Kim 350*a159c266SJung-uk Kim Status = AcpiNsDeleteSubtree (Handle); 351*a159c266SJung-uk Kim 352*a159c266SJung-uk Kim return_ACPI_STATUS (Status); 353*a159c266SJung-uk Kim } 354*a159c266SJung-uk Kim #endif 355*a159c266SJung-uk Kim #endif 356*a159c266SJung-uk Kim 357