diff options
Diffstat (limited to 'drivers/acpi/dispatcher/dswload.c')
-rw-r--r-- | drivers/acpi/dispatcher/dswload.c | 244 |
1 files changed, 176 insertions, 68 deletions
diff --git a/drivers/acpi/dispatcher/dswload.c b/drivers/acpi/dispatcher/dswload.c index 411731261c29..4cad6afa82f7 100644 --- a/drivers/acpi/dispatcher/dswload.c +++ b/drivers/acpi/dispatcher/dswload.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2005, R. Byron Moore | 8 | * Copyright (C) 2000 - 2006, R. Byron Moore |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -127,7 +127,7 @@ acpi_ds_load1_begin_op(struct acpi_walk_state * walk_state, | |||
127 | char *path; | 127 | char *path; |
128 | u32 flags; | 128 | u32 flags; |
129 | 129 | ||
130 | ACPI_FUNCTION_NAME("ds_load1_begin_op"); | 130 | ACPI_FUNCTION_TRACE("ds_load1_begin_op"); |
131 | 131 | ||
132 | op = walk_state->op; | 132 | op = walk_state->op; |
133 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op, | 133 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op, |
@@ -138,14 +138,14 @@ acpi_ds_load1_begin_op(struct acpi_walk_state * walk_state, | |||
138 | if (op) { | 138 | if (op) { |
139 | if (!(walk_state->op_info->flags & AML_NAMED)) { | 139 | if (!(walk_state->op_info->flags & AML_NAMED)) { |
140 | *out_op = op; | 140 | *out_op = op; |
141 | return (AE_OK); | 141 | return_ACPI_STATUS(AE_OK); |
142 | } | 142 | } |
143 | 143 | ||
144 | /* Check if this object has already been installed in the namespace */ | 144 | /* Check if this object has already been installed in the namespace */ |
145 | 145 | ||
146 | if (op->common.node) { | 146 | if (op->common.node) { |
147 | *out_op = op; | 147 | *out_op = op; |
148 | return (AE_OK); | 148 | return_ACPI_STATUS(AE_OK); |
149 | } | 149 | } |
150 | } | 150 | } |
151 | 151 | ||
@@ -188,7 +188,7 @@ acpi_ds_load1_begin_op(struct acpi_walk_state * walk_state, | |||
188 | #endif | 188 | #endif |
189 | if (ACPI_FAILURE(status)) { | 189 | if (ACPI_FAILURE(status)) { |
190 | ACPI_REPORT_NSERROR(path, status); | 190 | ACPI_REPORT_NSERROR(path, status); |
191 | return (status); | 191 | return_ACPI_STATUS(status); |
192 | } | 192 | } |
193 | 193 | ||
194 | /* | 194 | /* |
@@ -235,7 +235,7 @@ acpi_ds_load1_begin_op(struct acpi_walk_state * walk_state, | |||
235 | 235 | ||
236 | ACPI_REPORT_ERROR(("Invalid type (%s) for target of Scope operator [%4.4s] (Cannot override)\n", acpi_ut_get_type_name(node->type), path)); | 236 | ACPI_REPORT_ERROR(("Invalid type (%s) for target of Scope operator [%4.4s] (Cannot override)\n", acpi_ut_get_type_name(node->type), path)); |
237 | 237 | ||
238 | return (AE_AML_OPERAND_TYPE); | 238 | return_ACPI_STATUS(AE_AML_OPERAND_TYPE); |
239 | } | 239 | } |
240 | break; | 240 | break; |
241 | 241 | ||
@@ -257,6 +257,7 @@ acpi_ds_load1_begin_op(struct acpi_walk_state * walk_state, | |||
257 | * buffer_field, or Package), the name of the object is already | 257 | * buffer_field, or Package), the name of the object is already |
258 | * in the namespace. | 258 | * in the namespace. |
259 | */ | 259 | */ |
260 | |||
260 | if (walk_state->deferred_node) { | 261 | if (walk_state->deferred_node) { |
261 | /* This name is already in the namespace, get the node */ | 262 | /* This name is already in the namespace, get the node */ |
262 | 263 | ||
@@ -265,6 +266,16 @@ acpi_ds_load1_begin_op(struct acpi_walk_state * walk_state, | |||
265 | break; | 266 | break; |
266 | } | 267 | } |
267 | 268 | ||
269 | /* | ||
270 | * If we are executing a method, do not create any namespace objects | ||
271 | * during the load phase, only during execution. | ||
272 | */ | ||
273 | if (walk_state->method_node) { | ||
274 | node = NULL; | ||
275 | status = AE_OK; | ||
276 | break; | ||
277 | } | ||
278 | |||
268 | flags = ACPI_NS_NO_UPSEARCH; | 279 | flags = ACPI_NS_NO_UPSEARCH; |
269 | if ((walk_state->opcode != AML_SCOPE_OP) && | 280 | if ((walk_state->opcode != AML_SCOPE_OP) && |
270 | (!(walk_state->parse_flags & ACPI_PARSE_DEFERRED_OP))) { | 281 | (!(walk_state->parse_flags & ACPI_PARSE_DEFERRED_OP))) { |
@@ -290,7 +301,7 @@ acpi_ds_load1_begin_op(struct acpi_walk_state * walk_state, | |||
290 | &(node)); | 301 | &(node)); |
291 | if (ACPI_FAILURE(status)) { | 302 | if (ACPI_FAILURE(status)) { |
292 | ACPI_REPORT_NSERROR(path, status); | 303 | ACPI_REPORT_NSERROR(path, status); |
293 | return (status); | 304 | return_ACPI_STATUS(status); |
294 | } | 305 | } |
295 | break; | 306 | break; |
296 | } | 307 | } |
@@ -302,28 +313,29 @@ acpi_ds_load1_begin_op(struct acpi_walk_state * walk_state, | |||
302 | 313 | ||
303 | op = acpi_ps_alloc_op(walk_state->opcode); | 314 | op = acpi_ps_alloc_op(walk_state->opcode); |
304 | if (!op) { | 315 | if (!op) { |
305 | return (AE_NO_MEMORY); | 316 | return_ACPI_STATUS(AE_NO_MEMORY); |
306 | } | 317 | } |
307 | } | 318 | } |
308 | 319 | ||
309 | /* Initialize */ | 320 | /* Initialize the op */ |
310 | |||
311 | op->named.name = node->name.integer; | ||
312 | 321 | ||
313 | #if (defined (ACPI_NO_METHOD_EXECUTION) || defined (ACPI_CONSTANT_EVAL_ONLY)) | 322 | #if (defined (ACPI_NO_METHOD_EXECUTION) || defined (ACPI_CONSTANT_EVAL_ONLY)) |
314 | op->named.path = (u8 *) path; | 323 | op->named.path = ACPI_CAST_PTR(u8, path); |
315 | #endif | 324 | #endif |
316 | 325 | ||
317 | /* | 326 | if (node) { |
318 | * Put the Node in the "op" object that the parser uses, so we | 327 | /* |
319 | * can get it again quickly when this scope is closed | 328 | * Put the Node in the "op" object that the parser uses, so we |
320 | */ | 329 | * can get it again quickly when this scope is closed |
321 | op->common.node = node; | 330 | */ |
331 | op->common.node = node; | ||
332 | op->named.name = node->name.integer; | ||
333 | } | ||
334 | |||
322 | acpi_ps_append_arg(acpi_ps_get_parent_scope(&walk_state->parser_state), | 335 | acpi_ps_append_arg(acpi_ps_get_parent_scope(&walk_state->parser_state), |
323 | op); | 336 | op); |
324 | |||
325 | *out_op = op; | 337 | *out_op = op; |
326 | return (status); | 338 | return_ACPI_STATUS(status); |
327 | } | 339 | } |
328 | 340 | ||
329 | /******************************************************************************* | 341 | /******************************************************************************* |
@@ -339,13 +351,13 @@ acpi_ds_load1_begin_op(struct acpi_walk_state * walk_state, | |||
339 | * | 351 | * |
340 | ******************************************************************************/ | 352 | ******************************************************************************/ |
341 | 353 | ||
342 | acpi_status acpi_ds_load1_end_op(struct acpi_walk_state * walk_state) | 354 | acpi_status acpi_ds_load1_end_op(struct acpi_walk_state *walk_state) |
343 | { | 355 | { |
344 | union acpi_parse_object *op; | 356 | union acpi_parse_object *op; |
345 | acpi_object_type object_type; | 357 | acpi_object_type object_type; |
346 | acpi_status status = AE_OK; | 358 | acpi_status status = AE_OK; |
347 | 359 | ||
348 | ACPI_FUNCTION_NAME("ds_load1_end_op"); | 360 | ACPI_FUNCTION_TRACE("ds_load1_end_op"); |
349 | 361 | ||
350 | op = walk_state->op; | 362 | op = walk_state->op; |
351 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op, | 363 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op, |
@@ -354,7 +366,7 @@ acpi_status acpi_ds_load1_end_op(struct acpi_walk_state * walk_state) | |||
354 | /* We are only interested in opcodes that have an associated name */ | 366 | /* We are only interested in opcodes that have an associated name */ |
355 | 367 | ||
356 | if (!(walk_state->op_info->flags & (AML_NAMED | AML_FIELD))) { | 368 | if (!(walk_state->op_info->flags & (AML_NAMED | AML_FIELD))) { |
357 | return (AE_OK); | 369 | return_ACPI_STATUS(AE_OK); |
358 | } | 370 | } |
359 | 371 | ||
360 | /* Get the object type to determine if we should pop the scope */ | 372 | /* Get the object type to determine if we should pop the scope */ |
@@ -363,21 +375,37 @@ acpi_status acpi_ds_load1_end_op(struct acpi_walk_state * walk_state) | |||
363 | 375 | ||
364 | #ifndef ACPI_NO_METHOD_EXECUTION | 376 | #ifndef ACPI_NO_METHOD_EXECUTION |
365 | if (walk_state->op_info->flags & AML_FIELD) { | 377 | if (walk_state->op_info->flags & AML_FIELD) { |
366 | if (walk_state->opcode == AML_FIELD_OP || | 378 | /* |
367 | walk_state->opcode == AML_BANK_FIELD_OP || | 379 | * If we are executing a method, do not create any namespace objects |
368 | walk_state->opcode == AML_INDEX_FIELD_OP) { | 380 | * during the load phase, only during execution. |
369 | status = acpi_ds_init_field_objects(op, walk_state); | 381 | */ |
382 | if (!walk_state->method_node) { | ||
383 | if (walk_state->opcode == AML_FIELD_OP || | ||
384 | walk_state->opcode == AML_BANK_FIELD_OP || | ||
385 | walk_state->opcode == AML_INDEX_FIELD_OP) { | ||
386 | status = | ||
387 | acpi_ds_init_field_objects(op, walk_state); | ||
388 | } | ||
370 | } | 389 | } |
371 | return (status); | 390 | return_ACPI_STATUS(status); |
372 | } | 391 | } |
373 | 392 | ||
374 | if (op->common.aml_opcode == AML_REGION_OP) { | 393 | /* |
375 | status = acpi_ex_create_region(op->named.data, op->named.length, | 394 | * If we are executing a method, do not create any namespace objects |
376 | (acpi_adr_space_type) | 395 | * during the load phase, only during execution. |
377 | ((op->common.value.arg)->common. | 396 | */ |
378 | value.integer), walk_state); | 397 | if (!walk_state->method_node) { |
379 | if (ACPI_FAILURE(status)) { | 398 | if (op->common.aml_opcode == AML_REGION_OP) { |
380 | return (status); | 399 | status = |
400 | acpi_ex_create_region(op->named.data, | ||
401 | op->named.length, | ||
402 | (acpi_adr_space_type) | ||
403 | ((op->common.value.arg)-> | ||
404 | common.value.integer), | ||
405 | walk_state); | ||
406 | if (ACPI_FAILURE(status)) { | ||
407 | return_ACPI_STATUS(status); | ||
408 | } | ||
381 | } | 409 | } |
382 | } | 410 | } |
383 | #endif | 411 | #endif |
@@ -391,47 +419,63 @@ acpi_status acpi_ds_load1_end_op(struct acpi_walk_state * walk_state) | |||
391 | common. | 419 | common. |
392 | aml_opcode))-> | 420 | aml_opcode))-> |
393 | object_type; | 421 | object_type; |
394 | op->common.node->type = (u8) object_type; | 422 | |
423 | /* Set node type if we have a namespace node */ | ||
424 | |||
425 | if (op->common.node) { | ||
426 | op->common.node->type = (u8) object_type; | ||
427 | } | ||
395 | } | 428 | } |
396 | } | 429 | } |
397 | 430 | ||
398 | if (op->common.aml_opcode == AML_METHOD_OP) { | 431 | /* |
399 | /* | 432 | * If we are executing a method, do not create any namespace objects |
400 | * method_op pkg_length name_string method_flags term_list | 433 | * during the load phase, only during execution. |
401 | * | 434 | */ |
402 | * Note: We must create the method node/object pair as soon as we | 435 | if (!walk_state->method_node) { |
403 | * see the method declaration. This allows later pass1 parsing | 436 | if (op->common.aml_opcode == AML_METHOD_OP) { |
404 | * of invocations of the method (need to know the number of | 437 | /* |
405 | * arguments.) | 438 | * method_op pkg_length name_string method_flags term_list |
406 | */ | 439 | * |
407 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, | 440 | * Note: We must create the method node/object pair as soon as we |
408 | "LOADING-Method: State=%p Op=%p named_obj=%p\n", | 441 | * see the method declaration. This allows later pass1 parsing |
409 | walk_state, op, op->named.node)); | 442 | * of invocations of the method (need to know the number of |
443 | * arguments.) | ||
444 | */ | ||
445 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, | ||
446 | "LOADING-Method: State=%p Op=%p named_obj=%p\n", | ||
447 | walk_state, op, op->named.node)); | ||
410 | 448 | ||
411 | if (!acpi_ns_get_attached_object(op->named.node)) { | 449 | if (!acpi_ns_get_attached_object(op->named.node)) { |
412 | walk_state->operands[0] = (void *)op->named.node; | 450 | walk_state->operands[0] = |
413 | walk_state->num_operands = 1; | 451 | ACPI_CAST_PTR(void, op->named.node); |
452 | walk_state->num_operands = 1; | ||
414 | 453 | ||
415 | status = | 454 | status = |
416 | acpi_ds_create_operands(walk_state, | 455 | acpi_ds_create_operands(walk_state, |
417 | op->common.value.arg); | 456 | op->common.value. |
418 | if (ACPI_SUCCESS(status)) { | 457 | arg); |
419 | status = acpi_ex_create_method(op->named.data, | 458 | if (ACPI_SUCCESS(status)) { |
420 | op->named.length, | 459 | status = |
421 | walk_state); | 460 | acpi_ex_create_method(op->named. |
422 | } | 461 | data, |
423 | walk_state->operands[0] = NULL; | 462 | op->named. |
424 | walk_state->num_operands = 0; | 463 | length, |
464 | walk_state); | ||
465 | } | ||
466 | walk_state->operands[0] = NULL; | ||
467 | walk_state->num_operands = 0; | ||
425 | 468 | ||
426 | if (ACPI_FAILURE(status)) { | 469 | if (ACPI_FAILURE(status)) { |
427 | return (status); | 470 | return_ACPI_STATUS(status); |
471 | } | ||
428 | } | 472 | } |
429 | } | 473 | } |
430 | } | 474 | } |
431 | 475 | ||
432 | /* Pop the scope stack */ | 476 | /* Pop the scope stack (only if loading a table) */ |
433 | 477 | ||
434 | if (acpi_ns_opens_scope(object_type)) { | 478 | if (!walk_state->method_node && acpi_ns_opens_scope(object_type)) { |
435 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, | 479 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, |
436 | "(%s): Popping scope for Op %p\n", | 480 | "(%s): Popping scope for Op %p\n", |
437 | acpi_ut_get_type_name(object_type), op)); | 481 | acpi_ut_get_type_name(object_type), op)); |
@@ -439,7 +483,7 @@ acpi_status acpi_ds_load1_end_op(struct acpi_walk_state * walk_state) | |||
439 | status = acpi_ds_scope_stack_pop(walk_state); | 483 | status = acpi_ds_scope_stack_pop(walk_state); |
440 | } | 484 | } |
441 | 485 | ||
442 | return (status); | 486 | return_ACPI_STATUS(status); |
443 | } | 487 | } |
444 | 488 | ||
445 | /******************************************************************************* | 489 | /******************************************************************************* |
@@ -456,8 +500,8 @@ acpi_status acpi_ds_load1_end_op(struct acpi_walk_state * walk_state) | |||
456 | ******************************************************************************/ | 500 | ******************************************************************************/ |
457 | 501 | ||
458 | acpi_status | 502 | acpi_status |
459 | acpi_ds_load2_begin_op(struct acpi_walk_state * walk_state, | 503 | acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state, |
460 | union acpi_parse_object ** out_op) | 504 | union acpi_parse_object **out_op) |
461 | { | 505 | { |
462 | union acpi_parse_object *op; | 506 | union acpi_parse_object *op; |
463 | struct acpi_namespace_node *node; | 507 | struct acpi_namespace_node *node; |
@@ -840,6 +884,13 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state) | |||
840 | 884 | ||
841 | case AML_TYPE_NAMED_FIELD: | 885 | case AML_TYPE_NAMED_FIELD: |
842 | 886 | ||
887 | /* | ||
888 | * If we are executing a method, initialize the field | ||
889 | */ | ||
890 | if (walk_state->method_node) { | ||
891 | status = acpi_ds_init_field_objects(op, walk_state); | ||
892 | } | ||
893 | |||
843 | switch (op->common.aml_opcode) { | 894 | switch (op->common.aml_opcode) { |
844 | case AML_INDEX_FIELD_OP: | 895 | case AML_INDEX_FIELD_OP: |
845 | 896 | ||
@@ -929,6 +980,24 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state) | |||
929 | switch (op->common.aml_opcode) { | 980 | switch (op->common.aml_opcode) { |
930 | #ifndef ACPI_NO_METHOD_EXECUTION | 981 | #ifndef ACPI_NO_METHOD_EXECUTION |
931 | case AML_REGION_OP: | 982 | case AML_REGION_OP: |
983 | |||
984 | /* | ||
985 | * If we are executing a method, initialize the region | ||
986 | */ | ||
987 | if (walk_state->method_node) { | ||
988 | status = | ||
989 | acpi_ex_create_region(op->named.data, | ||
990 | op->named.length, | ||
991 | (acpi_adr_space_type) | ||
992 | ((op->common.value. | ||
993 | arg)->common.value. | ||
994 | integer), | ||
995 | walk_state); | ||
996 | if (ACPI_FAILURE(status)) { | ||
997 | return (status); | ||
998 | } | ||
999 | } | ||
1000 | |||
932 | /* | 1001 | /* |
933 | * The op_region is not fully parsed at this time. Only valid | 1002 | * The op_region is not fully parsed at this time. Only valid |
934 | * argument is the space_id. (We must save the address of the | 1003 | * argument is the space_id. (We must save the address of the |
@@ -957,11 +1026,50 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state) | |||
957 | 1026 | ||
958 | status = acpi_ds_create_node(walk_state, node, op); | 1027 | status = acpi_ds_create_node(walk_state, node, op); |
959 | break; | 1028 | break; |
1029 | |||
1030 | case AML_METHOD_OP: | ||
1031 | /* | ||
1032 | * method_op pkg_length name_string method_flags term_list | ||
1033 | * | ||
1034 | * Note: We must create the method node/object pair as soon as we | ||
1035 | * see the method declaration. This allows later pass1 parsing | ||
1036 | * of invocations of the method (need to know the number of | ||
1037 | * arguments.) | ||
1038 | */ | ||
1039 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, | ||
1040 | "LOADING-Method: State=%p Op=%p named_obj=%p\n", | ||
1041 | walk_state, op, op->named.node)); | ||
1042 | |||
1043 | if (!acpi_ns_get_attached_object(op->named.node)) { | ||
1044 | walk_state->operands[0] = | ||
1045 | ACPI_CAST_PTR(void, op->named.node); | ||
1046 | walk_state->num_operands = 1; | ||
1047 | |||
1048 | status = | ||
1049 | acpi_ds_create_operands(walk_state, | ||
1050 | op->common.value. | ||
1051 | arg); | ||
1052 | if (ACPI_SUCCESS(status)) { | ||
1053 | status = | ||
1054 | acpi_ex_create_method(op->named. | ||
1055 | data, | ||
1056 | op->named. | ||
1057 | length, | ||
1058 | walk_state); | ||
1059 | } | ||
1060 | walk_state->operands[0] = NULL; | ||
1061 | walk_state->num_operands = 0; | ||
1062 | |||
1063 | if (ACPI_FAILURE(status)) { | ||
1064 | return_ACPI_STATUS(status); | ||
1065 | } | ||
1066 | } | ||
1067 | break; | ||
1068 | |||
960 | #endif /* ACPI_NO_METHOD_EXECUTION */ | 1069 | #endif /* ACPI_NO_METHOD_EXECUTION */ |
961 | 1070 | ||
962 | default: | 1071 | default: |
963 | /* All NAMED_COMPLEX opcodes must be handled above */ | 1072 | /* All NAMED_COMPLEX opcodes must be handled above */ |
964 | /* Note: Method objects were already created in Pass 1 */ | ||
965 | break; | 1073 | break; |
966 | } | 1074 | } |
967 | break; | 1075 | break; |