diff options
author | Bob Moore <robert.moore@intel.com> | 2008-04-10 11:06:36 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2008-04-22 14:29:20 -0400 |
commit | 773069d48030e670cf2032a13ddf16a2e0034df3 (patch) | |
tree | 2f45fd7e90600d26c08c641c75059eb0b15d6dcd /drivers/acpi/dispatcher/dswstate.c | |
parent | 4b119e21d0c66c22e8ca03df05d9de623d0eb50f (diff) |
ACPICA: Several fixes for internal method result stack
fixes STACK_OVERFLOW exception on nested method calls. internal
bugzilla 262 and 275.
Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Alexey Starikovskiy <astarikovskiy@suse.de>
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/dispatcher/dswstate.c')
-rw-r--r-- | drivers/acpi/dispatcher/dswstate.c | 513 |
1 files changed, 111 insertions, 402 deletions
diff --git a/drivers/acpi/dispatcher/dswstate.c b/drivers/acpi/dispatcher/dswstate.c index 5afcdd9c7449..698d2e1c219e 100644 --- a/drivers/acpi/dispatcher/dswstate.c +++ b/drivers/acpi/dispatcher/dswstate.c | |||
@@ -49,85 +49,9 @@ | |||
49 | #define _COMPONENT ACPI_DISPATCHER | 49 | #define _COMPONENT ACPI_DISPATCHER |
50 | ACPI_MODULE_NAME("dswstate") | 50 | ACPI_MODULE_NAME("dswstate") |
51 | 51 | ||
52 | /* Local prototypes */ | 52 | /* Local prototypes */ |
53 | #ifdef ACPI_OBSOLETE_FUNCTIONS | 53 | static acpi_status acpi_ds_result_stack_push(struct acpi_walk_state *ws); |
54 | acpi_status | 54 | static acpi_status acpi_ds_result_stack_pop(struct acpi_walk_state *ws); |
55 | acpi_ds_result_insert(void *object, | ||
56 | u32 index, struct acpi_walk_state *walk_state); | ||
57 | |||
58 | acpi_status acpi_ds_obj_stack_delete_all(struct acpi_walk_state *walk_state); | ||
59 | |||
60 | acpi_status | ||
61 | acpi_ds_obj_stack_pop_object(union acpi_operand_object **object, | ||
62 | struct acpi_walk_state *walk_state); | ||
63 | |||
64 | void *acpi_ds_obj_stack_get_value(u32 index, | ||
65 | struct acpi_walk_state *walk_state); | ||
66 | #endif | ||
67 | |||
68 | #ifdef ACPI_FUTURE_USAGE | ||
69 | /******************************************************************************* | ||
70 | * | ||
71 | * FUNCTION: acpi_ds_result_remove | ||
72 | * | ||
73 | * PARAMETERS: Object - Where to return the popped object | ||
74 | * Index - Where to extract the object | ||
75 | * walk_state - Current Walk state | ||
76 | * | ||
77 | * RETURN: Status | ||
78 | * | ||
79 | * DESCRIPTION: Pop an object off the bottom of this walk's result stack. In | ||
80 | * other words, this is a FIFO. | ||
81 | * | ||
82 | ******************************************************************************/ | ||
83 | |||
84 | acpi_status | ||
85 | acpi_ds_result_remove(union acpi_operand_object **object, | ||
86 | u32 index, struct acpi_walk_state *walk_state) | ||
87 | { | ||
88 | union acpi_generic_state *state; | ||
89 | |||
90 | ACPI_FUNCTION_NAME(ds_result_remove); | ||
91 | |||
92 | state = walk_state->results; | ||
93 | if (!state) { | ||
94 | ACPI_ERROR((AE_INFO, "No result object pushed! State=%p", | ||
95 | walk_state)); | ||
96 | return (AE_NOT_EXIST); | ||
97 | } | ||
98 | |||
99 | if (index >= ACPI_OBJ_MAX_OPERAND) { | ||
100 | ACPI_ERROR((AE_INFO, | ||
101 | "Index out of range: %X State=%p Num=%X", | ||
102 | index, walk_state, state->results.num_results)); | ||
103 | } | ||
104 | |||
105 | /* Check for a valid result object */ | ||
106 | |||
107 | if (!state->results.obj_desc[index]) { | ||
108 | ACPI_ERROR((AE_INFO, | ||
109 | "Null operand! State=%p #Ops=%X, Index=%X", | ||
110 | walk_state, state->results.num_results, index)); | ||
111 | return (AE_AML_NO_RETURN_VALUE); | ||
112 | } | ||
113 | |||
114 | /* Remove the object */ | ||
115 | |||
116 | state->results.num_results--; | ||
117 | |||
118 | *object = state->results.obj_desc[index]; | ||
119 | state->results.obj_desc[index] = NULL; | ||
120 | |||
121 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | ||
122 | "Obj=%p [%s] Index=%X State=%p Num=%X\n", | ||
123 | *object, | ||
124 | (*object) ? acpi_ut_get_object_type_name(*object) : | ||
125 | "NULL", index, walk_state, | ||
126 | state->results.num_results)); | ||
127 | |||
128 | return (AE_OK); | ||
129 | } | ||
130 | #endif /* ACPI_FUTURE_USAGE */ | ||
131 | 55 | ||
132 | /******************************************************************************* | 56 | /******************************************************************************* |
133 | * | 57 | * |
@@ -138,122 +62,67 @@ acpi_ds_result_remove(union acpi_operand_object **object, | |||
138 | * | 62 | * |
139 | * RETURN: Status | 63 | * RETURN: Status |
140 | * | 64 | * |
141 | * DESCRIPTION: Pop an object off the bottom of this walk's result stack. In | 65 | * DESCRIPTION: Pop an object off the top of this walk's result stack |
142 | * other words, this is a FIFO. | ||
143 | * | 66 | * |
144 | ******************************************************************************/ | 67 | ******************************************************************************/ |
145 | 68 | ||
146 | acpi_status | 69 | acpi_status |
147 | acpi_ds_result_pop(union acpi_operand_object ** object, | 70 | acpi_ds_result_pop(union acpi_operand_object **object, |
148 | struct acpi_walk_state * walk_state) | 71 | struct acpi_walk_state *walk_state) |
149 | { | 72 | { |
150 | acpi_native_uint index; | 73 | acpi_native_uint index; |
151 | union acpi_generic_state *state; | 74 | union acpi_generic_state *state; |
75 | acpi_status status; | ||
152 | 76 | ||
153 | ACPI_FUNCTION_NAME(ds_result_pop); | 77 | ACPI_FUNCTION_NAME(ds_result_pop); |
154 | 78 | ||
155 | state = walk_state->results; | 79 | state = walk_state->results; |
156 | if (!state) { | ||
157 | return (AE_OK); | ||
158 | } | ||
159 | |||
160 | if (!state->results.num_results) { | ||
161 | ACPI_ERROR((AE_INFO, "Result stack is empty! State=%p", | ||
162 | walk_state)); | ||
163 | return (AE_AML_NO_RETURN_VALUE); | ||
164 | } | ||
165 | 80 | ||
166 | /* Remove top element */ | 81 | /* Incorrect state of result stack */ |
167 | 82 | ||
168 | state->results.num_results--; | 83 | if (state && !walk_state->result_count) { |
169 | 84 | ACPI_ERROR((AE_INFO, "No results on result stack")); | |
170 | for (index = ACPI_OBJ_NUM_OPERANDS; index; index--) { | 85 | return (AE_AML_INTERNAL); |
171 | |||
172 | /* Check for a valid result object */ | ||
173 | |||
174 | if (state->results.obj_desc[index - 1]) { | ||
175 | *object = state->results.obj_desc[index - 1]; | ||
176 | state->results.obj_desc[index - 1] = NULL; | ||
177 | |||
178 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | ||
179 | "Obj=%p [%s] Index=%X State=%p Num=%X\n", | ||
180 | *object, | ||
181 | (*object) ? | ||
182 | acpi_ut_get_object_type_name(*object) | ||
183 | : "NULL", (u32) index - 1, walk_state, | ||
184 | state->results.num_results)); | ||
185 | |||
186 | return (AE_OK); | ||
187 | } | ||
188 | } | 86 | } |
189 | 87 | ||
190 | ACPI_ERROR((AE_INFO, "No result objects! State=%p", walk_state)); | 88 | if (!state && walk_state->result_count) { |
191 | return (AE_AML_NO_RETURN_VALUE); | 89 | ACPI_ERROR((AE_INFO, "No result state for result stack")); |
192 | } | 90 | return (AE_AML_INTERNAL); |
193 | 91 | } | |
194 | /******************************************************************************* | ||
195 | * | ||
196 | * FUNCTION: acpi_ds_result_pop_from_bottom | ||
197 | * | ||
198 | * PARAMETERS: Object - Where to return the popped object | ||
199 | * walk_state - Current Walk state | ||
200 | * | ||
201 | * RETURN: Status | ||
202 | * | ||
203 | * DESCRIPTION: Pop an object off the bottom of this walk's result stack. In | ||
204 | * other words, this is a FIFO. | ||
205 | * | ||
206 | ******************************************************************************/ | ||
207 | |||
208 | acpi_status | ||
209 | acpi_ds_result_pop_from_bottom(union acpi_operand_object ** object, | ||
210 | struct acpi_walk_state * walk_state) | ||
211 | { | ||
212 | acpi_native_uint index; | ||
213 | union acpi_generic_state *state; | ||
214 | 92 | ||
215 | ACPI_FUNCTION_NAME(ds_result_pop_from_bottom); | 93 | /* Empty result stack */ |
216 | 94 | ||
217 | state = walk_state->results; | ||
218 | if (!state) { | 95 | if (!state) { |
219 | ACPI_ERROR((AE_INFO, | 96 | ACPI_ERROR((AE_INFO, "Result stack is empty! State=%p", |
220 | "No result object pushed! State=%p", walk_state)); | ||
221 | return (AE_NOT_EXIST); | ||
222 | } | ||
223 | |||
224 | if (!state->results.num_results) { | ||
225 | ACPI_ERROR((AE_INFO, "No result objects! State=%p", | ||
226 | walk_state)); | 97 | walk_state)); |
227 | return (AE_AML_NO_RETURN_VALUE); | 98 | return (AE_AML_NO_RETURN_VALUE); |
228 | } | 99 | } |
229 | 100 | ||
230 | /* Remove Bottom element */ | 101 | /* Return object of the top element and clean that top element result stack */ |
231 | |||
232 | *object = state->results.obj_desc[0]; | ||
233 | |||
234 | /* Push entire stack down one element */ | ||
235 | |||
236 | for (index = 0; index < state->results.num_results; index++) { | ||
237 | state->results.obj_desc[index] = | ||
238 | state->results.obj_desc[index + 1]; | ||
239 | } | ||
240 | 102 | ||
241 | state->results.num_results--; | 103 | walk_state->result_count--; |
242 | 104 | index = walk_state->result_count % ACPI_RESULTS_FRAME_OBJ_NUM; | |
243 | /* Check for a valid result object */ | ||
244 | 105 | ||
106 | *object = state->results.obj_desc[index]; | ||
245 | if (!*object) { | 107 | if (!*object) { |
246 | ACPI_ERROR((AE_INFO, | 108 | ACPI_ERROR((AE_INFO, |
247 | "Null operand! State=%p #Ops=%X Index=%X", | 109 | "No result objects on result stack, State=%p", |
248 | walk_state, state->results.num_results, | 110 | walk_state)); |
249 | (u32) index)); | ||
250 | return (AE_AML_NO_RETURN_VALUE); | 111 | return (AE_AML_NO_RETURN_VALUE); |
251 | } | 112 | } |
252 | 113 | ||
253 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Obj=%p [%s] Results=%p State=%p\n", | 114 | state->results.obj_desc[index] = NULL; |
254 | *object, | 115 | if (index == 0) { |
255 | (*object) ? acpi_ut_get_object_type_name(*object) : | 116 | status = acpi_ds_result_stack_pop(walk_state); |
256 | "NULL", state, walk_state)); | 117 | if (ACPI_FAILURE(status)) { |
118 | return (status); | ||
119 | } | ||
120 | } | ||
121 | |||
122 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | ||
123 | "Obj=%p [%s] Index=%X State=%p Num=%X\n", *object, | ||
124 | acpi_ut_get_object_type_name(*object), | ||
125 | (u32) index, walk_state, walk_state->result_count)); | ||
257 | 126 | ||
258 | return (AE_OK); | 127 | return (AE_OK); |
259 | } | 128 | } |
@@ -276,39 +145,56 @@ acpi_ds_result_push(union acpi_operand_object * object, | |||
276 | struct acpi_walk_state * walk_state) | 145 | struct acpi_walk_state * walk_state) |
277 | { | 146 | { |
278 | union acpi_generic_state *state; | 147 | union acpi_generic_state *state; |
148 | acpi_status status; | ||
149 | acpi_native_uint index; | ||
279 | 150 | ||
280 | ACPI_FUNCTION_NAME(ds_result_push); | 151 | ACPI_FUNCTION_NAME(ds_result_push); |
281 | 152 | ||
153 | if (walk_state->result_count > walk_state->result_size) { | ||
154 | ACPI_ERROR((AE_INFO, "Result stack is full")); | ||
155 | return (AE_AML_INTERNAL); | ||
156 | } else if (walk_state->result_count == walk_state->result_size) { | ||
157 | |||
158 | /* Extend the result stack */ | ||
159 | |||
160 | status = acpi_ds_result_stack_push(walk_state); | ||
161 | if (ACPI_FAILURE(status)) { | ||
162 | ACPI_ERROR((AE_INFO, | ||
163 | "Failed to extend the result stack")); | ||
164 | return (status); | ||
165 | } | ||
166 | } | ||
167 | |||
168 | if (!(walk_state->result_count < walk_state->result_size)) { | ||
169 | ACPI_ERROR((AE_INFO, "No free elements in result stack")); | ||
170 | return (AE_AML_INTERNAL); | ||
171 | } | ||
172 | |||
282 | state = walk_state->results; | 173 | state = walk_state->results; |
283 | if (!state) { | 174 | if (!state) { |
284 | ACPI_ERROR((AE_INFO, "No result stack frame during push")); | 175 | ACPI_ERROR((AE_INFO, "No result stack frame during push")); |
285 | return (AE_AML_INTERNAL); | 176 | return (AE_AML_INTERNAL); |
286 | } | 177 | } |
287 | 178 | ||
288 | if (state->results.num_results == ACPI_OBJ_NUM_OPERANDS) { | ||
289 | ACPI_ERROR((AE_INFO, | ||
290 | "Result stack overflow: Obj=%p State=%p Num=%X", | ||
291 | object, walk_state, state->results.num_results)); | ||
292 | return (AE_STACK_OVERFLOW); | ||
293 | } | ||
294 | |||
295 | if (!object) { | 179 | if (!object) { |
296 | ACPI_ERROR((AE_INFO, | 180 | ACPI_ERROR((AE_INFO, |
297 | "Null Object! Obj=%p State=%p Num=%X", | 181 | "Null Object! Obj=%p State=%p Num=%X", |
298 | object, walk_state, state->results.num_results)); | 182 | object, walk_state, walk_state->result_count)); |
299 | return (AE_BAD_PARAMETER); | 183 | return (AE_BAD_PARAMETER); |
300 | } | 184 | } |
301 | 185 | ||
302 | state->results.obj_desc[state->results.num_results] = object; | 186 | /* Assign the address of object to the top free element of result stack */ |
303 | state->results.num_results++; | 187 | |
188 | index = walk_state->result_count % ACPI_RESULTS_FRAME_OBJ_NUM; | ||
189 | state->results.obj_desc[index] = object; | ||
190 | walk_state->result_count++; | ||
304 | 191 | ||
305 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Obj=%p [%s] State=%p Num=%X Cur=%X\n", | 192 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Obj=%p [%s] State=%p Num=%X Cur=%X\n", |
306 | object, | 193 | object, |
307 | object ? | ||
308 | acpi_ut_get_object_type_name((union | 194 | acpi_ut_get_object_type_name((union |
309 | acpi_operand_object *) | 195 | acpi_operand_object *) |
310 | object) : "NULL", | 196 | object), walk_state, |
311 | walk_state, state->results.num_results, | 197 | walk_state->result_count, |
312 | walk_state->current_result)); | 198 | walk_state->current_result)); |
313 | 199 | ||
314 | return (AE_OK); | 200 | return (AE_OK); |
@@ -322,16 +208,25 @@ acpi_ds_result_push(union acpi_operand_object * object, | |||
322 | * | 208 | * |
323 | * RETURN: Status | 209 | * RETURN: Status |
324 | * | 210 | * |
325 | * DESCRIPTION: Push an object onto the walk_state result stack. | 211 | * DESCRIPTION: Push an object onto the walk_state result stack |
326 | * | 212 | * |
327 | ******************************************************************************/ | 213 | ******************************************************************************/ |
328 | 214 | ||
329 | acpi_status acpi_ds_result_stack_push(struct acpi_walk_state * walk_state) | 215 | static acpi_status acpi_ds_result_stack_push(struct acpi_walk_state *walk_state) |
330 | { | 216 | { |
331 | union acpi_generic_state *state; | 217 | union acpi_generic_state *state; |
332 | 218 | ||
333 | ACPI_FUNCTION_NAME(ds_result_stack_push); | 219 | ACPI_FUNCTION_NAME(ds_result_stack_push); |
334 | 220 | ||
221 | /* Check for stack overflow */ | ||
222 | |||
223 | if ((walk_state->result_size + ACPI_RESULTS_FRAME_OBJ_NUM) > | ||
224 | ACPI_RESULTS_OBJ_NUM_MAX) { | ||
225 | ACPI_ERROR((AE_INFO, "Result stack overflow: State=%p Num=%X", | ||
226 | walk_state, walk_state->result_size)); | ||
227 | return (AE_STACK_OVERFLOW); | ||
228 | } | ||
229 | |||
335 | state = acpi_ut_create_generic_state(); | 230 | state = acpi_ut_create_generic_state(); |
336 | if (!state) { | 231 | if (!state) { |
337 | return (AE_NO_MEMORY); | 232 | return (AE_NO_MEMORY); |
@@ -340,6 +235,10 @@ acpi_status acpi_ds_result_stack_push(struct acpi_walk_state * walk_state) | |||
340 | state->common.descriptor_type = ACPI_DESC_TYPE_STATE_RESULT; | 235 | state->common.descriptor_type = ACPI_DESC_TYPE_STATE_RESULT; |
341 | acpi_ut_push_generic_state(&walk_state->results, state); | 236 | acpi_ut_push_generic_state(&walk_state->results, state); |
342 | 237 | ||
238 | /* Increase the length of the result stack by the length of frame */ | ||
239 | |||
240 | walk_state->result_size += ACPI_RESULTS_FRAME_OBJ_NUM; | ||
241 | |||
343 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Results=%p State=%p\n", | 242 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Results=%p State=%p\n", |
344 | state, walk_state)); | 243 | state, walk_state)); |
345 | 244 | ||
@@ -354,11 +253,11 @@ acpi_status acpi_ds_result_stack_push(struct acpi_walk_state * walk_state) | |||
354 | * | 253 | * |
355 | * RETURN: Status | 254 | * RETURN: Status |
356 | * | 255 | * |
357 | * DESCRIPTION: Pop an object off of the walk_state result stack. | 256 | * DESCRIPTION: Pop an object off of the walk_state result stack |
358 | * | 257 | * |
359 | ******************************************************************************/ | 258 | ******************************************************************************/ |
360 | 259 | ||
361 | acpi_status acpi_ds_result_stack_pop(struct acpi_walk_state * walk_state) | 260 | static acpi_status acpi_ds_result_stack_pop(struct acpi_walk_state *walk_state) |
362 | { | 261 | { |
363 | union acpi_generic_state *state; | 262 | union acpi_generic_state *state; |
364 | 263 | ||
@@ -367,18 +266,27 @@ acpi_status acpi_ds_result_stack_pop(struct acpi_walk_state * walk_state) | |||
367 | /* Check for stack underflow */ | 266 | /* Check for stack underflow */ |
368 | 267 | ||
369 | if (walk_state->results == NULL) { | 268 | if (walk_state->results == NULL) { |
370 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Underflow - State=%p\n", | 269 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, |
270 | "Result stack underflow - State=%p\n", | ||
371 | walk_state)); | 271 | walk_state)); |
372 | return (AE_AML_NO_OPERAND); | 272 | return (AE_AML_NO_OPERAND); |
373 | } | 273 | } |
374 | 274 | ||
275 | if (walk_state->result_size < ACPI_RESULTS_FRAME_OBJ_NUM) { | ||
276 | ACPI_ERROR((AE_INFO, "Insufficient result stack size")); | ||
277 | return (AE_AML_INTERNAL); | ||
278 | } | ||
279 | |||
375 | state = acpi_ut_pop_generic_state(&walk_state->results); | 280 | state = acpi_ut_pop_generic_state(&walk_state->results); |
281 | acpi_ut_delete_generic_state(state); | ||
282 | |||
283 | /* Decrease the length of result stack by the length of frame */ | ||
284 | |||
285 | walk_state->result_size -= ACPI_RESULTS_FRAME_OBJ_NUM; | ||
376 | 286 | ||
377 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | 287 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, |
378 | "Result=%p RemainingResults=%X State=%p\n", | 288 | "Result=%p RemainingResults=%X State=%p\n", |
379 | state, state->results.num_results, walk_state)); | 289 | state, walk_state->result_count, walk_state)); |
380 | |||
381 | acpi_ut_delete_generic_state(state); | ||
382 | 290 | ||
383 | return (AE_OK); | 291 | return (AE_OK); |
384 | } | 292 | } |
@@ -412,9 +320,13 @@ acpi_ds_obj_stack_push(void *object, struct acpi_walk_state * walk_state) | |||
412 | 320 | ||
413 | /* Put the object onto the stack */ | 321 | /* Put the object onto the stack */ |
414 | 322 | ||
415 | walk_state->operands[walk_state->num_operands] = object; | 323 | walk_state->operands[walk_state->operand_index] = object; |
416 | walk_state->num_operands++; | 324 | walk_state->num_operands++; |
417 | 325 | ||
326 | /* For the usual order of filling the operand stack */ | ||
327 | |||
328 | walk_state->operand_index++; | ||
329 | |||
418 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Obj=%p [%s] State=%p #Ops=%X\n", | 330 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Obj=%p [%s] State=%p #Ops=%X\n", |
419 | object, | 331 | object, |
420 | acpi_ut_get_object_type_name((union | 332 | acpi_ut_get_object_type_name((union |
@@ -484,43 +396,36 @@ acpi_ds_obj_stack_pop(u32 pop_count, struct acpi_walk_state * walk_state) | |||
484 | * | 396 | * |
485 | ******************************************************************************/ | 397 | ******************************************************************************/ |
486 | 398 | ||
487 | acpi_status | 399 | void |
488 | acpi_ds_obj_stack_pop_and_delete(u32 pop_count, | 400 | acpi_ds_obj_stack_pop_and_delete(u32 pop_count, |
489 | struct acpi_walk_state * walk_state) | 401 | struct acpi_walk_state *walk_state) |
490 | { | 402 | { |
491 | u32 i; | 403 | u32 i; |
492 | union acpi_operand_object *obj_desc; | 404 | union acpi_operand_object *obj_desc; |
493 | 405 | ||
494 | ACPI_FUNCTION_NAME(ds_obj_stack_pop_and_delete); | 406 | ACPI_FUNCTION_NAME(ds_obj_stack_pop_and_delete); |
495 | 407 | ||
496 | for (i = 0; i < pop_count; i++) { | 408 | if (pop_count == 0) { |
497 | 409 | return; | |
498 | /* Check for stack underflow */ | 410 | } |
499 | 411 | ||
412 | for (i = (pop_count - 1); i >= 0; i--) { | ||
500 | if (walk_state->num_operands == 0) { | 413 | if (walk_state->num_operands == 0) { |
501 | ACPI_ERROR((AE_INFO, | 414 | return; |
502 | "Object stack underflow! Count=%X State=%p #Ops=%X", | ||
503 | pop_count, walk_state, | ||
504 | walk_state->num_operands)); | ||
505 | return (AE_STACK_UNDERFLOW); | ||
506 | } | 415 | } |
507 | 416 | ||
508 | /* Pop the stack and delete an object if present in this stack entry */ | 417 | /* Pop the stack and delete an object if present in this stack entry */ |
509 | 418 | ||
510 | walk_state->num_operands--; | 419 | walk_state->num_operands--; |
511 | obj_desc = walk_state->operands[walk_state->num_operands]; | 420 | obj_desc = walk_state->operands[i]; |
512 | if (obj_desc) { | 421 | if (obj_desc) { |
513 | acpi_ut_remove_reference(walk_state-> | 422 | acpi_ut_remove_reference(walk_state->operands[i]); |
514 | operands[walk_state-> | 423 | walk_state->operands[i] = NULL; |
515 | num_operands]); | ||
516 | walk_state->operands[walk_state->num_operands] = NULL; | ||
517 | } | 424 | } |
518 | } | 425 | } |
519 | 426 | ||
520 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Count=%X State=%p #Ops=%X\n", | 427 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Count=%X State=%p #Ops=%X\n", |
521 | pop_count, walk_state, walk_state->num_operands)); | 428 | pop_count, walk_state, walk_state->num_operands)); |
522 | |||
523 | return (AE_OK); | ||
524 | } | 429 | } |
525 | 430 | ||
526 | /******************************************************************************* | 431 | /******************************************************************************* |
@@ -560,7 +465,7 @@ struct acpi_walk_state *acpi_ds_get_current_walk_state(struct acpi_thread_state | |||
560 | * | 465 | * |
561 | * RETURN: None | 466 | * RETURN: None |
562 | * | 467 | * |
563 | * DESCRIPTION: Place the Thread state at the head of the state list. | 468 | * DESCRIPTION: Place the Thread state at the head of the state list |
564 | * | 469 | * |
565 | ******************************************************************************/ | 470 | ******************************************************************************/ |
566 | 471 | ||
@@ -636,7 +541,6 @@ struct acpi_walk_state *acpi_ds_create_walk_state(acpi_owner_id owner_id, union | |||
636 | *thread) | 541 | *thread) |
637 | { | 542 | { |
638 | struct acpi_walk_state *walk_state; | 543 | struct acpi_walk_state *walk_state; |
639 | acpi_status status; | ||
640 | 544 | ||
641 | ACPI_FUNCTION_TRACE(ds_create_walk_state); | 545 | ACPI_FUNCTION_TRACE(ds_create_walk_state); |
642 | 546 | ||
@@ -659,14 +563,6 @@ struct acpi_walk_state *acpi_ds_create_walk_state(acpi_owner_id owner_id, union | |||
659 | acpi_ds_method_data_init(walk_state); | 563 | acpi_ds_method_data_init(walk_state); |
660 | #endif | 564 | #endif |
661 | 565 | ||
662 | /* Create an initial result stack entry */ | ||
663 | |||
664 | status = acpi_ds_result_stack_push(walk_state); | ||
665 | if (ACPI_FAILURE(status)) { | ||
666 | ACPI_FREE(walk_state); | ||
667 | return_PTR(NULL); | ||
668 | } | ||
669 | |||
670 | /* Put the new state at the head of the walk list */ | 566 | /* Put the new state at the head of the walk list */ |
671 | 567 | ||
672 | if (thread) { | 568 | if (thread) { |
@@ -860,190 +756,3 @@ void acpi_ds_delete_walk_state(struct acpi_walk_state *walk_state) | |||
860 | ACPI_FREE(walk_state); | 756 | ACPI_FREE(walk_state); |
861 | return_VOID; | 757 | return_VOID; |
862 | } | 758 | } |
863 | |||
864 | #ifdef ACPI_OBSOLETE_FUNCTIONS | ||
865 | /******************************************************************************* | ||
866 | * | ||
867 | * FUNCTION: acpi_ds_result_insert | ||
868 | * | ||
869 | * PARAMETERS: Object - Object to push | ||
870 | * Index - Where to insert the object | ||
871 | * walk_state - Current Walk state | ||
872 | * | ||
873 | * RETURN: Status | ||
874 | * | ||
875 | * DESCRIPTION: Insert an object onto this walk's result stack | ||
876 | * | ||
877 | ******************************************************************************/ | ||
878 | |||
879 | acpi_status | ||
880 | acpi_ds_result_insert(void *object, | ||
881 | u32 index, struct acpi_walk_state *walk_state) | ||
882 | { | ||
883 | union acpi_generic_state *state; | ||
884 | |||
885 | ACPI_FUNCTION_NAME(ds_result_insert); | ||
886 | |||
887 | state = walk_state->results; | ||
888 | if (!state) { | ||
889 | ACPI_ERROR((AE_INFO, "No result object pushed! State=%p", | ||
890 | walk_state)); | ||
891 | return (AE_NOT_EXIST); | ||
892 | } | ||
893 | |||
894 | if (index >= ACPI_OBJ_NUM_OPERANDS) { | ||
895 | ACPI_ERROR((AE_INFO, | ||
896 | "Index out of range: %X Obj=%p State=%p Num=%X", | ||
897 | index, object, walk_state, | ||
898 | state->results.num_results)); | ||
899 | return (AE_BAD_PARAMETER); | ||
900 | } | ||
901 | |||
902 | if (!object) { | ||
903 | ACPI_ERROR((AE_INFO, | ||
904 | "Null Object! Index=%X Obj=%p State=%p Num=%X", | ||
905 | index, object, walk_state, | ||
906 | state->results.num_results)); | ||
907 | return (AE_BAD_PARAMETER); | ||
908 | } | ||
909 | |||
910 | state->results.obj_desc[index] = object; | ||
911 | state->results.num_results++; | ||
912 | |||
913 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | ||
914 | "Obj=%p [%s] State=%p Num=%X Cur=%X\n", | ||
915 | object, | ||
916 | object ? | ||
917 | acpi_ut_get_object_type_name((union | ||
918 | acpi_operand_object *) | ||
919 | object) : "NULL", | ||
920 | walk_state, state->results.num_results, | ||
921 | walk_state->current_result)); | ||
922 | |||
923 | return (AE_OK); | ||
924 | } | ||
925 | |||
926 | /******************************************************************************* | ||
927 | * | ||
928 | * FUNCTION: acpi_ds_obj_stack_delete_all | ||
929 | * | ||
930 | * PARAMETERS: walk_state - Current Walk state | ||
931 | * | ||
932 | * RETURN: Status | ||
933 | * | ||
934 | * DESCRIPTION: Clear the object stack by deleting all objects that are on it. | ||
935 | * Should be used with great care, if at all! | ||
936 | * | ||
937 | ******************************************************************************/ | ||
938 | |||
939 | acpi_status acpi_ds_obj_stack_delete_all(struct acpi_walk_state * walk_state) | ||
940 | { | ||
941 | u32 i; | ||
942 | |||
943 | ACPI_FUNCTION_TRACE_PTR(ds_obj_stack_delete_all, walk_state); | ||
944 | |||
945 | /* The stack size is configurable, but fixed */ | ||
946 | |||
947 | for (i = 0; i < ACPI_OBJ_NUM_OPERANDS; i++) { | ||
948 | if (walk_state->operands[i]) { | ||
949 | acpi_ut_remove_reference(walk_state->operands[i]); | ||
950 | walk_state->operands[i] = NULL; | ||
951 | } | ||
952 | } | ||
953 | |||
954 | return_ACPI_STATUS(AE_OK); | ||
955 | } | ||
956 | |||
957 | /******************************************************************************* | ||
958 | * | ||
959 | * FUNCTION: acpi_ds_obj_stack_pop_object | ||
960 | * | ||
961 | * PARAMETERS: Object - Where to return the popped object | ||
962 | * walk_state - Current Walk state | ||
963 | * | ||
964 | * RETURN: Status | ||
965 | * | ||
966 | * DESCRIPTION: Pop this walk's object stack. Objects on the stack are NOT | ||
967 | * deleted by this routine. | ||
968 | * | ||
969 | ******************************************************************************/ | ||
970 | |||
971 | acpi_status | ||
972 | acpi_ds_obj_stack_pop_object(union acpi_operand_object **object, | ||
973 | struct acpi_walk_state *walk_state) | ||
974 | { | ||
975 | ACPI_FUNCTION_NAME(ds_obj_stack_pop_object); | ||
976 | |||
977 | /* Check for stack underflow */ | ||
978 | |||
979 | if (walk_state->num_operands == 0) { | ||
980 | ACPI_ERROR((AE_INFO, | ||
981 | "Missing operand/stack empty! State=%p #Ops=%X", | ||
982 | walk_state, walk_state->num_operands)); | ||
983 | *object = NULL; | ||
984 | return (AE_AML_NO_OPERAND); | ||
985 | } | ||
986 | |||
987 | /* Pop the stack */ | ||
988 | |||
989 | walk_state->num_operands--; | ||
990 | |||
991 | /* Check for a valid operand */ | ||
992 | |||
993 | if (!walk_state->operands[walk_state->num_operands]) { | ||
994 | ACPI_ERROR((AE_INFO, | ||
995 | "Null operand! State=%p #Ops=%X", | ||
996 | walk_state, walk_state->num_operands)); | ||
997 | *object = NULL; | ||
998 | return (AE_AML_NO_OPERAND); | ||
999 | } | ||
1000 | |||
1001 | /* Get operand and set stack entry to null */ | ||
1002 | |||
1003 | *object = walk_state->operands[walk_state->num_operands]; | ||
1004 | walk_state->operands[walk_state->num_operands] = NULL; | ||
1005 | |||
1006 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Obj=%p [%s] State=%p #Ops=%X\n", | ||
1007 | *object, acpi_ut_get_object_type_name(*object), | ||
1008 | walk_state, walk_state->num_operands)); | ||
1009 | |||
1010 | return (AE_OK); | ||
1011 | } | ||
1012 | |||
1013 | /******************************************************************************* | ||
1014 | * | ||
1015 | * FUNCTION: acpi_ds_obj_stack_get_value | ||
1016 | * | ||
1017 | * PARAMETERS: Index - Stack index whose value is desired. Based | ||
1018 | * on the top of the stack (index=0 == top) | ||
1019 | * walk_state - Current Walk state | ||
1020 | * | ||
1021 | * RETURN: Pointer to the requested operand | ||
1022 | * | ||
1023 | * DESCRIPTION: Retrieve an object from this walk's operand stack. Index must | ||
1024 | * be within the range of the current stack pointer. | ||
1025 | * | ||
1026 | ******************************************************************************/ | ||
1027 | |||
1028 | void *acpi_ds_obj_stack_get_value(u32 index, struct acpi_walk_state *walk_state) | ||
1029 | { | ||
1030 | |||
1031 | ACPI_FUNCTION_TRACE_PTR(ds_obj_stack_get_value, walk_state); | ||
1032 | |||
1033 | /* Can't do it if the stack is empty */ | ||
1034 | |||
1035 | if (walk_state->num_operands == 0) { | ||
1036 | return_PTR(NULL); | ||
1037 | } | ||
1038 | |||
1039 | /* or if the index is past the top of the stack */ | ||
1040 | |||
1041 | if (index > (walk_state->num_operands - (u32) 1)) { | ||
1042 | return_PTR(NULL); | ||
1043 | } | ||
1044 | |||
1045 | return_PTR(walk_state-> | ||
1046 | operands[(acpi_native_uint) (walk_state->num_operands - 1) - | ||
1047 | index]); | ||
1048 | } | ||
1049 | #endif | ||