patch-2.4.6 linux/drivers/acpi/dispatcher/dsmethod.c
Next file: linux/drivers/acpi/dispatcher/dsmthdat.c
Previous file: linux/drivers/acpi/dispatcher/dsfield.c
Back to the patch index
Back to the overall index
- Lines: 268
- Date:
Wed Jun 20 17:47:39 2001
- Orig file:
v2.4.5/linux/drivers/acpi/dispatcher/dsmethod.c
- Orig date:
Mon Jan 22 13:23:42 2001
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/dispatcher/dsmethod.c linux/drivers/acpi/dispatcher/dsmethod.c
@@ -1,7 +1,7 @@
/******************************************************************************
*
* Module Name: dsmethod - Parser/Interpreter interface - control method parsing
- * $Revision: 56 $
+ * $Revision: 63 $
*
*****************************************************************************/
@@ -34,7 +34,7 @@
#include "acdebug.h"
-#define _COMPONENT DISPATCHER
+#define _COMPONENT ACPI_DISPATCHER
MODULE_NAME ("dsmethod")
@@ -85,9 +85,9 @@
/* Create a mutex for the method if there is a concurrency limit */
if ((obj_desc->method.concurrency != INFINITE_CONCURRENCY) &&
- (!obj_desc->method.semaphore))
- {
- status = acpi_os_create_semaphore (1,obj_desc->method.concurrency,
+ (!obj_desc->method.semaphore)) {
+ status = acpi_os_create_semaphore (obj_desc->method.concurrency,
+ obj_desc->method.concurrency,
&obj_desc->method.semaphore);
if (ACPI_FAILURE (status)) {
return (status);
@@ -98,7 +98,6 @@
* Allocate a new parser op to be the root of the parsed
* method tree
*/
-
op = acpi_ps_alloc_op (AML_METHOD_OP);
if (!op) {
return (AE_NO_MEMORY);
@@ -113,15 +112,13 @@
/*
* Parse the method, first pass
*
- * The first pass load is
- * where newly declared named objects are
+ * The first pass load is where newly declared named objects are
* added into the namespace. Actual evaluation of
* the named objects (what would be called a "second
* pass") happens during the actual execution of the
* method so that operands to the named objects can
* take on dynamic run-time values.
*/
-
status = acpi_ps_parse_aml (op, obj_desc->method.pcode,
obj_desc->method.pcode_length,
ACPI_PARSE_LOAD_PASS1 | ACPI_PARSE_DELETE_TREE,
@@ -134,7 +131,7 @@
/* Get a new Owner_id for objects created by this method */
- owner_id = acpi_cm_allocate_owner_id (OWNER_TYPE_METHOD);
+ owner_id = acpi_ut_allocate_owner_id (OWNER_TYPE_METHOD);
obj_desc->method.owning_id = owner_id;
/* Install the parsed tree in the method object */
@@ -142,7 +139,6 @@
acpi_ps_delete_parse_tree (op);
-
return (status);
}
@@ -151,8 +147,9 @@
*
* FUNCTION: Acpi_ds_begin_method_execution
*
- * PARAMETERS: Method_node - Node of the method
+ * PARAMETERS: Method_node - Node of the method
* Obj_desc - The method object
+ * Calling_method_node - Caller of this method (if non-null)
*
* RETURN: Status
*
@@ -167,7 +164,8 @@
ACPI_STATUS
acpi_ds_begin_method_execution (
ACPI_NAMESPACE_NODE *method_node,
- ACPI_OPERAND_OBJECT *obj_desc)
+ ACPI_OPERAND_OBJECT *obj_desc,
+ ACPI_NAMESPACE_NODE *calling_method_node)
{
ACPI_STATUS status = AE_OK;
@@ -176,34 +174,41 @@
return (AE_NULL_ENTRY);
}
- obj_desc = acpi_ns_get_attached_object (method_node);
- if (!obj_desc) {
- return (AE_NULL_OBJECT);
- }
-
/*
* If there is a concurrency limit on this method, we need to
- * obtain a unit from the method semaphore. This releases the
- * interpreter if we block
+ * obtain a unit from the method semaphore.
*/
-
if (obj_desc->method.semaphore) {
- status = acpi_aml_system_wait_semaphore (obj_desc->method.semaphore,
+ /*
+ * Allow recursive method calls, up to the reentrancy/concurrency
+ * limit imposed by the SERIALIZED rule and the Sync_level method
+ * parameter.
+ *
+ * The point of this code is to avoid permanently blocking a
+ * thread that is making recursive method calls.
+ */
+ if (method_node == calling_method_node) {
+ if (obj_desc->method.thread_count >= obj_desc->method.concurrency) {
+ return (AE_AML_METHOD_LIMIT);
+ }
+ }
+
+ /*
+ * Get a unit from the method semaphore. This releases the
+ * interpreter if we block
+ */
+ status = acpi_ex_system_wait_semaphore (obj_desc->method.semaphore,
WAIT_FOREVER);
}
/*
- * Increment the method parse tree thread count since there
- * is one additional thread executing in it. If configured
- * for deletion-on-exit, the parse tree will be deleted when
- * the last thread completes execution of the method
+ * Increment the method parse tree thread count since it has been
+ * reentered one more time (even if it is the same thread)
*/
-
obj_desc->method.thread_count++;
-
return (status);
}
@@ -238,7 +243,6 @@
/*
* Get the namespace entry for the control method we are about to call
*/
-
method_node = this_walk_state->method_call_node;
if (!method_node) {
return (AE_NULL_ENTRY);
@@ -252,12 +256,12 @@
/* Init for new method, wait on concurrency semaphore */
- status = acpi_ds_begin_method_execution (method_node, obj_desc);
+ status = acpi_ds_begin_method_execution (method_node, obj_desc,
+ this_walk_state->method_node);
if (ACPI_FAILURE (status)) {
return (status);
}
-
/* Create and initialize a new parser state */
parser_state = acpi_ps_create_state (obj_desc->method.pcode,
@@ -307,7 +311,6 @@
* stack. Operands on the previous walk state stack always
* start at index 0.
*/
-
status = acpi_ds_method_data_init_args (&this_walk_state->operands[0],
this_walk_state->num_operands,
next_walk_state);
@@ -335,9 +338,8 @@
* Delete the operands on the previous walkstate operand stack
* (they were copied to new objects)
*/
-
for (i = 0; i < obj_desc->method.param_count; i++) {
- acpi_cm_remove_reference (this_walk_state->operands [i]);
+ acpi_ut_remove_reference (this_walk_state->operands [i]);
this_walk_state->operands [i] = NULL;
}
@@ -386,10 +388,9 @@
* Get the return value (if any) from the previous method.
* NULL if no return value
*/
-
status = acpi_ds_result_push (return_desc, walk_state);
if (ACPI_FAILURE (status)) {
- acpi_cm_remove_reference (return_desc);
+ acpi_ut_remove_reference (return_desc);
return (status);
}
}
@@ -399,7 +400,7 @@
* Delete the return value if it will not be used by the
* calling method
*/
- acpi_cm_remove_reference (return_desc);
+ acpi_ut_remove_reference (return_desc);
}
}
@@ -427,7 +428,6 @@
acpi_ds_terminate_control_method (
ACPI_WALK_STATE *walk_state)
{
- ACPI_STATUS status;
ACPI_OPERAND_OBJECT *obj_desc;
ACPI_NAMESPACE_NODE *method_node;
@@ -448,15 +448,14 @@
* If this is the last thread executing the method,
* we have additional cleanup to perform
*/
-
- acpi_cm_acquire_mutex (ACPI_MTX_PARSER);
+ acpi_ut_acquire_mutex (ACPI_MTX_PARSER);
/* Signal completion of the execution of this method if necessary */
if (walk_state->method_desc->method.semaphore) {
- status = acpi_os_signal_semaphore (
- walk_state->method_desc->method.semaphore, 1);
+ acpi_os_signal_semaphore (
+ walk_state->method_desc->method.semaphore, 1);
}
/* Decrement the thread count on the method parse tree */
@@ -470,11 +469,12 @@
* The method Node is stored in the walk state
*/
method_node = walk_state->method_node;
+
/*
* Delete any namespace entries created immediately underneath
* the method
*/
- acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE);
+ acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
if (method_node->child) {
acpi_ns_delete_namespace_subtree (method_node);
}
@@ -484,10 +484,10 @@
* the namespace
*/
acpi_ns_delete_namespace_by_owner (walk_state->method_desc->method.owning_id);
- acpi_cm_release_mutex (ACPI_MTX_NAMESPACE);
+ acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
}
- acpi_cm_release_mutex (ACPI_MTX_PARSER);
+ acpi_ut_release_mutex (ACPI_MTX_PARSER);
return (AE_OK);
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)