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: Bob Moore <robert.moore@intel.com>
Signed-off-by: Lin Ming <ming.m.lin@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
This commit is contained in:
Bob Moore 2009-06-29 13:43:27 +08:00 committed by Len Brown
parent 6557a49a44
commit 8e4319c425
8 changed files with 70 additions and 35 deletions

View file

@ -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);

View file

@ -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++);
/* Delete the node and any attached objects */
/* Detach an object if there is one, then delete the node */
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;
}

View file

@ -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);
}

View file

@ -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;
}

View file

@ -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 */
}

View file

@ -687,7 +687,7 @@ acpi_bus_get_ejd(acpi_handle handle, acpi_handle *ejd)
}
EXPORT_SYMBOL_GPL(acpi_bus_get_ejd);
void acpi_bus_data_handler(acpi_handle handle, u32 function, void *context)
void acpi_bus_data_handler(acpi_handle handle, void *context)
{
/* TBD */

View file

@ -312,7 +312,7 @@ struct acpi_bus_event {
extern struct kobject *acpi_kobj;
extern int acpi_bus_generate_netlink_event(const char*, const char*, u8, int);
void acpi_bus_private_data_handler(acpi_handle, u32, void *);
void acpi_bus_private_data_handler(acpi_handle, void *);
int acpi_bus_get_private_data(acpi_handle, void **);
extern int acpi_notifier_call_chain(struct acpi_device *, u32, u32);
extern int register_acpi_notifier(struct notifier_block *);
@ -325,7 +325,7 @@ extern void unregister_acpi_bus_notifier(struct notifier_block *nb);
*/
int acpi_bus_get_device(acpi_handle handle, struct acpi_device **device);
void acpi_bus_data_handler(acpi_handle handle, u32 function, void *context);
void acpi_bus_data_handler(acpi_handle handle, void *context);
int acpi_bus_get_status(struct acpi_device *device);
int acpi_bus_get_power(acpi_handle handle, int *state);
int acpi_bus_set_power(acpi_handle handle, int state);

View file

@ -922,7 +922,7 @@ typedef
void (*acpi_notify_handler) (acpi_handle device, u32 value, void *context);
typedef
void (*acpi_object_handler) (acpi_handle object, u32 function, void *data);
void (*acpi_object_handler) (acpi_handle object, void *data);
typedef acpi_status(*acpi_init_handler) (acpi_handle object, u32 function);