Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8e4319c4 authored by Bob Moore's avatar Bob Moore Committed by Len Brown
Browse files

ACPICA: Fix several acpi_attach_data problems

Handler was never invoked. Now invoked if/when host node is deleted.
Data object was not automatically deleted when host node was deleted.
Interface to handler had an unused parameter, removed it.
ACPICA BZ 778.

http://acpica.org/bugzilla/show_bug.cgi?id=778



Signed-off-by: default avatarBob Moore <robert.moore@intel.com>
Signed-off-by: default avatarLin Ming <ming.m.lin@intel.com>
Signed-off-by: default avatarLen Brown <len.brown@intel.com>
parent 6557a49a
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -144,6 +144,8 @@ struct acpi_namespace_node *acpi_ns_create_node(u32 name);

void acpi_ns_delete_node(struct acpi_namespace_node *node);

void acpi_ns_remove_node(struct acpi_namespace_node *node);

void
acpi_ns_delete_namespace_subtree(struct acpi_namespace_node *parent_handle);

+61 −27
Original line number Diff line number Diff line
@@ -96,17 +96,68 @@ struct acpi_namespace_node *acpi_ns_create_node(u32 name)
 *
 * RETURN:      None
 *
 * DESCRIPTION: Delete a namespace node
 * DESCRIPTION: Delete a namespace node. All node deletions must come through
 *              here. Detaches any attached objects, including any attached
 *              data. If a handler is associated with attached data, it is
 *              invoked before the node is deleted.
 *
 ******************************************************************************/

void acpi_ns_delete_node(struct acpi_namespace_node *node)
{
	union acpi_operand_object *obj_desc;

	ACPI_FUNCTION_NAME(ns_delete_node);

	/* Detach an object if there is one */

	acpi_ns_detach_object(node);

	/*
	 * Delete an attached data object if present (an object that was created
	 * and attached via acpi_attach_data). Note: After any normal object is
	 * detached above, the only possible remaining object is a data object.
	 */
	obj_desc = node->object;
	if (obj_desc && (obj_desc->common.type == ACPI_TYPE_LOCAL_DATA)) {

		/* Invoke the attached data deletion handler if present */

		if (obj_desc->data.handler) {
			obj_desc->data.handler(node, obj_desc->data.pointer);
		}

		acpi_ut_remove_reference(obj_desc);
	}

	/* Now we can delete the node */

	(void)acpi_os_release_object(acpi_gbl_namespace_cache, node);

	ACPI_MEM_TRACKING(acpi_gbl_ns_node_list->total_freed++);
	ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, "Node %p, Remaining %X\n",
			  node, acpi_gbl_current_node_count));
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_ns_remove_node
 *
 * PARAMETERS:  Node            - Node to be removed/deleted
 *
 * RETURN:      None
 *
 * DESCRIPTION: Remove (unlink) and delete a namespace node
 *
 ******************************************************************************/

void acpi_ns_remove_node(struct acpi_namespace_node *node)
{
	struct acpi_namespace_node *parent_node;
	struct acpi_namespace_node *prev_node;
	struct acpi_namespace_node *next_node;

	ACPI_FUNCTION_TRACE_PTR(ns_delete_node, node);
	ACPI_FUNCTION_TRACE_PTR(ns_remove_node, node);

	parent_node = acpi_ns_get_parent_node(node);

@@ -142,12 +193,9 @@ void acpi_ns_delete_node(struct acpi_namespace_node *node)
		}
	}

	ACPI_MEM_TRACKING(acpi_gbl_ns_node_list->total_freed++);

	/* Detach an object if there is one, then delete the node */
	/* Delete the node and any attached objects */

	acpi_ns_detach_object(node);
	(void)acpi_os_release_object(acpi_gbl_namespace_cache, node);
	acpi_ns_delete_node(node);
	return_VOID;
}

@@ -273,25 +321,11 @@ void acpi_ns_delete_children(struct acpi_namespace_node *parent_node)
				    parent_node, child_node));
		}

		/* Now we can free this child object */

		ACPI_MEM_TRACKING(acpi_gbl_ns_node_list->total_freed++);

		ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
				  "Object %p, Remaining %X\n", child_node,
				  acpi_gbl_current_node_count));

		/* Detach an object if there is one, then free the child node */

		acpi_ns_detach_object(child_node);

		/* Now we can delete the node */

		(void)acpi_os_release_object(acpi_gbl_namespace_cache,
					     child_node);

		/* And move on to the next child in the list */

		/*
		 * Delete this child node and move on to the next child in the list.
		 * No need to unlink the node since we are deleting the entire branch.
		 */
		acpi_ns_delete_node(child_node);
		child_node = next_node;

	} while (!(flags & ANOBJ_END_OF_PEER_LIST));
@@ -433,7 +467,7 @@ void acpi_ns_delete_namespace_by_owner(acpi_owner_id owner_id)

		if (deletion_node) {
			acpi_ns_delete_children(deletion_node);
			acpi_ns_delete_node(deletion_node);
			acpi_ns_remove_node(deletion_node);
			deletion_node = NULL;
		}

+1 −2
Original line number Diff line number Diff line
@@ -270,8 +270,7 @@ static acpi_status acpi_ns_delete_subtree(acpi_handle start_handle)

	/* Now delete the starting object, and we are done */

	acpi_ns_delete_node(child_handle);

	acpi_ns_remove_node(child_handle);
	return_ACPI_STATUS(AE_OK);
}

+1 −1
Original line number Diff line number Diff line
@@ -141,7 +141,7 @@ int acpi_bus_get_status(struct acpi_device *device)
EXPORT_SYMBOL(acpi_bus_get_status);

void acpi_bus_private_data_handler(acpi_handle handle,
				   u32 function, void *context)
				   void *context)
{
	return;
}
+1 −1
Original line number Diff line number Diff line
@@ -119,7 +119,7 @@ EXPORT_SYMBOL(acpi_get_child);

/* Link ACPI devices with physical devices */
static void acpi_glue_data_handler(acpi_handle handle,
				   u32 function, void *context)
				   void *context)
{
	/* we provide an empty handler */
}
Loading