xref: /titanic_52/usr/src/uts/intel/io/acpica/namespace/nsobject.c (revision 385cc6b4ad1792caef3f84eb61eed3f27085801f)
1ae115bc7Smrj /*******************************************************************************
2ae115bc7Smrj  *
3ae115bc7Smrj  * Module Name: nsobject - Utilities for objects attached to namespace
4ae115bc7Smrj  *                         table entries
5ae115bc7Smrj  *
6ae115bc7Smrj  ******************************************************************************/
7ae115bc7Smrj 
826f3cdf0SGordon Ross /*
9*385cc6b4SJerry Jelinek  * Copyright (C) 2000 - 2016, Intel Corp.
10ae115bc7Smrj  * All rights reserved.
11ae115bc7Smrj  *
1226f3cdf0SGordon Ross  * Redistribution and use in source and binary forms, with or without
1326f3cdf0SGordon Ross  * modification, are permitted provided that the following conditions
1426f3cdf0SGordon Ross  * are met:
1526f3cdf0SGordon Ross  * 1. Redistributions of source code must retain the above copyright
1626f3cdf0SGordon Ross  *    notice, this list of conditions, and the following disclaimer,
1726f3cdf0SGordon Ross  *    without modification.
1826f3cdf0SGordon Ross  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
1926f3cdf0SGordon Ross  *    substantially similar to the "NO WARRANTY" disclaimer below
2026f3cdf0SGordon Ross  *    ("Disclaimer") and any redistribution must be conditioned upon
2126f3cdf0SGordon Ross  *    including a substantially similar Disclaimer requirement for further
2226f3cdf0SGordon Ross  *    binary redistribution.
2326f3cdf0SGordon Ross  * 3. Neither the names of the above-listed copyright holders nor the names
2426f3cdf0SGordon Ross  *    of any contributors may be used to endorse or promote products derived
2526f3cdf0SGordon Ross  *    from this software without specific prior written permission.
26ae115bc7Smrj  *
2726f3cdf0SGordon Ross  * Alternatively, this software may be distributed under the terms of the
2826f3cdf0SGordon Ross  * GNU General Public License ("GPL") version 2 as published by the Free
2926f3cdf0SGordon Ross  * Software Foundation.
30ae115bc7Smrj  *
3126f3cdf0SGordon Ross  * NO WARRANTY
3226f3cdf0SGordon Ross  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
3326f3cdf0SGordon Ross  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3426f3cdf0SGordon Ross  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
3526f3cdf0SGordon Ross  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3626f3cdf0SGordon Ross  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
3726f3cdf0SGordon Ross  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
3826f3cdf0SGordon Ross  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3926f3cdf0SGordon Ross  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
4026f3cdf0SGordon Ross  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
4126f3cdf0SGordon Ross  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
4226f3cdf0SGordon Ross  * POSSIBILITY OF SUCH DAMAGES.
4326f3cdf0SGordon Ross  */
44ae115bc7Smrj 
45ae115bc7Smrj #include "acpi.h"
46aa2aa9a6SDana Myers #include "accommon.h"
47ae115bc7Smrj #include "acnamesp.h"
48ae115bc7Smrj 
49ae115bc7Smrj 
50ae115bc7Smrj #define _COMPONENT          ACPI_NAMESPACE
51ae115bc7Smrj         ACPI_MODULE_NAME    ("nsobject")
52ae115bc7Smrj 
53ae115bc7Smrj 
54ae115bc7Smrj /*******************************************************************************
55ae115bc7Smrj  *
56ae115bc7Smrj  * FUNCTION:    AcpiNsAttachObject
57ae115bc7Smrj  *
58ae115bc7Smrj  * PARAMETERS:  Node                - Parent Node
59ae115bc7Smrj  *              Object              - Object to be attached
60ae115bc7Smrj  *              Type                - Type of object, or ACPI_TYPE_ANY if not
61ae115bc7Smrj  *                                    known
62ae115bc7Smrj  *
63ae115bc7Smrj  * RETURN:      Status
64ae115bc7Smrj  *
65ae115bc7Smrj  * DESCRIPTION: Record the given object as the value associated with the
66ae115bc7Smrj  *              name whose ACPI_HANDLE is passed. If Object is NULL
67ae115bc7Smrj  *              and Type is ACPI_TYPE_ANY, set the name as having no value.
68ae115bc7Smrj  *              Note: Future may require that the Node->Flags field be passed
69ae115bc7Smrj  *              as a parameter.
70ae115bc7Smrj  *
71ae115bc7Smrj  * MUTEX:       Assumes namespace is locked
72ae115bc7Smrj  *
73ae115bc7Smrj  ******************************************************************************/
74ae115bc7Smrj 
75ae115bc7Smrj ACPI_STATUS
76ae115bc7Smrj AcpiNsAttachObject (
77ae115bc7Smrj     ACPI_NAMESPACE_NODE     *Node,
78ae115bc7Smrj     ACPI_OPERAND_OBJECT     *Object,
79ae115bc7Smrj     ACPI_OBJECT_TYPE        Type)
80ae115bc7Smrj {
81ae115bc7Smrj     ACPI_OPERAND_OBJECT     *ObjDesc;
82ae115bc7Smrj     ACPI_OPERAND_OBJECT     *LastObjDesc;
83ae115bc7Smrj     ACPI_OBJECT_TYPE        ObjectType = ACPI_TYPE_ANY;
84ae115bc7Smrj 
85ae115bc7Smrj 
86ae115bc7Smrj     ACPI_FUNCTION_TRACE (NsAttachObject);
87ae115bc7Smrj 
88ae115bc7Smrj 
89ae115bc7Smrj     /*
90ae115bc7Smrj      * Parameter validation
91ae115bc7Smrj      */
92ae115bc7Smrj     if (!Node)
93ae115bc7Smrj     {
94ae115bc7Smrj         /* Invalid handle */
95ae115bc7Smrj 
96ae115bc7Smrj         ACPI_ERROR ((AE_INFO, "Null NamedObj handle"));
97ae115bc7Smrj         return_ACPI_STATUS (AE_BAD_PARAMETER);
98ae115bc7Smrj     }
99ae115bc7Smrj 
100ae115bc7Smrj     if (!Object && (ACPI_TYPE_ANY != Type))
101ae115bc7Smrj     {
102ae115bc7Smrj         /* Null object */
103ae115bc7Smrj 
104ae115bc7Smrj         ACPI_ERROR ((AE_INFO,
105ae115bc7Smrj             "Null object, but type not ACPI_TYPE_ANY"));
106ae115bc7Smrj         return_ACPI_STATUS (AE_BAD_PARAMETER);
107ae115bc7Smrj     }
108ae115bc7Smrj 
109ae115bc7Smrj     if (ACPI_GET_DESCRIPTOR_TYPE (Node) != ACPI_DESC_TYPE_NAMED)
110ae115bc7Smrj     {
111ae115bc7Smrj         /* Not a name handle */
112ae115bc7Smrj 
113ae115bc7Smrj         ACPI_ERROR ((AE_INFO, "Invalid handle %p [%s]",
114ae115bc7Smrj             Node, AcpiUtGetDescriptorName (Node)));
115ae115bc7Smrj         return_ACPI_STATUS (AE_BAD_PARAMETER);
116ae115bc7Smrj     }
117ae115bc7Smrj 
118ae115bc7Smrj     /* Check if this object is already attached */
119ae115bc7Smrj 
120ae115bc7Smrj     if (Node->Object == Object)
121ae115bc7Smrj     {
122ae115bc7Smrj         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
123ae115bc7Smrj             "Obj %p already installed in NameObj %p\n",
124ae115bc7Smrj             Object, Node));
125ae115bc7Smrj 
126ae115bc7Smrj         return_ACPI_STATUS (AE_OK);
127ae115bc7Smrj     }
128ae115bc7Smrj 
129ae115bc7Smrj     /* If null object, we will just install it */
130ae115bc7Smrj 
131ae115bc7Smrj     if (!Object)
132ae115bc7Smrj     {
133ae115bc7Smrj         ObjDesc    = NULL;
134ae115bc7Smrj         ObjectType = ACPI_TYPE_ANY;
135ae115bc7Smrj     }
136ae115bc7Smrj 
137ae115bc7Smrj     /*
138ae115bc7Smrj      * If the source object is a namespace Node with an attached object,
139ae115bc7Smrj      * we will use that (attached) object
140ae115bc7Smrj      */
141ae115bc7Smrj     else if ((ACPI_GET_DESCRIPTOR_TYPE (Object) == ACPI_DESC_TYPE_NAMED) &&
142ae115bc7Smrj             ((ACPI_NAMESPACE_NODE *) Object)->Object)
143ae115bc7Smrj     {
144ae115bc7Smrj         /*
145ae115bc7Smrj          * Value passed is a name handle and that name has a
146ae115bc7Smrj          * non-null value. Use that name's value and type.
147ae115bc7Smrj          */
148ae115bc7Smrj         ObjDesc = ((ACPI_NAMESPACE_NODE *) Object)->Object;
149ae115bc7Smrj         ObjectType = ((ACPI_NAMESPACE_NODE *) Object)->Type;
150ae115bc7Smrj     }
151ae115bc7Smrj 
152ae115bc7Smrj     /*
153ae115bc7Smrj      * Otherwise, we will use the parameter object, but we must type
154ae115bc7Smrj      * it first
155ae115bc7Smrj      */
156ae115bc7Smrj     else
157ae115bc7Smrj     {
158ae115bc7Smrj         ObjDesc = (ACPI_OPERAND_OBJECT  *) Object;
159ae115bc7Smrj 
160ae115bc7Smrj         /* Use the given type */
161ae115bc7Smrj 
162ae115bc7Smrj         ObjectType = Type;
163ae115bc7Smrj     }
164ae115bc7Smrj 
165ae115bc7Smrj     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Installing %p into Node %p [%4.4s]\n",
166ae115bc7Smrj         ObjDesc, Node, AcpiUtGetNodeName (Node)));
167ae115bc7Smrj 
168ae115bc7Smrj     /* Detach an existing attached object if present */
169ae115bc7Smrj 
170ae115bc7Smrj     if (Node->Object)
171ae115bc7Smrj     {
172ae115bc7Smrj         AcpiNsDetachObject (Node);
173ae115bc7Smrj     }
174ae115bc7Smrj 
175ae115bc7Smrj     if (ObjDesc)
176ae115bc7Smrj     {
177ae115bc7Smrj         /*
178ae115bc7Smrj          * Must increment the new value's reference count
179ae115bc7Smrj          * (if it is an internal object)
180ae115bc7Smrj          */
181ae115bc7Smrj         AcpiUtAddReference (ObjDesc);
182ae115bc7Smrj 
183ae115bc7Smrj         /*
184ae115bc7Smrj          * Handle objects with multiple descriptors - walk
185ae115bc7Smrj          * to the end of the descriptor list
186ae115bc7Smrj          */
187ae115bc7Smrj         LastObjDesc = ObjDesc;
188ae115bc7Smrj         while (LastObjDesc->Common.NextObject)
189ae115bc7Smrj         {
190ae115bc7Smrj             LastObjDesc = LastObjDesc->Common.NextObject;
191ae115bc7Smrj         }
192ae115bc7Smrj 
193ae115bc7Smrj         /* Install the object at the front of the object list */
194ae115bc7Smrj 
195ae115bc7Smrj         LastObjDesc->Common.NextObject = Node->Object;
196ae115bc7Smrj     }
197ae115bc7Smrj 
198ae115bc7Smrj     Node->Type = (UINT8) ObjectType;
199ae115bc7Smrj     Node->Object = ObjDesc;
200ae115bc7Smrj 
201ae115bc7Smrj     return_ACPI_STATUS (AE_OK);
202ae115bc7Smrj }
203ae115bc7Smrj 
204ae115bc7Smrj 
205ae115bc7Smrj /*******************************************************************************
206ae115bc7Smrj  *
207ae115bc7Smrj  * FUNCTION:    AcpiNsDetachObject
208ae115bc7Smrj  *
209ae115bc7Smrj  * PARAMETERS:  Node           - A Namespace node whose object will be detached
210ae115bc7Smrj  *
211ae115bc7Smrj  * RETURN:      None.
212ae115bc7Smrj  *
213ae115bc7Smrj  * DESCRIPTION: Detach/delete an object associated with a namespace node.
214ae115bc7Smrj  *              if the object is an allocated object, it is freed.
215ae115bc7Smrj  *              Otherwise, the field is simply cleared.
216ae115bc7Smrj  *
217ae115bc7Smrj  ******************************************************************************/
218ae115bc7Smrj 
219ae115bc7Smrj void
220ae115bc7Smrj AcpiNsDetachObject (
221ae115bc7Smrj     ACPI_NAMESPACE_NODE     *Node)
222ae115bc7Smrj {
223ae115bc7Smrj     ACPI_OPERAND_OBJECT     *ObjDesc;
224ae115bc7Smrj 
225ae115bc7Smrj 
226ae115bc7Smrj     ACPI_FUNCTION_TRACE (NsDetachObject);
227ae115bc7Smrj 
228ae115bc7Smrj 
229ae115bc7Smrj     ObjDesc = Node->Object;
230ae115bc7Smrj 
231ae115bc7Smrj     if (!ObjDesc ||
232aa2aa9a6SDana Myers         (ObjDesc->Common.Type == ACPI_TYPE_LOCAL_DATA))
233ae115bc7Smrj     {
234ae115bc7Smrj         return_VOID;
235ae115bc7Smrj     }
236ae115bc7Smrj 
237aa2aa9a6SDana Myers     if (Node->Flags & ANOBJ_ALLOCATED_BUFFER)
238aa2aa9a6SDana Myers     {
239aa2aa9a6SDana Myers         /* Free the dynamic aml buffer */
240aa2aa9a6SDana Myers 
241aa2aa9a6SDana Myers         if (ObjDesc->Common.Type == ACPI_TYPE_METHOD)
242aa2aa9a6SDana Myers         {
243aa2aa9a6SDana Myers             ACPI_FREE (ObjDesc->Method.AmlStart);
244aa2aa9a6SDana Myers         }
245aa2aa9a6SDana Myers     }
246aa2aa9a6SDana Myers 
247*385cc6b4SJerry Jelinek     /* Clear the Node entry in all cases */
248ae115bc7Smrj 
249ae115bc7Smrj     Node->Object = NULL;
250ae115bc7Smrj     if (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc) == ACPI_DESC_TYPE_OPERAND)
251ae115bc7Smrj     {
252*385cc6b4SJerry Jelinek         /* Unlink object from front of possible object list */
253*385cc6b4SJerry Jelinek 
254ae115bc7Smrj         Node->Object = ObjDesc->Common.NextObject;
255*385cc6b4SJerry Jelinek 
256*385cc6b4SJerry Jelinek         /* Handle possible 2-descriptor object */
257*385cc6b4SJerry Jelinek 
258ae115bc7Smrj         if (Node->Object &&
259*385cc6b4SJerry Jelinek            (Node->Object->Common.Type != ACPI_TYPE_LOCAL_DATA))
260ae115bc7Smrj         {
261ae115bc7Smrj             Node->Object = Node->Object->Common.NextObject;
262ae115bc7Smrj         }
263*385cc6b4SJerry Jelinek 
264*385cc6b4SJerry Jelinek         /*
265*385cc6b4SJerry Jelinek          * Detach the object from any data objects (which are still held by
266*385cc6b4SJerry Jelinek          * the namespace node)
267*385cc6b4SJerry Jelinek          */
268*385cc6b4SJerry Jelinek         if (ObjDesc->Common.NextObject &&
269*385cc6b4SJerry Jelinek            ((ObjDesc->Common.NextObject)->Common.Type == ACPI_TYPE_LOCAL_DATA))
270*385cc6b4SJerry Jelinek         {
271*385cc6b4SJerry Jelinek            ObjDesc->Common.NextObject = NULL;
272*385cc6b4SJerry Jelinek         }
273ae115bc7Smrj     }
274ae115bc7Smrj 
275ae115bc7Smrj     /* Reset the node type to untyped */
276ae115bc7Smrj 
277ae115bc7Smrj     Node->Type = ACPI_TYPE_ANY;
278ae115bc7Smrj 
279ae115bc7Smrj     ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Node %p [%4.4s] Object %p\n",
280ae115bc7Smrj         Node, AcpiUtGetNodeName (Node), ObjDesc));
281ae115bc7Smrj 
282ae115bc7Smrj     /* Remove one reference on the object (and all subobjects) */
283ae115bc7Smrj 
284ae115bc7Smrj     AcpiUtRemoveReference (ObjDesc);
285ae115bc7Smrj     return_VOID;
286ae115bc7Smrj }
287ae115bc7Smrj 
288ae115bc7Smrj 
289ae115bc7Smrj /*******************************************************************************
290ae115bc7Smrj  *
291ae115bc7Smrj  * FUNCTION:    AcpiNsGetAttachedObject
292ae115bc7Smrj  *
293ae115bc7Smrj  * PARAMETERS:  Node             - Namespace node
294ae115bc7Smrj  *
295ae115bc7Smrj  * RETURN:      Current value of the object field from the Node whose
296ae115bc7Smrj  *              handle is passed
297ae115bc7Smrj  *
298ae115bc7Smrj  * DESCRIPTION: Obtain the object attached to a namespace node.
299ae115bc7Smrj  *
300ae115bc7Smrj  ******************************************************************************/
301ae115bc7Smrj 
302ae115bc7Smrj ACPI_OPERAND_OBJECT *
303ae115bc7Smrj AcpiNsGetAttachedObject (
304ae115bc7Smrj     ACPI_NAMESPACE_NODE     *Node)
305ae115bc7Smrj {
306ae115bc7Smrj     ACPI_FUNCTION_TRACE_PTR (NsGetAttachedObject, Node);
307ae115bc7Smrj 
308ae115bc7Smrj 
309ae115bc7Smrj     if (!Node)
310ae115bc7Smrj     {
311ae115bc7Smrj         ACPI_WARNING ((AE_INFO, "Null Node ptr"));
312ae115bc7Smrj         return_PTR (NULL);
313ae115bc7Smrj     }
314ae115bc7Smrj 
315ae115bc7Smrj     if (!Node->Object ||
316ae115bc7Smrj             ((ACPI_GET_DESCRIPTOR_TYPE (Node->Object) != ACPI_DESC_TYPE_OPERAND) &&
317ae115bc7Smrj              (ACPI_GET_DESCRIPTOR_TYPE (Node->Object) != ACPI_DESC_TYPE_NAMED))  ||
318aa2aa9a6SDana Myers         ((Node->Object)->Common.Type == ACPI_TYPE_LOCAL_DATA))
319ae115bc7Smrj     {
320ae115bc7Smrj         return_PTR (NULL);
321ae115bc7Smrj     }
322ae115bc7Smrj 
323ae115bc7Smrj     return_PTR (Node->Object);
324ae115bc7Smrj }
325ae115bc7Smrj 
326ae115bc7Smrj 
327ae115bc7Smrj /*******************************************************************************
328ae115bc7Smrj  *
329ae115bc7Smrj  * FUNCTION:    AcpiNsGetSecondaryObject
330ae115bc7Smrj  *
331ae115bc7Smrj  * PARAMETERS:  Node             - Namespace node
332ae115bc7Smrj  *
333ae115bc7Smrj  * RETURN:      Current value of the object field from the Node whose
334ae115bc7Smrj  *              handle is passed.
335ae115bc7Smrj  *
336ae115bc7Smrj  * DESCRIPTION: Obtain a secondary object associated with a namespace node.
337ae115bc7Smrj  *
338ae115bc7Smrj  ******************************************************************************/
339ae115bc7Smrj 
340ae115bc7Smrj ACPI_OPERAND_OBJECT *
341ae115bc7Smrj AcpiNsGetSecondaryObject (
342ae115bc7Smrj     ACPI_OPERAND_OBJECT     *ObjDesc)
343ae115bc7Smrj {
344ae115bc7Smrj     ACPI_FUNCTION_TRACE_PTR (NsGetSecondaryObject, ObjDesc);
345ae115bc7Smrj 
346ae115bc7Smrj 
347ae115bc7Smrj     if ((!ObjDesc)                                     ||
348aa2aa9a6SDana Myers         (ObjDesc->Common.Type== ACPI_TYPE_LOCAL_DATA)  ||
349ae115bc7Smrj         (!ObjDesc->Common.NextObject)                  ||
350aa2aa9a6SDana Myers         ((ObjDesc->Common.NextObject)->Common.Type == ACPI_TYPE_LOCAL_DATA))
351ae115bc7Smrj     {
352ae115bc7Smrj         return_PTR (NULL);
353ae115bc7Smrj     }
354ae115bc7Smrj 
355ae115bc7Smrj     return_PTR (ObjDesc->Common.NextObject);
356ae115bc7Smrj }
357ae115bc7Smrj 
358ae115bc7Smrj 
359ae115bc7Smrj /*******************************************************************************
360ae115bc7Smrj  *
361ae115bc7Smrj  * FUNCTION:    AcpiNsAttachData
362ae115bc7Smrj  *
363ae115bc7Smrj  * PARAMETERS:  Node            - Namespace node
364ae115bc7Smrj  *              Handler         - Handler to be associated with the data
365ae115bc7Smrj  *              Data            - Data to be attached
366ae115bc7Smrj  *
367ae115bc7Smrj  * RETURN:      Status
368ae115bc7Smrj  *
369ae115bc7Smrj  * DESCRIPTION: Low-level attach data. Create and attach a Data object.
370ae115bc7Smrj  *
371ae115bc7Smrj  ******************************************************************************/
372ae115bc7Smrj 
373ae115bc7Smrj ACPI_STATUS
374ae115bc7Smrj AcpiNsAttachData (
375ae115bc7Smrj     ACPI_NAMESPACE_NODE     *Node,
376ae115bc7Smrj     ACPI_OBJECT_HANDLER     Handler,
377ae115bc7Smrj     void                    *Data)
378ae115bc7Smrj {
379ae115bc7Smrj     ACPI_OPERAND_OBJECT     *PrevObjDesc;
380ae115bc7Smrj     ACPI_OPERAND_OBJECT     *ObjDesc;
381ae115bc7Smrj     ACPI_OPERAND_OBJECT     *DataDesc;
382ae115bc7Smrj 
383ae115bc7Smrj 
384ae115bc7Smrj     /* We only allow one attachment per handler */
385ae115bc7Smrj 
386ae115bc7Smrj     PrevObjDesc = NULL;
387ae115bc7Smrj     ObjDesc = Node->Object;
388ae115bc7Smrj     while (ObjDesc)
389ae115bc7Smrj     {
390aa2aa9a6SDana Myers         if ((ObjDesc->Common.Type == ACPI_TYPE_LOCAL_DATA) &&
391ae115bc7Smrj             (ObjDesc->Data.Handler == Handler))
392ae115bc7Smrj         {
393ae115bc7Smrj             return (AE_ALREADY_EXISTS);
394ae115bc7Smrj         }
395ae115bc7Smrj 
396ae115bc7Smrj         PrevObjDesc = ObjDesc;
397ae115bc7Smrj         ObjDesc = ObjDesc->Common.NextObject;
398ae115bc7Smrj     }
399ae115bc7Smrj 
400ae115bc7Smrj     /* Create an internal object for the data */
401ae115bc7Smrj 
402ae115bc7Smrj     DataDesc = AcpiUtCreateInternalObject (ACPI_TYPE_LOCAL_DATA);
403ae115bc7Smrj     if (!DataDesc)
404ae115bc7Smrj     {
405ae115bc7Smrj         return (AE_NO_MEMORY);
406ae115bc7Smrj     }
407ae115bc7Smrj 
408ae115bc7Smrj     DataDesc->Data.Handler = Handler;
409ae115bc7Smrj     DataDesc->Data.Pointer = Data;
410ae115bc7Smrj 
411ae115bc7Smrj     /* Install the data object */
412ae115bc7Smrj 
413ae115bc7Smrj     if (PrevObjDesc)
414ae115bc7Smrj     {
415ae115bc7Smrj         PrevObjDesc->Common.NextObject = DataDesc;
416ae115bc7Smrj     }
417ae115bc7Smrj     else
418ae115bc7Smrj     {
419ae115bc7Smrj         Node->Object = DataDesc;
420ae115bc7Smrj     }
421ae115bc7Smrj 
422ae115bc7Smrj     return (AE_OK);
423ae115bc7Smrj }
424ae115bc7Smrj 
425ae115bc7Smrj 
426ae115bc7Smrj /*******************************************************************************
427ae115bc7Smrj  *
428ae115bc7Smrj  * FUNCTION:    AcpiNsDetachData
429ae115bc7Smrj  *
430ae115bc7Smrj  * PARAMETERS:  Node            - Namespace node
431ae115bc7Smrj  *              Handler         - Handler associated with the data
432ae115bc7Smrj  *
433ae115bc7Smrj  * RETURN:      Status
434ae115bc7Smrj  *
435ae115bc7Smrj  * DESCRIPTION: Low-level detach data. Delete the data node, but the caller
436ae115bc7Smrj  *              is responsible for the actual data.
437ae115bc7Smrj  *
438ae115bc7Smrj  ******************************************************************************/
439ae115bc7Smrj 
440ae115bc7Smrj ACPI_STATUS
441ae115bc7Smrj AcpiNsDetachData (
442ae115bc7Smrj     ACPI_NAMESPACE_NODE     *Node,
443ae115bc7Smrj     ACPI_OBJECT_HANDLER     Handler)
444ae115bc7Smrj {
445ae115bc7Smrj     ACPI_OPERAND_OBJECT     *ObjDesc;
446ae115bc7Smrj     ACPI_OPERAND_OBJECT     *PrevObjDesc;
447ae115bc7Smrj 
448ae115bc7Smrj 
449ae115bc7Smrj     PrevObjDesc = NULL;
450ae115bc7Smrj     ObjDesc = Node->Object;
451ae115bc7Smrj     while (ObjDesc)
452ae115bc7Smrj     {
453aa2aa9a6SDana Myers         if ((ObjDesc->Common.Type == ACPI_TYPE_LOCAL_DATA) &&
454ae115bc7Smrj             (ObjDesc->Data.Handler == Handler))
455ae115bc7Smrj         {
456ae115bc7Smrj             if (PrevObjDesc)
457ae115bc7Smrj             {
458ae115bc7Smrj                 PrevObjDesc->Common.NextObject = ObjDesc->Common.NextObject;
459ae115bc7Smrj             }
460ae115bc7Smrj             else
461ae115bc7Smrj             {
462ae115bc7Smrj                 Node->Object = ObjDesc->Common.NextObject;
463ae115bc7Smrj             }
464ae115bc7Smrj 
465ae115bc7Smrj             AcpiUtRemoveReference (ObjDesc);
466ae115bc7Smrj             return (AE_OK);
467ae115bc7Smrj         }
468ae115bc7Smrj 
469ae115bc7Smrj         PrevObjDesc = ObjDesc;
470ae115bc7Smrj         ObjDesc = ObjDesc->Common.NextObject;
471ae115bc7Smrj     }
472ae115bc7Smrj 
473ae115bc7Smrj     return (AE_NOT_FOUND);
474ae115bc7Smrj }
475ae115bc7Smrj 
476ae115bc7Smrj 
477ae115bc7Smrj /*******************************************************************************
478ae115bc7Smrj  *
479ae115bc7Smrj  * FUNCTION:    AcpiNsGetAttachedData
480ae115bc7Smrj  *
481ae115bc7Smrj  * PARAMETERS:  Node            - Namespace node
482ae115bc7Smrj  *              Handler         - Handler associated with the data
483ae115bc7Smrj  *              Data            - Where the data is returned
484ae115bc7Smrj  *
485ae115bc7Smrj  * RETURN:      Status
486ae115bc7Smrj  *
487ae115bc7Smrj  * DESCRIPTION: Low level interface to obtain data previously associated with
488ae115bc7Smrj  *              a namespace node.
489ae115bc7Smrj  *
490ae115bc7Smrj  ******************************************************************************/
491ae115bc7Smrj 
492ae115bc7Smrj ACPI_STATUS
493ae115bc7Smrj AcpiNsGetAttachedData (
494ae115bc7Smrj     ACPI_NAMESPACE_NODE     *Node,
495ae115bc7Smrj     ACPI_OBJECT_HANDLER     Handler,
496ae115bc7Smrj     void                    **Data)
497ae115bc7Smrj {
498ae115bc7Smrj     ACPI_OPERAND_OBJECT     *ObjDesc;
499ae115bc7Smrj 
500ae115bc7Smrj 
501ae115bc7Smrj     ObjDesc = Node->Object;
502ae115bc7Smrj     while (ObjDesc)
503ae115bc7Smrj     {
504aa2aa9a6SDana Myers         if ((ObjDesc->Common.Type == ACPI_TYPE_LOCAL_DATA) &&
505ae115bc7Smrj             (ObjDesc->Data.Handler == Handler))
506ae115bc7Smrj         {
507ae115bc7Smrj             *Data = ObjDesc->Data.Pointer;
508ae115bc7Smrj             return (AE_OK);
509ae115bc7Smrj         }
510ae115bc7Smrj 
511ae115bc7Smrj         ObjDesc = ObjDesc->Common.NextObject;
512ae115bc7Smrj     }
513ae115bc7Smrj 
514ae115bc7Smrj     return (AE_NOT_FOUND);
515ae115bc7Smrj }
516