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