2 /******************************************************************************
4 * Module Name: cmdelete - object deletion and reference count utilities
6 *****************************************************************************/
9 * Copyright (C) 2000 R. Byron Moore
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
33 #define _COMPONENT MISCELLANEOUS
34 MODULE_NAME ("cmdelete");
37 /******************************************************************************
39 * FUNCTION: Acpi_cm_delete_internal_obj
41 * PARAMETERS: *Object - Pointer to the list to be deleted
45 * DESCRIPTION: Low level object deletion, after reference counts have been
46 * updated (All reference counts, including sub-objects!)
48 ******************************************************************************/
51 acpi_cm_delete_internal_obj (
52 ACPI_OBJECT_INTERNAL
*object
)
54 void *obj_pointer
= NULL
;
62 * Must delete or free any pointers within the object that are not
63 * actual ACPI objects (for example, a raw buffer pointer).
66 switch (object
->common
.type
)
69 case ACPI_TYPE_STRING
:
71 /* Free the actual string buffer */
73 obj_pointer
= object
->string
.pointer
;
77 case ACPI_TYPE_BUFFER
:
79 /* Free the actual buffer */
81 obj_pointer
= object
->buffer
.pointer
;
85 case ACPI_TYPE_PACKAGE
:
88 * Elements of the package are not handled here, they are deleted
92 /* Free the (variable length) element pointer array */
94 obj_pointer
= object
->package
.elements
;
100 acpi_os_delete_semaphore (object
->mutex
.semaphore
);
104 case ACPI_TYPE_EVENT
:
106 acpi_os_delete_semaphore (object
->event
.semaphore
);
107 object
->event
.semaphore
= NULL
;
111 case ACPI_TYPE_METHOD
:
113 /* Delete parse tree if it exists */
115 if (object
->method
.parser_op
) {
116 acpi_ps_delete_parse_tree (object
->method
.parser_op
);
117 object
->method
.parser_op
= NULL
;
120 /* Delete semaphore if it exists */
122 if (object
->method
.semaphore
) {
123 acpi_os_delete_semaphore (object
->method
.semaphore
);
124 object
->method
.semaphore
= NULL
;
136 * Delete any allocated memory found above
140 if (!acpi_tb_system_table_pointer (obj_pointer
)) {
141 acpi_cm_free (obj_pointer
);
146 /* Only delete the object if it was dynamically allocated */
149 if (!(object
->common
.flags
& AO_STATIC_ALLOCATION
)) {
150 acpi_cm_delete_object_desc (object
);
158 /******************************************************************************
160 * FUNCTION: Acpi_cm_delete_internal_object_list
162 * PARAMETERS: *Obj_list - Pointer to the list to be deleted
164 * RETURN: Status - the status of the call
166 * DESCRIPTION: This function deletes an internal object list, including both
167 * simple objects and package objects
169 ******************************************************************************/
172 acpi_cm_delete_internal_object_list (
173 ACPI_OBJECT_INTERNAL
**obj_list
)
175 ACPI_OBJECT_INTERNAL
**internal_obj
;
178 /* Walk the null-terminated internal list */
180 for (internal_obj
= obj_list
; *internal_obj
; internal_obj
++) {
182 * Check for a package
183 * Simple objects are simply stored in the array and do not
184 * need to be deleted separately.
187 if (IS_THIS_OBJECT_TYPE ((*internal_obj
), ACPI_TYPE_PACKAGE
)) {
188 /* Delete the package */
191 * TBD: [Investigate] This might not be the right thing to do,
192 * depending on how the internal package object was allocated!!!
194 acpi_cm_delete_internal_obj (*internal_obj
);
199 /* Free the combined parameter pointer list and object array */
201 acpi_cm_free (obj_list
);
207 /******************************************************************************
209 * FUNCTION: Acpi_cm_update_ref_count
211 * PARAMETERS: *Object - Object whose ref count is to be updated
212 * Count - Current ref count
213 * Action - What to do
215 * RETURN: New ref count
217 * DESCRIPTION: Modify the ref count and return it.
219 ******************************************************************************/
222 acpi_cm_update_ref_count (
223 ACPI_OBJECT_INTERNAL
*object
,
235 count
= object
->common
.reference_count
;
239 * Reference count action (increment, decrement, or force delete)
248 object
->common
.reference_count
= new_count
;
265 object
->common
.reference_count
= new_count
;
266 if (new_count
== 0) {
267 acpi_cm_delete_internal_obj (object
);
273 case REF_FORCE_DELETE
:
276 object
->common
.reference_count
= new_count
;
277 acpi_cm_delete_internal_obj (object
);
288 * Sanity check the reference count, for debug purposes only.
289 * (A deleted object will have a huge reference count)
297 /******************************************************************************
299 * FUNCTION: Acpi_cm_update_object_reference
301 * PARAMETERS: *Object - Increment ref count for this object
302 * and all sub-objects
303 * Action - Either REF_INCREMENT or REF_DECREMENT or
308 * DESCRIPTION: Increment the object reference count
310 * Object references are incremented when:
311 * 1) An object is added as a value in an Name Table Entry (NTE)
312 * 2) An object is copied (all subobjects must be incremented)
314 * Object references are decremented when:
315 * 1) An object is removed from an NTE
317 ******************************************************************************/
320 acpi_cm_update_object_reference (
321 ACPI_OBJECT_INTERNAL
*object
,
326 ACPI_OBJECT_INTERNAL
*next
;
327 ACPI_OBJECT_INTERNAL
*new;
328 ACPI_GENERIC_STATE
*state_list
= NULL
;
329 ACPI_GENERIC_STATE
*state
;
332 /* Ignore a null object ptr */
340 * Make sure that this isn't a namespace handle or an AML pointer
343 if (VALID_DESCRIPTOR_TYPE (object
, ACPI_DESC_TYPE_NAMED
)) {
347 if (acpi_tb_system_table_pointer (object
)) {
352 state
= acpi_cm_create_update_state (object
, action
);
356 object
= state
->update
.object
;
357 action
= state
->update
.value
;
358 acpi_cm_delete_generic_state (state
);
361 * All sub-objects must have their reference count incremented also.
362 * Different object types have different subobjects.
364 switch (object
->common
.type
)
367 case ACPI_TYPE_DEVICE
:
369 status
= acpi_cm_create_update_state_and_push (object
->device
.addr_handler
,
370 action
, &state_list
);
371 if (ACPI_FAILURE (status
)) {
375 acpi_cm_update_ref_count (object
->device
.sys_handler
, action
);
376 acpi_cm_update_ref_count (object
->device
.drv_handler
, action
);
380 case INTERNAL_TYPE_ADDRESS_HANDLER
:
382 /* Must walk list of address handlers */
384 next
= object
->addr_handler
.link
;
386 new = next
->addr_handler
.link
;
387 acpi_cm_update_ref_count (next
, action
);
394 case ACPI_TYPE_PACKAGE
:
397 * We must update all the sub-objects of the package
398 * (Each of whom may have their own sub-objects, etc.
400 for (i
= 0; i
< object
->package
.count
; i
++) {
402 * Push each element onto the stack for later processing.
403 * Note: There can be null elements within the package,
404 * these are simply ignored
408 acpi_cm_create_update_state_and_push (object
->package
.elements
[i
],
409 action
, &state_list
);
410 if (ACPI_FAILURE (status
)) {
417 case ACPI_TYPE_FIELD_UNIT
:
420 acpi_cm_create_update_state_and_push (object
->field_unit
.container
,
421 action
, &state_list
);
422 if (ACPI_FAILURE (status
)) {
428 case INTERNAL_TYPE_DEF_FIELD
:
431 acpi_cm_create_update_state_and_push (object
->field
.container
,
432 action
, &state_list
);
433 if (ACPI_FAILURE (status
)) {
439 case INTERNAL_TYPE_BANK_FIELD
:
442 acpi_cm_create_update_state_and_push (object
->bank_field
.bank_select
,
443 action
, &state_list
);
444 if (ACPI_FAILURE (status
)) {
449 acpi_cm_create_update_state_and_push (object
->bank_field
.container
,
450 action
, &state_list
);
451 if (ACPI_FAILURE (status
)) {
457 case ACPI_TYPE_REGION
:
459 acpi_cm_update_ref_count (object
->region
.method
, action
);
461 /* TBD: [Investigate]
462 Acpi_cm_update_ref_count (Object->Region.Addr_handler, Action);
466 Acpi_cm_create_update_state_and_push (Object->Region.Addr_handler,
467 Action, &State_list);
468 if (ACPI_FAILURE (Status)) {
475 case INTERNAL_TYPE_REFERENCE
:
482 * Now we can update the count in the main object. This can only
483 * happen after we update the sub-objects in case this causes the
484 * main object to be deleted.
487 acpi_cm_update_ref_count (object
, action
);
490 /* Move on to the next object to be updated */
492 state
= acpi_cm_pop_generic_state (&state_list
);
500 /******************************************************************************
502 * FUNCTION: Acpi_cm_add_reference
504 * PARAMETERS: *Object - Object whose reference count is to be
509 * DESCRIPTION: Add one reference to an ACPI object
511 ******************************************************************************/
514 acpi_cm_add_reference (
515 ACPI_OBJECT_INTERNAL
*object
)
520 * Ensure that we have a valid object
523 if (!acpi_cm_valid_internal_object (object
)) {
529 * We have a valid ACPI internal object, now increment the reference count
532 acpi_cm_update_object_reference (object
, REF_INCREMENT
);
538 /******************************************************************************
540 * FUNCTION: Acpi_cm_remove_reference
542 * PARAMETERS: *Object - Object whose ref count will be decremented
546 * DESCRIPTION: Decrement the reference count of an ACPI internal object
548 ******************************************************************************/
551 acpi_cm_remove_reference (
552 ACPI_OBJECT_INTERNAL
*object
)
557 * Ensure that we have a valid object
560 if (!acpi_cm_valid_internal_object (object
)) {
565 * Decrement the reference count, and only actually delete the object
566 * if the reference count becomes 0. (Must also decrement the ref count
567 * of all subobjects!)
570 acpi_cm_update_object_reference (object
, REF_DECREMENT
);
573 * If the reference count has reached zero,
574 * delete the object and all sub-objects contained within it
577 if (Object->Common.Reference_count == 0) {
578 Acpi_cm_delete_internal_obj (Object);