1 /*******************************************************************************
3 * Module Name: cmdelete - object deletion and reference count utilities
6 ******************************************************************************/
9 * Copyright (C) 2000, 2001 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
29 #define _COMPONENT ACPI_UTILITIES
30 MODULE_NAME ("cmdelete")
33 /*******************************************************************************
35 * FUNCTION: Acpi_cm_delete_internal_obj
37 * PARAMETERS: *Object - Pointer to the list to be deleted
41 * DESCRIPTION: Low level object deletion, after reference counts have been
42 * updated (All reference counts, including sub-objects!)
44 ******************************************************************************/
47 acpi_cm_delete_internal_obj (
48 ACPI_OPERAND_OBJECT
*object
)
50 void *obj_pointer
= NULL
;
51 ACPI_OPERAND_OBJECT
*handler_desc
;
59 * Must delete or free any pointers within the object that are not
60 * actual ACPI objects (for example, a raw buffer pointer).
63 switch (object
->common
.type
) {
65 case ACPI_TYPE_STRING
:
67 /* Free the actual string buffer */
69 obj_pointer
= object
->string
.pointer
;
73 case ACPI_TYPE_BUFFER
:
75 /* Free the actual buffer */
77 obj_pointer
= object
->buffer
.pointer
;
81 case ACPI_TYPE_PACKAGE
:
84 * Elements of the package are not handled here, they are deleted
88 /* Free the (variable length) element pointer array */
90 obj_pointer
= object
->package
.elements
;
96 acpi_aml_unlink_mutex (object
);
97 acpi_os_delete_semaphore (object
->mutex
.semaphore
);
101 case ACPI_TYPE_EVENT
:
103 acpi_os_delete_semaphore (object
->event
.semaphore
);
104 object
->event
.semaphore
= NULL
;
108 case ACPI_TYPE_METHOD
:
110 /* Delete the method semaphore if it exists */
112 if (object
->method
.semaphore
) {
113 acpi_os_delete_semaphore (object
->method
.semaphore
);
114 object
->method
.semaphore
= NULL
;
120 case ACPI_TYPE_REGION
:
123 if (object
->region
.extra
) {
125 * Free the Region_context if and only if the handler is one of the
126 * default handlers -- and therefore, we created the context object
127 * locally, it was not created by an external caller.
129 handler_desc
= object
->region
.addr_handler
;
130 if ((handler_desc
) &&
131 (handler_desc
->addr_handler
.hflags
== ADDR_HANDLER_DEFAULT_INSTALLED
)) {
132 obj_pointer
= object
->region
.extra
->extra
.region_context
;
135 /* Now we can free the Extra object */
137 acpi_cm_delete_object_desc (object
->region
.extra
);
142 case ACPI_TYPE_FIELD_UNIT
:
144 if (object
->field_unit
.extra
) {
145 acpi_cm_delete_object_desc (object
->field_unit
.extra
);
155 * Delete any allocated memory found above
159 if (!acpi_tb_system_table_pointer (obj_pointer
)) {
160 acpi_cm_free (obj_pointer
);
165 /* Only delete the object if it was dynamically allocated */
168 if (!(object
->common
.flags
& AOPOBJ_STATIC_ALLOCATION
)) {
169 acpi_cm_delete_object_desc (object
);
177 /*******************************************************************************
179 * FUNCTION: Acpi_cm_delete_internal_object_list
181 * PARAMETERS: *Obj_list - Pointer to the list to be deleted
183 * RETURN: Status - the status of the call
185 * DESCRIPTION: This function deletes an internal object list, including both
186 * simple objects and package objects
188 ******************************************************************************/
191 acpi_cm_delete_internal_object_list (
192 ACPI_OPERAND_OBJECT
**obj_list
)
194 ACPI_OPERAND_OBJECT
**internal_obj
;
197 /* Walk the null-terminated internal list */
199 for (internal_obj
= obj_list
; *internal_obj
; internal_obj
++) {
201 * Check for a package
202 * Simple objects are simply stored in the array and do not
203 * need to be deleted separately.
206 if (IS_THIS_OBJECT_TYPE ((*internal_obj
), ACPI_TYPE_PACKAGE
)) {
207 /* Delete the package */
210 * TBD: [Investigate] This might not be the right thing to do,
211 * depending on how the internal package object was allocated!!!
213 acpi_cm_delete_internal_obj (*internal_obj
);
218 /* Free the combined parameter pointer list and object array */
220 acpi_cm_free (obj_list
);
226 /*******************************************************************************
228 * FUNCTION: Acpi_cm_update_ref_count
230 * PARAMETERS: *Object - Object whose ref count is to be updated
231 * Action - What to do
233 * RETURN: New ref count
235 * DESCRIPTION: Modify the ref count and return it.
237 ******************************************************************************/
240 acpi_cm_update_ref_count (
241 ACPI_OPERAND_OBJECT
*object
,
253 count
= object
->common
.reference_count
;
257 * Reference count action (increment, decrement, or force delete)
265 object
->common
.reference_count
= new_count
;
282 object
->common
.reference_count
= new_count
;
283 if (new_count
== 0) {
284 acpi_cm_delete_internal_obj (object
);
290 case REF_FORCE_DELETE
:
293 object
->common
.reference_count
= new_count
;
294 acpi_cm_delete_internal_obj (object
);
305 * Sanity check the reference count, for debug purposes only.
306 * (A deleted object will have a huge reference count)
314 /*******************************************************************************
316 * FUNCTION: Acpi_cm_update_object_reference
318 * PARAMETERS: *Object - Increment ref count for this object
319 * and all sub-objects
320 * Action - Either REF_INCREMENT or REF_DECREMENT or
325 * DESCRIPTION: Increment the object reference count
327 * Object references are incremented when:
328 * 1) An object is attached to a Node (namespace object)
329 * 2) An object is copied (all subobjects must be incremented)
331 * Object references are decremented when:
332 * 1) An object is detached from an Node
334 ******************************************************************************/
337 acpi_cm_update_object_reference (
338 ACPI_OPERAND_OBJECT
*object
,
343 ACPI_OPERAND_OBJECT
*next
;
344 ACPI_OPERAND_OBJECT
*new;
345 ACPI_GENERIC_STATE
*state_list
= NULL
;
346 ACPI_GENERIC_STATE
*state
;
349 /* Ignore a null object ptr */
357 * Make sure that this isn't a namespace handle or an AML pointer
360 if (VALID_DESCRIPTOR_TYPE (object
, ACPI_DESC_TYPE_NAMED
)) {
364 if (acpi_tb_system_table_pointer (object
)) {
369 state
= acpi_cm_create_update_state (object
, action
);
373 object
= state
->update
.object
;
374 action
= state
->update
.value
;
375 acpi_cm_delete_generic_state (state
);
378 * All sub-objects must have their reference count incremented also.
379 * Different object types have different subobjects.
381 switch (object
->common
.type
) {
383 case ACPI_TYPE_DEVICE
:
385 status
= acpi_cm_create_update_state_and_push (object
->device
.addr_handler
,
386 action
, &state_list
);
387 if (ACPI_FAILURE (status
)) {
391 acpi_cm_update_ref_count (object
->device
.sys_handler
, action
);
392 acpi_cm_update_ref_count (object
->device
.drv_handler
, action
);
396 case INTERNAL_TYPE_ADDRESS_HANDLER
:
398 /* Must walk list of address handlers */
400 next
= object
->addr_handler
.next
;
402 new = next
->addr_handler
.next
;
403 acpi_cm_update_ref_count (next
, action
);
410 case ACPI_TYPE_PACKAGE
:
413 * We must update all the sub-objects of the package
414 * (Each of whom may have their own sub-objects, etc.
416 for (i
= 0; i
< object
->package
.count
; i
++) {
418 * Push each element onto the stack for later processing.
419 * Note: There can be null elements within the package,
420 * these are simply ignored
423 status
= acpi_cm_create_update_state_and_push (
424 object
->package
.elements
[i
], action
, &state_list
);
425 if (ACPI_FAILURE (status
)) {
432 case ACPI_TYPE_FIELD_UNIT
:
434 status
= acpi_cm_create_update_state_and_push (
435 object
->field_unit
.container
, action
, &state_list
);
437 if (ACPI_FAILURE (status
)) {
443 case INTERNAL_TYPE_DEF_FIELD
:
445 status
= acpi_cm_create_update_state_and_push (
446 object
->field
.container
, action
, &state_list
);
447 if (ACPI_FAILURE (status
)) {
453 case INTERNAL_TYPE_BANK_FIELD
:
455 status
= acpi_cm_create_update_state_and_push (
456 object
->bank_field
.bank_select
, action
, &state_list
);
457 if (ACPI_FAILURE (status
)) {
461 status
= acpi_cm_create_update_state_and_push (
462 object
->bank_field
.container
, action
, &state_list
);
463 if (ACPI_FAILURE (status
)) {
469 case ACPI_TYPE_REGION
:
471 /* TBD: [Investigate]
472 Acpi_cm_update_ref_count (Object->Region.Addr_handler, Action);
476 Acpi_cm_create_update_state_and_push (Object->Region.Addr_handler,
477 Action, &State_list);
478 if (ACPI_FAILURE (Status))
486 case INTERNAL_TYPE_REFERENCE
:
493 * Now we can update the count in the main object. This can only
494 * happen after we update the sub-objects in case this causes the
495 * main object to be deleted.
498 acpi_cm_update_ref_count (object
, action
);
501 /* Move on to the next object to be updated */
503 state
= acpi_cm_pop_generic_state (&state_list
);
511 /*******************************************************************************
513 * FUNCTION: Acpi_cm_add_reference
515 * PARAMETERS: *Object - Object whose reference count is to be
520 * DESCRIPTION: Add one reference to an ACPI object
522 ******************************************************************************/
525 acpi_cm_add_reference (
526 ACPI_OPERAND_OBJECT
*object
)
531 * Ensure that we have a valid object
534 if (!acpi_cm_valid_internal_object (object
)) {
539 * We have a valid ACPI internal object, now increment the reference count
542 acpi_cm_update_object_reference (object
, REF_INCREMENT
);
548 /*******************************************************************************
550 * FUNCTION: Acpi_cm_remove_reference
552 * PARAMETERS: *Object - Object whose ref count will be decremented
556 * DESCRIPTION: Decrement the reference count of an ACPI internal object
558 ******************************************************************************/
561 acpi_cm_remove_reference (
562 ACPI_OPERAND_OBJECT
*object
)
567 * Ensure that we have a valid object
570 if (!acpi_cm_valid_internal_object (object
)) {
575 * Decrement the reference count, and only actually delete the object
576 * if the reference count becomes 0. (Must also decrement the ref count
577 * of all subobjects!)
580 acpi_cm_update_object_reference (object
, REF_DECREMENT
);