diff options
Diffstat (limited to 'drivers')
31 files changed, 905 insertions, 987 deletions
diff --git a/drivers/acpi/dispatcher/dsmethod.c b/drivers/acpi/dispatcher/dsmethod.c index e348db0e541e..21f059986273 100644 --- a/drivers/acpi/dispatcher/dsmethod.c +++ b/drivers/acpi/dispatcher/dsmethod.c | |||
@@ -231,7 +231,7 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread, | |||
231 | struct acpi_namespace_node *method_node; | 231 | struct acpi_namespace_node *method_node; |
232 | struct acpi_walk_state *next_walk_state = NULL; | 232 | struct acpi_walk_state *next_walk_state = NULL; |
233 | union acpi_operand_object *obj_desc; | 233 | union acpi_operand_object *obj_desc; |
234 | struct acpi_parameter_info info; | 234 | struct acpi_evaluate_info *info; |
235 | u32 i; | 235 | u32 i; |
236 | 236 | ||
237 | ACPI_FUNCTION_TRACE_PTR(ds_call_control_method, this_walk_state); | 237 | ACPI_FUNCTION_TRACE_PTR(ds_call_control_method, this_walk_state); |
@@ -319,12 +319,24 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread, | |||
319 | */ | 319 | */ |
320 | this_walk_state->operands[this_walk_state->num_operands] = NULL; | 320 | this_walk_state->operands[this_walk_state->num_operands] = NULL; |
321 | 321 | ||
322 | info.parameters = &this_walk_state->operands[0]; | 322 | /* |
323 | info.parameter_type = ACPI_PARAM_ARGS; | 323 | * Allocate and initialize the evaluation information block |
324 | * TBD: this is somewhat inefficient, should change interface to | ||
325 | * ds_init_aml_walk. For now, keeps this struct off the CPU stack | ||
326 | */ | ||
327 | info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info)); | ||
328 | if (!info) { | ||
329 | return_ACPI_STATUS(AE_NO_MEMORY); | ||
330 | } | ||
331 | |||
332 | info->parameters = &this_walk_state->operands[0]; | ||
333 | info->parameter_type = ACPI_PARAM_ARGS; | ||
324 | 334 | ||
325 | status = acpi_ds_init_aml_walk(next_walk_state, NULL, method_node, | 335 | status = acpi_ds_init_aml_walk(next_walk_state, NULL, method_node, |
326 | obj_desc->method.aml_start, | 336 | obj_desc->method.aml_start, |
327 | obj_desc->method.aml_length, &info, 3); | 337 | obj_desc->method.aml_length, info, 3); |
338 | |||
339 | ACPI_FREE(info); | ||
328 | if (ACPI_FAILURE(status)) { | 340 | if (ACPI_FAILURE(status)) { |
329 | goto cleanup; | 341 | goto cleanup; |
330 | } | 342 | } |
diff --git a/drivers/acpi/dispatcher/dswexec.c b/drivers/acpi/dispatcher/dswexec.c index 8afb20384e96..3acbd9145d72 100644 --- a/drivers/acpi/dispatcher/dswexec.c +++ b/drivers/acpi/dispatcher/dswexec.c | |||
@@ -295,7 +295,7 @@ acpi_ds_exec_begin_op(struct acpi_walk_state *walk_state, | |||
295 | 295 | ||
296 | case AML_CLASS_NAMED_OBJECT: | 296 | case AML_CLASS_NAMED_OBJECT: |
297 | 297 | ||
298 | if (walk_state->walk_type == ACPI_WALK_METHOD) { | 298 | if (walk_state->walk_type & ACPI_WALK_METHOD) { |
299 | /* | 299 | /* |
300 | * Found a named object declaration during method execution; | 300 | * Found a named object declaration during method execution; |
301 | * we must enter this object into the namespace. The created | 301 | * we must enter this object into the namespace. The created |
diff --git a/drivers/acpi/dispatcher/dswstate.c b/drivers/acpi/dispatcher/dswstate.c index 82c1e219bf15..7817e5522679 100644 --- a/drivers/acpi/dispatcher/dswstate.c +++ b/drivers/acpi/dispatcher/dswstate.c | |||
@@ -703,7 +703,7 @@ acpi_ds_init_aml_walk(struct acpi_walk_state *walk_state, | |||
703 | struct acpi_namespace_node *method_node, | 703 | struct acpi_namespace_node *method_node, |
704 | u8 * aml_start, | 704 | u8 * aml_start, |
705 | u32 aml_length, | 705 | u32 aml_length, |
706 | struct acpi_parameter_info *info, u8 pass_number) | 706 | struct acpi_evaluate_info *info, u8 pass_number) |
707 | { | 707 | { |
708 | acpi_status status; | 708 | acpi_status status; |
709 | struct acpi_parse_state *parser_state = &walk_state->parser_state; | 709 | struct acpi_parse_state *parser_state = &walk_state->parser_state; |
@@ -825,9 +825,12 @@ void acpi_ds_delete_walk_state(struct acpi_walk_state *walk_state) | |||
825 | return; | 825 | return; |
826 | } | 826 | } |
827 | 827 | ||
828 | /* There should not be any open scopes */ | ||
829 | |||
828 | if (walk_state->parser_state.scope) { | 830 | if (walk_state->parser_state.scope) { |
829 | ACPI_ERROR((AE_INFO, "%p walk still has a scope list", | 831 | ACPI_ERROR((AE_INFO, "%p walk still has a scope list", |
830 | walk_state)); | 832 | walk_state)); |
833 | acpi_ps_cleanup_scope(&walk_state->parser_state); | ||
831 | } | 834 | } |
832 | 835 | ||
833 | /* Always must free any linked control states */ | 836 | /* Always must free any linked control states */ |
diff --git a/drivers/acpi/events/evgpe.c b/drivers/acpi/events/evgpe.c index aa179dc78011..23fe53ba7375 100644 --- a/drivers/acpi/events/evgpe.c +++ b/drivers/acpi/events/evgpe.c | |||
@@ -488,9 +488,9 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list) | |||
488 | * | 488 | * |
489 | * RETURN: None | 489 | * RETURN: None |
490 | * | 490 | * |
491 | * DESCRIPTION: Perform the actual execution of a GPE control method. This | 491 | * DESCRIPTION: Perform the actual execution of a GPE control method. This |
492 | * function is called from an invocation of acpi_os_exece | 492 | * function is called from an invocation of acpi_os_execute and |
493 | * (and therefore does NOT execute at interrupt level) so that | 493 | * therefore does NOT execute at interrupt level - so that |
494 | * the control method itself is not executed in the context of | 494 | * the control method itself is not executed in the context of |
495 | * an interrupt handler. | 495 | * an interrupt handler. |
496 | * | 496 | * |
@@ -502,7 +502,7 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context) | |||
502 | u32 gpe_number = 0; | 502 | u32 gpe_number = 0; |
503 | acpi_status status; | 503 | acpi_status status; |
504 | struct acpi_gpe_event_info local_gpe_event_info; | 504 | struct acpi_gpe_event_info local_gpe_event_info; |
505 | struct acpi_parameter_info info; | 505 | struct acpi_evaluate_info *info; |
506 | 506 | ||
507 | ACPI_FUNCTION_TRACE(ev_asynch_execute_gpe_method); | 507 | ACPI_FUNCTION_TRACE(ev_asynch_execute_gpe_method); |
508 | 508 | ||
@@ -540,16 +540,29 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context) | |||
540 | */ | 540 | */ |
541 | if ((local_gpe_event_info.flags & ACPI_GPE_DISPATCH_MASK) == | 541 | if ((local_gpe_event_info.flags & ACPI_GPE_DISPATCH_MASK) == |
542 | ACPI_GPE_DISPATCH_METHOD) { | 542 | ACPI_GPE_DISPATCH_METHOD) { |
543 | /* | ||
544 | * Invoke the GPE Method (_Lxx, _Exx) i.e., evaluate the _Lxx/_Exx | ||
545 | * control method that corresponds to this GPE | ||
546 | */ | ||
547 | info.node = local_gpe_event_info.dispatch.method_node; | ||
548 | info.parameters = | ||
549 | ACPI_CAST_PTR(union acpi_operand_object *, gpe_event_info); | ||
550 | info.parameter_type = ACPI_PARAM_GPE; | ||
551 | 543 | ||
552 | status = acpi_ns_evaluate_by_handle(&info); | 544 | /* Allocate the evaluation information block */ |
545 | |||
546 | info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info)); | ||
547 | if (!info) { | ||
548 | status = AE_NO_MEMORY; | ||
549 | } else { | ||
550 | /* | ||
551 | * Invoke the GPE Method (_Lxx, _Exx) i.e., evaluate the _Lxx/_Exx | ||
552 | * control method that corresponds to this GPE | ||
553 | */ | ||
554 | info->prefix_node = | ||
555 | local_gpe_event_info.dispatch.method_node; | ||
556 | info->parameters = | ||
557 | ACPI_CAST_PTR(union acpi_operand_object *, | ||
558 | gpe_event_info); | ||
559 | info->parameter_type = ACPI_PARAM_GPE; | ||
560 | info->flags = ACPI_IGNORE_RETURN_VALUE; | ||
561 | |||
562 | status = acpi_ns_evaluate(info); | ||
563 | ACPI_FREE(info); | ||
564 | } | ||
565 | |||
553 | if (ACPI_FAILURE(status)) { | 566 | if (ACPI_FAILURE(status)) { |
554 | ACPI_EXCEPTION((AE_INFO, status, | 567 | ACPI_EXCEPTION((AE_INFO, status, |
555 | "While evaluating method [%4.4s] for GPE[%2X]", | 568 | "While evaluating method [%4.4s] for GPE[%2X]", |
diff --git a/drivers/acpi/events/evmisc.c b/drivers/acpi/events/evmisc.c index 24e0b8d36f31..6eef4efddcf6 100644 --- a/drivers/acpi/events/evmisc.c +++ b/drivers/acpi/events/evmisc.c | |||
@@ -49,12 +49,13 @@ | |||
49 | #define _COMPONENT ACPI_EVENTS | 49 | #define _COMPONENT ACPI_EVENTS |
50 | ACPI_MODULE_NAME("evmisc") | 50 | ACPI_MODULE_NAME("evmisc") |
51 | 51 | ||
52 | /* Names for Notify() values, used for debug output */ | ||
52 | #ifdef ACPI_DEBUG_OUTPUT | 53 | #ifdef ACPI_DEBUG_OUTPUT |
53 | static const char *acpi_notify_value_names[] = { | 54 | static const char *acpi_notify_value_names[] = { |
54 | "Bus Check", | 55 | "Bus Check", |
55 | "Device Check", | 56 | "Device Check", |
56 | "Device Wake", | 57 | "Device Wake", |
57 | "Eject request", | 58 | "Eject Request", |
58 | "Device Check Light", | 59 | "Device Check Light", |
59 | "Frequency Mismatch", | 60 | "Frequency Mismatch", |
60 | "Bus Mode Mismatch", | 61 | "Bus Mode Mismatch", |
@@ -191,8 +192,9 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node * node, | |||
191 | notify_info->notify.value = (u16) notify_value; | 192 | notify_info->notify.value = (u16) notify_value; |
192 | notify_info->notify.handler_obj = handler_obj; | 193 | notify_info->notify.handler_obj = handler_obj; |
193 | 194 | ||
194 | status = acpi_os_execute(OSL_NOTIFY_HANDLER, | 195 | status = |
195 | acpi_ev_notify_dispatch, notify_info); | 196 | acpi_os_execute(OSL_NOTIFY_HANDLER, acpi_ev_notify_dispatch, |
197 | notify_info); | ||
196 | if (ACPI_FAILURE(status)) { | 198 | if (ACPI_FAILURE(status)) { |
197 | acpi_ut_delete_generic_state(notify_info); | 199 | acpi_ut_delete_generic_state(notify_info); |
198 | } | 200 | } |
@@ -345,8 +347,9 @@ static u32 acpi_ev_global_lock_handler(void *context) | |||
345 | 347 | ||
346 | /* Run the Global Lock thread which will signal all waiting threads */ | 348 | /* Run the Global Lock thread which will signal all waiting threads */ |
347 | 349 | ||
348 | status = acpi_os_execute(OSL_GLOBAL_LOCK_HANDLER, | 350 | status = |
349 | acpi_ev_global_lock_thread, context); | 351 | acpi_os_execute(OSL_GLOBAL_LOCK_HANDLER, |
352 | acpi_ev_global_lock_thread, context); | ||
350 | if (ACPI_FAILURE(status)) { | 353 | if (ACPI_FAILURE(status)) { |
351 | ACPI_EXCEPTION((AE_INFO, status, | 354 | ACPI_EXCEPTION((AE_INFO, status, |
352 | "Could not queue Global Lock thread")); | 355 | "Could not queue Global Lock thread")); |
@@ -462,8 +465,9 @@ acpi_status acpi_ev_acquire_global_lock(u16 timeout) | |||
462 | * Acquire the global lock semaphore first. | 465 | * Acquire the global lock semaphore first. |
463 | * Since this wait will block, we must release the interpreter | 466 | * Since this wait will block, we must release the interpreter |
464 | */ | 467 | */ |
465 | status = acpi_ex_system_wait_semaphore(acpi_gbl_global_lock_semaphore, | 468 | status = |
466 | timeout); | 469 | acpi_ex_system_wait_semaphore(acpi_gbl_global_lock_semaphore, |
470 | timeout); | ||
467 | return_ACPI_STATUS(status); | 471 | return_ACPI_STATUS(status); |
468 | } | 472 | } |
469 | 473 | ||
diff --git a/drivers/acpi/events/evregion.c b/drivers/acpi/events/evregion.c index edf9d2e1dff9..094a17e4c86d 100644 --- a/drivers/acpi/events/evregion.c +++ b/drivers/acpi/events/evregion.c | |||
@@ -193,8 +193,8 @@ acpi_status acpi_ev_initialize_op_regions(void) | |||
193 | acpi_status | 193 | acpi_status |
194 | acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function) | 194 | acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function) |
195 | { | 195 | { |
196 | struct acpi_parameter_info info; | 196 | struct acpi_evaluate_info *info; |
197 | union acpi_operand_object *params[3]; | 197 | union acpi_operand_object *args[3]; |
198 | union acpi_operand_object *region_obj2; | 198 | union acpi_operand_object *region_obj2; |
199 | acpi_status status; | 199 | acpi_status status; |
200 | 200 | ||
@@ -209,47 +209,60 @@ acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function) | |||
209 | return_ACPI_STATUS(AE_OK); | 209 | return_ACPI_STATUS(AE_OK); |
210 | } | 210 | } |
211 | 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 | |||
212 | /* | 225 | /* |
213 | * The _REG method has two arguments: | 226 | * The _REG method has two arguments: |
214 | * | 227 | * |
215 | * Arg0, Integer: Operation region space ID | 228 | * Arg0 - Integer: |
216 | * Same value as region_obj->Region.space_id | 229 | * Operation region space ID Same value as region_obj->Region.space_id |
217 | * Arg1, Integer: connection status | 230 | * |
218 | * 1 for connecting the handler, | 231 | * Arg1 - Integer: |
219 | * 0 for disconnecting the handler | 232 | * connection status 1 for connecting the handler, 0 for disconnecting |
220 | * Passed as a parameter | 233 | * the handler (Passed as a parameter) |
221 | */ | 234 | */ |
222 | params[0] = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER); | 235 | args[0] = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER); |
223 | if (!params[0]) { | 236 | if (!args[0]) { |
224 | return_ACPI_STATUS(AE_NO_MEMORY); | 237 | status = AE_NO_MEMORY; |
238 | goto cleanup1; | ||
225 | } | 239 | } |
226 | 240 | ||
227 | params[1] = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER); | 241 | args[1] = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER); |
228 | if (!params[1]) { | 242 | if (!args[1]) { |
229 | status = AE_NO_MEMORY; | 243 | status = AE_NO_MEMORY; |
230 | goto cleanup; | 244 | goto cleanup2; |
231 | } | 245 | } |
232 | 246 | ||
233 | /* Setup the parameter objects */ | 247 | /* Setup the parameter objects */ |
234 | 248 | ||
235 | params[0]->integer.value = region_obj->region.space_id; | 249 | args[0]->integer.value = region_obj->region.space_id; |
236 | params[1]->integer.value = function; | 250 | args[1]->integer.value = function; |
237 | params[2] = NULL; | 251 | args[2] = NULL; |
238 | |||
239 | info.node = region_obj2->extra.method_REG; | ||
240 | info.parameters = params; | ||
241 | info.parameter_type = ACPI_PARAM_ARGS; | ||
242 | 252 | ||
243 | /* Execute the method, no return value */ | 253 | /* Execute the method, no return value */ |
244 | 254 | ||
245 | ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname | 255 | ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname |
246 | (ACPI_TYPE_METHOD, info.node, NULL)); | 256 | (ACPI_TYPE_METHOD, info->prefix_node, NULL)); |
247 | status = acpi_ns_evaluate_by_handle(&info); | 257 | |
258 | status = acpi_ns_evaluate(info); | ||
259 | acpi_ut_remove_reference(args[1]); | ||
248 | 260 | ||
249 | acpi_ut_remove_reference(params[1]); | 261 | cleanup2: |
262 | acpi_ut_remove_reference(args[0]); | ||
250 | 263 | ||
251 | cleanup: | 264 | cleanup1: |
252 | acpi_ut_remove_reference(params[0]); | 265 | ACPI_FREE(info); |
253 | return_ACPI_STATUS(status); | 266 | return_ACPI_STATUS(status); |
254 | } | 267 | } |
255 | 268 | ||
diff --git a/drivers/acpi/events/evrgnini.c b/drivers/acpi/events/evrgnini.c index 1cecd577b899..5b3c7a85eb9a 100644 --- a/drivers/acpi/events/evrgnini.c +++ b/drivers/acpi/events/evrgnini.c | |||
@@ -475,8 +475,9 @@ acpi_ev_initialize_region(union acpi_operand_object *region_obj, | |||
475 | 475 | ||
476 | /* Find any "_REG" method associated with this region definition */ | 476 | /* Find any "_REG" method associated with this region definition */ |
477 | 477 | ||
478 | status = acpi_ns_search_node(*reg_name_ptr, node, | 478 | status = |
479 | ACPI_TYPE_METHOD, &method_node); | 479 | acpi_ns_search_one_scope(*reg_name_ptr, node, ACPI_TYPE_METHOD, |
480 | &method_node); | ||
480 | if (ACPI_SUCCESS(status)) { | 481 | if (ACPI_SUCCESS(status)) { |
481 | /* | 482 | /* |
482 | * The _REG method is optional and there can be only one per region | 483 | * The _REG method is optional and there can be only one per region |
diff --git a/drivers/acpi/executer/exconfig.c b/drivers/acpi/executer/exconfig.c index 9ae3cb55979b..823352435e08 100644 --- a/drivers/acpi/executer/exconfig.c +++ b/drivers/acpi/executer/exconfig.c | |||
@@ -214,9 +214,8 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state, | |||
214 | * location within the namespace where the table will be loaded. | 214 | * location within the namespace where the table will be loaded. |
215 | */ | 215 | */ |
216 | status = | 216 | status = |
217 | acpi_ns_get_node_by_path(operand[3]->string.pointer, | 217 | acpi_ns_get_node(start_node, operand[3]->string.pointer, |
218 | start_node, ACPI_NS_SEARCH_PARENT, | 218 | ACPI_NS_SEARCH_PARENT, &parent_node); |
219 | &parent_node); | ||
220 | if (ACPI_FAILURE(status)) { | 219 | if (ACPI_FAILURE(status)) { |
221 | return_ACPI_STATUS(status); | 220 | return_ACPI_STATUS(status); |
222 | } | 221 | } |
@@ -237,9 +236,8 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state, | |||
237 | /* Find the node referenced by the parameter_path_string */ | 236 | /* Find the node referenced by the parameter_path_string */ |
238 | 237 | ||
239 | status = | 238 | status = |
240 | acpi_ns_get_node_by_path(operand[4]->string.pointer, | 239 | acpi_ns_get_node(start_node, operand[4]->string.pointer, |
241 | start_node, ACPI_NS_SEARCH_PARENT, | 240 | ACPI_NS_SEARCH_PARENT, ¶meter_node); |
242 | ¶meter_node); | ||
243 | if (ACPI_FAILURE(status)) { | 241 | if (ACPI_FAILURE(status)) { |
244 | return_ACPI_STATUS(status); | 242 | return_ACPI_STATUS(status); |
245 | } | 243 | } |
diff --git a/drivers/acpi/executer/exfldio.c b/drivers/acpi/executer/exfldio.c index ca9925c0d011..3b7c4352ec57 100644 --- a/drivers/acpi/executer/exfldio.c +++ b/drivers/acpi/executer/exfldio.c | |||
@@ -145,10 +145,10 @@ acpi_ex_setup_region(union acpi_operand_object *obj_desc, | |||
145 | * length of one field datum (access width) must fit within the region. | 145 | * length of one field datum (access width) must fit within the region. |
146 | * (Region length is specified in bytes) | 146 | * (Region length is specified in bytes) |
147 | */ | 147 | */ |
148 | if (rgn_desc->region.length < (obj_desc->common_field.base_byte_offset + | 148 | if (rgn_desc->region.length < |
149 | field_datum_byte_offset + | 149 | (obj_desc->common_field.base_byte_offset + |
150 | obj_desc->common_field. | 150 | field_datum_byte_offset + |
151 | access_byte_width)) { | 151 | obj_desc->common_field.access_byte_width)) { |
152 | if (acpi_gbl_enable_interpreter_slack) { | 152 | if (acpi_gbl_enable_interpreter_slack) { |
153 | /* | 153 | /* |
154 | * Slack mode only: We will go ahead and allow access to this | 154 | * Slack mode only: We will go ahead and allow access to this |
@@ -811,13 +811,15 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc, | |||
811 | 811 | ||
812 | mask = | 812 | mask = |
813 | ACPI_MASK_BITS_BELOW(obj_desc->common_field.start_field_bit_offset); | 813 | ACPI_MASK_BITS_BELOW(obj_desc->common_field.start_field_bit_offset); |
814 | datum_count = | 814 | |
815 | ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length, | 815 | datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length, |
816 | obj_desc->common_field.access_bit_width); | 816 | obj_desc->common_field.access_bit_width); |
817 | field_datum_count = | 817 | |
818 | ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length + | 818 | field_datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length + |
819 | obj_desc->common_field.start_field_bit_offset, | 819 | obj_desc->common_field. |
820 | obj_desc->common_field.access_bit_width); | 820 | start_field_bit_offset, |
821 | obj_desc->common_field. | ||
822 | access_bit_width); | ||
821 | 823 | ||
822 | /* Get initial Datum from the input buffer */ | 824 | /* Get initial Datum from the input buffer */ |
823 | 825 | ||
diff --git a/drivers/acpi/executer/exmisc.c b/drivers/acpi/executer/exmisc.c index 794d9b8de956..bd98aab017cf 100644 --- a/drivers/acpi/executer/exmisc.c +++ b/drivers/acpi/executer/exmisc.c | |||
@@ -445,10 +445,24 @@ acpi_ex_do_math_op(u16 opcode, acpi_integer integer0, acpi_integer integer1) | |||
445 | 445 | ||
446 | case AML_SHIFT_LEFT_OP: /* shift_left (Operand, shift_count, Result) */ | 446 | case AML_SHIFT_LEFT_OP: /* shift_left (Operand, shift_count, Result) */ |
447 | 447 | ||
448 | /* | ||
449 | * We need to check if the shiftcount is larger than the integer bit | ||
450 | * width since the behavior of this is not well-defined in the C language. | ||
451 | */ | ||
452 | if (integer1 >= acpi_gbl_integer_bit_width) { | ||
453 | return (0); | ||
454 | } | ||
448 | return (integer0 << integer1); | 455 | return (integer0 << integer1); |
449 | 456 | ||
450 | case AML_SHIFT_RIGHT_OP: /* shift_right (Operand, shift_count, Result) */ | 457 | case AML_SHIFT_RIGHT_OP: /* shift_right (Operand, shift_count, Result) */ |
451 | 458 | ||
459 | /* | ||
460 | * We need to check if the shiftcount is larger than the integer bit | ||
461 | * width since the behavior of this is not well-defined in the C language. | ||
462 | */ | ||
463 | if (integer1 >= acpi_gbl_integer_bit_width) { | ||
464 | return (0); | ||
465 | } | ||
452 | return (integer0 >> integer1); | 466 | return (integer0 >> integer1); |
453 | 467 | ||
454 | case AML_SUBTRACT_OP: /* Subtract (Integer0, Integer1, Result) */ | 468 | case AML_SUBTRACT_OP: /* Subtract (Integer0, Integer1, Result) */ |
diff --git a/drivers/acpi/executer/exoparg1.c b/drivers/acpi/executer/exoparg1.c index 05b89c5878eb..8284c52875be 100644 --- a/drivers/acpi/executer/exoparg1.c +++ b/drivers/acpi/executer/exoparg1.c | |||
@@ -874,16 +874,14 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state) | |||
874 | * Field, so we need to resolve the node to a value. | 874 | * Field, so we need to resolve the node to a value. |
875 | */ | 875 | */ |
876 | status = | 876 | status = |
877 | acpi_ns_get_node_by_path(operand[0]->string. | 877 | acpi_ns_get_node(walk_state->scope_info-> |
878 | pointer, | 878 | scope.node, |
879 | walk_state-> | 879 | operand[0]->string.pointer, |
880 | scope_info->scope. | 880 | ACPI_NS_SEARCH_PARENT, |
881 | node, | 881 | ACPI_CAST_INDIRECT_PTR |
882 | ACPI_NS_SEARCH_PARENT, | 882 | (struct |
883 | ACPI_CAST_INDIRECT_PTR | 883 | acpi_namespace_node, |
884 | (struct | 884 | &return_desc)); |
885 | acpi_namespace_node, | ||
886 | &return_desc)); | ||
887 | if (ACPI_FAILURE(status)) { | 885 | if (ACPI_FAILURE(status)) { |
888 | goto cleanup; | 886 | goto cleanup; |
889 | } | 887 | } |
diff --git a/drivers/acpi/executer/exregion.c b/drivers/acpi/executer/exregion.c index 4fba452a5590..3cc97ba48b36 100644 --- a/drivers/acpi/executer/exregion.c +++ b/drivers/acpi/executer/exregion.c | |||
@@ -477,23 +477,16 @@ acpi_ex_data_table_space_handler(u32 function, | |||
477 | acpi_integer * value, | 477 | acpi_integer * value, |
478 | void *handler_context, void *region_context) | 478 | void *handler_context, void *region_context) |
479 | { | 479 | { |
480 | acpi_status status = AE_OK; | ||
481 | u32 byte_width = ACPI_DIV_8(bit_width); | ||
482 | u32 i; | ||
483 | char *logical_addr_ptr; | ||
484 | |||
485 | ACPI_FUNCTION_TRACE(ex_data_table_space_handler); | 480 | ACPI_FUNCTION_TRACE(ex_data_table_space_handler); |
486 | 481 | ||
487 | logical_addr_ptr = ACPI_PHYSADDR_TO_PTR(address); | ||
488 | |||
489 | /* Perform the memory read or write */ | 482 | /* Perform the memory read or write */ |
490 | 483 | ||
491 | switch (function) { | 484 | switch (function) { |
492 | case ACPI_READ: | 485 | case ACPI_READ: |
493 | 486 | ||
494 | for (i = 0; i < byte_width; i++) { | 487 | ACPI_MEMCPY(ACPI_CAST_PTR(char, value), |
495 | ((char *)value)[i] = logical_addr_ptr[i]; | 488 | ACPI_PHYSADDR_TO_PTR(address), |
496 | } | 489 | ACPI_DIV_8(bit_width)); |
497 | break; | 490 | break; |
498 | 491 | ||
499 | case ACPI_WRITE: | 492 | case ACPI_WRITE: |
@@ -502,5 +495,5 @@ acpi_ex_data_table_space_handler(u32 function, | |||
502 | return_ACPI_STATUS(AE_SUPPORT); | 495 | return_ACPI_STATUS(AE_SUPPORT); |
503 | } | 496 | } |
504 | 497 | ||
505 | return_ACPI_STATUS(status); | 498 | return_ACPI_STATUS(AE_OK); |
506 | } | 499 | } |
diff --git a/drivers/acpi/hardware/hwregs.c b/drivers/acpi/hardware/hwregs.c index ec9f5a11a8b3..5a3aa8dd8cb7 100644 --- a/drivers/acpi/hardware/hwregs.c +++ b/drivers/acpi/hardware/hwregs.c | |||
@@ -127,8 +127,7 @@ acpi_status | |||
127 | acpi_get_sleep_type_data(u8 sleep_state, u8 * sleep_type_a, u8 * sleep_type_b) | 127 | acpi_get_sleep_type_data(u8 sleep_state, u8 * sleep_type_a, u8 * sleep_type_b) |
128 | { | 128 | { |
129 | acpi_status status = AE_OK; | 129 | acpi_status status = AE_OK; |
130 | struct acpi_parameter_info info; | 130 | struct acpi_evaluate_info *info; |
131 | char *sleep_state_name; | ||
132 | 131 | ||
133 | ACPI_FUNCTION_TRACE(acpi_get_sleep_type_data); | 132 | ACPI_FUNCTION_TRACE(acpi_get_sleep_type_data); |
134 | 133 | ||
@@ -138,34 +137,39 @@ acpi_get_sleep_type_data(u8 sleep_state, u8 * sleep_type_a, u8 * sleep_type_b) | |||
138 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 137 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
139 | } | 138 | } |
140 | 139 | ||
141 | /* Evaluate the namespace object containing the values for this state */ | 140 | /* Allocate the evaluation information block */ |
141 | |||
142 | info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info)); | ||
143 | if (!info) { | ||
144 | return_ACPI_STATUS(AE_NO_MEMORY); | ||
145 | } | ||
142 | 146 | ||
143 | info.parameters = NULL; | 147 | info->pathname = |
144 | info.return_object = NULL; | ||
145 | sleep_state_name = | ||
146 | ACPI_CAST_PTR(char, acpi_gbl_sleep_state_names[sleep_state]); | 148 | ACPI_CAST_PTR(char, acpi_gbl_sleep_state_names[sleep_state]); |
147 | 149 | ||
148 | status = acpi_ns_evaluate_by_name(sleep_state_name, &info); | 150 | /* Evaluate the namespace object containing the values for this state */ |
151 | |||
152 | status = acpi_ns_evaluate(info); | ||
149 | if (ACPI_FAILURE(status)) { | 153 | if (ACPI_FAILURE(status)) { |
150 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | 154 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, |
151 | "%s while evaluating SleepState [%s]\n", | 155 | "%s while evaluating SleepState [%s]\n", |
152 | acpi_format_exception(status), | 156 | acpi_format_exception(status), |
153 | sleep_state_name)); | 157 | info->pathname)); |
154 | 158 | ||
155 | return_ACPI_STATUS(status); | 159 | goto cleanup; |
156 | } | 160 | } |
157 | 161 | ||
158 | /* Must have a return object */ | 162 | /* Must have a return object */ |
159 | 163 | ||
160 | if (!info.return_object) { | 164 | if (!info->return_object) { |
161 | ACPI_ERROR((AE_INFO, "No Sleep State object returned from [%s]", | 165 | ACPI_ERROR((AE_INFO, "No Sleep State object returned from [%s]", |
162 | sleep_state_name)); | 166 | info->pathname)); |
163 | status = AE_NOT_EXIST; | 167 | status = AE_NOT_EXIST; |
164 | } | 168 | } |
165 | 169 | ||
166 | /* It must be of type Package */ | 170 | /* It must be of type Package */ |
167 | 171 | ||
168 | else if (ACPI_GET_OBJECT_TYPE(info.return_object) != ACPI_TYPE_PACKAGE) { | 172 | else if (ACPI_GET_OBJECT_TYPE(info->return_object) != ACPI_TYPE_PACKAGE) { |
169 | ACPI_ERROR((AE_INFO, | 173 | ACPI_ERROR((AE_INFO, |
170 | "Sleep State return object is not a Package")); | 174 | "Sleep State return object is not a Package")); |
171 | status = AE_AML_OPERAND_TYPE; | 175 | status = AE_AML_OPERAND_TYPE; |
@@ -178,7 +182,7 @@ acpi_get_sleep_type_data(u8 sleep_state, u8 * sleep_type_a, u8 * sleep_type_b) | |||
178 | * by BIOS vendors seems to be to have 2 or more elements, at least | 182 | * by BIOS vendors seems to be to have 2 or more elements, at least |
179 | * one per sleep type (A/B). | 183 | * one per sleep type (A/B). |
180 | */ | 184 | */ |
181 | else if (info.return_object->package.count < 2) { | 185 | else if (info->return_object->package.count < 2) { |
182 | ACPI_ERROR((AE_INFO, | 186 | ACPI_ERROR((AE_INFO, |
183 | "Sleep State return package does not have at least two elements")); | 187 | "Sleep State return package does not have at least two elements")); |
184 | status = AE_AML_NO_OPERAND; | 188 | status = AE_AML_NO_OPERAND; |
@@ -186,35 +190,38 @@ acpi_get_sleep_type_data(u8 sleep_state, u8 * sleep_type_a, u8 * sleep_type_b) | |||
186 | 190 | ||
187 | /* The first two elements must both be of type Integer */ | 191 | /* The first two elements must both be of type Integer */ |
188 | 192 | ||
189 | else if ((ACPI_GET_OBJECT_TYPE(info.return_object->package.elements[0]) | 193 | else if ((ACPI_GET_OBJECT_TYPE(info->return_object->package.elements[0]) |
190 | != ACPI_TYPE_INTEGER) || | 194 | != ACPI_TYPE_INTEGER) || |
191 | (ACPI_GET_OBJECT_TYPE(info.return_object->package.elements[1]) | 195 | (ACPI_GET_OBJECT_TYPE(info->return_object->package.elements[1]) |
192 | != ACPI_TYPE_INTEGER)) { | 196 | != ACPI_TYPE_INTEGER)) { |
193 | ACPI_ERROR((AE_INFO, | 197 | ACPI_ERROR((AE_INFO, |
194 | "Sleep State return package elements are not both Integers (%s, %s)", | 198 | "Sleep State return package elements are not both Integers (%s, %s)", |
195 | acpi_ut_get_object_type_name(info.return_object-> | 199 | acpi_ut_get_object_type_name(info->return_object-> |
196 | package.elements[0]), | 200 | package.elements[0]), |
197 | acpi_ut_get_object_type_name(info.return_object-> | 201 | acpi_ut_get_object_type_name(info->return_object-> |
198 | package.elements[1]))); | 202 | package.elements[1]))); |
199 | status = AE_AML_OPERAND_TYPE; | 203 | status = AE_AML_OPERAND_TYPE; |
200 | } else { | 204 | } else { |
201 | /* Valid _Sx_ package size, type, and value */ | 205 | /* Valid _Sx_ package size, type, and value */ |
202 | 206 | ||
203 | *sleep_type_a = (u8) | 207 | *sleep_type_a = (u8) |
204 | (info.return_object->package.elements[0])->integer.value; | 208 | (info->return_object->package.elements[0])->integer.value; |
205 | *sleep_type_b = (u8) | 209 | *sleep_type_b = (u8) |
206 | (info.return_object->package.elements[1])->integer.value; | 210 | (info->return_object->package.elements[1])->integer.value; |
207 | } | 211 | } |
208 | 212 | ||
209 | if (ACPI_FAILURE(status)) { | 213 | if (ACPI_FAILURE(status)) { |
210 | ACPI_EXCEPTION((AE_INFO, status, | 214 | ACPI_EXCEPTION((AE_INFO, status, |
211 | "While evaluating SleepState [%s], bad Sleep object %p type %s", | 215 | "While evaluating SleepState [%s], bad Sleep object %p type %s", |
212 | sleep_state_name, info.return_object, | 216 | info->pathname, info->return_object, |
213 | acpi_ut_get_object_type_name(info. | 217 | acpi_ut_get_object_type_name(info-> |
214 | return_object))); | 218 | return_object))); |
215 | } | 219 | } |
216 | 220 | ||
217 | acpi_ut_remove_reference(info.return_object); | 221 | acpi_ut_remove_reference(info->return_object); |
222 | |||
223 | cleanup: | ||
224 | ACPI_FREE(info); | ||
218 | return_ACPI_STATUS(status); | 225 | return_ACPI_STATUS(status); |
219 | } | 226 | } |
220 | 227 | ||
diff --git a/drivers/acpi/namespace/nsaccess.c b/drivers/acpi/namespace/nsaccess.c index ba8ad569188f..48fadade52e2 100644 --- a/drivers/acpi/namespace/nsaccess.c +++ b/drivers/acpi/namespace/nsaccess.c | |||
@@ -259,10 +259,8 @@ acpi_status acpi_ns_root_initialize(void) | |||
259 | /* Save a handle to "_GPE", it is always present */ | 259 | /* Save a handle to "_GPE", it is always present */ |
260 | 260 | ||
261 | if (ACPI_SUCCESS(status)) { | 261 | if (ACPI_SUCCESS(status)) { |
262 | status = | 262 | status = acpi_ns_get_node(NULL, "\\_GPE", ACPI_NS_NO_UPSEARCH, |
263 | acpi_ns_get_node_by_path("\\_GPE", NULL, | 263 | &acpi_gbl_fadt_gpe_device); |
264 | ACPI_NS_NO_UPSEARCH, | ||
265 | &acpi_gbl_fadt_gpe_device); | ||
266 | } | 264 | } |
267 | 265 | ||
268 | return_ACPI_STATUS(status); | 266 | return_ACPI_STATUS(status); |
diff --git a/drivers/acpi/namespace/nseval.c b/drivers/acpi/namespace/nseval.c index 4b054062b46a..4b0a4a8c9843 100644 --- a/drivers/acpi/namespace/nseval.c +++ b/drivers/acpi/namespace/nseval.c | |||
@@ -1,7 +1,6 @@ | |||
1 | /******************************************************************************* | 1 | /******************************************************************************* |
2 | * | 2 | * |
3 | * Module Name: nseval - Object evaluation interfaces -- includes control | 3 | * Module Name: nseval - Object evaluation, includes control method execution |
4 | * method lookup and execution. | ||
5 | * | 4 | * |
6 | ******************************************************************************/ | 5 | ******************************************************************************/ |
7 | 6 | ||
@@ -50,196 +49,14 @@ | |||
50 | #define _COMPONENT ACPI_NAMESPACE | 49 | #define _COMPONENT ACPI_NAMESPACE |
51 | ACPI_MODULE_NAME("nseval") | 50 | ACPI_MODULE_NAME("nseval") |
52 | 51 | ||
53 | /* Local prototypes */ | ||
54 | static acpi_status | ||
55 | acpi_ns_execute_control_method(struct acpi_parameter_info *info); | ||
56 | |||
57 | static acpi_status acpi_ns_get_object_value(struct acpi_parameter_info *info); | ||
58 | |||
59 | /******************************************************************************* | ||
60 | * | ||
61 | * FUNCTION: acpi_ns_evaluate_relative | ||
62 | * | ||
63 | * PARAMETERS: Pathname - Name of method to execute, If NULL, the | ||
64 | * handle is the object to execute | ||
65 | * Info - Method info block, contains: | ||
66 | * return_object - Where to put method's return value (if | ||
67 | * any). If NULL, no value is returned. | ||
68 | * Params - List of parameters to pass to the method, | ||
69 | * terminated by NULL. Params itself may be | ||
70 | * NULL if no parameters are being passed. | ||
71 | * | ||
72 | * RETURN: Status | ||
73 | * | ||
74 | * DESCRIPTION: Evaluate the object or find and execute the requested method | ||
75 | * | ||
76 | * MUTEX: Locks Namespace | ||
77 | * | ||
78 | ******************************************************************************/ | ||
79 | |||
80 | acpi_status | ||
81 | acpi_ns_evaluate_relative(char *pathname, struct acpi_parameter_info *info) | ||
82 | { | ||
83 | acpi_status status; | ||
84 | struct acpi_namespace_node *node = NULL; | ||
85 | union acpi_generic_state *scope_info; | ||
86 | char *internal_path = NULL; | ||
87 | |||
88 | ACPI_FUNCTION_TRACE(ns_evaluate_relative); | ||
89 | |||
90 | /* | ||
91 | * Must have a valid object handle | ||
92 | */ | ||
93 | if (!info || !info->node) { | ||
94 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
95 | } | ||
96 | |||
97 | /* Build an internal name string for the method */ | ||
98 | |||
99 | status = acpi_ns_internalize_name(pathname, &internal_path); | ||
100 | if (ACPI_FAILURE(status)) { | ||
101 | return_ACPI_STATUS(status); | ||
102 | } | ||
103 | |||
104 | scope_info = acpi_ut_create_generic_state(); | ||
105 | if (!scope_info) { | ||
106 | goto cleanup1; | ||
107 | } | ||
108 | |||
109 | /* Get the prefix handle and Node */ | ||
110 | |||
111 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | ||
112 | if (ACPI_FAILURE(status)) { | ||
113 | goto cleanup; | ||
114 | } | ||
115 | |||
116 | info->node = acpi_ns_map_handle_to_node(info->node); | ||
117 | if (!info->node) { | ||
118 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | ||
119 | status = AE_BAD_PARAMETER; | ||
120 | goto cleanup; | ||
121 | } | ||
122 | |||
123 | /* Lookup the name in the namespace */ | ||
124 | |||
125 | scope_info->scope.node = info->node; | ||
126 | status = acpi_ns_lookup(scope_info, internal_path, ACPI_TYPE_ANY, | ||
127 | ACPI_IMODE_EXECUTE, ACPI_NS_NO_UPSEARCH, NULL, | ||
128 | &node); | ||
129 | |||
130 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | ||
131 | |||
132 | if (ACPI_FAILURE(status)) { | ||
133 | ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "Object [%s] not found [%s]\n", | ||
134 | pathname, acpi_format_exception(status))); | ||
135 | goto cleanup; | ||
136 | } | ||
137 | |||
138 | /* | ||
139 | * Now that we have a handle to the object, we can attempt to evaluate it. | ||
140 | */ | ||
141 | ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "%s [%p] Value %p\n", | ||
142 | pathname, node, acpi_ns_get_attached_object(node))); | ||
143 | |||
144 | info->node = node; | ||
145 | status = acpi_ns_evaluate_by_handle(info); | ||
146 | |||
147 | ACPI_DEBUG_PRINT((ACPI_DB_NAMES, | ||
148 | "*** Completed eval of object %s ***\n", pathname)); | ||
149 | |||
150 | cleanup: | ||
151 | acpi_ut_delete_generic_state(scope_info); | ||
152 | |||
153 | cleanup1: | ||
154 | ACPI_FREE(internal_path); | ||
155 | return_ACPI_STATUS(status); | ||
156 | } | ||
157 | |||
158 | /******************************************************************************* | ||
159 | * | ||
160 | * FUNCTION: acpi_ns_evaluate_by_name | ||
161 | * | ||
162 | * PARAMETERS: Pathname - Fully qualified pathname to the object | ||
163 | * Info - Method info block, contains: | ||
164 | * return_object - Where to put method's return value (if | ||
165 | * any). If NULL, no value is returned. | ||
166 | * Params - List of parameters to pass to the method, | ||
167 | * terminated by NULL. Params itself may be | ||
168 | * NULL if no parameters are being passed. | ||
169 | * | ||
170 | * RETURN: Status | ||
171 | * | ||
172 | * DESCRIPTION: Evaluate the object or rind and execute the requested method | ||
173 | * passing the given parameters | ||
174 | * | ||
175 | * MUTEX: Locks Namespace | ||
176 | * | ||
177 | ******************************************************************************/ | ||
178 | |||
179 | acpi_status | ||
180 | acpi_ns_evaluate_by_name(char *pathname, struct acpi_parameter_info *info) | ||
181 | { | ||
182 | acpi_status status; | ||
183 | char *internal_path = NULL; | ||
184 | |||
185 | ACPI_FUNCTION_TRACE(ns_evaluate_by_name); | ||
186 | |||
187 | /* Build an internal name string for the method */ | ||
188 | |||
189 | status = acpi_ns_internalize_name(pathname, &internal_path); | ||
190 | if (ACPI_FAILURE(status)) { | ||
191 | return_ACPI_STATUS(status); | ||
192 | } | ||
193 | |||
194 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | ||
195 | if (ACPI_FAILURE(status)) { | ||
196 | goto cleanup; | ||
197 | } | ||
198 | |||
199 | /* Lookup the name in the namespace */ | ||
200 | |||
201 | status = acpi_ns_lookup(NULL, internal_path, ACPI_TYPE_ANY, | ||
202 | ACPI_IMODE_EXECUTE, ACPI_NS_NO_UPSEARCH, NULL, | ||
203 | &info->node); | ||
204 | |||
205 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | ||
206 | |||
207 | if (ACPI_FAILURE(status)) { | ||
208 | ACPI_DEBUG_PRINT((ACPI_DB_NAMES, | ||
209 | "Object at [%s] was not found, status=%.4X\n", | ||
210 | pathname, status)); | ||
211 | goto cleanup; | ||
212 | } | ||
213 | |||
214 | /* | ||
215 | * Now that we have a handle to the object, we can attempt to evaluate it. | ||
216 | */ | ||
217 | ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "%s [%p] Value %p\n", | ||
218 | pathname, info->node, | ||
219 | acpi_ns_get_attached_object(info->node))); | ||
220 | |||
221 | status = acpi_ns_evaluate_by_handle(info); | ||
222 | |||
223 | ACPI_DEBUG_PRINT((ACPI_DB_NAMES, | ||
224 | "*** Completed eval of object %s ***\n", pathname)); | ||
225 | |||
226 | cleanup: | ||
227 | |||
228 | /* Cleanup */ | ||
229 | |||
230 | if (internal_path) { | ||
231 | ACPI_FREE(internal_path); | ||
232 | } | ||
233 | |||
234 | return_ACPI_STATUS(status); | ||
235 | } | ||
236 | |||
237 | /******************************************************************************* | 52 | /******************************************************************************* |
238 | * | 53 | * |
239 | * FUNCTION: acpi_ns_evaluate_by_handle | 54 | * FUNCTION: acpi_ns_evaluate |
240 | * | 55 | * |
241 | * PARAMETERS: Info - Method info block, contains: | 56 | * PARAMETERS: Info - Evaluation info block, contains: |
242 | * Node - Method/Object Node to execute | 57 | * prefix_node - Prefix or Method/Object Node to execute |
58 | * Pathname - Name of method to execute, If NULL, the | ||
59 | * Node is the object to execute | ||
243 | * Parameters - List of parameters to pass to the method, | 60 | * Parameters - List of parameters to pass to the method, |
244 | * terminated by NULL. Params itself may be | 61 | * terminated by NULL. Params itself may be |
245 | * NULL if no parameters are being passed. | 62 | * NULL if no parameters are being passed. |
@@ -248,29 +65,21 @@ acpi_ns_evaluate_by_name(char *pathname, struct acpi_parameter_info *info) | |||
248 | * parameter_type - Type of Parameter list | 65 | * parameter_type - Type of Parameter list |
249 | * return_object - Where to put method's return value (if | 66 | * return_object - Where to put method's return value (if |
250 | * any). If NULL, no value is returned. | 67 | * any). If NULL, no value is returned. |
68 | * Flags - ACPI_IGNORE_RETURN_VALUE to delete return | ||
251 | * | 69 | * |
252 | * RETURN: Status | 70 | * RETURN: Status |
253 | * | 71 | * |
254 | * DESCRIPTION: Evaluate object or execute the requested method passing the | 72 | * DESCRIPTION: Execute a control method or return the current value of an |
255 | * given parameters | 73 | * ACPI namespace object. |
256 | * | 74 | * |
257 | * MUTEX: Locks Namespace | 75 | * MUTEX: Locks interpreter |
258 | * | 76 | * |
259 | ******************************************************************************/ | 77 | ******************************************************************************/ |
260 | 78 | acpi_status acpi_ns_evaluate(struct acpi_evaluate_info *info) | |
261 | acpi_status acpi_ns_evaluate_by_handle(struct acpi_parameter_info *info) | ||
262 | { | 79 | { |
263 | acpi_status status; | 80 | acpi_status status; |
264 | 81 | ||
265 | ACPI_FUNCTION_TRACE(ns_evaluate_by_handle); | 82 | ACPI_FUNCTION_TRACE(ns_evaluate); |
266 | |||
267 | /* Check if namespace has been initialized */ | ||
268 | |||
269 | if (!acpi_gbl_root_node) { | ||
270 | return_ACPI_STATUS(AE_NO_NAMESPACE); | ||
271 | } | ||
272 | |||
273 | /* Parameter Validation */ | ||
274 | 83 | ||
275 | if (!info) { | 84 | if (!info) { |
276 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 85 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
@@ -280,203 +89,120 @@ acpi_status acpi_ns_evaluate_by_handle(struct acpi_parameter_info *info) | |||
280 | 89 | ||
281 | info->return_object = NULL; | 90 | info->return_object = NULL; |
282 | 91 | ||
283 | /* Get the prefix handle and Node */ | 92 | /* |
284 | 93 | * Get the actual namespace node for the target object. Handles these cases: | |
285 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | 94 | * |
95 | * 1) Null node, Pathname (absolute path) | ||
96 | * 2) Node, Pathname (path relative to Node) | ||
97 | * 3) Node, Null Pathname | ||
98 | */ | ||
99 | status = acpi_ns_get_node(info->prefix_node, info->pathname, | ||
100 | ACPI_NS_NO_UPSEARCH, &info->resolved_node); | ||
286 | if (ACPI_FAILURE(status)) { | 101 | if (ACPI_FAILURE(status)) { |
287 | return_ACPI_STATUS(status); | 102 | return_ACPI_STATUS(status); |
288 | } | 103 | } |
289 | 104 | ||
290 | info->node = acpi_ns_map_handle_to_node(info->node); | ||
291 | if (!info->node) { | ||
292 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | ||
293 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
294 | } | ||
295 | |||
296 | /* | 105 | /* |
297 | * For a method alias, we must grab the actual method node so that proper | 106 | * For a method alias, we must grab the actual method node so that proper |
298 | * scoping context will be established before execution. | 107 | * scoping context will be established before execution. |
299 | */ | 108 | */ |
300 | if (acpi_ns_get_type(info->node) == ACPI_TYPE_LOCAL_METHOD_ALIAS) { | 109 | if (acpi_ns_get_type(info->resolved_node) == |
301 | info->node = | 110 | ACPI_TYPE_LOCAL_METHOD_ALIAS) { |
111 | info->resolved_node = | ||
302 | ACPI_CAST_PTR(struct acpi_namespace_node, | 112 | ACPI_CAST_PTR(struct acpi_namespace_node, |
303 | info->node->object); | 113 | info->resolved_node->object); |
304 | } | 114 | } |
305 | 115 | ||
116 | ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "%s [%p] Value %p\n", info->pathname, | ||
117 | info->resolved_node, | ||
118 | acpi_ns_get_attached_object(info->resolved_node))); | ||
119 | |||
306 | /* | 120 | /* |
307 | * Two major cases here: | 121 | * Two major cases here: |
308 | * 1) The object is an actual control method -- execute it. | ||
309 | * 2) The object is not a method -- just return it's current value | ||
310 | * | 122 | * |
311 | * In both cases, the namespace is unlocked by the acpi_ns* procedure | 123 | * 1) The object is a control method -- execute it |
124 | * 2) The object is not a method -- just return it's current value | ||
312 | */ | 125 | */ |
313 | if (acpi_ns_get_type(info->node) == ACPI_TYPE_METHOD) { | 126 | if (acpi_ns_get_type(info->resolved_node) == ACPI_TYPE_METHOD) { |
314 | /* | 127 | /* |
315 | * Case 1) We have an actual control method to execute | 128 | * 1) Object is a control method - execute it |
316 | */ | 129 | */ |
317 | status = acpi_ns_execute_control_method(info); | ||
318 | } else { | ||
319 | /* | ||
320 | * Case 2) Object is NOT a method, just return its current value | ||
321 | */ | ||
322 | status = acpi_ns_get_object_value(info); | ||
323 | } | ||
324 | |||
325 | /* | ||
326 | * Check if there is a return value on the stack that must be dealt with | ||
327 | */ | ||
328 | if (status == AE_CTRL_RETURN_VALUE) { | ||
329 | |||
330 | /* Map AE_CTRL_RETURN_VALUE to AE_OK, we are done with it */ | ||
331 | |||
332 | status = AE_OK; | ||
333 | } | ||
334 | |||
335 | /* | ||
336 | * Namespace was unlocked by the handling acpi_ns* function, so we | ||
337 | * just return | ||
338 | */ | ||
339 | return_ACPI_STATUS(status); | ||
340 | } | ||
341 | |||
342 | /******************************************************************************* | ||
343 | * | ||
344 | * FUNCTION: acpi_ns_execute_control_method | ||
345 | * | ||
346 | * PARAMETERS: Info - Method info block, contains: | ||
347 | * Node - Method Node to execute | ||
348 | * obj_desc - Method object | ||
349 | * Parameters - List of parameters to pass to the method, | ||
350 | * terminated by NULL. Params itself may be | ||
351 | * NULL if no parameters are being passed. | ||
352 | * return_object - Where to put method's return value (if | ||
353 | * any). If NULL, no value is returned. | ||
354 | * parameter_type - Type of Parameter list | ||
355 | * return_object - Where to put method's return value (if | ||
356 | * any). If NULL, no value is returned. | ||
357 | * | ||
358 | * RETURN: Status | ||
359 | * | ||
360 | * DESCRIPTION: Execute the requested method passing the given parameters | ||
361 | * | ||
362 | * MUTEX: Assumes namespace is locked | ||
363 | * | ||
364 | ******************************************************************************/ | ||
365 | |||
366 | static acpi_status | ||
367 | acpi_ns_execute_control_method(struct acpi_parameter_info *info) | ||
368 | { | ||
369 | acpi_status status; | ||
370 | |||
371 | ACPI_FUNCTION_TRACE(ns_execute_control_method); | ||
372 | |||
373 | /* Verify that there is a method associated with this object */ | ||
374 | |||
375 | info->obj_desc = acpi_ns_get_attached_object(info->node); | ||
376 | if (!info->obj_desc) { | ||
377 | ACPI_ERROR((AE_INFO, "No attached method object")); | ||
378 | 130 | ||
379 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | 131 | /* Verify that there is a method object associated with this node */ |
380 | return_ACPI_STATUS(AE_NULL_OBJECT); | ||
381 | } | ||
382 | |||
383 | ACPI_DUMP_PATHNAME(info->node, "Execute Method:", | ||
384 | ACPI_LV_INFO, _COMPONENT); | ||
385 | |||
386 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Method at AML address %p Length %X\n", | ||
387 | info->obj_desc->method.aml_start + 1, | ||
388 | info->obj_desc->method.aml_length - 1)); | ||
389 | |||
390 | /* | ||
391 | * Unlock the namespace before execution. This allows namespace access | ||
392 | * via the external Acpi* interfaces while a method is being executed. | ||
393 | * However, any namespace deletion must acquire both the namespace and | ||
394 | * interpreter locks to ensure that no thread is using the portion of the | ||
395 | * namespace that is being deleted. | ||
396 | */ | ||
397 | status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | ||
398 | if (ACPI_FAILURE(status)) { | ||
399 | return_ACPI_STATUS(status); | ||
400 | } | ||
401 | 132 | ||
402 | /* | 133 | info->obj_desc = |
403 | * Execute the method via the interpreter. The interpreter is locked | 134 | acpi_ns_get_attached_object(info->resolved_node); |
404 | * here before calling into the AML parser | 135 | if (!info->obj_desc) { |
405 | */ | 136 | ACPI_ERROR((AE_INFO, |
406 | status = acpi_ex_enter_interpreter(); | 137 | "Control method has no attached sub-object")); |
407 | if (ACPI_FAILURE(status)) { | 138 | return_ACPI_STATUS(AE_NULL_OBJECT); |
408 | return_ACPI_STATUS(status); | 139 | } |
409 | } | ||
410 | 140 | ||
411 | status = acpi_ps_execute_method(info); | 141 | ACPI_DUMP_PATHNAME(info->resolved_node, "Execute Method:", |
412 | acpi_ex_exit_interpreter(); | 142 | ACPI_LV_INFO, _COMPONENT); |
413 | 143 | ||
414 | return_ACPI_STATUS(status); | 144 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, |
415 | } | 145 | "Method at AML address %p Length %X\n", |
146 | info->obj_desc->method.aml_start + 1, | ||
147 | info->obj_desc->method.aml_length - 1)); | ||
416 | 148 | ||
417 | /******************************************************************************* | 149 | /* |
418 | * | 150 | * Any namespace deletion must acquire both the namespace and |
419 | * FUNCTION: acpi_ns_get_object_value | 151 | * interpreter locks to ensure that no thread is using the portion of |
420 | * | 152 | * the namespace that is being deleted. |
421 | * PARAMETERS: Info - Method info block, contains: | 153 | * |
422 | * Node - Object's NS node | 154 | * Execute the method via the interpreter. The interpreter is locked |
423 | * return_object - Where to put object value (if | 155 | * here before calling into the AML parser |
424 | * any). If NULL, no value is returned. | 156 | */ |
425 | * | 157 | status = acpi_ex_enter_interpreter(); |
426 | * RETURN: Status | 158 | if (ACPI_FAILURE(status)) { |
427 | * | 159 | return_ACPI_STATUS(status); |
428 | * DESCRIPTION: Return the current value of the object | 160 | } |
429 | * | ||
430 | * MUTEX: Assumes namespace is locked, leaves namespace unlocked | ||
431 | * | ||
432 | ******************************************************************************/ | ||
433 | 161 | ||
434 | static acpi_status acpi_ns_get_object_value(struct acpi_parameter_info *info) | 162 | status = acpi_ps_execute_method(info); |
435 | { | 163 | acpi_ex_exit_interpreter(); |
436 | acpi_status status = AE_OK; | 164 | } else { |
437 | struct acpi_namespace_node *resolved_node = info->node; | 165 | /* |
166 | * 2) Object is not a method, return its current value | ||
167 | */ | ||
438 | 168 | ||
439 | ACPI_FUNCTION_TRACE(ns_get_object_value); | 169 | /* |
170 | * Objects require additional resolution steps (e.g., the Node may be | ||
171 | * a field that must be read, etc.) -- we can't just grab the object | ||
172 | * out of the node. | ||
173 | * | ||
174 | * Use resolve_node_to_value() to get the associated value. | ||
175 | * | ||
176 | * NOTE: we can get away with passing in NULL for a walk state because | ||
177 | * resolved_node is guaranteed to not be a reference to either a method | ||
178 | * local or a method argument (because this interface is never called | ||
179 | * from a running method.) | ||
180 | * | ||
181 | * Even though we do not directly invoke the interpreter for object | ||
182 | * resolution, we must lock it because we could access an opregion. | ||
183 | * The opregion access code assumes that the interpreter is locked. | ||
184 | */ | ||
185 | status = acpi_ex_enter_interpreter(); | ||
186 | if (ACPI_FAILURE(status)) { | ||
187 | return_ACPI_STATUS(status); | ||
188 | } | ||
440 | 189 | ||
441 | /* | 190 | /* Function has a strange interface */ |
442 | * Objects require additional resolution steps (e.g., the Node may be a | ||
443 | * field that must be read, etc.) -- we can't just grab the object out of | ||
444 | * the node. | ||
445 | */ | ||
446 | 191 | ||
447 | /* | 192 | status = |
448 | * Use resolve_node_to_value() to get the associated value. This call always | 193 | acpi_ex_resolve_node_to_value(&info->resolved_node, NULL); |
449 | * deletes obj_desc (allocated above). | 194 | acpi_ex_exit_interpreter(); |
450 | * | ||
451 | * NOTE: we can get away with passing in NULL for a walk state because | ||
452 | * obj_desc is guaranteed to not be a reference to either a method local or | ||
453 | * a method argument (because this interface can only be called from the | ||
454 | * acpi_evaluate external interface, never called from a running method.) | ||
455 | * | ||
456 | * Even though we do not directly invoke the interpreter for this, we must | ||
457 | * enter it because we could access an opregion. The opregion access code | ||
458 | * assumes that the interpreter is locked. | ||
459 | * | ||
460 | * We must release the namespace lock before entering the intepreter. | ||
461 | */ | ||
462 | status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | ||
463 | if (ACPI_FAILURE(status)) { | ||
464 | return_ACPI_STATUS(status); | ||
465 | } | ||
466 | 195 | ||
467 | status = acpi_ex_enter_interpreter(); | ||
468 | if (ACPI_SUCCESS(status)) { | ||
469 | status = acpi_ex_resolve_node_to_value(&resolved_node, NULL); | ||
470 | /* | 196 | /* |
471 | * If acpi_ex_resolve_node_to_value() succeeded, the return value was placed | 197 | * If acpi_ex_resolve_node_to_value() succeeded, the return value was placed |
472 | * in resolved_node. | 198 | * in resolved_node. |
473 | */ | 199 | */ |
474 | acpi_ex_exit_interpreter(); | ||
475 | |||
476 | if (ACPI_SUCCESS(status)) { | 200 | if (ACPI_SUCCESS(status)) { |
477 | status = AE_CTRL_RETURN_VALUE; | 201 | status = AE_CTRL_RETURN_VALUE; |
478 | info->return_object = ACPI_CAST_PTR | 202 | info->return_object = |
479 | (union acpi_operand_object, resolved_node); | 203 | ACPI_CAST_PTR(union acpi_operand_object, |
204 | info->resolved_node); | ||
205 | |||
480 | ACPI_DEBUG_PRINT((ACPI_DB_NAMES, | 206 | ACPI_DEBUG_PRINT((ACPI_DB_NAMES, |
481 | "Returning object %p [%s]\n", | 207 | "Returning object %p [%s]\n", |
482 | info->return_object, | 208 | info->return_object, |
@@ -485,7 +211,30 @@ static acpi_status acpi_ns_get_object_value(struct acpi_parameter_info *info) | |||
485 | } | 211 | } |
486 | } | 212 | } |
487 | 213 | ||
488 | /* Namespace is unlocked */ | 214 | /* |
215 | * Check if there is a return value that must be dealt with | ||
216 | */ | ||
217 | if (status == AE_CTRL_RETURN_VALUE) { | ||
218 | |||
219 | /* If caller does not want the return value, delete it */ | ||
489 | 220 | ||
221 | if (info->flags & ACPI_IGNORE_RETURN_VALUE) { | ||
222 | acpi_ut_remove_reference(info->return_object); | ||
223 | info->return_object = NULL; | ||
224 | } | ||
225 | |||
226 | /* Map AE_CTRL_RETURN_VALUE to AE_OK, we are done with it */ | ||
227 | |||
228 | status = AE_OK; | ||
229 | } | ||
230 | |||
231 | ACPI_DEBUG_PRINT((ACPI_DB_NAMES, | ||
232 | "*** Completed evaluation of object %s ***\n", | ||
233 | info->pathname)); | ||
234 | |||
235 | /* | ||
236 | * Namespace was unlocked by the handling acpi_ns* function, so we | ||
237 | * just return | ||
238 | */ | ||
490 | return_ACPI_STATUS(status); | 239 | return_ACPI_STATUS(status); |
491 | } | 240 | } |
diff --git a/drivers/acpi/namespace/nsinit.c b/drivers/acpi/namespace/nsinit.c index bf1d8dbc0b86..1c9ca6e05314 100644 --- a/drivers/acpi/namespace/nsinit.c +++ b/drivers/acpi/namespace/nsinit.c | |||
@@ -154,7 +154,16 @@ acpi_status acpi_ns_initialize_devices(void) | |||
154 | ACPI_UINT32_MAX, FALSE, | 154 | ACPI_UINT32_MAX, FALSE, |
155 | acpi_ns_find_ini_methods, &info, NULL); | 155 | acpi_ns_find_ini_methods, &info, NULL); |
156 | if (ACPI_FAILURE(status)) { | 156 | if (ACPI_FAILURE(status)) { |
157 | ACPI_EXCEPTION((AE_INFO, status, "During WalkNamespace")); | 157 | goto error_exit; |
158 | } | ||
159 | |||
160 | /* Allocate the evaluation information block */ | ||
161 | |||
162 | info.evaluate_info = | ||
163 | ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info)); | ||
164 | if (!info.evaluate_info) { | ||
165 | status = AE_NO_MEMORY; | ||
166 | goto error_exit; | ||
158 | } | 167 | } |
159 | 168 | ||
160 | /* Walk namespace to execute all _INIs on present devices */ | 169 | /* Walk namespace to execute all _INIs on present devices */ |
@@ -162,8 +171,10 @@ acpi_status acpi_ns_initialize_devices(void) | |||
162 | status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, | 171 | status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, |
163 | ACPI_UINT32_MAX, FALSE, | 172 | ACPI_UINT32_MAX, FALSE, |
164 | acpi_ns_init_one_device, &info, NULL); | 173 | acpi_ns_init_one_device, &info, NULL); |
174 | |||
175 | ACPI_FREE(info.evaluate_info); | ||
165 | if (ACPI_FAILURE(status)) { | 176 | if (ACPI_FAILURE(status)) { |
166 | ACPI_EXCEPTION((AE_INFO, status, "During WalkNamespace")); | 177 | goto error_exit; |
167 | } | 178 | } |
168 | 179 | ||
169 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, | 180 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, |
@@ -171,6 +182,10 @@ acpi_status acpi_ns_initialize_devices(void) | |||
171 | info.num_INI, info.num_STA, info.device_count)); | 182 | info.num_INI, info.num_STA, info.device_count)); |
172 | 183 | ||
173 | return_ACPI_STATUS(status); | 184 | return_ACPI_STATUS(status); |
185 | |||
186 | error_exit: | ||
187 | ACPI_EXCEPTION((AE_INFO, status, "During device initialization")); | ||
188 | return_ACPI_STATUS(status); | ||
174 | } | 189 | } |
175 | 190 | ||
176 | /******************************************************************************* | 191 | /******************************************************************************* |
@@ -398,9 +413,9 @@ static acpi_status | |||
398 | acpi_ns_init_one_device(acpi_handle obj_handle, | 413 | acpi_ns_init_one_device(acpi_handle obj_handle, |
399 | u32 nesting_level, void *context, void **return_value) | 414 | u32 nesting_level, void *context, void **return_value) |
400 | { | 415 | { |
401 | struct acpi_device_walk_info *info = | 416 | struct acpi_device_walk_info *walk_info = |
402 | ACPI_CAST_PTR(struct acpi_device_walk_info, context); | 417 | ACPI_CAST_PTR(struct acpi_device_walk_info, context); |
403 | struct acpi_parameter_info pinfo; | 418 | struct acpi_evaluate_info *info = walk_info->evaluate_info; |
404 | u32 flags; | 419 | u32 flags; |
405 | acpi_status status; | 420 | acpi_status status; |
406 | struct acpi_namespace_node *device_node; | 421 | struct acpi_namespace_node *device_node; |
@@ -460,7 +475,7 @@ acpi_ns_init_one_device(acpi_handle obj_handle, | |||
460 | * other words, the device is present, ..., and functioning)" | 475 | * other words, the device is present, ..., and functioning)" |
461 | */ | 476 | */ |
462 | if (flags != ACPI_UINT32_MAX) { | 477 | if (flags != ACPI_UINT32_MAX) { |
463 | info->num_STA++; | 478 | walk_info->num_STA++; |
464 | } | 479 | } |
465 | 480 | ||
466 | /* | 481 | /* |
@@ -516,20 +531,16 @@ acpi_ns_init_one_device(acpi_handle obj_handle, | |||
516 | ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname | 531 | ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname |
517 | (ACPI_TYPE_METHOD, device_node, METHOD_NAME__INI)); | 532 | (ACPI_TYPE_METHOD, device_node, METHOD_NAME__INI)); |
518 | 533 | ||
519 | pinfo.node = device_node; | 534 | info->prefix_node = device_node; |
520 | pinfo.parameters = NULL; | 535 | info->pathname = METHOD_NAME__INI; |
521 | pinfo.parameter_type = ACPI_PARAM_ARGS; | 536 | info->parameters = NULL; |
537 | info->parameter_type = ACPI_PARAM_ARGS; | ||
538 | info->flags = ACPI_IGNORE_RETURN_VALUE; | ||
522 | 539 | ||
523 | status = acpi_ns_evaluate_relative(METHOD_NAME__INI, &pinfo); | 540 | status = acpi_ns_evaluate(info); |
524 | if (ACPI_SUCCESS(status)) { | 541 | if (ACPI_SUCCESS(status)) { |
542 | walk_info->num_INI++; | ||
525 | 543 | ||
526 | /* Delete any return object (especially if implicit_return is enabled) */ | ||
527 | |||
528 | if (pinfo.return_object) { | ||
529 | acpi_ut_remove_reference(pinfo.return_object); | ||
530 | } | ||
531 | |||
532 | info->num_INI++; | ||
533 | if ((acpi_dbg_level <= ACPI_LV_ALL_EXCEPTIONS) && | 544 | if ((acpi_dbg_level <= ACPI_LV_ALL_EXCEPTIONS) && |
534 | (!(acpi_dbg_level & ACPI_LV_INFO))) { | 545 | (!(acpi_dbg_level & ACPI_LV_INFO))) { |
535 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, ".")); | 546 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, ".")); |
@@ -540,20 +551,24 @@ acpi_ns_init_one_device(acpi_handle obj_handle, | |||
540 | 551 | ||
541 | /* Ignore error and move on to next device */ | 552 | /* Ignore error and move on to next device */ |
542 | 553 | ||
543 | char *scope_name = acpi_ns_get_external_pathname(pinfo.node); | 554 | char *scope_name = |
555 | acpi_ns_get_external_pathname(info->resolved_node); | ||
544 | 556 | ||
545 | ACPI_EXCEPTION((AE_INFO, status, "during %s._INI execution", | 557 | ACPI_EXCEPTION((AE_INFO, status, "during %s._INI execution", |
546 | scope_name)); | 558 | scope_name)); |
547 | ACPI_FREE(scope_name); | 559 | ACPI_FREE(scope_name); |
560 | status = AE_OK; | ||
548 | } | 561 | } |
549 | #endif | 562 | #endif |
550 | 563 | ||
551 | /* If an external initialization handler is present, call it */ | 564 | /* |
552 | 565 | * The _INI method has been run if present; call the Global Initialization | |
566 | * Handler for this device. | ||
567 | */ | ||
553 | if (acpi_gbl_init_handler) { | 568 | if (acpi_gbl_init_handler) { |
554 | status = | 569 | status = |
555 | acpi_gbl_init_handler(pinfo.node, ACPI_INIT_DEVICE_INI); | 570 | acpi_gbl_init_handler(device_node, ACPI_INIT_DEVICE_INI); |
556 | } | 571 | } |
557 | 572 | ||
558 | return_ACPI_STATUS(AE_OK); | 573 | return_ACPI_STATUS(status); |
559 | } | 574 | } |
diff --git a/drivers/acpi/namespace/nssearch.c b/drivers/acpi/namespace/nssearch.c index d2473476afa5..500e2bbcfaf7 100644 --- a/drivers/acpi/namespace/nssearch.c +++ b/drivers/acpi/namespace/nssearch.c | |||
@@ -56,16 +56,16 @@ acpi_ns_search_parent_tree(u32 target_name, | |||
56 | 56 | ||
57 | /******************************************************************************* | 57 | /******************************************************************************* |
58 | * | 58 | * |
59 | * FUNCTION: acpi_ns_search_node | 59 | * FUNCTION: acpi_ns_search_one_scope |
60 | * | 60 | * |
61 | * PARAMETERS: target_name - Ascii ACPI name to search for | 61 | * PARAMETERS: target_name - Ascii ACPI name to search for |
62 | * Node - Starting node where search will begin | 62 | * parent_node - Starting node where search will begin |
63 | * Type - Object type to match | 63 | * Type - Object type to match |
64 | * return_node - Where the matched Named obj is returned | 64 | * return_node - Where the matched Named obj is returned |
65 | * | 65 | * |
66 | * RETURN: Status | 66 | * RETURN: Status |
67 | * | 67 | * |
68 | * DESCRIPTION: Search a single level of the namespace. Performs a | 68 | * DESCRIPTION: Search a single level of the namespace. Performs a |
69 | * simple search of the specified level, and does not add | 69 | * simple search of the specified level, and does not add |
70 | * entries or search parents. | 70 | * entries or search parents. |
71 | * | 71 | * |
@@ -75,32 +75,37 @@ acpi_ns_search_parent_tree(u32 target_name, | |||
75 | * | 75 | * |
76 | * All namespace searching is linear in this implementation, but | 76 | * All namespace searching is linear in this implementation, but |
77 | * could be easily modified to support any improved search | 77 | * could be easily modified to support any improved search |
78 | * algorithm. However, the linear search was chosen for simplicity | 78 | * algorithm. However, the linear search was chosen for simplicity |
79 | * and because the trees are small and the other interpreter | 79 | * and because the trees are small and the other interpreter |
80 | * execution overhead is relatively high. | 80 | * execution overhead is relatively high. |
81 | * | 81 | * |
82 | * Note: CPU execution analysis has shown that the AML interpreter spends | ||
83 | * a very small percentage of its time searching the namespace. Therefore, | ||
84 | * the linear search seems to be sufficient, as there would seem to be | ||
85 | * little value in improving the search. | ||
86 | * | ||
82 | ******************************************************************************/ | 87 | ******************************************************************************/ |
83 | 88 | ||
84 | acpi_status | 89 | acpi_status |
85 | acpi_ns_search_node(u32 target_name, | 90 | acpi_ns_search_one_scope(u32 target_name, |
86 | struct acpi_namespace_node *node, | 91 | struct acpi_namespace_node *parent_node, |
87 | acpi_object_type type, | 92 | acpi_object_type type, |
88 | struct acpi_namespace_node **return_node) | 93 | struct acpi_namespace_node **return_node) |
89 | { | 94 | { |
90 | struct acpi_namespace_node *next_node; | 95 | struct acpi_namespace_node *node; |
91 | 96 | ||
92 | ACPI_FUNCTION_TRACE(ns_search_node); | 97 | ACPI_FUNCTION_TRACE(ns_search_one_scope); |
93 | 98 | ||
94 | #ifdef ACPI_DEBUG_OUTPUT | 99 | #ifdef ACPI_DEBUG_OUTPUT |
95 | if (ACPI_LV_NAMES & acpi_dbg_level) { | 100 | if (ACPI_LV_NAMES & acpi_dbg_level) { |
96 | char *scope_name; | 101 | char *scope_name; |
97 | 102 | ||
98 | scope_name = acpi_ns_get_external_pathname(node); | 103 | scope_name = acpi_ns_get_external_pathname(parent_node); |
99 | if (scope_name) { | 104 | if (scope_name) { |
100 | ACPI_DEBUG_PRINT((ACPI_DB_NAMES, | 105 | ACPI_DEBUG_PRINT((ACPI_DB_NAMES, |
101 | "Searching %s (%p) For [%4.4s] (%s)\n", | 106 | "Searching %s (%p) For [%4.4s] (%s)\n", |
102 | scope_name, node, ACPI_CAST_PTR(char, | 107 | scope_name, parent_node, |
103 | &target_name), | 108 | ACPI_CAST_PTR(char, &target_name), |
104 | acpi_ut_get_type_name(type))); | 109 | acpi_ut_get_type_name(type))); |
105 | 110 | ||
106 | ACPI_FREE(scope_name); | 111 | ACPI_FREE(scope_name); |
@@ -112,20 +117,20 @@ acpi_ns_search_node(u32 target_name, | |||
112 | * Search for name at this namespace level, which is to say that we | 117 | * Search for name at this namespace level, which is to say that we |
113 | * must search for the name among the children of this object | 118 | * must search for the name among the children of this object |
114 | */ | 119 | */ |
115 | next_node = node->child; | 120 | node = parent_node->child; |
116 | while (next_node) { | 121 | while (node) { |
117 | 122 | ||
118 | /* Check for match against the name */ | 123 | /* Check for match against the name */ |
119 | 124 | ||
120 | if (next_node->name.integer == target_name) { | 125 | if (node->name.integer == target_name) { |
121 | 126 | ||
122 | /* Resolve a control method alias if any */ | 127 | /* Resolve a control method alias if any */ |
123 | 128 | ||
124 | if (acpi_ns_get_type(next_node) == | 129 | if (acpi_ns_get_type(node) == |
125 | ACPI_TYPE_LOCAL_METHOD_ALIAS) { | 130 | ACPI_TYPE_LOCAL_METHOD_ALIAS) { |
126 | next_node = | 131 | node = |
127 | ACPI_CAST_PTR(struct acpi_namespace_node, | 132 | ACPI_CAST_PTR(struct acpi_namespace_node, |
128 | next_node->object); | 133 | node->object); |
129 | } | 134 | } |
130 | 135 | ||
131 | /* Found matching entry */ | 136 | /* Found matching entry */ |
@@ -133,12 +138,12 @@ acpi_ns_search_node(u32 target_name, | |||
133 | ACPI_DEBUG_PRINT((ACPI_DB_NAMES, | 138 | ACPI_DEBUG_PRINT((ACPI_DB_NAMES, |
134 | "Name [%4.4s] (%s) %p found in scope [%4.4s] %p\n", | 139 | "Name [%4.4s] (%s) %p found in scope [%4.4s] %p\n", |
135 | ACPI_CAST_PTR(char, &target_name), | 140 | ACPI_CAST_PTR(char, &target_name), |
136 | acpi_ut_get_type_name(next_node-> | 141 | acpi_ut_get_type_name(node->type), |
137 | type), | 142 | node, |
138 | next_node, | 143 | acpi_ut_get_node_name(parent_node), |
139 | acpi_ut_get_node_name(node), node)); | 144 | parent_node)); |
140 | 145 | ||
141 | *return_node = next_node; | 146 | *return_node = node; |
142 | return_ACPI_STATUS(AE_OK); | 147 | return_ACPI_STATUS(AE_OK); |
143 | } | 148 | } |
144 | 149 | ||
@@ -146,7 +151,7 @@ acpi_ns_search_node(u32 target_name, | |||
146 | * The last entry in the list points back to the parent, | 151 | * The last entry in the list points back to the parent, |
147 | * so a flag is used to indicate the end-of-list | 152 | * so a flag is used to indicate the end-of-list |
148 | */ | 153 | */ |
149 | if (next_node->flags & ANOBJ_END_OF_PEER_LIST) { | 154 | if (node->flags & ANOBJ_END_OF_PEER_LIST) { |
150 | 155 | ||
151 | /* Searched entire list, we are done */ | 156 | /* Searched entire list, we are done */ |
152 | 157 | ||
@@ -155,7 +160,7 @@ acpi_ns_search_node(u32 target_name, | |||
155 | 160 | ||
156 | /* Didn't match name, move on to the next peer object */ | 161 | /* Didn't match name, move on to the next peer object */ |
157 | 162 | ||
158 | next_node = next_node->peer; | 163 | node = node->peer; |
159 | } | 164 | } |
160 | 165 | ||
161 | /* Searched entire namespace level, not found */ | 166 | /* Searched entire namespace level, not found */ |
@@ -164,7 +169,8 @@ acpi_ns_search_node(u32 target_name, | |||
164 | "Name [%4.4s] (%s) not found in search in scope [%4.4s] %p first child %p\n", | 169 | "Name [%4.4s] (%s) not found in search in scope [%4.4s] %p first child %p\n", |
165 | ACPI_CAST_PTR(char, &target_name), | 170 | ACPI_CAST_PTR(char, &target_name), |
166 | acpi_ut_get_type_name(type), | 171 | acpi_ut_get_type_name(type), |
167 | acpi_ut_get_node_name(node), node, node->child)); | 172 | acpi_ut_get_node_name(parent_node), parent_node, |
173 | parent_node->child)); | ||
168 | 174 | ||
169 | return_ACPI_STATUS(AE_NOT_FOUND); | 175 | return_ACPI_STATUS(AE_NOT_FOUND); |
170 | } | 176 | } |
@@ -181,14 +187,14 @@ acpi_ns_search_node(u32 target_name, | |||
181 | * RETURN: Status | 187 | * RETURN: Status |
182 | * | 188 | * |
183 | * DESCRIPTION: Called when a name has not been found in the current namespace | 189 | * DESCRIPTION: Called when a name has not been found in the current namespace |
184 | * level. Before adding it or giving up, ACPI scope rules require | 190 | * level. Before adding it or giving up, ACPI scope rules require |
185 | * searching enclosing scopes in cases identified by acpi_ns_local(). | 191 | * searching enclosing scopes in cases identified by acpi_ns_local(). |
186 | * | 192 | * |
187 | * "A name is located by finding the matching name in the current | 193 | * "A name is located by finding the matching name in the current |
188 | * name space, and then in the parent name space. If the parent | 194 | * name space, and then in the parent name space. If the parent |
189 | * name space does not contain the name, the search continues | 195 | * name space does not contain the name, the search continues |
190 | * recursively until either the name is found or the name space | 196 | * recursively until either the name is found or the name space |
191 | * does not have a parent (the root of the name space). This | 197 | * does not have a parent (the root of the name space). This |
192 | * indicates that the name is not found" (From ACPI Specification, | 198 | * indicates that the name is not found" (From ACPI Specification, |
193 | * section 5.3) | 199 | * section 5.3) |
194 | * | 200 | * |
@@ -237,11 +243,12 @@ acpi_ns_search_parent_tree(u32 target_name, | |||
237 | */ | 243 | */ |
238 | while (parent_node) { | 244 | while (parent_node) { |
239 | /* | 245 | /* |
240 | * Search parent scope. Use TYPE_ANY because we don't care about the | 246 | * Search parent scope. Use TYPE_ANY because we don't care about the |
241 | * object type at this point, we only care about the existence of | 247 | * object type at this point, we only care about the existence of |
242 | * the actual name we are searching for. Typechecking comes later. | 248 | * the actual name we are searching for. Typechecking comes later. |
243 | */ | 249 | */ |
244 | status = acpi_ns_search_node(target_name, parent_node, | 250 | status = |
251 | acpi_ns_search_one_scope(target_name, parent_node, | ||
245 | ACPI_TYPE_ANY, return_node); | 252 | ACPI_TYPE_ANY, return_node); |
246 | if (ACPI_SUCCESS(status)) { | 253 | if (ACPI_SUCCESS(status)) { |
247 | return_ACPI_STATUS(status); | 254 | return_ACPI_STATUS(status); |
@@ -273,7 +280,7 @@ acpi_ns_search_parent_tree(u32 target_name, | |||
273 | * RETURN: Status | 280 | * RETURN: Status |
274 | * | 281 | * |
275 | * DESCRIPTION: Search for a name segment in a single namespace level, | 282 | * DESCRIPTION: Search for a name segment in a single namespace level, |
276 | * optionally adding it if it is not found. If the passed | 283 | * optionally adding it if it is not found. If the passed |
277 | * Type is not Any and the type previously stored in the | 284 | * Type is not Any and the type previously stored in the |
278 | * entry was Any (i.e. unknown), update the stored type. | 285 | * entry was Any (i.e. unknown), update the stored type. |
279 | * | 286 | * |
@@ -332,7 +339,7 @@ acpi_ns_search_and_enter(u32 target_name, | |||
332 | /* Try to find the name in the namespace level specified by the caller */ | 339 | /* Try to find the name in the namespace level specified by the caller */ |
333 | 340 | ||
334 | *return_node = ACPI_ENTRY_NOT_FOUND; | 341 | *return_node = ACPI_ENTRY_NOT_FOUND; |
335 | status = acpi_ns_search_node(target_name, node, type, return_node); | 342 | status = acpi_ns_search_one_scope(target_name, node, type, return_node); |
336 | if (status != AE_NOT_FOUND) { | 343 | if (status != AE_NOT_FOUND) { |
337 | /* | 344 | /* |
338 | * If we found it AND the request specifies that a find is an error, | 345 | * If we found it AND the request specifies that a find is an error, |
@@ -348,10 +355,10 @@ acpi_ns_search_and_enter(u32 target_name, | |||
348 | } | 355 | } |
349 | 356 | ||
350 | /* | 357 | /* |
351 | * The name was not found. If we are NOT performing the first pass | 358 | * The name was not found. If we are NOT performing the first pass |
352 | * (name entry) of loading the namespace, search the parent tree (all the | 359 | * (name entry) of loading the namespace, search the parent tree (all the |
353 | * way to the root if necessary.) We don't want to perform the parent | 360 | * way to the root if necessary.) We don't want to perform the parent |
354 | * search when the namespace is actually being loaded. We want to perform | 361 | * search when the namespace is actually being loaded. We want to perform |
355 | * the search when namespace references are being resolved (load pass 2) | 362 | * the search when namespace references are being resolved (load pass 2) |
356 | * and during the execution phase. | 363 | * and during the execution phase. |
357 | */ | 364 | */ |
@@ -386,6 +393,9 @@ acpi_ns_search_and_enter(u32 target_name, | |||
386 | return_ACPI_STATUS(AE_NO_MEMORY); | 393 | return_ACPI_STATUS(AE_NO_MEMORY); |
387 | } | 394 | } |
388 | #ifdef ACPI_ASL_COMPILER | 395 | #ifdef ACPI_ASL_COMPILER |
396 | /* | ||
397 | * Node is an object defined by an External() statement | ||
398 | */ | ||
389 | if (flags & ACPI_NS_EXTERNAL) { | 399 | if (flags & ACPI_NS_EXTERNAL) { |
390 | new_node->flags |= ANOBJ_IS_EXTERNAL; | 400 | new_node->flags |= ANOBJ_IS_EXTERNAL; |
391 | } | 401 | } |
diff --git a/drivers/acpi/namespace/nsutils.c b/drivers/acpi/namespace/nsutils.c index d1d55032b455..aa4e799d9a8c 100644 --- a/drivers/acpi/namespace/nsutils.c +++ b/drivers/acpi/namespace/nsutils.c | |||
@@ -142,8 +142,9 @@ acpi_ns_report_method_error(char *module_name, | |||
142 | acpi_os_printf("ACPI Error (%s-%04d): ", module_name, line_number); | 142 | acpi_os_printf("ACPI Error (%s-%04d): ", module_name, line_number); |
143 | 143 | ||
144 | if (path) { | 144 | if (path) { |
145 | status = acpi_ns_get_node_by_path(path, prefix_node, | 145 | status = |
146 | ACPI_NS_NO_UPSEARCH, &node); | 146 | acpi_ns_get_node(prefix_node, path, ACPI_NS_NO_UPSEARCH, |
147 | &node); | ||
147 | if (ACPI_FAILURE(status)) { | 148 | if (ACPI_FAILURE(status)) { |
148 | acpi_os_printf("[Could not get node by pathname]"); | 149 | acpi_os_printf("[Could not get node by pathname]"); |
149 | } | 150 | } |
@@ -685,13 +686,9 @@ struct acpi_namespace_node *acpi_ns_map_handle_to_node(acpi_handle handle) | |||
685 | ACPI_FUNCTION_ENTRY(); | 686 | ACPI_FUNCTION_ENTRY(); |
686 | 687 | ||
687 | /* | 688 | /* |
688 | * Simple implementation. | 689 | * Simple implementation |
689 | */ | 690 | */ |
690 | if (!handle) { | 691 | if ((!handle) || (handle == ACPI_ROOT_OBJECT)) { |
691 | return (NULL); | ||
692 | } | ||
693 | |||
694 | if (handle == ACPI_ROOT_OBJECT) { | ||
695 | return (acpi_gbl_root_node); | 692 | return (acpi_gbl_root_node); |
696 | } | 693 | } |
697 | 694 | ||
@@ -701,7 +698,7 @@ struct acpi_namespace_node *acpi_ns_map_handle_to_node(acpi_handle handle) | |||
701 | return (NULL); | 698 | return (NULL); |
702 | } | 699 | } |
703 | 700 | ||
704 | return ((struct acpi_namespace_node *)handle); | 701 | return (ACPI_CAST_PTR(struct acpi_namespace_node, handle)); |
705 | } | 702 | } |
706 | 703 | ||
707 | /******************************************************************************* | 704 | /******************************************************************************* |
@@ -811,12 +808,12 @@ u32 acpi_ns_opens_scope(acpi_object_type type) | |||
811 | 808 | ||
812 | /******************************************************************************* | 809 | /******************************************************************************* |
813 | * | 810 | * |
814 | * FUNCTION: acpi_ns_get_node_by_path | 811 | * FUNCTION: acpi_ns_get_node |
815 | * | 812 | * |
816 | * PARAMETERS: *Pathname - Name to be found, in external (ASL) format. The | 813 | * PARAMETERS: *Pathname - Name to be found, in external (ASL) format. The |
817 | * \ (backslash) and ^ (carat) prefixes, and the | 814 | * \ (backslash) and ^ (carat) prefixes, and the |
818 | * . (period) to separate segments are supported. | 815 | * . (period) to separate segments are supported. |
819 | * start_node - Root of subtree to be searched, or NS_ALL for the | 816 | * prefix_node - Root of subtree to be searched, or NS_ALL for the |
820 | * root of the name space. If Name is fully | 817 | * root of the name space. If Name is fully |
821 | * qualified (first s8 is '\'), the passed value | 818 | * qualified (first s8 is '\'), the passed value |
822 | * of Scope will not be accessed. | 819 | * of Scope will not be accessed. |
@@ -832,24 +829,29 @@ u32 acpi_ns_opens_scope(acpi_object_type type) | |||
832 | ******************************************************************************/ | 829 | ******************************************************************************/ |
833 | 830 | ||
834 | acpi_status | 831 | acpi_status |
835 | acpi_ns_get_node_by_path(char *pathname, | 832 | acpi_ns_get_node(struct acpi_namespace_node *prefix_node, |
836 | struct acpi_namespace_node *start_node, | 833 | char *pathname, |
837 | u32 flags, struct acpi_namespace_node **return_node) | 834 | u32 flags, struct acpi_namespace_node **return_node) |
838 | { | 835 | { |
839 | union acpi_generic_state scope_info; | 836 | union acpi_generic_state scope_info; |
840 | acpi_status status; | 837 | acpi_status status; |
841 | char *internal_path = NULL; | 838 | char *internal_path; |
842 | 839 | ||
843 | ACPI_FUNCTION_TRACE_PTR(ns_get_node_by_path, pathname); | 840 | ACPI_FUNCTION_TRACE_PTR(ns_get_node, pathname); |
844 | 841 | ||
845 | if (pathname) { | 842 | if (!pathname) { |
843 | *return_node = prefix_node; | ||
844 | if (!prefix_node) { | ||
845 | *return_node = acpi_gbl_root_node; | ||
846 | } | ||
847 | return_ACPI_STATUS(AE_OK); | ||
848 | } | ||
846 | 849 | ||
847 | /* Convert path to internal representation */ | 850 | /* Convert path to internal representation */ |
848 | 851 | ||
849 | status = acpi_ns_internalize_name(pathname, &internal_path); | 852 | status = acpi_ns_internalize_name(pathname, &internal_path); |
850 | if (ACPI_FAILURE(status)) { | 853 | if (ACPI_FAILURE(status)) { |
851 | return_ACPI_STATUS(status); | 854 | return_ACPI_STATUS(status); |
852 | } | ||
853 | } | 855 | } |
854 | 856 | ||
855 | /* Must lock namespace during lookup */ | 857 | /* Must lock namespace during lookup */ |
@@ -861,26 +863,23 @@ acpi_ns_get_node_by_path(char *pathname, | |||
861 | 863 | ||
862 | /* Setup lookup scope (search starting point) */ | 864 | /* Setup lookup scope (search starting point) */ |
863 | 865 | ||
864 | scope_info.scope.node = start_node; | 866 | scope_info.scope.node = prefix_node; |
865 | 867 | ||
866 | /* Lookup the name in the namespace */ | 868 | /* Lookup the name in the namespace */ |
867 | 869 | ||
868 | status = acpi_ns_lookup(&scope_info, internal_path, | 870 | status = acpi_ns_lookup(&scope_info, internal_path, ACPI_TYPE_ANY, |
869 | ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, | 871 | ACPI_IMODE_EXECUTE, |
870 | (flags | ACPI_NS_DONT_OPEN_SCOPE), | 872 | (flags | ACPI_NS_DONT_OPEN_SCOPE), NULL, |
871 | NULL, return_node); | 873 | return_node); |
872 | if (ACPI_FAILURE(status)) { | 874 | if (ACPI_FAILURE(status)) { |
873 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s, %s\n", | 875 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s, %s\n", |
874 | internal_path, | 876 | pathname, acpi_format_exception(status))); |
875 | acpi_format_exception(status))); | ||
876 | } | 877 | } |
877 | 878 | ||
878 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | 879 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); |
879 | 880 | ||
880 | cleanup: | 881 | cleanup: |
881 | if (internal_path) { | 882 | ACPI_FREE(internal_path); |
882 | ACPI_FREE(internal_path); | ||
883 | } | ||
884 | return_ACPI_STATUS(status); | 883 | return_ACPI_STATUS(status); |
885 | } | 884 | } |
886 | 885 | ||
diff --git a/drivers/acpi/namespace/nsxfeval.c b/drivers/acpi/namespace/nsxfeval.c index 998b29611b19..6d9bd45af30a 100644 --- a/drivers/acpi/namespace/nsxfeval.c +++ b/drivers/acpi/namespace/nsxfeval.c | |||
@@ -171,51 +171,61 @@ acpi_evaluate_object(acpi_handle handle, | |||
171 | { | 171 | { |
172 | acpi_status status; | 172 | acpi_status status; |
173 | acpi_status status2; | 173 | acpi_status status2; |
174 | struct acpi_parameter_info info; | 174 | struct acpi_evaluate_info *info; |
175 | acpi_size buffer_space_needed; | 175 | acpi_size buffer_space_needed; |
176 | u32 i; | 176 | u32 i; |
177 | 177 | ||
178 | ACPI_FUNCTION_TRACE(acpi_evaluate_object); | 178 | ACPI_FUNCTION_TRACE(acpi_evaluate_object); |
179 | 179 | ||
180 | info.node = handle; | 180 | /* Allocate and initialize the evaluation information block */ |
181 | info.parameters = NULL; | 181 | |
182 | info.return_object = NULL; | 182 | info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info)); |
183 | info.parameter_type = ACPI_PARAM_ARGS; | 183 | if (!info) { |
184 | return_ACPI_STATUS(AE_NO_MEMORY); | ||
185 | } | ||
186 | |||
187 | info->pathname = pathname; | ||
188 | info->parameter_type = ACPI_PARAM_ARGS; | ||
189 | |||
190 | /* Convert and validate the device handle */ | ||
191 | |||
192 | info->prefix_node = acpi_ns_map_handle_to_node(handle); | ||
193 | if (!info->prefix_node) { | ||
194 | status = AE_BAD_PARAMETER; | ||
195 | goto cleanup; | ||
196 | } | ||
184 | 197 | ||
185 | /* | 198 | /* |
186 | * If there are parameters to be passed to the object | 199 | * If there are parameters to be passed to a control method, the external |
187 | * (which must be a control method), the external objects | 200 | * objects must all be converted to internal objects |
188 | * must be converted to internal objects | ||
189 | */ | 201 | */ |
190 | if (external_params && external_params->count) { | 202 | if (external_params && external_params->count) { |
191 | /* | 203 | /* |
192 | * Allocate a new parameter block for the internal objects | 204 | * Allocate a new parameter block for the internal objects |
193 | * Add 1 to count to allow for null terminated internal list | 205 | * Add 1 to count to allow for null terminated internal list |
194 | */ | 206 | */ |
195 | info.parameters = ACPI_ALLOCATE_ZEROED(((acpi_size) | 207 | info->parameters = ACPI_ALLOCATE_ZEROED(((acpi_size) |
196 | external_params->count + | 208 | external_params-> |
197 | 1) * sizeof(void *)); | 209 | count + |
198 | if (!info.parameters) { | 210 | 1) * sizeof(void *)); |
199 | return_ACPI_STATUS(AE_NO_MEMORY); | 211 | if (!info->parameters) { |
212 | status = AE_NO_MEMORY; | ||
213 | goto cleanup; | ||
200 | } | 214 | } |
201 | 215 | ||
202 | /* | 216 | /* Convert each external object in the list to an internal object */ |
203 | * Convert each external object in the list to an | 217 | |
204 | * internal object | ||
205 | */ | ||
206 | for (i = 0; i < external_params->count; i++) { | 218 | for (i = 0; i < external_params->count; i++) { |
207 | status = | 219 | status = |
208 | acpi_ut_copy_eobject_to_iobject(&external_params-> | 220 | acpi_ut_copy_eobject_to_iobject(&external_params-> |
209 | pointer[i], | 221 | pointer[i], |
210 | &info. | 222 | &info-> |
211 | parameters[i]); | 223 | parameters[i]); |
212 | if (ACPI_FAILURE(status)) { | 224 | if (ACPI_FAILURE(status)) { |
213 | acpi_ut_delete_internal_object_list(info. | 225 | goto cleanup; |
214 | parameters); | ||
215 | return_ACPI_STATUS(status); | ||
216 | } | 226 | } |
217 | } | 227 | } |
218 | info.parameters[external_params->count] = NULL; | 228 | info->parameters[external_params->count] = NULL; |
219 | } | 229 | } |
220 | 230 | ||
221 | /* | 231 | /* |
@@ -228,12 +238,13 @@ acpi_evaluate_object(acpi_handle handle, | |||
228 | 238 | ||
229 | /* The path is fully qualified, just evaluate by name */ | 239 | /* The path is fully qualified, just evaluate by name */ |
230 | 240 | ||
231 | status = acpi_ns_evaluate_by_name(pathname, &info); | 241 | info->prefix_node = NULL; |
242 | status = acpi_ns_evaluate(info); | ||
232 | } else if (!handle) { | 243 | } else if (!handle) { |
233 | /* | 244 | /* |
234 | * A handle is optional iff a fully qualified pathname | 245 | * A handle is optional iff a fully qualified pathname is specified. |
235 | * is specified. Since we've already handled fully | 246 | * Since we've already handled fully qualified names above, this is |
236 | * qualified names above, this is an error | 247 | * an error |
237 | */ | 248 | */ |
238 | if (!pathname) { | 249 | if (!pathname) { |
239 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 250 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
@@ -246,22 +257,9 @@ acpi_evaluate_object(acpi_handle handle, | |||
246 | 257 | ||
247 | status = AE_BAD_PARAMETER; | 258 | status = AE_BAD_PARAMETER; |
248 | } else { | 259 | } else { |
249 | /* | 260 | /* We have a namespace a node and a possible relative path */ |
250 | * We get here if we have a handle -- and if we have a | ||
251 | * pathname it is relative. The handle will be validated | ||
252 | * in the lower procedures | ||
253 | */ | ||
254 | if (!pathname) { | ||
255 | /* | ||
256 | * The null pathname case means the handle is for | ||
257 | * the actual object to be evaluated | ||
258 | */ | ||
259 | status = acpi_ns_evaluate_by_handle(&info); | ||
260 | } else { | ||
261 | /* Both a Handle and a relative Pathname */ | ||
262 | 261 | ||
263 | status = acpi_ns_evaluate_relative(pathname, &info); | 262 | status = acpi_ns_evaluate(info); |
264 | } | ||
265 | } | 263 | } |
266 | 264 | ||
267 | /* | 265 | /* |
@@ -269,10 +267,10 @@ acpi_evaluate_object(acpi_handle handle, | |||
269 | * copy the return value to an external object. | 267 | * copy the return value to an external object. |
270 | */ | 268 | */ |
271 | if (return_buffer) { | 269 | if (return_buffer) { |
272 | if (!info.return_object) { | 270 | if (!info->return_object) { |
273 | return_buffer->length = 0; | 271 | return_buffer->length = 0; |
274 | } else { | 272 | } else { |
275 | if (ACPI_GET_DESCRIPTOR_TYPE(info.return_object) == | 273 | if (ACPI_GET_DESCRIPTOR_TYPE(info->return_object) == |
276 | ACPI_DESC_TYPE_NAMED) { | 274 | ACPI_DESC_TYPE_NAMED) { |
277 | /* | 275 | /* |
278 | * If we received a NS Node as a return object, this means that | 276 | * If we received a NS Node as a return object, this means that |
@@ -283,17 +281,16 @@ acpi_evaluate_object(acpi_handle handle, | |||
283 | * support for various types at a later date if necessary. | 281 | * support for various types at a later date if necessary. |
284 | */ | 282 | */ |
285 | status = AE_TYPE; | 283 | status = AE_TYPE; |
286 | info.return_object = NULL; /* No need to delete a NS Node */ | 284 | info->return_object = NULL; /* No need to delete a NS Node */ |
287 | return_buffer->length = 0; | 285 | return_buffer->length = 0; |
288 | } | 286 | } |
289 | 287 | ||
290 | if (ACPI_SUCCESS(status)) { | 288 | if (ACPI_SUCCESS(status)) { |
291 | /* | 289 | |
292 | * Find out how large a buffer is needed | 290 | /* Get the size of the returned object */ |
293 | * to contain the returned object | 291 | |
294 | */ | ||
295 | status = | 292 | status = |
296 | acpi_ut_get_object_size(info.return_object, | 293 | acpi_ut_get_object_size(info->return_object, |
297 | &buffer_space_needed); | 294 | &buffer_space_needed); |
298 | if (ACPI_SUCCESS(status)) { | 295 | if (ACPI_SUCCESS(status)) { |
299 | 296 | ||
@@ -319,7 +316,7 @@ acpi_evaluate_object(acpi_handle handle, | |||
319 | 316 | ||
320 | status = | 317 | status = |
321 | acpi_ut_copy_iobject_to_eobject | 318 | acpi_ut_copy_iobject_to_eobject |
322 | (info.return_object, | 319 | (info->return_object, |
323 | return_buffer); | 320 | return_buffer); |
324 | } | 321 | } |
325 | } | 322 | } |
@@ -327,31 +324,33 @@ acpi_evaluate_object(acpi_handle handle, | |||
327 | } | 324 | } |
328 | } | 325 | } |
329 | 326 | ||
330 | if (info.return_object) { | 327 | if (info->return_object) { |
331 | /* | 328 | /* |
332 | * Delete the internal return object. NOTE: Interpreter | 329 | * Delete the internal return object. NOTE: Interpreter must be |
333 | * must be locked to avoid race condition. | 330 | * locked to avoid race condition. |
334 | */ | 331 | */ |
335 | status2 = acpi_ex_enter_interpreter(); | 332 | status2 = acpi_ex_enter_interpreter(); |
336 | if (ACPI_SUCCESS(status2)) { | 333 | if (ACPI_SUCCESS(status2)) { |
337 | /* | 334 | |
338 | * Delete the internal return object. (Or at least | 335 | /* Remove one reference on the return object (should delete it) */ |
339 | * decrement the reference count by one) | 336 | |
340 | */ | 337 | acpi_ut_remove_reference(info->return_object); |
341 | acpi_ut_remove_reference(info.return_object); | ||
342 | acpi_ex_exit_interpreter(); | 338 | acpi_ex_exit_interpreter(); |
343 | } | 339 | } |
344 | } | 340 | } |
345 | 341 | ||
342 | cleanup: | ||
343 | |||
346 | /* Free the input parameter list (if we created one) */ | 344 | /* Free the input parameter list (if we created one) */ |
347 | 345 | ||
348 | if (info.parameters) { | 346 | if (info->parameters) { |
349 | 347 | ||
350 | /* Free the allocated parameter block */ | 348 | /* Free the allocated parameter block */ |
351 | 349 | ||
352 | acpi_ut_delete_internal_object_list(info.parameters); | 350 | acpi_ut_delete_internal_object_list(info->parameters); |
353 | } | 351 | } |
354 | 352 | ||
353 | ACPI_FREE(info); | ||
355 | return_ACPI_STATUS(status); | 354 | return_ACPI_STATUS(status); |
356 | } | 355 | } |
357 | 356 | ||
diff --git a/drivers/acpi/namespace/nsxfname.c b/drivers/acpi/namespace/nsxfname.c index 1303e2b062bb..978213a6c19f 100644 --- a/drivers/acpi/namespace/nsxfname.c +++ b/drivers/acpi/namespace/nsxfname.c | |||
@@ -112,9 +112,8 @@ acpi_get_handle(acpi_handle parent, | |||
112 | /* | 112 | /* |
113 | * Find the Node and convert to a handle | 113 | * Find the Node and convert to a handle |
114 | */ | 114 | */ |
115 | status = | 115 | status = acpi_ns_get_node(prefix_node, pathname, ACPI_NS_NO_UPSEARCH, |
116 | acpi_ns_get_node_by_path(pathname, prefix_node, ACPI_NS_NO_UPSEARCH, | 116 | &node); |
117 | &node); | ||
118 | 117 | ||
119 | *ret_handle = NULL; | 118 | *ret_handle = NULL; |
120 | if (ACPI_SUCCESS(status)) { | 119 | if (ACPI_SUCCESS(status)) { |
diff --git a/drivers/acpi/parser/psparse.c b/drivers/acpi/parser/psparse.c index 796f6b719929..7ee2f2e77525 100644 --- a/drivers/acpi/parser/psparse.c +++ b/drivers/acpi/parser/psparse.c | |||
@@ -464,6 +464,7 @@ acpi_status acpi_ps_parse_aml(struct acpi_walk_state *walk_state) | |||
464 | 464 | ||
465 | thread = acpi_ut_create_thread_state(); | 465 | thread = acpi_ut_create_thread_state(); |
466 | if (!thread) { | 466 | if (!thread) { |
467 | acpi_ds_delete_walk_state(walk_state); | ||
467 | return_ACPI_STATUS(AE_NO_MEMORY); | 468 | return_ACPI_STATUS(AE_NO_MEMORY); |
468 | } | 469 | } |
469 | 470 | ||
diff --git a/drivers/acpi/parser/psxface.c b/drivers/acpi/parser/psxface.c index 6b1411f1087d..5d996c1140af 100644 --- a/drivers/acpi/parser/psxface.c +++ b/drivers/acpi/parser/psxface.c | |||
@@ -50,14 +50,14 @@ | |||
50 | ACPI_MODULE_NAME("psxface") | 50 | ACPI_MODULE_NAME("psxface") |
51 | 51 | ||
52 | /* Local Prototypes */ | 52 | /* Local Prototypes */ |
53 | static void acpi_ps_start_trace(struct acpi_parameter_info *info); | 53 | static void acpi_ps_start_trace(struct acpi_evaluate_info *info); |
54 | 54 | ||
55 | static void acpi_ps_stop_trace(struct acpi_parameter_info *info); | 55 | static void acpi_ps_stop_trace(struct acpi_evaluate_info *info); |
56 | 56 | ||
57 | static acpi_status acpi_ps_execute_pass(struct acpi_parameter_info *info); | 57 | static acpi_status acpi_ps_execute_pass(struct acpi_evaluate_info *info); |
58 | 58 | ||
59 | static void | 59 | static void |
60 | acpi_ps_update_parameter_list(struct acpi_parameter_info *info, u16 action); | 60 | acpi_ps_update_parameter_list(struct acpi_evaluate_info *info, u16 action); |
61 | 61 | ||
62 | /******************************************************************************* | 62 | /******************************************************************************* |
63 | * | 63 | * |
@@ -113,7 +113,7 @@ acpi_debug_trace(char *name, u32 debug_level, u32 debug_layer, u32 flags) | |||
113 | * | 113 | * |
114 | ******************************************************************************/ | 114 | ******************************************************************************/ |
115 | 115 | ||
116 | static void acpi_ps_start_trace(struct acpi_parameter_info *info) | 116 | static void acpi_ps_start_trace(struct acpi_evaluate_info *info) |
117 | { | 117 | { |
118 | acpi_status status; | 118 | acpi_status status; |
119 | 119 | ||
@@ -125,7 +125,7 @@ static void acpi_ps_start_trace(struct acpi_parameter_info *info) | |||
125 | } | 125 | } |
126 | 126 | ||
127 | if ((!acpi_gbl_trace_method_name) || | 127 | if ((!acpi_gbl_trace_method_name) || |
128 | (acpi_gbl_trace_method_name != info->node->name.integer)) { | 128 | (acpi_gbl_trace_method_name != info->resolved_node->name.integer)) { |
129 | goto exit; | 129 | goto exit; |
130 | } | 130 | } |
131 | 131 | ||
@@ -158,7 +158,7 @@ static void acpi_ps_start_trace(struct acpi_parameter_info *info) | |||
158 | * | 158 | * |
159 | ******************************************************************************/ | 159 | ******************************************************************************/ |
160 | 160 | ||
161 | static void acpi_ps_stop_trace(struct acpi_parameter_info *info) | 161 | static void acpi_ps_stop_trace(struct acpi_evaluate_info *info) |
162 | { | 162 | { |
163 | acpi_status status; | 163 | acpi_status status; |
164 | 164 | ||
@@ -170,7 +170,7 @@ static void acpi_ps_stop_trace(struct acpi_parameter_info *info) | |||
170 | } | 170 | } |
171 | 171 | ||
172 | if ((!acpi_gbl_trace_method_name) || | 172 | if ((!acpi_gbl_trace_method_name) || |
173 | (acpi_gbl_trace_method_name != info->node->name.integer)) { | 173 | (acpi_gbl_trace_method_name != info->resolved_node->name.integer)) { |
174 | goto exit; | 174 | goto exit; |
175 | } | 175 | } |
176 | 176 | ||
@@ -212,7 +212,7 @@ static void acpi_ps_stop_trace(struct acpi_parameter_info *info) | |||
212 | * | 212 | * |
213 | ******************************************************************************/ | 213 | ******************************************************************************/ |
214 | 214 | ||
215 | acpi_status acpi_ps_execute_method(struct acpi_parameter_info *info) | 215 | acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info) |
216 | { | 216 | { |
217 | acpi_status status; | 217 | acpi_status status; |
218 | 218 | ||
@@ -220,14 +220,15 @@ acpi_status acpi_ps_execute_method(struct acpi_parameter_info *info) | |||
220 | 220 | ||
221 | /* Validate the Info and method Node */ | 221 | /* Validate the Info and method Node */ |
222 | 222 | ||
223 | if (!info || !info->node) { | 223 | if (!info || !info->resolved_node) { |
224 | return_ACPI_STATUS(AE_NULL_ENTRY); | 224 | return_ACPI_STATUS(AE_NULL_ENTRY); |
225 | } | 225 | } |
226 | 226 | ||
227 | /* Init for new method, wait on concurrency semaphore */ | 227 | /* Init for new method, wait on concurrency semaphore */ |
228 | 228 | ||
229 | status = | 229 | status = |
230 | acpi_ds_begin_method_execution(info->node, info->obj_desc, NULL); | 230 | acpi_ds_begin_method_execution(info->resolved_node, info->obj_desc, |
231 | NULL); | ||
231 | if (ACPI_FAILURE(status)) { | 232 | if (ACPI_FAILURE(status)) { |
232 | return_ACPI_STATUS(status); | 233 | return_ACPI_STATUS(status); |
233 | } | 234 | } |
@@ -248,7 +249,7 @@ acpi_status acpi_ps_execute_method(struct acpi_parameter_info *info) | |||
248 | */ | 249 | */ |
249 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE, | 250 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE, |
250 | "**** Begin Method Parse **** Entry=%p obj=%p\n", | 251 | "**** Begin Method Parse **** Entry=%p obj=%p\n", |
251 | info->node, info->obj_desc)); | 252 | info->resolved_node, info->obj_desc)); |
252 | 253 | ||
253 | info->pass_number = 1; | 254 | info->pass_number = 1; |
254 | status = acpi_ps_execute_pass(info); | 255 | status = acpi_ps_execute_pass(info); |
@@ -261,7 +262,7 @@ acpi_status acpi_ps_execute_method(struct acpi_parameter_info *info) | |||
261 | */ | 262 | */ |
262 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE, | 263 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE, |
263 | "**** Begin Method Execution **** Entry=%p obj=%p\n", | 264 | "**** Begin Method Execution **** Entry=%p obj=%p\n", |
264 | info->node, info->obj_desc)); | 265 | info->resolved_node, info->obj_desc)); |
265 | 266 | ||
266 | info->pass_number = 3; | 267 | info->pass_number = 3; |
267 | status = acpi_ps_execute_pass(info); | 268 | status = acpi_ps_execute_pass(info); |
@@ -300,7 +301,7 @@ acpi_status acpi_ps_execute_method(struct acpi_parameter_info *info) | |||
300 | * | 301 | * |
301 | * FUNCTION: acpi_ps_update_parameter_list | 302 | * FUNCTION: acpi_ps_update_parameter_list |
302 | * | 303 | * |
303 | * PARAMETERS: Info - See struct acpi_parameter_info | 304 | * PARAMETERS: Info - See struct acpi_evaluate_info |
304 | * (Used: parameter_type and Parameters) | 305 | * (Used: parameter_type and Parameters) |
305 | * Action - Add or Remove reference | 306 | * Action - Add or Remove reference |
306 | * | 307 | * |
@@ -311,7 +312,7 @@ acpi_status acpi_ps_execute_method(struct acpi_parameter_info *info) | |||
311 | ******************************************************************************/ | 312 | ******************************************************************************/ |
312 | 313 | ||
313 | static void | 314 | static void |
314 | acpi_ps_update_parameter_list(struct acpi_parameter_info *info, u16 action) | 315 | acpi_ps_update_parameter_list(struct acpi_evaluate_info *info, u16 action) |
315 | { | 316 | { |
316 | acpi_native_uint i; | 317 | acpi_native_uint i; |
317 | 318 | ||
@@ -334,7 +335,7 @@ acpi_ps_update_parameter_list(struct acpi_parameter_info *info, u16 action) | |||
334 | * | 335 | * |
335 | * FUNCTION: acpi_ps_execute_pass | 336 | * FUNCTION: acpi_ps_execute_pass |
336 | * | 337 | * |
337 | * PARAMETERS: Info - See struct acpi_parameter_info | 338 | * PARAMETERS: Info - See struct acpi_evaluate_info |
338 | * (Used: pass_number, Node, and obj_desc) | 339 | * (Used: pass_number, Node, and obj_desc) |
339 | * | 340 | * |
340 | * RETURN: Status | 341 | * RETURN: Status |
@@ -343,7 +344,7 @@ acpi_ps_update_parameter_list(struct acpi_parameter_info *info, u16 action) | |||
343 | * | 344 | * |
344 | ******************************************************************************/ | 345 | ******************************************************************************/ |
345 | 346 | ||
346 | static acpi_status acpi_ps_execute_pass(struct acpi_parameter_info *info) | 347 | static acpi_status acpi_ps_execute_pass(struct acpi_evaluate_info *info) |
347 | { | 348 | { |
348 | acpi_status status; | 349 | acpi_status status; |
349 | union acpi_parse_object *op; | 350 | union acpi_parse_object *op; |
@@ -368,7 +369,7 @@ static acpi_status acpi_ps_execute_pass(struct acpi_parameter_info *info) | |||
368 | goto cleanup; | 369 | goto cleanup; |
369 | } | 370 | } |
370 | 371 | ||
371 | status = acpi_ds_init_aml_walk(walk_state, op, info->node, | 372 | status = acpi_ds_init_aml_walk(walk_state, op, info->resolved_node, |
372 | info->obj_desc->method.aml_start, | 373 | info->obj_desc->method.aml_start, |
373 | info->obj_desc->method.aml_length, | 374 | info->obj_desc->method.aml_length, |
374 | info->pass_number == 1 ? NULL : info, | 375 | info->pass_number == 1 ? NULL : info, |
diff --git a/drivers/acpi/resources/rsutils.c b/drivers/acpi/resources/rsutils.c index 0e493f2fec4d..a9cbee8e8b44 100644 --- a/drivers/acpi/resources/rsutils.c +++ b/drivers/acpi/resources/rsutils.c | |||
@@ -442,7 +442,7 @@ acpi_rs_set_resource_source(union aml_resource * aml, | |||
442 | * | 442 | * |
443 | * FUNCTION: acpi_rs_get_prt_method_data | 443 | * FUNCTION: acpi_rs_get_prt_method_data |
444 | * | 444 | * |
445 | * PARAMETERS: Handle - Handle to the containing object | 445 | * PARAMETERS: Node - Device node |
446 | * ret_buffer - Pointer to a buffer structure for the | 446 | * ret_buffer - Pointer to a buffer structure for the |
447 | * results | 447 | * results |
448 | * | 448 | * |
@@ -457,7 +457,8 @@ acpi_rs_set_resource_source(union aml_resource * aml, | |||
457 | ******************************************************************************/ | 457 | ******************************************************************************/ |
458 | 458 | ||
459 | acpi_status | 459 | acpi_status |
460 | acpi_rs_get_prt_method_data(acpi_handle handle, struct acpi_buffer * ret_buffer) | 460 | acpi_rs_get_prt_method_data(struct acpi_namespace_node * node, |
461 | struct acpi_buffer * ret_buffer) | ||
461 | { | 462 | { |
462 | union acpi_operand_object *obj_desc; | 463 | union acpi_operand_object *obj_desc; |
463 | acpi_status status; | 464 | acpi_status status; |
@@ -468,7 +469,7 @@ acpi_rs_get_prt_method_data(acpi_handle handle, struct acpi_buffer * ret_buffer) | |||
468 | 469 | ||
469 | /* Execute the method, no parameters */ | 470 | /* Execute the method, no parameters */ |
470 | 471 | ||
471 | status = acpi_ut_evaluate_object(handle, METHOD_NAME__PRT, | 472 | status = acpi_ut_evaluate_object(node, METHOD_NAME__PRT, |
472 | ACPI_BTYPE_PACKAGE, &obj_desc); | 473 | ACPI_BTYPE_PACKAGE, &obj_desc); |
473 | if (ACPI_FAILURE(status)) { | 474 | if (ACPI_FAILURE(status)) { |
474 | return_ACPI_STATUS(status); | 475 | return_ACPI_STATUS(status); |
@@ -490,7 +491,7 @@ acpi_rs_get_prt_method_data(acpi_handle handle, struct acpi_buffer * ret_buffer) | |||
490 | * | 491 | * |
491 | * FUNCTION: acpi_rs_get_crs_method_data | 492 | * FUNCTION: acpi_rs_get_crs_method_data |
492 | * | 493 | * |
493 | * PARAMETERS: Handle - Handle to the containing object | 494 | * PARAMETERS: Node - Device node |
494 | * ret_buffer - Pointer to a buffer structure for the | 495 | * ret_buffer - Pointer to a buffer structure for the |
495 | * results | 496 | * results |
496 | * | 497 | * |
@@ -505,7 +506,8 @@ acpi_rs_get_prt_method_data(acpi_handle handle, struct acpi_buffer * ret_buffer) | |||
505 | ******************************************************************************/ | 506 | ******************************************************************************/ |
506 | 507 | ||
507 | acpi_status | 508 | acpi_status |
508 | acpi_rs_get_crs_method_data(acpi_handle handle, struct acpi_buffer *ret_buffer) | 509 | acpi_rs_get_crs_method_data(struct acpi_namespace_node *node, |
510 | struct acpi_buffer *ret_buffer) | ||
509 | { | 511 | { |
510 | union acpi_operand_object *obj_desc; | 512 | union acpi_operand_object *obj_desc; |
511 | acpi_status status; | 513 | acpi_status status; |
@@ -516,7 +518,7 @@ acpi_rs_get_crs_method_data(acpi_handle handle, struct acpi_buffer *ret_buffer) | |||
516 | 518 | ||
517 | /* Execute the method, no parameters */ | 519 | /* Execute the method, no parameters */ |
518 | 520 | ||
519 | status = acpi_ut_evaluate_object(handle, METHOD_NAME__CRS, | 521 | status = acpi_ut_evaluate_object(node, METHOD_NAME__CRS, |
520 | ACPI_BTYPE_BUFFER, &obj_desc); | 522 | ACPI_BTYPE_BUFFER, &obj_desc); |
521 | if (ACPI_FAILURE(status)) { | 523 | if (ACPI_FAILURE(status)) { |
522 | return_ACPI_STATUS(status); | 524 | return_ACPI_STATUS(status); |
@@ -539,7 +541,7 @@ acpi_rs_get_crs_method_data(acpi_handle handle, struct acpi_buffer *ret_buffer) | |||
539 | * | 541 | * |
540 | * FUNCTION: acpi_rs_get_prs_method_data | 542 | * FUNCTION: acpi_rs_get_prs_method_data |
541 | * | 543 | * |
542 | * PARAMETERS: Handle - Handle to the containing object | 544 | * PARAMETERS: Node - Device node |
543 | * ret_buffer - Pointer to a buffer structure for the | 545 | * ret_buffer - Pointer to a buffer structure for the |
544 | * results | 546 | * results |
545 | * | 547 | * |
@@ -555,7 +557,8 @@ acpi_rs_get_crs_method_data(acpi_handle handle, struct acpi_buffer *ret_buffer) | |||
555 | 557 | ||
556 | #ifdef ACPI_FUTURE_USAGE | 558 | #ifdef ACPI_FUTURE_USAGE |
557 | acpi_status | 559 | acpi_status |
558 | acpi_rs_get_prs_method_data(acpi_handle handle, struct acpi_buffer *ret_buffer) | 560 | acpi_rs_get_prs_method_data(struct acpi_namespace_node *node, |
561 | struct acpi_buffer *ret_buffer) | ||
559 | { | 562 | { |
560 | union acpi_operand_object *obj_desc; | 563 | union acpi_operand_object *obj_desc; |
561 | acpi_status status; | 564 | acpi_status status; |
@@ -566,7 +569,7 @@ acpi_rs_get_prs_method_data(acpi_handle handle, struct acpi_buffer *ret_buffer) | |||
566 | 569 | ||
567 | /* Execute the method, no parameters */ | 570 | /* Execute the method, no parameters */ |
568 | 571 | ||
569 | status = acpi_ut_evaluate_object(handle, METHOD_NAME__PRS, | 572 | status = acpi_ut_evaluate_object(node, METHOD_NAME__PRS, |
570 | ACPI_BTYPE_BUFFER, &obj_desc); | 573 | ACPI_BTYPE_BUFFER, &obj_desc); |
571 | if (ACPI_FAILURE(status)) { | 574 | if (ACPI_FAILURE(status)) { |
572 | return_ACPI_STATUS(status); | 575 | return_ACPI_STATUS(status); |
@@ -641,7 +644,7 @@ acpi_rs_get_method_data(acpi_handle handle, | |||
641 | * | 644 | * |
642 | * FUNCTION: acpi_rs_set_srs_method_data | 645 | * FUNCTION: acpi_rs_set_srs_method_data |
643 | * | 646 | * |
644 | * PARAMETERS: Handle - Handle to the containing object | 647 | * PARAMETERS: Node - Device node |
645 | * in_buffer - Pointer to a buffer structure of the | 648 | * in_buffer - Pointer to a buffer structure of the |
646 | * parameter | 649 | * parameter |
647 | * | 650 | * |
@@ -653,23 +656,37 @@ acpi_rs_get_method_data(acpi_handle handle, | |||
653 | * If the function fails an appropriate status will be returned | 656 | * If the function fails an appropriate status will be returned |
654 | * and the contents of the callers buffer is undefined. | 657 | * and the contents of the callers buffer is undefined. |
655 | * | 658 | * |
659 | * Note: Parameters guaranteed valid by caller | ||
660 | * | ||
656 | ******************************************************************************/ | 661 | ******************************************************************************/ |
657 | 662 | ||
658 | acpi_status | 663 | acpi_status |
659 | acpi_rs_set_srs_method_data(acpi_handle handle, struct acpi_buffer *in_buffer) | 664 | acpi_rs_set_srs_method_data(struct acpi_namespace_node *node, |
665 | struct acpi_buffer *in_buffer) | ||
660 | { | 666 | { |
661 | struct acpi_parameter_info info; | 667 | struct acpi_evaluate_info *info; |
662 | union acpi_operand_object *params[2]; | 668 | union acpi_operand_object *args[2]; |
663 | acpi_status status; | 669 | acpi_status status; |
664 | struct acpi_buffer buffer; | 670 | struct acpi_buffer buffer; |
665 | 671 | ||
666 | ACPI_FUNCTION_TRACE(rs_set_srs_method_data); | 672 | ACPI_FUNCTION_TRACE(rs_set_srs_method_data); |
667 | 673 | ||
668 | /* Parameters guaranteed valid by caller */ | 674 | /* Allocate and initialize the evaluation information block */ |
675 | |||
676 | info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info)); | ||
677 | if (!info) { | ||
678 | return_ACPI_STATUS(AE_NO_MEMORY); | ||
679 | } | ||
680 | |||
681 | info->prefix_node = node; | ||
682 | info->pathname = METHOD_NAME__SRS; | ||
683 | info->parameters = args; | ||
684 | info->parameter_type = ACPI_PARAM_ARGS; | ||
685 | info->flags = ACPI_IGNORE_RETURN_VALUE; | ||
669 | 686 | ||
670 | /* | 687 | /* |
671 | * The in_buffer parameter will point to a linked list of | 688 | * The in_buffer parameter will point to a linked list of |
672 | * resource parameters. It needs to be formatted into a | 689 | * resource parameters. It needs to be formatted into a |
673 | * byte stream to be sent in as an input parameter to _SRS | 690 | * byte stream to be sent in as an input parameter to _SRS |
674 | * | 691 | * |
675 | * Convert the linked list into a byte stream | 692 | * Convert the linked list into a byte stream |
@@ -677,42 +694,36 @@ acpi_rs_set_srs_method_data(acpi_handle handle, struct acpi_buffer *in_buffer) | |||
677 | buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; | 694 | buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; |
678 | status = acpi_rs_create_aml_resources(in_buffer->pointer, &buffer); | 695 | status = acpi_rs_create_aml_resources(in_buffer->pointer, &buffer); |
679 | if (ACPI_FAILURE(status)) { | 696 | if (ACPI_FAILURE(status)) { |
680 | return_ACPI_STATUS(status); | 697 | goto cleanup; |
681 | } | 698 | } |
682 | 699 | ||
683 | /* Init the param object */ | 700 | /* Create and initialize the method parameter object */ |
684 | 701 | ||
685 | params[0] = acpi_ut_create_internal_object(ACPI_TYPE_BUFFER); | 702 | args[0] = acpi_ut_create_internal_object(ACPI_TYPE_BUFFER); |
686 | if (!params[0]) { | 703 | if (!args[0]) { |
687 | acpi_os_free(buffer.pointer); | 704 | /* |
688 | return_ACPI_STATUS(AE_NO_MEMORY); | 705 | * Must free the buffer allocated above (otherwise it is freed |
706 | * later) | ||
707 | */ | ||
708 | ACPI_FREE(buffer.pointer); | ||
709 | status = AE_NO_MEMORY; | ||
710 | goto cleanup; | ||
689 | } | 711 | } |
690 | 712 | ||
691 | /* Set up the parameter object */ | 713 | args[0]->buffer.length = (u32) buffer.length; |
692 | 714 | args[0]->buffer.pointer = buffer.pointer; | |
693 | params[0]->buffer.length = (u32) buffer.length; | 715 | args[0]->common.flags = AOPOBJ_DATA_VALID; |
694 | params[0]->buffer.pointer = buffer.pointer; | 716 | args[1] = NULL; |
695 | params[0]->common.flags = AOPOBJ_DATA_VALID; | ||
696 | params[1] = NULL; | ||
697 | 717 | ||
698 | info.node = handle; | 718 | /* Execute the method, no return value is expected */ |
699 | info.parameters = params; | ||
700 | info.parameter_type = ACPI_PARAM_ARGS; | ||
701 | 719 | ||
702 | /* Execute the method, no return value */ | 720 | status = acpi_ns_evaluate(info); |
703 | 721 | ||
704 | status = acpi_ns_evaluate_relative(METHOD_NAME__SRS, &info); | 722 | /* Clean up and return the status from acpi_ns_evaluate */ |
705 | if (ACPI_SUCCESS(status)) { | ||
706 | |||
707 | /* Delete any return object (especially if implicit_return is enabled) */ | ||
708 | |||
709 | if (info.return_object) { | ||
710 | acpi_ut_remove_reference(info.return_object); | ||
711 | } | ||
712 | } | ||
713 | 723 | ||
714 | /* Clean up and return the status from acpi_ns_evaluate_relative */ | 724 | acpi_ut_remove_reference(args[0]); |
715 | 725 | ||
716 | acpi_ut_remove_reference(params[0]); | 726 | cleanup: |
727 | ACPI_FREE(info); | ||
717 | return_ACPI_STATUS(status); | 728 | return_ACPI_STATUS(status); |
718 | } | 729 | } |
diff --git a/drivers/acpi/resources/rsxface.c b/drivers/acpi/resources/rsxface.c index 8c1628c12cc8..1999e2ab7daa 100644 --- a/drivers/acpi/resources/rsxface.c +++ b/drivers/acpi/resources/rsxface.c | |||
@@ -43,6 +43,7 @@ | |||
43 | 43 | ||
44 | #include <acpi/acpi.h> | 44 | #include <acpi/acpi.h> |
45 | #include <acpi/acresrc.h> | 45 | #include <acpi/acresrc.h> |
46 | #include <acpi/acnamesp.h> | ||
46 | 47 | ||
47 | #define _COMPONENT ACPI_RESOURCES | 48 | #define _COMPONENT ACPI_RESOURCES |
48 | ACPI_MODULE_NAME("rsxface") | 49 | ACPI_MODULE_NAME("rsxface") |
@@ -66,19 +67,80 @@ ACPI_MODULE_NAME("rsxface") | |||
66 | static acpi_status | 67 | static acpi_status |
67 | acpi_rs_match_vendor_resource(struct acpi_resource *resource, void *context); | 68 | acpi_rs_match_vendor_resource(struct acpi_resource *resource, void *context); |
68 | 69 | ||
70 | static acpi_status | ||
71 | acpi_rs_validate_parameters(acpi_handle device_handle, | ||
72 | struct acpi_buffer *buffer, | ||
73 | struct acpi_namespace_node **return_node); | ||
74 | |||
75 | /******************************************************************************* | ||
76 | * | ||
77 | * FUNCTION: acpi_rs_validate_parameters | ||
78 | * | ||
79 | * PARAMETERS: device_handle - Handle to a device | ||
80 | * Buffer - Pointer to a data buffer | ||
81 | * return_node - Pointer to where the device node is returned | ||
82 | * | ||
83 | * RETURN: Status | ||
84 | * | ||
85 | * DESCRIPTION: Common parameter validation for resource interfaces | ||
86 | * | ||
87 | ******************************************************************************/ | ||
88 | |||
89 | static acpi_status | ||
90 | acpi_rs_validate_parameters(acpi_handle device_handle, | ||
91 | struct acpi_buffer *buffer, | ||
92 | struct acpi_namespace_node **return_node) | ||
93 | { | ||
94 | acpi_status status; | ||
95 | struct acpi_namespace_node *node; | ||
96 | |||
97 | ACPI_FUNCTION_TRACE(rs_validate_parameters); | ||
98 | |||
99 | /* | ||
100 | * Must have a valid handle to an ACPI device | ||
101 | */ | ||
102 | if (!device_handle) { | ||
103 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
104 | } | ||
105 | |||
106 | node = acpi_ns_map_handle_to_node(device_handle); | ||
107 | if (!node) { | ||
108 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
109 | } | ||
110 | |||
111 | if (node->type != ACPI_TYPE_DEVICE) { | ||
112 | return_ACPI_STATUS(AE_TYPE); | ||
113 | } | ||
114 | |||
115 | /* | ||
116 | * Validate the user buffer object | ||
117 | * | ||
118 | * if there is a non-zero buffer length we also need a valid pointer in | ||
119 | * the buffer. If it's a zero buffer length, we'll be returning the | ||
120 | * needed buffer size (later), so keep going. | ||
121 | */ | ||
122 | status = acpi_ut_validate_buffer(buffer); | ||
123 | if (ACPI_FAILURE(status)) { | ||
124 | return_ACPI_STATUS(status); | ||
125 | } | ||
126 | |||
127 | *return_node = node; | ||
128 | return_ACPI_STATUS(AE_OK); | ||
129 | } | ||
130 | |||
69 | /******************************************************************************* | 131 | /******************************************************************************* |
70 | * | 132 | * |
71 | * FUNCTION: acpi_get_irq_routing_table | 133 | * FUNCTION: acpi_get_irq_routing_table |
72 | * | 134 | * |
73 | * PARAMETERS: device_handle - a handle to the Bus device we are querying | 135 | * PARAMETERS: device_handle - Handle to the Bus device we are querying |
74 | * ret_buffer - a pointer to a buffer to receive the | 136 | * ret_buffer - Pointer to a buffer to receive the |
75 | * current resources for the device | 137 | * current resources for the device |
76 | * | 138 | * |
77 | * RETURN: Status | 139 | * RETURN: Status |
78 | * | 140 | * |
79 | * DESCRIPTION: This function is called to get the IRQ routing table for a | 141 | * DESCRIPTION: This function is called to get the IRQ routing table for a |
80 | * specific bus. The caller must first acquire a handle for the | 142 | * specific bus. The caller must first acquire a handle for the |
81 | * desired bus. The routine table is placed in the buffer pointed | 143 | * desired bus. The routine table is placed in the buffer pointed |
82 | * to by the ret_buffer variable parameter. | 144 | * to by the ret_buffer variable parameter. |
83 | * | 145 | * |
84 | * If the function fails an appropriate status will be returned | 146 | * If the function fails an appropriate status will be returned |
@@ -94,25 +156,18 @@ acpi_get_irq_routing_table(acpi_handle device_handle, | |||
94 | struct acpi_buffer *ret_buffer) | 156 | struct acpi_buffer *ret_buffer) |
95 | { | 157 | { |
96 | acpi_status status; | 158 | acpi_status status; |
159 | struct acpi_namespace_node *node; | ||
97 | 160 | ||
98 | ACPI_FUNCTION_TRACE(acpi_get_irq_routing_table); | 161 | ACPI_FUNCTION_TRACE(acpi_get_irq_routing_table); |
99 | 162 | ||
100 | /* | 163 | /* Validate parameters then dispatch to internal routine */ |
101 | * Must have a valid handle and buffer, So we have to have a handle | ||
102 | * and a return buffer structure, and if there is a non-zero buffer length | ||
103 | * we also need a valid pointer in the buffer. If it's a zero buffer length, | ||
104 | * we'll be returning the needed buffer size, so keep going. | ||
105 | */ | ||
106 | if (!device_handle) { | ||
107 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
108 | } | ||
109 | 164 | ||
110 | status = acpi_ut_validate_buffer(ret_buffer); | 165 | status = acpi_rs_validate_parameters(device_handle, ret_buffer, &node); |
111 | if (ACPI_FAILURE(status)) { | 166 | if (ACPI_FAILURE(status)) { |
112 | return_ACPI_STATUS(status); | 167 | return_ACPI_STATUS(status); |
113 | } | 168 | } |
114 | 169 | ||
115 | status = acpi_rs_get_prt_method_data(device_handle, ret_buffer); | 170 | status = acpi_rs_get_prt_method_data(node, ret_buffer); |
116 | return_ACPI_STATUS(status); | 171 | return_ACPI_STATUS(status); |
117 | } | 172 | } |
118 | 173 | ||
@@ -122,16 +177,16 @@ ACPI_EXPORT_SYMBOL(acpi_get_irq_routing_table) | |||
122 | * | 177 | * |
123 | * FUNCTION: acpi_get_current_resources | 178 | * FUNCTION: acpi_get_current_resources |
124 | * | 179 | * |
125 | * PARAMETERS: device_handle - a handle to the device object for the | 180 | * PARAMETERS: device_handle - Handle to the device object for the |
126 | * device we are querying | 181 | * device we are querying |
127 | * ret_buffer - a pointer to a buffer to receive the | 182 | * ret_buffer - Pointer to a buffer to receive the |
128 | * current resources for the device | 183 | * current resources for the device |
129 | * | 184 | * |
130 | * RETURN: Status | 185 | * RETURN: Status |
131 | * | 186 | * |
132 | * DESCRIPTION: This function is called to get the current resources for a | 187 | * DESCRIPTION: This function is called to get the current resources for a |
133 | * specific device. The caller must first acquire a handle for | 188 | * specific device. The caller must first acquire a handle for |
134 | * the desired device. The resource data is placed in the buffer | 189 | * the desired device. The resource data is placed in the buffer |
135 | * pointed to by the ret_buffer variable parameter. | 190 | * pointed to by the ret_buffer variable parameter. |
136 | * | 191 | * |
137 | * If the function fails an appropriate status will be returned | 192 | * If the function fails an appropriate status will be returned |
@@ -146,25 +201,18 @@ acpi_get_current_resources(acpi_handle device_handle, | |||
146 | struct acpi_buffer *ret_buffer) | 201 | struct acpi_buffer *ret_buffer) |
147 | { | 202 | { |
148 | acpi_status status; | 203 | acpi_status status; |
204 | struct acpi_namespace_node *node; | ||
149 | 205 | ||
150 | ACPI_FUNCTION_TRACE(acpi_get_current_resources); | 206 | ACPI_FUNCTION_TRACE(acpi_get_current_resources); |
151 | 207 | ||
152 | /* | 208 | /* Validate parameters then dispatch to internal routine */ |
153 | * Must have a valid handle and buffer, So we have to have a handle | ||
154 | * and a return buffer structure, and if there is a non-zero buffer length | ||
155 | * we also need a valid pointer in the buffer. If it's a zero buffer length, | ||
156 | * we'll be returning the needed buffer size, so keep going. | ||
157 | */ | ||
158 | if (!device_handle) { | ||
159 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
160 | } | ||
161 | 209 | ||
162 | status = acpi_ut_validate_buffer(ret_buffer); | 210 | status = acpi_rs_validate_parameters(device_handle, ret_buffer, &node); |
163 | if (ACPI_FAILURE(status)) { | 211 | if (ACPI_FAILURE(status)) { |
164 | return_ACPI_STATUS(status); | 212 | return_ACPI_STATUS(status); |
165 | } | 213 | } |
166 | 214 | ||
167 | status = acpi_rs_get_crs_method_data(device_handle, ret_buffer); | 215 | status = acpi_rs_get_crs_method_data(node, ret_buffer); |
168 | return_ACPI_STATUS(status); | 216 | return_ACPI_STATUS(status); |
169 | } | 217 | } |
170 | 218 | ||
@@ -175,16 +223,16 @@ ACPI_EXPORT_SYMBOL(acpi_get_current_resources) | |||
175 | * | 223 | * |
176 | * FUNCTION: acpi_get_possible_resources | 224 | * FUNCTION: acpi_get_possible_resources |
177 | * | 225 | * |
178 | * PARAMETERS: device_handle - a handle to the device object for the | 226 | * PARAMETERS: device_handle - Handle to the device object for the |
179 | * device we are querying | 227 | * device we are querying |
180 | * ret_buffer - a pointer to a buffer to receive the | 228 | * ret_buffer - Pointer to a buffer to receive the |
181 | * resources for the device | 229 | * resources for the device |
182 | * | 230 | * |
183 | * RETURN: Status | 231 | * RETURN: Status |
184 | * | 232 | * |
185 | * DESCRIPTION: This function is called to get a list of the possible resources | 233 | * DESCRIPTION: This function is called to get a list of the possible resources |
186 | * for a specific device. The caller must first acquire a handle | 234 | * for a specific device. The caller must first acquire a handle |
187 | * for the desired device. The resource data is placed in the | 235 | * for the desired device. The resource data is placed in the |
188 | * buffer pointed to by the ret_buffer variable. | 236 | * buffer pointed to by the ret_buffer variable. |
189 | * | 237 | * |
190 | * If the function fails an appropriate status will be returned | 238 | * If the function fails an appropriate status will be returned |
@@ -196,25 +244,18 @@ acpi_get_possible_resources(acpi_handle device_handle, | |||
196 | struct acpi_buffer *ret_buffer) | 244 | struct acpi_buffer *ret_buffer) |
197 | { | 245 | { |
198 | acpi_status status; | 246 | acpi_status status; |
247 | struct acpi_namespace_node *node; | ||
199 | 248 | ||
200 | ACPI_FUNCTION_TRACE(acpi_get_possible_resources); | 249 | ACPI_FUNCTION_TRACE(acpi_get_possible_resources); |
201 | 250 | ||
202 | /* | 251 | /* Validate parameters then dispatch to internal routine */ |
203 | * Must have a valid handle and buffer, So we have to have a handle | ||
204 | * and a return buffer structure, and if there is a non-zero buffer length | ||
205 | * we also need a valid pointer in the buffer. If it's a zero buffer length, | ||
206 | * we'll be returning the needed buffer size, so keep going. | ||
207 | */ | ||
208 | if (!device_handle) { | ||
209 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
210 | } | ||
211 | 252 | ||
212 | status = acpi_ut_validate_buffer(ret_buffer); | 253 | status = acpi_rs_validate_parameters(device_handle, ret_buffer, &node); |
213 | if (ACPI_FAILURE(status)) { | 254 | if (ACPI_FAILURE(status)) { |
214 | return_ACPI_STATUS(status); | 255 | return_ACPI_STATUS(status); |
215 | } | 256 | } |
216 | 257 | ||
217 | status = acpi_rs_get_prs_method_data(device_handle, ret_buffer); | 258 | status = acpi_rs_get_prs_method_data(node, ret_buffer); |
218 | return_ACPI_STATUS(status); | 259 | return_ACPI_STATUS(status); |
219 | } | 260 | } |
220 | 261 | ||
@@ -223,113 +264,18 @@ ACPI_EXPORT_SYMBOL(acpi_get_possible_resources) | |||
223 | 264 | ||
224 | /******************************************************************************* | 265 | /******************************************************************************* |
225 | * | 266 | * |
226 | * FUNCTION: acpi_walk_resources | ||
227 | * | ||
228 | * PARAMETERS: device_handle - Handle to the device object for the | ||
229 | * device we are querying | ||
230 | * Name - Method name of the resources we want | ||
231 | * (METHOD_NAME__CRS or METHOD_NAME__PRS) | ||
232 | * user_function - Called for each resource | ||
233 | * Context - Passed to user_function | ||
234 | * | ||
235 | * RETURN: Status | ||
236 | * | ||
237 | * DESCRIPTION: Retrieves the current or possible resource list for the | ||
238 | * specified device. The user_function is called once for | ||
239 | * each resource in the list. | ||
240 | * | ||
241 | ******************************************************************************/ | ||
242 | acpi_status | ||
243 | acpi_walk_resources(acpi_handle device_handle, | ||
244 | char *name, | ||
245 | acpi_walk_resource_callback user_function, void *context) | ||
246 | { | ||
247 | acpi_status status; | ||
248 | struct acpi_buffer buffer; | ||
249 | struct acpi_resource *resource; | ||
250 | struct acpi_resource *resource_end; | ||
251 | |||
252 | ACPI_FUNCTION_TRACE(acpi_walk_resources); | ||
253 | |||
254 | /* Parameter validation */ | ||
255 | |||
256 | if (!device_handle || !user_function || !name || | ||
257 | (!ACPI_COMPARE_NAME(name, METHOD_NAME__CRS) && | ||
258 | !ACPI_COMPARE_NAME(name, METHOD_NAME__PRS))) { | ||
259 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
260 | } | ||
261 | |||
262 | /* Get the _CRS or _PRS resource list */ | ||
263 | |||
264 | buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; | ||
265 | status = acpi_rs_get_method_data(device_handle, name, &buffer); | ||
266 | if (ACPI_FAILURE(status)) { | ||
267 | return_ACPI_STATUS(status); | ||
268 | } | ||
269 | |||
270 | /* Buffer now contains the resource list */ | ||
271 | |||
272 | resource = ACPI_CAST_PTR(struct acpi_resource, buffer.pointer); | ||
273 | resource_end = | ||
274 | ACPI_ADD_PTR(struct acpi_resource, buffer.pointer, buffer.length); | ||
275 | |||
276 | /* Walk the resource list until the end_tag is found (or buffer end) */ | ||
277 | |||
278 | while (resource < resource_end) { | ||
279 | |||
280 | /* Sanity check the resource */ | ||
281 | |||
282 | if (resource->type > ACPI_RESOURCE_TYPE_MAX) { | ||
283 | status = AE_AML_INVALID_RESOURCE_TYPE; | ||
284 | break; | ||
285 | } | ||
286 | |||
287 | /* Invoke the user function, abort on any error returned */ | ||
288 | |||
289 | status = user_function(resource, context); | ||
290 | if (ACPI_FAILURE(status)) { | ||
291 | if (status == AE_CTRL_TERMINATE) { | ||
292 | |||
293 | /* This is an OK termination by the user function */ | ||
294 | |||
295 | status = AE_OK; | ||
296 | } | ||
297 | break; | ||
298 | } | ||
299 | |||
300 | /* end_tag indicates end-of-list */ | ||
301 | |||
302 | if (resource->type == ACPI_RESOURCE_TYPE_END_TAG) { | ||
303 | break; | ||
304 | } | ||
305 | |||
306 | /* Get the next resource descriptor */ | ||
307 | |||
308 | resource = | ||
309 | ACPI_ADD_PTR(struct acpi_resource, resource, | ||
310 | resource->length); | ||
311 | } | ||
312 | |||
313 | ACPI_FREE(buffer.pointer); | ||
314 | return_ACPI_STATUS(status); | ||
315 | } | ||
316 | |||
317 | ACPI_EXPORT_SYMBOL(acpi_walk_resources) | ||
318 | |||
319 | /******************************************************************************* | ||
320 | * | ||
321 | * FUNCTION: acpi_set_current_resources | 267 | * FUNCTION: acpi_set_current_resources |
322 | * | 268 | * |
323 | * PARAMETERS: device_handle - a handle to the device object for the | 269 | * PARAMETERS: device_handle - Handle to the device object for the |
324 | * device we are changing the resources of | 270 | * device we are setting resources |
325 | * in_buffer - a pointer to a buffer containing the | 271 | * in_buffer - Pointer to a buffer containing the |
326 | * resources to be set for the device | 272 | * resources to be set for the device |
327 | * | 273 | * |
328 | * RETURN: Status | 274 | * RETURN: Status |
329 | * | 275 | * |
330 | * DESCRIPTION: This function is called to set the current resources for a | 276 | * DESCRIPTION: This function is called to set the current resources for a |
331 | * specific device. The caller must first acquire a handle for | 277 | * specific device. The caller must first acquire a handle for |
332 | * the desired device. The resource data is passed to the routine | 278 | * the desired device. The resource data is passed to the routine |
333 | * the buffer pointed to by the in_buffer variable. | 279 | * the buffer pointed to by the in_buffer variable. |
334 | * | 280 | * |
335 | ******************************************************************************/ | 281 | ******************************************************************************/ |
@@ -338,17 +284,24 @@ acpi_set_current_resources(acpi_handle device_handle, | |||
338 | struct acpi_buffer *in_buffer) | 284 | struct acpi_buffer *in_buffer) |
339 | { | 285 | { |
340 | acpi_status status; | 286 | acpi_status status; |
287 | struct acpi_namespace_node *node; | ||
341 | 288 | ||
342 | ACPI_FUNCTION_TRACE(acpi_set_current_resources); | 289 | ACPI_FUNCTION_TRACE(acpi_set_current_resources); |
343 | 290 | ||
344 | /* Must have a valid handle and buffer */ | 291 | /* Validate the buffer, don't allow zero length */ |
345 | 292 | ||
346 | if ((!device_handle) || | 293 | if ((!in_buffer) || (!in_buffer->pointer) || (!in_buffer->length)) { |
347 | (!in_buffer) || (!in_buffer->pointer) || (!in_buffer->length)) { | ||
348 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 294 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
349 | } | 295 | } |
350 | 296 | ||
351 | status = acpi_rs_set_srs_method_data(device_handle, in_buffer); | 297 | /* Validate parameters then dispatch to internal routine */ |
298 | |||
299 | status = acpi_rs_validate_parameters(device_handle, in_buffer, &node); | ||
300 | if (ACPI_FAILURE(status)) { | ||
301 | return_ACPI_STATUS(status); | ||
302 | } | ||
303 | |||
304 | status = acpi_rs_set_srs_method_data(node, in_buffer); | ||
352 | return_ACPI_STATUS(status); | 305 | return_ACPI_STATUS(status); |
353 | } | 306 | } |
354 | 307 | ||
@@ -358,15 +311,14 @@ ACPI_EXPORT_SYMBOL(acpi_set_current_resources) | |||
358 | * | 311 | * |
359 | * FUNCTION: acpi_resource_to_address64 | 312 | * FUNCTION: acpi_resource_to_address64 |
360 | * | 313 | * |
361 | * PARAMETERS: Resource - Pointer to a resource | 314 | * PARAMETERS: Resource - Pointer to a resource |
362 | * Out - Pointer to the users's return | 315 | * Out - Pointer to the users's return buffer |
363 | * buffer (a struct | 316 | * (a struct acpi_resource_address64) |
364 | * struct acpi_resource_address64) | ||
365 | * | 317 | * |
366 | * RETURN: Status | 318 | * RETURN: Status |
367 | * | 319 | * |
368 | * DESCRIPTION: If the resource is an address16, address32, or address64, | 320 | * DESCRIPTION: If the resource is an address16, address32, or address64, |
369 | * copy it to the address64 return buffer. This saves the | 321 | * copy it to the address64 return buffer. This saves the |
370 | * caller from having to duplicate code for different-sized | 322 | * caller from having to duplicate code for different-sized |
371 | * addresses. | 323 | * addresses. |
372 | * | 324 | * |
@@ -418,12 +370,12 @@ ACPI_EXPORT_SYMBOL(acpi_resource_to_address64) | |||
418 | * | 370 | * |
419 | * FUNCTION: acpi_get_vendor_resource | 371 | * FUNCTION: acpi_get_vendor_resource |
420 | * | 372 | * |
421 | * PARAMETERS: device_handle - Handle for the parent device object | 373 | * PARAMETERS: device_handle - Handle for the parent device object |
422 | * Name - Method name for the parent resource | 374 | * Name - Method name for the parent resource |
423 | * (METHOD_NAME__CRS or METHOD_NAME__PRS) | 375 | * (METHOD_NAME__CRS or METHOD_NAME__PRS) |
424 | * Uuid - Pointer to the UUID to be matched. | 376 | * Uuid - Pointer to the UUID to be matched. |
425 | * includes both subtype and 16-byte UUID | 377 | * includes both subtype and 16-byte UUID |
426 | * ret_buffer - Where the vendor resource is returned | 378 | * ret_buffer - Where the vendor resource is returned |
427 | * | 379 | * |
428 | * RETURN: Status | 380 | * RETURN: Status |
429 | * | 381 | * |
@@ -525,3 +477,99 @@ acpi_rs_match_vendor_resource(struct acpi_resource *resource, void *context) | |||
525 | } | 477 | } |
526 | 478 | ||
527 | ACPI_EXPORT_SYMBOL(acpi_rs_match_vendor_resource) | 479 | ACPI_EXPORT_SYMBOL(acpi_rs_match_vendor_resource) |
480 | |||
481 | /******************************************************************************* | ||
482 | * | ||
483 | * FUNCTION: acpi_walk_resources | ||
484 | * | ||
485 | * PARAMETERS: device_handle - Handle to the device object for the | ||
486 | * device we are querying | ||
487 | * Name - Method name of the resources we want | ||
488 | * (METHOD_NAME__CRS or METHOD_NAME__PRS) | ||
489 | * user_function - Called for each resource | ||
490 | * Context - Passed to user_function | ||
491 | * | ||
492 | * RETURN: Status | ||
493 | * | ||
494 | * DESCRIPTION: Retrieves the current or possible resource list for the | ||
495 | * specified device. The user_function is called once for | ||
496 | * each resource in the list. | ||
497 | * | ||
498 | ******************************************************************************/ | ||
499 | |||
500 | acpi_status | ||
501 | acpi_walk_resources(acpi_handle device_handle, | ||
502 | char *name, | ||
503 | acpi_walk_resource_callback user_function, void *context) | ||
504 | { | ||
505 | acpi_status status; | ||
506 | struct acpi_buffer buffer; | ||
507 | struct acpi_resource *resource; | ||
508 | struct acpi_resource *resource_end; | ||
509 | |||
510 | ACPI_FUNCTION_TRACE(acpi_walk_resources); | ||
511 | |||
512 | /* Parameter validation */ | ||
513 | |||
514 | if (!device_handle || !user_function || !name || | ||
515 | (!ACPI_COMPARE_NAME(name, METHOD_NAME__CRS) && | ||
516 | !ACPI_COMPARE_NAME(name, METHOD_NAME__PRS))) { | ||
517 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
518 | } | ||
519 | |||
520 | /* Get the _CRS or _PRS resource list */ | ||
521 | |||
522 | buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; | ||
523 | status = acpi_rs_get_method_data(device_handle, name, &buffer); | ||
524 | if (ACPI_FAILURE(status)) { | ||
525 | return_ACPI_STATUS(status); | ||
526 | } | ||
527 | |||
528 | /* Buffer now contains the resource list */ | ||
529 | |||
530 | resource = ACPI_CAST_PTR(struct acpi_resource, buffer.pointer); | ||
531 | resource_end = | ||
532 | ACPI_ADD_PTR(struct acpi_resource, buffer.pointer, buffer.length); | ||
533 | |||
534 | /* Walk the resource list until the end_tag is found (or buffer end) */ | ||
535 | |||
536 | while (resource < resource_end) { | ||
537 | |||
538 | /* Sanity check the resource */ | ||
539 | |||
540 | if (resource->type > ACPI_RESOURCE_TYPE_MAX) { | ||
541 | status = AE_AML_INVALID_RESOURCE_TYPE; | ||
542 | break; | ||
543 | } | ||
544 | |||
545 | /* Invoke the user function, abort on any error returned */ | ||
546 | |||
547 | status = user_function(resource, context); | ||
548 | if (ACPI_FAILURE(status)) { | ||
549 | if (status == AE_CTRL_TERMINATE) { | ||
550 | |||
551 | /* This is an OK termination by the user function */ | ||
552 | |||
553 | status = AE_OK; | ||
554 | } | ||
555 | break; | ||
556 | } | ||
557 | |||
558 | /* end_tag indicates end-of-list */ | ||
559 | |||
560 | if (resource->type == ACPI_RESOURCE_TYPE_END_TAG) { | ||
561 | break; | ||
562 | } | ||
563 | |||
564 | /* Get the next resource descriptor */ | ||
565 | |||
566 | resource = | ||
567 | ACPI_ADD_PTR(struct acpi_resource, resource, | ||
568 | resource->length); | ||
569 | } | ||
570 | |||
571 | ACPI_FREE(buffer.pointer); | ||
572 | return_ACPI_STATUS(status); | ||
573 | } | ||
574 | |||
575 | ACPI_EXPORT_SYMBOL(acpi_walk_resources) | ||
diff --git a/drivers/acpi/tables/tbget.c b/drivers/acpi/tables/tbget.c index 3a4f46ca3884..99eacceff563 100644 --- a/drivers/acpi/tables/tbget.c +++ b/drivers/acpi/tables/tbget.c | |||
@@ -417,7 +417,7 @@ acpi_tb_get_this_table(struct acpi_pointer *address, | |||
417 | * | 417 | * |
418 | * PARAMETERS: table_type - one of the defined table types | 418 | * PARAMETERS: table_type - one of the defined table types |
419 | * Instance - Which table of this type | 419 | * Instance - Which table of this type |
420 | * table_ptr_loc - pointer to location to place the pointer for | 420 | * return_table - pointer to location to place the pointer for |
421 | * return | 421 | * return |
422 | * | 422 | * |
423 | * RETURN: Status | 423 | * RETURN: Status |
@@ -428,58 +428,34 @@ acpi_tb_get_this_table(struct acpi_pointer *address, | |||
428 | 428 | ||
429 | acpi_status | 429 | acpi_status |
430 | acpi_tb_get_table_ptr(acpi_table_type table_type, | 430 | acpi_tb_get_table_ptr(acpi_table_type table_type, |
431 | u32 instance, struct acpi_table_header **table_ptr_loc) | 431 | u32 instance, struct acpi_table_header **return_table) |
432 | { | 432 | { |
433 | struct acpi_table_desc *table_desc; | 433 | struct acpi_table_desc *table_desc; |
434 | u32 i; | 434 | u32 i; |
435 | 435 | ||
436 | ACPI_FUNCTION_TRACE(tb_get_table_ptr); | 436 | ACPI_FUNCTION_TRACE(tb_get_table_ptr); |
437 | 437 | ||
438 | if (!acpi_gbl_DSDT) { | ||
439 | return_ACPI_STATUS(AE_NO_ACPI_TABLES); | ||
440 | } | ||
441 | |||
442 | if (table_type > ACPI_TABLE_ID_MAX) { | 438 | if (table_type > ACPI_TABLE_ID_MAX) { |
443 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 439 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
444 | } | 440 | } |
445 | 441 | ||
446 | /* | 442 | /* Check for instance out of range of the current table count */ |
447 | * For all table types (Single/Multiple), the first | ||
448 | * instance is always in the list head. | ||
449 | */ | ||
450 | if (instance == 1) { | ||
451 | |||
452 | /* Get the first */ | ||
453 | |||
454 | *table_ptr_loc = NULL; | ||
455 | if (acpi_gbl_table_lists[table_type].next) { | ||
456 | *table_ptr_loc = | ||
457 | acpi_gbl_table_lists[table_type].next->pointer; | ||
458 | } | ||
459 | return_ACPI_STATUS(AE_OK); | ||
460 | } | ||
461 | |||
462 | /* Check for instance out of range */ | ||
463 | 443 | ||
464 | if (instance > acpi_gbl_table_lists[table_type].count) { | 444 | if (instance > acpi_gbl_table_lists[table_type].count) { |
465 | return_ACPI_STATUS(AE_NOT_EXIST); | 445 | return_ACPI_STATUS(AE_NOT_EXIST); |
466 | } | 446 | } |
467 | 447 | ||
468 | /* Walk the list to get the desired table | 448 | /* |
469 | * Since the if (Instance == 1) check above checked for the | 449 | * Walk the list to get the desired table |
470 | * first table, setting table_desc equal to the .Next member | 450 | * Note: Instance is one-based |
471 | * is actually pointing to the second table. Therefore, we | ||
472 | * need to walk from the 2nd table until we reach the Instance | ||
473 | * that the user is looking for and return its table pointer. | ||
474 | */ | 451 | */ |
475 | table_desc = acpi_gbl_table_lists[table_type].next; | 452 | table_desc = acpi_gbl_table_lists[table_type].next; |
476 | for (i = 2; i < instance; i++) { | 453 | for (i = 1; i < instance; i++) { |
477 | table_desc = table_desc->next; | 454 | table_desc = table_desc->next; |
478 | } | 455 | } |
479 | 456 | ||
480 | /* We are now pointing to the requested table's descriptor */ | 457 | /* We are now pointing to the requested table's descriptor */ |
481 | 458 | ||
482 | *table_ptr_loc = table_desc->pointer; | 459 | *return_table = table_desc->pointer; |
483 | |||
484 | return_ACPI_STATUS(AE_OK); | 460 | return_ACPI_STATUS(AE_OK); |
485 | } | 461 | } |
diff --git a/drivers/acpi/tables/tbrsdt.c b/drivers/acpi/tables/tbrsdt.c index 494965229fa2..abcb08c2592a 100644 --- a/drivers/acpi/tables/tbrsdt.c +++ b/drivers/acpi/tables/tbrsdt.c | |||
@@ -78,7 +78,7 @@ acpi_status acpi_tb_verify_rsdp(struct acpi_pointer *address) | |||
78 | */ | 78 | */ |
79 | status = acpi_os_map_memory(address->pointer.physical, | 79 | status = acpi_os_map_memory(address->pointer.physical, |
80 | sizeof(struct rsdp_descriptor), | 80 | sizeof(struct rsdp_descriptor), |
81 | (void *)&rsdp); | 81 | ACPI_CAST_PTR(void, &rsdp)); |
82 | if (ACPI_FAILURE(status)) { | 82 | if (ACPI_FAILURE(status)) { |
83 | return_ACPI_STATUS(status); | 83 | return_ACPI_STATUS(status); |
84 | } | 84 | } |
@@ -95,11 +95,16 @@ acpi_status acpi_tb_verify_rsdp(struct acpi_pointer *address) | |||
95 | goto cleanup; | 95 | goto cleanup; |
96 | } | 96 | } |
97 | 97 | ||
98 | /* The RSDP supplied is OK */ | 98 | /* RSDP is ok. Init the table info */ |
99 | 99 | ||
100 | table_info.pointer = ACPI_CAST_PTR(struct acpi_table_header, rsdp); | 100 | table_info.pointer = ACPI_CAST_PTR(struct acpi_table_header, rsdp); |
101 | table_info.length = sizeof(struct rsdp_descriptor); | 101 | table_info.length = sizeof(struct rsdp_descriptor); |
102 | table_info.allocation = ACPI_MEM_MAPPED; | 102 | |
103 | if (address->pointer_type == ACPI_PHYSICAL_POINTER) { | ||
104 | table_info.allocation = ACPI_MEM_MAPPED; | ||
105 | } else { | ||
106 | table_info.allocation = ACPI_MEM_NOT_ALLOCATED; | ||
107 | } | ||
103 | 108 | ||
104 | /* Save the table pointers and allocation info */ | 109 | /* Save the table pointers and allocation info */ |
105 | 110 | ||
diff --git a/drivers/acpi/utilities/utalloc.c b/drivers/acpi/utilities/utalloc.c index 65a7c2ed9aa1..7940fc1bd69e 100644 --- a/drivers/acpi/utilities/utalloc.c +++ b/drivers/acpi/utilities/utalloc.c | |||
@@ -61,24 +61,6 @@ acpi_status acpi_ut_create_caches(void) | |||
61 | { | 61 | { |
62 | acpi_status status; | 62 | acpi_status status; |
63 | 63 | ||
64 | #ifdef ACPI_DBG_TRACK_ALLOCATIONS | ||
65 | |||
66 | /* Memory allocation lists */ | ||
67 | |||
68 | status = acpi_ut_create_list("Acpi-Global", 0, &acpi_gbl_global_list); | ||
69 | if (ACPI_FAILURE(status)) { | ||
70 | return (status); | ||
71 | } | ||
72 | |||
73 | status = | ||
74 | acpi_ut_create_list("Acpi-Namespace", | ||
75 | sizeof(struct acpi_namespace_node), | ||
76 | &acpi_gbl_ns_node_list); | ||
77 | if (ACPI_FAILURE(status)) { | ||
78 | return (status); | ||
79 | } | ||
80 | #endif | ||
81 | |||
82 | /* Object Caches, for frequently used objects */ | 64 | /* Object Caches, for frequently used objects */ |
83 | 65 | ||
84 | status = | 66 | status = |
@@ -125,6 +107,24 @@ acpi_status acpi_ut_create_caches(void) | |||
125 | return (status); | 107 | return (status); |
126 | } | 108 | } |
127 | 109 | ||
110 | #ifdef ACPI_DBG_TRACK_ALLOCATIONS | ||
111 | |||
112 | /* Memory allocation lists */ | ||
113 | |||
114 | status = acpi_ut_create_list("Acpi-Global", 0, &acpi_gbl_global_list); | ||
115 | if (ACPI_FAILURE(status)) { | ||
116 | return (status); | ||
117 | } | ||
118 | |||
119 | status = | ||
120 | acpi_ut_create_list("Acpi-Namespace", | ||
121 | sizeof(struct acpi_namespace_node), | ||
122 | &acpi_gbl_ns_node_list); | ||
123 | if (ACPI_FAILURE(status)) { | ||
124 | return (status); | ||
125 | } | ||
126 | #endif | ||
127 | |||
128 | return (AE_OK); | 128 | return (AE_OK); |
129 | } | 129 | } |
130 | 130 | ||
@@ -158,6 +158,21 @@ acpi_status acpi_ut_delete_caches(void) | |||
158 | (void)acpi_os_delete_cache(acpi_gbl_ps_node_ext_cache); | 158 | (void)acpi_os_delete_cache(acpi_gbl_ps_node_ext_cache); |
159 | acpi_gbl_ps_node_ext_cache = NULL; | 159 | acpi_gbl_ps_node_ext_cache = NULL; |
160 | 160 | ||
161 | #ifdef ACPI_DBG_TRACK_ALLOCATIONS | ||
162 | |||
163 | /* Debug only - display leftover memory allocation, if any */ | ||
164 | |||
165 | acpi_ut_dump_allocations(ACPI_UINT32_MAX, NULL); | ||
166 | |||
167 | /* Free memory lists */ | ||
168 | |||
169 | acpi_os_free(acpi_gbl_global_list); | ||
170 | acpi_gbl_global_list = NULL; | ||
171 | |||
172 | acpi_os_free(acpi_gbl_ns_node_list); | ||
173 | acpi_gbl_ns_node_list = NULL; | ||
174 | #endif | ||
175 | |||
161 | return (AE_OK); | 176 | return (AE_OK); |
162 | } | 177 | } |
163 | 178 | ||
diff --git a/drivers/acpi/utilities/utdelete.c b/drivers/acpi/utilities/utdelete.c index 0bb4b59b2804..67b9f325c6fa 100644 --- a/drivers/acpi/utilities/utdelete.c +++ b/drivers/acpi/utilities/utdelete.c | |||
@@ -319,11 +319,9 @@ acpi_ut_update_ref_count(union acpi_operand_object *object, u32 action) | |||
319 | new_count = count; | 319 | new_count = count; |
320 | 320 | ||
321 | /* | 321 | /* |
322 | * Perform the reference count action | 322 | * Perform the reference count action (increment, decrement, force delete) |
323 | * (increment, decrement, or force delete) | ||
324 | */ | 323 | */ |
325 | switch (action) { | 324 | switch (action) { |
326 | |||
327 | case REF_INCREMENT: | 325 | case REF_INCREMENT: |
328 | 326 | ||
329 | new_count++; | 327 | new_count++; |
@@ -360,7 +358,6 @@ acpi_ut_update_ref_count(union acpi_operand_object *object, u32 action) | |||
360 | if (new_count == 0) { | 358 | if (new_count == 0) { |
361 | acpi_ut_delete_internal_obj(object); | 359 | acpi_ut_delete_internal_obj(object); |
362 | } | 360 | } |
363 | |||
364 | break; | 361 | break; |
365 | 362 | ||
366 | case REF_FORCE_DELETE: | 363 | case REF_FORCE_DELETE: |
@@ -385,13 +382,10 @@ acpi_ut_update_ref_count(union acpi_operand_object *object, u32 action) | |||
385 | * (A deleted object will have a huge reference count) | 382 | * (A deleted object will have a huge reference count) |
386 | */ | 383 | */ |
387 | if (count > ACPI_MAX_REFERENCE_COUNT) { | 384 | if (count > ACPI_MAX_REFERENCE_COUNT) { |
388 | |||
389 | ACPI_WARNING((AE_INFO, | 385 | ACPI_WARNING((AE_INFO, |
390 | "Large Reference Count (%X) in object %p", | 386 | "Large Reference Count (%X) in object %p", count, |
391 | count, object)); | 387 | object)); |
392 | } | 388 | } |
393 | |||
394 | return; | ||
395 | } | 389 | } |
396 | 390 | ||
397 | /******************************************************************************* | 391 | /******************************************************************************* |
@@ -417,7 +411,7 @@ acpi_ut_update_ref_count(union acpi_operand_object *object, u32 action) | |||
417 | ******************************************************************************/ | 411 | ******************************************************************************/ |
418 | 412 | ||
419 | acpi_status | 413 | acpi_status |
420 | acpi_ut_update_object_reference(union acpi_operand_object * object, u16 action) | 414 | acpi_ut_update_object_reference(union acpi_operand_object *object, u16 action) |
421 | { | 415 | { |
422 | acpi_status status = AE_OK; | 416 | acpi_status status = AE_OK; |
423 | union acpi_generic_state *state_list = NULL; | 417 | union acpi_generic_state *state_list = NULL; |
@@ -521,11 +515,11 @@ acpi_ut_update_object_reference(union acpi_operand_object * object, u16 action) | |||
521 | 515 | ||
522 | case ACPI_TYPE_REGION: | 516 | case ACPI_TYPE_REGION: |
523 | default: | 517 | default: |
524 | break; /* No subobjects */ | 518 | break; /* No subobjects for all other types */ |
525 | } | 519 | } |
526 | 520 | ||
527 | /* | 521 | /* |
528 | * Now we can update the count in the main object. This can only | 522 | * Now we can update the count in the main object. This can only |
529 | * happen after we update the sub-objects in case this causes the | 523 | * happen after we update the sub-objects in case this causes the |
530 | * main object to be deleted. | 524 | * main object to be deleted. |
531 | */ | 525 | */ |
@@ -606,8 +600,8 @@ void acpi_ut_remove_reference(union acpi_operand_object *object) | |||
606 | ACPI_FUNCTION_TRACE_PTR(ut_remove_reference, object); | 600 | ACPI_FUNCTION_TRACE_PTR(ut_remove_reference, object); |
607 | 601 | ||
608 | /* | 602 | /* |
609 | * Allow a NULL pointer to be passed in, just ignore it. This saves | 603 | * Allow a NULL pointer to be passed in, just ignore it. This saves |
610 | * each caller from having to check. Also, ignore NS nodes. | 604 | * each caller from having to check. Also, ignore NS nodes. |
611 | * | 605 | * |
612 | */ | 606 | */ |
613 | if (!object || | 607 | if (!object || |
@@ -627,7 +621,7 @@ void acpi_ut_remove_reference(union acpi_operand_object *object) | |||
627 | 621 | ||
628 | /* | 622 | /* |
629 | * Decrement the reference count, and only actually delete the object | 623 | * Decrement the reference count, and only actually delete the object |
630 | * if the reference count becomes 0. (Must also decrement the ref count | 624 | * if the reference count becomes 0. (Must also decrement the ref count |
631 | * of all subobjects!) | 625 | * of all subobjects!) |
632 | */ | 626 | */ |
633 | (void)acpi_ut_update_object_reference(object, REF_DECREMENT); | 627 | (void)acpi_ut_update_object_reference(object, REF_DECREMENT); |
diff --git a/drivers/acpi/utilities/uteval.c b/drivers/acpi/utilities/uteval.c index 444d3a502c46..d6d7121583c0 100644 --- a/drivers/acpi/utilities/uteval.c +++ b/drivers/acpi/utilities/uteval.c | |||
@@ -181,19 +181,26 @@ acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node, | |||
181 | u32 expected_return_btypes, | 181 | u32 expected_return_btypes, |
182 | union acpi_operand_object **return_desc) | 182 | union acpi_operand_object **return_desc) |
183 | { | 183 | { |
184 | struct acpi_parameter_info info; | 184 | struct acpi_evaluate_info *info; |
185 | acpi_status status; | 185 | acpi_status status; |
186 | u32 return_btype; | 186 | u32 return_btype; |
187 | 187 | ||
188 | ACPI_FUNCTION_TRACE(ut_evaluate_object); | 188 | ACPI_FUNCTION_TRACE(ut_evaluate_object); |
189 | 189 | ||
190 | info.node = prefix_node; | 190 | /* Allocate the evaluation information block */ |
191 | info.parameters = NULL; | 191 | |
192 | info.parameter_type = ACPI_PARAM_ARGS; | 192 | info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info)); |
193 | if (!info) { | ||
194 | return_ACPI_STATUS(AE_NO_MEMORY); | ||
195 | } | ||
196 | |||
197 | info->prefix_node = prefix_node; | ||
198 | info->pathname = path; | ||
199 | info->parameter_type = ACPI_PARAM_ARGS; | ||
193 | 200 | ||
194 | /* Evaluate the object/method */ | 201 | /* Evaluate the object/method */ |
195 | 202 | ||
196 | status = acpi_ns_evaluate_relative(path, &info); | 203 | status = acpi_ns_evaluate(info); |
197 | if (ACPI_FAILURE(status)) { | 204 | if (ACPI_FAILURE(status)) { |
198 | if (status == AE_NOT_FOUND) { | 205 | if (status == AE_NOT_FOUND) { |
199 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | 206 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, |
@@ -205,25 +212,25 @@ acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node, | |||
205 | prefix_node, path, status); | 212 | prefix_node, path, status); |
206 | } | 213 | } |
207 | 214 | ||
208 | return_ACPI_STATUS(status); | 215 | goto cleanup; |
209 | } | 216 | } |
210 | 217 | ||
211 | /* Did we get a return object? */ | 218 | /* Did we get a return object? */ |
212 | 219 | ||
213 | if (!info.return_object) { | 220 | if (!info->return_object) { |
214 | if (expected_return_btypes) { | 221 | if (expected_return_btypes) { |
215 | ACPI_ERROR_METHOD("No object was returned from", | 222 | ACPI_ERROR_METHOD("No object was returned from", |
216 | prefix_node, path, AE_NOT_EXIST); | 223 | prefix_node, path, AE_NOT_EXIST); |
217 | 224 | ||
218 | return_ACPI_STATUS(AE_NOT_EXIST); | 225 | status = AE_NOT_EXIST; |
219 | } | 226 | } |
220 | 227 | ||
221 | return_ACPI_STATUS(AE_OK); | 228 | goto cleanup; |
222 | } | 229 | } |
223 | 230 | ||
224 | /* Map the return object type to the bitmapped type */ | 231 | /* Map the return object type to the bitmapped type */ |
225 | 232 | ||
226 | switch (ACPI_GET_OBJECT_TYPE(info.return_object)) { | 233 | switch (ACPI_GET_OBJECT_TYPE(info->return_object)) { |
227 | case ACPI_TYPE_INTEGER: | 234 | case ACPI_TYPE_INTEGER: |
228 | return_btype = ACPI_BTYPE_INTEGER; | 235 | return_btype = ACPI_BTYPE_INTEGER; |
229 | break; | 236 | break; |
@@ -251,8 +258,8 @@ acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node, | |||
251 | * happen frequently if the "implicit return" feature is enabled. | 258 | * happen frequently if the "implicit return" feature is enabled. |
252 | * Just delete the return object and return AE_OK. | 259 | * Just delete the return object and return AE_OK. |
253 | */ | 260 | */ |
254 | acpi_ut_remove_reference(info.return_object); | 261 | acpi_ut_remove_reference(info->return_object); |
255 | return_ACPI_STATUS(AE_OK); | 262 | goto cleanup; |
256 | } | 263 | } |
257 | 264 | ||
258 | /* Is the return object one of the expected types? */ | 265 | /* Is the return object one of the expected types? */ |
@@ -264,19 +271,23 @@ acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node, | |||
264 | ACPI_ERROR((AE_INFO, | 271 | ACPI_ERROR((AE_INFO, |
265 | "Type returned from %s was incorrect: %s, expected Btypes: %X", | 272 | "Type returned from %s was incorrect: %s, expected Btypes: %X", |
266 | path, | 273 | path, |
267 | acpi_ut_get_object_type_name(info.return_object), | 274 | acpi_ut_get_object_type_name(info->return_object), |
268 | expected_return_btypes)); | 275 | expected_return_btypes)); |
269 | 276 | ||
270 | /* On error exit, we must delete the return object */ | 277 | /* On error exit, we must delete the return object */ |
271 | 278 | ||
272 | acpi_ut_remove_reference(info.return_object); | 279 | acpi_ut_remove_reference(info->return_object); |
273 | return_ACPI_STATUS(AE_TYPE); | 280 | status = AE_TYPE; |
281 | goto cleanup; | ||
274 | } | 282 | } |
275 | 283 | ||
276 | /* Object type is OK, return it */ | 284 | /* Object type is OK, return it */ |
277 | 285 | ||
278 | *return_desc = info.return_object; | 286 | *return_desc = info->return_object; |
279 | return_ACPI_STATUS(AE_OK); | 287 | |
288 | cleanup: | ||
289 | ACPI_FREE(info); | ||
290 | return_ACPI_STATUS(status); | ||
280 | } | 291 | } |
281 | 292 | ||
282 | /******************************************************************************* | 293 | /******************************************************************************* |
diff --git a/drivers/acpi/utilities/utinit.c b/drivers/acpi/utilities/utinit.c index c65747d3c880..ff76055eb7d6 100644 --- a/drivers/acpi/utilities/utinit.c +++ b/drivers/acpi/utilities/utinit.c | |||
@@ -228,6 +228,7 @@ void acpi_ut_subsystem_shutdown(void) | |||
228 | /* Subsystem appears active, go ahead and shut it down */ | 228 | /* Subsystem appears active, go ahead and shut it down */ |
229 | 229 | ||
230 | acpi_gbl_shutdown = TRUE; | 230 | acpi_gbl_shutdown = TRUE; |
231 | acpi_gbl_startup_flags = 0; | ||
231 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Shutting down ACPI Subsystem\n")); | 232 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Shutting down ACPI Subsystem\n")); |
232 | 233 | ||
233 | /* Close the acpi_event Handling */ | 234 | /* Close the acpi_event Handling */ |
@@ -245,12 +246,5 @@ void acpi_ut_subsystem_shutdown(void) | |||
245 | /* Purge the local caches */ | 246 | /* Purge the local caches */ |
246 | 247 | ||
247 | (void)acpi_ut_delete_caches(); | 248 | (void)acpi_ut_delete_caches(); |
248 | |||
249 | /* Debug only - display leftover memory allocation, if any */ | ||
250 | |||
251 | #ifdef ACPI_DBG_TRACK_ALLOCATIONS | ||
252 | acpi_ut_dump_allocations(ACPI_UINT32_MAX, NULL); | ||
253 | #endif | ||
254 | |||
255 | return_VOID; | 249 | return_VOID; |
256 | } | 250 | } |
diff --git a/drivers/acpi/utilities/utmisc.c b/drivers/acpi/utilities/utmisc.c index 874467117cec..5c75d35ad1cd 100644 --- a/drivers/acpi/utilities/utmisc.c +++ b/drivers/acpi/utilities/utmisc.c | |||
@@ -601,7 +601,8 @@ acpi_name acpi_ut_repair_name(acpi_name name) | |||
601 | * FUNCTION: acpi_ut_strtoul64 | 601 | * FUNCTION: acpi_ut_strtoul64 |
602 | * | 602 | * |
603 | * PARAMETERS: String - Null terminated string | 603 | * PARAMETERS: String - Null terminated string |
604 | * Base - Radix of the string: 10, 16, or ACPI_ANY_BASE | 604 | * Base - Radix of the string: 16 or ACPI_ANY_BASE; |
605 | * ACPI_ANY_BASE means 'in behalf of to_integer' | ||
605 | * ret_integer - Where the converted integer is returned | 606 | * ret_integer - Where the converted integer is returned |
606 | * | 607 | * |
607 | * RETURN: Status and Converted value | 608 | * RETURN: Status and Converted value |
@@ -617,16 +618,17 @@ acpi_ut_strtoul64(char *string, u32 base, acpi_integer * ret_integer) | |||
617 | u32 this_digit = 0; | 618 | u32 this_digit = 0; |
618 | acpi_integer return_value = 0; | 619 | acpi_integer return_value = 0; |
619 | acpi_integer quotient; | 620 | acpi_integer quotient; |
621 | acpi_integer dividend; | ||
622 | u32 to_integer_op = (base == ACPI_ANY_BASE); | ||
623 | u32 mode32 = (acpi_gbl_integer_byte_width == 4); | ||
624 | u8 valid_digits = 0; | ||
625 | u8 sign_of0x = 0; | ||
626 | u8 term = 0; | ||
620 | 627 | ||
621 | ACPI_FUNCTION_TRACE(ut_stroul64); | 628 | ACPI_FUNCTION_TRACE(ut_stroul64); |
622 | 629 | ||
623 | if ((!string) || !(*string)) { | ||
624 | goto error_exit; | ||
625 | } | ||
626 | |||
627 | switch (base) { | 630 | switch (base) { |
628 | case ACPI_ANY_BASE: | 631 | case ACPI_ANY_BASE: |
629 | case 10: | ||
630 | case 16: | 632 | case 16: |
631 | break; | 633 | break; |
632 | 634 | ||
@@ -635,39 +637,45 @@ acpi_ut_strtoul64(char *string, u32 base, acpi_integer * ret_integer) | |||
635 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 637 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
636 | } | 638 | } |
637 | 639 | ||
640 | if (!string) { | ||
641 | goto error_exit; | ||
642 | } | ||
643 | |||
638 | /* Skip over any white space in the buffer */ | 644 | /* Skip over any white space in the buffer */ |
639 | 645 | ||
640 | while (ACPI_IS_SPACE(*string) || *string == '\t') { | 646 | while ((*string) && (ACPI_IS_SPACE(*string) || *string == '\t')) { |
641 | string++; | 647 | string++; |
642 | } | 648 | } |
643 | 649 | ||
644 | /* | 650 | if (to_integer_op) { |
645 | * If the input parameter Base is zero, then we need to | 651 | /* |
646 | * determine if it is decimal or hexadecimal: | 652 | * Base equal to ACPI_ANY_BASE means 'to_integer operation case'. |
647 | */ | 653 | * We need to determine if it is decimal or hexadecimal. |
648 | if (base == 0) { | 654 | */ |
649 | if ((*string == '0') && (ACPI_TOLOWER(*(string + 1)) == 'x')) { | 655 | if ((*string == '0') && (ACPI_TOLOWER(*(string + 1)) == 'x')) { |
656 | sign_of0x = 1; | ||
650 | base = 16; | 657 | base = 16; |
658 | |||
659 | /* Skip over the leading '0x' */ | ||
651 | string += 2; | 660 | string += 2; |
652 | } else { | 661 | } else { |
653 | base = 10; | 662 | base = 10; |
654 | } | 663 | } |
655 | } | 664 | } |
656 | 665 | ||
657 | /* | 666 | /* Any string left? Check that '0x' is not followed by white space. */ |
658 | * For hexadecimal base, skip over the leading | 667 | |
659 | * 0 or 0x, if they are present. | 668 | if (!(*string) || ACPI_IS_SPACE(*string) || *string == '\t') { |
660 | */ | 669 | if (to_integer_op) { |
661 | if ((base == 16) && | 670 | goto error_exit; |
662 | (*string == '0') && (ACPI_TOLOWER(*(string + 1)) == 'x')) { | 671 | } else { |
663 | string += 2; | 672 | goto all_done; |
673 | } | ||
664 | } | 674 | } |
665 | 675 | ||
666 | /* Any string left? */ | 676 | dividend = (mode32) ? ACPI_UINT32_MAX : ACPI_UINT64_MAX; |
667 | 677 | ||
668 | if (!(*string)) { | 678 | /* At least one character in the string here */ |
669 | goto error_exit; | ||
670 | } | ||
671 | 679 | ||
672 | /* Main loop: convert the string to a 64-bit integer */ | 680 | /* Main loop: convert the string to a 64-bit integer */ |
673 | 681 | ||
@@ -677,14 +685,12 @@ acpi_ut_strtoul64(char *string, u32 base, acpi_integer * ret_integer) | |||
677 | /* Convert ASCII 0-9 to Decimal value */ | 685 | /* Convert ASCII 0-9 to Decimal value */ |
678 | 686 | ||
679 | this_digit = ((u8) * string) - '0'; | 687 | this_digit = ((u8) * string) - '0'; |
680 | } else { | 688 | } else if (base == 10) { |
681 | if (base == 10) { | ||
682 | 689 | ||
683 | /* Digit is out of range */ | 690 | /* Digit is out of range; possible in to_integer case only */ |
684 | |||
685 | goto error_exit; | ||
686 | } | ||
687 | 691 | ||
692 | term = 1; | ||
693 | } else { | ||
688 | this_digit = (u8) ACPI_TOUPPER(*string); | 694 | this_digit = (u8) ACPI_TOUPPER(*string); |
689 | if (ACPI_IS_XDIGIT((char)this_digit)) { | 695 | if (ACPI_IS_XDIGIT((char)this_digit)) { |
690 | 696 | ||
@@ -692,22 +698,49 @@ acpi_ut_strtoul64(char *string, u32 base, acpi_integer * ret_integer) | |||
692 | 698 | ||
693 | this_digit = this_digit - 'A' + 10; | 699 | this_digit = this_digit - 'A' + 10; |
694 | } else { | 700 | } else { |
695 | /* | 701 | term = 1; |
696 | * We allow non-hex chars, just stop now, same as end-of-string. | 702 | } |
697 | * See ACPI spec, string-to-integer conversion. | 703 | } |
698 | */ | 704 | |
705 | if (term) { | ||
706 | if (to_integer_op) { | ||
707 | goto error_exit; | ||
708 | } else { | ||
699 | break; | 709 | break; |
700 | } | 710 | } |
711 | } else if ((valid_digits == 0) && (this_digit == 0) | ||
712 | && !sign_of0x) { | ||
713 | |||
714 | /* Skip zeros */ | ||
715 | string++; | ||
716 | continue; | ||
717 | } | ||
718 | |||
719 | valid_digits++; | ||
720 | |||
721 | if (sign_of0x | ||
722 | && ((valid_digits > 16) | ||
723 | || ((valid_digits > 8) && mode32))) { | ||
724 | /* | ||
725 | * This is to_integer operation case. | ||
726 | * No any restrictions for string-to-integer conversion, | ||
727 | * see ACPI spec. | ||
728 | */ | ||
729 | goto error_exit; | ||
701 | } | 730 | } |
702 | 731 | ||
703 | /* Divide the digit into the correct position */ | 732 | /* Divide the digit into the correct position */ |
704 | 733 | ||
705 | (void) | 734 | (void) |
706 | acpi_ut_short_divide((ACPI_INTEGER_MAX - | 735 | acpi_ut_short_divide((dividend - (acpi_integer) this_digit), |
707 | (acpi_integer) this_digit), base, | 736 | base, "ient, NULL); |
708 | "ient, NULL); | 737 | |
709 | if (return_value > quotient) { | 738 | if (return_value > quotient) { |
710 | goto error_exit; | 739 | if (to_integer_op) { |
740 | goto error_exit; | ||
741 | } else { | ||
742 | break; | ||
743 | } | ||
711 | } | 744 | } |
712 | 745 | ||
713 | return_value *= base; | 746 | return_value *= base; |
@@ -717,6 +750,8 @@ acpi_ut_strtoul64(char *string, u32 base, acpi_integer * ret_integer) | |||
717 | 750 | ||
718 | /* All done, normal exit */ | 751 | /* All done, normal exit */ |
719 | 752 | ||
753 | all_done: | ||
754 | |||
720 | *ret_integer = return_value; | 755 | *ret_integer = return_value; |
721 | return_ACPI_STATUS(AE_OK); | 756 | return_ACPI_STATUS(AE_OK); |
722 | 757 | ||