diff options
author | Bob Moore <robert.moore@intel.com> | 2005-12-02 18:27:00 -0500 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2005-12-10 00:29:11 -0500 |
commit | 28f55ebce5bd2fceec8adc7c8860953d3e4532a8 (patch) | |
tree | 2c5c10c18e51f9a717514dfccdc287fc517730c6 /drivers/acpi/dispatcher/dswload.c | |
parent | c51a4de85de720670f2fbc592a6f8040af72ad87 (diff) |
[ACPI] ACPICA 20051202
Modified the parsing of control methods to no longer
create namespace objects during the first pass of the
parse. Objects are now created only during the execute
phase, at the moment the namespace creation operator
is encountered in the AML (Name, OperationRegion,
CreateByteField, etc.) This should eliminate ALREADY_EXISTS
exceptions seen on some machines where reentrant control
methods are protected by an AML mutex. The mutex will now
correctly block multiple threads from attempting to create
the same object more than once.
Increased the number of available Owner Ids for namespace
object tracking from 32 to 255. This should eliminate the
OWNER_ID_LIMIT exceptions seen on some machines with a
large number of ACPI tables (either static or dynamic).
Enhanced the namespace dump routine to output the owner
ID for each namespace object.
Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/dispatcher/dswload.c')
-rw-r--r-- | drivers/acpi/dispatcher/dswload.c | 132 |
1 files changed, 95 insertions, 37 deletions
diff --git a/drivers/acpi/dispatcher/dswload.c b/drivers/acpi/dispatcher/dswload.c index 89d318cbc8a3..44d4f4bb2f92 100644 --- a/drivers/acpi/dispatcher/dswload.c +++ b/drivers/acpi/dispatcher/dswload.c | |||
@@ -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 = ACPI_CAST_PTR(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,7 +419,12 @@ 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 | ||
@@ -424,7 +457,7 @@ acpi_status acpi_ds_load1_end_op(struct acpi_walk_state * walk_state) | |||
424 | walk_state->num_operands = 0; | 457 | walk_state->num_operands = 0; |
425 | 458 | ||
426 | if (ACPI_FAILURE(status)) { | 459 | if (ACPI_FAILURE(status)) { |
427 | return (status); | 460 | return_ACPI_STATUS(status); |
428 | } | 461 | } |
429 | } | 462 | } |
430 | } | 463 | } |
@@ -439,7 +472,7 @@ acpi_status acpi_ds_load1_end_op(struct acpi_walk_state * walk_state) | |||
439 | status = acpi_ds_scope_stack_pop(walk_state); | 472 | status = acpi_ds_scope_stack_pop(walk_state); |
440 | } | 473 | } |
441 | 474 | ||
442 | return (status); | 475 | return_ACPI_STATUS(status); |
443 | } | 476 | } |
444 | 477 | ||
445 | /******************************************************************************* | 478 | /******************************************************************************* |
@@ -456,8 +489,8 @@ acpi_status acpi_ds_load1_end_op(struct acpi_walk_state * walk_state) | |||
456 | ******************************************************************************/ | 489 | ******************************************************************************/ |
457 | 490 | ||
458 | acpi_status | 491 | acpi_status |
459 | acpi_ds_load2_begin_op(struct acpi_walk_state * walk_state, | 492 | acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state, |
460 | union acpi_parse_object ** out_op) | 493 | union acpi_parse_object **out_op) |
461 | { | 494 | { |
462 | union acpi_parse_object *op; | 495 | union acpi_parse_object *op; |
463 | struct acpi_namespace_node *node; | 496 | struct acpi_namespace_node *node; |
@@ -840,6 +873,13 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state) | |||
840 | 873 | ||
841 | case AML_TYPE_NAMED_FIELD: | 874 | case AML_TYPE_NAMED_FIELD: |
842 | 875 | ||
876 | /* | ||
877 | * If we are executing a method, initialize the field | ||
878 | */ | ||
879 | if (walk_state->method_node) { | ||
880 | status = acpi_ds_init_field_objects(op, walk_state); | ||
881 | } | ||
882 | |||
843 | switch (op->common.aml_opcode) { | 883 | switch (op->common.aml_opcode) { |
844 | case AML_INDEX_FIELD_OP: | 884 | case AML_INDEX_FIELD_OP: |
845 | 885 | ||
@@ -929,6 +969,24 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state) | |||
929 | switch (op->common.aml_opcode) { | 969 | switch (op->common.aml_opcode) { |
930 | #ifndef ACPI_NO_METHOD_EXECUTION | 970 | #ifndef ACPI_NO_METHOD_EXECUTION |
931 | case AML_REGION_OP: | 971 | case AML_REGION_OP: |
972 | |||
973 | /* | ||
974 | * If we are executing a method, initialize the region | ||
975 | */ | ||
976 | if (walk_state->method_node) { | ||
977 | status = | ||
978 | acpi_ex_create_region(op->named.data, | ||
979 | op->named.length, | ||
980 | (acpi_adr_space_type) | ||
981 | ((op->common.value. | ||
982 | arg)->common.value. | ||
983 | integer), | ||
984 | walk_state); | ||
985 | if (ACPI_FAILURE(status)) { | ||
986 | return (status); | ||
987 | } | ||
988 | } | ||
989 | |||
932 | /* | 990 | /* |
933 | * The op_region is not fully parsed at this time. Only valid | 991 | * 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 | 992 | * argument is the space_id. (We must save the address of the |