aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/events/evregion.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/events/evregion.c')
-rw-r--r--drivers/acpi/events/evregion.c115
1 files changed, 68 insertions, 47 deletions
diff --git a/drivers/acpi/events/evregion.c b/drivers/acpi/events/evregion.c
index 6da58e776413..094a17e4c86d 100644
--- a/drivers/acpi/events/evregion.c
+++ b/drivers/acpi/events/evregion.c
@@ -83,7 +83,7 @@ acpi_status acpi_ev_install_region_handlers(void)
83 acpi_status status; 83 acpi_status status;
84 acpi_native_uint i; 84 acpi_native_uint i;
85 85
86 ACPI_FUNCTION_TRACE("ev_install_region_handlers"); 86 ACPI_FUNCTION_TRACE(ev_install_region_handlers);
87 87
88 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); 88 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
89 if (ACPI_FAILURE(status)) { 89 if (ACPI_FAILURE(status)) {
@@ -153,7 +153,7 @@ acpi_status acpi_ev_initialize_op_regions(void)
153 acpi_status status; 153 acpi_status status;
154 acpi_native_uint i; 154 acpi_native_uint i;
155 155
156 ACPI_FUNCTION_TRACE("ev_initialize_op_regions"); 156 ACPI_FUNCTION_TRACE(ev_initialize_op_regions);
157 157
158 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); 158 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
159 if (ACPI_FAILURE(status)) { 159 if (ACPI_FAILURE(status)) {
@@ -164,6 +164,7 @@ acpi_status acpi_ev_initialize_op_regions(void)
164 * Run the _REG methods for op_regions in each default address space 164 * Run the _REG methods for op_regions in each default address space
165 */ 165 */
166 for (i = 0; i < ACPI_NUM_DEFAULT_SPACES; i++) { 166 for (i = 0; i < ACPI_NUM_DEFAULT_SPACES; i++) {
167
167 /* TBD: Make sure handler is the DEFAULT handler, otherwise 168 /* TBD: Make sure handler is the DEFAULT handler, otherwise
168 * _REG will have already been run. 169 * _REG will have already been run.
169 */ 170 */
@@ -192,12 +193,12 @@ acpi_status acpi_ev_initialize_op_regions(void)
192acpi_status 193acpi_status
193acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function) 194acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function)
194{ 195{
195 struct acpi_parameter_info info; 196 struct acpi_evaluate_info *info;
196 union acpi_operand_object *params[3]; 197 union acpi_operand_object *args[3];
197 union acpi_operand_object *region_obj2; 198 union acpi_operand_object *region_obj2;
198 acpi_status status; 199 acpi_status status;
199 200
200 ACPI_FUNCTION_TRACE("ev_execute_reg_method"); 201 ACPI_FUNCTION_TRACE(ev_execute_reg_method);
201 202
202 region_obj2 = acpi_ns_get_secondary_object(region_obj); 203 region_obj2 = acpi_ns_get_secondary_object(region_obj);
203 if (!region_obj2) { 204 if (!region_obj2) {
@@ -208,48 +209,60 @@ acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function)
208 return_ACPI_STATUS(AE_OK); 209 return_ACPI_STATUS(AE_OK);
209 } 210 }
210 211
212 /* Allocate and initialize the evaluation information block */
213
214 info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
215 if (!info) {
216 return_ACPI_STATUS(AE_NO_MEMORY);
217 }
218
219 info->prefix_node = region_obj2->extra.method_REG;
220 info->pathname = NULL;
221 info->parameters = args;
222 info->parameter_type = ACPI_PARAM_ARGS;
223 info->flags = ACPI_IGNORE_RETURN_VALUE;
224
211 /* 225 /*
212 * The _REG method has two arguments: 226 * The _REG method has two arguments:
213 * 227 *
214 * Arg0, Integer: Operation region space ID 228 * Arg0 - Integer:
215 * Same value as region_obj->Region.space_id 229 * Operation region space ID Same value as region_obj->Region.space_id
216 * Arg1, Integer: connection status 230 *
217 * 1 for connecting the handler, 231 * Arg1 - Integer:
218 * 0 for disconnecting the handler 232 * connection status 1 for connecting the handler, 0 for disconnecting
219 * Passed as a parameter 233 * the handler (Passed as a parameter)
220 */ 234 */
221 params[0] = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER); 235 args[0] = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
222 if (!params[0]) { 236 if (!args[0]) {
223 return_ACPI_STATUS(AE_NO_MEMORY); 237 status = AE_NO_MEMORY;
238 goto cleanup1;
224 } 239 }
225 240
226 params[1] = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER); 241 args[1] = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
227 if (!params[1]) { 242 if (!args[1]) {
228 status = AE_NO_MEMORY; 243 status = AE_NO_MEMORY;
229 goto cleanup; 244 goto cleanup2;
230 } 245 }
231 246
232 /* Setup the parameter objects */ 247 /* Setup the parameter objects */
233 248
234 params[0]->integer.value = region_obj->region.space_id; 249 args[0]->integer.value = region_obj->region.space_id;
235 params[1]->integer.value = function; 250 args[1]->integer.value = function;
236 params[2] = NULL; 251 args[2] = NULL;
237
238 info.node = region_obj2->extra.method_REG;
239 info.parameters = params;
240 info.parameter_type = ACPI_PARAM_ARGS;
241 252
242 /* Execute the method, no return value */ 253 /* Execute the method, no return value */
243 254
244 ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname 255 ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname
245 (ACPI_TYPE_METHOD, info.node, NULL)); 256 (ACPI_TYPE_METHOD, info->prefix_node, NULL));
246 status = acpi_ns_evaluate_by_handle(&info);
247 257
248 acpi_ut_remove_reference(params[1]); 258 status = acpi_ns_evaluate(info);
259 acpi_ut_remove_reference(args[1]);
249 260
250 cleanup: 261 cleanup2:
251 acpi_ut_remove_reference(params[0]); 262 acpi_ut_remove_reference(args[0]);
252 263
264 cleanup1:
265 ACPI_FREE(info);
253 return_ACPI_STATUS(status); 266 return_ACPI_STATUS(status);
254} 267}
255 268
@@ -261,7 +274,8 @@ acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function)
261 * Function - Read or Write operation 274 * Function - Read or Write operation
262 * Address - Where in the space to read or write 275 * Address - Where in the space to read or write
263 * bit_width - Field width in bits (8, 16, 32, or 64) 276 * bit_width - Field width in bits (8, 16, 32, or 64)
264 * Value - Pointer to in or out value 277 * Value - Pointer to in or out value, must be
278 * full 64-bit acpi_integer
265 * 279 *
266 * RETURN: Status 280 * RETURN: Status
267 * 281 *
@@ -274,7 +288,7 @@ acpi_status
274acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, 288acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj,
275 u32 function, 289 u32 function,
276 acpi_physical_address address, 290 acpi_physical_address address,
277 u32 bit_width, void *value) 291 u32 bit_width, acpi_integer * value)
278{ 292{
279 acpi_status status; 293 acpi_status status;
280 acpi_status status2; 294 acpi_status status2;
@@ -284,7 +298,7 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj,
284 union acpi_operand_object *region_obj2; 298 union acpi_operand_object *region_obj2;
285 void *region_context = NULL; 299 void *region_context = NULL;
286 300
287 ACPI_FUNCTION_TRACE("ev_address_space_dispatch"); 301 ACPI_FUNCTION_TRACE(ev_address_space_dispatch);
288 302
289 region_obj2 = acpi_ns_get_secondary_object(region_obj); 303 region_obj2 = acpi_ns_get_secondary_object(region_obj);
290 if (!region_obj2) { 304 if (!region_obj2) {
@@ -315,6 +329,7 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj,
315 */ 329 */
316 region_setup = handler_desc->address_space.setup; 330 region_setup = handler_desc->address_space.setup;
317 if (!region_setup) { 331 if (!region_setup) {
332
318 /* No initialization routine, exit with error */ 333 /* No initialization routine, exit with error */
319 334
320 ACPI_ERROR((AE_INFO, 335 ACPI_ERROR((AE_INFO,
@@ -361,9 +376,10 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj,
361 region_obj->region.flags |= AOPOBJ_SETUP_COMPLETE; 376 region_obj->region.flags |= AOPOBJ_SETUP_COMPLETE;
362 377
363 if (region_obj2->extra.region_context) { 378 if (region_obj2->extra.region_context) {
379
364 /* The handler for this region was already installed */ 380 /* The handler for this region was already installed */
365 381
366 ACPI_MEM_FREE(region_context); 382 ACPI_FREE(region_context);
367 } else { 383 } else {
368 /* 384 /*
369 * Save the returned context for use in all accesses to 385 * Save the returned context for use in all accesses to
@@ -386,9 +402,8 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj,
386 acpi_ut_get_region_name(region_obj->region. 402 acpi_ut_get_region_name(region_obj->region.
387 space_id))); 403 space_id)));
388 404
389 if (! 405 if (!(handler_desc->address_space.handler_flags &
390 (handler_desc->address_space. 406 ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) {
391 hflags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) {
392 /* 407 /*
393 * For handlers other than the default (supplied) handlers, we must 408 * For handlers other than the default (supplied) handlers, we must
394 * exit the interpreter because the handler *might* block -- we don't 409 * exit the interpreter because the handler *might* block -- we don't
@@ -409,9 +424,8 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj,
409 space_id))); 424 space_id)));
410 } 425 }
411 426
412 if (! 427 if (!(handler_desc->address_space.handler_flags &
413 (handler_desc->address_space. 428 ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) {
414 hflags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) {
415 /* 429 /*
416 * We just returned from a non-default handler, we must re-enter the 430 * We just returned from a non-default handler, we must re-enter the
417 * interpreter 431 * interpreter
@@ -451,7 +465,7 @@ acpi_ev_detach_region(union acpi_operand_object *region_obj,
451 union acpi_operand_object *region_obj2; 465 union acpi_operand_object *region_obj2;
452 acpi_status status; 466 acpi_status status;
453 467
454 ACPI_FUNCTION_TRACE("ev_detach_region"); 468 ACPI_FUNCTION_TRACE(ev_detach_region);
455 469
456 region_obj2 = acpi_ns_get_secondary_object(region_obj); 470 region_obj2 = acpi_ns_get_secondary_object(region_obj);
457 if (!region_obj2) { 471 if (!region_obj2) {
@@ -463,6 +477,7 @@ acpi_ev_detach_region(union acpi_operand_object *region_obj,
463 477
464 handler_obj = region_obj->region.handler; 478 handler_obj = region_obj->region.handler;
465 if (!handler_obj) { 479 if (!handler_obj) {
480
466 /* This region has no handler, all done */ 481 /* This region has no handler, all done */
467 482
468 return_VOID; 483 return_VOID;
@@ -474,6 +489,7 @@ acpi_ev_detach_region(union acpi_operand_object *region_obj,
474 last_obj_ptr = &handler_obj->address_space.region_list; 489 last_obj_ptr = &handler_obj->address_space.region_list;
475 490
476 while (obj_desc) { 491 while (obj_desc) {
492
477 /* Is this the correct Region? */ 493 /* Is this the correct Region? */
478 494
479 if (obj_desc == region_obj) { 495 if (obj_desc == region_obj) {
@@ -583,7 +599,7 @@ acpi_ev_attach_region(union acpi_operand_object *handler_obj,
583 u8 acpi_ns_is_locked) 599 u8 acpi_ns_is_locked)
584{ 600{
585 601
586 ACPI_FUNCTION_TRACE("ev_attach_region"); 602 ACPI_FUNCTION_TRACE(ev_attach_region);
587 603
588 ACPI_DEBUG_PRINT((ACPI_DB_OPREGION, 604 ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
589 "Adding Region [%4.4s] %p to address handler %p [%s]\n", 605 "Adding Region [%4.4s] %p to address handler %p [%s]\n",
@@ -636,7 +652,7 @@ acpi_ev_install_handler(acpi_handle obj_handle,
636 struct acpi_namespace_node *node; 652 struct acpi_namespace_node *node;
637 acpi_status status; 653 acpi_status status;
638 654
639 ACPI_FUNCTION_NAME("ev_install_handler"); 655 ACPI_FUNCTION_NAME(ev_install_handler);
640 656
641 handler_obj = (union acpi_operand_object *)context; 657 handler_obj = (union acpi_operand_object *)context;
642 658
@@ -666,6 +682,7 @@ acpi_ev_install_handler(acpi_handle obj_handle,
666 682
667 obj_desc = acpi_ns_get_attached_object(node); 683 obj_desc = acpi_ns_get_attached_object(node);
668 if (!obj_desc) { 684 if (!obj_desc) {
685
669 /* No object, just exit */ 686 /* No object, just exit */
670 687
671 return (AE_OK); 688 return (AE_OK);
@@ -674,10 +691,12 @@ acpi_ev_install_handler(acpi_handle obj_handle,
674 /* Devices are handled different than regions */ 691 /* Devices are handled different than regions */
675 692
676 if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_DEVICE) { 693 if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_DEVICE) {
694
677 /* Check if this Device already has a handler for this address space */ 695 /* Check if this Device already has a handler for this address space */
678 696
679 next_handler_obj = obj_desc->device.handler; 697 next_handler_obj = obj_desc->device.handler;
680 while (next_handler_obj) { 698 while (next_handler_obj) {
699
681 /* Found a handler, is it for the same address space? */ 700 /* Found a handler, is it for the same address space? */
682 701
683 if (next_handler_obj->address_space.space_id == 702 if (next_handler_obj->address_space.space_id ==
@@ -764,9 +783,9 @@ acpi_ev_install_space_handler(struct acpi_namespace_node * node,
764 union acpi_operand_object *handler_obj; 783 union acpi_operand_object *handler_obj;
765 acpi_status status; 784 acpi_status status;
766 acpi_object_type type; 785 acpi_object_type type;
767 u16 flags = 0; 786 u8 flags = 0;
768 787
769 ACPI_FUNCTION_TRACE("ev_install_space_handler"); 788 ACPI_FUNCTION_TRACE(ev_install_space_handler);
770 789
771 /* 790 /*
772 * This registration is valid for only the types below 791 * This registration is valid for only the types below
@@ -839,6 +858,7 @@ acpi_ev_install_space_handler(struct acpi_namespace_node * node,
839 /* Walk the handler list for this device */ 858 /* Walk the handler list for this device */
840 859
841 while (handler_obj) { 860 while (handler_obj) {
861
842 /* Same space_id indicates a handler already installed */ 862 /* Same space_id indicates a handler already installed */
843 863
844 if (handler_obj->address_space.space_id == space_id) { 864 if (handler_obj->address_space.space_id == space_id) {
@@ -921,7 +941,7 @@ acpi_ev_install_space_handler(struct acpi_namespace_node * node,
921 /* Init handler obj */ 941 /* Init handler obj */
922 942
923 handler_obj->address_space.space_id = (u8) space_id; 943 handler_obj->address_space.space_id = (u8) space_id;
924 handler_obj->address_space.hflags = flags; 944 handler_obj->address_space.handler_flags = flags;
925 handler_obj->address_space.region_list = NULL; 945 handler_obj->address_space.region_list = NULL;
926 handler_obj->address_space.node = node; 946 handler_obj->address_space.node = node;
927 handler_obj->address_space.handler = handler; 947 handler_obj->address_space.handler = handler;
@@ -979,7 +999,7 @@ acpi_ev_execute_reg_methods(struct acpi_namespace_node *node,
979{ 999{
980 acpi_status status; 1000 acpi_status status;
981 1001
982 ACPI_FUNCTION_TRACE("ev_execute_reg_methods"); 1002 ACPI_FUNCTION_TRACE(ev_execute_reg_methods);
983 1003
984 /* 1004 /*
985 * Run all _REG methods for all Operation Regions for this 1005 * Run all _REG methods for all Operation Regions for this
@@ -1001,7 +1021,7 @@ acpi_ev_execute_reg_methods(struct acpi_namespace_node *node,
1001 * 1021 *
1002 * PARAMETERS: walk_namespace callback 1022 * PARAMETERS: walk_namespace callback
1003 * 1023 *
1004 * DESCRIPTION: Run _REg method for region objects of the requested space_iD 1024 * DESCRIPTION: Run _REG method for region objects of the requested space_iD
1005 * 1025 *
1006 ******************************************************************************/ 1026 ******************************************************************************/
1007 1027
@@ -1035,6 +1055,7 @@ acpi_ev_reg_run(acpi_handle obj_handle,
1035 1055
1036 obj_desc = acpi_ns_get_attached_object(node); 1056 obj_desc = acpi_ns_get_attached_object(node);
1037 if (!obj_desc) { 1057 if (!obj_desc) {
1058
1038 /* No object, just exit */ 1059 /* No object, just exit */
1039 1060
1040 return (AE_OK); 1061 return (AE_OK);