nsobject.c revision 107325
1/*******************************************************************************
2 *
3 * Module Name: nsobject - Utilities for objects attached to namespace
4 *                         table entries
5 *              $Revision: 85 $
6 *
7 ******************************************************************************/
8
9/******************************************************************************
10 *
11 * 1. Copyright Notice
12 *
13 * Some or all of this work - Copyright (c) 1999 - 2002, Intel Corp.
14 * All rights reserved.
15 *
16 * 2. License
17 *
18 * 2.1. This is your license from Intel Corp. under its intellectual property
19 * rights.  You may have additional license terms from the party that provided
20 * you this software, covering your right to use that party's intellectual
21 * property rights.
22 *
23 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
24 * copy of the source code appearing in this file ("Covered Code") an
25 * irrevocable, perpetual, worldwide license under Intel's copyrights in the
26 * base code distributed originally by Intel ("Original Intel Code") to copy,
27 * make derivatives, distribute, use and display any portion of the Covered
28 * Code in any form, with the right to sublicense such rights; and
29 *
30 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
31 * license (with the right to sublicense), under only those claims of Intel
32 * patents that are infringed by the Original Intel Code, to make, use, sell,
33 * offer to sell, and import the Covered Code and derivative works thereof
34 * solely to the minimum extent necessary to exercise the above copyright
35 * license, and in no event shall the patent license extend to any additions
36 * to or modifications of the Original Intel Code.  No other license or right
37 * is granted directly or by implication, estoppel or otherwise;
38 *
39 * The above copyright and patent license is granted only if the following
40 * conditions are met:
41 *
42 * 3. Conditions
43 *
44 * 3.1. Redistribution of Source with Rights to Further Distribute Source.
45 * Redistribution of source code of any substantial portion of the Covered
46 * Code or modification with rights to further distribute source must include
47 * the above Copyright Notice, the above License, this list of Conditions,
48 * and the following Disclaimer and Export Compliance provision.  In addition,
49 * Licensee must cause all Covered Code to which Licensee contributes to
50 * contain a file documenting the changes Licensee made to create that Covered
51 * Code and the date of any change.  Licensee must include in that file the
52 * documentation of any changes made by any predecessor Licensee.  Licensee
53 * must include a prominent statement that the modification is derived,
54 * directly or indirectly, from Original Intel Code.
55 *
56 * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
57 * Redistribution of source code of any substantial portion of the Covered
58 * Code or modification without rights to further distribute source must
59 * include the following Disclaimer and Export Compliance provision in the
60 * documentation and/or other materials provided with distribution.  In
61 * addition, Licensee may not authorize further sublicense of source of any
62 * portion of the Covered Code, and must include terms to the effect that the
63 * license from Licensee to its licensee is limited to the intellectual
64 * property embodied in the software Licensee provides to its licensee, and
65 * not to intellectual property embodied in modifications its licensee may
66 * make.
67 *
68 * 3.3. Redistribution of Executable. Redistribution in executable form of any
69 * substantial portion of the Covered Code or modification must reproduce the
70 * above Copyright Notice, and the following Disclaimer and Export Compliance
71 * provision in the documentation and/or other materials provided with the
72 * distribution.
73 *
74 * 3.4. Intel retains all right, title, and interest in and to the Original
75 * Intel Code.
76 *
77 * 3.5. Neither the name Intel nor any other trademark owned or controlled by
78 * Intel shall be used in advertising or otherwise to promote the sale, use or
79 * other dealings in products derived from or relating to the Covered Code
80 * without prior written authorization from Intel.
81 *
82 * 4. Disclaimer and Export Compliance
83 *
84 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
85 * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
86 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
87 * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
88 * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
89 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
90 * PARTICULAR PURPOSE.
91 *
92 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
93 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
94 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
95 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
96 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
97 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
98 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
99 * LIMITED REMEDY.
100 *
101 * 4.3. Licensee shall not export, either directly or indirectly, any of this
102 * software or system incorporating such software without first obtaining any
103 * required license or other approval from the U. S. Department of Commerce or
104 * any other agency or department of the United States Government.  In the
105 * event Licensee exports any such software from the United States or
106 * re-exports any such software from a foreign destination, Licensee shall
107 * ensure that the distribution and export/re-export of the software is in
108 * compliance with all laws, regulations, orders, or other restrictions of the
109 * U.S. Export Administration Regulations. Licensee agrees that neither it nor
110 * any of its subsidiaries will export/re-export any technical data, process,
111 * software, or service, directly or indirectly, to any country for which the
112 * United States government or any agency thereof requires an export license,
113 * other governmental approval, or letter of assurance, without first obtaining
114 * such license, approval or letter.
115 *
116 *****************************************************************************/
117
118
119#define __NSOBJECT_C__
120
121#include "acpi.h"
122#include "acnamesp.h"
123
124
125#define _COMPONENT          ACPI_NAMESPACE
126        ACPI_MODULE_NAME    ("nsobject")
127
128
129/*******************************************************************************
130 *
131 * FUNCTION:    AcpiNsAttachObject
132 *
133 * PARAMETERS:  Node                - Parent Node
134 *              Object              - Object to be attached
135 *              Type                - Type of object, or ACPI_TYPE_ANY if not
136 *                                    known
137 *
138 * DESCRIPTION: Record the given object as the value associated with the
139 *              name whose ACPI_HANDLE is passed.  If Object is NULL
140 *              and Type is ACPI_TYPE_ANY, set the name as having no value.
141 *              Note: Future may require that the Node->Flags field be passed
142 *              as a parameter.
143 *
144 * MUTEX:       Assumes namespace is locked
145 *
146 ******************************************************************************/
147
148ACPI_STATUS
149AcpiNsAttachObject (
150    ACPI_NAMESPACE_NODE     *Node,
151    ACPI_OPERAND_OBJECT     *Object,
152    ACPI_OBJECT_TYPE        Type)
153{
154    ACPI_OPERAND_OBJECT     *ObjDesc;
155    ACPI_OPERAND_OBJECT     *LastObjDesc;
156    ACPI_OBJECT_TYPE        ObjectType = ACPI_TYPE_ANY;
157
158
159    ACPI_FUNCTION_TRACE ("NsAttachObject");
160
161
162    /*
163     * Parameter validation
164     */
165    if (!Node)
166    {
167        /* Invalid handle */
168
169        ACPI_REPORT_ERROR (("NsAttachObject: Null NamedObj handle\n"));
170        return_ACPI_STATUS (AE_BAD_PARAMETER);
171    }
172
173    if (!Object && (ACPI_TYPE_ANY != Type))
174    {
175        /* Null object */
176
177        ACPI_REPORT_ERROR (("NsAttachObject: Null object, but type not ACPI_TYPE_ANY\n"));
178        return_ACPI_STATUS (AE_BAD_PARAMETER);
179    }
180
181    if (ACPI_GET_DESCRIPTOR_TYPE (Node) != ACPI_DESC_TYPE_NAMED)
182    {
183        /* Not a name handle */
184
185        ACPI_REPORT_ERROR (("NsAttachObject: Invalid handle\n"));
186        return_ACPI_STATUS (AE_BAD_PARAMETER);
187    }
188
189    /* Check if this object is already attached */
190
191    if (Node->Object == Object)
192    {
193        ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj %p already installed in NameObj %p\n",
194            Object, Node));
195
196        return_ACPI_STATUS (AE_OK);
197    }
198
199    /* If null object, we will just install it */
200
201    if (!Object)
202    {
203        ObjDesc    = NULL;
204        ObjectType = ACPI_TYPE_ANY;
205    }
206
207    /*
208     * If the source object is a namespace Node with an attached object,
209     * we will use that (attached) object
210     */
211    else if ((ACPI_GET_DESCRIPTOR_TYPE (Object) == ACPI_DESC_TYPE_NAMED) &&
212            ((ACPI_NAMESPACE_NODE *) Object)->Object)
213    {
214        /*
215         * Value passed is a name handle and that name has a
216         * non-null value.  Use that name's value and type.
217         */
218        ObjDesc    = ((ACPI_NAMESPACE_NODE *) Object)->Object;
219        ObjectType = ((ACPI_NAMESPACE_NODE *) Object)->Type;
220    }
221
222    /*
223     * Otherwise, we will use the parameter object, but we must type
224     * it first
225     */
226    else
227    {
228        ObjDesc = (ACPI_OPERAND_OBJECT  *) Object;
229
230        /* Use the given type */
231
232        ObjectType = Type;
233    }
234
235    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Installing %p into Node %p [%4.4s]\n",
236        ObjDesc, Node, Node->Name.Ascii));
237
238    /* Detach an existing attached object if present */
239
240    if (Node->Object)
241    {
242        AcpiNsDetachObject (Node);
243    }
244
245    if (ObjDesc)
246    {
247        /*
248         * Must increment the new value's reference count
249         * (if it is an internal object)
250         */
251        AcpiUtAddReference (ObjDesc);
252
253        /*
254         * Handle objects with multiple descriptors - walk
255         * to the end of the descriptor list
256         */
257        LastObjDesc = ObjDesc;
258        while (LastObjDesc->Common.NextObject)
259        {
260            LastObjDesc = LastObjDesc->Common.NextObject;
261        }
262
263        /* Install the object at the front of the object list */
264
265        LastObjDesc->Common.NextObject = Node->Object;
266    }
267
268    Node->Type     = (UINT8) ObjectType;
269    Node->Object   = ObjDesc;
270
271    return_ACPI_STATUS (AE_OK);
272}
273
274
275/*******************************************************************************
276 *
277 * FUNCTION:    AcpiNsDetachObject
278 *
279 * PARAMETERS:  Node           - An node whose object will be detached
280 *
281 * RETURN:      None.
282 *
283 * DESCRIPTION: Detach/delete an object associated with a namespace node.
284 *              if the object is an allocated object, it is freed.
285 *              Otherwise, the field is simply cleared.
286 *
287 ******************************************************************************/
288
289void
290AcpiNsDetachObject (
291    ACPI_NAMESPACE_NODE     *Node)
292{
293    ACPI_OPERAND_OBJECT     *ObjDesc;
294
295
296    ACPI_FUNCTION_TRACE ("NsDetachObject");
297
298
299    ObjDesc = Node->Object;
300
301    if (!ObjDesc ||
302        (ACPI_GET_OBJECT_TYPE (ObjDesc) == ACPI_TYPE_LOCAL_DATA))
303    {
304        return_VOID;
305    }
306
307    /* Clear the entry in all cases */
308
309    Node->Object = NULL;
310    if (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc) == ACPI_DESC_TYPE_OPERAND)
311    {
312        Node->Object = ObjDesc->Common.NextObject;
313        if (Node->Object &&
314           (ACPI_GET_OBJECT_TYPE (Node->Object) != ACPI_TYPE_LOCAL_DATA))
315        {
316            Node->Object = Node->Object->Common.NextObject;
317        }
318    }
319
320    /* Reset the node type to untyped */
321
322    Node->Type = ACPI_TYPE_ANY;
323
324    ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Node %p [%4.4s] Object %p\n",
325        Node, Node->Name.Ascii, ObjDesc));
326
327    /* Remove one reference on the object (and all subobjects) */
328
329    AcpiUtRemoveReference (ObjDesc);
330    return_VOID;
331}
332
333
334/*******************************************************************************
335 *
336 * FUNCTION:    AcpiNsGetAttachedObject
337 *
338 * PARAMETERS:  Node             - Parent Node to be examined
339 *
340 * RETURN:      Current value of the object field from the Node whose
341 *              handle is passed
342 *
343 * DESCRIPTION: Obtain the object attached to a namespace node.
344 *
345 ******************************************************************************/
346
347ACPI_OPERAND_OBJECT *
348AcpiNsGetAttachedObject (
349    ACPI_NAMESPACE_NODE     *Node)
350{
351    ACPI_FUNCTION_TRACE_PTR ("NsGetAttachedObject", Node);
352
353
354    if (!Node)
355    {
356        ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Null Node ptr\n"));
357        return_PTR (NULL);
358    }
359
360    if (!Node->Object ||
361            ((ACPI_GET_DESCRIPTOR_TYPE (Node->Object) != ACPI_DESC_TYPE_OPERAND) &&
362             (ACPI_GET_DESCRIPTOR_TYPE (Node->Object) != ACPI_DESC_TYPE_NAMED))  ||
363        (ACPI_GET_OBJECT_TYPE (Node->Object) == ACPI_TYPE_LOCAL_DATA))
364    {
365        return_PTR (NULL);
366    }
367
368    return_PTR (Node->Object);
369}
370
371
372/*******************************************************************************
373 *
374 * FUNCTION:    AcpiNsGetSecondaryObject
375 *
376 * PARAMETERS:  Node             - Parent Node to be examined
377 *
378 * RETURN:      Current value of the object field from the Node whose
379 *              handle is passed.
380 *
381 * DESCRIPTION: Obtain a secondary object associated with a namespace node.
382 *
383 ******************************************************************************/
384
385ACPI_OPERAND_OBJECT *
386AcpiNsGetSecondaryObject (
387    ACPI_OPERAND_OBJECT     *ObjDesc)
388{
389    ACPI_FUNCTION_TRACE_PTR ("NsGetSecondaryObject", ObjDesc);
390
391
392    if ((!ObjDesc)                                                ||
393        (ACPI_GET_OBJECT_TYPE (ObjDesc) == ACPI_TYPE_LOCAL_DATA)  ||
394        (!ObjDesc->Common.NextObject)                             ||
395        (ACPI_GET_OBJECT_TYPE (ObjDesc->Common.NextObject) == ACPI_TYPE_LOCAL_DATA))
396    {
397        return_PTR (NULL);
398    }
399
400    return_PTR (ObjDesc->Common.NextObject);
401}
402
403
404/*******************************************************************************
405 *
406 * FUNCTION:    AcpiNsAttachData
407 *
408 * PARAMETERS:  Node            - Namespace node
409 *              Handler         - Handler to be associated with the data
410 *              Data            - Data to be attached
411 *
412 * RETURN:      Status
413 *
414 * DESCRIPTION: Low-level attach data.  Create and attach a Data object.
415 *
416 ******************************************************************************/
417
418ACPI_STATUS
419AcpiNsAttachData (
420    ACPI_NAMESPACE_NODE     *Node,
421    ACPI_OBJECT_HANDLER     Handler,
422    void                    *Data)
423{
424    ACPI_OPERAND_OBJECT     *PrevObjDesc;
425    ACPI_OPERAND_OBJECT     *ObjDesc;
426    ACPI_OPERAND_OBJECT     *DataDesc;
427
428
429    /* We only allow one attachment per handler */
430
431    PrevObjDesc = NULL;
432    ObjDesc = Node->Object;
433    while (ObjDesc)
434    {
435        if ((ACPI_GET_OBJECT_TYPE (ObjDesc) == ACPI_TYPE_LOCAL_DATA) &&
436            (ObjDesc->Data.Handler == Handler))
437        {
438            return (AE_ALREADY_EXISTS);
439        }
440
441        PrevObjDesc = ObjDesc;
442        ObjDesc = ObjDesc->Common.NextObject;
443    }
444
445    /* Create an internal object for the data */
446
447    DataDesc = AcpiUtCreateInternalObject (ACPI_TYPE_LOCAL_DATA);
448    if (!DataDesc)
449    {
450        return (AE_NO_MEMORY);
451    }
452
453    DataDesc->Data.Handler = Handler;
454    DataDesc->Data.Pointer = Data;
455
456    /* Install the data object */
457
458    if (PrevObjDesc)
459    {
460        PrevObjDesc->Common.NextObject = DataDesc;
461    }
462    else
463    {
464        Node->Object = DataDesc;
465    }
466
467    return (AE_OK);
468}
469
470
471/*******************************************************************************
472 *
473 * FUNCTION:    AcpiNsDetachData
474 *
475 * PARAMETERS:  Node            - Namespace node
476 *              Handler         - Handler associated with the data
477 *
478 * RETURN:      Status
479 *
480 * DESCRIPTION: Low-level detach data.  Delete the data node, but the caller
481 *              is responsible for the actual data.
482 *
483 ******************************************************************************/
484
485ACPI_STATUS
486AcpiNsDetachData (
487    ACPI_NAMESPACE_NODE     *Node,
488    ACPI_OBJECT_HANDLER     Handler)
489{
490    ACPI_OPERAND_OBJECT     *ObjDesc;
491    ACPI_OPERAND_OBJECT     *PrevObjDesc;
492
493
494    PrevObjDesc = NULL;
495    ObjDesc = Node->Object;
496    while (ObjDesc)
497    {
498        if ((ACPI_GET_OBJECT_TYPE (ObjDesc) == ACPI_TYPE_LOCAL_DATA) &&
499            (ObjDesc->Data.Handler == Handler))
500        {
501            if (PrevObjDesc)
502            {
503                PrevObjDesc->Common.NextObject = ObjDesc->Common.NextObject;
504            }
505            else
506            {
507                Node->Object = ObjDesc->Common.NextObject;
508            }
509
510            AcpiUtRemoveReference (ObjDesc);
511            return (AE_OK);
512        }
513
514        PrevObjDesc = ObjDesc;
515        ObjDesc = ObjDesc->Common.NextObject;
516    }
517
518    return (AE_NOT_FOUND);
519}
520
521
522/*******************************************************************************
523 *
524 * FUNCTION:    AcpiNsGetAttachedData
525 *
526 * PARAMETERS:  Node            - Namespace node
527 *              Handler         - Handler associated with the data
528 *              Data            - Where the data is returned
529 *
530 * RETURN:      Status
531 *
532 * DESCRIPTION: Low level interface to obtain data previously associated with
533 *              a namespace node.
534 *
535 ******************************************************************************/
536
537ACPI_STATUS
538AcpiNsGetAttachedData (
539    ACPI_NAMESPACE_NODE     *Node,
540    ACPI_OBJECT_HANDLER     Handler,
541    void                    **Data)
542{
543    ACPI_OPERAND_OBJECT     *ObjDesc;
544
545
546    ObjDesc = Node->Object;
547    while (ObjDesc)
548    {
549        if ((ACPI_GET_OBJECT_TYPE (ObjDesc) == ACPI_TYPE_LOCAL_DATA) &&
550            (ObjDesc->Data.Handler == Handler))
551        {
552            *Data = ObjDesc->Data.Pointer;
553            return (AE_OK);
554        }
555
556        ObjDesc = ObjDesc->Common.NextObject;
557    }
558
559    return (AE_NOT_FOUND);
560}
561
562
563