diff options
author | Bob Moore <robert.moore@intel.com> | 2009-06-29 01:43:27 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2009-08-27 10:17:19 -0400 |
commit | 8e4319c425077c4cc540696a5bb6c4d12f017dcd (patch) | |
tree | 6498586c5d438d679489b30ef6e294dfdeb3b655 /drivers/acpi/acpica | |
parent | 6557a49a443a347d24aed58076365432ded30edc (diff) |
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>
Diffstat (limited to 'drivers/acpi/acpica')
-rw-r--r-- | drivers/acpi/acpica/acnamesp.h | 2 | ||||
-rw-r--r-- | drivers/acpi/acpica/nsalloc.c | 88 | ||||
-rw-r--r-- | drivers/acpi/acpica/nsload.c | 3 |
3 files changed, 64 insertions, 29 deletions
diff --git a/drivers/acpi/acpica/acnamesp.h b/drivers/acpi/acpica/acnamesp.h index 94cdc2b8cb9..a78e02f62d5 100644 --- a/drivers/acpi/acpica/acnamesp.h +++ b/drivers/acpi/acpica/acnamesp.h | |||
@@ -144,6 +144,8 @@ struct acpi_namespace_node *acpi_ns_create_node(u32 name); | |||
144 | 144 | ||
145 | void acpi_ns_delete_node(struct acpi_namespace_node *node); | 145 | void acpi_ns_delete_node(struct acpi_namespace_node *node); |
146 | 146 | ||
147 | void acpi_ns_remove_node(struct acpi_namespace_node *node); | ||
148 | |||
147 | void | 149 | void |
148 | acpi_ns_delete_namespace_subtree(struct acpi_namespace_node *parent_handle); | 150 | acpi_ns_delete_namespace_subtree(struct acpi_namespace_node *parent_handle); |
149 | 151 | ||
diff --git a/drivers/acpi/acpica/nsalloc.c b/drivers/acpi/acpica/nsalloc.c index efc971ab7d6..8a58a1b85aa 100644 --- a/drivers/acpi/acpica/nsalloc.c +++ b/drivers/acpi/acpica/nsalloc.c | |||
@@ -96,17 +96,68 @@ struct acpi_namespace_node *acpi_ns_create_node(u32 name) | |||
96 | * | 96 | * |
97 | * RETURN: None | 97 | * RETURN: None |
98 | * | 98 | * |
99 | * DESCRIPTION: Delete a namespace node | 99 | * DESCRIPTION: Delete a namespace node. All node deletions must come through |
100 | * here. Detaches any attached objects, including any attached | ||
101 | * data. If a handler is associated with attached data, it is | ||
102 | * invoked before the node is deleted. | ||
100 | * | 103 | * |
101 | ******************************************************************************/ | 104 | ******************************************************************************/ |
102 | 105 | ||
103 | void acpi_ns_delete_node(struct acpi_namespace_node *node) | 106 | void acpi_ns_delete_node(struct acpi_namespace_node *node) |
104 | { | 107 | { |
108 | union acpi_operand_object *obj_desc; | ||
109 | |||
110 | ACPI_FUNCTION_NAME(ns_delete_node); | ||
111 | |||
112 | /* Detach an object if there is one */ | ||
113 | |||
114 | acpi_ns_detach_object(node); | ||
115 | |||
116 | /* | ||
117 | * Delete an attached data object if present (an object that was created | ||
118 | * and attached via acpi_attach_data). Note: After any normal object is | ||
119 | * detached above, the only possible remaining object is a data object. | ||
120 | */ | ||
121 | obj_desc = node->object; | ||
122 | if (obj_desc && (obj_desc->common.type == ACPI_TYPE_LOCAL_DATA)) { | ||
123 | |||
124 | /* Invoke the attached data deletion handler if present */ | ||
125 | |||
126 | if (obj_desc->data.handler) { | ||
127 | obj_desc->data.handler(node, obj_desc->data.pointer); | ||
128 | } | ||
129 | |||
130 | acpi_ut_remove_reference(obj_desc); | ||
131 | } | ||
132 | |||
133 | /* Now we can delete the node */ | ||
134 | |||
135 | (void)acpi_os_release_object(acpi_gbl_namespace_cache, node); | ||
136 | |||
137 | ACPI_MEM_TRACKING(acpi_gbl_ns_node_list->total_freed++); | ||
138 | ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, "Node %p, Remaining %X\n", | ||
139 | node, acpi_gbl_current_node_count)); | ||
140 | } | ||
141 | |||
142 | /******************************************************************************* | ||
143 | * | ||
144 | * FUNCTION: acpi_ns_remove_node | ||
145 | * | ||
146 | * PARAMETERS: Node - Node to be removed/deleted | ||
147 | * | ||
148 | * RETURN: None | ||
149 | * | ||
150 | * DESCRIPTION: Remove (unlink) and delete a namespace node | ||
151 | * | ||
152 | ******************************************************************************/ | ||
153 | |||
154 | void acpi_ns_remove_node(struct acpi_namespace_node *node) | ||
155 | { | ||
105 | struct acpi_namespace_node *parent_node; | 156 | struct acpi_namespace_node *parent_node; |
106 | struct acpi_namespace_node *prev_node; | 157 | struct acpi_namespace_node *prev_node; |
107 | struct acpi_namespace_node *next_node; | 158 | struct acpi_namespace_node *next_node; |
108 | 159 | ||
109 | ACPI_FUNCTION_TRACE_PTR(ns_delete_node, node); | 160 | ACPI_FUNCTION_TRACE_PTR(ns_remove_node, node); |
110 | 161 | ||
111 | parent_node = acpi_ns_get_parent_node(node); | 162 | parent_node = acpi_ns_get_parent_node(node); |
112 | 163 | ||
@@ -142,12 +193,9 @@ void acpi_ns_delete_node(struct acpi_namespace_node *node) | |||
142 | } | 193 | } |
143 | } | 194 | } |
144 | 195 | ||
145 | ACPI_MEM_TRACKING(acpi_gbl_ns_node_list->total_freed++); | 196 | /* Delete the node and any attached objects */ |
146 | |||
147 | /* Detach an object if there is one, then delete the node */ | ||
148 | 197 | ||
149 | acpi_ns_detach_object(node); | 198 | acpi_ns_delete_node(node); |
150 | (void)acpi_os_release_object(acpi_gbl_namespace_cache, node); | ||
151 | return_VOID; | 199 | return_VOID; |
152 | } | 200 | } |
153 | 201 | ||
@@ -273,25 +321,11 @@ void acpi_ns_delete_children(struct acpi_namespace_node *parent_node) | |||
273 | parent_node, child_node)); | 321 | parent_node, child_node)); |
274 | } | 322 | } |
275 | 323 | ||
276 | /* Now we can free this child object */ | 324 | /* |
277 | 325 | * Delete this child node and move on to the next child in the list. | |
278 | ACPI_MEM_TRACKING(acpi_gbl_ns_node_list->total_freed++); | 326 | * No need to unlink the node since we are deleting the entire branch. |
279 | 327 | */ | |
280 | ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, | 328 | acpi_ns_delete_node(child_node); |
281 | "Object %p, Remaining %X\n", child_node, | ||
282 | acpi_gbl_current_node_count)); | ||
283 | |||
284 | /* Detach an object if there is one, then free the child node */ | ||
285 | |||
286 | acpi_ns_detach_object(child_node); | ||
287 | |||
288 | /* Now we can delete the node */ | ||
289 | |||
290 | (void)acpi_os_release_object(acpi_gbl_namespace_cache, | ||
291 | child_node); | ||
292 | |||
293 | /* And move on to the next child in the list */ | ||
294 | |||
295 | child_node = next_node; | 329 | child_node = next_node; |
296 | 330 | ||
297 | } while (!(flags & ANOBJ_END_OF_PEER_LIST)); | 331 | } while (!(flags & ANOBJ_END_OF_PEER_LIST)); |
@@ -433,7 +467,7 @@ void acpi_ns_delete_namespace_by_owner(acpi_owner_id owner_id) | |||
433 | 467 | ||
434 | if (deletion_node) { | 468 | if (deletion_node) { |
435 | acpi_ns_delete_children(deletion_node); | 469 | acpi_ns_delete_children(deletion_node); |
436 | acpi_ns_delete_node(deletion_node); | 470 | acpi_ns_remove_node(deletion_node); |
437 | deletion_node = NULL; | 471 | deletion_node = NULL; |
438 | } | 472 | } |
439 | 473 | ||
diff --git a/drivers/acpi/acpica/nsload.c b/drivers/acpi/acpica/nsload.c index dcd7a6adbbb..a7234e60e98 100644 --- a/drivers/acpi/acpica/nsload.c +++ b/drivers/acpi/acpica/nsload.c | |||
@@ -270,8 +270,7 @@ static acpi_status acpi_ns_delete_subtree(acpi_handle start_handle) | |||
270 | 270 | ||
271 | /* Now delete the starting object, and we are done */ | 271 | /* Now delete the starting object, and we are done */ |
272 | 272 | ||
273 | acpi_ns_delete_node(child_handle); | 273 | acpi_ns_remove_node(child_handle); |
274 | |||
275 | return_ACPI_STATUS(AE_OK); | 274 | return_ACPI_STATUS(AE_OK); |
276 | } | 275 | } |
277 | 276 | ||