OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [acpi/] [parser/] [pswalk.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/******************************************************************************
2
 *
3
 * Module Name: pswalk - Parser routines to walk parsed op tree(s)
4
 *
5
 *****************************************************************************/
6
 
7
/*
8
 * Copyright (C) 2000 - 2004, 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
 
49
#define _COMPONENT          ACPI_PARSER
50
         ACPI_MODULE_NAME    ("pswalk")
51
 
52
 
53
/*******************************************************************************
54
 *
55
 * FUNCTION:    acpi_ps_get_next_walk_op
56
 *
57
 * PARAMETERS:  walk_state          - Current state of the walk
58
 *              Op                  - Current Op to be walked
59
 *              ascending_callback  - Procedure called when Op is complete
60
 *
61
 * RETURN:      Status
62
 *
63
 * DESCRIPTION: Get the next Op in a walk of the parse tree.
64
 *
65
 ******************************************************************************/
66
 
67
acpi_status
68
acpi_ps_get_next_walk_op (
69
        struct acpi_walk_state          *walk_state,
70
        union acpi_parse_object         *op,
71
        acpi_parse_upwards              ascending_callback)
72
{
73
        union acpi_parse_object         *next;
74
        union acpi_parse_object         *parent;
75
        union acpi_parse_object         *grand_parent;
76
        acpi_status                     status;
77
 
78
 
79
        ACPI_FUNCTION_TRACE_PTR ("ps_get_next_walk_op", op);
80
 
81
 
82
        /* Check for a argument only if we are descending in the tree */
83
 
84
        if (walk_state->next_op_info != ACPI_NEXT_OP_UPWARD) {
85
                /* Look for an argument or child of the current op */
86
 
87
                next = acpi_ps_get_arg (op, 0);
88
                if (next) {
89
                        /* Still going downward in tree (Op is not completed yet) */
90
 
91
                        walk_state->prev_op     = op;
92
                        walk_state->next_op     = next;
93
                        walk_state->next_op_info = ACPI_NEXT_OP_DOWNWARD;
94
 
95
                        return_ACPI_STATUS (AE_OK);
96
                }
97
 
98
                /*
99
                 * No more children, this Op is complete.  Save Next and Parent
100
                 * in case the Op object gets deleted by the callback routine
101
                 */
102
                next    = op->common.next;
103
                parent  = op->common.parent;
104
 
105
                walk_state->op    = op;
106
                walk_state->op_info = acpi_ps_get_opcode_info (op->common.aml_opcode);
107
                walk_state->opcode = op->common.aml_opcode;
108
 
109
                status = ascending_callback (walk_state);
110
 
111
                /*
112
                 * If we are back to the starting point, the walk is complete.
113
                 */
114
                if (op == walk_state->origin) {
115
                        /* Reached the point of origin, the walk is complete */
116
 
117
                        walk_state->prev_op     = op;
118
                        walk_state->next_op     = NULL;
119
 
120
                        return_ACPI_STATUS (status);
121
                }
122
 
123
                /*
124
                 * Check for a sibling to the current op.  A sibling means
125
                 * we are still going "downward" in the tree.
126
                 */
127
                if (next) {
128
                        /* There is a sibling, it will be next */
129
 
130
                        walk_state->prev_op     = op;
131
                        walk_state->next_op     = next;
132
                        walk_state->next_op_info = ACPI_NEXT_OP_DOWNWARD;
133
 
134
                        /* Continue downward */
135
 
136
                        return_ACPI_STATUS (status);
137
                }
138
 
139
                /*
140
                 * Drop into the loop below because we are moving upwards in
141
                 * the tree
142
                 */
143
        }
144
        else {
145
                /*
146
                 * We are resuming a walk, and we were (are) going upward in the tree.
147
                 * So, we want to drop into the parent loop below.
148
                 */
149
                parent = op;
150
        }
151
 
152
        /*
153
         * Look for a sibling of the current Op's parent
154
         * Continue moving up the tree until we find a node that has not been
155
         * visited, or we get back to where we started.
156
         */
157
        while (parent) {
158
                /* We are moving up the tree, therefore this parent Op is complete */
159
 
160
                grand_parent = parent->common.parent;
161
                next        = parent->common.next;
162
 
163
                walk_state->op    = parent;
164
                walk_state->op_info = acpi_ps_get_opcode_info (parent->common.aml_opcode);
165
                walk_state->opcode = parent->common.aml_opcode;
166
 
167
                status = ascending_callback (walk_state);
168
 
169
                /*
170
                 * If we are back to the starting point, the walk is complete.
171
                 */
172
                if (parent == walk_state->origin) {
173
                        /* Reached the point of origin, the walk is complete */
174
 
175
                        walk_state->prev_op     = parent;
176
                        walk_state->next_op     = NULL;
177
 
178
                        return_ACPI_STATUS (status);
179
                }
180
 
181
                /*
182
                 * If there is a sibling to this parent (it is not the starting point
183
                 * Op), then we will visit it.
184
                 */
185
                if (next) {
186
                        /* found sibling of parent */
187
 
188
                        walk_state->prev_op     = parent;
189
                        walk_state->next_op     = next;
190
                        walk_state->next_op_info = ACPI_NEXT_OP_DOWNWARD;
191
 
192
                        return_ACPI_STATUS (status);
193
                }
194
 
195
                /* No siblings, no errors, just move up one more level in the tree */
196
 
197
                op                  = parent;
198
                parent              = grand_parent;
199
                walk_state->prev_op = op;
200
        }
201
 
202
 
203
        /*
204
         * Got all the way to the top of the tree, we must be done!
205
         * However, the code should have terminated in the loop above
206
         */
207
        walk_state->next_op     = NULL;
208
 
209
        return_ACPI_STATUS (AE_OK);
210
}
211
 
212
 
213
/*******************************************************************************
214
 *
215
 * FUNCTION:    acpi_ps_delete_completed_op
216
 *
217
 * PARAMETERS:  State           - Walk state
218
 *              Op              - Completed op
219
 *
220
 * RETURN:      AE_OK
221
 *
222
 * DESCRIPTION: Callback function for acpi_ps_get_next_walk_op(). Used during
223
 *              acpi_ps_delete_parse tree to delete Op objects when all sub-objects
224
 *              have been visited (and deleted.)
225
 *
226
 ******************************************************************************/
227
 
228
acpi_status
229
acpi_ps_delete_completed_op (
230
        struct acpi_walk_state          *walk_state)
231
{
232
 
233
        acpi_ps_free_op (walk_state->op);
234
        return (AE_OK);
235
}
236
 
237
 
238
/*******************************************************************************
239
 *
240
 * FUNCTION:    acpi_ps_delete_parse_tree
241
 *
242
 * PARAMETERS:  subtree_root        - Root of tree (or subtree) to delete
243
 *
244
 * RETURN:      None
245
 *
246
 * DESCRIPTION: Delete a portion of or an entire parse tree.
247
 *
248
 ******************************************************************************/
249
 
250
void
251
acpi_ps_delete_parse_tree (
252
        union acpi_parse_object         *subtree_root)
253
{
254
        struct acpi_walk_state          *walk_state;
255
        struct acpi_thread_state        *thread;
256
        acpi_status                     status;
257
 
258
 
259
        ACPI_FUNCTION_TRACE_PTR ("ps_delete_parse_tree", subtree_root);
260
 
261
 
262
        if (!subtree_root) {
263
                return_VOID;
264
        }
265
 
266
        /* Create and initialize a new walk list */
267
 
268
        thread = acpi_ut_create_thread_state ();
269
        if (!thread) {
270
                return_VOID;
271
        }
272
 
273
        walk_state = acpi_ds_create_walk_state (0, NULL, NULL, thread);
274
        if (!walk_state) {
275
                return_VOID;
276
        }
277
 
278
        walk_state->parse_flags         = 0;
279
        walk_state->descending_callback = NULL;
280
        walk_state->ascending_callback  = NULL;
281
 
282
        walk_state->origin = subtree_root;
283
        walk_state->next_op = subtree_root;
284
 
285
        /* Head downward in the tree */
286
 
287
        walk_state->next_op_info = ACPI_NEXT_OP_DOWNWARD;
288
 
289
        /* Visit all nodes in the subtree */
290
 
291
        while (walk_state->next_op) {
292
                status = acpi_ps_get_next_walk_op (walk_state, walk_state->next_op,
293
                                 acpi_ps_delete_completed_op);
294
                if (ACPI_FAILURE (status)) {
295
                        break;
296
                }
297
        }
298
 
299
        /* We are done with this walk */
300
 
301
        acpi_ut_delete_generic_state (ACPI_CAST_PTR (union acpi_generic_state, thread));
302
        acpi_ds_delete_walk_state (walk_state);
303
 
304
        return_VOID;
305
}
306
 
307
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.