Linux-2.6.12-rc2
[linux-flexiantxendom0-natty.git] / drivers / acpi / dispatcher / dswstate.c
1 /******************************************************************************
2  *
3  * Module Name: dswstate - Dispatcher parse tree walk management routines
4  *
5  *****************************************************************************/
6
7 /*
8  * Copyright (C) 2000 - 2005, R. Byron Moore
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions, and the following disclaimer,
16  *    without modification.
17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18  *    substantially similar to the "NO WARRANTY" disclaimer below
19  *    ("Disclaimer") and any redistribution must be conditioned upon
20  *    including a substantially similar Disclaimer requirement for further
21  *    binary redistribution.
22  * 3. Neither the names of the above-listed copyright holders nor the names
23  *    of any contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * Alternatively, this software may be distributed under the terms of the
27  * GNU General Public License ("GPL") version 2 as published by the Free
28  * Software Foundation.
29  *
30  * NO WARRANTY
31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41  * POSSIBILITY OF SUCH DAMAGES.
42  */
43
44
45 #include <acpi/acpi.h>
46 #include <acpi/acparser.h>
47 #include <acpi/acdispat.h>
48 #include <acpi/acnamesp.h>
49
50 #define _COMPONENT          ACPI_DISPATCHER
51          ACPI_MODULE_NAME    ("dswstate")
52
53
54 #ifdef ACPI_FUTURE_USAGE
55
56 /*******************************************************************************
57  *
58  * FUNCTION:    acpi_ds_result_insert
59  *
60  * PARAMETERS:  Object              - Object to push
61  *              Index               - Where to insert the object
62  *              walk_state          - Current Walk state
63  *
64  * RETURN:      Status
65  *
66  * DESCRIPTION: Insert an object onto this walk's result stack
67  *
68  ******************************************************************************/
69
70 acpi_status
71 acpi_ds_result_insert (
72         void                            *object,
73         u32                             index,
74         struct acpi_walk_state          *walk_state)
75 {
76         union acpi_generic_state        *state;
77
78
79         ACPI_FUNCTION_NAME ("ds_result_insert");
80
81
82         state = walk_state->results;
83         if (!state) {
84                 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No result object pushed! State=%p\n",
85                         walk_state));
86                 return (AE_NOT_EXIST);
87         }
88
89         if (index >= ACPI_OBJ_NUM_OPERANDS) {
90                 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
91                         "Index out of range: %X Obj=%p State=%p Num=%X\n",
92                         index, object, walk_state, state->results.num_results));
93                 return (AE_BAD_PARAMETER);
94         }
95
96         if (!object) {
97                 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
98                         "Null Object! Index=%X Obj=%p State=%p Num=%X\n",
99                         index, object, walk_state, state->results.num_results));
100                 return (AE_BAD_PARAMETER);
101         }
102
103         state->results.obj_desc [index] = object;
104         state->results.num_results++;
105
106         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
107                 "Obj=%p [%s] State=%p Num=%X Cur=%X\n",
108                 object, object ? acpi_ut_get_object_type_name ((union acpi_operand_object *) object) : "NULL",
109                 walk_state, state->results.num_results, walk_state->current_result));
110
111         return (AE_OK);
112 }
113
114
115 /*******************************************************************************
116  *
117  * FUNCTION:    acpi_ds_result_remove
118  *
119  * PARAMETERS:  Object              - Where to return the popped object
120  *              Index               - Where to extract the object
121  *              walk_state          - Current Walk state
122  *
123  * RETURN:      Status
124  *
125  * DESCRIPTION: Pop an object off the bottom of this walk's result stack.  In
126  *              other words, this is a FIFO.
127  *
128  ******************************************************************************/
129
130 acpi_status
131 acpi_ds_result_remove (
132         union acpi_operand_object       **object,
133         u32                             index,
134         struct acpi_walk_state          *walk_state)
135 {
136         union acpi_generic_state        *state;
137
138
139         ACPI_FUNCTION_NAME ("ds_result_remove");
140
141
142         state = walk_state->results;
143         if (!state) {
144                 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No result object pushed! State=%p\n",
145                         walk_state));
146                 return (AE_NOT_EXIST);
147         }
148
149         if (index >= ACPI_OBJ_MAX_OPERAND) {
150                 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
151                         "Index out of range: %X State=%p Num=%X\n",
152                         index, walk_state, state->results.num_results));
153         }
154
155         /* Check for a valid result object */
156
157         if (!state->results.obj_desc [index]) {
158                 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
159                         "Null operand! State=%p #Ops=%X, Index=%X\n",
160                         walk_state, state->results.num_results, index));
161                 return (AE_AML_NO_RETURN_VALUE);
162         }
163
164         /* Remove the object */
165
166         state->results.num_results--;
167
168         *object = state->results.obj_desc [index];
169         state->results.obj_desc [index] = NULL;
170
171         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
172                 "Obj=%p [%s] Index=%X State=%p Num=%X\n",
173                 *object, (*object) ? acpi_ut_get_object_type_name (*object) : "NULL",
174                 index, walk_state, state->results.num_results));
175
176         return (AE_OK);
177 }
178
179 #endif  /*  ACPI_FUTURE_USAGE  */
180
181
182 /*******************************************************************************
183  *
184  * FUNCTION:    acpi_ds_result_pop
185  *
186  * PARAMETERS:  Object              - Where to return the popped object
187  *              walk_state          - Current Walk state
188  *
189  * RETURN:      Status
190  *
191  * DESCRIPTION: Pop an object off the bottom of this walk's result stack.  In
192  *              other words, this is a FIFO.
193  *
194  ******************************************************************************/
195
196 acpi_status
197 acpi_ds_result_pop (
198         union acpi_operand_object       **object,
199         struct acpi_walk_state          *walk_state)
200 {
201         acpi_native_uint                index;
202         union acpi_generic_state        *state;
203
204
205         ACPI_FUNCTION_NAME ("ds_result_pop");
206
207
208         state = walk_state->results;
209         if (!state) {
210                 return (AE_OK);
211         }
212
213         if (!state->results.num_results) {
214                 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Result stack is empty! State=%p\n",
215                         walk_state));
216                 return (AE_AML_NO_RETURN_VALUE);
217         }
218
219         /* Remove top element */
220
221         state->results.num_results--;
222
223         for (index = ACPI_OBJ_NUM_OPERANDS; index; index--) {
224                 /* Check for a valid result object */
225
226                 if (state->results.obj_desc [index -1]) {
227                         *object = state->results.obj_desc [index -1];
228                         state->results.obj_desc [index -1] = NULL;
229
230                         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s] Index=%X State=%p Num=%X\n",
231                                 *object, (*object) ? acpi_ut_get_object_type_name (*object) : "NULL",
232                                 (u32) index -1, walk_state, state->results.num_results));
233
234                         return (AE_OK);
235                 }
236         }
237
238         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No result objects! State=%p\n", walk_state));
239         return (AE_AML_NO_RETURN_VALUE);
240 }
241
242
243 /*******************************************************************************
244  *
245  * FUNCTION:    acpi_ds_result_pop_from_bottom
246  *
247  * PARAMETERS:  Object              - Where to return the popped object
248  *              walk_state          - Current Walk state
249  *
250  * RETURN:      Status
251  *
252  * DESCRIPTION: Pop an object off the bottom of this walk's result stack.  In
253  *              other words, this is a FIFO.
254  *
255  ******************************************************************************/
256
257 acpi_status
258 acpi_ds_result_pop_from_bottom (
259         union acpi_operand_object       **object,
260         struct acpi_walk_state          *walk_state)
261 {
262         acpi_native_uint                index;
263         union acpi_generic_state        *state;
264
265
266         ACPI_FUNCTION_NAME ("ds_result_pop_from_bottom");
267
268
269         state = walk_state->results;
270         if (!state) {
271                 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
272                         "Warning: No result object pushed! State=%p\n", walk_state));
273                 return (AE_NOT_EXIST);
274         }
275
276         if (!state->results.num_results) {
277                 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No result objects! State=%p\n", walk_state));
278                 return (AE_AML_NO_RETURN_VALUE);
279         }
280
281         /* Remove Bottom element */
282
283         *object = state->results.obj_desc [0];
284
285         /* Push entire stack down one element */
286
287         for (index = 0; index < state->results.num_results; index++) {
288                 state->results.obj_desc [index] = state->results.obj_desc [index + 1];
289         }
290
291         state->results.num_results--;
292
293         /* Check for a valid result object */
294
295         if (!*object) {
296                 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null operand! State=%p #Ops=%X, Index=%X\n",
297                         walk_state, state->results.num_results, (u32) index));
298                 return (AE_AML_NO_RETURN_VALUE);
299         }
300
301         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s], Results=%p State=%p\n",
302                 *object, (*object) ? acpi_ut_get_object_type_name (*object) : "NULL",
303                 state, walk_state));
304
305         return (AE_OK);
306 }
307
308
309 /*******************************************************************************
310  *
311  * FUNCTION:    acpi_ds_result_push
312  *
313  * PARAMETERS:  Object              - Where to return the popped object
314  *              walk_state          - Current Walk state
315  *
316  * RETURN:      Status
317  *
318  * DESCRIPTION: Push an object onto the current result stack
319  *
320  ******************************************************************************/
321
322 acpi_status
323 acpi_ds_result_push (
324         union acpi_operand_object       *object,
325         struct acpi_walk_state          *walk_state)
326 {
327         union acpi_generic_state        *state;
328
329
330         ACPI_FUNCTION_NAME ("ds_result_push");
331
332
333         state = walk_state->results;
334         if (!state) {
335                 ACPI_REPORT_ERROR (("No result stack frame during push\n"));
336                 return (AE_AML_INTERNAL);
337         }
338
339         if (state->results.num_results == ACPI_OBJ_NUM_OPERANDS) {
340                 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
341                         "Result stack overflow: Obj=%p State=%p Num=%X\n",
342                         object, walk_state, state->results.num_results));
343                 return (AE_STACK_OVERFLOW);
344         }
345
346         if (!object) {
347                 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null Object! Obj=%p State=%p Num=%X\n",
348                         object, walk_state, state->results.num_results));
349                 return (AE_BAD_PARAMETER);
350         }
351
352         state->results.obj_desc [state->results.num_results] = object;
353         state->results.num_results++;
354
355         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s] State=%p Num=%X Cur=%X\n",
356                 object, object ? acpi_ut_get_object_type_name ((union acpi_operand_object *) object) : "NULL",
357                 walk_state, state->results.num_results, walk_state->current_result));
358
359         return (AE_OK);
360 }
361
362
363 /*******************************************************************************
364  *
365  * FUNCTION:    acpi_ds_result_stack_push
366  *
367  * PARAMETERS:  walk_state          - Current Walk state
368  *
369  * RETURN:      Status
370  *
371  * DESCRIPTION: Push an object onto the walk_state result stack.
372  *
373  ******************************************************************************/
374
375 acpi_status
376 acpi_ds_result_stack_push (
377         struct acpi_walk_state          *walk_state)
378 {
379         union acpi_generic_state        *state;
380
381         ACPI_FUNCTION_NAME ("ds_result_stack_push");
382
383
384         state = acpi_ut_create_generic_state ();
385         if (!state) {
386                 return (AE_NO_MEMORY);
387         }
388
389         state->common.data_type = ACPI_DESC_TYPE_STATE_RESULT;
390         acpi_ut_push_generic_state (&walk_state->results, state);
391
392         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Results=%p State=%p\n",
393                 state, walk_state));
394
395         return (AE_OK);
396 }
397
398
399 /*******************************************************************************
400  *
401  * FUNCTION:    acpi_ds_result_stack_pop
402  *
403  * PARAMETERS:  walk_state          - Current Walk state
404  *
405  * RETURN:      Status
406  *
407  * DESCRIPTION: Pop an object off of the walk_state result stack.
408  *
409  ******************************************************************************/
410
411 acpi_status
412 acpi_ds_result_stack_pop (
413         struct acpi_walk_state          *walk_state)
414 {
415         union acpi_generic_state        *state;
416
417         ACPI_FUNCTION_NAME ("ds_result_stack_pop");
418
419
420         /* Check for stack underflow */
421
422         if (walk_state->results == NULL) {
423                 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Underflow - State=%p\n",
424                         walk_state));
425                 return (AE_AML_NO_OPERAND);
426         }
427
428         state = acpi_ut_pop_generic_state (&walk_state->results);
429
430         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
431                 "Result=%p remaining_results=%X State=%p\n",
432                 state, state->results.num_results, walk_state));
433
434         acpi_ut_delete_generic_state (state);
435
436         return (AE_OK);
437 }
438
439
440 /*******************************************************************************
441  *
442  * FUNCTION:    acpi_ds_obj_stack_delete_all
443  *
444  * PARAMETERS:  walk_state          - Current Walk state
445  *
446  * RETURN:      Status
447  *
448  * DESCRIPTION: Clear the object stack by deleting all objects that are on it.
449  *              Should be used with great care, if at all!
450  *
451  ******************************************************************************/
452 #ifdef ACPI_FUTURE_USAGE
453 acpi_status
454 acpi_ds_obj_stack_delete_all (
455         struct acpi_walk_state          *walk_state)
456 {
457         u32                             i;
458
459
460         ACPI_FUNCTION_TRACE_PTR ("ds_obj_stack_delete_all", walk_state);
461
462
463         /* The stack size is configurable, but fixed */
464
465         for (i = 0; i < ACPI_OBJ_NUM_OPERANDS; i++) {
466                 if (walk_state->operands[i]) {
467                         acpi_ut_remove_reference (walk_state->operands[i]);
468                         walk_state->operands[i] = NULL;
469                 }
470         }
471
472         return_ACPI_STATUS (AE_OK);
473 }
474 #endif  /*  ACPI_FUTURE_USAGE  */
475
476
477 /*******************************************************************************
478  *
479  * FUNCTION:    acpi_ds_obj_stack_push
480  *
481  * PARAMETERS:  Object              - Object to push
482  *              walk_state          - Current Walk state
483  *
484  * RETURN:      Status
485  *
486  * DESCRIPTION: Push an object onto this walk's object/operand stack
487  *
488  ******************************************************************************/
489
490 acpi_status
491 acpi_ds_obj_stack_push (
492         void                            *object,
493         struct acpi_walk_state          *walk_state)
494 {
495         ACPI_FUNCTION_NAME ("ds_obj_stack_push");
496
497
498         /* Check for stack overflow */
499
500         if (walk_state->num_operands >= ACPI_OBJ_NUM_OPERANDS) {
501                 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
502                         "overflow! Obj=%p State=%p #Ops=%X\n",
503                         object, walk_state, walk_state->num_operands));
504                 return (AE_STACK_OVERFLOW);
505         }
506
507         /* Put the object onto the stack */
508
509         walk_state->operands [walk_state->num_operands] = object;
510         walk_state->num_operands++;
511
512         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s] State=%p #Ops=%X\n",
513                           object, acpi_ut_get_object_type_name ((union acpi_operand_object *) object),
514                           walk_state, walk_state->num_operands));
515
516         return (AE_OK);
517 }
518
519
520 #if 0
521 /*******************************************************************************
522  *
523  * FUNCTION:    acpi_ds_obj_stack_pop_object
524  *
525  * PARAMETERS:  pop_count           - Number of objects/entries to pop
526  *              walk_state          - Current Walk state
527  *
528  * RETURN:      Status
529  *
530  * DESCRIPTION: Pop this walk's object stack.  Objects on the stack are NOT
531  *              deleted by this routine.
532  *
533  ******************************************************************************/
534
535 acpi_status
536 acpi_ds_obj_stack_pop_object (
537         union acpi_operand_object       **object,
538         struct acpi_walk_state          *walk_state)
539 {
540         ACPI_FUNCTION_NAME ("ds_obj_stack_pop_object");
541
542
543         /* Check for stack underflow */
544
545         if (walk_state->num_operands == 0) {
546                 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
547                         "Missing operand/stack empty! State=%p #Ops=%X\n",
548                         walk_state, walk_state->num_operands));
549                 *object = NULL;
550                 return (AE_AML_NO_OPERAND);
551         }
552
553         /* Pop the stack */
554
555         walk_state->num_operands--;
556
557         /* Check for a valid operand */
558
559         if (!walk_state->operands [walk_state->num_operands]) {
560                 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
561                         "Null operand! State=%p #Ops=%X\n",
562                         walk_state, walk_state->num_operands));
563                 *object = NULL;
564                 return (AE_AML_NO_OPERAND);
565         }
566
567         /* Get operand and set stack entry to null */
568
569         *object = walk_state->operands [walk_state->num_operands];
570         walk_state->operands [walk_state->num_operands] = NULL;
571
572         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s] State=%p #Ops=%X\n",
573                           *object, acpi_ut_get_object_type_name (*object),
574                           walk_state, walk_state->num_operands));
575
576         return (AE_OK);
577 }
578 #endif
579
580
581 /*******************************************************************************
582  *
583  * FUNCTION:    acpi_ds_obj_stack_pop
584  *
585  * PARAMETERS:  pop_count           - Number of objects/entries to pop
586  *              walk_state          - Current Walk state
587  *
588  * RETURN:      Status
589  *
590  * DESCRIPTION: Pop this walk's object stack.  Objects on the stack are NOT
591  *              deleted by this routine.
592  *
593  ******************************************************************************/
594
595 acpi_status
596 acpi_ds_obj_stack_pop (
597         u32                             pop_count,
598         struct acpi_walk_state          *walk_state)
599 {
600         u32                             i;
601
602         ACPI_FUNCTION_NAME ("ds_obj_stack_pop");
603
604
605         for (i = 0; i < pop_count; i++) {
606                 /* Check for stack underflow */
607
608                 if (walk_state->num_operands == 0) {
609                         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
610                                 "Underflow! Count=%X State=%p #Ops=%X\n",
611                                 pop_count, walk_state, walk_state->num_operands));
612                         return (AE_STACK_UNDERFLOW);
613                 }
614
615                 /* Just set the stack entry to null */
616
617                 walk_state->num_operands--;
618                 walk_state->operands [walk_state->num_operands] = NULL;
619         }
620
621         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Count=%X State=%p #Ops=%X\n",
622                           pop_count, walk_state, walk_state->num_operands));
623
624         return (AE_OK);
625 }
626
627
628 /*******************************************************************************
629  *
630  * FUNCTION:    acpi_ds_obj_stack_pop_and_delete
631  *
632  * PARAMETERS:  pop_count           - Number of objects/entries to pop
633  *              walk_state          - Current Walk state
634  *
635  * RETURN:      Status
636  *
637  * DESCRIPTION: Pop this walk's object stack and delete each object that is
638  *              popped off.
639  *
640  ******************************************************************************/
641
642 acpi_status
643 acpi_ds_obj_stack_pop_and_delete (
644         u32                             pop_count,
645         struct acpi_walk_state          *walk_state)
646 {
647         u32                             i;
648         union acpi_operand_object       *obj_desc;
649
650
651         ACPI_FUNCTION_NAME ("ds_obj_stack_pop_and_delete");
652
653
654         for (i = 0; i < pop_count; i++) {
655                 /* Check for stack underflow */
656
657                 if (walk_state->num_operands == 0) {
658                         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
659                                 "Underflow! Count=%X State=%p #Ops=%X\n",
660                                 pop_count, walk_state, walk_state->num_operands));
661                         return (AE_STACK_UNDERFLOW);
662                 }
663
664                 /* Pop the stack and delete an object if present in this stack entry */
665
666                 walk_state->num_operands--;
667                 obj_desc = walk_state->operands [walk_state->num_operands];
668                 if (obj_desc) {
669                         acpi_ut_remove_reference (walk_state->operands [walk_state->num_operands]);
670                         walk_state->operands [walk_state->num_operands] = NULL;
671                 }
672         }
673
674         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Count=%X State=%p #Ops=%X\n",
675                           pop_count, walk_state, walk_state->num_operands));
676
677         return (AE_OK);
678 }
679
680
681 /*******************************************************************************
682  *
683  * FUNCTION:    acpi_ds_obj_stack_get_value
684  *
685  * PARAMETERS:  Index               - Stack index whose value is desired.  Based
686  *                                    on the top of the stack (index=0 == top)
687  *              walk_state          - Current Walk state
688  *
689  * RETURN:      Status
690  *
691  * DESCRIPTION: Retrieve an object from this walk's object stack.  Index must
692  *              be within the range of the current stack pointer.
693  *
694  ******************************************************************************/
695 #ifdef ACPI_FUTURE_USAGE
696 void *
697 acpi_ds_obj_stack_get_value (
698         u32                             index,
699         struct acpi_walk_state          *walk_state)
700 {
701
702         ACPI_FUNCTION_TRACE_PTR ("ds_obj_stack_get_value", walk_state);
703
704
705         /* Can't do it if the stack is empty */
706
707         if (walk_state->num_operands == 0) {
708                 return_PTR (NULL);
709         }
710
711         /* or if the index is past the top of the stack */
712
713         if (index > (walk_state->num_operands - (u32) 1)) {
714                 return_PTR (NULL);
715         }
716
717         return_PTR (walk_state->operands[(acpi_native_uint)(walk_state->num_operands - 1) -
718                           index]);
719 }
720 #endif  /*  ACPI_FUTURE_USAGE  */
721
722
723 /*******************************************************************************
724  *
725  * FUNCTION:    acpi_ds_get_current_walk_state
726  *
727  * PARAMETERS:  Thread          - Get current active state for this Thread
728  *
729  * RETURN:      Pointer to the current walk state
730  *
731  * DESCRIPTION: Get the walk state that is at the head of the list (the "current"
732  *              walk state.)
733  *
734  ******************************************************************************/
735
736 struct acpi_walk_state *
737 acpi_ds_get_current_walk_state (
738         struct acpi_thread_state        *thread)
739
740 {
741         ACPI_FUNCTION_NAME ("ds_get_current_walk_state");
742
743
744         if (!thread) {
745                 return (NULL);
746         }
747
748         ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Current walk_state %p\n",
749                 thread->walk_state_list));
750
751         return (thread->walk_state_list);
752 }
753
754
755 /*******************************************************************************
756  *
757  * FUNCTION:    acpi_ds_push_walk_state
758  *
759  * PARAMETERS:  walk_state      - State to push
760  *              walk_list       - The list that owns the walk stack
761  *
762  * RETURN:      None
763  *
764  * DESCRIPTION: Place the walk_state at the head of the state list.
765  *
766  ******************************************************************************/
767
768 void
769 acpi_ds_push_walk_state (
770         struct acpi_walk_state          *walk_state,
771         struct acpi_thread_state        *thread)
772 {
773         ACPI_FUNCTION_TRACE ("ds_push_walk_state");
774
775
776         walk_state->next      = thread->walk_state_list;
777         thread->walk_state_list = walk_state;
778
779         return_VOID;
780 }
781
782
783 /*******************************************************************************
784  *
785  * FUNCTION:    acpi_ds_pop_walk_state
786  *
787  * PARAMETERS:  walk_list       - The list that owns the walk stack
788  *
789  * RETURN:      A walk_state object popped from the stack
790  *
791  * DESCRIPTION: Remove and return the walkstate object that is at the head of
792  *              the walk stack for the given walk list.  NULL indicates that
793  *              the list is empty.
794  *
795  ******************************************************************************/
796
797 struct acpi_walk_state *
798 acpi_ds_pop_walk_state (
799         struct acpi_thread_state        *thread)
800 {
801         struct acpi_walk_state          *walk_state;
802
803
804         ACPI_FUNCTION_TRACE ("ds_pop_walk_state");
805
806
807         walk_state = thread->walk_state_list;
808
809         if (walk_state) {
810                 /* Next walk state becomes the current walk state */
811
812                 thread->walk_state_list = walk_state->next;
813
814                 /*
815                  * Don't clear the NEXT field, this serves as an indicator
816                  * that there is a parent WALK STATE
817                  *     NO: walk_state->Next = NULL;
818                  */
819         }
820
821         return_PTR (walk_state);
822 }
823
824
825 /*******************************************************************************
826  *
827  * FUNCTION:    acpi_ds_create_walk_state
828  *
829  * PARAMETERS:  Origin          - Starting point for this walk
830  *              Thread          - Current thread state
831  *
832  * RETURN:      Pointer to the new walk state.
833  *
834  * DESCRIPTION: Allocate and initialize a new walk state.  The current walk
835  *              state is set to this new state.
836  *
837  ******************************************************************************/
838
839 struct acpi_walk_state *
840 acpi_ds_create_walk_state (
841         acpi_owner_id                   owner_id,
842         union acpi_parse_object         *origin,
843         union acpi_operand_object       *mth_desc,
844         struct acpi_thread_state        *thread)
845 {
846         struct acpi_walk_state          *walk_state;
847         acpi_status                     status;
848
849
850         ACPI_FUNCTION_TRACE ("ds_create_walk_state");
851
852
853         walk_state = acpi_ut_acquire_from_cache (ACPI_MEM_LIST_WALK);
854         if (!walk_state) {
855                 return_PTR (NULL);
856         }
857
858         walk_state->data_type       = ACPI_DESC_TYPE_WALK;
859         walk_state->owner_id        = owner_id;
860         walk_state->origin          = origin;
861         walk_state->method_desc     = mth_desc;
862         walk_state->thread          = thread;
863
864         walk_state->parser_state.start_op = origin;
865
866         /* Init the method args/local */
867
868 #if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY))
869         acpi_ds_method_data_init (walk_state);
870 #endif
871
872         /* Create an initial result stack entry */
873
874         status = acpi_ds_result_stack_push (walk_state);
875         if (ACPI_FAILURE (status)) {
876                 acpi_ut_release_to_cache (ACPI_MEM_LIST_WALK, walk_state);
877                 return_PTR (NULL);
878         }
879
880         /* Put the new state at the head of the walk list */
881
882         if (thread) {
883                 acpi_ds_push_walk_state (walk_state, thread);
884         }
885
886         return_PTR (walk_state);
887 }
888
889
890 /*******************************************************************************
891  *
892  * FUNCTION:    acpi_ds_init_aml_walk
893  *
894  * PARAMETERS:  walk_state      - New state to be initialized
895  *              Op              - Current parse op
896  *              method_node     - Control method NS node, if any
897  *              aml_start       - Start of AML
898  *              aml_length      - Length of AML
899  *              Params          - Method args, if any
900  *              return_obj_desc - Where to store a return object, if any
901  *              pass_number     - 1, 2, or 3
902  *
903  * RETURN:      Status
904  *
905  * DESCRIPTION: Initialize a walk state for a pass 1 or 2 parse tree walk
906  *
907  ******************************************************************************/
908
909 acpi_status
910 acpi_ds_init_aml_walk (
911         struct acpi_walk_state          *walk_state,
912         union acpi_parse_object         *op,
913         struct acpi_namespace_node      *method_node,
914         u8                              *aml_start,
915         u32                             aml_length,
916         struct acpi_parameter_info      *info,
917         u32                             pass_number)
918 {
919         acpi_status                     status;
920         struct acpi_parse_state         *parser_state = &walk_state->parser_state;
921         union acpi_parse_object         *extra_op;
922
923
924         ACPI_FUNCTION_TRACE ("ds_init_aml_walk");
925
926
927         walk_state->parser_state.aml    =
928         walk_state->parser_state.aml_start = aml_start;
929         walk_state->parser_state.aml_end =
930         walk_state->parser_state.pkg_end = aml_start + aml_length;
931
932         /* The next_op of the next_walk will be the beginning of the method */
933
934         walk_state->next_op             = NULL;
935
936         if (info) {
937                 if (info->parameter_type == ACPI_PARAM_GPE) {
938                         walk_state->gpe_event_info = ACPI_CAST_PTR (struct acpi_gpe_event_info,
939                                            info->parameters);
940                 }
941                 else {
942                         walk_state->params              = info->parameters;
943                         walk_state->caller_return_desc  = &info->return_object;
944                 }
945         }
946
947         status = acpi_ps_init_scope (&walk_state->parser_state, op);
948         if (ACPI_FAILURE (status)) {
949                 return_ACPI_STATUS (status);
950         }
951
952         if (method_node) {
953                 walk_state->parser_state.start_node = method_node;
954                 walk_state->walk_type            = ACPI_WALK_METHOD;
955                 walk_state->method_node          = method_node;
956                 walk_state->method_desc          = acpi_ns_get_attached_object (method_node);
957
958                 /* Push start scope on scope stack and make it current  */
959
960                 status = acpi_ds_scope_stack_push (method_node, ACPI_TYPE_METHOD, walk_state);
961                 if (ACPI_FAILURE (status)) {
962                         return_ACPI_STATUS (status);
963                 }
964
965                 /* Init the method arguments */
966
967                 status = acpi_ds_method_data_init_args (walk_state->params, ACPI_METHOD_NUM_ARGS, walk_state);
968                 if (ACPI_FAILURE (status)) {
969                         return_ACPI_STATUS (status);
970                 }
971         }
972         else {
973                 /*
974                  * Setup the current scope.
975                  * Find a Named Op that has a namespace node associated with it.
976                  * search upwards from this Op.  Current scope is the first
977                  * Op with a namespace node.
978                  */
979                 extra_op = parser_state->start_op;
980                 while (extra_op && !extra_op->common.node) {
981                         extra_op = extra_op->common.parent;
982                 }
983
984                 if (!extra_op) {
985                         parser_state->start_node = NULL;
986                 }
987                 else {
988                         parser_state->start_node = extra_op->common.node;
989                 }
990
991                 if (parser_state->start_node) {
992                         /* Push start scope on scope stack and make it current  */
993
994                         status = acpi_ds_scope_stack_push (parser_state->start_node,
995                                           parser_state->start_node->type, walk_state);
996                         if (ACPI_FAILURE (status)) {
997                                 return_ACPI_STATUS (status);
998                         }
999                 }
1000         }
1001
1002         status = acpi_ds_init_callbacks (walk_state, pass_number);
1003         return_ACPI_STATUS (status);
1004 }
1005
1006
1007 /*******************************************************************************
1008  *
1009  * FUNCTION:    acpi_ds_delete_walk_state
1010  *
1011  * PARAMETERS:  walk_state      - State to delete
1012  *
1013  * RETURN:      Status
1014  *
1015  * DESCRIPTION: Delete a walk state including all internal data structures
1016  *
1017  ******************************************************************************/
1018
1019 void
1020 acpi_ds_delete_walk_state (
1021         struct acpi_walk_state          *walk_state)
1022 {
1023         union acpi_generic_state        *state;
1024
1025
1026         ACPI_FUNCTION_TRACE_PTR ("ds_delete_walk_state", walk_state);
1027
1028
1029         if (!walk_state) {
1030                 return;
1031         }
1032
1033         if (walk_state->data_type != ACPI_DESC_TYPE_WALK) {
1034                 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%p is not a valid walk state\n", walk_state));
1035                 return;
1036         }
1037
1038         if (walk_state->parser_state.scope) {
1039                 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%p walk still has a scope list\n", walk_state));
1040         }
1041
1042         /* Always must free any linked control states */
1043
1044         while (walk_state->control_state) {
1045                 state = walk_state->control_state;
1046                 walk_state->control_state = state->common.next;
1047
1048                 acpi_ut_delete_generic_state (state);
1049         }
1050
1051         /* Always must free any linked parse states */
1052
1053         while (walk_state->scope_info) {
1054                 state = walk_state->scope_info;
1055                 walk_state->scope_info = state->common.next;
1056
1057                 acpi_ut_delete_generic_state (state);
1058         }
1059
1060         /* Always must free any stacked result states */
1061
1062         while (walk_state->results) {
1063                 state = walk_state->results;
1064                 walk_state->results = state->common.next;
1065
1066                 acpi_ut_delete_generic_state (state);
1067         }
1068
1069         acpi_ut_release_to_cache (ACPI_MEM_LIST_WALK, walk_state);
1070         return_VOID;
1071 }
1072
1073
1074 #ifdef ACPI_ENABLE_OBJECT_CACHE
1075 /******************************************************************************
1076  *
1077  * FUNCTION:    acpi_ds_delete_walk_state_cache
1078  *
1079  * PARAMETERS:  None
1080  *
1081  * RETURN:      Status
1082  *
1083  * DESCRIPTION: Purge the global state object cache.  Used during subsystem
1084  *              termination.
1085  *
1086  ******************************************************************************/
1087
1088 void
1089 acpi_ds_delete_walk_state_cache (
1090         void)
1091 {
1092         ACPI_FUNCTION_TRACE ("ds_delete_walk_state_cache");
1093
1094
1095         acpi_ut_delete_generic_cache (ACPI_MEM_LIST_WALK);
1096         return_VOID;
1097 }
1098 #endif
1099
1100