diff options
Diffstat (limited to 'drivers/acpi/utilities/utdelete.c')
-rw-r--r-- | drivers/acpi/utilities/utdelete.c | 676 |
1 files changed, 0 insertions, 676 deletions
diff --git a/drivers/acpi/utilities/utdelete.c b/drivers/acpi/utilities/utdelete.c deleted file mode 100644 index d197c6b29e17..000000000000 --- a/drivers/acpi/utilities/utdelete.c +++ /dev/null | |||
@@ -1,676 +0,0 @@ | |||
1 | /******************************************************************************* | ||
2 | * | ||
3 | * Module Name: utdelete - object deletion and reference count utilities | ||
4 | * | ||
5 | ******************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2008, Intel Corp. | ||
9 | * All rights reserved. | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * 1. Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions, and the following disclaimer, | ||
16 | * without modification. | ||
17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
18 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
19 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
20 | * including a substantially similar Disclaimer requirement for further | ||
21 | * binary redistribution. | ||
22 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
23 | * of any contributors may be used to endorse or promote products derived | ||
24 | * from this software without specific prior written permission. | ||
25 | * | ||
26 | * Alternatively, this software may be distributed under the terms of the | ||
27 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
28 | * Software Foundation. | ||
29 | * | ||
30 | * NO WARRANTY | ||
31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
41 | * POSSIBILITY OF SUCH DAMAGES. | ||
42 | */ | ||
43 | |||
44 | #include <acpi/acpi.h> | ||
45 | #include <acpi/acinterp.h> | ||
46 | #include <acpi/acnamesp.h> | ||
47 | #include <acpi/acevents.h> | ||
48 | |||
49 | #define _COMPONENT ACPI_UTILITIES | ||
50 | ACPI_MODULE_NAME("utdelete") | ||
51 | |||
52 | /* Local prototypes */ | ||
53 | static void acpi_ut_delete_internal_obj(union acpi_operand_object *object); | ||
54 | |||
55 | static void | ||
56 | acpi_ut_update_ref_count(union acpi_operand_object *object, u32 action); | ||
57 | |||
58 | /******************************************************************************* | ||
59 | * | ||
60 | * FUNCTION: acpi_ut_delete_internal_obj | ||
61 | * | ||
62 | * PARAMETERS: Object - Object to be deleted | ||
63 | * | ||
64 | * RETURN: None | ||
65 | * | ||
66 | * DESCRIPTION: Low level object deletion, after reference counts have been | ||
67 | * updated (All reference counts, including sub-objects!) | ||
68 | * | ||
69 | ******************************************************************************/ | ||
70 | |||
71 | static void acpi_ut_delete_internal_obj(union acpi_operand_object *object) | ||
72 | { | ||
73 | void *obj_pointer = NULL; | ||
74 | union acpi_operand_object *handler_desc; | ||
75 | union acpi_operand_object *second_desc; | ||
76 | union acpi_operand_object *next_desc; | ||
77 | |||
78 | ACPI_FUNCTION_TRACE_PTR(ut_delete_internal_obj, object); | ||
79 | |||
80 | if (!object) { | ||
81 | return_VOID; | ||
82 | } | ||
83 | |||
84 | /* | ||
85 | * Must delete or free any pointers within the object that are not | ||
86 | * actual ACPI objects (for example, a raw buffer pointer). | ||
87 | */ | ||
88 | switch (ACPI_GET_OBJECT_TYPE(object)) { | ||
89 | case ACPI_TYPE_STRING: | ||
90 | |||
91 | ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, | ||
92 | "**** String %p, ptr %p\n", object, | ||
93 | object->string.pointer)); | ||
94 | |||
95 | /* Free the actual string buffer */ | ||
96 | |||
97 | if (!(object->common.flags & AOPOBJ_STATIC_POINTER)) { | ||
98 | |||
99 | /* But only if it is NOT a pointer into an ACPI table */ | ||
100 | |||
101 | obj_pointer = object->string.pointer; | ||
102 | } | ||
103 | break; | ||
104 | |||
105 | case ACPI_TYPE_BUFFER: | ||
106 | |||
107 | ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, | ||
108 | "**** Buffer %p, ptr %p\n", object, | ||
109 | object->buffer.pointer)); | ||
110 | |||
111 | /* Free the actual buffer */ | ||
112 | |||
113 | if (!(object->common.flags & AOPOBJ_STATIC_POINTER)) { | ||
114 | |||
115 | /* But only if it is NOT a pointer into an ACPI table */ | ||
116 | |||
117 | obj_pointer = object->buffer.pointer; | ||
118 | } | ||
119 | break; | ||
120 | |||
121 | case ACPI_TYPE_PACKAGE: | ||
122 | |||
123 | ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, | ||
124 | " **** Package of count %X\n", | ||
125 | object->package.count)); | ||
126 | |||
127 | /* | ||
128 | * Elements of the package are not handled here, they are deleted | ||
129 | * separately | ||
130 | */ | ||
131 | |||
132 | /* Free the (variable length) element pointer array */ | ||
133 | |||
134 | obj_pointer = object->package.elements; | ||
135 | break; | ||
136 | |||
137 | /* | ||
138 | * These objects have a possible list of notify handlers. | ||
139 | * Device object also may have a GPE block. | ||
140 | */ | ||
141 | case ACPI_TYPE_DEVICE: | ||
142 | |||
143 | if (object->device.gpe_block) { | ||
144 | (void)acpi_ev_delete_gpe_block(object->device. | ||
145 | gpe_block); | ||
146 | } | ||
147 | |||
148 | /*lint -fallthrough */ | ||
149 | |||
150 | case ACPI_TYPE_PROCESSOR: | ||
151 | case ACPI_TYPE_THERMAL: | ||
152 | |||
153 | /* Walk the notify handler list for this object */ | ||
154 | |||
155 | handler_desc = object->common_notify.handler; | ||
156 | while (handler_desc) { | ||
157 | next_desc = handler_desc->address_space.next; | ||
158 | acpi_ut_remove_reference(handler_desc); | ||
159 | handler_desc = next_desc; | ||
160 | } | ||
161 | break; | ||
162 | |||
163 | case ACPI_TYPE_MUTEX: | ||
164 | |||
165 | ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, | ||
166 | "***** Mutex %p, OS Mutex %p\n", | ||
167 | object, object->mutex.os_mutex)); | ||
168 | |||
169 | if (object == acpi_gbl_global_lock_mutex) { | ||
170 | |||
171 | /* Global Lock has extra semaphore */ | ||
172 | |||
173 | (void) | ||
174 | acpi_os_delete_semaphore | ||
175 | (acpi_gbl_global_lock_semaphore); | ||
176 | acpi_gbl_global_lock_semaphore = NULL; | ||
177 | |||
178 | acpi_os_delete_mutex(object->mutex.os_mutex); | ||
179 | acpi_gbl_global_lock_mutex = NULL; | ||
180 | } else { | ||
181 | acpi_ex_unlink_mutex(object); | ||
182 | acpi_os_delete_mutex(object->mutex.os_mutex); | ||
183 | } | ||
184 | break; | ||
185 | |||
186 | case ACPI_TYPE_EVENT: | ||
187 | |||
188 | ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, | ||
189 | "***** Event %p, OS Semaphore %p\n", | ||
190 | object, object->event.os_semaphore)); | ||
191 | |||
192 | (void)acpi_os_delete_semaphore(object->event.os_semaphore); | ||
193 | object->event.os_semaphore = NULL; | ||
194 | break; | ||
195 | |||
196 | case ACPI_TYPE_METHOD: | ||
197 | |||
198 | ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, | ||
199 | "***** Method %p\n", object)); | ||
200 | |||
201 | /* Delete the method mutex if it exists */ | ||
202 | |||
203 | if (object->method.mutex) { | ||
204 | acpi_os_delete_mutex(object->method.mutex->mutex. | ||
205 | os_mutex); | ||
206 | acpi_ut_delete_object_desc(object->method.mutex); | ||
207 | object->method.mutex = NULL; | ||
208 | } | ||
209 | break; | ||
210 | |||
211 | case ACPI_TYPE_REGION: | ||
212 | |||
213 | ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, | ||
214 | "***** Region %p\n", object)); | ||
215 | |||
216 | second_desc = acpi_ns_get_secondary_object(object); | ||
217 | if (second_desc) { | ||
218 | /* | ||
219 | * Free the region_context if and only if the handler is one of the | ||
220 | * default handlers -- and therefore, we created the context object | ||
221 | * locally, it was not created by an external caller. | ||
222 | */ | ||
223 | handler_desc = object->region.handler; | ||
224 | if (handler_desc) { | ||
225 | if (handler_desc->address_space.handler_flags & | ||
226 | ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) { | ||
227 | |||
228 | /* Deactivate region and free region context */ | ||
229 | |||
230 | if (handler_desc->address_space.setup) { | ||
231 | (void)handler_desc-> | ||
232 | address_space.setup(object, | ||
233 | ACPI_REGION_DEACTIVATE, | ||
234 | handler_desc-> | ||
235 | address_space. | ||
236 | context, | ||
237 | &second_desc-> | ||
238 | extra. | ||
239 | region_context); | ||
240 | } | ||
241 | } | ||
242 | |||
243 | acpi_ut_remove_reference(handler_desc); | ||
244 | } | ||
245 | |||
246 | /* Now we can free the Extra object */ | ||
247 | |||
248 | acpi_ut_delete_object_desc(second_desc); | ||
249 | } | ||
250 | break; | ||
251 | |||
252 | case ACPI_TYPE_BUFFER_FIELD: | ||
253 | |||
254 | ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, | ||
255 | "***** Buffer Field %p\n", object)); | ||
256 | |||
257 | second_desc = acpi_ns_get_secondary_object(object); | ||
258 | if (second_desc) { | ||
259 | acpi_ut_delete_object_desc(second_desc); | ||
260 | } | ||
261 | break; | ||
262 | |||
263 | case ACPI_TYPE_LOCAL_BANK_FIELD: | ||
264 | |||
265 | ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, | ||
266 | "***** Bank Field %p\n", object)); | ||
267 | |||
268 | second_desc = acpi_ns_get_secondary_object(object); | ||
269 | if (second_desc) { | ||
270 | acpi_ut_delete_object_desc(second_desc); | ||
271 | } | ||
272 | break; | ||
273 | |||
274 | default: | ||
275 | break; | ||
276 | } | ||
277 | |||
278 | /* Free any allocated memory (pointer within the object) found above */ | ||
279 | |||
280 | if (obj_pointer) { | ||
281 | ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, | ||
282 | "Deleting Object Subptr %p\n", obj_pointer)); | ||
283 | ACPI_FREE(obj_pointer); | ||
284 | } | ||
285 | |||
286 | /* Now the object can be safely deleted */ | ||
287 | |||
288 | ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, "Deleting Object %p [%s]\n", | ||
289 | object, acpi_ut_get_object_type_name(object))); | ||
290 | |||
291 | acpi_ut_delete_object_desc(object); | ||
292 | return_VOID; | ||
293 | } | ||
294 | |||
295 | /******************************************************************************* | ||
296 | * | ||
297 | * FUNCTION: acpi_ut_delete_internal_object_list | ||
298 | * | ||
299 | * PARAMETERS: obj_list - Pointer to the list to be deleted | ||
300 | * | ||
301 | * RETURN: None | ||
302 | * | ||
303 | * DESCRIPTION: This function deletes an internal object list, including both | ||
304 | * simple objects and package objects | ||
305 | * | ||
306 | ******************************************************************************/ | ||
307 | |||
308 | void acpi_ut_delete_internal_object_list(union acpi_operand_object **obj_list) | ||
309 | { | ||
310 | union acpi_operand_object **internal_obj; | ||
311 | |||
312 | ACPI_FUNCTION_TRACE(ut_delete_internal_object_list); | ||
313 | |||
314 | /* Walk the null-terminated internal list */ | ||
315 | |||
316 | for (internal_obj = obj_list; *internal_obj; internal_obj++) { | ||
317 | acpi_ut_remove_reference(*internal_obj); | ||
318 | } | ||
319 | |||
320 | /* Free the combined parameter pointer list and object array */ | ||
321 | |||
322 | ACPI_FREE(obj_list); | ||
323 | return_VOID; | ||
324 | } | ||
325 | |||
326 | /******************************************************************************* | ||
327 | * | ||
328 | * FUNCTION: acpi_ut_update_ref_count | ||
329 | * | ||
330 | * PARAMETERS: Object - Object whose ref count is to be updated | ||
331 | * Action - What to do | ||
332 | * | ||
333 | * RETURN: New ref count | ||
334 | * | ||
335 | * DESCRIPTION: Modify the ref count and return it. | ||
336 | * | ||
337 | ******************************************************************************/ | ||
338 | |||
339 | static void | ||
340 | acpi_ut_update_ref_count(union acpi_operand_object *object, u32 action) | ||
341 | { | ||
342 | u16 count; | ||
343 | u16 new_count; | ||
344 | |||
345 | ACPI_FUNCTION_NAME(ut_update_ref_count); | ||
346 | |||
347 | if (!object) { | ||
348 | return; | ||
349 | } | ||
350 | |||
351 | count = object->common.reference_count; | ||
352 | new_count = count; | ||
353 | |||
354 | /* | ||
355 | * Perform the reference count action (increment, decrement, force delete) | ||
356 | */ | ||
357 | switch (action) { | ||
358 | case REF_INCREMENT: | ||
359 | |||
360 | new_count++; | ||
361 | object->common.reference_count = new_count; | ||
362 | |||
363 | ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, | ||
364 | "Obj %p Refs=%X, [Incremented]\n", | ||
365 | object, new_count)); | ||
366 | break; | ||
367 | |||
368 | case REF_DECREMENT: | ||
369 | |||
370 | if (count < 1) { | ||
371 | ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, | ||
372 | "Obj %p Refs=%X, can't decrement! (Set to 0)\n", | ||
373 | object, new_count)); | ||
374 | |||
375 | new_count = 0; | ||
376 | } else { | ||
377 | new_count--; | ||
378 | |||
379 | ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, | ||
380 | "Obj %p Refs=%X, [Decremented]\n", | ||
381 | object, new_count)); | ||
382 | } | ||
383 | |||
384 | if (ACPI_GET_OBJECT_TYPE(object) == ACPI_TYPE_METHOD) { | ||
385 | ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, | ||
386 | "Method Obj %p Refs=%X, [Decremented]\n", | ||
387 | object, new_count)); | ||
388 | } | ||
389 | |||
390 | object->common.reference_count = new_count; | ||
391 | if (new_count == 0) { | ||
392 | acpi_ut_delete_internal_obj(object); | ||
393 | } | ||
394 | break; | ||
395 | |||
396 | case REF_FORCE_DELETE: | ||
397 | |||
398 | ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, | ||
399 | "Obj %p Refs=%X, Force delete! (Set to 0)\n", | ||
400 | object, count)); | ||
401 | |||
402 | new_count = 0; | ||
403 | object->common.reference_count = new_count; | ||
404 | acpi_ut_delete_internal_obj(object); | ||
405 | break; | ||
406 | |||
407 | default: | ||
408 | |||
409 | ACPI_ERROR((AE_INFO, "Unknown action (%X)", action)); | ||
410 | break; | ||
411 | } | ||
412 | |||
413 | /* | ||
414 | * Sanity check the reference count, for debug purposes only. | ||
415 | * (A deleted object will have a huge reference count) | ||
416 | */ | ||
417 | if (count > ACPI_MAX_REFERENCE_COUNT) { | ||
418 | ACPI_WARNING((AE_INFO, | ||
419 | "Large Reference Count (%X) in object %p", count, | ||
420 | object)); | ||
421 | } | ||
422 | } | ||
423 | |||
424 | /******************************************************************************* | ||
425 | * | ||
426 | * FUNCTION: acpi_ut_update_object_reference | ||
427 | * | ||
428 | * PARAMETERS: Object - Increment ref count for this object | ||
429 | * and all sub-objects | ||
430 | * Action - Either REF_INCREMENT or REF_DECREMENT or | ||
431 | * REF_FORCE_DELETE | ||
432 | * | ||
433 | * RETURN: Status | ||
434 | * | ||
435 | * DESCRIPTION: Increment the object reference count | ||
436 | * | ||
437 | * Object references are incremented when: | ||
438 | * 1) An object is attached to a Node (namespace object) | ||
439 | * 2) An object is copied (all subobjects must be incremented) | ||
440 | * | ||
441 | * Object references are decremented when: | ||
442 | * 1) An object is detached from an Node | ||
443 | * | ||
444 | ******************************************************************************/ | ||
445 | |||
446 | acpi_status | ||
447 | acpi_ut_update_object_reference(union acpi_operand_object *object, u16 action) | ||
448 | { | ||
449 | acpi_status status = AE_OK; | ||
450 | union acpi_generic_state *state_list = NULL; | ||
451 | union acpi_operand_object *next_object = NULL; | ||
452 | union acpi_generic_state *state; | ||
453 | u32 i; | ||
454 | |||
455 | ACPI_FUNCTION_TRACE_PTR(ut_update_object_reference, object); | ||
456 | |||
457 | while (object) { | ||
458 | |||
459 | /* Make sure that this isn't a namespace handle */ | ||
460 | |||
461 | if (ACPI_GET_DESCRIPTOR_TYPE(object) == ACPI_DESC_TYPE_NAMED) { | ||
462 | ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, | ||
463 | "Object %p is NS handle\n", object)); | ||
464 | return_ACPI_STATUS(AE_OK); | ||
465 | } | ||
466 | |||
467 | /* | ||
468 | * All sub-objects must have their reference count incremented also. | ||
469 | * Different object types have different subobjects. | ||
470 | */ | ||
471 | switch (ACPI_GET_OBJECT_TYPE(object)) { | ||
472 | case ACPI_TYPE_DEVICE: | ||
473 | case ACPI_TYPE_PROCESSOR: | ||
474 | case ACPI_TYPE_POWER: | ||
475 | case ACPI_TYPE_THERMAL: | ||
476 | |||
477 | /* Update the notify objects for these types (if present) */ | ||
478 | |||
479 | acpi_ut_update_ref_count(object->common_notify. | ||
480 | system_notify, action); | ||
481 | acpi_ut_update_ref_count(object->common_notify. | ||
482 | device_notify, action); | ||
483 | break; | ||
484 | |||
485 | case ACPI_TYPE_PACKAGE: | ||
486 | /* | ||
487 | * We must update all the sub-objects of the package, | ||
488 | * each of whom may have their own sub-objects. | ||
489 | */ | ||
490 | for (i = 0; i < object->package.count; i++) { | ||
491 | /* | ||
492 | * Push each element onto the stack for later processing. | ||
493 | * Note: There can be null elements within the package, | ||
494 | * these are simply ignored | ||
495 | */ | ||
496 | status = | ||
497 | acpi_ut_create_update_state_and_push | ||
498 | (object->package.elements[i], action, | ||
499 | &state_list); | ||
500 | if (ACPI_FAILURE(status)) { | ||
501 | goto error_exit; | ||
502 | } | ||
503 | } | ||
504 | break; | ||
505 | |||
506 | case ACPI_TYPE_BUFFER_FIELD: | ||
507 | |||
508 | next_object = object->buffer_field.buffer_obj; | ||
509 | break; | ||
510 | |||
511 | case ACPI_TYPE_LOCAL_REGION_FIELD: | ||
512 | |||
513 | next_object = object->field.region_obj; | ||
514 | break; | ||
515 | |||
516 | case ACPI_TYPE_LOCAL_BANK_FIELD: | ||
517 | |||
518 | next_object = object->bank_field.bank_obj; | ||
519 | status = | ||
520 | acpi_ut_create_update_state_and_push(object-> | ||
521 | bank_field. | ||
522 | region_obj, | ||
523 | action, | ||
524 | &state_list); | ||
525 | if (ACPI_FAILURE(status)) { | ||
526 | goto error_exit; | ||
527 | } | ||
528 | break; | ||
529 | |||
530 | case ACPI_TYPE_LOCAL_INDEX_FIELD: | ||
531 | |||
532 | next_object = object->index_field.index_obj; | ||
533 | status = | ||
534 | acpi_ut_create_update_state_and_push(object-> | ||
535 | index_field. | ||
536 | data_obj, | ||
537 | action, | ||
538 | &state_list); | ||
539 | if (ACPI_FAILURE(status)) { | ||
540 | goto error_exit; | ||
541 | } | ||
542 | break; | ||
543 | |||
544 | case ACPI_TYPE_LOCAL_REFERENCE: | ||
545 | /* | ||
546 | * The target of an Index (a package, string, or buffer) or a named | ||
547 | * reference must track changes to the ref count of the index or | ||
548 | * target object. | ||
549 | */ | ||
550 | if ((object->reference.class == ACPI_REFCLASS_INDEX) || | ||
551 | (object->reference.class == ACPI_REFCLASS_NAME)) { | ||
552 | next_object = object->reference.object; | ||
553 | } | ||
554 | break; | ||
555 | |||
556 | case ACPI_TYPE_REGION: | ||
557 | default: | ||
558 | break; /* No subobjects for all other types */ | ||
559 | } | ||
560 | |||
561 | /* | ||
562 | * Now we can update the count in the main object. This can only | ||
563 | * happen after we update the sub-objects in case this causes the | ||
564 | * main object to be deleted. | ||
565 | */ | ||
566 | acpi_ut_update_ref_count(object, action); | ||
567 | object = NULL; | ||
568 | |||
569 | /* Move on to the next object to be updated */ | ||
570 | |||
571 | if (next_object) { | ||
572 | object = next_object; | ||
573 | next_object = NULL; | ||
574 | } else if (state_list) { | ||
575 | state = acpi_ut_pop_generic_state(&state_list); | ||
576 | object = state->update.object; | ||
577 | acpi_ut_delete_generic_state(state); | ||
578 | } | ||
579 | } | ||
580 | |||
581 | return_ACPI_STATUS(AE_OK); | ||
582 | |||
583 | error_exit: | ||
584 | |||
585 | ACPI_EXCEPTION((AE_INFO, status, | ||
586 | "Could not update object reference count")); | ||
587 | |||
588 | /* Free any stacked Update State objects */ | ||
589 | |||
590 | while (state_list) { | ||
591 | state = acpi_ut_pop_generic_state(&state_list); | ||
592 | acpi_ut_delete_generic_state(state); | ||
593 | } | ||
594 | |||
595 | return_ACPI_STATUS(status); | ||
596 | } | ||
597 | |||
598 | /******************************************************************************* | ||
599 | * | ||
600 | * FUNCTION: acpi_ut_add_reference | ||
601 | * | ||
602 | * PARAMETERS: Object - Object whose reference count is to be | ||
603 | * incremented | ||
604 | * | ||
605 | * RETURN: None | ||
606 | * | ||
607 | * DESCRIPTION: Add one reference to an ACPI object | ||
608 | * | ||
609 | ******************************************************************************/ | ||
610 | |||
611 | void acpi_ut_add_reference(union acpi_operand_object *object) | ||
612 | { | ||
613 | |||
614 | ACPI_FUNCTION_TRACE_PTR(ut_add_reference, object); | ||
615 | |||
616 | /* Ensure that we have a valid object */ | ||
617 | |||
618 | if (!acpi_ut_valid_internal_object(object)) { | ||
619 | return_VOID; | ||
620 | } | ||
621 | |||
622 | ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, | ||
623 | "Obj %p Current Refs=%X [To Be Incremented]\n", | ||
624 | object, object->common.reference_count)); | ||
625 | |||
626 | /* Increment the reference count */ | ||
627 | |||
628 | (void)acpi_ut_update_object_reference(object, REF_INCREMENT); | ||
629 | return_VOID; | ||
630 | } | ||
631 | |||
632 | /******************************************************************************* | ||
633 | * | ||
634 | * FUNCTION: acpi_ut_remove_reference | ||
635 | * | ||
636 | * PARAMETERS: Object - Object whose ref count will be decremented | ||
637 | * | ||
638 | * RETURN: None | ||
639 | * | ||
640 | * DESCRIPTION: Decrement the reference count of an ACPI internal object | ||
641 | * | ||
642 | ******************************************************************************/ | ||
643 | |||
644 | void acpi_ut_remove_reference(union acpi_operand_object *object) | ||
645 | { | ||
646 | |||
647 | ACPI_FUNCTION_TRACE_PTR(ut_remove_reference, object); | ||
648 | |||
649 | /* | ||
650 | * Allow a NULL pointer to be passed in, just ignore it. This saves | ||
651 | * each caller from having to check. Also, ignore NS nodes. | ||
652 | * | ||
653 | */ | ||
654 | if (!object || | ||
655 | (ACPI_GET_DESCRIPTOR_TYPE(object) == ACPI_DESC_TYPE_NAMED)) { | ||
656 | return_VOID; | ||
657 | } | ||
658 | |||
659 | /* Ensure that we have a valid object */ | ||
660 | |||
661 | if (!acpi_ut_valid_internal_object(object)) { | ||
662 | return_VOID; | ||
663 | } | ||
664 | |||
665 | ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, | ||
666 | "Obj %p Current Refs=%X [To Be Decremented]\n", | ||
667 | object, object->common.reference_count)); | ||
668 | |||
669 | /* | ||
670 | * Decrement the reference count, and only actually delete the object | ||
671 | * if the reference count becomes 0. (Must also decrement the ref count | ||
672 | * of all subobjects!) | ||
673 | */ | ||
674 | (void)acpi_ut_update_object_reference(object, REF_DECREMENT); | ||
675 | return_VOID; | ||
676 | } | ||