1*4882a593Smuzhiyun // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2*4882a593Smuzhiyun /*******************************************************************************
3*4882a593Smuzhiyun *
4*4882a593Smuzhiyun * Module Name: nsobject - Utilities for objects attached to namespace
5*4882a593Smuzhiyun * table entries
6*4882a593Smuzhiyun *
7*4882a593Smuzhiyun ******************************************************************************/
8*4882a593Smuzhiyun
9*4882a593Smuzhiyun #include <acpi/acpi.h>
10*4882a593Smuzhiyun #include "accommon.h"
11*4882a593Smuzhiyun #include "acnamesp.h"
12*4882a593Smuzhiyun
13*4882a593Smuzhiyun #define _COMPONENT ACPI_NAMESPACE
14*4882a593Smuzhiyun ACPI_MODULE_NAME("nsobject")
15*4882a593Smuzhiyun
16*4882a593Smuzhiyun /*******************************************************************************
17*4882a593Smuzhiyun *
18*4882a593Smuzhiyun * FUNCTION: acpi_ns_attach_object
19*4882a593Smuzhiyun *
20*4882a593Smuzhiyun * PARAMETERS: node - Parent Node
21*4882a593Smuzhiyun * object - Object to be attached
22*4882a593Smuzhiyun * type - Type of object, or ACPI_TYPE_ANY if not
23*4882a593Smuzhiyun * known
24*4882a593Smuzhiyun *
25*4882a593Smuzhiyun * RETURN: Status
26*4882a593Smuzhiyun *
27*4882a593Smuzhiyun * DESCRIPTION: Record the given object as the value associated with the
28*4882a593Smuzhiyun * name whose acpi_handle is passed. If Object is NULL
29*4882a593Smuzhiyun * and Type is ACPI_TYPE_ANY, set the name as having no value.
30*4882a593Smuzhiyun * Note: Future may require that the Node->Flags field be passed
31*4882a593Smuzhiyun * as a parameter.
32*4882a593Smuzhiyun *
33*4882a593Smuzhiyun * MUTEX: Assumes namespace is locked
34*4882a593Smuzhiyun *
35*4882a593Smuzhiyun ******************************************************************************/
36*4882a593Smuzhiyun acpi_status
acpi_ns_attach_object(struct acpi_namespace_node * node,union acpi_operand_object * object,acpi_object_type type)37*4882a593Smuzhiyun acpi_ns_attach_object(struct acpi_namespace_node *node,
38*4882a593Smuzhiyun union acpi_operand_object *object, acpi_object_type type)
39*4882a593Smuzhiyun {
40*4882a593Smuzhiyun union acpi_operand_object *obj_desc;
41*4882a593Smuzhiyun union acpi_operand_object *last_obj_desc;
42*4882a593Smuzhiyun acpi_object_type object_type = ACPI_TYPE_ANY;
43*4882a593Smuzhiyun
44*4882a593Smuzhiyun ACPI_FUNCTION_TRACE(ns_attach_object);
45*4882a593Smuzhiyun
46*4882a593Smuzhiyun /*
47*4882a593Smuzhiyun * Parameter validation
48*4882a593Smuzhiyun */
49*4882a593Smuzhiyun if (!node) {
50*4882a593Smuzhiyun
51*4882a593Smuzhiyun /* Invalid handle */
52*4882a593Smuzhiyun
53*4882a593Smuzhiyun ACPI_ERROR((AE_INFO, "Null NamedObj handle"));
54*4882a593Smuzhiyun return_ACPI_STATUS(AE_BAD_PARAMETER);
55*4882a593Smuzhiyun }
56*4882a593Smuzhiyun
57*4882a593Smuzhiyun if (!object && (ACPI_TYPE_ANY != type)) {
58*4882a593Smuzhiyun
59*4882a593Smuzhiyun /* Null object */
60*4882a593Smuzhiyun
61*4882a593Smuzhiyun ACPI_ERROR((AE_INFO,
62*4882a593Smuzhiyun "Null object, but type not ACPI_TYPE_ANY"));
63*4882a593Smuzhiyun return_ACPI_STATUS(AE_BAD_PARAMETER);
64*4882a593Smuzhiyun }
65*4882a593Smuzhiyun
66*4882a593Smuzhiyun if (ACPI_GET_DESCRIPTOR_TYPE(node) != ACPI_DESC_TYPE_NAMED) {
67*4882a593Smuzhiyun
68*4882a593Smuzhiyun /* Not a name handle */
69*4882a593Smuzhiyun
70*4882a593Smuzhiyun ACPI_ERROR((AE_INFO, "Invalid handle %p [%s]",
71*4882a593Smuzhiyun node, acpi_ut_get_descriptor_name(node)));
72*4882a593Smuzhiyun return_ACPI_STATUS(AE_BAD_PARAMETER);
73*4882a593Smuzhiyun }
74*4882a593Smuzhiyun
75*4882a593Smuzhiyun /* Check if this object is already attached */
76*4882a593Smuzhiyun
77*4882a593Smuzhiyun if (node->object == object) {
78*4882a593Smuzhiyun ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
79*4882a593Smuzhiyun "Obj %p already installed in NameObj %p\n",
80*4882a593Smuzhiyun object, node));
81*4882a593Smuzhiyun
82*4882a593Smuzhiyun return_ACPI_STATUS(AE_OK);
83*4882a593Smuzhiyun }
84*4882a593Smuzhiyun
85*4882a593Smuzhiyun /* If null object, we will just install it */
86*4882a593Smuzhiyun
87*4882a593Smuzhiyun if (!object) {
88*4882a593Smuzhiyun obj_desc = NULL;
89*4882a593Smuzhiyun object_type = ACPI_TYPE_ANY;
90*4882a593Smuzhiyun }
91*4882a593Smuzhiyun
92*4882a593Smuzhiyun /*
93*4882a593Smuzhiyun * If the source object is a namespace Node with an attached object,
94*4882a593Smuzhiyun * we will use that (attached) object
95*4882a593Smuzhiyun */
96*4882a593Smuzhiyun else if ((ACPI_GET_DESCRIPTOR_TYPE(object) == ACPI_DESC_TYPE_NAMED) &&
97*4882a593Smuzhiyun ((struct acpi_namespace_node *)object)->object) {
98*4882a593Smuzhiyun /*
99*4882a593Smuzhiyun * Value passed is a name handle and that name has a
100*4882a593Smuzhiyun * non-null value. Use that name's value and type.
101*4882a593Smuzhiyun */
102*4882a593Smuzhiyun obj_desc = ((struct acpi_namespace_node *)object)->object;
103*4882a593Smuzhiyun object_type = ((struct acpi_namespace_node *)object)->type;
104*4882a593Smuzhiyun }
105*4882a593Smuzhiyun
106*4882a593Smuzhiyun /*
107*4882a593Smuzhiyun * Otherwise, we will use the parameter object, but we must type
108*4882a593Smuzhiyun * it first
109*4882a593Smuzhiyun */
110*4882a593Smuzhiyun else {
111*4882a593Smuzhiyun obj_desc = (union acpi_operand_object *)object;
112*4882a593Smuzhiyun
113*4882a593Smuzhiyun /* Use the given type */
114*4882a593Smuzhiyun
115*4882a593Smuzhiyun object_type = type;
116*4882a593Smuzhiyun }
117*4882a593Smuzhiyun
118*4882a593Smuzhiyun ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Installing %p into Node %p [%4.4s]\n",
119*4882a593Smuzhiyun obj_desc, node, acpi_ut_get_node_name(node)));
120*4882a593Smuzhiyun
121*4882a593Smuzhiyun /* Detach an existing attached object if present */
122*4882a593Smuzhiyun
123*4882a593Smuzhiyun if (node->object) {
124*4882a593Smuzhiyun acpi_ns_detach_object(node);
125*4882a593Smuzhiyun }
126*4882a593Smuzhiyun
127*4882a593Smuzhiyun if (obj_desc) {
128*4882a593Smuzhiyun /*
129*4882a593Smuzhiyun * Must increment the new value's reference count
130*4882a593Smuzhiyun * (if it is an internal object)
131*4882a593Smuzhiyun */
132*4882a593Smuzhiyun acpi_ut_add_reference(obj_desc);
133*4882a593Smuzhiyun
134*4882a593Smuzhiyun /*
135*4882a593Smuzhiyun * Handle objects with multiple descriptors - walk
136*4882a593Smuzhiyun * to the end of the descriptor list
137*4882a593Smuzhiyun */
138*4882a593Smuzhiyun last_obj_desc = obj_desc;
139*4882a593Smuzhiyun while (last_obj_desc->common.next_object) {
140*4882a593Smuzhiyun last_obj_desc = last_obj_desc->common.next_object;
141*4882a593Smuzhiyun }
142*4882a593Smuzhiyun
143*4882a593Smuzhiyun /* Install the object at the front of the object list */
144*4882a593Smuzhiyun
145*4882a593Smuzhiyun last_obj_desc->common.next_object = node->object;
146*4882a593Smuzhiyun }
147*4882a593Smuzhiyun
148*4882a593Smuzhiyun node->type = (u8) object_type;
149*4882a593Smuzhiyun node->object = obj_desc;
150*4882a593Smuzhiyun
151*4882a593Smuzhiyun return_ACPI_STATUS(AE_OK);
152*4882a593Smuzhiyun }
153*4882a593Smuzhiyun
154*4882a593Smuzhiyun /*******************************************************************************
155*4882a593Smuzhiyun *
156*4882a593Smuzhiyun * FUNCTION: acpi_ns_detach_object
157*4882a593Smuzhiyun *
158*4882a593Smuzhiyun * PARAMETERS: node - A Namespace node whose object will be detached
159*4882a593Smuzhiyun *
160*4882a593Smuzhiyun * RETURN: None.
161*4882a593Smuzhiyun *
162*4882a593Smuzhiyun * DESCRIPTION: Detach/delete an object associated with a namespace node.
163*4882a593Smuzhiyun * if the object is an allocated object, it is freed.
164*4882a593Smuzhiyun * Otherwise, the field is simply cleared.
165*4882a593Smuzhiyun *
166*4882a593Smuzhiyun ******************************************************************************/
167*4882a593Smuzhiyun
acpi_ns_detach_object(struct acpi_namespace_node * node)168*4882a593Smuzhiyun void acpi_ns_detach_object(struct acpi_namespace_node *node)
169*4882a593Smuzhiyun {
170*4882a593Smuzhiyun union acpi_operand_object *obj_desc;
171*4882a593Smuzhiyun
172*4882a593Smuzhiyun ACPI_FUNCTION_TRACE(ns_detach_object);
173*4882a593Smuzhiyun
174*4882a593Smuzhiyun obj_desc = node->object;
175*4882a593Smuzhiyun
176*4882a593Smuzhiyun if (!obj_desc || (obj_desc->common.type == ACPI_TYPE_LOCAL_DATA)) {
177*4882a593Smuzhiyun return_VOID;
178*4882a593Smuzhiyun }
179*4882a593Smuzhiyun
180*4882a593Smuzhiyun if (node->flags & ANOBJ_ALLOCATED_BUFFER) {
181*4882a593Smuzhiyun
182*4882a593Smuzhiyun /* Free the dynamic aml buffer */
183*4882a593Smuzhiyun
184*4882a593Smuzhiyun if (obj_desc->common.type == ACPI_TYPE_METHOD) {
185*4882a593Smuzhiyun ACPI_FREE(obj_desc->method.aml_start);
186*4882a593Smuzhiyun }
187*4882a593Smuzhiyun }
188*4882a593Smuzhiyun
189*4882a593Smuzhiyun if (obj_desc->common.type == ACPI_TYPE_REGION) {
190*4882a593Smuzhiyun acpi_ut_remove_address_range(obj_desc->region.space_id, node);
191*4882a593Smuzhiyun }
192*4882a593Smuzhiyun
193*4882a593Smuzhiyun /* Clear the Node entry in all cases */
194*4882a593Smuzhiyun
195*4882a593Smuzhiyun node->object = NULL;
196*4882a593Smuzhiyun if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) == ACPI_DESC_TYPE_OPERAND) {
197*4882a593Smuzhiyun
198*4882a593Smuzhiyun /* Unlink object from front of possible object list */
199*4882a593Smuzhiyun
200*4882a593Smuzhiyun node->object = obj_desc->common.next_object;
201*4882a593Smuzhiyun
202*4882a593Smuzhiyun /* Handle possible 2-descriptor object */
203*4882a593Smuzhiyun
204*4882a593Smuzhiyun if (node->object &&
205*4882a593Smuzhiyun (node->object->common.type != ACPI_TYPE_LOCAL_DATA)) {
206*4882a593Smuzhiyun node->object = node->object->common.next_object;
207*4882a593Smuzhiyun }
208*4882a593Smuzhiyun
209*4882a593Smuzhiyun /*
210*4882a593Smuzhiyun * Detach the object from any data objects (which are still held by
211*4882a593Smuzhiyun * the namespace node)
212*4882a593Smuzhiyun */
213*4882a593Smuzhiyun if (obj_desc->common.next_object &&
214*4882a593Smuzhiyun ((obj_desc->common.next_object)->common.type ==
215*4882a593Smuzhiyun ACPI_TYPE_LOCAL_DATA)) {
216*4882a593Smuzhiyun obj_desc->common.next_object = NULL;
217*4882a593Smuzhiyun }
218*4882a593Smuzhiyun }
219*4882a593Smuzhiyun
220*4882a593Smuzhiyun /* Reset the node type to untyped */
221*4882a593Smuzhiyun
222*4882a593Smuzhiyun node->type = ACPI_TYPE_ANY;
223*4882a593Smuzhiyun
224*4882a593Smuzhiyun ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "Node %p [%4.4s] Object %p\n",
225*4882a593Smuzhiyun node, acpi_ut_get_node_name(node), obj_desc));
226*4882a593Smuzhiyun
227*4882a593Smuzhiyun /* Remove one reference on the object (and all subobjects) */
228*4882a593Smuzhiyun
229*4882a593Smuzhiyun acpi_ut_remove_reference(obj_desc);
230*4882a593Smuzhiyun return_VOID;
231*4882a593Smuzhiyun }
232*4882a593Smuzhiyun
233*4882a593Smuzhiyun /*******************************************************************************
234*4882a593Smuzhiyun *
235*4882a593Smuzhiyun * FUNCTION: acpi_ns_get_attached_object
236*4882a593Smuzhiyun *
237*4882a593Smuzhiyun * PARAMETERS: node - Namespace node
238*4882a593Smuzhiyun *
239*4882a593Smuzhiyun * RETURN: Current value of the object field from the Node whose
240*4882a593Smuzhiyun * handle is passed
241*4882a593Smuzhiyun *
242*4882a593Smuzhiyun * DESCRIPTION: Obtain the object attached to a namespace node.
243*4882a593Smuzhiyun *
244*4882a593Smuzhiyun ******************************************************************************/
245*4882a593Smuzhiyun
acpi_ns_get_attached_object(struct acpi_namespace_node * node)246*4882a593Smuzhiyun union acpi_operand_object *acpi_ns_get_attached_object(struct
247*4882a593Smuzhiyun acpi_namespace_node
248*4882a593Smuzhiyun *node)
249*4882a593Smuzhiyun {
250*4882a593Smuzhiyun ACPI_FUNCTION_TRACE_PTR(ns_get_attached_object, node);
251*4882a593Smuzhiyun
252*4882a593Smuzhiyun if (!node) {
253*4882a593Smuzhiyun ACPI_WARNING((AE_INFO, "Null Node ptr"));
254*4882a593Smuzhiyun return_PTR(NULL);
255*4882a593Smuzhiyun }
256*4882a593Smuzhiyun
257*4882a593Smuzhiyun if (!node->object ||
258*4882a593Smuzhiyun ((ACPI_GET_DESCRIPTOR_TYPE(node->object) != ACPI_DESC_TYPE_OPERAND)
259*4882a593Smuzhiyun && (ACPI_GET_DESCRIPTOR_TYPE(node->object) !=
260*4882a593Smuzhiyun ACPI_DESC_TYPE_NAMED))
261*4882a593Smuzhiyun || ((node->object)->common.type == ACPI_TYPE_LOCAL_DATA)) {
262*4882a593Smuzhiyun return_PTR(NULL);
263*4882a593Smuzhiyun }
264*4882a593Smuzhiyun
265*4882a593Smuzhiyun return_PTR(node->object);
266*4882a593Smuzhiyun }
267*4882a593Smuzhiyun
268*4882a593Smuzhiyun /*******************************************************************************
269*4882a593Smuzhiyun *
270*4882a593Smuzhiyun * FUNCTION: acpi_ns_get_secondary_object
271*4882a593Smuzhiyun *
272*4882a593Smuzhiyun * PARAMETERS: node - Namespace node
273*4882a593Smuzhiyun *
274*4882a593Smuzhiyun * RETURN: Current value of the object field from the Node whose
275*4882a593Smuzhiyun * handle is passed.
276*4882a593Smuzhiyun *
277*4882a593Smuzhiyun * DESCRIPTION: Obtain a secondary object associated with a namespace node.
278*4882a593Smuzhiyun *
279*4882a593Smuzhiyun ******************************************************************************/
280*4882a593Smuzhiyun
acpi_ns_get_secondary_object(union acpi_operand_object * obj_desc)281*4882a593Smuzhiyun union acpi_operand_object *acpi_ns_get_secondary_object(union
282*4882a593Smuzhiyun acpi_operand_object
283*4882a593Smuzhiyun *obj_desc)
284*4882a593Smuzhiyun {
285*4882a593Smuzhiyun ACPI_FUNCTION_TRACE_PTR(ns_get_secondary_object, obj_desc);
286*4882a593Smuzhiyun
287*4882a593Smuzhiyun if ((!obj_desc) ||
288*4882a593Smuzhiyun (obj_desc->common.type == ACPI_TYPE_LOCAL_DATA) ||
289*4882a593Smuzhiyun (!obj_desc->common.next_object) ||
290*4882a593Smuzhiyun ((obj_desc->common.next_object)->common.type ==
291*4882a593Smuzhiyun ACPI_TYPE_LOCAL_DATA)) {
292*4882a593Smuzhiyun return_PTR(NULL);
293*4882a593Smuzhiyun }
294*4882a593Smuzhiyun
295*4882a593Smuzhiyun return_PTR(obj_desc->common.next_object);
296*4882a593Smuzhiyun }
297*4882a593Smuzhiyun
298*4882a593Smuzhiyun /*******************************************************************************
299*4882a593Smuzhiyun *
300*4882a593Smuzhiyun * FUNCTION: acpi_ns_attach_data
301*4882a593Smuzhiyun *
302*4882a593Smuzhiyun * PARAMETERS: node - Namespace node
303*4882a593Smuzhiyun * handler - Handler to be associated with the data
304*4882a593Smuzhiyun * data - Data to be attached
305*4882a593Smuzhiyun *
306*4882a593Smuzhiyun * RETURN: Status
307*4882a593Smuzhiyun *
308*4882a593Smuzhiyun * DESCRIPTION: Low-level attach data. Create and attach a Data object.
309*4882a593Smuzhiyun *
310*4882a593Smuzhiyun ******************************************************************************/
311*4882a593Smuzhiyun
312*4882a593Smuzhiyun acpi_status
acpi_ns_attach_data(struct acpi_namespace_node * node,acpi_object_handler handler,void * data)313*4882a593Smuzhiyun acpi_ns_attach_data(struct acpi_namespace_node *node,
314*4882a593Smuzhiyun acpi_object_handler handler, void *data)
315*4882a593Smuzhiyun {
316*4882a593Smuzhiyun union acpi_operand_object *prev_obj_desc;
317*4882a593Smuzhiyun union acpi_operand_object *obj_desc;
318*4882a593Smuzhiyun union acpi_operand_object *data_desc;
319*4882a593Smuzhiyun
320*4882a593Smuzhiyun /* We only allow one attachment per handler */
321*4882a593Smuzhiyun
322*4882a593Smuzhiyun prev_obj_desc = NULL;
323*4882a593Smuzhiyun obj_desc = node->object;
324*4882a593Smuzhiyun while (obj_desc) {
325*4882a593Smuzhiyun if ((obj_desc->common.type == ACPI_TYPE_LOCAL_DATA) &&
326*4882a593Smuzhiyun (obj_desc->data.handler == handler)) {
327*4882a593Smuzhiyun return (AE_ALREADY_EXISTS);
328*4882a593Smuzhiyun }
329*4882a593Smuzhiyun
330*4882a593Smuzhiyun prev_obj_desc = obj_desc;
331*4882a593Smuzhiyun obj_desc = obj_desc->common.next_object;
332*4882a593Smuzhiyun }
333*4882a593Smuzhiyun
334*4882a593Smuzhiyun /* Create an internal object for the data */
335*4882a593Smuzhiyun
336*4882a593Smuzhiyun data_desc = acpi_ut_create_internal_object(ACPI_TYPE_LOCAL_DATA);
337*4882a593Smuzhiyun if (!data_desc) {
338*4882a593Smuzhiyun return (AE_NO_MEMORY);
339*4882a593Smuzhiyun }
340*4882a593Smuzhiyun
341*4882a593Smuzhiyun data_desc->data.handler = handler;
342*4882a593Smuzhiyun data_desc->data.pointer = data;
343*4882a593Smuzhiyun
344*4882a593Smuzhiyun /* Install the data object */
345*4882a593Smuzhiyun
346*4882a593Smuzhiyun if (prev_obj_desc) {
347*4882a593Smuzhiyun prev_obj_desc->common.next_object = data_desc;
348*4882a593Smuzhiyun } else {
349*4882a593Smuzhiyun node->object = data_desc;
350*4882a593Smuzhiyun }
351*4882a593Smuzhiyun
352*4882a593Smuzhiyun return (AE_OK);
353*4882a593Smuzhiyun }
354*4882a593Smuzhiyun
355*4882a593Smuzhiyun /*******************************************************************************
356*4882a593Smuzhiyun *
357*4882a593Smuzhiyun * FUNCTION: acpi_ns_detach_data
358*4882a593Smuzhiyun *
359*4882a593Smuzhiyun * PARAMETERS: node - Namespace node
360*4882a593Smuzhiyun * handler - Handler associated with the data
361*4882a593Smuzhiyun *
362*4882a593Smuzhiyun * RETURN: Status
363*4882a593Smuzhiyun *
364*4882a593Smuzhiyun * DESCRIPTION: Low-level detach data. Delete the data node, but the caller
365*4882a593Smuzhiyun * is responsible for the actual data.
366*4882a593Smuzhiyun *
367*4882a593Smuzhiyun ******************************************************************************/
368*4882a593Smuzhiyun
369*4882a593Smuzhiyun acpi_status
acpi_ns_detach_data(struct acpi_namespace_node * node,acpi_object_handler handler)370*4882a593Smuzhiyun acpi_ns_detach_data(struct acpi_namespace_node *node,
371*4882a593Smuzhiyun acpi_object_handler handler)
372*4882a593Smuzhiyun {
373*4882a593Smuzhiyun union acpi_operand_object *obj_desc;
374*4882a593Smuzhiyun union acpi_operand_object *prev_obj_desc;
375*4882a593Smuzhiyun
376*4882a593Smuzhiyun prev_obj_desc = NULL;
377*4882a593Smuzhiyun obj_desc = node->object;
378*4882a593Smuzhiyun while (obj_desc) {
379*4882a593Smuzhiyun if ((obj_desc->common.type == ACPI_TYPE_LOCAL_DATA) &&
380*4882a593Smuzhiyun (obj_desc->data.handler == handler)) {
381*4882a593Smuzhiyun if (prev_obj_desc) {
382*4882a593Smuzhiyun prev_obj_desc->common.next_object =
383*4882a593Smuzhiyun obj_desc->common.next_object;
384*4882a593Smuzhiyun } else {
385*4882a593Smuzhiyun node->object = obj_desc->common.next_object;
386*4882a593Smuzhiyun }
387*4882a593Smuzhiyun
388*4882a593Smuzhiyun acpi_ut_remove_reference(obj_desc);
389*4882a593Smuzhiyun return (AE_OK);
390*4882a593Smuzhiyun }
391*4882a593Smuzhiyun
392*4882a593Smuzhiyun prev_obj_desc = obj_desc;
393*4882a593Smuzhiyun obj_desc = obj_desc->common.next_object;
394*4882a593Smuzhiyun }
395*4882a593Smuzhiyun
396*4882a593Smuzhiyun return (AE_NOT_FOUND);
397*4882a593Smuzhiyun }
398*4882a593Smuzhiyun
399*4882a593Smuzhiyun /*******************************************************************************
400*4882a593Smuzhiyun *
401*4882a593Smuzhiyun * FUNCTION: acpi_ns_get_attached_data
402*4882a593Smuzhiyun *
403*4882a593Smuzhiyun * PARAMETERS: node - Namespace node
404*4882a593Smuzhiyun * handler - Handler associated with the data
405*4882a593Smuzhiyun * data - Where the data is returned
406*4882a593Smuzhiyun *
407*4882a593Smuzhiyun * RETURN: Status
408*4882a593Smuzhiyun *
409*4882a593Smuzhiyun * DESCRIPTION: Low level interface to obtain data previously associated with
410*4882a593Smuzhiyun * a namespace node.
411*4882a593Smuzhiyun *
412*4882a593Smuzhiyun ******************************************************************************/
413*4882a593Smuzhiyun
414*4882a593Smuzhiyun acpi_status
acpi_ns_get_attached_data(struct acpi_namespace_node * node,acpi_object_handler handler,void ** data)415*4882a593Smuzhiyun acpi_ns_get_attached_data(struct acpi_namespace_node *node,
416*4882a593Smuzhiyun acpi_object_handler handler, void **data)
417*4882a593Smuzhiyun {
418*4882a593Smuzhiyun union acpi_operand_object *obj_desc;
419*4882a593Smuzhiyun
420*4882a593Smuzhiyun obj_desc = node->object;
421*4882a593Smuzhiyun while (obj_desc) {
422*4882a593Smuzhiyun if ((obj_desc->common.type == ACPI_TYPE_LOCAL_DATA) &&
423*4882a593Smuzhiyun (obj_desc->data.handler == handler)) {
424*4882a593Smuzhiyun *data = obj_desc->data.pointer;
425*4882a593Smuzhiyun return (AE_OK);
426*4882a593Smuzhiyun }
427*4882a593Smuzhiyun
428*4882a593Smuzhiyun obj_desc = obj_desc->common.next_object;
429*4882a593Smuzhiyun }
430*4882a593Smuzhiyun
431*4882a593Smuzhiyun return (AE_NOT_FOUND);
432*4882a593Smuzhiyun }
433