- Send the SCM reply packet with the final status after completing the requested...
[reactos.git] / reactos / drivers / bus / acpi / namespace / nsobject.c
1 /*******************************************************************************
2 *
3 * Module Name: nsobject - Utilities for objects attached to namespace
4 * table entries
5 * $Revision: 1.1 $
6 *
7 ******************************************************************************/
8
9 /*
10 * Copyright (C) 2000, 2001 R. Byron Moore
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 */
26
27
28 #include <acpi.h>
29
30 #define _COMPONENT ACPI_NAMESPACE
31 MODULE_NAME ("nsobject")
32
33
34 /*******************************************************************************
35 *
36 * FUNCTION: Acpi_ns_attach_object
37 *
38 * PARAMETERS: Node - Parent Node
39 * Object - Object to be attached
40 * Type - Type of object, or ACPI_TYPE_ANY if not
41 * known
42 *
43 * DESCRIPTION: Record the given object as the value associated with the
44 * name whose ACPI_HANDLE is passed. If Object is NULL
45 * and Type is ACPI_TYPE_ANY, set the name as having no value.
46 *
47 * MUTEX: Assumes namespace is locked
48 *
49 ******************************************************************************/
50
51 ACPI_STATUS
52 acpi_ns_attach_object (
53 ACPI_NAMESPACE_NODE *node,
54 ACPI_OPERAND_OBJECT *object,
55 OBJECT_TYPE_INTERNAL type)
56 {
57 ACPI_OPERAND_OBJECT *obj_desc;
58 ACPI_OPERAND_OBJECT *previous_obj_desc;
59 OBJECT_TYPE_INTERNAL obj_type = ACPI_TYPE_ANY;
60 u8 flags;
61 u16 opcode;
62
63
64 /*
65 * Parameter validation
66 */
67
68 if (!acpi_gbl_root_node) {
69 /* Name space not initialized */
70
71 REPORT_ERROR (("Ns_attach_object: Namespace not initialized\n"));
72 return (AE_NO_NAMESPACE);
73 }
74
75 if (!node) {
76 /* Invalid handle */
77
78 REPORT_ERROR (("Ns_attach_object: Null Named_obj handle\n"));
79 return (AE_BAD_PARAMETER);
80 }
81
82 if (!object && (ACPI_TYPE_ANY != type)) {
83 /* Null object */
84
85 REPORT_ERROR (("Ns_attach_object: Null object, but type not ACPI_TYPE_ANY\n"));
86 return (AE_BAD_PARAMETER);
87 }
88
89 if (!VALID_DESCRIPTOR_TYPE (node, ACPI_DESC_TYPE_NAMED)) {
90 /* Not a name handle */
91
92 REPORT_ERROR (("Ns_attach_object: Invalid handle\n"));
93 return (AE_BAD_PARAMETER);
94 }
95
96 /* Check if this object is already attached */
97
98 if (node->object == object) {
99 return (AE_OK);
100 }
101
102
103 /* Get the current flags field of the Node */
104
105 flags = node->flags;
106 flags &= ~ANOBJ_AML_ATTACHMENT;
107
108
109 /* If null object, we will just install it */
110
111 if (!object) {
112 obj_desc = NULL;
113 obj_type = ACPI_TYPE_ANY;
114 }
115
116 /*
117 * If the object is an Node with an attached object,
118 * we will use that (attached) object
119 */
120
121 else if (VALID_DESCRIPTOR_TYPE (object, ACPI_DESC_TYPE_NAMED) &&
122 ((ACPI_NAMESPACE_NODE *) object)->object) {
123 /*
124 * Value passed is a name handle and that name has a
125 * non-null value. Use that name's value and type.
126 */
127
128 obj_desc = ((ACPI_NAMESPACE_NODE *) object)->object;
129 obj_type = ((ACPI_NAMESPACE_NODE *) object)->type;
130
131 /*
132 * Copy appropriate flags
133 */
134
135 if (((ACPI_NAMESPACE_NODE *) object)->flags & ANOBJ_AML_ATTACHMENT) {
136 flags |= ANOBJ_AML_ATTACHMENT;
137 }
138 }
139
140
141 /*
142 * Otherwise, we will use the parameter object, but we must type
143 * it first
144 */
145
146 else {
147 obj_desc = (ACPI_OPERAND_OBJECT *) object;
148
149
150 /* If a valid type (non-ANY) was given, just use it */
151
152 if (ACPI_TYPE_ANY != type) {
153 obj_type = type;
154 }
155
156
157 /*
158 * Type is TYPE_Any, we must try to determinte the
159 * actual type of the object
160 */
161
162 /*
163 * Check if value points into the AML code
164 */
165 else if (acpi_tb_system_table_pointer (object)) {
166 /*
167 * Object points into the AML stream.
168 * Set a flag bit in the Node to indicate this
169 */
170
171 flags |= ANOBJ_AML_ATTACHMENT;
172
173 /*
174 * The next byte (perhaps the next two bytes)
175 * will be the AML opcode
176 */
177
178 MOVE_UNALIGNED16_TO_16 (&opcode, object);
179
180 /* Check for a recognized Opcode */
181
182 switch (opcode) {
183
184 case AML_OP_PREFIX:
185
186 if (opcode != AML_REVISION_OP) {
187 /*
188 * Op_prefix is unrecognized unless part
189 * of Revision_op
190 */
191
192 break;
193 }
194
195 /* Else fall through to set type as Number */
196
197
198 case AML_ZERO_OP: case AML_ONES_OP: case AML_ONE_OP:
199 case AML_BYTE_OP: case AML_WORD_OP: case AML_DWORD_OP:
200
201 obj_type = ACPI_TYPE_INTEGER;
202 break;
203
204
205 case AML_STRING_OP:
206
207 obj_type = ACPI_TYPE_STRING;
208 break;
209
210
211 case AML_BUFFER_OP:
212
213 obj_type = ACPI_TYPE_BUFFER;
214 break;
215
216
217 case AML_MUTEX_OP:
218
219 obj_type = ACPI_TYPE_MUTEX;
220 break;
221
222
223 case AML_PACKAGE_OP:
224
225 obj_type = ACPI_TYPE_PACKAGE;
226 break;
227
228
229 default:
230
231 return (AE_TYPE);
232 break;
233 }
234 }
235
236 else {
237 /*
238 * Cannot figure out the type -- set to Def_any which
239 * will print as an error in the name table dump
240 */
241
242
243 obj_type = INTERNAL_TYPE_DEF_ANY;
244 }
245 }
246
247
248 /*
249 * Must increment the new value's reference count
250 * (if it is an internal object)
251 */
252
253 acpi_cm_add_reference (obj_desc);
254
255 /* Save the existing object (if any) for deletion later */
256
257 previous_obj_desc = node->object;
258
259 /* Install the object and set the type, flags */
260
261 node->object = obj_desc;
262 node->type = (u8) obj_type;
263 node->flags |= flags;
264
265
266 /*
267 * Delete an existing attached object.
268 */
269
270 if (previous_obj_desc) {
271 /* One for the attach to the Node */
272
273 acpi_cm_remove_reference (previous_obj_desc);
274
275 /* Now delete */
276
277 acpi_cm_remove_reference (previous_obj_desc);
278 }
279
280 return (AE_OK);
281 }
282
283
284 /*******************************************************************************
285 *
286 * FUNCTION: Acpi_ns_detach_object
287 *
288 * PARAMETERS: Node - An object whose Value will be deleted
289 *
290 * RETURN: None.
291 *
292 * DESCRIPTION: Delete the Value associated with a namespace object. If the
293 * Value is an allocated object, it is freed. Otherwise, the
294 * field is simply cleared.
295 *
296 ******************************************************************************/
297
298 void
299 acpi_ns_detach_object (
300 ACPI_NAMESPACE_NODE *node)
301 {
302 ACPI_OPERAND_OBJECT *obj_desc;
303
304
305 obj_desc = node->object;
306 if (!obj_desc) {
307 return;
308 }
309
310 /* Clear the entry in all cases */
311
312 node->object = NULL;
313
314 /* Found a valid value */
315
316 /*
317 * Not every value is an object allocated via Acpi_cm_callocate,
318 * - must check
319 */
320
321 if (!acpi_tb_system_table_pointer (obj_desc)) {
322 /* Attempt to delete the object (and all subobjects) */
323
324 acpi_cm_remove_reference (obj_desc);
325 }
326
327 return;
328 }
329
330
331 /*******************************************************************************
332 *
333 * FUNCTION: Acpi_ns_get_attached_object
334 *
335 * PARAMETERS: Handle - Parent Node to be examined
336 *
337 * RETURN: Current value of the object field from the Node whose
338 * handle is passed
339 *
340 ******************************************************************************/
341
342 void *
343 acpi_ns_get_attached_object (
344 ACPI_HANDLE handle)
345 {
346
347 if (!handle) {
348 /* handle invalid */
349
350 return (NULL);
351 }
352
353 return (((ACPI_NAMESPACE_NODE *) handle)->object);
354 }
355
356