aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBob Moore <robert.moore@intel.com>2005-12-02 18:27:00 -0500
committerLen Brown <len.brown@intel.com>2005-12-10 00:29:11 -0500
commit28f55ebce5bd2fceec8adc7c8860953d3e4532a8 (patch)
tree2c5c10c18e51f9a717514dfccdc287fc517730c6
parentc51a4de85de720670f2fbc592a6f8040af72ad87 (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>
-rw-r--r--drivers/acpi/dispatcher/dsmethod.c337
-rw-r--r--drivers/acpi/dispatcher/dswload.c132
-rw-r--r--drivers/acpi/namespace/nsdump.c4
-rw-r--r--drivers/acpi/utilities/utglobal.c9
-rw-r--r--drivers/acpi/utilities/utmisc.c79
-rw-r--r--include/acpi/acconfig.h6
-rw-r--r--include/acpi/acglobal.h5
-rw-r--r--include/acpi/acmacros.h4
8 files changed, 350 insertions, 226 deletions
diff --git a/drivers/acpi/dispatcher/dsmethod.c b/drivers/acpi/dispatcher/dsmethod.c
index 36c1ca0b9adb..58ad00b31ee9 100644
--- a/drivers/acpi/dispatcher/dsmethod.c
+++ b/drivers/acpi/dispatcher/dsmethod.c
@@ -53,133 +53,6 @@ ACPI_MODULE_NAME("dsmethod")
53 53
54/******************************************************************************* 54/*******************************************************************************
55 * 55 *
56 * FUNCTION: acpi_ds_parse_method
57 *
58 * PARAMETERS: Node - Method node
59 *
60 * RETURN: Status
61 *
62 * DESCRIPTION: Parse the AML that is associated with the method.
63 *
64 * MUTEX: Assumes parser is locked
65 *
66 ******************************************************************************/
67acpi_status acpi_ds_parse_method(struct acpi_namespace_node *node)
68{
69 acpi_status status;
70 union acpi_operand_object *obj_desc;
71 union acpi_parse_object *op;
72 struct acpi_walk_state *walk_state;
73
74 ACPI_FUNCTION_TRACE_PTR("ds_parse_method", node);
75
76 /* Parameter Validation */
77
78 if (!node) {
79 return_ACPI_STATUS(AE_NULL_ENTRY);
80 }
81
82 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
83 "**** Parsing [%4.4s] **** named_obj=%p\n",
84 acpi_ut_get_node_name(node), node));
85
86 /* Extract the method object from the method Node */
87
88 obj_desc = acpi_ns_get_attached_object(node);
89 if (!obj_desc) {
90 return_ACPI_STATUS(AE_NULL_OBJECT);
91 }
92
93 /* Create a mutex for the method if there is a concurrency limit */
94
95 if ((obj_desc->method.concurrency != ACPI_INFINITE_CONCURRENCY) &&
96 (!obj_desc->method.semaphore)) {
97 status = acpi_os_create_semaphore(obj_desc->method.concurrency,
98 obj_desc->method.concurrency,
99 &obj_desc->method.semaphore);
100 if (ACPI_FAILURE(status)) {
101 return_ACPI_STATUS(status);
102 }
103 }
104
105 /*
106 * Allocate a new parser op to be the root of the parsed
107 * method tree
108 */
109 op = acpi_ps_alloc_op(AML_METHOD_OP);
110 if (!op) {
111 return_ACPI_STATUS(AE_NO_MEMORY);
112 }
113
114 /* Init new op with the method name and pointer back to the Node */
115
116 acpi_ps_set_name(op, node->name.integer);
117 op->common.node = node;
118
119 /*
120 * Get a new owner_id for objects created by this method. Namespace
121 * objects (such as Operation Regions) can be created during the
122 * first pass parse.
123 */
124 status = acpi_ut_allocate_owner_id(&obj_desc->method.owner_id);
125 if (ACPI_FAILURE(status)) {
126 goto cleanup;
127 }
128
129 /* Create and initialize a new walk state */
130
131 walk_state =
132 acpi_ds_create_walk_state(obj_desc->method.owner_id, NULL, NULL,
133 NULL);
134 if (!walk_state) {
135 status = AE_NO_MEMORY;
136 goto cleanup2;
137 }
138
139 status = acpi_ds_init_aml_walk(walk_state, op, node,
140 obj_desc->method.aml_start,
141 obj_desc->method.aml_length, NULL, 1);
142 if (ACPI_FAILURE(status)) {
143 acpi_ds_delete_walk_state(walk_state);
144 goto cleanup2;
145 }
146
147 /*
148 * Parse the method, first pass
149 *
150 * The first pass load is where newly declared named objects are added into
151 * the namespace. Actual evaluation of the named objects (what would be
152 * called a "second pass") happens during the actual execution of the
153 * method so that operands to the named objects can take on dynamic
154 * run-time values.
155 */
156 status = acpi_ps_parse_aml(walk_state);
157 if (ACPI_FAILURE(status)) {
158 goto cleanup2;
159 }
160
161 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
162 "**** [%4.4s] Parsed **** named_obj=%p Op=%p\n",
163 acpi_ut_get_node_name(node), node, op));
164
165 /*
166 * Delete the parse tree. We simply re-parse the method for every
167 * execution since there isn't much overhead (compared to keeping lots
168 * of parse trees around)
169 */
170 acpi_ns_delete_namespace_subtree(node);
171 acpi_ns_delete_namespace_by_owner(obj_desc->method.owner_id);
172
173 cleanup2:
174 acpi_ut_release_owner_id(&obj_desc->method.owner_id);
175
176 cleanup:
177 acpi_ps_delete_parse_tree(op);
178 return_ACPI_STATUS(status);
179}
180
181/*******************************************************************************
182 *
183 * FUNCTION: acpi_ds_begin_method_execution 56 * FUNCTION: acpi_ds_begin_method_execution
184 * 57 *
185 * PARAMETERS: method_node - Node of the method 58 * PARAMETERS: method_node - Node of the method
@@ -193,7 +66,6 @@ acpi_status acpi_ds_parse_method(struct acpi_namespace_node *node)
193 * for clearance to execute. 66 * for clearance to execute.
194 * 67 *
195 ******************************************************************************/ 68 ******************************************************************************/
196
197acpi_status 69acpi_status
198acpi_ds_begin_method_execution(struct acpi_namespace_node *method_node, 70acpi_ds_begin_method_execution(struct acpi_namespace_node *method_node,
199 union acpi_operand_object *obj_desc, 71 union acpi_operand_object *obj_desc,
@@ -545,16 +417,54 @@ void acpi_ds_terminate_control_method(struct acpi_walk_state *walk_state)
545 } 417 }
546 } 418 }
547 419
420 /*
421 * There are no more threads executing this method. Perform
422 * additional cleanup.
423 *
424 * The method Node is stored in the walk state
425 */
426 method_node = walk_state->method_node;
427
428 /* Lock namespace for possible update */
429
430 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
431 if (ACPI_FAILURE(status)) {
432 goto exit;
433 }
434
435 /*
436 * Delete any namespace entries created immediately underneath
437 * the method
438 */
439 if (method_node->child) {
440 acpi_ns_delete_namespace_subtree(method_node);
441 }
442
443 /*
444 * Delete any namespace entries created anywhere else within
445 * the namespace by the execution of this method
446 */
447 acpi_ns_delete_namespace_by_owner(walk_state->method_desc->method.
448 owner_id);
449 status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
450
451 /* Are there any other threads currently executing this method? */
452
548 if (walk_state->method_desc->method.thread_count) { 453 if (walk_state->method_desc->method.thread_count) {
454 /*
455 * Additional threads. Do not release the owner_id in this case,
456 * we immediately reuse it for the next thread executing this method
457 */
549 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, 458 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
550 "*** Not deleting method namespace, there are still %d threads\n", 459 "*** Completed execution of one thread, %d threads remaining\n",
551 walk_state->method_desc->method. 460 walk_state->method_desc->method.
552 thread_count)); 461 thread_count));
553 } else { /* This is the last executing thread */ 462 } else {
463 /* This is the only executing thread for this method */
554 464
555 /* 465 /*
556 * Support to dynamically change a method from not_serialized to 466 * Support to dynamically change a method from not_serialized to
557 * Serialized if it appears that the method is written foolishly and 467 * Serialized if it appears that the method is incorrectly written and
558 * does not support multiple thread execution. The best example of this 468 * does not support multiple thread execution. The best example of this
559 * is if such a method creates namespace objects and blocks. A second 469 * is if such a method creates namespace objects and blocks. A second
560 * thread will fail with an AE_ALREADY_EXISTS exception 470 * thread will fail with an AE_ALREADY_EXISTS exception
@@ -570,34 +480,8 @@ void acpi_ds_terminate_control_method(struct acpi_walk_state *walk_state)
570 semaphore); 480 semaphore);
571 } 481 }
572 482
573 /* 483 /* No more threads, we can free the owner_id */
574 * There are no more threads executing this method. Perform
575 * additional cleanup.
576 *
577 * The method Node is stored in the walk state
578 */
579 method_node = walk_state->method_node;
580
581 /*
582 * Delete any namespace entries created immediately underneath
583 * the method
584 */
585 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
586 if (ACPI_FAILURE(status)) {
587 goto exit;
588 }
589
590 if (method_node->child) {
591 acpi_ns_delete_namespace_subtree(method_node);
592 }
593 484
594 /*
595 * Delete any namespace entries created anywhere else within
596 * the namespace
597 */
598 acpi_ns_delete_namespace_by_owner(walk_state->method_desc->
599 method.owner_id);
600 status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
601 acpi_ut_release_owner_id(&walk_state->method_desc->method. 485 acpi_ut_release_owner_id(&walk_state->method_desc->method.
602 owner_id); 486 owner_id);
603 } 487 }
@@ -606,3 +490,140 @@ void acpi_ds_terminate_control_method(struct acpi_walk_state *walk_state)
606 (void)acpi_ut_release_mutex(ACPI_MTX_PARSER); 490 (void)acpi_ut_release_mutex(ACPI_MTX_PARSER);
607 return_VOID; 491 return_VOID;
608} 492}
493
494#ifdef ACPI_INIT_PARSE_METHODS
495 /*
496 * Note 11/2005: Removed this code to parse all methods during table
497 * load because it causes problems if there are any errors during the
498 * parse. Also, it seems like overkill and we probably don't want to
499 * abort a table load because of an issue with a single method.
500 */
501
502/*******************************************************************************
503 *
504 * FUNCTION: acpi_ds_parse_method
505 *
506 * PARAMETERS: Node - Method node
507 *
508 * RETURN: Status
509 *
510 * DESCRIPTION: Parse the AML that is associated with the method.
511 *
512 * MUTEX: Assumes parser is locked
513 *
514 ******************************************************************************/
515
516acpi_status acpi_ds_parse_method(struct acpi_namespace_node *node)
517{
518 acpi_status status;
519 union acpi_operand_object *obj_desc;
520 union acpi_parse_object *op;
521 struct acpi_walk_state *walk_state;
522
523 ACPI_FUNCTION_TRACE_PTR("ds_parse_method", node);
524
525 /* Parameter Validation */
526
527 if (!node) {
528 return_ACPI_STATUS(AE_NULL_ENTRY);
529 }
530
531 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
532 "**** Parsing [%4.4s] **** named_obj=%p\n",
533 acpi_ut_get_node_name(node), node));
534
535 /* Extract the method object from the method Node */
536
537 obj_desc = acpi_ns_get_attached_object(node);
538 if (!obj_desc) {
539 return_ACPI_STATUS(AE_NULL_OBJECT);
540 }
541
542 /* Create a mutex for the method if there is a concurrency limit */
543
544 if ((obj_desc->method.concurrency != ACPI_INFINITE_CONCURRENCY) &&
545 (!obj_desc->method.semaphore)) {
546 status = acpi_os_create_semaphore(obj_desc->method.concurrency,
547 obj_desc->method.concurrency,
548 &obj_desc->method.semaphore);
549 if (ACPI_FAILURE(status)) {
550 return_ACPI_STATUS(status);
551 }
552 }
553
554 /*
555 * Allocate a new parser op to be the root of the parsed
556 * method tree
557 */
558 op = acpi_ps_alloc_op(AML_METHOD_OP);
559 if (!op) {
560 return_ACPI_STATUS(AE_NO_MEMORY);
561 }
562
563 /* Init new op with the method name and pointer back to the Node */
564
565 acpi_ps_set_name(op, node->name.integer);
566 op->common.node = node;
567
568 /*
569 * Get a new owner_id for objects created by this method. Namespace
570 * objects (such as Operation Regions) can be created during the
571 * first pass parse.
572 */
573 status = acpi_ut_allocate_owner_id(&obj_desc->method.owner_id);
574 if (ACPI_FAILURE(status)) {
575 goto cleanup;
576 }
577
578 /* Create and initialize a new walk state */
579
580 walk_state =
581 acpi_ds_create_walk_state(obj_desc->method.owner_id, NULL, NULL,
582 NULL);
583 if (!walk_state) {
584 status = AE_NO_MEMORY;
585 goto cleanup2;
586 }
587
588 status = acpi_ds_init_aml_walk(walk_state, op, node,
589 obj_desc->method.aml_start,
590 obj_desc->method.aml_length, NULL, 1);
591 if (ACPI_FAILURE(status)) {
592 acpi_ds_delete_walk_state(walk_state);
593 goto cleanup2;
594 }
595
596 /*
597 * Parse the method, first pass
598 *
599 * The first pass load is where newly declared named objects are added into
600 * the namespace. Actual evaluation of the named objects (what would be
601 * called a "second pass") happens during the actual execution of the
602 * method so that operands to the named objects can take on dynamic
603 * run-time values.
604 */
605 status = acpi_ps_parse_aml(walk_state);
606 if (ACPI_FAILURE(status)) {
607 goto cleanup2;
608 }
609
610 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
611 "**** [%4.4s] Parsed **** named_obj=%p Op=%p\n",
612 acpi_ut_get_node_name(node), node, op));
613
614 /*
615 * Delete the parse tree. We simply re-parse the method for every
616 * execution since there isn't much overhead (compared to keeping lots
617 * of parse trees around)
618 */
619 acpi_ns_delete_namespace_subtree(node);
620 acpi_ns_delete_namespace_by_owner(obj_desc->method.owner_id);
621
622 cleanup2:
623 acpi_ut_release_owner_id(&obj_desc->method.owner_id);
624
625 cleanup:
626 acpi_ps_delete_parse_tree(op);
627 return_ACPI_STATUS(status);
628}
629#endif
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
342acpi_status acpi_ds_load1_end_op(struct acpi_walk_state * walk_state) 354acpi_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
458acpi_status 491acpi_status
459acpi_ds_load2_begin_op(struct acpi_walk_state * walk_state, 492acpi_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
diff --git a/drivers/acpi/namespace/nsdump.c b/drivers/acpi/namespace/nsdump.c
index 9faf1d5c86ed..864c642759fa 100644
--- a/drivers/acpi/namespace/nsdump.c
+++ b/drivers/acpi/namespace/nsdump.c
@@ -212,7 +212,9 @@ acpi_ns_dump_one_object(acpi_handle obj_handle,
212 /* 212 /*
213 * Now we can print out the pertinent information 213 * Now we can print out the pertinent information
214 */ 214 */
215 acpi_os_printf(" %-12s %p ", acpi_ut_get_type_name(type), this_node); 215 acpi_os_printf(" %-12s %p %2.2X ",
216 acpi_ut_get_type_name(type), this_node,
217 this_node->owner_id);
216 218
217 dbg_level = acpi_dbg_level; 219 dbg_level = acpi_dbg_level;
218 acpi_dbg_level = 0; 220 acpi_dbg_level = 0;
diff --git a/drivers/acpi/utilities/utglobal.c b/drivers/acpi/utilities/utglobal.c
index d6813d88a104..6828c7aefa8a 100644
--- a/drivers/acpi/utilities/utglobal.c
+++ b/drivers/acpi/utilities/utglobal.c
@@ -793,6 +793,11 @@ void acpi_ut_init_globals(void)
793 acpi_gbl_mutex_info[i].use_count = 0; 793 acpi_gbl_mutex_info[i].use_count = 0;
794 } 794 }
795 795
796 for (i = 0; i < ACPI_NUM_OWNERID_MASKS; i++) {
797 acpi_gbl_owner_id_mask[i] = 0;
798 }
799 acpi_gbl_owner_id_mask[ACPI_NUM_OWNERID_MASKS - 1] = 0x80000000; /* Last ID is never valid */
800
796 /* GPE support */ 801 /* GPE support */
797 802
798 acpi_gbl_gpe_xrupt_list_head = NULL; 803 acpi_gbl_gpe_xrupt_list_head = NULL;
@@ -830,8 +835,8 @@ void acpi_ut_init_globals(void)
830 acpi_gbl_ns_lookup_count = 0; 835 acpi_gbl_ns_lookup_count = 0;
831 acpi_gbl_ps_find_count = 0; 836 acpi_gbl_ps_find_count = 0;
832 acpi_gbl_acpi_hardware_present = TRUE; 837 acpi_gbl_acpi_hardware_present = TRUE;
833 acpi_gbl_owner_id_mask = 0; 838 acpi_gbl_last_owner_id_index = 0;
834 acpi_gbl_last_owner_id = 0; 839 acpi_gbl_next_owner_id_offset = 0;
835 acpi_gbl_trace_method_name = 0; 840 acpi_gbl_trace_method_name = 0;
836 acpi_gbl_trace_dbg_level = 0; 841 acpi_gbl_trace_dbg_level = 0;
837 acpi_gbl_trace_dbg_layer = 0; 842 acpi_gbl_trace_dbg_layer = 0;
diff --git a/drivers/acpi/utilities/utmisc.c b/drivers/acpi/utilities/utmisc.c
index 89efba7bf449..64dd64b1aa18 100644
--- a/drivers/acpi/utilities/utmisc.c
+++ b/drivers/acpi/utilities/utmisc.c
@@ -64,6 +64,7 @@ acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id)
64{ 64{
65 acpi_native_uint i; 65 acpi_native_uint i;
66 acpi_native_uint j; 66 acpi_native_uint j;
67 acpi_native_uint k;
67 acpi_status status; 68 acpi_status status;
68 69
69 ACPI_FUNCTION_TRACE("ut_allocate_owner_id"); 70 ACPI_FUNCTION_TRACE("ut_allocate_owner_id");
@@ -85,32 +86,50 @@ acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id)
85 86
86 /* 87 /*
87 * Find a free owner ID, cycle through all possible IDs on repeated 88 * Find a free owner ID, cycle through all possible IDs on repeated
88 * allocations. Note: Index for next possible ID is equal to the value 89 * allocations. (ACPI_NUM_OWNERID_MASKS + 1) because first index may have
89 * of the last allocated ID. 90 * to be scanned twice.
90 */ 91 */
91 for (i = 0, j = acpi_gbl_last_owner_id; i < 32; i++, j++) { 92 for (i = 0, j = acpi_gbl_last_owner_id_index;
92 if (j >= 32) { 93 i < (ACPI_NUM_OWNERID_MASKS + 1); i++, j++) {
93 j = 0; /* Wraparound to ID start */ 94 if (j >= ACPI_NUM_OWNERID_MASKS) {
95 j = 0; /* Wraparound to start of mask array */
94 } 96 }
95 97
96 if (!(acpi_gbl_owner_id_mask & (1 << j))) { 98 for (k = acpi_gbl_next_owner_id_offset; k < 32; k++) {
97 /* 99 if (acpi_gbl_owner_id_mask[j] == ACPI_UINT32_MAX) {
98 * Found a free ID. The actual ID is the bit index plus one, 100 /* There are no free IDs in this mask */
99 * making zero an invalid Owner ID. Save this as the last ID
100 * allocated and update the global ID mask.
101 */
102 acpi_gbl_last_owner_id = (acpi_owner_id) (j + 1);
103 *owner_id = acpi_gbl_last_owner_id;
104 101
105 ACPI_DEBUG_PRINT((ACPI_DB_VALUES, 102 break;
106 "Current owner_id mask: %8.8X New ID: %2.2X\n", 103 }
107 acpi_gbl_owner_id_mask,
108 (unsigned int)
109 acpi_gbl_last_owner_id));
110 104
111 acpi_gbl_owner_id_mask |= (1 << j); 105 if (!(acpi_gbl_owner_id_mask[j] & (1 << k))) {
112 goto exit; 106 /*
107 * Found a free ID. The actual ID is the bit index plus one,
108 * making zero an invalid Owner ID. Save this as the last ID
109 * allocated and update the global ID mask.
110 */
111 acpi_gbl_owner_id_mask[j] |= (1 << k);
112
113 acpi_gbl_last_owner_id_index = (u8) j;
114 acpi_gbl_next_owner_id_offset = (u8) (k + 1);
115
116 /*
117 * Construct encoded ID from the index and bit position
118 *
119 * Note: Last [j].k (bit 255) is never used and is marked
120 * permanently allocated (prevents +1 overflow)
121 */
122 *owner_id =
123 (acpi_owner_id) ((k + 1) + ACPI_MUL_32(j));
124
125 ACPI_DEBUG_PRINT((ACPI_DB_VALUES,
126 "Allocated owner_id: %2.2X\n",
127 (unsigned int)*owner_id));
128 goto exit;
129 }
113 } 130 }
131
132 acpi_gbl_next_owner_id_offset = 0;
114 } 133 }
115 134
116 /* 135 /*
@@ -124,7 +143,7 @@ acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id)
124 * methods, or there may be a bug where the IDs are not released. 143 * methods, or there may be a bug where the IDs are not released.
125 */ 144 */
126 status = AE_OWNER_ID_LIMIT; 145 status = AE_OWNER_ID_LIMIT;
127 ACPI_REPORT_ERROR(("Could not allocate new owner_id (32 max), AE_OWNER_ID_LIMIT\n")); 146 ACPI_REPORT_ERROR(("Could not allocate new owner_id (255 max), AE_OWNER_ID_LIMIT\n"));
128 147
129 exit: 148 exit:
130 (void)acpi_ut_release_mutex(ACPI_MTX_CACHES); 149 (void)acpi_ut_release_mutex(ACPI_MTX_CACHES);
@@ -141,7 +160,7 @@ acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id)
141 * control method or unloading a table. Either way, we would 160 * control method or unloading a table. Either way, we would
142 * ignore any error anyway. 161 * ignore any error anyway.
143 * 162 *
144 * DESCRIPTION: Release a table or method owner ID. Valid IDs are 1 - 32 163 * DESCRIPTION: Release a table or method owner ID. Valid IDs are 1 - 255
145 * 164 *
146 ******************************************************************************/ 165 ******************************************************************************/
147 166
@@ -149,6 +168,8 @@ void acpi_ut_release_owner_id(acpi_owner_id * owner_id_ptr)
149{ 168{
150 acpi_owner_id owner_id = *owner_id_ptr; 169 acpi_owner_id owner_id = *owner_id_ptr;
151 acpi_status status; 170 acpi_status status;
171 acpi_native_uint index;
172 u32 bit;
152 173
153 ACPI_FUNCTION_TRACE_U32("ut_release_owner_id", owner_id); 174 ACPI_FUNCTION_TRACE_U32("ut_release_owner_id", owner_id);
154 175
@@ -158,7 +179,7 @@ void acpi_ut_release_owner_id(acpi_owner_id * owner_id_ptr)
158 179
159 /* Zero is not a valid owner_iD */ 180 /* Zero is not a valid owner_iD */
160 181
161 if ((owner_id == 0) || (owner_id > 32)) { 182 if ((owner_id == 0) || (owner_id > 255)) {
162 ACPI_REPORT_ERROR(("Invalid owner_id: %2.2X\n", owner_id)); 183 ACPI_REPORT_ERROR(("Invalid owner_id: %2.2X\n", owner_id));
163 return_VOID; 184 return_VOID;
164 } 185 }
@@ -174,10 +195,18 @@ void acpi_ut_release_owner_id(acpi_owner_id * owner_id_ptr)
174 195
175 owner_id--; 196 owner_id--;
176 197
198 /* Decode ID to index/offset pair */
199
200 index = ACPI_DIV_32(owner_id);
201 bit = 1 << ACPI_MOD_32(owner_id);
202
177 /* Free the owner ID only if it is valid */ 203 /* Free the owner ID only if it is valid */
178 204
179 if (acpi_gbl_owner_id_mask & (1 << owner_id)) { 205 if (acpi_gbl_owner_id_mask[index] & bit) {
180 acpi_gbl_owner_id_mask ^= (1 << owner_id); 206 acpi_gbl_owner_id_mask[index] ^= bit;
207 } else {
208 ACPI_REPORT_ERROR(("Release of non-allocated owner_id: %2.2X\n",
209 owner_id + 1));
181 } 210 }
182 211
183 (void)acpi_ut_release_mutex(ACPI_MTX_CACHES); 212 (void)acpi_ut_release_mutex(ACPI_MTX_CACHES);
diff --git a/include/acpi/acconfig.h b/include/acpi/acconfig.h
index 08eafece3eed..f48b9ee9a876 100644
--- a/include/acpi/acconfig.h
+++ b/include/acpi/acconfig.h
@@ -63,7 +63,7 @@
63 63
64/* Current ACPICA subsystem version in YYYYMMDD format */ 64/* Current ACPICA subsystem version in YYYYMMDD format */
65 65
66#define ACPI_CA_VERSION 0x20051117 66#define ACPI_CA_VERSION 0x20051202
67 67
68/* 68/*
69 * OS name, used for the _OS object. The _OS object is essentially obsolete, 69 * OS name, used for the _OS object. The _OS object is essentially obsolete,
@@ -110,6 +110,10 @@
110 110
111#define ACPI_SYSMEM_REGION_WINDOW_SIZE 4096 111#define ACPI_SYSMEM_REGION_WINDOW_SIZE 4096
112 112
113/* owner_id tracking. 8 entries allows for 255 owner_ids */
114
115#define ACPI_NUM_OWNERID_MASKS 8
116
113/****************************************************************************** 117/******************************************************************************
114 * 118 *
115 * ACPI Specification constants (Do not change unless the specification changes) 119 * ACPI Specification constants (Do not change unless the specification changes)
diff --git a/include/acpi/acglobal.h b/include/acpi/acglobal.h
index bd344e51313b..3f37560c26ab 100644
--- a/include/acpi/acglobal.h
+++ b/include/acpi/acglobal.h
@@ -220,10 +220,11 @@ ACPI_EXTERN u32 acpi_gbl_original_mode;
220ACPI_EXTERN u32 acpi_gbl_rsdp_original_location; 220ACPI_EXTERN u32 acpi_gbl_rsdp_original_location;
221ACPI_EXTERN u32 acpi_gbl_ns_lookup_count; 221ACPI_EXTERN u32 acpi_gbl_ns_lookup_count;
222ACPI_EXTERN u32 acpi_gbl_ps_find_count; 222ACPI_EXTERN u32 acpi_gbl_ps_find_count;
223ACPI_EXTERN u32 acpi_gbl_owner_id_mask; 223ACPI_EXTERN u32 acpi_gbl_owner_id_mask[ACPI_NUM_OWNERID_MASKS];
224ACPI_EXTERN u16 acpi_gbl_pm1_enable_register_save; 224ACPI_EXTERN u16 acpi_gbl_pm1_enable_register_save;
225ACPI_EXTERN u16 acpi_gbl_global_lock_handle; 225ACPI_EXTERN u16 acpi_gbl_global_lock_handle;
226ACPI_EXTERN u8 acpi_gbl_last_owner_id; 226ACPI_EXTERN u8 acpi_gbl_last_owner_id_index;
227ACPI_EXTERN u8 acpi_gbl_next_owner_id_offset;
227ACPI_EXTERN u8 acpi_gbl_debugger_configuration; 228ACPI_EXTERN u8 acpi_gbl_debugger_configuration;
228ACPI_EXTERN u8 acpi_gbl_global_lock_acquired; 229ACPI_EXTERN u8 acpi_gbl_global_lock_acquired;
229ACPI_EXTERN u8 acpi_gbl_step_to_next_call; 230ACPI_EXTERN u8 acpi_gbl_step_to_next_call;
diff --git a/include/acpi/acmacros.h b/include/acpi/acmacros.h
index 5b78ff4091b9..65a1a5c1a689 100644
--- a/include/acpi/acmacros.h
+++ b/include/acpi/acmacros.h
@@ -332,6 +332,10 @@
332#define ACPI_MUL_16(a) _ACPI_MUL(a,4) 332#define ACPI_MUL_16(a) _ACPI_MUL(a,4)
333#define ACPI_MOD_16(a) _ACPI_MOD(a,16) 333#define ACPI_MOD_16(a) _ACPI_MOD(a,16)
334 334
335#define ACPI_DIV_32(a) _ACPI_DIV(a,5)
336#define ACPI_MUL_32(a) _ACPI_MUL(a,5)
337#define ACPI_MOD_32(a) _ACPI_MOD(a,32)
338
335/* 339/*
336 * Rounding macros (Power of two boundaries only) 340 * Rounding macros (Power of two boundaries only)
337 */ 341 */