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