xref: /OK3568_Linux_fs/kernel/drivers/acpi/acpica/nsobject.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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