import of ftp.dlink.com/GPL/DSMG-600_reB/ppclinux.tar.gz
[linux-2.4.21-pre4.git] / drivers / acpi / parser / psutils.c
1 /******************************************************************************
2  *
3  * Module Name: psutils - Parser miscellaneous utilities (Parser only)
4  *              $Revision: 1.1.1.1 $
5  *
6  *****************************************************************************/
7
8 /*
9  *  Copyright (C) 2000, 2001 R. Byron Moore
10  *
11  *  This program is free software; you can redistribute it and/or modify
12  *  it under the terms of the GNU General Public License as published by
13  *  the Free Software Foundation; either version 2 of the License, or
14  *  (at your option) any later version.
15  *
16  *  This program is distributed in the hope that it will be useful,
17  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  *  GNU General Public License for more details.
20  *
21  *  You should have received a copy of the GNU General Public License
22  *  along with this program; if not, write to the Free Software
23  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24  */
25
26
27 #include "acpi.h"
28 #include "acparser.h"
29 #include "amlcode.h"
30
31 #define _COMPONENT          ACPI_PARSER
32          MODULE_NAME         ("psutils")
33
34
35 #define PARSEOP_GENERIC     0x01
36 #define PARSEOP_NAMED       0x02
37 #define PARSEOP_DEFERRED    0x04
38 #define PARSEOP_BYTELIST    0x08
39 #define PARSEOP_IN_CACHE    0x80
40
41
42 /*******************************************************************************
43  *
44  * FUNCTION:    Acpi_ps_init_op
45  *
46  * PARAMETERS:  Op              - A newly allocated Op object
47  *              Opcode          - Opcode to store in the Op
48  *
49  * RETURN:      Status
50  *
51  * DESCRIPTION: Allocate an acpi_op, choose op type (and thus size) based on
52  *              opcode
53  *
54  ******************************************************************************/
55
56 void
57 acpi_ps_init_op (
58         acpi_parse_object       *op,
59         u16                     opcode)
60 {
61         const acpi_opcode_info  *aml_op;
62
63
64         FUNCTION_ENTRY ();
65
66
67         op->data_type = ACPI_DESC_TYPE_PARSER;
68         op->opcode = opcode;
69
70         aml_op = acpi_ps_get_opcode_info (opcode);
71
72         DEBUG_ONLY_MEMBERS (STRNCPY (op->op_name, aml_op->name,
73                            sizeof (op->op_name)));
74 }
75
76
77 /*******************************************************************************
78  *
79  * FUNCTION:    Acpi_ps_alloc_op
80  *
81  * PARAMETERS:  Opcode          - Opcode that will be stored in the new Op
82  *
83  * RETURN:      Pointer to the new Op.
84  *
85  * DESCRIPTION: Allocate an acpi_op, choose op type (and thus size) based on
86  *              opcode.  A cache of opcodes is available for the pure
87  *              GENERIC_OP, since this is by far the most commonly used.
88  *
89  ******************************************************************************/
90
91 acpi_parse_object*
92 acpi_ps_alloc_op (
93         u16                     opcode)
94 {
95         acpi_parse_object       *op = NULL;
96         u32                     size;
97         u8                      flags;
98         const acpi_opcode_info  *op_info;
99
100
101         FUNCTION_ENTRY ();
102
103
104         op_info = acpi_ps_get_opcode_info (opcode);
105
106         /* Allocate the minimum required size object */
107
108         if (op_info->flags & AML_DEFER) {
109                 size = sizeof (acpi_parse2_object);
110                 flags = PARSEOP_DEFERRED;
111         }
112
113         else if (op_info->flags & AML_NAMED) {
114                 size = sizeof (acpi_parse2_object);
115                 flags = PARSEOP_NAMED;
116         }
117
118         else if (opcode == AML_INT_BYTELIST_OP) {
119                 size = sizeof (acpi_parse2_object);
120                 flags = PARSEOP_BYTELIST;
121         }
122
123         else {
124                 size = sizeof (acpi_parse_object);
125                 flags = PARSEOP_GENERIC;
126         }
127
128
129         if (size == sizeof (acpi_parse_object)) {
130                 /*
131                  * The generic op is by far the most common (16 to 1)
132                  */
133                 op = acpi_ut_acquire_from_cache (ACPI_MEM_LIST_PSNODE);
134         }
135
136         else {
137                 op = acpi_ut_acquire_from_cache (ACPI_MEM_LIST_PSNODE_EXT);
138         }
139
140         /* Initialize the Op */
141
142         if (op) {
143                 acpi_ps_init_op (op, opcode);
144                 op->flags = flags;
145         }
146
147         return (op);
148 }
149
150
151 /*******************************************************************************
152  *
153  * FUNCTION:    Acpi_ps_free_op
154  *
155  * PARAMETERS:  Op              - Op to be freed
156  *
157  * RETURN:      None.
158  *
159  * DESCRIPTION: Free an Op object.  Either put it on the GENERIC_OP cache list
160  *              or actually free it.
161  *
162  ******************************************************************************/
163
164 void
165 acpi_ps_free_op (
166         acpi_parse_object       *op)
167 {
168         PROC_NAME ("Ps_free_op");
169
170
171         if (op->opcode == AML_INT_RETURN_VALUE_OP) {
172                 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Free retval op: %p\n", op));
173         }
174
175         if (op->flags == PARSEOP_GENERIC) {
176                 acpi_ut_release_to_cache (ACPI_MEM_LIST_PSNODE, op);
177         }
178
179         else {
180                 acpi_ut_release_to_cache (ACPI_MEM_LIST_PSNODE_EXT, op);
181         }
182 }
183
184
185 /*******************************************************************************
186  *
187  * FUNCTION:    Acpi_ps_delete_parse_cache
188  *
189  * PARAMETERS:  None
190  *
191  * RETURN:      None
192  *
193  * DESCRIPTION: Free all objects that are on the parse cache list.
194  *
195  ******************************************************************************/
196
197 void
198 acpi_ps_delete_parse_cache (
199         void)
200 {
201         FUNCTION_TRACE ("Ps_delete_parse_cache");
202
203
204         acpi_ut_delete_generic_cache (ACPI_MEM_LIST_PSNODE);
205         acpi_ut_delete_generic_cache (ACPI_MEM_LIST_PSNODE_EXT);
206         return_VOID;
207 }
208
209
210 /*******************************************************************************
211  *
212  * FUNCTION:    Utility functions
213  *
214  * DESCRIPTION: Low level character and object functions
215  *
216  ******************************************************************************/
217
218
219 /*
220  * Is "c" a namestring lead character?
221  */
222 u8
223 acpi_ps_is_leading_char (
224         u32                     c)
225 {
226         return ((u8) (c == '_' || (c >= 'A' && c <= 'Z')));
227 }
228
229
230 /*
231  * Is "c" a namestring prefix character?
232  */
233 u8
234 acpi_ps_is_prefix_char (
235         u32                     c)
236 {
237         return ((u8) (c == '\\' || c == '^'));
238 }
239
240
241 /*
242  * Get op's name (4-byte name segment) or 0 if unnamed
243  */
244 u32
245 acpi_ps_get_name (
246         acpi_parse_object       *op)
247 {
248
249
250         /* The "generic" object has no name associated with it */
251
252         if (op->flags & PARSEOP_GENERIC) {
253                 return (0);
254         }
255
256         /* Only the "Extended" parse objects have a name */
257
258         return (((acpi_parse2_object *) op)->name);
259 }
260
261
262 /*
263  * Set op's name
264  */
265 void
266 acpi_ps_set_name (
267         acpi_parse_object       *op,
268         u32                     name)
269 {
270
271         /* The "generic" object has no name associated with it */
272
273         if (op->flags & PARSEOP_GENERIC) {
274                 return;
275         }
276
277         ((acpi_parse2_object *) op)->name = name;
278 }
279