/*******************************************************************************
 *
 * Module Name: utdelete - object deletion and reference count utilities
 *
 ******************************************************************************/

/*
 * Copyright (C) 2000 - 2005, R. Byron Moore
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions, and the following disclaimer,
 *    without modification.
 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
 *    substantially similar to the "NO WARRANTY" disclaimer below
 *    ("Disclaimer") and any redistribution must be conditioned upon
 *    including a substantially similar Disclaimer requirement for further
 *    binary redistribution.
 * 3. Neither the names of the above-listed copyright holders nor the names
 *    of any contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * Alternatively, this software may be distributed under the terms of the
 * GNU General Public License ("GPL") version 2 as published by the Free
 * Software Foundation.
 *
 * NO WARRANTY
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGES.
 */


#include <acpi/acpi.h>
#include <acpi/acinterp.h>
#include <acpi/acnamesp.h>
#include <acpi/acevents.h>
#include <acpi/amlcode.h>

#define _COMPONENT          ACPI_UTILITIES
	 ACPI_MODULE_NAME    ("utdelete")

/* Local prototypes */

static void
acpi_ut_delete_internal_obj (
	union acpi_operand_object       *object);

static void
acpi_ut_update_ref_count (
	union acpi_operand_object       *object,
	u32                             action);


/*******************************************************************************
 *
 * FUNCTION:    acpi_ut_delete_internal_obj
 *
 * PARAMETERS:  Object         - Object to be deleted
 *
 * RETURN:      None
 *
 * DESCRIPTION: Low level object deletion, after reference counts have been
 *              updated (All reference counts, including sub-objects!)
 *
 ******************************************************************************/

static void
acpi_ut_delete_internal_obj (
	union acpi_operand_object       *object)
{
	void                            *obj_pointer = NULL;
	union acpi_operand_object       *handler_desc;
	union acpi_operand_object       *second_desc;
	union acpi_operand_object       *next_desc;


	ACPI_FUNCTION_TRACE_PTR ("ut_delete_internal_obj", object);


	if (!object) {
		return_VOID;
	}

	/*
	 * Must delete or free any pointers within the object that are not
	 * actual ACPI objects (for example, a raw buffer pointer).
	 */
	switch (ACPI_GET_OBJECT_TYPE (object)) {
	case ACPI_TYPE_STRING:

		ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "**** String %p, ptr %p\n",
			object, object->string.pointer));

		/* Free the actual string buffer */

		if (!(object->common.flags & AOPOBJ_STATIC_POINTER)) {
			/* But only if it is NOT a pointer into an ACPI table */

			obj_pointer = object->string.pointer;
		}
		break;


	case ACPI_TYPE_BUFFER:

		ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "**** Buffer %p, ptr %p\n",
			object, object->buffer.pointer));

		/* Free the actual buffer */

		if (!(object->common.flags & AOPOBJ_STATIC_POINTER)) {
			/* But only if it is NOT a pointer into an ACPI table */

			obj_pointer = object->buffer.pointer;
		}
		break;


	case ACPI_TYPE_PACKAGE:

		ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, " **** Package of count %X\n",
			object->package.count));

		/*
		 * Elements of the package are not handled here, they are deleted
		 * separately
		 */

		/* Free the (variable length) element pointer array */

		obj_pointer = object->package.elements;
		break;


	case ACPI_TYPE_DEVICE:

		if (object->device.gpe_block) {
			(void) acpi_ev_delete_gpe_block (object->device.gpe_block);
		}

		/* Walk the handler list for this device */

		handler_desc = object->device.handler;
		while (handler_desc) {
			next_desc = handler_desc->address_space.next;
			acpi_ut_remove_reference (handler_desc);
			handler_desc = next_desc;
		}
		break;


	case ACPI_TYPE_MUTEX:

		ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
			"***** Mutex %p, Semaphore %p\n",
			object, object->mutex.semaphore));

		acpi_ex_unlink_mutex (object);
		(void) acpi_os_delete_semaphore (object->mutex.semaphore);
		break;


	case ACPI_TYPE_EVENT:

		ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
			"***** Event %p, Semaphore %p\n",
			object, object->event.semaphore));

		(void) acpi_os_delete_semaphore (object->event.semaphore);
		object->event.semaphore = NULL;
		break;


	case ACPI_TYPE_METHOD:

		ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
			"***** Method %p\n", object));

		/* Delete the method semaphore if it exists */

		if (object->method.semaphore) {
			(void) acpi_os_delete_semaphore (object->method.semaphore);
			object->method.semaphore = NULL;
		}
		break;


	case ACPI_TYPE_REGION:

		ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
			"***** Region %p\n", object));

		second_desc = acpi_ns_get_secondary_object (object);
		if (second_desc) {
			/*
			 * Free the region_context if and only if the handler is one of the
			 * default handlers -- and therefore, we created the context object
			 * locally, it was not created by an external caller.
			 */
			handler_desc = object->region.handler;
			if (handler_desc) {
				if (handler_desc->address_space.hflags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) {
					obj_pointer = second_desc->extra.region_context;
				}

				acpi_ut_remove_reference (handler_desc);
			}

			/* Now we can free the Extra object */

			acpi_ut_delete_object_desc (second_desc);
		}
		break;


	case ACPI_TYPE_BUFFER_FIELD:

		ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
			"***** Buffer Field %p\n", object));

		second_desc = acpi_ns_get_secondary_object (object);
		if (second_desc) {
			acpi_ut_delete_object_desc (second_desc);
		}
		break;


	default:
		break;
	}

	/* Free any allocated memory (pointer within the object) found above */

	if (obj_pointer) {
		ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Deleting Object Subptr %p\n",
				obj_pointer));
		ACPI_MEM_FREE (obj_pointer);
	}

	/* Now the object can be safely deleted */

	ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Deleting Object %p [%s]\n",
			object, acpi_ut_get_object_type_name (object)));

	acpi_ut_delete_object_desc (object);
	return_VOID;
}


/*******************************************************************************
 *
 * FUNCTION:    acpi_ut_delete_internal_object_list
 *
 * PARAMETERS:  obj_list        - Pointer to the list to be deleted
 *
 * RETURN:      None
 *
 * DESCRIPTION: This function deletes an internal object list, including both
 *              simple objects and package objects
 *
 ******************************************************************************/

void
acpi_ut_delete_internal_object_list (
	union acpi_operand_object       **obj_list)
{
	union acpi_operand_object       **internal_obj;


	ACPI_FUNCTION_TRACE ("ut_delete_internal_object_list");


	/* Walk the null-terminated internal list */

	for (internal_obj = obj_list; *internal_obj; internal_obj++) {
		acpi_ut_remove_reference (*internal_obj);
	}

	/* Free the combined parameter pointer list and object array */

	ACPI_MEM_FREE (obj_list);
	return_VOID;
}


/*******************************************************************************
 *
 * FUNCTION:    acpi_ut_update_ref_count
 *
 * PARAMETERS:  Object          - Object whose ref count is to be updated
 *              Action          - What to do
 *
 * RETURN:      New ref count
 *
 * DESCRIPTION: Modify the ref count and return it.
 *
 ******************************************************************************/

static void
acpi_ut_update_ref_count (
	union acpi_operand_object       *object,
	u32                             action)
{
	u16                             count;
	u16                             new_count;


	ACPI_FUNCTION_NAME ("ut_update_ref_count");


	if (!object) {
		return;
	}

	count = object->common.reference_count;
	new_count = count;

	/*
	 * Perform the reference count action
	 * (increment, decrement, or force delete)
	 */
	switch (action) {

	case REF_INCREMENT:

		new_count++;
		object->common.reference_count = new_count;

		ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
			"Obj %p Refs=%X, [Incremented]\n",
			object, new_count));
		break;


	case REF_DECREMENT:

		if (count < 1) {
			ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
				"Obj %p Refs=%X, can't decrement! (Set to 0)\n",
				object, new_count));

			new_count = 0;
		}
		else {
			new_count--;

			ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
				"Obj %p Refs=%X, [Decremented]\n",
				object, new_count));
		}

		if (ACPI_GET_OBJECT_TYPE (object) == ACPI_TYPE_METHOD) {
			ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
				"Method Obj %p Refs=%X, [Decremented]\n",
				object, new_count));
		}

		object->common.reference_count = new_count;
		if (new_count == 0) {
			acpi_ut_delete_internal_obj (object);
		}

		break;


	case REF_FORCE_DELETE:

		ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
			"Obj %p Refs=%X, Force delete! (Set to 0)\n",
			object, count));

		new_count = 0;
		object->common.reference_count = new_count;
		acpi_ut_delete_internal_obj (object);
		break;


	default:

		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown action (%X)\n", action));
		break;
	}

	/*
	 * Sanity check the reference count, for debug purposes only.
	 * (A deleted object will have a huge reference count)
	 */
	if (count > ACPI_MAX_REFERENCE_COUNT) {

		ACPI_DEBUG_PRINT ((ACPI_DB_WARN,
			"**** Warning **** Large Reference Count (%X) in object %p\n\n",
			count, object));
	}

	return;
}


/*******************************************************************************
 *
 * FUNCTION:    acpi_ut_update_object_reference
 *
 * PARAMETERS:  Object              - Increment ref count for this object
 *                                    and all sub-objects
 *              Action              - Either REF_INCREMENT or REF_DECREMENT or
 *                                    REF_FORCE_DELETE
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Increment the object reference count
 *
 * Object references are incremented when:
 * 1) An object is attached to a Node (namespace object)
 * 2) An object is copied (all subobjects must be incremented)
 *
 * Object references are decremented when:
 * 1) An object is detached from an Node
 *
 ******************************************************************************/

acpi_status
acpi_ut_update_object_reference (
	union acpi_operand_object       *object,
	u16                             action)
{
	acpi_status                     status;
	u32                             i;
	union acpi_generic_state         *state_list = NULL;
	union acpi_generic_state         *state;
	union acpi_operand_object        *tmp;

	ACPI_FUNCTION_TRACE_PTR ("ut_update_object_reference", object);


	/* Ignore a null object ptr */

	if (!object) {
		return_ACPI_STATUS (AE_OK);
	}

	/* Make sure that this isn't a namespace handle */

	if (ACPI_GET_DESCRIPTOR_TYPE (object) == ACPI_DESC_TYPE_NAMED) {
		ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
			"Object %p is NS handle\n", object));
		return_ACPI_STATUS (AE_OK);
	}

	state = acpi_ut_create_update_state (object, action);

	while (state) {
		object = state->update.object;
		action = state->update.value;
		acpi_ut_delete_generic_state (state);

		/*
		 * All sub-objects must have their reference count incremented also.
		 * Different object types have different subobjects.
		 */
		switch (ACPI_GET_OBJECT_TYPE (object)) {
		case ACPI_TYPE_DEVICE:

			tmp = object->device.system_notify;
			if (tmp && (tmp->common.reference_count <= 1) && action == REF_DECREMENT)
				object->device.system_notify = NULL;
			acpi_ut_update_ref_count (tmp, action);

			tmp = object->device.device_notify;
			if (tmp && (tmp->common.reference_count <= 1) && action == REF_DECREMENT)
				object->device.device_notify = NULL;
			acpi_ut_update_ref_count (tmp, action);

			break;


		case ACPI_TYPE_PACKAGE:

			/*
			 * We must update all the sub-objects of the package
			 * (Each of whom may have their own sub-objects, etc.
			 */
			for (i = 0; i < object->package.count; i++) {
				/*
				 * Push each element onto the stack for later processing.
				 * Note: There can be null elements within the package,
				 * these are simply ignored
				 */
				status = acpi_ut_create_update_state_and_push (
						 object->package.elements[i], action, &state_list);
				if (ACPI_FAILURE (status)) {
					goto error_exit;
				}

				tmp = object->package.elements[i];
				if (tmp && (tmp->common.reference_count <= 1)  && action == REF_DECREMENT)
					object->package.elements[i] = NULL;
			}
			break;


		case ACPI_TYPE_BUFFER_FIELD:

			status = acpi_ut_create_update_state_and_push (
					 object->buffer_field.buffer_obj, action, &state_list);
			if (ACPI_FAILURE (status)) {
				goto error_exit;
			}

			tmp = object->buffer_field.buffer_obj;
			if ( tmp && (tmp->common.reference_count <= 1)  && action == REF_DECREMENT)
				object->buffer_field.buffer_obj = NULL;
			break;


		case ACPI_TYPE_LOCAL_REGION_FIELD:

			status = acpi_ut_create_update_state_and_push (
					 object->field.region_obj, action, &state_list);
			if (ACPI_FAILURE (status)) {
				goto error_exit;
			}

			tmp = object->field.region_obj;
			if ( tmp && (tmp->common.reference_count <= 1)  && action == REF_DECREMENT)
				object->field.region_obj = NULL;
		   break;


		case ACPI_TYPE_LOCAL_BANK_FIELD:

			status = acpi_ut_create_update_state_and_push (
					 object->bank_field.bank_obj, action, &state_list);
			if (ACPI_FAILURE (status)) {
				goto error_exit;
			}

			tmp = object->bank_field.bank_obj;
			if ( tmp && (tmp->common.reference_count <= 1)  && action == REF_DECREMENT)
				object->bank_field.bank_obj = NULL;

			status = acpi_ut_create_update_state_and_push (
					 object->bank_field.region_obj, action, &state_list);
			if (ACPI_FAILURE (status)) {
				goto error_exit;
			}

			tmp = object->bank_field.region_obj;
			if ( tmp && (tmp->common.reference_count <= 1)  && action == REF_DECREMENT)
				object->bank_field.region_obj = NULL;
			break;


		case ACPI_TYPE_LOCAL_INDEX_FIELD:

			status = acpi_ut_create_update_state_and_push (
					 object->index_field.index_obj, action, &state_list);
			if (ACPI_FAILURE (status)) {
				goto error_exit;
			}

			tmp = object->index_field.index_obj;
			if ( tmp && (tmp->common.reference_count <= 1)  && action == REF_DECREMENT)
				object->index_field.index_obj = NULL;

			status = acpi_ut_create_update_state_and_push (
					 object->index_field.data_obj, action, &state_list);
			if (ACPI_FAILURE (status)) {
				goto error_exit;
			}

			tmp = object->index_field.data_obj;
			if ( tmp && (tmp->common.reference_count <= 1)  && action == REF_DECREMENT)
				object->index_field.data_obj = NULL;
			break;


		case ACPI_TYPE_LOCAL_REFERENCE:

			/*
			 * The target of an Index (a package, string, or buffer) must track
			 * changes to the ref count of the index.
			 */
			if (object->reference.opcode == AML_INDEX_OP) {
				status = acpi_ut_create_update_state_and_push (
						 object->reference.object, action, &state_list);
				if (ACPI_FAILURE (status)) {
					goto error_exit;
				}
			}
			break;


		case ACPI_TYPE_REGION:
		default:

			/* No subobjects */
			break;
		}

		/*
		 * Now we can update the count in the main object.  This can only
		 * happen after we update the sub-objects in case this causes the
		 * main object to be deleted.
		 */
		acpi_ut_update_ref_count (object, action);

		/* Move on to the next object to be updated */

		state = acpi_ut_pop_generic_state (&state_list);
	}

	return_ACPI_STATUS (AE_OK);


error_exit:

	ACPI_REPORT_ERROR (("Could not update object reference count, %s\n",
		acpi_format_exception (status)));

	return_ACPI_STATUS (status);
}


/*******************************************************************************
 *
 * FUNCTION:    acpi_ut_add_reference
 *
 * PARAMETERS:  Object          - Object whose reference count is to be
 *                                incremented
 *
 * RETURN:      None
 *
 * DESCRIPTION: Add one reference to an ACPI object
 *
 ******************************************************************************/

void
acpi_ut_add_reference (
	union acpi_operand_object       *object)
{

	ACPI_FUNCTION_TRACE_PTR ("ut_add_reference", object);


	/* Ensure that we have a valid object */

	if (!acpi_ut_valid_internal_object (object)) {
		return_VOID;
	}

	ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
		"Obj %p Current Refs=%X [To Be Incremented]\n",
		object, object->common.reference_count));

	/* Increment the reference count */

	(void) acpi_ut_update_object_reference (object, REF_INCREMENT);
	return_VOID;
}


/*******************************************************************************
 *
 * FUNCTION:    acpi_ut_remove_reference
 *
 * PARAMETERS:  Object         - Object whose ref count will be decremented
 *
 * RETURN:      None
 *
 * DESCRIPTION: Decrement the reference count of an ACPI internal object
 *
 ******************************************************************************/

void
acpi_ut_remove_reference (
	union acpi_operand_object       *object)
{

	ACPI_FUNCTION_TRACE_PTR ("ut_remove_reference", object);


	/*
	 * Allow a NULL pointer to be passed in, just ignore it.  This saves
	 * each caller from having to check.  Also, ignore NS nodes.
	 *
	 */
	if (!object ||
		(ACPI_GET_DESCRIPTOR_TYPE (object) == ACPI_DESC_TYPE_NAMED)) {
		return_VOID;
	}

	/* Ensure that we have a valid object */

	if (!acpi_ut_valid_internal_object (object)) {
		return_VOID;
	}

	ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
		"Obj %p Current Refs=%X [To Be Decremented]\n",
		object, object->common.reference_count));

	/*
	 * Decrement the reference count, and only actually delete the object
	 * if the reference count becomes 0.  (Must also decrement the ref count
	 * of all subobjects!)
	 */
	(void) acpi_ut_update_object_reference (object, REF_DECREMENT);
	return_VOID;
}


