aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 */