aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/dispatcher/dsmethod.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/dispatcher/dsmethod.c')
-rw-r--r--drivers/acpi/dispatcher/dsmethod.c67
1 files changed, 42 insertions, 25 deletions
diff --git a/drivers/acpi/dispatcher/dsmethod.c b/drivers/acpi/dispatcher/dsmethod.c
index 9fc3f4c033eb..e344c06ed33f 100644
--- a/drivers/acpi/dispatcher/dsmethod.c
+++ b/drivers/acpi/dispatcher/dsmethod.c
@@ -58,12 +58,11 @@
58 * 58 *
59 * FUNCTION: acpi_ds_parse_method 59 * FUNCTION: acpi_ds_parse_method
60 * 60 *
61 * PARAMETERS: obj_handle - Method node 61 * PARAMETERS: Node - Method node
62 * 62 *
63 * RETURN: Status 63 * RETURN: Status
64 * 64 *
65 * DESCRIPTION: Call the parser and parse the AML that is associated with the 65 * DESCRIPTION: Parse the AML that is associated with the method.
66 * method.
67 * 66 *
68 * MUTEX: Assumes parser is locked 67 * MUTEX: Assumes parser is locked
69 * 68 *
@@ -71,31 +70,28 @@
71 70
72acpi_status 71acpi_status
73acpi_ds_parse_method ( 72acpi_ds_parse_method (
74 acpi_handle obj_handle) 73 struct acpi_namespace_node *node)
75{ 74{
76 acpi_status status; 75 acpi_status status;
77 union acpi_operand_object *obj_desc; 76 union acpi_operand_object *obj_desc;
78 union acpi_parse_object *op; 77 union acpi_parse_object *op;
79 struct acpi_namespace_node *node;
80 acpi_owner_id owner_id;
81 struct acpi_walk_state *walk_state; 78 struct acpi_walk_state *walk_state;
82 79
83 80
84 ACPI_FUNCTION_TRACE_PTR ("ds_parse_method", obj_handle); 81 ACPI_FUNCTION_TRACE_PTR ("ds_parse_method", node);
85 82
86 83
87 /* Parameter Validation */ 84 /* Parameter Validation */
88 85
89 if (!obj_handle) { 86 if (!node) {
90 return_ACPI_STATUS (AE_NULL_ENTRY); 87 return_ACPI_STATUS (AE_NULL_ENTRY);
91 } 88 }
92 89
93 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "**** Parsing [%4.4s] **** named_obj=%p\n", 90 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "**** Parsing [%4.4s] **** named_obj=%p\n",
94 acpi_ut_get_node_name (obj_handle), obj_handle)); 91 acpi_ut_get_node_name (node), node));
95 92
96 /* Extract the method object from the method Node */ 93 /* Extract the method object from the method Node */
97 94
98 node = (struct acpi_namespace_node *) obj_handle;
99 obj_desc = acpi_ns_get_attached_object (node); 95 obj_desc = acpi_ns_get_attached_object (node);
100 if (!obj_desc) { 96 if (!obj_desc) {
101 return_ACPI_STATUS (AE_NULL_OBJECT); 97 return_ACPI_STATUS (AE_NULL_OBJECT);
@@ -132,14 +128,18 @@ acpi_ds_parse_method (
132 * objects (such as Operation Regions) can be created during the 128 * objects (such as Operation Regions) can be created during the
133 * first pass parse. 129 * first pass parse.
134 */ 130 */
135 owner_id = acpi_ut_allocate_owner_id (ACPI_OWNER_TYPE_METHOD); 131 status = acpi_ut_allocate_owner_id (&obj_desc->method.owner_id);
136 obj_desc->method.owning_id = owner_id; 132 if (ACPI_FAILURE (status)) {
133 goto cleanup;
134 }
137 135
138 /* Create and initialize a new walk state */ 136 /* Create and initialize a new walk state */
139 137
140 walk_state = acpi_ds_create_walk_state (owner_id, NULL, NULL, NULL); 138 walk_state = acpi_ds_create_walk_state (
139 obj_desc->method.owner_id, NULL, NULL, NULL);
141 if (!walk_state) { 140 if (!walk_state) {
142 return_ACPI_STATUS (AE_NO_MEMORY); 141 status = AE_NO_MEMORY;
142 goto cleanup2;
143 } 143 }
144 144
145 status = acpi_ds_init_aml_walk (walk_state, op, node, 145 status = acpi_ds_init_aml_walk (walk_state, op, node,
@@ -147,7 +147,7 @@ acpi_ds_parse_method (
147 obj_desc->method.aml_length, NULL, 1); 147 obj_desc->method.aml_length, NULL, 1);
148 if (ACPI_FAILURE (status)) { 148 if (ACPI_FAILURE (status)) {
149 acpi_ds_delete_walk_state (walk_state); 149 acpi_ds_delete_walk_state (walk_state);
150 return_ACPI_STATUS (status); 150 goto cleanup2;
151 } 151 }
152 152
153 /* 153 /*
@@ -161,13 +161,25 @@ acpi_ds_parse_method (
161 */ 161 */
162 status = acpi_ps_parse_aml (walk_state); 162 status = acpi_ps_parse_aml (walk_state);
163 if (ACPI_FAILURE (status)) { 163 if (ACPI_FAILURE (status)) {
164 return_ACPI_STATUS (status); 164 goto cleanup2;
165 } 165 }
166 166
167 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, 167 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
168 "**** [%4.4s] Parsed **** named_obj=%p Op=%p\n", 168 "**** [%4.4s] Parsed **** named_obj=%p Op=%p\n",
169 acpi_ut_get_node_name (obj_handle), obj_handle, op)); 169 acpi_ut_get_node_name (node), node, op));
170
171 /*
172 * Delete the parse tree. We simply re-parse the method for every
173 * execution since there isn't much overhead (compared to keeping lots
174 * of parse trees around)
175 */
176 acpi_ns_delete_namespace_subtree (node);
177 acpi_ns_delete_namespace_by_owner (obj_desc->method.owner_id);
178
179cleanup2:
180 acpi_ut_release_owner_id (&obj_desc->method.owner_id);
170 181
182cleanup:
171 acpi_ps_delete_parse_tree (op); 183 acpi_ps_delete_parse_tree (op);
172 return_ACPI_STATUS (status); 184 return_ACPI_STATUS (status);
173} 185}
@@ -263,7 +275,7 @@ acpi_ds_call_control_method (
263{ 275{
264 acpi_status status; 276 acpi_status status;
265 struct acpi_namespace_node *method_node; 277 struct acpi_namespace_node *method_node;
266 struct acpi_walk_state *next_walk_state; 278 struct acpi_walk_state *next_walk_state = NULL;
267 union acpi_operand_object *obj_desc; 279 union acpi_operand_object *obj_desc;
268 struct acpi_parameter_info info; 280 struct acpi_parameter_info info;
269 u32 i; 281 u32 i;
@@ -287,20 +299,23 @@ acpi_ds_call_control_method (
287 return_ACPI_STATUS (AE_NULL_OBJECT); 299 return_ACPI_STATUS (AE_NULL_OBJECT);
288 } 300 }
289 301
290 obj_desc->method.owning_id = acpi_ut_allocate_owner_id (ACPI_OWNER_TYPE_METHOD); 302 status = acpi_ut_allocate_owner_id (&obj_desc->method.owner_id);
303 if (ACPI_FAILURE (status)) {
304 return_ACPI_STATUS (status);
305 }
291 306
292 /* Init for new method, wait on concurrency semaphore */ 307 /* Init for new method, wait on concurrency semaphore */
293 308
294 status = acpi_ds_begin_method_execution (method_node, obj_desc, 309 status = acpi_ds_begin_method_execution (method_node, obj_desc,
295 this_walk_state->method_node); 310 this_walk_state->method_node);
296 if (ACPI_FAILURE (status)) { 311 if (ACPI_FAILURE (status)) {
297 return_ACPI_STATUS (status); 312 goto cleanup;
298 } 313 }
299 314
300 if (!(obj_desc->method.method_flags & AML_METHOD_INTERNAL_ONLY)) { 315 if (!(obj_desc->method.method_flags & AML_METHOD_INTERNAL_ONLY)) {
301 /* 1) Parse: Create a new walk state for the preempting walk */ 316 /* 1) Parse: Create a new walk state for the preempting walk */
302 317
303 next_walk_state = acpi_ds_create_walk_state (obj_desc->method.owning_id, 318 next_walk_state = acpi_ds_create_walk_state (obj_desc->method.owner_id,
304 op, obj_desc, NULL); 319 op, obj_desc, NULL);
305 if (!next_walk_state) { 320 if (!next_walk_state) {
306 return_ACPI_STATUS (AE_NO_MEMORY); 321 return_ACPI_STATUS (AE_NO_MEMORY);
@@ -330,7 +345,7 @@ acpi_ds_call_control_method (
330 345
331 /* 2) Execute: Create a new state for the preempting walk */ 346 /* 2) Execute: Create a new state for the preempting walk */
332 347
333 next_walk_state = acpi_ds_create_walk_state (obj_desc->method.owning_id, 348 next_walk_state = acpi_ds_create_walk_state (obj_desc->method.owner_id,
334 NULL, obj_desc, thread); 349 NULL, obj_desc, thread);
335 if (!next_walk_state) { 350 if (!next_walk_state) {
336 status = AE_NO_MEMORY; 351 status = AE_NO_MEMORY;
@@ -381,6 +396,7 @@ acpi_ds_call_control_method (
381 /* On error, we must delete the new walk state */ 396 /* On error, we must delete the new walk state */
382 397
383cleanup: 398cleanup:
399 acpi_ut_release_owner_id (&obj_desc->method.owner_id);
384 if (next_walk_state && (next_walk_state->method_desc)) { 400 if (next_walk_state && (next_walk_state->method_desc)) {
385 /* Decrement the thread count on the method parse tree */ 401 /* Decrement the thread count on the method parse tree */
386 402
@@ -552,8 +568,7 @@ acpi_ds_terminate_control_method (
552 */ 568 */
553 if ((walk_state->method_desc->method.concurrency == 1) && 569 if ((walk_state->method_desc->method.concurrency == 1) &&
554 (!walk_state->method_desc->method.semaphore)) { 570 (!walk_state->method_desc->method.semaphore)) {
555 status = acpi_os_create_semaphore (1, 571 status = acpi_os_create_semaphore (1, 1,
556 1,
557 &walk_state->method_desc->method.semaphore); 572 &walk_state->method_desc->method.semaphore);
558 } 573 }
559 574
@@ -582,8 +597,10 @@ acpi_ds_terminate_control_method (
582 * Delete any namespace entries created anywhere else within 597 * Delete any namespace entries created anywhere else within
583 * the namespace 598 * the namespace
584 */ 599 */
585 acpi_ns_delete_namespace_by_owner (walk_state->method_desc->method.owning_id); 600 acpi_ns_delete_namespace_by_owner (walk_state->method_desc->method.owner_id);
586 status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); 601 status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
602 acpi_ut_release_owner_id (&walk_state->method_desc->method.owner_id);
603
587 if (ACPI_FAILURE (status)) { 604 if (ACPI_FAILURE (status)) {
588 return_ACPI_STATUS (status); 605 return_ACPI_STATUS (status);
589 } 606 }