aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/acpica
diff options
context:
space:
mode:
authorLin Ming <ming.m.lin@intel.com>2009-10-12 22:29:30 -0400
committerLen Brown <len.brown@intel.com>2009-11-24 20:30:04 -0500
commit74d3ec77a5e0633b0c7a8490941432c2e4789037 (patch)
treee416b44a4533b77f85e30c65fe695a32d698e4d2 /drivers/acpi/acpica
parent0240d7b4f20f7d156a74dfdd0647a0231b7e8ef4 (diff)
ACPICA: Remove possibility of executing _REG methods twice
If a custom address space handler is installed by the host before the "initialize operation regions" phase of the ACPICA initialization, any _REG methods for that address space could be executed twice. This change fixes the problem. ACPICA BZ 427. http://www.acpica.org/bugzilla/show_bug.cgi?id=427 Signed-off-by: Lin Ming <ming.m.lin@intel.com> Signed-off-by: Bob Moore <robert.moore@intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/acpica')
-rw-r--r--drivers/acpi/acpica/evregion.c64
1 files changed, 59 insertions, 5 deletions
diff --git a/drivers/acpi/acpica/evregion.c b/drivers/acpi/acpica/evregion.c
index 98c7f9c62653..c9fa040725d4 100644
--- a/drivers/acpi/acpica/evregion.c
+++ b/drivers/acpi/acpica/evregion.c
@@ -51,6 +51,10 @@
51ACPI_MODULE_NAME("evregion") 51ACPI_MODULE_NAME("evregion")
52 52
53/* Local prototypes */ 53/* Local prototypes */
54static u8
55acpi_ev_has_default_handler(struct acpi_namespace_node *node,
56 acpi_adr_space_type space_id);
57
54static acpi_status 58static acpi_status
55acpi_ev_reg_run(acpi_handle obj_handle, 59acpi_ev_reg_run(acpi_handle obj_handle,
56 u32 level, void *context, void **return_value); 60 u32 level, void *context, void **return_value);
@@ -142,6 +146,50 @@ acpi_status acpi_ev_install_region_handlers(void)
142 146
143/******************************************************************************* 147/*******************************************************************************
144 * 148 *
149 * FUNCTION: acpi_ev_has_default_handler
150 *
151 * PARAMETERS: Node - Namespace node for the device
152 * space_id - The address space ID
153 *
154 * RETURN: TRUE if default handler is installed, FALSE otherwise
155 *
156 * DESCRIPTION: Check if the default handler is installed for the requested
157 * space ID.
158 *
159 ******************************************************************************/
160
161static u8
162acpi_ev_has_default_handler(struct acpi_namespace_node *node,
163 acpi_adr_space_type space_id)
164{
165 union acpi_operand_object *obj_desc;
166 union acpi_operand_object *handler_obj;
167
168 /* Must have an existing internal object */
169
170 obj_desc = acpi_ns_get_attached_object(node);
171 if (obj_desc) {
172 handler_obj = obj_desc->device.handler;
173
174 /* Walk the linked list of handlers for this object */
175
176 while (handler_obj) {
177 if (handler_obj->address_space.space_id == space_id) {
178 if (handler_obj->address_space.handler_flags &
179 ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) {
180 return (TRUE);
181 }
182 }
183
184 handler_obj = handler_obj->address_space.next;
185 }
186 }
187
188 return (FALSE);
189}
190
191/*******************************************************************************
192 *
145 * FUNCTION: acpi_ev_initialize_op_regions 193 * FUNCTION: acpi_ev_initialize_op_regions
146 * 194 *
147 * PARAMETERS: None 195 * PARAMETERS: None
@@ -169,12 +217,18 @@ acpi_status acpi_ev_initialize_op_regions(void)
169 217
170 for (i = 0; i < ACPI_NUM_DEFAULT_SPACES; i++) { 218 for (i = 0; i < ACPI_NUM_DEFAULT_SPACES; i++) {
171 /* 219 /*
172 * TBD: Make sure handler is the DEFAULT handler, otherwise 220 * Make sure the installed handler is the DEFAULT handler. If not the
173 * _REG will have already been run. 221 * default, the _REG methods will have already been run (when the
222 * handler was installed)
174 */ 223 */
175 status = acpi_ev_execute_reg_methods(acpi_gbl_root_node, 224 if (acpi_ev_has_default_handler(acpi_gbl_root_node,
176 acpi_gbl_default_address_spaces 225 acpi_gbl_default_address_spaces
177 [i]); 226 [i])) {
227 status =
228 acpi_ev_execute_reg_methods(acpi_gbl_root_node,
229 acpi_gbl_default_address_spaces
230 [i]);
231 }
178 } 232 }
179 233
180 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); 234 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);