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
33 #define _COMPONENT ACPI_UTILITIES
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_OPERAND_OBJECT *object)
54 void *obj_pointer = NULL;
55 ACPI_OPERAND_OBJECT *handler_desc;
63 * Must delete or free any pointers within the object that are not
64 * actual ACPI objects (for example, a raw buffer pointer).
67 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_aml_unlink_mutex (object);
101 acpi_os_delete_semaphore (object->mutex.semaphore);
105 case ACPI_TYPE_EVENT:
107 acpi_os_delete_semaphore (object->event.semaphore);
108 object->event.semaphore = NULL;
112 case ACPI_TYPE_METHOD:
114 /* Delete the method semaphore if it exists */
116 if (object->method.semaphore) {
117 acpi_os_delete_semaphore (object->method.semaphore);
118 object->method.semaphore = NULL;
124 case ACPI_TYPE_REGION:
127 if (object->region.extra) {
129 * Free the Region_context if and only if the handler is one of the
130 * default handlers -- and therefore, we created the context object
131 * locally, it was not created by an external caller.
133 handler_desc = object->region.addr_handler;
134 if ((handler_desc) &&
135 (handler_desc->addr_handler.hflags == ADDR_HANDLER_DEFAULT_INSTALLED)) {
136 obj_pointer = object->region.extra->extra.region_context;
139 /* Now we can free the Extra object */
141 acpi_cm_delete_object_desc (object->region.extra);
146 case ACPI_TYPE_FIELD_UNIT:
148 if (object->field_unit.extra) {
149 acpi_cm_delete_object_desc (object->field_unit.extra);
159 * Delete any allocated memory found above
163 if (!acpi_tb_system_table_pointer (obj_pointer)) {
164 acpi_cm_free (obj_pointer);
169 /* Only delete the object if it was dynamically allocated */
172 if (!(object->common.flags & AOPOBJ_STATIC_ALLOCATION)) {
173 acpi_cm_delete_object_desc (object);
181 /*******************************************************************************
183 * FUNCTION: Acpi_cm_delete_internal_object_list
185 * PARAMETERS: *Obj_list - Pointer to the list to be deleted
187 * RETURN: Status - the status of the call
189 * DESCRIPTION: This function deletes an internal object list, including both
190 * simple objects and package objects
192 ******************************************************************************/
195 acpi_cm_delete_internal_object_list (
196 ACPI_OPERAND_OBJECT **obj_list)
198 ACPI_OPERAND_OBJECT **internal_obj;
201 /* Walk the null-terminated internal list */
203 for (internal_obj = obj_list; *internal_obj; internal_obj++) {
205 * Check for a package
206 * Simple objects are simply stored in the array and do not
207 * need to be deleted separately.
210 if (IS_THIS_OBJECT_TYPE ((*internal_obj), ACPI_TYPE_PACKAGE)) {
211 /* Delete the package */
214 * TBD: [Investigate] This might not be the right thing to do,
215 * depending on how the internal package object was allocated!!!
217 acpi_cm_delete_internal_obj (*internal_obj);
222 /* Free the combined parameter pointer list and object array */
224 acpi_cm_free (obj_list);
230 /*******************************************************************************
232 * FUNCTION: Acpi_cm_update_ref_count
234 * PARAMETERS: *Object - Object whose ref count is to be updated
235 * Action - What to do
237 * RETURN: New ref count
239 * DESCRIPTION: Modify the ref count and return it.
241 ******************************************************************************/
244 acpi_cm_update_ref_count (
245 ACPI_OPERAND_OBJECT *object,
257 count = object->common.reference_count;
261 * Reference count action (increment, decrement, or force delete)
269 object->common.reference_count = new_count;
286 object->common.reference_count = new_count;
287 if (new_count == 0) {
288 acpi_cm_delete_internal_obj (object);
294 case REF_FORCE_DELETE:
297 object->common.reference_count = new_count;
298 acpi_cm_delete_internal_obj (object);
309 * Sanity check the reference count, for debug purposes only.
310 * (A deleted object will have a huge reference count)
318 /*******************************************************************************
320 * FUNCTION: Acpi_cm_update_object_reference
322 * PARAMETERS: *Object - Increment ref count for this object
323 * and all sub-objects
324 * Action - Either REF_INCREMENT or REF_DECREMENT or
329 * DESCRIPTION: Increment the object reference count
331 * Object references are incremented when:
332 * 1) An object is attached to a Node (namespace object)
333 * 2) An object is copied (all subobjects must be incremented)
335 * Object references are decremented when:
336 * 1) An object is detached from an Node
338 ******************************************************************************/
341 acpi_cm_update_object_reference (
342 ACPI_OPERAND_OBJECT *object,
347 ACPI_OPERAND_OBJECT *next;
348 ACPI_OPERAND_OBJECT *new;
349 ACPI_GENERIC_STATE *state_list = NULL;
350 ACPI_GENERIC_STATE *state;
353 /* Ignore a null object ptr */
361 * Make sure that this isn't a namespace handle or an AML pointer
364 if (VALID_DESCRIPTOR_TYPE (object, ACPI_DESC_TYPE_NAMED)) {
368 if (acpi_tb_system_table_pointer (object)) {
373 state = acpi_cm_create_update_state (object, action);
377 object = state->update.object;
378 action = state->update.value;
379 acpi_cm_delete_generic_state (state);
382 * All sub-objects must have their reference count incremented also.
383 * Different object types have different subobjects.
385 switch (object->common.type) {
387 case ACPI_TYPE_DEVICE:
389 status = acpi_cm_create_update_state_and_push (object->device.addr_handler,
390 action, &state_list);
391 if (ACPI_FAILURE (status)) {
395 acpi_cm_update_ref_count (object->device.sys_handler, action);
396 acpi_cm_update_ref_count (object->device.drv_handler, action);
400 case INTERNAL_TYPE_ADDRESS_HANDLER:
402 /* Must walk list of address handlers */
404 next = object->addr_handler.next;
406 new = next->addr_handler.next;
407 acpi_cm_update_ref_count (next, action);
414 case ACPI_TYPE_PACKAGE:
417 * We must update all the sub-objects of the package
418 * (Each of whom may have their own sub-objects, etc.
420 for (i = 0; i < object->package.count; i++) {
422 * Push each element onto the stack for later processing.
423 * Note: There can be null elements within the package,
424 * these are simply ignored
427 status = acpi_cm_create_update_state_and_push (
428 object->package.elements[i], action, &state_list);
429 if (ACPI_FAILURE (status)) {
436 case ACPI_TYPE_FIELD_UNIT:
438 status = acpi_cm_create_update_state_and_push (
439 object->field_unit.container, action, &state_list);
441 if (ACPI_FAILURE (status)) {
447 case INTERNAL_TYPE_DEF_FIELD:
449 status = acpi_cm_create_update_state_and_push (
450 object->field.container, action, &state_list);
451 if (ACPI_FAILURE (status)) {
457 case INTERNAL_TYPE_BANK_FIELD:
459 status = acpi_cm_create_update_state_and_push (
460 object->bank_field.bank_select, action, &state_list);
461 if (ACPI_FAILURE (status)) {
465 status = acpi_cm_create_update_state_and_push (
466 object->bank_field.container, action, &state_list);
467 if (ACPI_FAILURE (status)) {
473 case ACPI_TYPE_REGION:
475 /* TBD: [Investigate]
476 Acpi_cm_update_ref_count (Object->Region.Addr_handler, Action);
480 Acpi_cm_create_update_state_and_push (Object->Region.Addr_handler,
481 Action, &State_list);
482 if (ACPI_FAILURE (Status))
490 case INTERNAL_TYPE_REFERENCE:
497 * Now we can update the count in the main object. This can only
498 * happen after we update the sub-objects in case this causes the
499 * main object to be deleted.
502 acpi_cm_update_ref_count (object, action);
505 /* Move on to the next object to be updated */
507 state = acpi_cm_pop_generic_state (&state_list);
515 /*******************************************************************************
517 * FUNCTION: Acpi_cm_add_reference
519 * PARAMETERS: *Object - Object whose reference count is to be
524 * DESCRIPTION: Add one reference to an ACPI object
526 ******************************************************************************/
529 acpi_cm_add_reference (
530 ACPI_OPERAND_OBJECT *object)
535 * Ensure that we have a valid object
538 if (!acpi_cm_valid_internal_object (object)) {
543 * We have a valid ACPI internal object, now increment the reference count
546 acpi_cm_update_object_reference (object, REF_INCREMENT);
552 /*******************************************************************************
554 * FUNCTION: Acpi_cm_remove_reference
556 * PARAMETERS: *Object - Object whose ref count will be decremented
560 * DESCRIPTION: Decrement the reference count of an ACPI internal object
562 ******************************************************************************/
565 acpi_cm_remove_reference (
566 ACPI_OPERAND_OBJECT *object)
571 * Ensure that we have a valid object
574 if (!acpi_cm_valid_internal_object (object)) {
579 * Decrement the reference count, and only actually delete the object
580 * if the reference count becomes 0. (Must also decrement the ref count
581 * of all subobjects!)
584 acpi_cm_update_object_reference (object, REF_DECREMENT);