nsload.c revision 281075
1160892Ssobomax/******************************************************************************
2160892Ssobomax *
3160892Ssobomax * Module Name: nsload - namespace loading/expanding/contracting procedures
4160892Ssobomax *
5160892Ssobomax *****************************************************************************/
6160892Ssobomax
7160892Ssobomax/*
8160892Ssobomax * Copyright (C) 2000 - 2015, Intel Corp.
9160892Ssobomax * All rights reserved.
10160892Ssobomax *
11160892Ssobomax * Redistribution and use in source and binary forms, with or without
12160892Ssobomax * modification, are permitted provided that the following conditions
13160892Ssobomax * are met:
14160892Ssobomax * 1. Redistributions of source code must retain the above copyright
15160892Ssobomax *    notice, this list of conditions, and the following disclaimer,
16160892Ssobomax *    without modification.
17160892Ssobomax * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18160892Ssobomax *    substantially similar to the "NO WARRANTY" disclaimer below
19160892Ssobomax *    ("Disclaimer") and any redistribution must be conditioned upon
20160892Ssobomax *    including a substantially similar Disclaimer requirement for further
21160892Ssobomax *    binary redistribution.
22160892Ssobomax * 3. Neither the names of the above-listed copyright holders nor the names
23160892Ssobomax *    of any contributors may be used to endorse or promote products derived
24160892Ssobomax *    from this software without specific prior written permission.
25160892Ssobomax *
26160892Ssobomax * Alternatively, this software may be distributed under the terms of the
27160892Ssobomax * GNU General Public License ("GPL") version 2 as published by the Free
28160892Ssobomax * Software Foundation.
29160892Ssobomax *
30160892Ssobomax * NO WARRANTY
31160892Ssobomax * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32160892Ssobomax * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33160892Ssobomax * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34160892Ssobomax * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35160892Ssobomax * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36160892Ssobomax * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37160892Ssobomax * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38160892Ssobomax * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39160892Ssobomax * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40160892Ssobomax * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41160892Ssobomax * POSSIBILITY OF SUCH DAMAGES.
42160892Ssobomax */
43160892Ssobomax
44160892Ssobomax#include <contrib/dev/acpica/include/acpi.h>
45160892Ssobomax#include <contrib/dev/acpica/include/accommon.h>
46160892Ssobomax#include <contrib/dev/acpica/include/acnamesp.h>
47160892Ssobomax#include <contrib/dev/acpica/include/acdispat.h>
48160892Ssobomax#include <contrib/dev/acpica/include/actables.h>
49160892Ssobomax
50160892Ssobomax
51160892Ssobomax#define _COMPONENT          ACPI_NAMESPACE
52160892Ssobomax        ACPI_MODULE_NAME    ("nsload")
53160892Ssobomax
54253162Srdivacky/* Local prototypes */
55239733Srdivacky
56239733Srdivacky#ifdef ACPI_FUTURE_IMPLEMENTATION
57239733SrdivackyACPI_STATUS
58239733SrdivackyAcpiNsUnloadNamespace (
59160892Ssobomax    ACPI_HANDLE             Handle);
60160892Ssobomax
61160892Ssobomaxstatic ACPI_STATUS
62160892SsobomaxAcpiNsDeleteSubtree (
63160892Ssobomax    ACPI_HANDLE             StartHandle);
64160892Ssobomax#endif
65160892Ssobomax
66160892Ssobomax
67160892Ssobomax#ifndef ACPI_NO_METHOD_EXECUTION
68160892Ssobomax/*******************************************************************************
69160892Ssobomax *
70160892Ssobomax * FUNCTION:    AcpiNsLoadTable
71160892Ssobomax *
72160892Ssobomax * PARAMETERS:  TableIndex      - Index for table to be loaded
73160892Ssobomax *              Node            - Owning NS node
74160892Ssobomax *
75160892Ssobomax * RETURN:      Status
76160892Ssobomax *
77160892Ssobomax * DESCRIPTION: Load one ACPI table into the namespace
78160892Ssobomax *
79160892Ssobomax ******************************************************************************/
80160892Ssobomax
81160892SsobomaxACPI_STATUS
82160892SsobomaxAcpiNsLoadTable (
83160892Ssobomax    UINT32                  TableIndex,
84160892Ssobomax    ACPI_NAMESPACE_NODE     *Node)
85160892Ssobomax{
86160892Ssobomax    ACPI_STATUS             Status;
87160892Ssobomax
88160892Ssobomax
89160892Ssobomax    ACPI_FUNCTION_TRACE (NsLoadTable);
90160892Ssobomax
91160892Ssobomax
92160892Ssobomax    /*
93160892Ssobomax     * Parse the table and load the namespace with all named
94160892Ssobomax     * objects found within. Control methods are NOT parsed
95160892Ssobomax     * at this time. In fact, the control methods cannot be
96160892Ssobomax     * parsed until the entire namespace is loaded, because
97160892Ssobomax     * if a control method makes a forward reference (call)
98160892Ssobomax     * to another control method, we can't continue parsing
99160892Ssobomax     * because we don't know how many arguments to parse next!
100160892Ssobomax     */
101160892Ssobomax    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
102160892Ssobomax    if (ACPI_FAILURE (Status))
103160892Ssobomax    {
104160892Ssobomax        return_ACPI_STATUS (Status);
105160892Ssobomax    }
106160892Ssobomax
107160892Ssobomax    /* If table already loaded into namespace, just return */
108160892Ssobomax
109160892Ssobomax    if (AcpiTbIsTableLoaded (TableIndex))
110160892Ssobomax    {
111160892Ssobomax        Status = AE_ALREADY_EXISTS;
112160892Ssobomax        goto Unlock;
113160892Ssobomax    }
114160892Ssobomax
115160892Ssobomax    ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
116160892Ssobomax        "**** Loading table into namespace ****\n"));
117160892Ssobomax
118160892Ssobomax    Status = AcpiTbAllocateOwnerId (TableIndex);
119160892Ssobomax    if (ACPI_FAILURE (Status))
120160892Ssobomax    {
121160892Ssobomax        goto Unlock;
122160892Ssobomax    }
123239733Srdivacky
124239733Srdivacky    Status = AcpiNsParseTable (TableIndex, Node);
125239733Srdivacky    if (ACPI_SUCCESS (Status))
126160892Ssobomax    {
127160892Ssobomax        AcpiTbSetTableLoadedFlag (TableIndex, TRUE);
128160892Ssobomax    }
129160892Ssobomax    else
130160892Ssobomax    {
131160892Ssobomax        (void) AcpiTbReleaseOwnerId (TableIndex);
132160892Ssobomax    }
133160892Ssobomax
134160892SsobomaxUnlock:
135160892Ssobomax    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
136160892Ssobomax
137160892Ssobomax    if (ACPI_FAILURE (Status))
138160892Ssobomax    {
139160892Ssobomax        return_ACPI_STATUS (Status);
140160892Ssobomax    }
141160892Ssobomax
142160892Ssobomax    /*
143160892Ssobomax     * Now we can parse the control methods. We always parse
144160892Ssobomax     * them here for a sanity check, and if configured for
145160892Ssobomax     * just-in-time parsing, we delete the control method
146160892Ssobomax     * parse trees.
147160892Ssobomax     */
148160892Ssobomax    ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
149160892Ssobomax        "**** Begin Table Object Initialization\n"));
150160892Ssobomax
151160892Ssobomax    Status = AcpiDsInitializeObjects (TableIndex, Node);
152160892Ssobomax
153160892Ssobomax    ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
154160892Ssobomax        "**** Completed Table Object Initialization\n"));
155160892Ssobomax
156160892Ssobomax    return_ACPI_STATUS (Status);
157160892Ssobomax}
158160892Ssobomax
159160892Ssobomax
160160892Ssobomax#ifdef ACPI_OBSOLETE_FUNCTIONS
161160892Ssobomax/*******************************************************************************
162160892Ssobomax *
163160892Ssobomax * FUNCTION:    AcpiLoadNamespace
164160892Ssobomax *
165160892Ssobomax * PARAMETERS:  None
166160892Ssobomax *
167160892Ssobomax * RETURN:      Status
168160892Ssobomax *
169160892Ssobomax * DESCRIPTION: Load the name space from what ever is pointed to by DSDT.
170160892Ssobomax *              (DSDT points to either the BIOS or a buffer.)
171160892Ssobomax *
172160892Ssobomax ******************************************************************************/
173160892Ssobomax
174160892SsobomaxACPI_STATUS
175160892SsobomaxAcpiNsLoadNamespace (
176160892Ssobomax    void)
177160892Ssobomax{
178160892Ssobomax    ACPI_STATUS             Status;
179160892Ssobomax
180160892Ssobomax
181160892Ssobomax    ACPI_FUNCTION_TRACE (AcpiLoadNameSpace);
182160892Ssobomax
183160892Ssobomax
184160892Ssobomax    /* There must be at least a DSDT installed */
185160892Ssobomax
186160892Ssobomax    if (AcpiGbl_DSDT == NULL)
187160892Ssobomax    {
188160892Ssobomax        ACPI_ERROR ((AE_INFO, "DSDT is not in memory"));
189160892Ssobomax        return_ACPI_STATUS (AE_NO_ACPI_TABLES);
190160892Ssobomax    }
191160892Ssobomax
192160892Ssobomax    /*
193160892Ssobomax     * Load the namespace. The DSDT is required,
194160892Ssobomax     * but the SSDT and PSDT tables are optional.
195160892Ssobomax     */
196160892Ssobomax    Status = AcpiNsLoadTableByType (ACPI_TABLE_ID_DSDT);
197160892Ssobomax    if (ACPI_FAILURE (Status))
198160892Ssobomax    {
199160892Ssobomax        return_ACPI_STATUS (Status);
200160892Ssobomax    }
201160892Ssobomax
202160892Ssobomax    /* Ignore exceptions from these */
203160892Ssobomax
204160892Ssobomax    (void) AcpiNsLoadTableByType (ACPI_TABLE_ID_SSDT);
205160892Ssobomax    (void) AcpiNsLoadTableByType (ACPI_TABLE_ID_PSDT);
206160892Ssobomax
207160892Ssobomax    ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
208160892Ssobomax        "ACPI Namespace successfully loaded at root %p\n",
209160892Ssobomax        AcpiGbl_RootNode));
210160892Ssobomax
211160892Ssobomax    return_ACPI_STATUS (Status);
212160892Ssobomax}
213160892Ssobomax#endif
214160892Ssobomax
215160892Ssobomax#ifdef ACPI_FUTURE_IMPLEMENTATION
216160892Ssobomax/*******************************************************************************
217160892Ssobomax *
218160892Ssobomax * FUNCTION:    AcpiNsDeleteSubtree
219160892Ssobomax *
220160892Ssobomax * PARAMETERS:  StartHandle         - Handle in namespace where search begins
221160892Ssobomax *
222160892Ssobomax * RETURNS      Status
223160892Ssobomax *
224160892Ssobomax * DESCRIPTION: Walks the namespace starting at the given handle and deletes
225160892Ssobomax *              all objects, entries, and scopes in the entire subtree.
226160892Ssobomax *
227 *              Namespace/Interpreter should be locked or the subsystem should
228 *              be in shutdown before this routine is called.
229 *
230 ******************************************************************************/
231
232static ACPI_STATUS
233AcpiNsDeleteSubtree (
234    ACPI_HANDLE             StartHandle)
235{
236    ACPI_STATUS             Status;
237    ACPI_HANDLE             ChildHandle;
238    ACPI_HANDLE             ParentHandle;
239    ACPI_HANDLE             NextChildHandle;
240    ACPI_HANDLE             Dummy;
241    UINT32                  Level;
242
243
244    ACPI_FUNCTION_TRACE (NsDeleteSubtree);
245
246
247    ParentHandle = StartHandle;
248    ChildHandle  = NULL;
249    Level        = 1;
250
251    /*
252     * Traverse the tree of objects until we bubble back up
253     * to where we started.
254     */
255    while (Level > 0)
256    {
257        /* Attempt to get the next object in this scope */
258
259        Status = AcpiGetNextObject (ACPI_TYPE_ANY, ParentHandle,
260                                    ChildHandle, &NextChildHandle);
261
262        ChildHandle = NextChildHandle;
263
264        /* Did we get a new object? */
265
266        if (ACPI_SUCCESS (Status))
267        {
268            /* Check if this object has any children */
269
270            if (ACPI_SUCCESS (AcpiGetNextObject (ACPI_TYPE_ANY, ChildHandle,
271                                    NULL, &Dummy)))
272            {
273                /*
274                 * There is at least one child of this object,
275                 * visit the object
276                 */
277                Level++;
278                ParentHandle = ChildHandle;
279                ChildHandle  = NULL;
280            }
281        }
282        else
283        {
284            /*
285             * No more children in this object, go back up to
286             * the object's parent
287             */
288            Level--;
289
290            /* Delete all children now */
291
292            AcpiNsDeleteChildren (ChildHandle);
293
294            ChildHandle = ParentHandle;
295            Status = AcpiGetParent (ParentHandle, &ParentHandle);
296            if (ACPI_FAILURE (Status))
297            {
298                return_ACPI_STATUS (Status);
299            }
300        }
301    }
302
303    /* Now delete the starting object, and we are done */
304
305    AcpiNsRemoveNode (ChildHandle);
306    return_ACPI_STATUS (AE_OK);
307}
308
309
310/*******************************************************************************
311 *
312 *  FUNCTION:       AcpiNsUnloadNameSpace
313 *
314 *  PARAMETERS:     Handle          - Root of namespace subtree to be deleted
315 *
316 *  RETURN:         Status
317 *
318 *  DESCRIPTION:    Shrinks the namespace, typically in response to an undocking
319 *                  event. Deletes an entire subtree starting from (and
320 *                  including) the given handle.
321 *
322 ******************************************************************************/
323
324ACPI_STATUS
325AcpiNsUnloadNamespace (
326    ACPI_HANDLE             Handle)
327{
328    ACPI_STATUS             Status;
329
330
331    ACPI_FUNCTION_TRACE (NsUnloadNameSpace);
332
333
334    /* Parameter validation */
335
336    if (!AcpiGbl_RootNode)
337    {
338        return_ACPI_STATUS (AE_NO_NAMESPACE);
339    }
340
341    if (!Handle)
342    {
343        return_ACPI_STATUS (AE_BAD_PARAMETER);
344    }
345
346    /* This function does the real work */
347
348    Status = AcpiNsDeleteSubtree (Handle);
349
350    return_ACPI_STATUS (Status);
351}
352#endif
353#endif
354