aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/acpica
diff options
context:
space:
mode:
authorLen Brown <len.brown@intel.com>2009-01-09 00:13:17 -0500
committerLen Brown <len.brown@intel.com>2009-01-09 03:30:47 -0500
commit95b482a8d31116f3f5c2a5089569393234d06385 (patch)
treef32aec8673a285a9d188948be97af3034ee06e93 /drivers/acpi/acpica
parent6620e0c49f577454b772fb381543d60ae53eb885 (diff)
ACPICA: create acpica/ directory
also, delete sleep/ and delete ACPI_CFLAGS from Makefile Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/acpica')
-rw-r--r--drivers/acpi/acpica/Makefile44
-rw-r--r--drivers/acpi/acpica/dsfield.c650
-rw-r--r--drivers/acpi/acpica/dsinit.c205
-rw-r--r--drivers/acpi/acpica/dsmethod.c629
-rw-r--r--drivers/acpi/acpica/dsmthdat.c718
-rw-r--r--drivers/acpi/acpica/dsobject.c813
-rw-r--r--drivers/acpi/acpica/dsopcode.c1469
-rw-r--r--drivers/acpi/acpica/dsutils.c869
-rw-r--r--drivers/acpi/acpica/dswexec.c746
-rw-r--r--drivers/acpi/acpica/dswload.c1203
-rw-r--r--drivers/acpi/acpica/dswscope.c214
-rw-r--r--drivers/acpi/acpica/dswstate.c753
-rw-r--r--drivers/acpi/acpica/evevent.c313
-rw-r--r--drivers/acpi/acpica/evgpe.c722
-rw-r--r--drivers/acpi/acpica/evgpeblk.c1227
-rw-r--r--drivers/acpi/acpica/evmisc.c621
-rw-r--r--drivers/acpi/acpica/evregion.c1070
-rw-r--r--drivers/acpi/acpica/evrgnini.c684
-rw-r--r--drivers/acpi/acpica/evsci.c183
-rw-r--r--drivers/acpi/acpica/evxface.c821
-rw-r--r--drivers/acpi/acpica/evxfevnt.c871
-rw-r--r--drivers/acpi/acpica/evxfregn.c254
-rw-r--r--drivers/acpi/acpica/exconfig.c536
-rw-r--r--drivers/acpi/acpica/exconvrt.c692
-rw-r--r--drivers/acpi/acpica/excreate.c522
-rw-r--r--drivers/acpi/acpica/exdump.c1060
-rw-r--r--drivers/acpi/acpica/exfield.c340
-rw-r--r--drivers/acpi/acpica/exfldio.c961
-rw-r--r--drivers/acpi/acpica/exmisc.c726
-rw-r--r--drivers/acpi/acpica/exmutex.c474
-rw-r--r--drivers/acpi/acpica/exnames.c436
-rw-r--r--drivers/acpi/acpica/exoparg1.c1050
-rw-r--r--drivers/acpi/acpica/exoparg2.c605
-rw-r--r--drivers/acpi/acpica/exoparg3.c273
-rw-r--r--drivers/acpi/acpica/exoparg6.c341
-rw-r--r--drivers/acpi/acpica/exprep.c590
-rw-r--r--drivers/acpi/acpica/exregion.c499
-rw-r--r--drivers/acpi/acpica/exresnte.c278
-rw-r--r--drivers/acpi/acpica/exresolv.c551
-rw-r--r--drivers/acpi/acpica/exresop.c701
-rw-r--r--drivers/acpi/acpica/exstore.c716
-rw-r--r--drivers/acpi/acpica/exstoren.c304
-rw-r--r--drivers/acpi/acpica/exstorob.c209
-rw-r--r--drivers/acpi/acpica/exsystem.c303
-rw-r--r--drivers/acpi/acpica/exutils.c421
-rw-r--r--drivers/acpi/acpica/hwacpi.c185
-rw-r--r--drivers/acpi/acpica/hwgpe.c469
-rw-r--r--drivers/acpi/acpica/hwregs.c353
-rw-r--r--drivers/acpi/acpica/hwsleep.c629
-rw-r--r--drivers/acpi/acpica/hwtimer.c188
-rw-r--r--drivers/acpi/acpica/hwxface.c593
-rw-r--r--drivers/acpi/acpica/nsaccess.c676
-rw-r--r--drivers/acpi/acpica/nsalloc.c497
-rw-r--r--drivers/acpi/acpica/nsdump.c709
-rw-r--r--drivers/acpi/acpica/nsdumpdv.c141
-rw-r--r--drivers/acpi/acpica/nseval.c278
-rw-r--r--drivers/acpi/acpica/nsinit.c593
-rw-r--r--drivers/acpi/acpica/nsload.c315
-rw-r--r--drivers/acpi/acpica/nsnames.c265
-rw-r--r--drivers/acpi/acpica/nsobject.c441
-rw-r--r--drivers/acpi/acpica/nsparse.c204
-rw-r--r--drivers/acpi/acpica/nspredef.c1065
-rw-r--r--drivers/acpi/acpica/nssearch.c415
-rw-r--r--drivers/acpi/acpica/nsutils.c997
-rw-r--r--drivers/acpi/acpica/nswalk.c296
-rw-r--r--drivers/acpi/acpica/nsxfeval.c812
-rw-r--r--drivers/acpi/acpica/nsxfname.c360
-rw-r--r--drivers/acpi/acpica/nsxfobj.c287
-rw-r--r--drivers/acpi/acpica/psargs.c752
-rw-r--r--drivers/acpi/acpica/psloop.c1088
-rw-r--r--drivers/acpi/acpica/psopcode.c810
-rw-r--r--drivers/acpi/acpica/psparse.c701
-rw-r--r--drivers/acpi/acpica/psscope.c265
-rw-r--r--drivers/acpi/acpica/pstree.c312
-rw-r--r--drivers/acpi/acpica/psutils.c244
-rw-r--r--drivers/acpi/acpica/pswalk.c110
-rw-r--r--drivers/acpi/acpica/psxface.c385
-rw-r--r--drivers/acpi/acpica/rsaddr.c381
-rw-r--r--drivers/acpi/acpica/rscalc.c618
-rw-r--r--drivers/acpi/acpica/rscreate.c468
-rw-r--r--drivers/acpi/acpica/rsdump.c771
-rw-r--r--drivers/acpi/acpica/rsinfo.c206
-rw-r--r--drivers/acpi/acpica/rsio.c290
-rw-r--r--drivers/acpi/acpica/rsirq.c266
-rw-r--r--drivers/acpi/acpica/rslist.c203
-rw-r--r--drivers/acpi/acpica/rsmemory.c236
-rw-r--r--drivers/acpi/acpica/rsmisc.c561
-rw-r--r--drivers/acpi/acpica/rsutils.c727
-rw-r--r--drivers/acpi/acpica/rsxface.c571
-rw-r--r--drivers/acpi/acpica/tbfadt.c610
-rw-r--r--drivers/acpi/acpica/tbfind.c140
-rw-r--r--drivers/acpi/acpica/tbinstal.c574
-rw-r--r--drivers/acpi/acpica/tbutils.c582
-rw-r--r--drivers/acpi/acpica/tbxface.c735
-rw-r--r--drivers/acpi/acpica/tbxfroot.c274
-rw-r--r--drivers/acpi/acpica/utalloc.c383
-rw-r--r--drivers/acpi/acpica/utcopy.c970
-rw-r--r--drivers/acpi/acpica/utdebug.c651
-rw-r--r--drivers/acpi/acpica/utdelete.c677
-rw-r--r--drivers/acpi/acpica/uteval.c752
-rw-r--r--drivers/acpi/acpica/utglobal.c823
-rw-r--r--drivers/acpi/acpica/utinit.c152
-rw-r--r--drivers/acpi/acpica/utmath.c312
-rw-r--r--drivers/acpi/acpica/utmisc.c1093
-rw-r--r--drivers/acpi/acpica/utmutex.c342
-rw-r--r--drivers/acpi/acpica/utobject.c677
-rw-r--r--drivers/acpi/acpica/utresrc.c616
-rw-r--r--drivers/acpi/acpica/utstate.c347
-rw-r--r--drivers/acpi/acpica/utxface.c512
109 files changed, 59622 insertions, 0 deletions
diff --git a/drivers/acpi/acpica/Makefile b/drivers/acpi/acpica/Makefile
new file mode 100644
index 00000000000..3f23298ee3f
--- /dev/null
+++ b/drivers/acpi/acpica/Makefile
@@ -0,0 +1,44 @@
1#
2# Makefile for ACPICA Core interpreter
3#
4
5ccflags-y := -Os
6ccflags-$(CONFIG_ACPI_DEBUG) += -DACPI_DEBUG_OUTPUT
7
8obj-y := dsfield.o dsmthdat.o dsopcode.o dswexec.o dswscope.o \
9 dsmethod.o dsobject.o dsutils.o dswload.o dswstate.o \
10 dsinit.o
11
12obj-y += evevent.o evregion.o evsci.o evxfevnt.o \
13 evmisc.o evrgnini.o evxface.o evxfregn.o \
14 evgpe.o evgpeblk.o
15
16obj-y += exconfig.o exfield.o exnames.o exoparg6.o exresolv.o exstorob.o\
17 exconvrt.o exfldio.o exoparg1.o exprep.o exresop.o exsystem.o\
18 excreate.o exmisc.o exoparg2.o exregion.o exstore.o exutils.o \
19 exdump.o exmutex.o exoparg3.o exresnte.o exstoren.o
20
21obj-y += hwacpi.o hwgpe.o hwregs.o hwsleep.o hwxface.o
22
23obj-$(ACPI_FUTURE_USAGE) += hwtimer.o
24
25obj-y += nsaccess.o nsload.o nssearch.o nsxfeval.o \
26 nsalloc.o nseval.o nsnames.o nsutils.o nsxfname.o \
27 nsdump.o nsinit.o nsobject.o nswalk.o nsxfobj.o \
28 nsparse.o nspredef.o
29
30obj-$(ACPI_FUTURE_USAGE) += nsdumpdv.o
31
32obj-y += psargs.o psparse.o psloop.o pstree.o pswalk.o \
33 psopcode.o psscope.o psutils.o psxface.o
34
35obj-y += rsaddr.o rscreate.o rsinfo.o rsio.o rslist.o rsmisc.o rsxface.o \
36 rscalc.o rsirq.o rsmemory.o rsutils.o
37
38obj-$(ACPI_FUTURE_USAGE) += rsdump.o
39
40obj-y += tbxface.o tbinstal.o tbutils.o tbfind.o tbfadt.o tbxfroot.o
41
42obj-y += utalloc.o utdebug.o uteval.o utinit.o utmisc.o utxface.o \
43 utcopy.o utdelete.o utglobal.o utmath.o utobject.o \
44 utstate.o utmutex.o utobject.o utresrc.o
diff --git a/drivers/acpi/acpica/dsfield.c b/drivers/acpi/acpica/dsfield.c
new file mode 100644
index 00000000000..5fbc24075b4
--- /dev/null
+++ b/drivers/acpi/acpica/dsfield.c
@@ -0,0 +1,650 @@
1/******************************************************************************
2 *
3 * Module Name: dsfield - Dispatcher field routines
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46#include <acpi/amlcode.h>
47#include <acpi/acdispat.h>
48#include <acpi/acinterp.h>
49#include <acpi/acnamesp.h>
50#include <acpi/acparser.h>
51
52#define _COMPONENT ACPI_DISPATCHER
53ACPI_MODULE_NAME("dsfield")
54
55/* Local prototypes */
56static acpi_status
57acpi_ds_get_field_names(struct acpi_create_field_info *info,
58 struct acpi_walk_state *walk_state,
59 union acpi_parse_object *arg);
60
61/*******************************************************************************
62 *
63 * FUNCTION: acpi_ds_create_buffer_field
64 *
65 * PARAMETERS: Op - Current parse op (create_xXField)
66 * walk_state - Current state
67 *
68 * RETURN: Status
69 *
70 * DESCRIPTION: Execute the create_field operators:
71 * create_bit_field_op,
72 * create_byte_field_op,
73 * create_word_field_op,
74 * create_dword_field_op,
75 * create_qword_field_op,
76 * create_field_op (all of which define a field in a buffer)
77 *
78 ******************************************************************************/
79
80acpi_status
81acpi_ds_create_buffer_field(union acpi_parse_object *op,
82 struct acpi_walk_state *walk_state)
83{
84 union acpi_parse_object *arg;
85 struct acpi_namespace_node *node;
86 acpi_status status;
87 union acpi_operand_object *obj_desc;
88 union acpi_operand_object *second_desc = NULL;
89 u32 flags;
90
91 ACPI_FUNCTION_TRACE(ds_create_buffer_field);
92
93 /*
94 * Get the name_string argument (name of the new buffer_field)
95 */
96 if (op->common.aml_opcode == AML_CREATE_FIELD_OP) {
97
98 /* For create_field, name is the 4th argument */
99
100 arg = acpi_ps_get_arg(op, 3);
101 } else {
102 /* For all other create_xXXField operators, name is the 3rd argument */
103
104 arg = acpi_ps_get_arg(op, 2);
105 }
106
107 if (!arg) {
108 return_ACPI_STATUS(AE_AML_NO_OPERAND);
109 }
110
111 if (walk_state->deferred_node) {
112 node = walk_state->deferred_node;
113 status = AE_OK;
114 } else {
115 /* Execute flag should always be set when this function is entered */
116
117 if (!(walk_state->parse_flags & ACPI_PARSE_EXECUTE)) {
118 return_ACPI_STATUS(AE_AML_INTERNAL);
119 }
120
121 /* Creating new namespace node, should not already exist */
122
123 flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
124 ACPI_NS_ERROR_IF_FOUND;
125
126 /* Mark node temporary if we are executing a method */
127
128 if (walk_state->method_node) {
129 flags |= ACPI_NS_TEMPORARY;
130 }
131
132 /* Enter the name_string into the namespace */
133
134 status =
135 acpi_ns_lookup(walk_state->scope_info,
136 arg->common.value.string, ACPI_TYPE_ANY,
137 ACPI_IMODE_LOAD_PASS1, flags, walk_state,
138 &node);
139 if (ACPI_FAILURE(status)) {
140 ACPI_ERROR_NAMESPACE(arg->common.value.string, status);
141 return_ACPI_STATUS(status);
142 }
143 }
144
145 /*
146 * We could put the returned object (Node) on the object stack for later,
147 * but for now, we will put it in the "op" object that the parser uses,
148 * so we can get it again at the end of this scope.
149 */
150 op->common.node = node;
151
152 /*
153 * If there is no object attached to the node, this node was just created
154 * and we need to create the field object. Otherwise, this was a lookup
155 * of an existing node and we don't want to create the field object again.
156 */
157 obj_desc = acpi_ns_get_attached_object(node);
158 if (obj_desc) {
159 return_ACPI_STATUS(AE_OK);
160 }
161
162 /*
163 * The Field definition is not fully parsed at this time.
164 * (We must save the address of the AML for the buffer and index operands)
165 */
166
167 /* Create the buffer field object */
168
169 obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_BUFFER_FIELD);
170 if (!obj_desc) {
171 status = AE_NO_MEMORY;
172 goto cleanup;
173 }
174
175 /*
176 * Remember location in AML stream of the field unit opcode and operands --
177 * since the buffer and index operands must be evaluated.
178 */
179 second_desc = obj_desc->common.next_object;
180 second_desc->extra.aml_start = op->named.data;
181 second_desc->extra.aml_length = op->named.length;
182 obj_desc->buffer_field.node = node;
183
184 /* Attach constructed field descriptors to parent node */
185
186 status = acpi_ns_attach_object(node, obj_desc, ACPI_TYPE_BUFFER_FIELD);
187 if (ACPI_FAILURE(status)) {
188 goto cleanup;
189 }
190
191 cleanup:
192
193 /* Remove local reference to the object */
194
195 acpi_ut_remove_reference(obj_desc);
196 return_ACPI_STATUS(status);
197}
198
199/*******************************************************************************
200 *
201 * FUNCTION: acpi_ds_get_field_names
202 *
203 * PARAMETERS: Info - create_field info structure
204 * ` walk_state - Current method state
205 * Arg - First parser arg for the field name list
206 *
207 * RETURN: Status
208 *
209 * DESCRIPTION: Process all named fields in a field declaration. Names are
210 * entered into the namespace.
211 *
212 ******************************************************************************/
213
214static acpi_status
215acpi_ds_get_field_names(struct acpi_create_field_info *info,
216 struct acpi_walk_state *walk_state,
217 union acpi_parse_object *arg)
218{
219 acpi_status status;
220 acpi_integer position;
221
222 ACPI_FUNCTION_TRACE_PTR(ds_get_field_names, info);
223
224 /* First field starts at bit zero */
225
226 info->field_bit_position = 0;
227
228 /* Process all elements in the field list (of parse nodes) */
229
230 while (arg) {
231 /*
232 * Three types of field elements are handled:
233 * 1) Offset - specifies a bit offset
234 * 2) access_as - changes the access mode
235 * 3) Name - Enters a new named field into the namespace
236 */
237 switch (arg->common.aml_opcode) {
238 case AML_INT_RESERVEDFIELD_OP:
239
240 position = (acpi_integer) info->field_bit_position
241 + (acpi_integer) arg->common.value.size;
242
243 if (position > ACPI_UINT32_MAX) {
244 ACPI_ERROR((AE_INFO,
245 "Bit offset within field too large (> 0xFFFFFFFF)"));
246 return_ACPI_STATUS(AE_SUPPORT);
247 }
248
249 info->field_bit_position = (u32) position;
250 break;
251
252 case AML_INT_ACCESSFIELD_OP:
253
254 /*
255 * Get a new access_type and access_attribute -- to be used for all
256 * field units that follow, until field end or another access_as
257 * keyword.
258 *
259 * In field_flags, preserve the flag bits other than the
260 * ACCESS_TYPE bits
261 */
262 info->field_flags = (u8)
263 ((info->
264 field_flags & ~(AML_FIELD_ACCESS_TYPE_MASK)) |
265 ((u8) ((u32) arg->common.value.integer >> 8)));
266
267 info->attribute = (u8) (arg->common.value.integer);
268 break;
269
270 case AML_INT_NAMEDFIELD_OP:
271
272 /* Lookup the name, it should already exist */
273
274 status = acpi_ns_lookup(walk_state->scope_info,
275 (char *)&arg->named.name,
276 info->field_type,
277 ACPI_IMODE_EXECUTE,
278 ACPI_NS_DONT_OPEN_SCOPE,
279 walk_state, &info->field_node);
280 if (ACPI_FAILURE(status)) {
281 ACPI_ERROR_NAMESPACE((char *)&arg->named.name,
282 status);
283 return_ACPI_STATUS(status);
284 } else {
285 arg->common.node = info->field_node;
286 info->field_bit_length = arg->common.value.size;
287
288 /*
289 * If there is no object attached to the node, this node was
290 * just created and we need to create the field object.
291 * Otherwise, this was a lookup of an existing node and we
292 * don't want to create the field object again.
293 */
294 if (!acpi_ns_get_attached_object
295 (info->field_node)) {
296 status = acpi_ex_prep_field_value(info);
297 if (ACPI_FAILURE(status)) {
298 return_ACPI_STATUS(status);
299 }
300 }
301 }
302
303 /* Keep track of bit position for the next field */
304
305 position = (acpi_integer) info->field_bit_position
306 + (acpi_integer) arg->common.value.size;
307
308 if (position > ACPI_UINT32_MAX) {
309 ACPI_ERROR((AE_INFO,
310 "Field [%4.4s] bit offset too large (> 0xFFFFFFFF)",
311 ACPI_CAST_PTR(char,
312 &info->field_node->
313 name)));
314 return_ACPI_STATUS(AE_SUPPORT);
315 }
316
317 info->field_bit_position += info->field_bit_length;
318 break;
319
320 default:
321
322 ACPI_ERROR((AE_INFO,
323 "Invalid opcode in field list: %X",
324 arg->common.aml_opcode));
325 return_ACPI_STATUS(AE_AML_BAD_OPCODE);
326 }
327
328 arg = arg->common.next;
329 }
330
331 return_ACPI_STATUS(AE_OK);
332}
333
334/*******************************************************************************
335 *
336 * FUNCTION: acpi_ds_create_field
337 *
338 * PARAMETERS: Op - Op containing the Field definition and args
339 * region_node - Object for the containing Operation Region
340 * ` walk_state - Current method state
341 *
342 * RETURN: Status
343 *
344 * DESCRIPTION: Create a new field in the specified operation region
345 *
346 ******************************************************************************/
347
348acpi_status
349acpi_ds_create_field(union acpi_parse_object *op,
350 struct acpi_namespace_node *region_node,
351 struct acpi_walk_state *walk_state)
352{
353 acpi_status status;
354 union acpi_parse_object *arg;
355 struct acpi_create_field_info info;
356
357 ACPI_FUNCTION_TRACE_PTR(ds_create_field, op);
358
359 /* First arg is the name of the parent op_region (must already exist) */
360
361 arg = op->common.value.arg;
362 if (!region_node) {
363 status =
364 acpi_ns_lookup(walk_state->scope_info,
365 arg->common.value.name, ACPI_TYPE_REGION,
366 ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
367 walk_state, &region_node);
368 if (ACPI_FAILURE(status)) {
369 ACPI_ERROR_NAMESPACE(arg->common.value.name, status);
370 return_ACPI_STATUS(status);
371 }
372 }
373
374 /* Second arg is the field flags */
375
376 arg = arg->common.next;
377 info.field_flags = (u8) arg->common.value.integer;
378 info.attribute = 0;
379
380 /* Each remaining arg is a Named Field */
381
382 info.field_type = ACPI_TYPE_LOCAL_REGION_FIELD;
383 info.region_node = region_node;
384
385 status = acpi_ds_get_field_names(&info, walk_state, arg->common.next);
386
387 return_ACPI_STATUS(status);
388}
389
390/*******************************************************************************
391 *
392 * FUNCTION: acpi_ds_init_field_objects
393 *
394 * PARAMETERS: Op - Op containing the Field definition and args
395 * ` walk_state - Current method state
396 *
397 * RETURN: Status
398 *
399 * DESCRIPTION: For each "Field Unit" name in the argument list that is
400 * part of the field declaration, enter the name into the
401 * namespace.
402 *
403 ******************************************************************************/
404
405acpi_status
406acpi_ds_init_field_objects(union acpi_parse_object *op,
407 struct acpi_walk_state *walk_state)
408{
409 acpi_status status;
410 union acpi_parse_object *arg = NULL;
411 struct acpi_namespace_node *node;
412 u8 type = 0;
413 u32 flags;
414
415 ACPI_FUNCTION_TRACE_PTR(ds_init_field_objects, op);
416
417 /* Execute flag should always be set when this function is entered */
418
419 if (!(walk_state->parse_flags & ACPI_PARSE_EXECUTE)) {
420 if (walk_state->parse_flags & ACPI_PARSE_DEFERRED_OP) {
421
422 /* bank_field Op is deferred, just return OK */
423
424 return_ACPI_STATUS(AE_OK);
425 }
426
427 return_ACPI_STATUS(AE_AML_INTERNAL);
428 }
429
430 /*
431 * Get the field_list argument for this opcode. This is the start of the
432 * list of field elements.
433 */
434 switch (walk_state->opcode) {
435 case AML_FIELD_OP:
436 arg = acpi_ps_get_arg(op, 2);
437 type = ACPI_TYPE_LOCAL_REGION_FIELD;
438 break;
439
440 case AML_BANK_FIELD_OP:
441 arg = acpi_ps_get_arg(op, 4);
442 type = ACPI_TYPE_LOCAL_BANK_FIELD;
443 break;
444
445 case AML_INDEX_FIELD_OP:
446 arg = acpi_ps_get_arg(op, 3);
447 type = ACPI_TYPE_LOCAL_INDEX_FIELD;
448 break;
449
450 default:
451 return_ACPI_STATUS(AE_BAD_PARAMETER);
452 }
453
454 /* Creating new namespace node(s), should not already exist */
455
456 flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
457 ACPI_NS_ERROR_IF_FOUND;
458
459 /* Mark node(s) temporary if we are executing a method */
460
461 if (walk_state->method_node) {
462 flags |= ACPI_NS_TEMPORARY;
463 }
464
465 /*
466 * Walk the list of entries in the field_list
467 * Note: field_list can be of zero length. In this case, Arg will be NULL.
468 */
469 while (arg) {
470 /*
471 * Ignore OFFSET and ACCESSAS terms here; we are only interested in the
472 * field names in order to enter them into the namespace.
473 */
474 if (arg->common.aml_opcode == AML_INT_NAMEDFIELD_OP) {
475 status = acpi_ns_lookup(walk_state->scope_info,
476 (char *)&arg->named.name, type,
477 ACPI_IMODE_LOAD_PASS1, flags,
478 walk_state, &node);
479 if (ACPI_FAILURE(status)) {
480 ACPI_ERROR_NAMESPACE((char *)&arg->named.name,
481 status);
482 if (status != AE_ALREADY_EXISTS) {
483 return_ACPI_STATUS(status);
484 }
485
486 /* Name already exists, just ignore this error */
487
488 status = AE_OK;
489 }
490
491 arg->common.node = node;
492 }
493
494 /* Get the next field element in the list */
495
496 arg = arg->common.next;
497 }
498
499 return_ACPI_STATUS(AE_OK);
500}
501
502/*******************************************************************************
503 *
504 * FUNCTION: acpi_ds_create_bank_field
505 *
506 * PARAMETERS: Op - Op containing the Field definition and args
507 * region_node - Object for the containing Operation Region
508 * walk_state - Current method state
509 *
510 * RETURN: Status
511 *
512 * DESCRIPTION: Create a new bank field in the specified operation region
513 *
514 ******************************************************************************/
515
516acpi_status
517acpi_ds_create_bank_field(union acpi_parse_object *op,
518 struct acpi_namespace_node *region_node,
519 struct acpi_walk_state *walk_state)
520{
521 acpi_status status;
522 union acpi_parse_object *arg;
523 struct acpi_create_field_info info;
524
525 ACPI_FUNCTION_TRACE_PTR(ds_create_bank_field, op);
526
527 /* First arg is the name of the parent op_region (must already exist) */
528
529 arg = op->common.value.arg;
530 if (!region_node) {
531 status =
532 acpi_ns_lookup(walk_state->scope_info,
533 arg->common.value.name, ACPI_TYPE_REGION,
534 ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
535 walk_state, &region_node);
536 if (ACPI_FAILURE(status)) {
537 ACPI_ERROR_NAMESPACE(arg->common.value.name, status);
538 return_ACPI_STATUS(status);
539 }
540 }
541
542 /* Second arg is the Bank Register (Field) (must already exist) */
543
544 arg = arg->common.next;
545 status =
546 acpi_ns_lookup(walk_state->scope_info, arg->common.value.string,
547 ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
548 ACPI_NS_SEARCH_PARENT, walk_state,
549 &info.register_node);
550 if (ACPI_FAILURE(status)) {
551 ACPI_ERROR_NAMESPACE(arg->common.value.string, status);
552 return_ACPI_STATUS(status);
553 }
554
555 /*
556 * Third arg is the bank_value
557 * This arg is a term_arg, not a constant
558 * It will be evaluated later, by acpi_ds_eval_bank_field_operands
559 */
560 arg = arg->common.next;
561
562 /* Fourth arg is the field flags */
563
564 arg = arg->common.next;
565 info.field_flags = (u8) arg->common.value.integer;
566
567 /* Each remaining arg is a Named Field */
568
569 info.field_type = ACPI_TYPE_LOCAL_BANK_FIELD;
570 info.region_node = region_node;
571
572 /*
573 * Use Info.data_register_node to store bank_field Op
574 * It's safe because data_register_node will never be used when create bank field
575 * We store aml_start and aml_length in the bank_field Op for late evaluation
576 * Used in acpi_ex_prep_field_value(Info)
577 *
578 * TBD: Or, should we add a field in struct acpi_create_field_info, like "void *ParentOp"?
579 */
580 info.data_register_node = (struct acpi_namespace_node *)op;
581
582 status = acpi_ds_get_field_names(&info, walk_state, arg->common.next);
583 return_ACPI_STATUS(status);
584}
585
586/*******************************************************************************
587 *
588 * FUNCTION: acpi_ds_create_index_field
589 *
590 * PARAMETERS: Op - Op containing the Field definition and args
591 * region_node - Object for the containing Operation Region
592 * ` walk_state - Current method state
593 *
594 * RETURN: Status
595 *
596 * DESCRIPTION: Create a new index field in the specified operation region
597 *
598 ******************************************************************************/
599
600acpi_status
601acpi_ds_create_index_field(union acpi_parse_object *op,
602 struct acpi_namespace_node *region_node,
603 struct acpi_walk_state *walk_state)
604{
605 acpi_status status;
606 union acpi_parse_object *arg;
607 struct acpi_create_field_info info;
608
609 ACPI_FUNCTION_TRACE_PTR(ds_create_index_field, op);
610
611 /* First arg is the name of the Index register (must already exist) */
612
613 arg = op->common.value.arg;
614 status =
615 acpi_ns_lookup(walk_state->scope_info, arg->common.value.string,
616 ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
617 ACPI_NS_SEARCH_PARENT, walk_state,
618 &info.register_node);
619 if (ACPI_FAILURE(status)) {
620 ACPI_ERROR_NAMESPACE(arg->common.value.string, status);
621 return_ACPI_STATUS(status);
622 }
623
624 /* Second arg is the data register (must already exist) */
625
626 arg = arg->common.next;
627 status =
628 acpi_ns_lookup(walk_state->scope_info, arg->common.value.string,
629 ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
630 ACPI_NS_SEARCH_PARENT, walk_state,
631 &info.data_register_node);
632 if (ACPI_FAILURE(status)) {
633 ACPI_ERROR_NAMESPACE(arg->common.value.string, status);
634 return_ACPI_STATUS(status);
635 }
636
637 /* Next arg is the field flags */
638
639 arg = arg->common.next;
640 info.field_flags = (u8) arg->common.value.integer;
641
642 /* Each remaining arg is a Named Field */
643
644 info.field_type = ACPI_TYPE_LOCAL_INDEX_FIELD;
645 info.region_node = region_node;
646
647 status = acpi_ds_get_field_names(&info, walk_state, arg->common.next);
648
649 return_ACPI_STATUS(status);
650}
diff --git a/drivers/acpi/acpica/dsinit.c b/drivers/acpi/acpica/dsinit.c
new file mode 100644
index 00000000000..4f1cdd823fc
--- /dev/null
+++ b/drivers/acpi/acpica/dsinit.c
@@ -0,0 +1,205 @@
1/******************************************************************************
2 *
3 * Module Name: dsinit - Object initialization namespace walk
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46#include <acpi/acdispat.h>
47#include <acpi/acnamesp.h>
48#include <acpi/actables.h>
49
50#define _COMPONENT ACPI_DISPATCHER
51ACPI_MODULE_NAME("dsinit")
52
53/* Local prototypes */
54static acpi_status
55acpi_ds_init_one_object(acpi_handle obj_handle,
56 u32 level, void *context, void **return_value);
57
58/*******************************************************************************
59 *
60 * FUNCTION: acpi_ds_init_one_object
61 *
62 * PARAMETERS: obj_handle - Node for the object
63 * Level - Current nesting level
64 * Context - Points to a init info struct
65 * return_value - Not used
66 *
67 * RETURN: Status
68 *
69 * DESCRIPTION: Callback from acpi_walk_namespace. Invoked for every object
70 * within the namespace.
71 *
72 * Currently, the only objects that require initialization are:
73 * 1) Methods
74 * 2) Operation Regions
75 *
76 ******************************************************************************/
77
78static acpi_status
79acpi_ds_init_one_object(acpi_handle obj_handle,
80 u32 level, void *context, void **return_value)
81{
82 struct acpi_init_walk_info *info =
83 (struct acpi_init_walk_info *)context;
84 struct acpi_namespace_node *node =
85 (struct acpi_namespace_node *)obj_handle;
86 acpi_object_type type;
87 acpi_status status;
88
89 ACPI_FUNCTION_ENTRY();
90
91 /*
92 * We are only interested in NS nodes owned by the table that
93 * was just loaded
94 */
95 if (node->owner_id != info->owner_id) {
96 return (AE_OK);
97 }
98
99 info->object_count++;
100
101 /* And even then, we are only interested in a few object types */
102
103 type = acpi_ns_get_type(obj_handle);
104
105 switch (type) {
106 case ACPI_TYPE_REGION:
107
108 status = acpi_ds_initialize_region(obj_handle);
109 if (ACPI_FAILURE(status)) {
110 ACPI_EXCEPTION((AE_INFO, status,
111 "During Region initialization %p [%4.4s]",
112 obj_handle,
113 acpi_ut_get_node_name(obj_handle)));
114 }
115
116 info->op_region_count++;
117 break;
118
119 case ACPI_TYPE_METHOD:
120
121 info->method_count++;
122 break;
123
124 case ACPI_TYPE_DEVICE:
125
126 info->device_count++;
127 break;
128
129 default:
130 break;
131 }
132
133 /*
134 * We ignore errors from above, and always return OK, since
135 * we don't want to abort the walk on a single error.
136 */
137 return (AE_OK);
138}
139
140/*******************************************************************************
141 *
142 * FUNCTION: acpi_ds_initialize_objects
143 *
144 * PARAMETERS: table_desc - Descriptor for parent ACPI table
145 * start_node - Root of subtree to be initialized.
146 *
147 * RETURN: Status
148 *
149 * DESCRIPTION: Walk the namespace starting at "StartNode" and perform any
150 * necessary initialization on the objects found therein
151 *
152 ******************************************************************************/
153
154acpi_status
155acpi_ds_initialize_objects(u32 table_index,
156 struct acpi_namespace_node * start_node)
157{
158 acpi_status status;
159 struct acpi_init_walk_info info;
160 struct acpi_table_header *table;
161 acpi_owner_id owner_id;
162
163 ACPI_FUNCTION_TRACE(ds_initialize_objects);
164
165 status = acpi_tb_get_owner_id(table_index, &owner_id);
166 if (ACPI_FAILURE(status)) {
167 return_ACPI_STATUS(status);
168 }
169
170 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
171 "**** Starting initialization of namespace objects ****\n"));
172 ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, "Parsing all Control Methods:"));
173
174 info.method_count = 0;
175 info.op_region_count = 0;
176 info.object_count = 0;
177 info.device_count = 0;
178 info.table_index = table_index;
179 info.owner_id = owner_id;
180
181 /* Walk entire namespace from the supplied root */
182
183 status = acpi_walk_namespace(ACPI_TYPE_ANY, start_node, ACPI_UINT32_MAX,
184 acpi_ds_init_one_object, &info, NULL);
185 if (ACPI_FAILURE(status)) {
186 ACPI_EXCEPTION((AE_INFO, status, "During WalkNamespace"));
187 }
188
189 status = acpi_get_table_by_index(table_index, &table);
190 if (ACPI_FAILURE(status)) {
191 return_ACPI_STATUS(status);
192 }
193
194 ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
195 "\nTable [%4.4s](id %4.4X) - %hd Objects with %hd Devices %hd Methods %hd Regions\n",
196 table->signature, owner_id, info.object_count,
197 info.device_count, info.method_count,
198 info.op_region_count));
199
200 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
201 "%hd Methods, %hd Regions\n", info.method_count,
202 info.op_region_count));
203
204 return_ACPI_STATUS(AE_OK);
205}
diff --git a/drivers/acpi/acpica/dsmethod.c b/drivers/acpi/acpica/dsmethod.c
new file mode 100644
index 00000000000..333c8560d9f
--- /dev/null
+++ b/drivers/acpi/acpica/dsmethod.c
@@ -0,0 +1,629 @@
1/******************************************************************************
2 *
3 * Module Name: dsmethod - Parser/Interpreter interface - control method parsing
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46#include <acpi/amlcode.h>
47#include <acpi/acdispat.h>
48#include <acpi/acinterp.h>
49#include <acpi/acnamesp.h>
50#ifdef ACPI_DISASSEMBLER
51#include <acpi/acdisasm.h>
52#endif
53
54#define _COMPONENT ACPI_DISPATCHER
55ACPI_MODULE_NAME("dsmethod")
56
57/* Local prototypes */
58static acpi_status
59acpi_ds_create_method_mutex(union acpi_operand_object *method_desc);
60
61/*******************************************************************************
62 *
63 * FUNCTION: acpi_ds_method_error
64 *
65 * PARAMETERS: Status - Execution status
66 * walk_state - Current state
67 *
68 * RETURN: Status
69 *
70 * DESCRIPTION: Called on method error. Invoke the global exception handler if
71 * present, dump the method data if the disassembler is configured
72 *
73 * Note: Allows the exception handler to change the status code
74 *
75 ******************************************************************************/
76
77acpi_status
78acpi_ds_method_error(acpi_status status, struct acpi_walk_state *walk_state)
79{
80 ACPI_FUNCTION_ENTRY();
81
82 /* Ignore AE_OK and control exception codes */
83
84 if (ACPI_SUCCESS(status) || (status & AE_CODE_CONTROL)) {
85 return (status);
86 }
87
88 /* Invoke the global exception handler */
89
90 if (acpi_gbl_exception_handler) {
91
92 /* Exit the interpreter, allow handler to execute methods */
93
94 acpi_ex_exit_interpreter();
95
96 /*
97 * Handler can map the exception code to anything it wants, including
98 * AE_OK, in which case the executing method will not be aborted.
99 */
100 status = acpi_gbl_exception_handler(status,
101 walk_state->method_node ?
102 walk_state->method_node->
103 name.integer : 0,
104 walk_state->opcode,
105 walk_state->aml_offset,
106 NULL);
107 acpi_ex_enter_interpreter();
108 }
109
110 acpi_ds_clear_implicit_return(walk_state);
111
112#ifdef ACPI_DISASSEMBLER
113 if (ACPI_FAILURE(status)) {
114
115 /* Display method locals/args if disassembler is present */
116
117 acpi_dm_dump_method_info(status, walk_state, walk_state->op);
118 }
119#endif
120
121 return (status);
122}
123
124/*******************************************************************************
125 *
126 * FUNCTION: acpi_ds_create_method_mutex
127 *
128 * PARAMETERS: obj_desc - The method object
129 *
130 * RETURN: Status
131 *
132 * DESCRIPTION: Create a mutex object for a serialized control method
133 *
134 ******************************************************************************/
135
136static acpi_status
137acpi_ds_create_method_mutex(union acpi_operand_object *method_desc)
138{
139 union acpi_operand_object *mutex_desc;
140 acpi_status status;
141
142 ACPI_FUNCTION_TRACE(ds_create_method_mutex);
143
144 /* Create the new mutex object */
145
146 mutex_desc = acpi_ut_create_internal_object(ACPI_TYPE_MUTEX);
147 if (!mutex_desc) {
148 return_ACPI_STATUS(AE_NO_MEMORY);
149 }
150
151 /* Create the actual OS Mutex */
152
153 status = acpi_os_create_mutex(&mutex_desc->mutex.os_mutex);
154 if (ACPI_FAILURE(status)) {
155 return_ACPI_STATUS(status);
156 }
157
158 mutex_desc->mutex.sync_level = method_desc->method.sync_level;
159 method_desc->method.mutex = mutex_desc;
160 return_ACPI_STATUS(AE_OK);
161}
162
163/*******************************************************************************
164 *
165 * FUNCTION: acpi_ds_begin_method_execution
166 *
167 * PARAMETERS: method_node - Node of the method
168 * obj_desc - The method object
169 * walk_state - current state, NULL if not yet executing
170 * a method.
171 *
172 * RETURN: Status
173 *
174 * DESCRIPTION: Prepare a method for execution. Parses the method if necessary,
175 * increments the thread count, and waits at the method semaphore
176 * for clearance to execute.
177 *
178 ******************************************************************************/
179
180acpi_status
181acpi_ds_begin_method_execution(struct acpi_namespace_node *method_node,
182 union acpi_operand_object *obj_desc,
183 struct acpi_walk_state *walk_state)
184{
185 acpi_status status = AE_OK;
186
187 ACPI_FUNCTION_TRACE_PTR(ds_begin_method_execution, method_node);
188
189 if (!method_node) {
190 return_ACPI_STATUS(AE_NULL_ENTRY);
191 }
192
193 /* Prevent wraparound of thread count */
194
195 if (obj_desc->method.thread_count == ACPI_UINT8_MAX) {
196 ACPI_ERROR((AE_INFO,
197 "Method reached maximum reentrancy limit (255)"));
198 return_ACPI_STATUS(AE_AML_METHOD_LIMIT);
199 }
200
201 /*
202 * If this method is serialized, we need to acquire the method mutex.
203 */
204 if (obj_desc->method.method_flags & AML_METHOD_SERIALIZED) {
205 /*
206 * Create a mutex for the method if it is defined to be Serialized
207 * and a mutex has not already been created. We defer the mutex creation
208 * until a method is actually executed, to minimize the object count
209 */
210 if (!obj_desc->method.mutex) {
211 status = acpi_ds_create_method_mutex(obj_desc);
212 if (ACPI_FAILURE(status)) {
213 return_ACPI_STATUS(status);
214 }
215 }
216
217 /*
218 * The current_sync_level (per-thread) must be less than or equal to
219 * the sync level of the method. This mechanism provides some
220 * deadlock prevention
221 *
222 * Top-level method invocation has no walk state at this point
223 */
224 if (walk_state &&
225 (walk_state->thread->current_sync_level >
226 obj_desc->method.mutex->mutex.sync_level)) {
227 ACPI_ERROR((AE_INFO,
228 "Cannot acquire Mutex for method [%4.4s], current SyncLevel is too large (%d)",
229 acpi_ut_get_node_name(method_node),
230 walk_state->thread->current_sync_level));
231
232 return_ACPI_STATUS(AE_AML_MUTEX_ORDER);
233 }
234
235 /*
236 * Obtain the method mutex if necessary. Do not acquire mutex for a
237 * recursive call.
238 */
239 if (!walk_state ||
240 !obj_desc->method.mutex->mutex.thread_id ||
241 (walk_state->thread->thread_id !=
242 obj_desc->method.mutex->mutex.thread_id)) {
243 /*
244 * Acquire the method mutex. This releases the interpreter if we
245 * block (and reacquires it before it returns)
246 */
247 status =
248 acpi_ex_system_wait_mutex(obj_desc->method.mutex->
249 mutex.os_mutex,
250 ACPI_WAIT_FOREVER);
251 if (ACPI_FAILURE(status)) {
252 return_ACPI_STATUS(status);
253 }
254
255 /* Update the mutex and walk info and save the original sync_level */
256
257 if (walk_state) {
258 obj_desc->method.mutex->mutex.
259 original_sync_level =
260 walk_state->thread->current_sync_level;
261
262 obj_desc->method.mutex->mutex.thread_id =
263 walk_state->thread->thread_id;
264 walk_state->thread->current_sync_level =
265 obj_desc->method.sync_level;
266 } else {
267 obj_desc->method.mutex->mutex.
268 original_sync_level =
269 obj_desc->method.mutex->mutex.sync_level;
270 }
271 }
272
273 /* Always increase acquisition depth */
274
275 obj_desc->method.mutex->mutex.acquisition_depth++;
276 }
277
278 /*
279 * Allocate an Owner ID for this method, only if this is the first thread
280 * to begin concurrent execution. We only need one owner_id, even if the
281 * method is invoked recursively.
282 */
283 if (!obj_desc->method.owner_id) {
284 status = acpi_ut_allocate_owner_id(&obj_desc->method.owner_id);
285 if (ACPI_FAILURE(status)) {
286 goto cleanup;
287 }
288 }
289
290 /*
291 * Increment the method parse tree thread count since it has been
292 * reentered one more time (even if it is the same thread)
293 */
294 obj_desc->method.thread_count++;
295 return_ACPI_STATUS(status);
296
297 cleanup:
298 /* On error, must release the method mutex (if present) */
299
300 if (obj_desc->method.mutex) {
301 acpi_os_release_mutex(obj_desc->method.mutex->mutex.os_mutex);
302 }
303 return_ACPI_STATUS(status);
304}
305
306/*******************************************************************************
307 *
308 * FUNCTION: acpi_ds_call_control_method
309 *
310 * PARAMETERS: Thread - Info for this thread
311 * this_walk_state - Current walk state
312 * Op - Current Op to be walked
313 *
314 * RETURN: Status
315 *
316 * DESCRIPTION: Transfer execution to a called control method
317 *
318 ******************************************************************************/
319
320acpi_status
321acpi_ds_call_control_method(struct acpi_thread_state *thread,
322 struct acpi_walk_state *this_walk_state,
323 union acpi_parse_object *op)
324{
325 acpi_status status;
326 struct acpi_namespace_node *method_node;
327 struct acpi_walk_state *next_walk_state = NULL;
328 union acpi_operand_object *obj_desc;
329 struct acpi_evaluate_info *info;
330 u32 i;
331
332 ACPI_FUNCTION_TRACE_PTR(ds_call_control_method, this_walk_state);
333
334 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
335 "Calling method %p, currentstate=%p\n",
336 this_walk_state->prev_op, this_walk_state));
337
338 /*
339 * Get the namespace entry for the control method we are about to call
340 */
341 method_node = this_walk_state->method_call_node;
342 if (!method_node) {
343 return_ACPI_STATUS(AE_NULL_ENTRY);
344 }
345
346 obj_desc = acpi_ns_get_attached_object(method_node);
347 if (!obj_desc) {
348 return_ACPI_STATUS(AE_NULL_OBJECT);
349 }
350
351 /* Init for new method, possibly wait on method mutex */
352
353 status = acpi_ds_begin_method_execution(method_node, obj_desc,
354 this_walk_state);
355 if (ACPI_FAILURE(status)) {
356 return_ACPI_STATUS(status);
357 }
358
359 /* Begin method parse/execution. Create a new walk state */
360
361 next_walk_state = acpi_ds_create_walk_state(obj_desc->method.owner_id,
362 NULL, obj_desc, thread);
363 if (!next_walk_state) {
364 status = AE_NO_MEMORY;
365 goto cleanup;
366 }
367
368 /*
369 * The resolved arguments were put on the previous walk state's operand
370 * stack. Operands on the previous walk state stack always
371 * start at index 0. Also, null terminate the list of arguments
372 */
373 this_walk_state->operands[this_walk_state->num_operands] = NULL;
374
375 /*
376 * Allocate and initialize the evaluation information block
377 * TBD: this is somewhat inefficient, should change interface to
378 * ds_init_aml_walk. For now, keeps this struct off the CPU stack
379 */
380 info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
381 if (!info) {
382 return_ACPI_STATUS(AE_NO_MEMORY);
383 }
384
385 info->parameters = &this_walk_state->operands[0];
386
387 status = acpi_ds_init_aml_walk(next_walk_state, NULL, method_node,
388 obj_desc->method.aml_start,
389 obj_desc->method.aml_length, info,
390 ACPI_IMODE_EXECUTE);
391
392 ACPI_FREE(info);
393 if (ACPI_FAILURE(status)) {
394 goto cleanup;
395 }
396
397 /*
398 * Delete the operands on the previous walkstate operand stack
399 * (they were copied to new objects)
400 */
401 for (i = 0; i < obj_desc->method.param_count; i++) {
402 acpi_ut_remove_reference(this_walk_state->operands[i]);
403 this_walk_state->operands[i] = NULL;
404 }
405
406 /* Clear the operand stack */
407
408 this_walk_state->num_operands = 0;
409
410 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
411 "**** Begin nested execution of [%4.4s] **** WalkState=%p\n",
412 method_node->name.ascii, next_walk_state));
413
414 /* Invoke an internal method if necessary */
415
416 if (obj_desc->method.method_flags & AML_METHOD_INTERNAL_ONLY) {
417 status = obj_desc->method.implementation(next_walk_state);
418 if (status == AE_OK) {
419 status = AE_CTRL_TERMINATE;
420 }
421 }
422
423 return_ACPI_STATUS(status);
424
425 cleanup:
426
427 /* On error, we must terminate the method properly */
428
429 acpi_ds_terminate_control_method(obj_desc, next_walk_state);
430 if (next_walk_state) {
431 acpi_ds_delete_walk_state(next_walk_state);
432 }
433
434 return_ACPI_STATUS(status);
435}
436
437/*******************************************************************************
438 *
439 * FUNCTION: acpi_ds_restart_control_method
440 *
441 * PARAMETERS: walk_state - State for preempted method (caller)
442 * return_desc - Return value from the called method
443 *
444 * RETURN: Status
445 *
446 * DESCRIPTION: Restart a method that was preempted by another (nested) method
447 * invocation. Handle the return value (if any) from the callee.
448 *
449 ******************************************************************************/
450
451acpi_status
452acpi_ds_restart_control_method(struct acpi_walk_state *walk_state,
453 union acpi_operand_object *return_desc)
454{
455 acpi_status status;
456 int same_as_implicit_return;
457
458 ACPI_FUNCTION_TRACE_PTR(ds_restart_control_method, walk_state);
459
460 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
461 "****Restart [%4.4s] Op %p ReturnValueFromCallee %p\n",
462 acpi_ut_get_node_name(walk_state->method_node),
463 walk_state->method_call_op, return_desc));
464
465 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
466 " ReturnFromThisMethodUsed?=%X ResStack %p Walk %p\n",
467 walk_state->return_used,
468 walk_state->results, walk_state));
469
470 /* Did the called method return a value? */
471
472 if (return_desc) {
473
474 /* Is the implicit return object the same as the return desc? */
475
476 same_as_implicit_return =
477 (walk_state->implicit_return_obj == return_desc);
478
479 /* Are we actually going to use the return value? */
480
481 if (walk_state->return_used) {
482
483 /* Save the return value from the previous method */
484
485 status = acpi_ds_result_push(return_desc, walk_state);
486 if (ACPI_FAILURE(status)) {
487 acpi_ut_remove_reference(return_desc);
488 return_ACPI_STATUS(status);
489 }
490
491 /*
492 * Save as THIS method's return value in case it is returned
493 * immediately to yet another method
494 */
495 walk_state->return_desc = return_desc;
496 }
497
498 /*
499 * The following code is the optional support for the so-called
500 * "implicit return". Some AML code assumes that the last value of the
501 * method is "implicitly" returned to the caller, in the absence of an
502 * explicit return value.
503 *
504 * Just save the last result of the method as the return value.
505 *
506 * NOTE: this is optional because the ASL language does not actually
507 * support this behavior.
508 */
509 else if (!acpi_ds_do_implicit_return
510 (return_desc, walk_state, FALSE)
511 || same_as_implicit_return) {
512 /*
513 * Delete the return value if it will not be used by the
514 * calling method or remove one reference if the explicit return
515 * is the same as the implicit return value.
516 */
517 acpi_ut_remove_reference(return_desc);
518 }
519 }
520
521 return_ACPI_STATUS(AE_OK);
522}
523
524/*******************************************************************************
525 *
526 * FUNCTION: acpi_ds_terminate_control_method
527 *
528 * PARAMETERS: method_desc - Method object
529 * walk_state - State associated with the method
530 *
531 * RETURN: None
532 *
533 * DESCRIPTION: Terminate a control method. Delete everything that the method
534 * created, delete all locals and arguments, and delete the parse
535 * tree if requested.
536 *
537 * MUTEX: Interpreter is locked
538 *
539 ******************************************************************************/
540
541void
542acpi_ds_terminate_control_method(union acpi_operand_object *method_desc,
543 struct acpi_walk_state *walk_state)
544{
545
546 ACPI_FUNCTION_TRACE_PTR(ds_terminate_control_method, walk_state);
547
548 /* method_desc is required, walk_state is optional */
549
550 if (!method_desc) {
551 return_VOID;
552 }
553
554 if (walk_state) {
555
556 /* Delete all arguments and locals */
557
558 acpi_ds_method_data_delete_all(walk_state);
559
560 /*
561 * If method is serialized, release the mutex and restore the
562 * current sync level for this thread
563 */
564 if (method_desc->method.mutex) {
565
566 /* Acquisition Depth handles recursive calls */
567
568 method_desc->method.mutex->mutex.acquisition_depth--;
569 if (!method_desc->method.mutex->mutex.acquisition_depth) {
570 walk_state->thread->current_sync_level =
571 method_desc->method.mutex->mutex.
572 original_sync_level;
573
574 acpi_os_release_mutex(method_desc->method.
575 mutex->mutex.os_mutex);
576 method_desc->method.mutex->mutex.thread_id = NULL;
577 }
578 }
579
580 /*
581 * Delete any namespace objects created anywhere within
582 * the namespace by the execution of this method
583 */
584 acpi_ns_delete_namespace_by_owner(method_desc->method.owner_id);
585 }
586
587 /* Decrement the thread count on the method */
588
589 if (method_desc->method.thread_count) {
590 method_desc->method.thread_count--;
591 } else {
592 ACPI_ERROR((AE_INFO, "Invalid zero thread count in method"));
593 }
594
595 /* Are there any other threads currently executing this method? */
596
597 if (method_desc->method.thread_count) {
598 /*
599 * Additional threads. Do not release the owner_id in this case,
600 * we immediately reuse it for the next thread executing this method
601 */
602 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
603 "*** Completed execution of one thread, %d threads remaining\n",
604 method_desc->method.thread_count));
605 } else {
606 /* This is the only executing thread for this method */
607
608 /*
609 * Support to dynamically change a method from not_serialized to
610 * Serialized if it appears that the method is incorrectly written and
611 * does not support multiple thread execution. The best example of this
612 * is if such a method creates namespace objects and blocks. A second
613 * thread will fail with an AE_ALREADY_EXISTS exception
614 *
615 * This code is here because we must wait until the last thread exits
616 * before creating the synchronization semaphore.
617 */
618 if ((method_desc->method.method_flags & AML_METHOD_SERIALIZED)
619 && (!method_desc->method.mutex)) {
620 (void)acpi_ds_create_method_mutex(method_desc);
621 }
622
623 /* No more threads, we can free the owner_id */
624
625 acpi_ut_release_owner_id(&method_desc->method.owner_id);
626 }
627
628 return_VOID;
629}
diff --git a/drivers/acpi/acpica/dsmthdat.c b/drivers/acpi/acpica/dsmthdat.c
new file mode 100644
index 00000000000..a1a11996a65
--- /dev/null
+++ b/drivers/acpi/acpica/dsmthdat.c
@@ -0,0 +1,718 @@
1/*******************************************************************************
2 *
3 * Module Name: dsmthdat - control method arguments and local variables
4 *
5 ******************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46#include <acpi/acdispat.h>
47#include <acpi/acnamesp.h>
48#include <acpi/acinterp.h>
49
50#define _COMPONENT ACPI_DISPATCHER
51ACPI_MODULE_NAME("dsmthdat")
52
53/* Local prototypes */
54static void
55acpi_ds_method_data_delete_value(u8 type,
56 u32 index, struct acpi_walk_state *walk_state);
57
58static acpi_status
59acpi_ds_method_data_set_value(u8 type,
60 u32 index,
61 union acpi_operand_object *object,
62 struct acpi_walk_state *walk_state);
63
64#ifdef ACPI_OBSOLETE_FUNCTIONS
65acpi_object_type
66acpi_ds_method_data_get_type(u16 opcode,
67 u32 index, struct acpi_walk_state *walk_state);
68#endif
69
70/*******************************************************************************
71 *
72 * FUNCTION: acpi_ds_method_data_init
73 *
74 * PARAMETERS: walk_state - Current walk state object
75 *
76 * RETURN: Status
77 *
78 * DESCRIPTION: Initialize the data structures that hold the method's arguments
79 * and locals. The data struct is an array of namespace nodes for
80 * each - this allows ref_of and de_ref_of to work properly for these
81 * special data types.
82 *
83 * NOTES: walk_state fields are initialized to zero by the
84 * ACPI_ALLOCATE_ZEROED().
85 *
86 * A pseudo-Namespace Node is assigned to each argument and local
87 * so that ref_of() can return a pointer to the Node.
88 *
89 ******************************************************************************/
90
91void acpi_ds_method_data_init(struct acpi_walk_state *walk_state)
92{
93 u32 i;
94
95 ACPI_FUNCTION_TRACE(ds_method_data_init);
96
97 /* Init the method arguments */
98
99 for (i = 0; i < ACPI_METHOD_NUM_ARGS; i++) {
100 ACPI_MOVE_32_TO_32(&walk_state->arguments[i].name,
101 NAMEOF_ARG_NTE);
102 walk_state->arguments[i].name.integer |= (i << 24);
103 walk_state->arguments[i].descriptor_type = ACPI_DESC_TYPE_NAMED;
104 walk_state->arguments[i].type = ACPI_TYPE_ANY;
105 walk_state->arguments[i].flags =
106 ANOBJ_END_OF_PEER_LIST | ANOBJ_METHOD_ARG;
107 }
108
109 /* Init the method locals */
110
111 for (i = 0; i < ACPI_METHOD_NUM_LOCALS; i++) {
112 ACPI_MOVE_32_TO_32(&walk_state->local_variables[i].name,
113 NAMEOF_LOCAL_NTE);
114
115 walk_state->local_variables[i].name.integer |= (i << 24);
116 walk_state->local_variables[i].descriptor_type =
117 ACPI_DESC_TYPE_NAMED;
118 walk_state->local_variables[i].type = ACPI_TYPE_ANY;
119 walk_state->local_variables[i].flags =
120 ANOBJ_END_OF_PEER_LIST | ANOBJ_METHOD_LOCAL;
121 }
122
123 return_VOID;
124}
125
126/*******************************************************************************
127 *
128 * FUNCTION: acpi_ds_method_data_delete_all
129 *
130 * PARAMETERS: walk_state - Current walk state object
131 *
132 * RETURN: None
133 *
134 * DESCRIPTION: Delete method locals and arguments. Arguments are only
135 * deleted if this method was called from another method.
136 *
137 ******************************************************************************/
138
139void acpi_ds_method_data_delete_all(struct acpi_walk_state *walk_state)
140{
141 u32 index;
142
143 ACPI_FUNCTION_TRACE(ds_method_data_delete_all);
144
145 /* Detach the locals */
146
147 for (index = 0; index < ACPI_METHOD_NUM_LOCALS; index++) {
148 if (walk_state->local_variables[index].object) {
149 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Deleting Local%d=%p\n",
150 index,
151 walk_state->local_variables[index].
152 object));
153
154 /* Detach object (if present) and remove a reference */
155
156 acpi_ns_detach_object(&walk_state->
157 local_variables[index]);
158 }
159 }
160
161 /* Detach the arguments */
162
163 for (index = 0; index < ACPI_METHOD_NUM_ARGS; index++) {
164 if (walk_state->arguments[index].object) {
165 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Deleting Arg%d=%p\n",
166 index,
167 walk_state->arguments[index].object));
168
169 /* Detach object (if present) and remove a reference */
170
171 acpi_ns_detach_object(&walk_state->arguments[index]);
172 }
173 }
174
175 return_VOID;
176}
177
178/*******************************************************************************
179 *
180 * FUNCTION: acpi_ds_method_data_init_args
181 *
182 * PARAMETERS: *Params - Pointer to a parameter list for the method
183 * max_param_count - The arg count for this method
184 * walk_state - Current walk state object
185 *
186 * RETURN: Status
187 *
188 * DESCRIPTION: Initialize arguments for a method. The parameter list is a list
189 * of ACPI operand objects, either null terminated or whose length
190 * is defined by max_param_count.
191 *
192 ******************************************************************************/
193
194acpi_status
195acpi_ds_method_data_init_args(union acpi_operand_object **params,
196 u32 max_param_count,
197 struct acpi_walk_state *walk_state)
198{
199 acpi_status status;
200 u32 index = 0;
201
202 ACPI_FUNCTION_TRACE_PTR(ds_method_data_init_args, params);
203
204 if (!params) {
205 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
206 "No param list passed to method\n"));
207 return_ACPI_STATUS(AE_OK);
208 }
209
210 /* Copy passed parameters into the new method stack frame */
211
212 while ((index < ACPI_METHOD_NUM_ARGS) &&
213 (index < max_param_count) && params[index]) {
214 /*
215 * A valid parameter.
216 * Store the argument in the method/walk descriptor.
217 * Do not copy the arg in order to implement call by reference
218 */
219 status = acpi_ds_method_data_set_value(ACPI_REFCLASS_ARG, index,
220 params[index],
221 walk_state);
222 if (ACPI_FAILURE(status)) {
223 return_ACPI_STATUS(status);
224 }
225
226 index++;
227 }
228
229 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "%d args passed to method\n", index));
230 return_ACPI_STATUS(AE_OK);
231}
232
233/*******************************************************************************
234 *
235 * FUNCTION: acpi_ds_method_data_get_node
236 *
237 * PARAMETERS: Type - Either ACPI_REFCLASS_LOCAL or
238 * ACPI_REFCLASS_ARG
239 * Index - Which Local or Arg whose type to get
240 * walk_state - Current walk state object
241 * Node - Where the node is returned.
242 *
243 * RETURN: Status and node
244 *
245 * DESCRIPTION: Get the Node associated with a local or arg.
246 *
247 ******************************************************************************/
248
249acpi_status
250acpi_ds_method_data_get_node(u8 type,
251 u32 index,
252 struct acpi_walk_state *walk_state,
253 struct acpi_namespace_node **node)
254{
255 ACPI_FUNCTION_TRACE(ds_method_data_get_node);
256
257 /*
258 * Method Locals and Arguments are supported
259 */
260 switch (type) {
261 case ACPI_REFCLASS_LOCAL:
262
263 if (index > ACPI_METHOD_MAX_LOCAL) {
264 ACPI_ERROR((AE_INFO,
265 "Local index %d is invalid (max %d)",
266 index, ACPI_METHOD_MAX_LOCAL));
267 return_ACPI_STATUS(AE_AML_INVALID_INDEX);
268 }
269
270 /* Return a pointer to the pseudo-node */
271
272 *node = &walk_state->local_variables[index];
273 break;
274
275 case ACPI_REFCLASS_ARG:
276
277 if (index > ACPI_METHOD_MAX_ARG) {
278 ACPI_ERROR((AE_INFO,
279 "Arg index %d is invalid (max %d)",
280 index, ACPI_METHOD_MAX_ARG));
281 return_ACPI_STATUS(AE_AML_INVALID_INDEX);
282 }
283
284 /* Return a pointer to the pseudo-node */
285
286 *node = &walk_state->arguments[index];
287 break;
288
289 default:
290 ACPI_ERROR((AE_INFO, "Type %d is invalid", type));
291 return_ACPI_STATUS(AE_TYPE);
292 }
293
294 return_ACPI_STATUS(AE_OK);
295}
296
297/*******************************************************************************
298 *
299 * FUNCTION: acpi_ds_method_data_set_value
300 *
301 * PARAMETERS: Type - Either ACPI_REFCLASS_LOCAL or
302 * ACPI_REFCLASS_ARG
303 * Index - Which Local or Arg to get
304 * Object - Object to be inserted into the stack entry
305 * walk_state - Current walk state object
306 *
307 * RETURN: Status
308 *
309 * DESCRIPTION: Insert an object onto the method stack at entry Opcode:Index.
310 * Note: There is no "implicit conversion" for locals.
311 *
312 ******************************************************************************/
313
314static acpi_status
315acpi_ds_method_data_set_value(u8 type,
316 u32 index,
317 union acpi_operand_object *object,
318 struct acpi_walk_state *walk_state)
319{
320 acpi_status status;
321 struct acpi_namespace_node *node;
322
323 ACPI_FUNCTION_TRACE(ds_method_data_set_value);
324
325 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
326 "NewObj %p Type %2.2X, Refs=%d [%s]\n", object,
327 type, object->common.reference_count,
328 acpi_ut_get_type_name(object->common.type)));
329
330 /* Get the namespace node for the arg/local */
331
332 status = acpi_ds_method_data_get_node(type, index, walk_state, &node);
333 if (ACPI_FAILURE(status)) {
334 return_ACPI_STATUS(status);
335 }
336
337 /*
338 * Increment ref count so object can't be deleted while installed.
339 * NOTE: We do not copy the object in order to preserve the call by
340 * reference semantics of ACPI Control Method invocation.
341 * (See ACPI Specification 2.0_c)
342 */
343 acpi_ut_add_reference(object);
344
345 /* Install the object */
346
347 node->object = object;
348 return_ACPI_STATUS(status);
349}
350
351/*******************************************************************************
352 *
353 * FUNCTION: acpi_ds_method_data_get_value
354 *
355 * PARAMETERS: Type - Either ACPI_REFCLASS_LOCAL or
356 * ACPI_REFCLASS_ARG
357 * Index - Which local_var or argument to get
358 * walk_state - Current walk state object
359 * dest_desc - Where Arg or Local value is returned
360 *
361 * RETURN: Status
362 *
363 * DESCRIPTION: Retrieve value of selected Arg or Local for this method
364 * Used only in acpi_ex_resolve_to_value().
365 *
366 ******************************************************************************/
367
368acpi_status
369acpi_ds_method_data_get_value(u8 type,
370 u32 index,
371 struct acpi_walk_state *walk_state,
372 union acpi_operand_object **dest_desc)
373{
374 acpi_status status;
375 struct acpi_namespace_node *node;
376 union acpi_operand_object *object;
377
378 ACPI_FUNCTION_TRACE(ds_method_data_get_value);
379
380 /* Validate the object descriptor */
381
382 if (!dest_desc) {
383 ACPI_ERROR((AE_INFO, "Null object descriptor pointer"));
384 return_ACPI_STATUS(AE_BAD_PARAMETER);
385 }
386
387 /* Get the namespace node for the arg/local */
388
389 status = acpi_ds_method_data_get_node(type, index, walk_state, &node);
390 if (ACPI_FAILURE(status)) {
391 return_ACPI_STATUS(status);
392 }
393
394 /* Get the object from the node */
395
396 object = node->object;
397
398 /* Examine the returned object, it must be valid. */
399
400 if (!object) {
401 /*
402 * Index points to uninitialized object.
403 * This means that either 1) The expected argument was
404 * not passed to the method, or 2) A local variable
405 * was referenced by the method (via the ASL)
406 * before it was initialized. Either case is an error.
407 */
408
409 /* If slack enabled, init the local_x/arg_x to an Integer of value zero */
410
411 if (acpi_gbl_enable_interpreter_slack) {
412 object =
413 acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
414 if (!object) {
415 return_ACPI_STATUS(AE_NO_MEMORY);
416 }
417
418 object->integer.value = 0;
419 node->object = object;
420 }
421
422 /* Otherwise, return the error */
423
424 else
425 switch (type) {
426 case ACPI_REFCLASS_ARG:
427
428 ACPI_ERROR((AE_INFO,
429 "Uninitialized Arg[%d] at node %p",
430 index, node));
431
432 return_ACPI_STATUS(AE_AML_UNINITIALIZED_ARG);
433
434 case ACPI_REFCLASS_LOCAL:
435
436 ACPI_ERROR((AE_INFO,
437 "Uninitialized Local[%d] at node %p",
438 index, node));
439
440 return_ACPI_STATUS(AE_AML_UNINITIALIZED_LOCAL);
441
442 default:
443
444 ACPI_ERROR((AE_INFO,
445 "Not a Arg/Local opcode: %X",
446 type));
447 return_ACPI_STATUS(AE_AML_INTERNAL);
448 }
449 }
450
451 /*
452 * The Index points to an initialized and valid object.
453 * Return an additional reference to the object
454 */
455 *dest_desc = object;
456 acpi_ut_add_reference(object);
457
458 return_ACPI_STATUS(AE_OK);
459}
460
461/*******************************************************************************
462 *
463 * FUNCTION: acpi_ds_method_data_delete_value
464 *
465 * PARAMETERS: Type - Either ACPI_REFCLASS_LOCAL or
466 * ACPI_REFCLASS_ARG
467 * Index - Which local_var or argument to delete
468 * walk_state - Current walk state object
469 *
470 * RETURN: None
471 *
472 * DESCRIPTION: Delete the entry at Opcode:Index. Inserts
473 * a null into the stack slot after the object is deleted.
474 *
475 ******************************************************************************/
476
477static void
478acpi_ds_method_data_delete_value(u8 type,
479 u32 index, struct acpi_walk_state *walk_state)
480{
481 acpi_status status;
482 struct acpi_namespace_node *node;
483 union acpi_operand_object *object;
484
485 ACPI_FUNCTION_TRACE(ds_method_data_delete_value);
486
487 /* Get the namespace node for the arg/local */
488
489 status = acpi_ds_method_data_get_node(type, index, walk_state, &node);
490 if (ACPI_FAILURE(status)) {
491 return_VOID;
492 }
493
494 /* Get the associated object */
495
496 object = acpi_ns_get_attached_object(node);
497
498 /*
499 * Undefine the Arg or Local by setting its descriptor
500 * pointer to NULL. Locals/Args can contain both
501 * ACPI_OPERAND_OBJECTS and ACPI_NAMESPACE_NODEs
502 */
503 node->object = NULL;
504
505 if ((object) &&
506 (ACPI_GET_DESCRIPTOR_TYPE(object) == ACPI_DESC_TYPE_OPERAND)) {
507 /*
508 * There is a valid object.
509 * Decrement the reference count by one to balance the
510 * increment when the object was stored.
511 */
512 acpi_ut_remove_reference(object);
513 }
514
515 return_VOID;
516}
517
518/*******************************************************************************
519 *
520 * FUNCTION: acpi_ds_store_object_to_local
521 *
522 * PARAMETERS: Type - Either ACPI_REFCLASS_LOCAL or
523 * ACPI_REFCLASS_ARG
524 * Index - Which Local or Arg to set
525 * obj_desc - Value to be stored
526 * walk_state - Current walk state
527 *
528 * RETURN: Status
529 *
530 * DESCRIPTION: Store a value in an Arg or Local. The obj_desc is installed
531 * as the new value for the Arg or Local and the reference count
532 * for obj_desc is incremented.
533 *
534 ******************************************************************************/
535
536acpi_status
537acpi_ds_store_object_to_local(u8 type,
538 u32 index,
539 union acpi_operand_object *obj_desc,
540 struct acpi_walk_state *walk_state)
541{
542 acpi_status status;
543 struct acpi_namespace_node *node;
544 union acpi_operand_object *current_obj_desc;
545 union acpi_operand_object *new_obj_desc;
546
547 ACPI_FUNCTION_TRACE(ds_store_object_to_local);
548 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Type=%2.2X Index=%d Obj=%p\n",
549 type, index, obj_desc));
550
551 /* Parameter validation */
552
553 if (!obj_desc) {
554 return_ACPI_STATUS(AE_BAD_PARAMETER);
555 }
556
557 /* Get the namespace node for the arg/local */
558
559 status = acpi_ds_method_data_get_node(type, index, walk_state, &node);
560 if (ACPI_FAILURE(status)) {
561 return_ACPI_STATUS(status);
562 }
563
564 current_obj_desc = acpi_ns_get_attached_object(node);
565 if (current_obj_desc == obj_desc) {
566 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Obj=%p already installed!\n",
567 obj_desc));
568 return_ACPI_STATUS(status);
569 }
570
571 /*
572 * If the reference count on the object is more than one, we must
573 * take a copy of the object before we store. A reference count
574 * of exactly 1 means that the object was just created during the
575 * evaluation of an expression, and we can safely use it since it
576 * is not used anywhere else.
577 */
578 new_obj_desc = obj_desc;
579 if (obj_desc->common.reference_count > 1) {
580 status =
581 acpi_ut_copy_iobject_to_iobject(obj_desc, &new_obj_desc,
582 walk_state);
583 if (ACPI_FAILURE(status)) {
584 return_ACPI_STATUS(status);
585 }
586 }
587
588 /*
589 * If there is an object already in this slot, we either
590 * have to delete it, or if this is an argument and there
591 * is an object reference stored there, we have to do
592 * an indirect store!
593 */
594 if (current_obj_desc) {
595 /*
596 * Check for an indirect store if an argument
597 * contains an object reference (stored as an Node).
598 * We don't allow this automatic dereferencing for
599 * locals, since a store to a local should overwrite
600 * anything there, including an object reference.
601 *
602 * If both Arg0 and Local0 contain ref_of (Local4):
603 *
604 * Store (1, Arg0) - Causes indirect store to local4
605 * Store (1, Local0) - Stores 1 in local0, overwriting
606 * the reference to local4
607 * Store (1, de_refof (Local0)) - Causes indirect store to local4
608 *
609 * Weird, but true.
610 */
611 if (type == ACPI_REFCLASS_ARG) {
612 /*
613 * If we have a valid reference object that came from ref_of(),
614 * do the indirect store
615 */
616 if ((ACPI_GET_DESCRIPTOR_TYPE(current_obj_desc) ==
617 ACPI_DESC_TYPE_OPERAND)
618 && (current_obj_desc->common.type ==
619 ACPI_TYPE_LOCAL_REFERENCE)
620 && (current_obj_desc->reference.class ==
621 ACPI_REFCLASS_REFOF)) {
622 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
623 "Arg (%p) is an ObjRef(Node), storing in node %p\n",
624 new_obj_desc,
625 current_obj_desc));
626
627 /*
628 * Store this object to the Node (perform the indirect store)
629 * NOTE: No implicit conversion is performed, as per the ACPI
630 * specification rules on storing to Locals/Args.
631 */
632 status =
633 acpi_ex_store_object_to_node(new_obj_desc,
634 current_obj_desc->
635 reference.
636 object,
637 walk_state,
638 ACPI_NO_IMPLICIT_CONVERSION);
639
640 /* Remove local reference if we copied the object above */
641
642 if (new_obj_desc != obj_desc) {
643 acpi_ut_remove_reference(new_obj_desc);
644 }
645 return_ACPI_STATUS(status);
646 }
647 }
648
649 /* Delete the existing object before storing the new one */
650
651 acpi_ds_method_data_delete_value(type, index, walk_state);
652 }
653
654 /*
655 * Install the Obj descriptor (*new_obj_desc) into
656 * the descriptor for the Arg or Local.
657 * (increments the object reference count by one)
658 */
659 status =
660 acpi_ds_method_data_set_value(type, index, new_obj_desc,
661 walk_state);
662
663 /* Remove local reference if we copied the object above */
664
665 if (new_obj_desc != obj_desc) {
666 acpi_ut_remove_reference(new_obj_desc);
667 }
668
669 return_ACPI_STATUS(status);
670}
671
672#ifdef ACPI_OBSOLETE_FUNCTIONS
673/*******************************************************************************
674 *
675 * FUNCTION: acpi_ds_method_data_get_type
676 *
677 * PARAMETERS: Opcode - Either AML_LOCAL_OP or AML_ARG_OP
678 * Index - Which Local or Arg whose type to get
679 * walk_state - Current walk state object
680 *
681 * RETURN: Data type of current value of the selected Arg or Local
682 *
683 * DESCRIPTION: Get the type of the object stored in the Local or Arg
684 *
685 ******************************************************************************/
686
687acpi_object_type
688acpi_ds_method_data_get_type(u16 opcode,
689 u32 index, struct acpi_walk_state *walk_state)
690{
691 acpi_status status;
692 struct acpi_namespace_node *node;
693 union acpi_operand_object *object;
694
695 ACPI_FUNCTION_TRACE(ds_method_data_get_type);
696
697 /* Get the namespace node for the arg/local */
698
699 status = acpi_ds_method_data_get_node(opcode, index, walk_state, &node);
700 if (ACPI_FAILURE(status)) {
701 return_VALUE((ACPI_TYPE_NOT_FOUND));
702 }
703
704 /* Get the object */
705
706 object = acpi_ns_get_attached_object(node);
707 if (!object) {
708
709 /* Uninitialized local/arg, return TYPE_ANY */
710
711 return_VALUE(ACPI_TYPE_ANY);
712 }
713
714 /* Get the object type */
715
716 return_VALUE(ACPI_GET_OBJECT_TYPE(object));
717}
718#endif
diff --git a/drivers/acpi/acpica/dsobject.c b/drivers/acpi/acpica/dsobject.c
new file mode 100644
index 00000000000..6e6c73cc39f
--- /dev/null
+++ b/drivers/acpi/acpica/dsobject.c
@@ -0,0 +1,813 @@
1/******************************************************************************
2 *
3 * Module Name: dsobject - Dispatcher object management routines
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46#include <acpi/acparser.h>
47#include <acpi/amlcode.h>
48#include <acpi/acdispat.h>
49#include <acpi/acnamesp.h>
50#include <acpi/acinterp.h>
51
52#define _COMPONENT ACPI_DISPATCHER
53ACPI_MODULE_NAME("dsobject")
54
55/* Local prototypes */
56static acpi_status
57acpi_ds_build_internal_object(struct acpi_walk_state *walk_state,
58 union acpi_parse_object *op,
59 union acpi_operand_object **obj_desc_ptr);
60
61#ifndef ACPI_NO_METHOD_EXECUTION
62/*******************************************************************************
63 *
64 * FUNCTION: acpi_ds_build_internal_object
65 *
66 * PARAMETERS: walk_state - Current walk state
67 * Op - Parser object to be translated
68 * obj_desc_ptr - Where the ACPI internal object is returned
69 *
70 * RETURN: Status
71 *
72 * DESCRIPTION: Translate a parser Op object to the equivalent namespace object
73 * Simple objects are any objects other than a package object!
74 *
75 ******************************************************************************/
76
77static acpi_status
78acpi_ds_build_internal_object(struct acpi_walk_state *walk_state,
79 union acpi_parse_object *op,
80 union acpi_operand_object **obj_desc_ptr)
81{
82 union acpi_operand_object *obj_desc;
83 acpi_status status;
84
85 ACPI_FUNCTION_TRACE(ds_build_internal_object);
86
87 *obj_desc_ptr = NULL;
88 if (op->common.aml_opcode == AML_INT_NAMEPATH_OP) {
89 /*
90 * This is a named object reference. If this name was
91 * previously looked up in the namespace, it was stored in this op.
92 * Otherwise, go ahead and look it up now
93 */
94 if (!op->common.node) {
95 status = acpi_ns_lookup(walk_state->scope_info,
96 op->common.value.string,
97 ACPI_TYPE_ANY,
98 ACPI_IMODE_EXECUTE,
99 ACPI_NS_SEARCH_PARENT |
100 ACPI_NS_DONT_OPEN_SCOPE, NULL,
101 ACPI_CAST_INDIRECT_PTR(struct
102 acpi_namespace_node,
103 &(op->
104 common.
105 node)));
106 if (ACPI_FAILURE(status)) {
107
108 /* Check if we are resolving a named reference within a package */
109
110 if ((status == AE_NOT_FOUND)
111 && (acpi_gbl_enable_interpreter_slack)
112 &&
113 ((op->common.parent->common.aml_opcode ==
114 AML_PACKAGE_OP)
115 || (op->common.parent->common.aml_opcode ==
116 AML_VAR_PACKAGE_OP))) {
117 /*
118 * We didn't find the target and we are populating elements
119 * of a package - ignore if slack enabled. Some ASL code
120 * contains dangling invalid references in packages and
121 * expects that no exception will be issued. Leave the
122 * element as a null element. It cannot be used, but it
123 * can be overwritten by subsequent ASL code - this is
124 * typically the case.
125 */
126 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
127 "Ignoring unresolved reference in package [%4.4s]\n",
128 walk_state->
129 scope_info->scope.
130 node->name.ascii));
131
132 return_ACPI_STATUS(AE_OK);
133 } else {
134 ACPI_ERROR_NAMESPACE(op->common.value.
135 string, status);
136 }
137
138 return_ACPI_STATUS(status);
139 }
140 }
141
142 /* Special object resolution for elements of a package */
143
144 if ((op->common.parent->common.aml_opcode == AML_PACKAGE_OP) ||
145 (op->common.parent->common.aml_opcode ==
146 AML_VAR_PACKAGE_OP)) {
147 /*
148 * Attempt to resolve the node to a value before we insert it into
149 * the package. If this is a reference to a common data type,
150 * resolve it immediately. According to the ACPI spec, package
151 * elements can only be "data objects" or method references.
152 * Attempt to resolve to an Integer, Buffer, String or Package.
153 * If cannot, return the named reference (for things like Devices,
154 * Methods, etc.) Buffer Fields and Fields will resolve to simple
155 * objects (int/buf/str/pkg).
156 *
157 * NOTE: References to things like Devices, Methods, Mutexes, etc.
158 * will remain as named references. This behavior is not described
159 * in the ACPI spec, but it appears to be an oversight.
160 */
161 obj_desc =
162 ACPI_CAST_PTR(union acpi_operand_object,
163 op->common.node);
164
165 status =
166 acpi_ex_resolve_node_to_value(ACPI_CAST_INDIRECT_PTR
167 (struct
168 acpi_namespace_node,
169 &obj_desc),
170 walk_state);
171 if (ACPI_FAILURE(status)) {
172 return_ACPI_STATUS(status);
173 }
174
175 switch (op->common.node->type) {
176 /*
177 * For these types, we need the actual node, not the subobject.
178 * However, the subobject did not get an extra reference count above.
179 *
180 * TBD: should ex_resolve_node_to_value be changed to fix this?
181 */
182 case ACPI_TYPE_DEVICE:
183 case ACPI_TYPE_THERMAL:
184
185 acpi_ut_add_reference(op->common.node->object);
186
187 /*lint -fallthrough */
188 /*
189 * For these types, we need the actual node, not the subobject.
190 * The subobject got an extra reference count in ex_resolve_node_to_value.
191 */
192 case ACPI_TYPE_MUTEX:
193 case ACPI_TYPE_METHOD:
194 case ACPI_TYPE_POWER:
195 case ACPI_TYPE_PROCESSOR:
196 case ACPI_TYPE_EVENT:
197 case ACPI_TYPE_REGION:
198
199 /* We will create a reference object for these types below */
200 break;
201
202 default:
203 /*
204 * All other types - the node was resolved to an actual
205 * object, we are done.
206 */
207 goto exit;
208 }
209 }
210 }
211
212 /* Create and init a new internal ACPI object */
213
214 obj_desc = acpi_ut_create_internal_object((acpi_ps_get_opcode_info
215 (op->common.aml_opcode))->
216 object_type);
217 if (!obj_desc) {
218 return_ACPI_STATUS(AE_NO_MEMORY);
219 }
220
221 status =
222 acpi_ds_init_object_from_op(walk_state, op, op->common.aml_opcode,
223 &obj_desc);
224 if (ACPI_FAILURE(status)) {
225 acpi_ut_remove_reference(obj_desc);
226 return_ACPI_STATUS(status);
227 }
228
229 exit:
230 *obj_desc_ptr = obj_desc;
231 return_ACPI_STATUS(status);
232}
233
234/*******************************************************************************
235 *
236 * FUNCTION: acpi_ds_build_internal_buffer_obj
237 *
238 * PARAMETERS: walk_state - Current walk state
239 * Op - Parser object to be translated
240 * buffer_length - Length of the buffer
241 * obj_desc_ptr - Where the ACPI internal object is returned
242 *
243 * RETURN: Status
244 *
245 * DESCRIPTION: Translate a parser Op package object to the equivalent
246 * namespace object
247 *
248 ******************************************************************************/
249
250acpi_status
251acpi_ds_build_internal_buffer_obj(struct acpi_walk_state *walk_state,
252 union acpi_parse_object *op,
253 u32 buffer_length,
254 union acpi_operand_object **obj_desc_ptr)
255{
256 union acpi_parse_object *arg;
257 union acpi_operand_object *obj_desc;
258 union acpi_parse_object *byte_list;
259 u32 byte_list_length = 0;
260
261 ACPI_FUNCTION_TRACE(ds_build_internal_buffer_obj);
262
263 /*
264 * If we are evaluating a Named buffer object "Name (xxxx, Buffer)".
265 * The buffer object already exists (from the NS node), otherwise it must
266 * be created.
267 */
268 obj_desc = *obj_desc_ptr;
269 if (!obj_desc) {
270
271 /* Create a new buffer object */
272
273 obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_BUFFER);
274 *obj_desc_ptr = obj_desc;
275 if (!obj_desc) {
276 return_ACPI_STATUS(AE_NO_MEMORY);
277 }
278 }
279
280 /*
281 * Second arg is the buffer data (optional) byte_list can be either
282 * individual bytes or a string initializer. In either case, a
283 * byte_list appears in the AML.
284 */
285 arg = op->common.value.arg; /* skip first arg */
286
287 byte_list = arg->named.next;
288 if (byte_list) {
289 if (byte_list->common.aml_opcode != AML_INT_BYTELIST_OP) {
290 ACPI_ERROR((AE_INFO,
291 "Expecting bytelist, got AML opcode %X in op %p",
292 byte_list->common.aml_opcode, byte_list));
293
294 acpi_ut_remove_reference(obj_desc);
295 return (AE_TYPE);
296 }
297
298 byte_list_length = (u32) byte_list->common.value.integer;
299 }
300
301 /*
302 * The buffer length (number of bytes) will be the larger of:
303 * 1) The specified buffer length and
304 * 2) The length of the initializer byte list
305 */
306 obj_desc->buffer.length = buffer_length;
307 if (byte_list_length > buffer_length) {
308 obj_desc->buffer.length = byte_list_length;
309 }
310
311 /* Allocate the buffer */
312
313 if (obj_desc->buffer.length == 0) {
314 obj_desc->buffer.pointer = NULL;
315 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
316 "Buffer defined with zero length in AML, creating\n"));
317 } else {
318 obj_desc->buffer.pointer =
319 ACPI_ALLOCATE_ZEROED(obj_desc->buffer.length);
320 if (!obj_desc->buffer.pointer) {
321 acpi_ut_delete_object_desc(obj_desc);
322 return_ACPI_STATUS(AE_NO_MEMORY);
323 }
324
325 /* Initialize buffer from the byte_list (if present) */
326
327 if (byte_list) {
328 ACPI_MEMCPY(obj_desc->buffer.pointer,
329 byte_list->named.data, byte_list_length);
330 }
331 }
332
333 obj_desc->buffer.flags |= AOPOBJ_DATA_VALID;
334 op->common.node = ACPI_CAST_PTR(struct acpi_namespace_node, obj_desc);
335 return_ACPI_STATUS(AE_OK);
336}
337
338/*******************************************************************************
339 *
340 * FUNCTION: acpi_ds_build_internal_package_obj
341 *
342 * PARAMETERS: walk_state - Current walk state
343 * Op - Parser object to be translated
344 * element_count - Number of elements in the package - this is
345 * the num_elements argument to Package()
346 * obj_desc_ptr - Where the ACPI internal object is returned
347 *
348 * RETURN: Status
349 *
350 * DESCRIPTION: Translate a parser Op package object to the equivalent
351 * namespace object
352 *
353 * NOTE: The number of elements in the package will be always be the num_elements
354 * count, regardless of the number of elements in the package list. If
355 * num_elements is smaller, only that many package list elements are used.
356 * if num_elements is larger, the Package object is padded out with
357 * objects of type Uninitialized (as per ACPI spec.)
358 *
359 * Even though the ASL compilers do not allow num_elements to be smaller
360 * than the Package list length (for the fixed length package opcode), some
361 * BIOS code modifies the AML on the fly to adjust the num_elements, and
362 * this code compensates for that. This also provides compatibility with
363 * other AML interpreters.
364 *
365 ******************************************************************************/
366
367acpi_status
368acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state,
369 union acpi_parse_object *op,
370 u32 element_count,
371 union acpi_operand_object **obj_desc_ptr)
372{
373 union acpi_parse_object *arg;
374 union acpi_parse_object *parent;
375 union acpi_operand_object *obj_desc = NULL;
376 acpi_status status = AE_OK;
377 unsigned i;
378 u16 index;
379 u16 reference_count;
380
381 ACPI_FUNCTION_TRACE(ds_build_internal_package_obj);
382
383 /* Find the parent of a possibly nested package */
384
385 parent = op->common.parent;
386 while ((parent->common.aml_opcode == AML_PACKAGE_OP) ||
387 (parent->common.aml_opcode == AML_VAR_PACKAGE_OP)) {
388 parent = parent->common.parent;
389 }
390
391 /*
392 * If we are evaluating a Named package object "Name (xxxx, Package)",
393 * the package object already exists, otherwise it must be created.
394 */
395 obj_desc = *obj_desc_ptr;
396 if (!obj_desc) {
397 obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_PACKAGE);
398 *obj_desc_ptr = obj_desc;
399 if (!obj_desc) {
400 return_ACPI_STATUS(AE_NO_MEMORY);
401 }
402
403 obj_desc->package.node = parent->common.node;
404 }
405
406 /*
407 * Allocate the element array (array of pointers to the individual
408 * objects) based on the num_elements parameter. Add an extra pointer slot
409 * so that the list is always null terminated.
410 */
411 obj_desc->package.elements = ACPI_ALLOCATE_ZEROED(((acpi_size)
412 element_count +
413 1) * sizeof(void *));
414
415 if (!obj_desc->package.elements) {
416 acpi_ut_delete_object_desc(obj_desc);
417 return_ACPI_STATUS(AE_NO_MEMORY);
418 }
419
420 obj_desc->package.count = element_count;
421
422 /*
423 * Initialize the elements of the package, up to the num_elements count.
424 * Package is automatically padded with uninitialized (NULL) elements
425 * if num_elements is greater than the package list length. Likewise,
426 * Package is truncated if num_elements is less than the list length.
427 */
428 arg = op->common.value.arg;
429 arg = arg->common.next;
430 for (i = 0; arg && (i < element_count); i++) {
431 if (arg->common.aml_opcode == AML_INT_RETURN_VALUE_OP) {
432 if (arg->common.node->type == ACPI_TYPE_METHOD) {
433 /*
434 * A method reference "looks" to the parser to be a method
435 * invocation, so we special case it here
436 */
437 arg->common.aml_opcode = AML_INT_NAMEPATH_OP;
438 status =
439 acpi_ds_build_internal_object(walk_state,
440 arg,
441 &obj_desc->
442 package.
443 elements[i]);
444 } else {
445 /* This package element is already built, just get it */
446
447 obj_desc->package.elements[i] =
448 ACPI_CAST_PTR(union acpi_operand_object,
449 arg->common.node);
450 }
451 } else {
452 status = acpi_ds_build_internal_object(walk_state, arg,
453 &obj_desc->
454 package.
455 elements[i]);
456 }
457
458 if (*obj_desc_ptr) {
459
460 /* Existing package, get existing reference count */
461
462 reference_count =
463 (*obj_desc_ptr)->common.reference_count;
464 if (reference_count > 1) {
465
466 /* Make new element ref count match original ref count */
467
468 for (index = 0; index < (reference_count - 1);
469 index++) {
470 acpi_ut_add_reference((obj_desc->
471 package.
472 elements[i]));
473 }
474 }
475 }
476
477 arg = arg->common.next;
478 }
479
480 /* Check for match between num_elements and actual length of package_list */
481
482 if (arg) {
483 /*
484 * num_elements was exhausted, but there are remaining elements in the
485 * package_list.
486 *
487 * Note: technically, this is an error, from ACPI spec: "It is an error
488 * for NumElements to be less than the number of elements in the
489 * PackageList". However, for now, we just print an error message and
490 * no exception is returned.
491 */
492 while (arg) {
493
494 /* Find out how many elements there really are */
495
496 i++;
497 arg = arg->common.next;
498 }
499
500 ACPI_WARNING((AE_INFO,
501 "Package List length (%X) larger than NumElements count (%X), truncated\n",
502 i, element_count));
503 } else if (i < element_count) {
504 /*
505 * Arg list (elements) was exhausted, but we did not reach num_elements count.
506 * Note: this is not an error, the package is padded out with NULLs.
507 */
508 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
509 "Package List length (%X) smaller than NumElements count (%X), padded with null elements\n",
510 i, element_count));
511 }
512
513 obj_desc->package.flags |= AOPOBJ_DATA_VALID;
514 op->common.node = ACPI_CAST_PTR(struct acpi_namespace_node, obj_desc);
515 return_ACPI_STATUS(status);
516}
517
518/*******************************************************************************
519 *
520 * FUNCTION: acpi_ds_create_node
521 *
522 * PARAMETERS: walk_state - Current walk state
523 * Node - NS Node to be initialized
524 * Op - Parser object to be translated
525 *
526 * RETURN: Status
527 *
528 * DESCRIPTION: Create the object to be associated with a namespace node
529 *
530 ******************************************************************************/
531
532acpi_status
533acpi_ds_create_node(struct acpi_walk_state *walk_state,
534 struct acpi_namespace_node *node,
535 union acpi_parse_object *op)
536{
537 acpi_status status;
538 union acpi_operand_object *obj_desc;
539
540 ACPI_FUNCTION_TRACE_PTR(ds_create_node, op);
541
542 /*
543 * Because of the execution pass through the non-control-method
544 * parts of the table, we can arrive here twice. Only init
545 * the named object node the first time through
546 */
547 if (acpi_ns_get_attached_object(node)) {
548 return_ACPI_STATUS(AE_OK);
549 }
550
551 if (!op->common.value.arg) {
552
553 /* No arguments, there is nothing to do */
554
555 return_ACPI_STATUS(AE_OK);
556 }
557
558 /* Build an internal object for the argument(s) */
559
560 status = acpi_ds_build_internal_object(walk_state, op->common.value.arg,
561 &obj_desc);
562 if (ACPI_FAILURE(status)) {
563 return_ACPI_STATUS(status);
564 }
565
566 /* Re-type the object according to its argument */
567
568 node->type = ACPI_GET_OBJECT_TYPE(obj_desc);
569
570 /* Attach obj to node */
571
572 status = acpi_ns_attach_object(node, obj_desc, node->type);
573
574 /* Remove local reference to the object */
575
576 acpi_ut_remove_reference(obj_desc);
577 return_ACPI_STATUS(status);
578}
579
580#endif /* ACPI_NO_METHOD_EXECUTION */
581
582/*******************************************************************************
583 *
584 * FUNCTION: acpi_ds_init_object_from_op
585 *
586 * PARAMETERS: walk_state - Current walk state
587 * Op - Parser op used to init the internal object
588 * Opcode - AML opcode associated with the object
589 * ret_obj_desc - Namespace object to be initialized
590 *
591 * RETURN: Status
592 *
593 * DESCRIPTION: Initialize a namespace object from a parser Op and its
594 * associated arguments. The namespace object is a more compact
595 * representation of the Op and its arguments.
596 *
597 ******************************************************************************/
598
599acpi_status
600acpi_ds_init_object_from_op(struct acpi_walk_state *walk_state,
601 union acpi_parse_object *op,
602 u16 opcode,
603 union acpi_operand_object **ret_obj_desc)
604{
605 const struct acpi_opcode_info *op_info;
606 union acpi_operand_object *obj_desc;
607 acpi_status status = AE_OK;
608
609 ACPI_FUNCTION_TRACE(ds_init_object_from_op);
610
611 obj_desc = *ret_obj_desc;
612 op_info = acpi_ps_get_opcode_info(opcode);
613 if (op_info->class == AML_CLASS_UNKNOWN) {
614
615 /* Unknown opcode */
616
617 return_ACPI_STATUS(AE_TYPE);
618 }
619
620 /* Perform per-object initialization */
621
622 switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
623 case ACPI_TYPE_BUFFER:
624
625 /*
626 * Defer evaluation of Buffer term_arg operand
627 */
628 obj_desc->buffer.node =
629 ACPI_CAST_PTR(struct acpi_namespace_node,
630 walk_state->operands[0]);
631 obj_desc->buffer.aml_start = op->named.data;
632 obj_desc->buffer.aml_length = op->named.length;
633 break;
634
635 case ACPI_TYPE_PACKAGE:
636
637 /*
638 * Defer evaluation of Package term_arg operand
639 */
640 obj_desc->package.node =
641 ACPI_CAST_PTR(struct acpi_namespace_node,
642 walk_state->operands[0]);
643 obj_desc->package.aml_start = op->named.data;
644 obj_desc->package.aml_length = op->named.length;
645 break;
646
647 case ACPI_TYPE_INTEGER:
648
649 switch (op_info->type) {
650 case AML_TYPE_CONSTANT:
651 /*
652 * Resolve AML Constants here - AND ONLY HERE!
653 * All constants are integers.
654 * We mark the integer with a flag that indicates that it started
655 * life as a constant -- so that stores to constants will perform
656 * as expected (noop). zero_op is used as a placeholder for optional
657 * target operands.
658 */
659 obj_desc->common.flags = AOPOBJ_AML_CONSTANT;
660
661 switch (opcode) {
662 case AML_ZERO_OP:
663
664 obj_desc->integer.value = 0;
665 break;
666
667 case AML_ONE_OP:
668
669 obj_desc->integer.value = 1;
670 break;
671
672 case AML_ONES_OP:
673
674 obj_desc->integer.value = ACPI_INTEGER_MAX;
675
676 /* Truncate value if we are executing from a 32-bit ACPI table */
677
678#ifndef ACPI_NO_METHOD_EXECUTION
679 acpi_ex_truncate_for32bit_table(obj_desc);
680#endif
681 break;
682
683 case AML_REVISION_OP:
684
685 obj_desc->integer.value = ACPI_CA_VERSION;
686 break;
687
688 default:
689
690 ACPI_ERROR((AE_INFO,
691 "Unknown constant opcode %X",
692 opcode));
693 status = AE_AML_OPERAND_TYPE;
694 break;
695 }
696 break;
697
698 case AML_TYPE_LITERAL:
699
700 obj_desc->integer.value = op->common.value.integer;
701#ifndef ACPI_NO_METHOD_EXECUTION
702 acpi_ex_truncate_for32bit_table(obj_desc);
703#endif
704 break;
705
706 default:
707 ACPI_ERROR((AE_INFO, "Unknown Integer type %X",
708 op_info->type));
709 status = AE_AML_OPERAND_TYPE;
710 break;
711 }
712 break;
713
714 case ACPI_TYPE_STRING:
715
716 obj_desc->string.pointer = op->common.value.string;
717 obj_desc->string.length =
718 (u32) ACPI_STRLEN(op->common.value.string);
719
720 /*
721 * The string is contained in the ACPI table, don't ever try
722 * to delete it
723 */
724 obj_desc->common.flags |= AOPOBJ_STATIC_POINTER;
725 break;
726
727 case ACPI_TYPE_METHOD:
728 break;
729
730 case ACPI_TYPE_LOCAL_REFERENCE:
731
732 switch (op_info->type) {
733 case AML_TYPE_LOCAL_VARIABLE:
734
735 /* Local ID (0-7) is (AML opcode - base AML_LOCAL_OP) */
736
737 obj_desc->reference.value = opcode - AML_LOCAL_OP;
738 obj_desc->reference.class = ACPI_REFCLASS_LOCAL;
739
740#ifndef ACPI_NO_METHOD_EXECUTION
741 status =
742 acpi_ds_method_data_get_node(ACPI_REFCLASS_LOCAL,
743 obj_desc->reference.
744 value, walk_state,
745 ACPI_CAST_INDIRECT_PTR
746 (struct
747 acpi_namespace_node,
748 &obj_desc->reference.
749 object));
750#endif
751 break;
752
753 case AML_TYPE_METHOD_ARGUMENT:
754
755 /* Arg ID (0-6) is (AML opcode - base AML_ARG_OP) */
756
757 obj_desc->reference.value = opcode - AML_ARG_OP;
758 obj_desc->reference.class = ACPI_REFCLASS_ARG;
759
760#ifndef ACPI_NO_METHOD_EXECUTION
761 status = acpi_ds_method_data_get_node(ACPI_REFCLASS_ARG,
762 obj_desc->
763 reference.value,
764 walk_state,
765 ACPI_CAST_INDIRECT_PTR
766 (struct
767 acpi_namespace_node,
768 &obj_desc->
769 reference.
770 object));
771#endif
772 break;
773
774 default: /* Object name or Debug object */
775
776 switch (op->common.aml_opcode) {
777 case AML_INT_NAMEPATH_OP:
778
779 /* Node was saved in Op */
780
781 obj_desc->reference.node = op->common.node;
782 obj_desc->reference.object =
783 op->common.node->object;
784 obj_desc->reference.class = ACPI_REFCLASS_NAME;
785 break;
786
787 case AML_DEBUG_OP:
788
789 obj_desc->reference.class = ACPI_REFCLASS_DEBUG;
790 break;
791
792 default:
793
794 ACPI_ERROR((AE_INFO,
795 "Unimplemented reference type for AML opcode: %4.4X",
796 opcode));
797 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
798 }
799 break;
800 }
801 break;
802
803 default:
804
805 ACPI_ERROR((AE_INFO, "Unimplemented data type: %X",
806 ACPI_GET_OBJECT_TYPE(obj_desc)));
807
808 status = AE_AML_OPERAND_TYPE;
809 break;
810 }
811
812 return_ACPI_STATUS(status);
813}
diff --git a/drivers/acpi/acpica/dsopcode.c b/drivers/acpi/acpica/dsopcode.c
new file mode 100644
index 00000000000..cb8a0d3109f
--- /dev/null
+++ b/drivers/acpi/acpica/dsopcode.c
@@ -0,0 +1,1469 @@
1/******************************************************************************
2 *
3 * Module Name: dsopcode - Dispatcher Op Region support and handling of
4 * "control" opcodes
5 *
6 *****************************************************************************/
7
8/*
9 * Copyright (C) 2000 - 2008, Intel Corp.
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions, and the following disclaimer,
17 * without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 * substantially similar to the "NO WARRANTY" disclaimer below
20 * ("Disclaimer") and any redistribution must be conditioned upon
21 * including a substantially similar Disclaimer requirement for further
22 * binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 * of any contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
30 *
31 * NO WARRANTY
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
43 */
44
45#include <acpi/acpi.h>
46#include <acpi/accommon.h>
47#include <acpi/acparser.h>
48#include <acpi/amlcode.h>
49#include <acpi/acdispat.h>
50#include <acpi/acinterp.h>
51#include <acpi/acnamesp.h>
52#include <acpi/acevents.h>
53#include <acpi/actables.h>
54
55#define _COMPONENT ACPI_DISPATCHER
56ACPI_MODULE_NAME("dsopcode")
57
58/* Local prototypes */
59static acpi_status
60acpi_ds_execute_arguments(struct acpi_namespace_node *node,
61 struct acpi_namespace_node *scope_node,
62 u32 aml_length, u8 * aml_start);
63
64static acpi_status
65acpi_ds_init_buffer_field(u16 aml_opcode,
66 union acpi_operand_object *obj_desc,
67 union acpi_operand_object *buffer_desc,
68 union acpi_operand_object *offset_desc,
69 union acpi_operand_object *length_desc,
70 union acpi_operand_object *result_desc);
71
72/*******************************************************************************
73 *
74 * FUNCTION: acpi_ds_execute_arguments
75 *
76 * PARAMETERS: Node - Object NS node
77 * scope_node - Parent NS node
78 * aml_length - Length of executable AML
79 * aml_start - Pointer to the AML
80 *
81 * RETURN: Status.
82 *
83 * DESCRIPTION: Late (deferred) execution of region or field arguments
84 *
85 ******************************************************************************/
86
87static acpi_status
88acpi_ds_execute_arguments(struct acpi_namespace_node *node,
89 struct acpi_namespace_node *scope_node,
90 u32 aml_length, u8 * aml_start)
91{
92 acpi_status status;
93 union acpi_parse_object *op;
94 struct acpi_walk_state *walk_state;
95
96 ACPI_FUNCTION_TRACE(ds_execute_arguments);
97
98 /*
99 * Allocate a new parser op to be the root of the parsed tree
100 */
101 op = acpi_ps_alloc_op(AML_INT_EVAL_SUBTREE_OP);
102 if (!op) {
103 return_ACPI_STATUS(AE_NO_MEMORY);
104 }
105
106 /* Save the Node for use in acpi_ps_parse_aml */
107
108 op->common.node = scope_node;
109
110 /* Create and initialize a new parser state */
111
112 walk_state = acpi_ds_create_walk_state(0, NULL, NULL, NULL);
113 if (!walk_state) {
114 status = AE_NO_MEMORY;
115 goto cleanup;
116 }
117
118 status = acpi_ds_init_aml_walk(walk_state, op, NULL, aml_start,
119 aml_length, NULL, ACPI_IMODE_LOAD_PASS1);
120 if (ACPI_FAILURE(status)) {
121 acpi_ds_delete_walk_state(walk_state);
122 goto cleanup;
123 }
124
125 /* Mark this parse as a deferred opcode */
126
127 walk_state->parse_flags = ACPI_PARSE_DEFERRED_OP;
128 walk_state->deferred_node = node;
129
130 /* Pass1: Parse the entire declaration */
131
132 status = acpi_ps_parse_aml(walk_state);
133 if (ACPI_FAILURE(status)) {
134 goto cleanup;
135 }
136
137 /* Get and init the Op created above */
138
139 op->common.node = node;
140 acpi_ps_delete_parse_tree(op);
141
142 /* Evaluate the deferred arguments */
143
144 op = acpi_ps_alloc_op(AML_INT_EVAL_SUBTREE_OP);
145 if (!op) {
146 return_ACPI_STATUS(AE_NO_MEMORY);
147 }
148
149 op->common.node = scope_node;
150
151 /* Create and initialize a new parser state */
152
153 walk_state = acpi_ds_create_walk_state(0, NULL, NULL, NULL);
154 if (!walk_state) {
155 status = AE_NO_MEMORY;
156 goto cleanup;
157 }
158
159 /* Execute the opcode and arguments */
160
161 status = acpi_ds_init_aml_walk(walk_state, op, NULL, aml_start,
162 aml_length, NULL, ACPI_IMODE_EXECUTE);
163 if (ACPI_FAILURE(status)) {
164 acpi_ds_delete_walk_state(walk_state);
165 goto cleanup;
166 }
167
168 /* Mark this execution as a deferred opcode */
169
170 walk_state->deferred_node = node;
171 status = acpi_ps_parse_aml(walk_state);
172
173 cleanup:
174 acpi_ps_delete_parse_tree(op);
175 return_ACPI_STATUS(status);
176}
177
178/*******************************************************************************
179 *
180 * FUNCTION: acpi_ds_get_buffer_field_arguments
181 *
182 * PARAMETERS: obj_desc - A valid buffer_field object
183 *
184 * RETURN: Status.
185 *
186 * DESCRIPTION: Get buffer_field Buffer and Index. This implements the late
187 * evaluation of these field attributes.
188 *
189 ******************************************************************************/
190
191acpi_status
192acpi_ds_get_buffer_field_arguments(union acpi_operand_object *obj_desc)
193{
194 union acpi_operand_object *extra_desc;
195 struct acpi_namespace_node *node;
196 acpi_status status;
197
198 ACPI_FUNCTION_TRACE_PTR(ds_get_buffer_field_arguments, obj_desc);
199
200 if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
201 return_ACPI_STATUS(AE_OK);
202 }
203
204 /* Get the AML pointer (method object) and buffer_field node */
205
206 extra_desc = acpi_ns_get_secondary_object(obj_desc);
207 node = obj_desc->buffer_field.node;
208
209 ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname
210 (ACPI_TYPE_BUFFER_FIELD, node, NULL));
211 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "[%4.4s] BufferField Arg Init\n",
212 acpi_ut_get_node_name(node)));
213
214 /* Execute the AML code for the term_arg arguments */
215
216 status = acpi_ds_execute_arguments(node, acpi_ns_get_parent_node(node),
217 extra_desc->extra.aml_length,
218 extra_desc->extra.aml_start);
219 return_ACPI_STATUS(status);
220}
221
222/*******************************************************************************
223 *
224 * FUNCTION: acpi_ds_get_bank_field_arguments
225 *
226 * PARAMETERS: obj_desc - A valid bank_field object
227 *
228 * RETURN: Status.
229 *
230 * DESCRIPTION: Get bank_field bank_value. This implements the late
231 * evaluation of these field attributes.
232 *
233 ******************************************************************************/
234
235acpi_status
236acpi_ds_get_bank_field_arguments(union acpi_operand_object *obj_desc)
237{
238 union acpi_operand_object *extra_desc;
239 struct acpi_namespace_node *node;
240 acpi_status status;
241
242 ACPI_FUNCTION_TRACE_PTR(ds_get_bank_field_arguments, obj_desc);
243
244 if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
245 return_ACPI_STATUS(AE_OK);
246 }
247
248 /* Get the AML pointer (method object) and bank_field node */
249
250 extra_desc = acpi_ns_get_secondary_object(obj_desc);
251 node = obj_desc->bank_field.node;
252
253 ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname
254 (ACPI_TYPE_LOCAL_BANK_FIELD, node, NULL));
255 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "[%4.4s] BankField Arg Init\n",
256 acpi_ut_get_node_name(node)));
257
258 /* Execute the AML code for the term_arg arguments */
259
260 status = acpi_ds_execute_arguments(node, acpi_ns_get_parent_node(node),
261 extra_desc->extra.aml_length,
262 extra_desc->extra.aml_start);
263 return_ACPI_STATUS(status);
264}
265
266/*******************************************************************************
267 *
268 * FUNCTION: acpi_ds_get_buffer_arguments
269 *
270 * PARAMETERS: obj_desc - A valid Buffer object
271 *
272 * RETURN: Status.
273 *
274 * DESCRIPTION: Get Buffer length and initializer byte list. This implements
275 * the late evaluation of these attributes.
276 *
277 ******************************************************************************/
278
279acpi_status acpi_ds_get_buffer_arguments(union acpi_operand_object *obj_desc)
280{
281 struct acpi_namespace_node *node;
282 acpi_status status;
283
284 ACPI_FUNCTION_TRACE_PTR(ds_get_buffer_arguments, obj_desc);
285
286 if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
287 return_ACPI_STATUS(AE_OK);
288 }
289
290 /* Get the Buffer node */
291
292 node = obj_desc->buffer.node;
293 if (!node) {
294 ACPI_ERROR((AE_INFO,
295 "No pointer back to NS node in buffer obj %p",
296 obj_desc));
297 return_ACPI_STATUS(AE_AML_INTERNAL);
298 }
299
300 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Buffer Arg Init\n"));
301
302 /* Execute the AML code for the term_arg arguments */
303
304 status = acpi_ds_execute_arguments(node, node,
305 obj_desc->buffer.aml_length,
306 obj_desc->buffer.aml_start);
307 return_ACPI_STATUS(status);
308}
309
310/*******************************************************************************
311 *
312 * FUNCTION: acpi_ds_get_package_arguments
313 *
314 * PARAMETERS: obj_desc - A valid Package object
315 *
316 * RETURN: Status.
317 *
318 * DESCRIPTION: Get Package length and initializer byte list. This implements
319 * the late evaluation of these attributes.
320 *
321 ******************************************************************************/
322
323acpi_status acpi_ds_get_package_arguments(union acpi_operand_object *obj_desc)
324{
325 struct acpi_namespace_node *node;
326 acpi_status status;
327
328 ACPI_FUNCTION_TRACE_PTR(ds_get_package_arguments, obj_desc);
329
330 if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
331 return_ACPI_STATUS(AE_OK);
332 }
333
334 /* Get the Package node */
335
336 node = obj_desc->package.node;
337 if (!node) {
338 ACPI_ERROR((AE_INFO,
339 "No pointer back to NS node in package %p",
340 obj_desc));
341 return_ACPI_STATUS(AE_AML_INTERNAL);
342 }
343
344 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Package Arg Init\n"));
345
346 /* Execute the AML code for the term_arg arguments */
347
348 status = acpi_ds_execute_arguments(node, node,
349 obj_desc->package.aml_length,
350 obj_desc->package.aml_start);
351 return_ACPI_STATUS(status);
352}
353
354/*****************************************************************************
355 *
356 * FUNCTION: acpi_ds_get_region_arguments
357 *
358 * PARAMETERS: obj_desc - A valid region object
359 *
360 * RETURN: Status.
361 *
362 * DESCRIPTION: Get region address and length. This implements the late
363 * evaluation of these region attributes.
364 *
365 ****************************************************************************/
366
367acpi_status acpi_ds_get_region_arguments(union acpi_operand_object *obj_desc)
368{
369 struct acpi_namespace_node *node;
370 acpi_status status;
371 union acpi_operand_object *extra_desc;
372
373 ACPI_FUNCTION_TRACE_PTR(ds_get_region_arguments, obj_desc);
374
375 if (obj_desc->region.flags & AOPOBJ_DATA_VALID) {
376 return_ACPI_STATUS(AE_OK);
377 }
378
379 extra_desc = acpi_ns_get_secondary_object(obj_desc);
380 if (!extra_desc) {
381 return_ACPI_STATUS(AE_NOT_EXIST);
382 }
383
384 /* Get the Region node */
385
386 node = obj_desc->region.node;
387
388 ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname
389 (ACPI_TYPE_REGION, node, NULL));
390
391 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "[%4.4s] OpRegion Arg Init at AML %p\n",
392 acpi_ut_get_node_name(node),
393 extra_desc->extra.aml_start));
394
395 /* Execute the argument AML */
396
397 status = acpi_ds_execute_arguments(node, acpi_ns_get_parent_node(node),
398 extra_desc->extra.aml_length,
399 extra_desc->extra.aml_start);
400 if (ACPI_FAILURE(status)) {
401 return_ACPI_STATUS(status);
402 }
403
404 /* Validate the region address/length via the host OS */
405
406 status = acpi_os_validate_address(obj_desc->region.space_id,
407 obj_desc->region.address,
408 (acpi_size) obj_desc->region.length,
409 acpi_ut_get_node_name(node));
410
411 if (ACPI_FAILURE(status)) {
412 /*
413 * Invalid address/length. We will emit an error message and mark
414 * the region as invalid, so that it will cause an additional error if
415 * it is ever used. Then return AE_OK.
416 */
417 ACPI_EXCEPTION((AE_INFO, status,
418 "During address validation of OpRegion [%4.4s]",
419 node->name.ascii));
420 obj_desc->common.flags |= AOPOBJ_INVALID;
421 status = AE_OK;
422 }
423
424 return_ACPI_STATUS(status);
425}
426
427/*******************************************************************************
428 *
429 * FUNCTION: acpi_ds_initialize_region
430 *
431 * PARAMETERS: obj_handle - Region namespace node
432 *
433 * RETURN: Status
434 *
435 * DESCRIPTION: Front end to ev_initialize_region
436 *
437 ******************************************************************************/
438
439acpi_status acpi_ds_initialize_region(acpi_handle obj_handle)
440{
441 union acpi_operand_object *obj_desc;
442 acpi_status status;
443
444 obj_desc = acpi_ns_get_attached_object(obj_handle);
445
446 /* Namespace is NOT locked */
447
448 status = acpi_ev_initialize_region(obj_desc, FALSE);
449 return (status);
450}
451
452/*******************************************************************************
453 *
454 * FUNCTION: acpi_ds_init_buffer_field
455 *
456 * PARAMETERS: aml_opcode - create_xxx_field
457 * obj_desc - buffer_field object
458 * buffer_desc - Host Buffer
459 * offset_desc - Offset into buffer
460 * length_desc - Length of field (CREATE_FIELD_OP only)
461 * result_desc - Where to store the result
462 *
463 * RETURN: Status
464 *
465 * DESCRIPTION: Perform actual initialization of a buffer field
466 *
467 ******************************************************************************/
468
469static acpi_status
470acpi_ds_init_buffer_field(u16 aml_opcode,
471 union acpi_operand_object *obj_desc,
472 union acpi_operand_object *buffer_desc,
473 union acpi_operand_object *offset_desc,
474 union acpi_operand_object *length_desc,
475 union acpi_operand_object *result_desc)
476{
477 u32 offset;
478 u32 bit_offset;
479 u32 bit_count;
480 u8 field_flags;
481 acpi_status status;
482
483 ACPI_FUNCTION_TRACE_PTR(ds_init_buffer_field, obj_desc);
484
485 /* Host object must be a Buffer */
486
487 if (ACPI_GET_OBJECT_TYPE(buffer_desc) != ACPI_TYPE_BUFFER) {
488 ACPI_ERROR((AE_INFO,
489 "Target of Create Field is not a Buffer object - %s",
490 acpi_ut_get_object_type_name(buffer_desc)));
491
492 status = AE_AML_OPERAND_TYPE;
493 goto cleanup;
494 }
495
496 /*
497 * The last parameter to all of these opcodes (result_desc) started
498 * out as a name_string, and should therefore now be a NS node
499 * after resolution in acpi_ex_resolve_operands().
500 */
501 if (ACPI_GET_DESCRIPTOR_TYPE(result_desc) != ACPI_DESC_TYPE_NAMED) {
502 ACPI_ERROR((AE_INFO,
503 "(%s) destination not a NS Node [%s]",
504 acpi_ps_get_opcode_name(aml_opcode),
505 acpi_ut_get_descriptor_name(result_desc)));
506
507 status = AE_AML_OPERAND_TYPE;
508 goto cleanup;
509 }
510
511 offset = (u32) offset_desc->integer.value;
512
513 /*
514 * Setup the Bit offsets and counts, according to the opcode
515 */
516 switch (aml_opcode) {
517 case AML_CREATE_FIELD_OP:
518
519 /* Offset is in bits, count is in bits */
520
521 field_flags = AML_FIELD_ACCESS_BYTE;
522 bit_offset = offset;
523 bit_count = (u32) length_desc->integer.value;
524
525 /* Must have a valid (>0) bit count */
526
527 if (bit_count == 0) {
528 ACPI_ERROR((AE_INFO,
529 "Attempt to CreateField of length zero"));
530 status = AE_AML_OPERAND_VALUE;
531 goto cleanup;
532 }
533 break;
534
535 case AML_CREATE_BIT_FIELD_OP:
536
537 /* Offset is in bits, Field is one bit */
538
539 bit_offset = offset;
540 bit_count = 1;
541 field_flags = AML_FIELD_ACCESS_BYTE;
542 break;
543
544 case AML_CREATE_BYTE_FIELD_OP:
545
546 /* Offset is in bytes, field is one byte */
547
548 bit_offset = 8 * offset;
549 bit_count = 8;
550 field_flags = AML_FIELD_ACCESS_BYTE;
551 break;
552
553 case AML_CREATE_WORD_FIELD_OP:
554
555 /* Offset is in bytes, field is one word */
556
557 bit_offset = 8 * offset;
558 bit_count = 16;
559 field_flags = AML_FIELD_ACCESS_WORD;
560 break;
561
562 case AML_CREATE_DWORD_FIELD_OP:
563
564 /* Offset is in bytes, field is one dword */
565
566 bit_offset = 8 * offset;
567 bit_count = 32;
568 field_flags = AML_FIELD_ACCESS_DWORD;
569 break;
570
571 case AML_CREATE_QWORD_FIELD_OP:
572
573 /* Offset is in bytes, field is one qword */
574
575 bit_offset = 8 * offset;
576 bit_count = 64;
577 field_flags = AML_FIELD_ACCESS_QWORD;
578 break;
579
580 default:
581
582 ACPI_ERROR((AE_INFO,
583 "Unknown field creation opcode %02x", aml_opcode));
584 status = AE_AML_BAD_OPCODE;
585 goto cleanup;
586 }
587
588 /* Entire field must fit within the current length of the buffer */
589
590 if ((bit_offset + bit_count) > (8 * (u32) buffer_desc->buffer.length)) {
591 ACPI_ERROR((AE_INFO,
592 "Field [%4.4s] at %d exceeds Buffer [%4.4s] size %d (bits)",
593 acpi_ut_get_node_name(result_desc),
594 bit_offset + bit_count,
595 acpi_ut_get_node_name(buffer_desc->buffer.node),
596 8 * (u32) buffer_desc->buffer.length));
597 status = AE_AML_BUFFER_LIMIT;
598 goto cleanup;
599 }
600
601 /*
602 * Initialize areas of the field object that are common to all fields
603 * For field_flags, use LOCK_RULE = 0 (NO_LOCK),
604 * UPDATE_RULE = 0 (UPDATE_PRESERVE)
605 */
606 status = acpi_ex_prep_common_field_object(obj_desc, field_flags, 0,
607 bit_offset, bit_count);
608 if (ACPI_FAILURE(status)) {
609 goto cleanup;
610 }
611
612 obj_desc->buffer_field.buffer_obj = buffer_desc;
613
614 /* Reference count for buffer_desc inherits obj_desc count */
615
616 buffer_desc->common.reference_count = (u16)
617 (buffer_desc->common.reference_count +
618 obj_desc->common.reference_count);
619
620 cleanup:
621
622 /* Always delete the operands */
623
624 acpi_ut_remove_reference(offset_desc);
625 acpi_ut_remove_reference(buffer_desc);
626
627 if (aml_opcode == AML_CREATE_FIELD_OP) {
628 acpi_ut_remove_reference(length_desc);
629 }
630
631 /* On failure, delete the result descriptor */
632
633 if (ACPI_FAILURE(status)) {
634 acpi_ut_remove_reference(result_desc); /* Result descriptor */
635 } else {
636 /* Now the address and length are valid for this buffer_field */
637
638 obj_desc->buffer_field.flags |= AOPOBJ_DATA_VALID;
639 }
640
641 return_ACPI_STATUS(status);
642}
643
644/*******************************************************************************
645 *
646 * FUNCTION: acpi_ds_eval_buffer_field_operands
647 *
648 * PARAMETERS: walk_state - Current walk
649 * Op - A valid buffer_field Op object
650 *
651 * RETURN: Status
652 *
653 * DESCRIPTION: Get buffer_field Buffer and Index
654 * Called from acpi_ds_exec_end_op during buffer_field parse tree walk
655 *
656 ******************************************************************************/
657
658acpi_status
659acpi_ds_eval_buffer_field_operands(struct acpi_walk_state *walk_state,
660 union acpi_parse_object *op)
661{
662 acpi_status status;
663 union acpi_operand_object *obj_desc;
664 struct acpi_namespace_node *node;
665 union acpi_parse_object *next_op;
666
667 ACPI_FUNCTION_TRACE_PTR(ds_eval_buffer_field_operands, op);
668
669 /*
670 * This is where we evaluate the address and length fields of the
671 * create_xxx_field declaration
672 */
673 node = op->common.node;
674
675 /* next_op points to the op that holds the Buffer */
676
677 next_op = op->common.value.arg;
678
679 /* Evaluate/create the address and length operands */
680
681 status = acpi_ds_create_operands(walk_state, next_op);
682 if (ACPI_FAILURE(status)) {
683 return_ACPI_STATUS(status);
684 }
685
686 obj_desc = acpi_ns_get_attached_object(node);
687 if (!obj_desc) {
688 return_ACPI_STATUS(AE_NOT_EXIST);
689 }
690
691 /* Resolve the operands */
692
693 status = acpi_ex_resolve_operands(op->common.aml_opcode,
694 ACPI_WALK_OPERANDS, walk_state);
695 if (ACPI_FAILURE(status)) {
696 ACPI_ERROR((AE_INFO, "(%s) bad operand(s) (%X)",
697 acpi_ps_get_opcode_name(op->common.aml_opcode),
698 status));
699
700 return_ACPI_STATUS(status);
701 }
702
703 /* Initialize the Buffer Field */
704
705 if (op->common.aml_opcode == AML_CREATE_FIELD_OP) {
706
707 /* NOTE: Slightly different operands for this opcode */
708
709 status =
710 acpi_ds_init_buffer_field(op->common.aml_opcode, obj_desc,
711 walk_state->operands[0],
712 walk_state->operands[1],
713 walk_state->operands[2],
714 walk_state->operands[3]);
715 } else {
716 /* All other, create_xxx_field opcodes */
717
718 status =
719 acpi_ds_init_buffer_field(op->common.aml_opcode, obj_desc,
720 walk_state->operands[0],
721 walk_state->operands[1], NULL,
722 walk_state->operands[2]);
723 }
724
725 return_ACPI_STATUS(status);
726}
727
728/*******************************************************************************
729 *
730 * FUNCTION: acpi_ds_eval_region_operands
731 *
732 * PARAMETERS: walk_state - Current walk
733 * Op - A valid region Op object
734 *
735 * RETURN: Status
736 *
737 * DESCRIPTION: Get region address and length
738 * Called from acpi_ds_exec_end_op during op_region parse tree walk
739 *
740 ******************************************************************************/
741
742acpi_status
743acpi_ds_eval_region_operands(struct acpi_walk_state *walk_state,
744 union acpi_parse_object *op)
745{
746 acpi_status status;
747 union acpi_operand_object *obj_desc;
748 union acpi_operand_object *operand_desc;
749 struct acpi_namespace_node *node;
750 union acpi_parse_object *next_op;
751
752 ACPI_FUNCTION_TRACE_PTR(ds_eval_region_operands, op);
753
754 /*
755 * This is where we evaluate the address and length fields of the
756 * op_region declaration
757 */
758 node = op->common.node;
759
760 /* next_op points to the op that holds the space_iD */
761
762 next_op = op->common.value.arg;
763
764 /* next_op points to address op */
765
766 next_op = next_op->common.next;
767
768 /* Evaluate/create the address and length operands */
769
770 status = acpi_ds_create_operands(walk_state, next_op);
771 if (ACPI_FAILURE(status)) {
772 return_ACPI_STATUS(status);
773 }
774
775 /* Resolve the length and address operands to numbers */
776
777 status = acpi_ex_resolve_operands(op->common.aml_opcode,
778 ACPI_WALK_OPERANDS, walk_state);
779 if (ACPI_FAILURE(status)) {
780 return_ACPI_STATUS(status);
781 }
782
783 obj_desc = acpi_ns_get_attached_object(node);
784 if (!obj_desc) {
785 return_ACPI_STATUS(AE_NOT_EXIST);
786 }
787
788 /*
789 * Get the length operand and save it
790 * (at Top of stack)
791 */
792 operand_desc = walk_state->operands[walk_state->num_operands - 1];
793
794 obj_desc->region.length = (u32) operand_desc->integer.value;
795 acpi_ut_remove_reference(operand_desc);
796
797 /*
798 * Get the address and save it
799 * (at top of stack - 1)
800 */
801 operand_desc = walk_state->operands[walk_state->num_operands - 2];
802
803 obj_desc->region.address = (acpi_physical_address)
804 operand_desc->integer.value;
805 acpi_ut_remove_reference(operand_desc);
806
807 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n",
808 obj_desc,
809 ACPI_FORMAT_NATIVE_UINT(obj_desc->region.address),
810 obj_desc->region.length));
811
812 /* Now the address and length are valid for this opregion */
813
814 obj_desc->region.flags |= AOPOBJ_DATA_VALID;
815
816 return_ACPI_STATUS(status);
817}
818
819/*******************************************************************************
820 *
821 * FUNCTION: acpi_ds_eval_table_region_operands
822 *
823 * PARAMETERS: walk_state - Current walk
824 * Op - A valid region Op object
825 *
826 * RETURN: Status
827 *
828 * DESCRIPTION: Get region address and length
829 * Called from acpi_ds_exec_end_op during data_table_region parse tree walk
830 *
831 ******************************************************************************/
832
833acpi_status
834acpi_ds_eval_table_region_operands(struct acpi_walk_state *walk_state,
835 union acpi_parse_object *op)
836{
837 acpi_status status;
838 union acpi_operand_object *obj_desc;
839 union acpi_operand_object **operand;
840 struct acpi_namespace_node *node;
841 union acpi_parse_object *next_op;
842 u32 table_index;
843 struct acpi_table_header *table;
844
845 ACPI_FUNCTION_TRACE_PTR(ds_eval_table_region_operands, op);
846
847 /*
848 * This is where we evaluate the signature_string and oem_iDString
849 * and oem_table_iDString of the data_table_region declaration
850 */
851 node = op->common.node;
852
853 /* next_op points to signature_string op */
854
855 next_op = op->common.value.arg;
856
857 /*
858 * Evaluate/create the signature_string and oem_iDString
859 * and oem_table_iDString operands
860 */
861 status = acpi_ds_create_operands(walk_state, next_op);
862 if (ACPI_FAILURE(status)) {
863 return_ACPI_STATUS(status);
864 }
865
866 /*
867 * Resolve the signature_string and oem_iDString
868 * and oem_table_iDString operands
869 */
870 status = acpi_ex_resolve_operands(op->common.aml_opcode,
871 ACPI_WALK_OPERANDS, walk_state);
872 if (ACPI_FAILURE(status)) {
873 return_ACPI_STATUS(status);
874 }
875
876 operand = &walk_state->operands[0];
877
878 /* Find the ACPI table */
879
880 status = acpi_tb_find_table(operand[0]->string.pointer,
881 operand[1]->string.pointer,
882 operand[2]->string.pointer, &table_index);
883 if (ACPI_FAILURE(status)) {
884 return_ACPI_STATUS(status);
885 }
886
887 acpi_ut_remove_reference(operand[0]);
888 acpi_ut_remove_reference(operand[1]);
889 acpi_ut_remove_reference(operand[2]);
890
891 status = acpi_get_table_by_index(table_index, &table);
892 if (ACPI_FAILURE(status)) {
893 return_ACPI_STATUS(status);
894 }
895
896 obj_desc = acpi_ns_get_attached_object(node);
897 if (!obj_desc) {
898 return_ACPI_STATUS(AE_NOT_EXIST);
899 }
900
901 obj_desc->region.address =
902 (acpi_physical_address) ACPI_TO_INTEGER(table);
903 obj_desc->region.length = table->length;
904
905 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n",
906 obj_desc,
907 ACPI_FORMAT_NATIVE_UINT(obj_desc->region.address),
908 obj_desc->region.length));
909
910 /* Now the address and length are valid for this opregion */
911
912 obj_desc->region.flags |= AOPOBJ_DATA_VALID;
913
914 return_ACPI_STATUS(status);
915}
916
917/*******************************************************************************
918 *
919 * FUNCTION: acpi_ds_eval_data_object_operands
920 *
921 * PARAMETERS: walk_state - Current walk
922 * Op - A valid data_object Op object
923 * obj_desc - data_object
924 *
925 * RETURN: Status
926 *
927 * DESCRIPTION: Get the operands and complete the following data object types:
928 * Buffer, Package.
929 *
930 ******************************************************************************/
931
932acpi_status
933acpi_ds_eval_data_object_operands(struct acpi_walk_state *walk_state,
934 union acpi_parse_object *op,
935 union acpi_operand_object *obj_desc)
936{
937 acpi_status status;
938 union acpi_operand_object *arg_desc;
939 u32 length;
940
941 ACPI_FUNCTION_TRACE(ds_eval_data_object_operands);
942
943 /* The first operand (for all of these data objects) is the length */
944
945 /*
946 * Set proper index into operand stack for acpi_ds_obj_stack_push
947 * invoked inside acpi_ds_create_operand.
948 */
949 walk_state->operand_index = walk_state->num_operands;
950
951 status = acpi_ds_create_operand(walk_state, op->common.value.arg, 1);
952 if (ACPI_FAILURE(status)) {
953 return_ACPI_STATUS(status);
954 }
955
956 status = acpi_ex_resolve_operands(walk_state->opcode,
957 &(walk_state->
958 operands[walk_state->num_operands -
959 1]), walk_state);
960 if (ACPI_FAILURE(status)) {
961 return_ACPI_STATUS(status);
962 }
963
964 /* Extract length operand */
965
966 arg_desc = walk_state->operands[walk_state->num_operands - 1];
967 length = (u32) arg_desc->integer.value;
968
969 /* Cleanup for length operand */
970
971 status = acpi_ds_obj_stack_pop(1, walk_state);
972 if (ACPI_FAILURE(status)) {
973 return_ACPI_STATUS(status);
974 }
975
976 acpi_ut_remove_reference(arg_desc);
977
978 /*
979 * Create the actual data object
980 */
981 switch (op->common.aml_opcode) {
982 case AML_BUFFER_OP:
983
984 status =
985 acpi_ds_build_internal_buffer_obj(walk_state, op, length,
986 &obj_desc);
987 break;
988
989 case AML_PACKAGE_OP:
990 case AML_VAR_PACKAGE_OP:
991
992 status =
993 acpi_ds_build_internal_package_obj(walk_state, op, length,
994 &obj_desc);
995 break;
996
997 default:
998 return_ACPI_STATUS(AE_AML_BAD_OPCODE);
999 }
1000
1001 if (ACPI_SUCCESS(status)) {
1002 /*
1003 * Return the object in the walk_state, unless the parent is a package -
1004 * in this case, the return object will be stored in the parse tree
1005 * for the package.
1006 */
1007 if ((!op->common.parent) ||
1008 ((op->common.parent->common.aml_opcode != AML_PACKAGE_OP) &&
1009 (op->common.parent->common.aml_opcode !=
1010 AML_VAR_PACKAGE_OP)
1011 && (op->common.parent->common.aml_opcode != AML_NAME_OP))) {
1012 walk_state->result_obj = obj_desc;
1013 }
1014 }
1015
1016 return_ACPI_STATUS(status);
1017}
1018
1019/*******************************************************************************
1020 *
1021 * FUNCTION: acpi_ds_eval_bank_field_operands
1022 *
1023 * PARAMETERS: walk_state - Current walk
1024 * Op - A valid bank_field Op object
1025 *
1026 * RETURN: Status
1027 *
1028 * DESCRIPTION: Get bank_field bank_value
1029 * Called from acpi_ds_exec_end_op during bank_field parse tree walk
1030 *
1031 ******************************************************************************/
1032
1033acpi_status
1034acpi_ds_eval_bank_field_operands(struct acpi_walk_state *walk_state,
1035 union acpi_parse_object *op)
1036{
1037 acpi_status status;
1038 union acpi_operand_object *obj_desc;
1039 union acpi_operand_object *operand_desc;
1040 struct acpi_namespace_node *node;
1041 union acpi_parse_object *next_op;
1042 union acpi_parse_object *arg;
1043
1044 ACPI_FUNCTION_TRACE_PTR(ds_eval_bank_field_operands, op);
1045
1046 /*
1047 * This is where we evaluate the bank_value field of the
1048 * bank_field declaration
1049 */
1050
1051 /* next_op points to the op that holds the Region */
1052
1053 next_op = op->common.value.arg;
1054
1055 /* next_op points to the op that holds the Bank Register */
1056
1057 next_op = next_op->common.next;
1058
1059 /* next_op points to the op that holds the Bank Value */
1060
1061 next_op = next_op->common.next;
1062
1063 /*
1064 * Set proper index into operand stack for acpi_ds_obj_stack_push
1065 * invoked inside acpi_ds_create_operand.
1066 *
1067 * We use walk_state->Operands[0] to store the evaluated bank_value
1068 */
1069 walk_state->operand_index = 0;
1070
1071 status = acpi_ds_create_operand(walk_state, next_op, 0);
1072 if (ACPI_FAILURE(status)) {
1073 return_ACPI_STATUS(status);
1074 }
1075
1076 status = acpi_ex_resolve_to_value(&walk_state->operands[0], walk_state);
1077 if (ACPI_FAILURE(status)) {
1078 return_ACPI_STATUS(status);
1079 }
1080
1081 ACPI_DUMP_OPERANDS(ACPI_WALK_OPERANDS,
1082 acpi_ps_get_opcode_name(op->common.aml_opcode), 1);
1083 /*
1084 * Get the bank_value operand and save it
1085 * (at Top of stack)
1086 */
1087 operand_desc = walk_state->operands[0];
1088
1089 /* Arg points to the start Bank Field */
1090
1091 arg = acpi_ps_get_arg(op, 4);
1092 while (arg) {
1093
1094 /* Ignore OFFSET and ACCESSAS terms here */
1095
1096 if (arg->common.aml_opcode == AML_INT_NAMEDFIELD_OP) {
1097 node = arg->common.node;
1098
1099 obj_desc = acpi_ns_get_attached_object(node);
1100 if (!obj_desc) {
1101 return_ACPI_STATUS(AE_NOT_EXIST);
1102 }
1103
1104 obj_desc->bank_field.value =
1105 (u32) operand_desc->integer.value;
1106 }
1107
1108 /* Move to next field in the list */
1109
1110 arg = arg->common.next;
1111 }
1112
1113 acpi_ut_remove_reference(operand_desc);
1114 return_ACPI_STATUS(status);
1115}
1116
1117/*******************************************************************************
1118 *
1119 * FUNCTION: acpi_ds_exec_begin_control_op
1120 *
1121 * PARAMETERS: walk_list - The list that owns the walk stack
1122 * Op - The control Op
1123 *
1124 * RETURN: Status
1125 *
1126 * DESCRIPTION: Handles all control ops encountered during control method
1127 * execution.
1128 *
1129 ******************************************************************************/
1130
1131acpi_status
1132acpi_ds_exec_begin_control_op(struct acpi_walk_state *walk_state,
1133 union acpi_parse_object *op)
1134{
1135 acpi_status status = AE_OK;
1136 union acpi_generic_state *control_state;
1137
1138 ACPI_FUNCTION_NAME(ds_exec_begin_control_op);
1139
1140 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Op=%p Opcode=%2.2X State=%p\n", op,
1141 op->common.aml_opcode, walk_state));
1142
1143 switch (op->common.aml_opcode) {
1144 case AML_WHILE_OP:
1145
1146 /*
1147 * If this is an additional iteration of a while loop, continue.
1148 * There is no need to allocate a new control state.
1149 */
1150 if (walk_state->control_state) {
1151 if (walk_state->control_state->control.aml_predicate_start
1152 == (walk_state->parser_state.aml - 1)) {
1153
1154 /* Reset the state to start-of-loop */
1155
1156 walk_state->control_state->common.state =
1157 ACPI_CONTROL_CONDITIONAL_EXECUTING;
1158 break;
1159 }
1160 }
1161
1162 /*lint -fallthrough */
1163
1164 case AML_IF_OP:
1165
1166 /*
1167 * IF/WHILE: Create a new control state to manage these
1168 * constructs. We need to manage these as a stack, in order
1169 * to handle nesting.
1170 */
1171 control_state = acpi_ut_create_control_state();
1172 if (!control_state) {
1173 status = AE_NO_MEMORY;
1174 break;
1175 }
1176 /*
1177 * Save a pointer to the predicate for multiple executions
1178 * of a loop
1179 */
1180 control_state->control.aml_predicate_start =
1181 walk_state->parser_state.aml - 1;
1182 control_state->control.package_end =
1183 walk_state->parser_state.pkg_end;
1184 control_state->control.opcode = op->common.aml_opcode;
1185
1186 /* Push the control state on this walk's control stack */
1187
1188 acpi_ut_push_generic_state(&walk_state->control_state,
1189 control_state);
1190 break;
1191
1192 case AML_ELSE_OP:
1193
1194 /* Predicate is in the state object */
1195 /* If predicate is true, the IF was executed, ignore ELSE part */
1196
1197 if (walk_state->last_predicate) {
1198 status = AE_CTRL_TRUE;
1199 }
1200
1201 break;
1202
1203 case AML_RETURN_OP:
1204
1205 break;
1206
1207 default:
1208 break;
1209 }
1210
1211 return (status);
1212}
1213
1214/*******************************************************************************
1215 *
1216 * FUNCTION: acpi_ds_exec_end_control_op
1217 *
1218 * PARAMETERS: walk_list - The list that owns the walk stack
1219 * Op - The control Op
1220 *
1221 * RETURN: Status
1222 *
1223 * DESCRIPTION: Handles all control ops encountered during control method
1224 * execution.
1225 *
1226 ******************************************************************************/
1227
1228acpi_status
1229acpi_ds_exec_end_control_op(struct acpi_walk_state * walk_state,
1230 union acpi_parse_object * op)
1231{
1232 acpi_status status = AE_OK;
1233 union acpi_generic_state *control_state;
1234
1235 ACPI_FUNCTION_NAME(ds_exec_end_control_op);
1236
1237 switch (op->common.aml_opcode) {
1238 case AML_IF_OP:
1239
1240 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "[IF_OP] Op=%p\n", op));
1241
1242 /*
1243 * Save the result of the predicate in case there is an
1244 * ELSE to come
1245 */
1246 walk_state->last_predicate =
1247 (u8) walk_state->control_state->common.value;
1248
1249 /*
1250 * Pop the control state that was created at the start
1251 * of the IF and free it
1252 */
1253 control_state =
1254 acpi_ut_pop_generic_state(&walk_state->control_state);
1255 acpi_ut_delete_generic_state(control_state);
1256 break;
1257
1258 case AML_ELSE_OP:
1259
1260 break;
1261
1262 case AML_WHILE_OP:
1263
1264 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "[WHILE_OP] Op=%p\n", op));
1265
1266 control_state = walk_state->control_state;
1267 if (control_state->common.value) {
1268
1269 /* Predicate was true, the body of the loop was just executed */
1270
1271 /*
1272 * This loop counter mechanism allows the interpreter to escape
1273 * possibly infinite loops. This can occur in poorly written AML
1274 * when the hardware does not respond within a while loop and the
1275 * loop does not implement a timeout.
1276 */
1277 control_state->control.loop_count++;
1278 if (control_state->control.loop_count >
1279 ACPI_MAX_LOOP_ITERATIONS) {
1280 status = AE_AML_INFINITE_LOOP;
1281 break;
1282 }
1283
1284 /*
1285 * Go back and evaluate the predicate and maybe execute the loop
1286 * another time
1287 */
1288 status = AE_CTRL_PENDING;
1289 walk_state->aml_last_while =
1290 control_state->control.aml_predicate_start;
1291 break;
1292 }
1293
1294 /* Predicate was false, terminate this while loop */
1295
1296 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
1297 "[WHILE_OP] termination! Op=%p\n", op));
1298
1299 /* Pop this control state and free it */
1300
1301 control_state =
1302 acpi_ut_pop_generic_state(&walk_state->control_state);
1303 acpi_ut_delete_generic_state(control_state);
1304 break;
1305
1306 case AML_RETURN_OP:
1307
1308 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
1309 "[RETURN_OP] Op=%p Arg=%p\n", op,
1310 op->common.value.arg));
1311
1312 /*
1313 * One optional operand -- the return value
1314 * It can be either an immediate operand or a result that
1315 * has been bubbled up the tree
1316 */
1317 if (op->common.value.arg) {
1318
1319 /* Since we have a real Return(), delete any implicit return */
1320
1321 acpi_ds_clear_implicit_return(walk_state);
1322
1323 /* Return statement has an immediate operand */
1324
1325 status =
1326 acpi_ds_create_operands(walk_state,
1327 op->common.value.arg);
1328 if (ACPI_FAILURE(status)) {
1329 return (status);
1330 }
1331
1332 /*
1333 * If value being returned is a Reference (such as
1334 * an arg or local), resolve it now because it may
1335 * cease to exist at the end of the method.
1336 */
1337 status =
1338 acpi_ex_resolve_to_value(&walk_state->operands[0],
1339 walk_state);
1340 if (ACPI_FAILURE(status)) {
1341 return (status);
1342 }
1343
1344 /*
1345 * Get the return value and save as the last result
1346 * value. This is the only place where walk_state->return_desc
1347 * is set to anything other than zero!
1348 */
1349 walk_state->return_desc = walk_state->operands[0];
1350 } else if (walk_state->result_count) {
1351
1352 /* Since we have a real Return(), delete any implicit return */
1353
1354 acpi_ds_clear_implicit_return(walk_state);
1355
1356 /*
1357 * The return value has come from a previous calculation.
1358 *
1359 * If value being returned is a Reference (such as
1360 * an arg or local), resolve it now because it may
1361 * cease to exist at the end of the method.
1362 *
1363 * Allow references created by the Index operator to return unchanged.
1364 */
1365 if ((ACPI_GET_DESCRIPTOR_TYPE
1366 (walk_state->results->results.obj_desc[0]) ==
1367 ACPI_DESC_TYPE_OPERAND)
1368 &&
1369 (ACPI_GET_OBJECT_TYPE
1370 (walk_state->results->results.obj_desc[0]) ==
1371 ACPI_TYPE_LOCAL_REFERENCE)
1372 && ((walk_state->results->results.obj_desc[0])->
1373 reference.class != ACPI_REFCLASS_INDEX)) {
1374 status =
1375 acpi_ex_resolve_to_value(&walk_state->
1376 results->results.
1377 obj_desc[0],
1378 walk_state);
1379 if (ACPI_FAILURE(status)) {
1380 return (status);
1381 }
1382 }
1383
1384 walk_state->return_desc =
1385 walk_state->results->results.obj_desc[0];
1386 } else {
1387 /* No return operand */
1388
1389 if (walk_state->num_operands) {
1390 acpi_ut_remove_reference(walk_state->
1391 operands[0]);
1392 }
1393
1394 walk_state->operands[0] = NULL;
1395 walk_state->num_operands = 0;
1396 walk_state->return_desc = NULL;
1397 }
1398
1399 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
1400 "Completed RETURN_OP State=%p, RetVal=%p\n",
1401 walk_state, walk_state->return_desc));
1402
1403 /* End the control method execution right now */
1404
1405 status = AE_CTRL_TERMINATE;
1406 break;
1407
1408 case AML_NOOP_OP:
1409
1410 /* Just do nothing! */
1411 break;
1412
1413 case AML_BREAK_POINT_OP:
1414
1415 /* Call up to the OS service layer to handle this */
1416
1417 status =
1418 acpi_os_signal(ACPI_SIGNAL_BREAKPOINT,
1419 "Executed AML Breakpoint opcode");
1420
1421 /* If and when it returns, all done. */
1422
1423 break;
1424
1425 case AML_BREAK_OP:
1426 case AML_CONTINUE_OP: /* ACPI 2.0 */
1427
1428 /* Pop and delete control states until we find a while */
1429
1430 while (walk_state->control_state &&
1431 (walk_state->control_state->control.opcode !=
1432 AML_WHILE_OP)) {
1433 control_state =
1434 acpi_ut_pop_generic_state(&walk_state->
1435 control_state);
1436 acpi_ut_delete_generic_state(control_state);
1437 }
1438
1439 /* No while found? */
1440
1441 if (!walk_state->control_state) {
1442 return (AE_AML_NO_WHILE);
1443 }
1444
1445 /* Was: walk_state->aml_last_while = walk_state->control_state->Control.aml_predicate_start; */
1446
1447 walk_state->aml_last_while =
1448 walk_state->control_state->control.package_end;
1449
1450 /* Return status depending on opcode */
1451
1452 if (op->common.aml_opcode == AML_BREAK_OP) {
1453 status = AE_CTRL_BREAK;
1454 } else {
1455 status = AE_CTRL_CONTINUE;
1456 }
1457 break;
1458
1459 default:
1460
1461 ACPI_ERROR((AE_INFO, "Unknown control opcode=%X Op=%p",
1462 op->common.aml_opcode, op));
1463
1464 status = AE_AML_BAD_OPCODE;
1465 break;
1466 }
1467
1468 return (status);
1469}
diff --git a/drivers/acpi/acpica/dsutils.c b/drivers/acpi/acpica/dsutils.c
new file mode 100644
index 00000000000..9c88846ca2c
--- /dev/null
+++ b/drivers/acpi/acpica/dsutils.c
@@ -0,0 +1,869 @@
1/*******************************************************************************
2 *
3 * Module Name: dsutils - Dispatcher utilities
4 *
5 ******************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46#include <acpi/acparser.h>
47#include <acpi/amlcode.h>
48#include <acpi/acdispat.h>
49#include <acpi/acinterp.h>
50#include <acpi/acnamesp.h>
51#include <acpi/acdebug.h>
52
53#define _COMPONENT ACPI_DISPATCHER
54ACPI_MODULE_NAME("dsutils")
55
56/*******************************************************************************
57 *
58 * FUNCTION: acpi_ds_clear_implicit_return
59 *
60 * PARAMETERS: walk_state - Current State
61 *
62 * RETURN: None.
63 *
64 * DESCRIPTION: Clear and remove a reference on an implicit return value. Used
65 * to delete "stale" return values (if enabled, the return value
66 * from every operator is saved at least momentarily, in case the
67 * parent method exits.)
68 *
69 ******************************************************************************/
70void acpi_ds_clear_implicit_return(struct acpi_walk_state *walk_state)
71{
72 ACPI_FUNCTION_NAME(ds_clear_implicit_return);
73
74 /*
75 * Slack must be enabled for this feature
76 */
77 if (!acpi_gbl_enable_interpreter_slack) {
78 return;
79 }
80
81 if (walk_state->implicit_return_obj) {
82 /*
83 * Delete any "stale" implicit return. However, in
84 * complex statements, the implicit return value can be
85 * bubbled up several levels.
86 */
87 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
88 "Removing reference on stale implicit return obj %p\n",
89 walk_state->implicit_return_obj));
90
91 acpi_ut_remove_reference(walk_state->implicit_return_obj);
92 walk_state->implicit_return_obj = NULL;
93 }
94}
95
96#ifndef ACPI_NO_METHOD_EXECUTION
97/*******************************************************************************
98 *
99 * FUNCTION: acpi_ds_do_implicit_return
100 *
101 * PARAMETERS: return_desc - The return value
102 * walk_state - Current State
103 * add_reference - True if a reference should be added to the
104 * return object
105 *
106 * RETURN: TRUE if implicit return enabled, FALSE otherwise
107 *
108 * DESCRIPTION: Implements the optional "implicit return". We save the result
109 * of every ASL operator and control method invocation in case the
110 * parent method exit. Before storing a new return value, we
111 * delete the previous return value.
112 *
113 ******************************************************************************/
114
115u8
116acpi_ds_do_implicit_return(union acpi_operand_object *return_desc,
117 struct acpi_walk_state *walk_state, u8 add_reference)
118{
119 ACPI_FUNCTION_NAME(ds_do_implicit_return);
120
121 /*
122 * Slack must be enabled for this feature, and we must
123 * have a valid return object
124 */
125 if ((!acpi_gbl_enable_interpreter_slack) || (!return_desc)) {
126 return (FALSE);
127 }
128
129 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
130 "Result %p will be implicitly returned; Prev=%p\n",
131 return_desc, walk_state->implicit_return_obj));
132
133 /*
134 * Delete any "stale" implicit return value first. However, in
135 * complex statements, the implicit return value can be
136 * bubbled up several levels, so we don't clear the value if it
137 * is the same as the return_desc.
138 */
139 if (walk_state->implicit_return_obj) {
140 if (walk_state->implicit_return_obj == return_desc) {
141 return (TRUE);
142 }
143 acpi_ds_clear_implicit_return(walk_state);
144 }
145
146 /* Save the implicit return value, add a reference if requested */
147
148 walk_state->implicit_return_obj = return_desc;
149 if (add_reference) {
150 acpi_ut_add_reference(return_desc);
151 }
152
153 return (TRUE);
154}
155
156/*******************************************************************************
157 *
158 * FUNCTION: acpi_ds_is_result_used
159 *
160 * PARAMETERS: Op - Current Op
161 * walk_state - Current State
162 *
163 * RETURN: TRUE if result is used, FALSE otherwise
164 *
165 * DESCRIPTION: Check if a result object will be used by the parent
166 *
167 ******************************************************************************/
168
169u8
170acpi_ds_is_result_used(union acpi_parse_object * op,
171 struct acpi_walk_state * walk_state)
172{
173 const struct acpi_opcode_info *parent_info;
174
175 ACPI_FUNCTION_TRACE_PTR(ds_is_result_used, op);
176
177 /* Must have both an Op and a Result Object */
178
179 if (!op) {
180 ACPI_ERROR((AE_INFO, "Null Op"));
181 return_UINT8(TRUE);
182 }
183
184 /*
185 * We know that this operator is not a
186 * Return() operator (would not come here.) The following code is the
187 * optional support for a so-called "implicit return". Some AML code
188 * assumes that the last value of the method is "implicitly" returned
189 * to the caller. Just save the last result as the return value.
190 * NOTE: this is optional because the ASL language does not actually
191 * support this behavior.
192 */
193 (void)acpi_ds_do_implicit_return(walk_state->result_obj, walk_state,
194 TRUE);
195
196 /*
197 * Now determine if the parent will use the result
198 *
199 * If there is no parent, or the parent is a scope_op, we are executing
200 * at the method level. An executing method typically has no parent,
201 * since each method is parsed separately. A method invoked externally
202 * via execute_control_method has a scope_op as the parent.
203 */
204 if ((!op->common.parent) ||
205 (op->common.parent->common.aml_opcode == AML_SCOPE_OP)) {
206
207 /* No parent, the return value cannot possibly be used */
208
209 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
210 "At Method level, result of [%s] not used\n",
211 acpi_ps_get_opcode_name(op->common.
212 aml_opcode)));
213 return_UINT8(FALSE);
214 }
215
216 /* Get info on the parent. The root_op is AML_SCOPE */
217
218 parent_info =
219 acpi_ps_get_opcode_info(op->common.parent->common.aml_opcode);
220 if (parent_info->class == AML_CLASS_UNKNOWN) {
221 ACPI_ERROR((AE_INFO, "Unknown parent opcode Op=%p", op));
222 return_UINT8(FALSE);
223 }
224
225 /*
226 * Decide what to do with the result based on the parent. If
227 * the parent opcode will not use the result, delete the object.
228 * Otherwise leave it as is, it will be deleted when it is used
229 * as an operand later.
230 */
231 switch (parent_info->class) {
232 case AML_CLASS_CONTROL:
233
234 switch (op->common.parent->common.aml_opcode) {
235 case AML_RETURN_OP:
236
237 /* Never delete the return value associated with a return opcode */
238
239 goto result_used;
240
241 case AML_IF_OP:
242 case AML_WHILE_OP:
243
244 /*
245 * If we are executing the predicate AND this is the predicate op,
246 * we will use the return value
247 */
248 if ((walk_state->control_state->common.state ==
249 ACPI_CONTROL_PREDICATE_EXECUTING)
250 && (walk_state->control_state->control.
251 predicate_op == op)) {
252 goto result_used;
253 }
254 break;
255
256 default:
257 /* Ignore other control opcodes */
258 break;
259 }
260
261 /* The general control opcode returns no result */
262
263 goto result_not_used;
264
265 case AML_CLASS_CREATE:
266
267 /*
268 * These opcodes allow term_arg(s) as operands and therefore
269 * the operands can be method calls. The result is used.
270 */
271 goto result_used;
272
273 case AML_CLASS_NAMED_OBJECT:
274
275 if ((op->common.parent->common.aml_opcode == AML_REGION_OP) ||
276 (op->common.parent->common.aml_opcode == AML_DATA_REGION_OP)
277 || (op->common.parent->common.aml_opcode == AML_PACKAGE_OP)
278 || (op->common.parent->common.aml_opcode ==
279 AML_VAR_PACKAGE_OP)
280 || (op->common.parent->common.aml_opcode == AML_BUFFER_OP)
281 || (op->common.parent->common.aml_opcode ==
282 AML_INT_EVAL_SUBTREE_OP)
283 || (op->common.parent->common.aml_opcode ==
284 AML_BANK_FIELD_OP)) {
285 /*
286 * These opcodes allow term_arg(s) as operands and therefore
287 * the operands can be method calls. The result is used.
288 */
289 goto result_used;
290 }
291
292 goto result_not_used;
293
294 default:
295
296 /*
297 * In all other cases. the parent will actually use the return
298 * object, so keep it.
299 */
300 goto result_used;
301 }
302
303 result_used:
304 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
305 "Result of [%s] used by Parent [%s] Op=%p\n",
306 acpi_ps_get_opcode_name(op->common.aml_opcode),
307 acpi_ps_get_opcode_name(op->common.parent->common.
308 aml_opcode), op));
309
310 return_UINT8(TRUE);
311
312 result_not_used:
313 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
314 "Result of [%s] not used by Parent [%s] Op=%p\n",
315 acpi_ps_get_opcode_name(op->common.aml_opcode),
316 acpi_ps_get_opcode_name(op->common.parent->common.
317 aml_opcode), op));
318
319 return_UINT8(FALSE);
320}
321
322/*******************************************************************************
323 *
324 * FUNCTION: acpi_ds_delete_result_if_not_used
325 *
326 * PARAMETERS: Op - Current parse Op
327 * result_obj - Result of the operation
328 * walk_state - Current state
329 *
330 * RETURN: Status
331 *
332 * DESCRIPTION: Used after interpretation of an opcode. If there is an internal
333 * result descriptor, check if the parent opcode will actually use
334 * this result. If not, delete the result now so that it will
335 * not become orphaned.
336 *
337 ******************************************************************************/
338
339void
340acpi_ds_delete_result_if_not_used(union acpi_parse_object *op,
341 union acpi_operand_object *result_obj,
342 struct acpi_walk_state *walk_state)
343{
344 union acpi_operand_object *obj_desc;
345 acpi_status status;
346
347 ACPI_FUNCTION_TRACE_PTR(ds_delete_result_if_not_used, result_obj);
348
349 if (!op) {
350 ACPI_ERROR((AE_INFO, "Null Op"));
351 return_VOID;
352 }
353
354 if (!result_obj) {
355 return_VOID;
356 }
357
358 if (!acpi_ds_is_result_used(op, walk_state)) {
359
360 /* Must pop the result stack (obj_desc should be equal to result_obj) */
361
362 status = acpi_ds_result_pop(&obj_desc, walk_state);
363 if (ACPI_SUCCESS(status)) {
364 acpi_ut_remove_reference(result_obj);
365 }
366 }
367
368 return_VOID;
369}
370
371/*******************************************************************************
372 *
373 * FUNCTION: acpi_ds_resolve_operands
374 *
375 * PARAMETERS: walk_state - Current walk state with operands on stack
376 *
377 * RETURN: Status
378 *
379 * DESCRIPTION: Resolve all operands to their values. Used to prepare
380 * arguments to a control method invocation (a call from one
381 * method to another.)
382 *
383 ******************************************************************************/
384
385acpi_status acpi_ds_resolve_operands(struct acpi_walk_state *walk_state)
386{
387 u32 i;
388 acpi_status status = AE_OK;
389
390 ACPI_FUNCTION_TRACE_PTR(ds_resolve_operands, walk_state);
391
392 /*
393 * Attempt to resolve each of the valid operands
394 * Method arguments are passed by reference, not by value. This means
395 * that the actual objects are passed, not copies of the objects.
396 */
397 for (i = 0; i < walk_state->num_operands; i++) {
398 status =
399 acpi_ex_resolve_to_value(&walk_state->operands[i],
400 walk_state);
401 if (ACPI_FAILURE(status)) {
402 break;
403 }
404 }
405
406 return_ACPI_STATUS(status);
407}
408
409/*******************************************************************************
410 *
411 * FUNCTION: acpi_ds_clear_operands
412 *
413 * PARAMETERS: walk_state - Current walk state with operands on stack
414 *
415 * RETURN: None
416 *
417 * DESCRIPTION: Clear all operands on the current walk state operand stack.
418 *
419 ******************************************************************************/
420
421void acpi_ds_clear_operands(struct acpi_walk_state *walk_state)
422{
423 u32 i;
424
425 ACPI_FUNCTION_TRACE_PTR(ds_clear_operands, walk_state);
426
427 /* Remove a reference on each operand on the stack */
428
429 for (i = 0; i < walk_state->num_operands; i++) {
430 /*
431 * Remove a reference to all operands, including both
432 * "Arguments" and "Targets".
433 */
434 acpi_ut_remove_reference(walk_state->operands[i]);
435 walk_state->operands[i] = NULL;
436 }
437
438 walk_state->num_operands = 0;
439 return_VOID;
440}
441#endif
442
443/*******************************************************************************
444 *
445 * FUNCTION: acpi_ds_create_operand
446 *
447 * PARAMETERS: walk_state - Current walk state
448 * Arg - Parse object for the argument
449 * arg_index - Which argument (zero based)
450 *
451 * RETURN: Status
452 *
453 * DESCRIPTION: Translate a parse tree object that is an argument to an AML
454 * opcode to the equivalent interpreter object. This may include
455 * looking up a name or entering a new name into the internal
456 * namespace.
457 *
458 ******************************************************************************/
459
460acpi_status
461acpi_ds_create_operand(struct acpi_walk_state *walk_state,
462 union acpi_parse_object *arg, u32 arg_index)
463{
464 acpi_status status = AE_OK;
465 char *name_string;
466 u32 name_length;
467 union acpi_operand_object *obj_desc;
468 union acpi_parse_object *parent_op;
469 u16 opcode;
470 acpi_interpreter_mode interpreter_mode;
471 const struct acpi_opcode_info *op_info;
472
473 ACPI_FUNCTION_TRACE_PTR(ds_create_operand, arg);
474
475 /* A valid name must be looked up in the namespace */
476
477 if ((arg->common.aml_opcode == AML_INT_NAMEPATH_OP) &&
478 (arg->common.value.string) &&
479 !(arg->common.flags & ACPI_PARSEOP_IN_STACK)) {
480 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Getting a name: Arg=%p\n",
481 arg));
482
483 /* Get the entire name string from the AML stream */
484
485 status =
486 acpi_ex_get_name_string(ACPI_TYPE_ANY,
487 arg->common.value.buffer,
488 &name_string, &name_length);
489
490 if (ACPI_FAILURE(status)) {
491 return_ACPI_STATUS(status);
492 }
493
494 /* All prefixes have been handled, and the name is in name_string */
495
496 /*
497 * Special handling for buffer_field declarations. This is a deferred
498 * opcode that unfortunately defines the field name as the last
499 * parameter instead of the first. We get here when we are performing
500 * the deferred execution, so the actual name of the field is already
501 * in the namespace. We don't want to attempt to look it up again
502 * because we may be executing in a different scope than where the
503 * actual opcode exists.
504 */
505 if ((walk_state->deferred_node) &&
506 (walk_state->deferred_node->type == ACPI_TYPE_BUFFER_FIELD)
507 && (arg_index ==
508 (u32) ((walk_state->opcode ==
509 AML_CREATE_FIELD_OP) ? 3 : 2))) {
510 obj_desc =
511 ACPI_CAST_PTR(union acpi_operand_object,
512 walk_state->deferred_node);
513 status = AE_OK;
514 } else { /* All other opcodes */
515
516 /*
517 * Differentiate between a namespace "create" operation
518 * versus a "lookup" operation (IMODE_LOAD_PASS2 vs.
519 * IMODE_EXECUTE) in order to support the creation of
520 * namespace objects during the execution of control methods.
521 */
522 parent_op = arg->common.parent;
523 op_info =
524 acpi_ps_get_opcode_info(parent_op->common.
525 aml_opcode);
526 if ((op_info->flags & AML_NSNODE)
527 && (parent_op->common.aml_opcode !=
528 AML_INT_METHODCALL_OP)
529 && (parent_op->common.aml_opcode != AML_REGION_OP)
530 && (parent_op->common.aml_opcode !=
531 AML_INT_NAMEPATH_OP)) {
532
533 /* Enter name into namespace if not found */
534
535 interpreter_mode = ACPI_IMODE_LOAD_PASS2;
536 } else {
537 /* Return a failure if name not found */
538
539 interpreter_mode = ACPI_IMODE_EXECUTE;
540 }
541
542 status =
543 acpi_ns_lookup(walk_state->scope_info, name_string,
544 ACPI_TYPE_ANY, interpreter_mode,
545 ACPI_NS_SEARCH_PARENT |
546 ACPI_NS_DONT_OPEN_SCOPE, walk_state,
547 ACPI_CAST_INDIRECT_PTR(struct
548 acpi_namespace_node,
549 &obj_desc));
550 /*
551 * The only case where we pass through (ignore) a NOT_FOUND
552 * error is for the cond_ref_of opcode.
553 */
554 if (status == AE_NOT_FOUND) {
555 if (parent_op->common.aml_opcode ==
556 AML_COND_REF_OF_OP) {
557 /*
558 * For the Conditional Reference op, it's OK if
559 * the name is not found; We just need a way to
560 * indicate this to the interpreter, set the
561 * object to the root
562 */
563 obj_desc = ACPI_CAST_PTR(union
564 acpi_operand_object,
565 acpi_gbl_root_node);
566 status = AE_OK;
567 } else {
568 /*
569 * We just plain didn't find it -- which is a
570 * very serious error at this point
571 */
572 status = AE_AML_NAME_NOT_FOUND;
573 }
574 }
575
576 if (ACPI_FAILURE(status)) {
577 ACPI_ERROR_NAMESPACE(name_string, status);
578 }
579 }
580
581 /* Free the namestring created above */
582
583 ACPI_FREE(name_string);
584
585 /* Check status from the lookup */
586
587 if (ACPI_FAILURE(status)) {
588 return_ACPI_STATUS(status);
589 }
590
591 /* Put the resulting object onto the current object stack */
592
593 status = acpi_ds_obj_stack_push(obj_desc, walk_state);
594 if (ACPI_FAILURE(status)) {
595 return_ACPI_STATUS(status);
596 }
597 ACPI_DEBUGGER_EXEC(acpi_db_display_argument_object
598 (obj_desc, walk_state));
599 } else {
600 /* Check for null name case */
601
602 if ((arg->common.aml_opcode == AML_INT_NAMEPATH_OP) &&
603 !(arg->common.flags & ACPI_PARSEOP_IN_STACK)) {
604 /*
605 * If the name is null, this means that this is an
606 * optional result parameter that was not specified
607 * in the original ASL. Create a Zero Constant for a
608 * placeholder. (Store to a constant is a Noop.)
609 */
610 opcode = AML_ZERO_OP; /* Has no arguments! */
611
612 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
613 "Null namepath: Arg=%p\n", arg));
614 } else {
615 opcode = arg->common.aml_opcode;
616 }
617
618 /* Get the object type of the argument */
619
620 op_info = acpi_ps_get_opcode_info(opcode);
621 if (op_info->object_type == ACPI_TYPE_INVALID) {
622 return_ACPI_STATUS(AE_NOT_IMPLEMENTED);
623 }
624
625 if ((op_info->flags & AML_HAS_RETVAL)
626 || (arg->common.flags & ACPI_PARSEOP_IN_STACK)) {
627 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
628 "Argument previously created, already stacked\n"));
629
630 ACPI_DEBUGGER_EXEC(acpi_db_display_argument_object
631 (walk_state->
632 operands[walk_state->num_operands -
633 1], walk_state));
634
635 /*
636 * Use value that was already previously returned
637 * by the evaluation of this argument
638 */
639 status = acpi_ds_result_pop(&obj_desc, walk_state);
640 if (ACPI_FAILURE(status)) {
641 /*
642 * Only error is underflow, and this indicates
643 * a missing or null operand!
644 */
645 ACPI_EXCEPTION((AE_INFO, status,
646 "Missing or null operand"));
647 return_ACPI_STATUS(status);
648 }
649 } else {
650 /* Create an ACPI_INTERNAL_OBJECT for the argument */
651
652 obj_desc =
653 acpi_ut_create_internal_object(op_info->
654 object_type);
655 if (!obj_desc) {
656 return_ACPI_STATUS(AE_NO_MEMORY);
657 }
658
659 /* Initialize the new object */
660
661 status =
662 acpi_ds_init_object_from_op(walk_state, arg, opcode,
663 &obj_desc);
664 if (ACPI_FAILURE(status)) {
665 acpi_ut_delete_object_desc(obj_desc);
666 return_ACPI_STATUS(status);
667 }
668 }
669
670 /* Put the operand object on the object stack */
671
672 status = acpi_ds_obj_stack_push(obj_desc, walk_state);
673 if (ACPI_FAILURE(status)) {
674 return_ACPI_STATUS(status);
675 }
676
677 ACPI_DEBUGGER_EXEC(acpi_db_display_argument_object
678 (obj_desc, walk_state));
679 }
680
681 return_ACPI_STATUS(AE_OK);
682}
683
684/*******************************************************************************
685 *
686 * FUNCTION: acpi_ds_create_operands
687 *
688 * PARAMETERS: walk_state - Current state
689 * first_arg - First argument of a parser argument tree
690 *
691 * RETURN: Status
692 *
693 * DESCRIPTION: Convert an operator's arguments from a parse tree format to
694 * namespace objects and place those argument object on the object
695 * stack in preparation for evaluation by the interpreter.
696 *
697 ******************************************************************************/
698
699acpi_status
700acpi_ds_create_operands(struct acpi_walk_state *walk_state,
701 union acpi_parse_object *first_arg)
702{
703 acpi_status status = AE_OK;
704 union acpi_parse_object *arg;
705 union acpi_parse_object *arguments[ACPI_OBJ_NUM_OPERANDS];
706 u32 arg_count = 0;
707 u32 index = walk_state->num_operands;
708 u32 i;
709
710 ACPI_FUNCTION_TRACE_PTR(ds_create_operands, first_arg);
711
712 /* Get all arguments in the list */
713
714 arg = first_arg;
715 while (arg) {
716 if (index >= ACPI_OBJ_NUM_OPERANDS) {
717 return_ACPI_STATUS(AE_BAD_DATA);
718 }
719
720 arguments[index] = arg;
721 walk_state->operands[index] = NULL;
722
723 /* Move on to next argument, if any */
724
725 arg = arg->common.next;
726 arg_count++;
727 index++;
728 }
729
730 index--;
731
732 /* It is the appropriate order to get objects from the Result stack */
733
734 for (i = 0; i < arg_count; i++) {
735 arg = arguments[index];
736
737 /* Force the filling of the operand stack in inverse order */
738
739 walk_state->operand_index = (u8) index;
740
741 status = acpi_ds_create_operand(walk_state, arg, index);
742 if (ACPI_FAILURE(status)) {
743 goto cleanup;
744 }
745
746 index--;
747
748 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
749 "Arg #%d (%p) done, Arg1=%p\n", index, arg,
750 first_arg));
751 }
752
753 return_ACPI_STATUS(status);
754
755 cleanup:
756 /*
757 * We must undo everything done above; meaning that we must
758 * pop everything off of the operand stack and delete those
759 * objects
760 */
761 acpi_ds_obj_stack_pop_and_delete(arg_count, walk_state);
762
763 ACPI_EXCEPTION((AE_INFO, status, "While creating Arg %d", index));
764 return_ACPI_STATUS(status);
765}
766
767/*****************************************************************************
768 *
769 * FUNCTION: acpi_ds_evaluate_name_path
770 *
771 * PARAMETERS: walk_state - Current state of the parse tree walk,
772 * the opcode of current operation should be
773 * AML_INT_NAMEPATH_OP
774 *
775 * RETURN: Status
776 *
777 * DESCRIPTION: Translate the -name_path- parse tree object to the equivalent
778 * interpreter object, convert it to value, if needed, duplicate
779 * it, if needed, and push it onto the current result stack.
780 *
781 ****************************************************************************/
782
783acpi_status acpi_ds_evaluate_name_path(struct acpi_walk_state *walk_state)
784{
785 acpi_status status = AE_OK;
786 union acpi_parse_object *op = walk_state->op;
787 union acpi_operand_object **operand = &walk_state->operands[0];
788 union acpi_operand_object *new_obj_desc;
789 u8 type;
790
791 ACPI_FUNCTION_TRACE_PTR(ds_evaluate_name_path, walk_state);
792
793 if (!op->common.parent) {
794
795 /* This happens after certain exception processing */
796
797 goto exit;
798 }
799
800 if ((op->common.parent->common.aml_opcode == AML_PACKAGE_OP) ||
801 (op->common.parent->common.aml_opcode == AML_VAR_PACKAGE_OP) ||
802 (op->common.parent->common.aml_opcode == AML_REF_OF_OP)) {
803
804 /* TBD: Should we specify this feature as a bit of op_info->Flags of these opcodes? */
805
806 goto exit;
807 }
808
809 status = acpi_ds_create_operand(walk_state, op, 0);
810 if (ACPI_FAILURE(status)) {
811 goto exit;
812 }
813
814 if (op->common.flags & ACPI_PARSEOP_TARGET) {
815 new_obj_desc = *operand;
816 goto push_result;
817 }
818
819 type = ACPI_GET_OBJECT_TYPE(*operand);
820
821 status = acpi_ex_resolve_to_value(operand, walk_state);
822 if (ACPI_FAILURE(status)) {
823 goto exit;
824 }
825
826 if (type == ACPI_TYPE_INTEGER) {
827
828 /* It was incremented by acpi_ex_resolve_to_value */
829
830 acpi_ut_remove_reference(*operand);
831
832 status =
833 acpi_ut_copy_iobject_to_iobject(*operand, &new_obj_desc,
834 walk_state);
835 if (ACPI_FAILURE(status)) {
836 goto exit;
837 }
838 } else {
839 /*
840 * The object either was anew created or is
841 * a Namespace node - don't decrement it.
842 */
843 new_obj_desc = *operand;
844 }
845
846 /* Cleanup for name-path operand */
847
848 status = acpi_ds_obj_stack_pop(1, walk_state);
849 if (ACPI_FAILURE(status)) {
850 walk_state->result_obj = new_obj_desc;
851 goto exit;
852 }
853
854 push_result:
855
856 walk_state->result_obj = new_obj_desc;
857
858 status = acpi_ds_result_push(walk_state->result_obj, walk_state);
859 if (ACPI_SUCCESS(status)) {
860
861 /* Force to take it from stack */
862
863 op->common.flags |= ACPI_PARSEOP_IN_STACK;
864 }
865
866 exit:
867
868 return_ACPI_STATUS(status);
869}
diff --git a/drivers/acpi/acpica/dswexec.c b/drivers/acpi/acpica/dswexec.c
new file mode 100644
index 00000000000..2482cbd37f2
--- /dev/null
+++ b/drivers/acpi/acpica/dswexec.c
@@ -0,0 +1,746 @@
1/******************************************************************************
2 *
3 * Module Name: dswexec - Dispatcher method execution callbacks;
4 * dispatch to interpreter.
5 *
6 *****************************************************************************/
7
8/*
9 * Copyright (C) 2000 - 2008, Intel Corp.
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions, and the following disclaimer,
17 * without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 * substantially similar to the "NO WARRANTY" disclaimer below
20 * ("Disclaimer") and any redistribution must be conditioned upon
21 * including a substantially similar Disclaimer requirement for further
22 * binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 * of any contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
30 *
31 * NO WARRANTY
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
43 */
44
45#include <acpi/acpi.h>
46#include <acpi/accommon.h>
47#include <acpi/acparser.h>
48#include <acpi/amlcode.h>
49#include <acpi/acdispat.h>
50#include <acpi/acinterp.h>
51#include <acpi/acnamesp.h>
52#include <acpi/acdebug.h>
53
54#define _COMPONENT ACPI_DISPATCHER
55ACPI_MODULE_NAME("dswexec")
56
57/*
58 * Dispatch table for opcode classes
59 */
60static ACPI_EXECUTE_OP acpi_gbl_op_type_dispatch[] = {
61 acpi_ex_opcode_0A_0T_1R,
62 acpi_ex_opcode_1A_0T_0R,
63 acpi_ex_opcode_1A_0T_1R,
64 acpi_ex_opcode_1A_1T_0R,
65 acpi_ex_opcode_1A_1T_1R,
66 acpi_ex_opcode_2A_0T_0R,
67 acpi_ex_opcode_2A_0T_1R,
68 acpi_ex_opcode_2A_1T_1R,
69 acpi_ex_opcode_2A_2T_1R,
70 acpi_ex_opcode_3A_0T_0R,
71 acpi_ex_opcode_3A_1T_1R,
72 acpi_ex_opcode_6A_0T_1R
73};
74
75/*****************************************************************************
76 *
77 * FUNCTION: acpi_ds_get_predicate_value
78 *
79 * PARAMETERS: walk_state - Current state of the parse tree walk
80 * result_obj - if non-zero, pop result from result stack
81 *
82 * RETURN: Status
83 *
84 * DESCRIPTION: Get the result of a predicate evaluation
85 *
86 ****************************************************************************/
87
88acpi_status
89acpi_ds_get_predicate_value(struct acpi_walk_state *walk_state,
90 union acpi_operand_object *result_obj)
91{
92 acpi_status status = AE_OK;
93 union acpi_operand_object *obj_desc;
94 union acpi_operand_object *local_obj_desc = NULL;
95
96 ACPI_FUNCTION_TRACE_PTR(ds_get_predicate_value, walk_state);
97
98 walk_state->control_state->common.state = 0;
99
100 if (result_obj) {
101 status = acpi_ds_result_pop(&obj_desc, walk_state);
102 if (ACPI_FAILURE(status)) {
103 ACPI_EXCEPTION((AE_INFO, status,
104 "Could not get result from predicate evaluation"));
105
106 return_ACPI_STATUS(status);
107 }
108 } else {
109 status = acpi_ds_create_operand(walk_state, walk_state->op, 0);
110 if (ACPI_FAILURE(status)) {
111 return_ACPI_STATUS(status);
112 }
113
114 status =
115 acpi_ex_resolve_to_value(&walk_state->operands[0],
116 walk_state);
117 if (ACPI_FAILURE(status)) {
118 return_ACPI_STATUS(status);
119 }
120
121 obj_desc = walk_state->operands[0];
122 }
123
124 if (!obj_desc) {
125 ACPI_ERROR((AE_INFO,
126 "No predicate ObjDesc=%p State=%p",
127 obj_desc, walk_state));
128
129 return_ACPI_STATUS(AE_AML_NO_OPERAND);
130 }
131
132 /*
133 * Result of predicate evaluation must be an Integer
134 * object. Implicitly convert the argument if necessary.
135 */
136 status = acpi_ex_convert_to_integer(obj_desc, &local_obj_desc, 16);
137 if (ACPI_FAILURE(status)) {
138 goto cleanup;
139 }
140
141 if (ACPI_GET_OBJECT_TYPE(local_obj_desc) != ACPI_TYPE_INTEGER) {
142 ACPI_ERROR((AE_INFO,
143 "Bad predicate (not an integer) ObjDesc=%p State=%p Type=%X",
144 obj_desc, walk_state,
145 ACPI_GET_OBJECT_TYPE(obj_desc)));
146
147 status = AE_AML_OPERAND_TYPE;
148 goto cleanup;
149 }
150
151 /* Truncate the predicate to 32-bits if necessary */
152
153 acpi_ex_truncate_for32bit_table(local_obj_desc);
154
155 /*
156 * Save the result of the predicate evaluation on
157 * the control stack
158 */
159 if (local_obj_desc->integer.value) {
160 walk_state->control_state->common.value = TRUE;
161 } else {
162 /*
163 * Predicate is FALSE, we will just toss the
164 * rest of the package
165 */
166 walk_state->control_state->common.value = FALSE;
167 status = AE_CTRL_FALSE;
168 }
169
170 /* Predicate can be used for an implicit return value */
171
172 (void)acpi_ds_do_implicit_return(local_obj_desc, walk_state, TRUE);
173
174 cleanup:
175
176 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Completed a predicate eval=%X Op=%p\n",
177 walk_state->control_state->common.value,
178 walk_state->op));
179
180 /* Break to debugger to display result */
181
182 ACPI_DEBUGGER_EXEC(acpi_db_display_result_object
183 (local_obj_desc, walk_state));
184
185 /*
186 * Delete the predicate result object (we know that
187 * we don't need it anymore)
188 */
189 if (local_obj_desc != obj_desc) {
190 acpi_ut_remove_reference(local_obj_desc);
191 }
192 acpi_ut_remove_reference(obj_desc);
193
194 walk_state->control_state->common.state = ACPI_CONTROL_NORMAL;
195 return_ACPI_STATUS(status);
196}
197
198/*****************************************************************************
199 *
200 * FUNCTION: acpi_ds_exec_begin_op
201 *
202 * PARAMETERS: walk_state - Current state of the parse tree walk
203 * out_op - Where to return op if a new one is created
204 *
205 * RETURN: Status
206 *
207 * DESCRIPTION: Descending callback used during the execution of control
208 * methods. This is where most operators and operands are
209 * dispatched to the interpreter.
210 *
211 ****************************************************************************/
212
213acpi_status
214acpi_ds_exec_begin_op(struct acpi_walk_state *walk_state,
215 union acpi_parse_object **out_op)
216{
217 union acpi_parse_object *op;
218 acpi_status status = AE_OK;
219 u32 opcode_class;
220
221 ACPI_FUNCTION_TRACE_PTR(ds_exec_begin_op, walk_state);
222
223 op = walk_state->op;
224 if (!op) {
225 status = acpi_ds_load2_begin_op(walk_state, out_op);
226 if (ACPI_FAILURE(status)) {
227 goto error_exit;
228 }
229
230 op = *out_op;
231 walk_state->op = op;
232 walk_state->opcode = op->common.aml_opcode;
233 walk_state->op_info =
234 acpi_ps_get_opcode_info(op->common.aml_opcode);
235
236 if (acpi_ns_opens_scope(walk_state->op_info->object_type)) {
237 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
238 "(%s) Popping scope for Op %p\n",
239 acpi_ut_get_type_name(walk_state->
240 op_info->
241 object_type),
242 op));
243
244 status = acpi_ds_scope_stack_pop(walk_state);
245 if (ACPI_FAILURE(status)) {
246 goto error_exit;
247 }
248 }
249 }
250
251 if (op == walk_state->origin) {
252 if (out_op) {
253 *out_op = op;
254 }
255
256 return_ACPI_STATUS(AE_OK);
257 }
258
259 /*
260 * If the previous opcode was a conditional, this opcode
261 * must be the beginning of the associated predicate.
262 * Save this knowledge in the current scope descriptor
263 */
264 if ((walk_state->control_state) &&
265 (walk_state->control_state->common.state ==
266 ACPI_CONTROL_CONDITIONAL_EXECUTING)) {
267 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
268 "Exec predicate Op=%p State=%p\n", op,
269 walk_state));
270
271 walk_state->control_state->common.state =
272 ACPI_CONTROL_PREDICATE_EXECUTING;
273
274 /* Save start of predicate */
275
276 walk_state->control_state->control.predicate_op = op;
277 }
278
279 opcode_class = walk_state->op_info->class;
280
281 /* We want to send namepaths to the load code */
282
283 if (op->common.aml_opcode == AML_INT_NAMEPATH_OP) {
284 opcode_class = AML_CLASS_NAMED_OBJECT;
285 }
286
287 /*
288 * Handle the opcode based upon the opcode type
289 */
290 switch (opcode_class) {
291 case AML_CLASS_CONTROL:
292
293 status = acpi_ds_exec_begin_control_op(walk_state, op);
294 break;
295
296 case AML_CLASS_NAMED_OBJECT:
297
298 if (walk_state->walk_type & ACPI_WALK_METHOD) {
299 /*
300 * Found a named object declaration during method execution;
301 * we must enter this object into the namespace. The created
302 * object is temporary and will be deleted upon completion of
303 * the execution of this method.
304 */
305 status = acpi_ds_load2_begin_op(walk_state, NULL);
306 }
307
308 break;
309
310 case AML_CLASS_EXECUTE:
311 case AML_CLASS_CREATE:
312
313 break;
314
315 default:
316 break;
317 }
318
319 /* Nothing to do here during method execution */
320
321 return_ACPI_STATUS(status);
322
323 error_exit:
324 status = acpi_ds_method_error(status, walk_state);
325 return_ACPI_STATUS(status);
326}
327
328/*****************************************************************************
329 *
330 * FUNCTION: acpi_ds_exec_end_op
331 *
332 * PARAMETERS: walk_state - Current state of the parse tree walk
333 *
334 * RETURN: Status
335 *
336 * DESCRIPTION: Ascending callback used during the execution of control
337 * methods. The only thing we really need to do here is to
338 * notice the beginning of IF, ELSE, and WHILE blocks.
339 *
340 ****************************************************************************/
341
342acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state)
343{
344 union acpi_parse_object *op;
345 acpi_status status = AE_OK;
346 u32 op_type;
347 u32 op_class;
348 union acpi_parse_object *next_op;
349 union acpi_parse_object *first_arg;
350
351 ACPI_FUNCTION_TRACE_PTR(ds_exec_end_op, walk_state);
352
353 op = walk_state->op;
354 op_type = walk_state->op_info->type;
355 op_class = walk_state->op_info->class;
356
357 if (op_class == AML_CLASS_UNKNOWN) {
358 ACPI_ERROR((AE_INFO, "Unknown opcode %X",
359 op->common.aml_opcode));
360 return_ACPI_STATUS(AE_NOT_IMPLEMENTED);
361 }
362
363 first_arg = op->common.value.arg;
364
365 /* Init the walk state */
366
367 walk_state->num_operands = 0;
368 walk_state->operand_index = 0;
369 walk_state->return_desc = NULL;
370 walk_state->result_obj = NULL;
371
372 /* Call debugger for single step support (DEBUG build only) */
373
374 ACPI_DEBUGGER_EXEC(status =
375 acpi_db_single_step(walk_state, op, op_class));
376 ACPI_DEBUGGER_EXEC(if (ACPI_FAILURE(status)) {
377 return_ACPI_STATUS(status);}
378 ) ;
379
380 /* Decode the Opcode Class */
381
382 switch (op_class) {
383 case AML_CLASS_ARGUMENT: /* Constants, literals, etc. */
384
385 if (walk_state->opcode == AML_INT_NAMEPATH_OP) {
386 status = acpi_ds_evaluate_name_path(walk_state);
387 if (ACPI_FAILURE(status)) {
388 goto cleanup;
389 }
390 }
391 break;
392
393 case AML_CLASS_EXECUTE: /* Most operators with arguments */
394
395 /* Build resolved operand stack */
396
397 status = acpi_ds_create_operands(walk_state, first_arg);
398 if (ACPI_FAILURE(status)) {
399 goto cleanup;
400 }
401
402 /*
403 * All opcodes require operand resolution, with the only exceptions
404 * being the object_type and size_of operators.
405 */
406 if (!(walk_state->op_info->flags & AML_NO_OPERAND_RESOLVE)) {
407
408 /* Resolve all operands */
409
410 status = acpi_ex_resolve_operands(walk_state->opcode,
411 &(walk_state->
412 operands
413 [walk_state->
414 num_operands - 1]),
415 walk_state);
416 }
417
418 if (ACPI_SUCCESS(status)) {
419 /*
420 * Dispatch the request to the appropriate interpreter handler
421 * routine. There is one routine per opcode "type" based upon the
422 * number of opcode arguments and return type.
423 */
424 status =
425 acpi_gbl_op_type_dispatch[op_type] (walk_state);
426 } else {
427 /*
428 * Treat constructs of the form "Store(LocalX,LocalX)" as noops when the
429 * Local is uninitialized.
430 */
431 if ((status == AE_AML_UNINITIALIZED_LOCAL) &&
432 (walk_state->opcode == AML_STORE_OP) &&
433 (walk_state->operands[0]->common.type ==
434 ACPI_TYPE_LOCAL_REFERENCE)
435 && (walk_state->operands[1]->common.type ==
436 ACPI_TYPE_LOCAL_REFERENCE)
437 && (walk_state->operands[0]->reference.class ==
438 walk_state->operands[1]->reference.class)
439 && (walk_state->operands[0]->reference.value ==
440 walk_state->operands[1]->reference.value)) {
441 status = AE_OK;
442 } else {
443 ACPI_EXCEPTION((AE_INFO, status,
444 "While resolving operands for [%s]",
445 acpi_ps_get_opcode_name
446 (walk_state->opcode)));
447 }
448 }
449
450 /* Always delete the argument objects and clear the operand stack */
451
452 acpi_ds_clear_operands(walk_state);
453
454 /*
455 * If a result object was returned from above, push it on the
456 * current result stack
457 */
458 if (ACPI_SUCCESS(status) && walk_state->result_obj) {
459 status =
460 acpi_ds_result_push(walk_state->result_obj,
461 walk_state);
462 }
463 break;
464
465 default:
466
467 switch (op_type) {
468 case AML_TYPE_CONTROL: /* Type 1 opcode, IF/ELSE/WHILE/NOOP */
469
470 /* 1 Operand, 0 external_result, 0 internal_result */
471
472 status = acpi_ds_exec_end_control_op(walk_state, op);
473
474 break;
475
476 case AML_TYPE_METHOD_CALL:
477
478 /*
479 * If the method is referenced from within a package
480 * declaration, it is not a invocation of the method, just
481 * a reference to it.
482 */
483 if ((op->asl.parent) &&
484 ((op->asl.parent->asl.aml_opcode == AML_PACKAGE_OP)
485 || (op->asl.parent->asl.aml_opcode ==
486 AML_VAR_PACKAGE_OP))) {
487 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
488 "Method Reference in a Package, Op=%p\n",
489 op));
490
491 op->common.node =
492 (struct acpi_namespace_node *)op->asl.value.
493 arg->asl.node;
494 acpi_ut_add_reference(op->asl.value.arg->asl.
495 node->object);
496 return_ACPI_STATUS(AE_OK);
497 }
498
499 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
500 "Method invocation, Op=%p\n", op));
501
502 /*
503 * (AML_METHODCALL) Op->Asl.Value.Arg->Asl.Node contains
504 * the method Node pointer
505 */
506 /* next_op points to the op that holds the method name */
507
508 next_op = first_arg;
509
510 /* next_op points to first argument op */
511
512 next_op = next_op->common.next;
513
514 /*
515 * Get the method's arguments and put them on the operand stack
516 */
517 status = acpi_ds_create_operands(walk_state, next_op);
518 if (ACPI_FAILURE(status)) {
519 break;
520 }
521
522 /*
523 * Since the operands will be passed to another control method,
524 * we must resolve all local references here (Local variables,
525 * arguments to *this* method, etc.)
526 */
527 status = acpi_ds_resolve_operands(walk_state);
528 if (ACPI_FAILURE(status)) {
529
530 /* On error, clear all resolved operands */
531
532 acpi_ds_clear_operands(walk_state);
533 break;
534 }
535
536 /*
537 * Tell the walk loop to preempt this running method and
538 * execute the new method
539 */
540 status = AE_CTRL_TRANSFER;
541
542 /*
543 * Return now; we don't want to disturb anything,
544 * especially the operand count!
545 */
546 return_ACPI_STATUS(status);
547
548 case AML_TYPE_CREATE_FIELD:
549
550 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
551 "Executing CreateField Buffer/Index Op=%p\n",
552 op));
553
554 status = acpi_ds_load2_end_op(walk_state);
555 if (ACPI_FAILURE(status)) {
556 break;
557 }
558
559 status =
560 acpi_ds_eval_buffer_field_operands(walk_state, op);
561 break;
562
563 case AML_TYPE_CREATE_OBJECT:
564
565 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
566 "Executing CreateObject (Buffer/Package) Op=%p\n",
567 op));
568
569 switch (op->common.parent->common.aml_opcode) {
570 case AML_NAME_OP:
571
572 /*
573 * Put the Node on the object stack (Contains the ACPI Name
574 * of this object)
575 */
576 walk_state->operands[0] =
577 (void *)op->common.parent->common.node;
578 walk_state->num_operands = 1;
579
580 status = acpi_ds_create_node(walk_state,
581 op->common.parent->
582 common.node,
583 op->common.parent);
584 if (ACPI_FAILURE(status)) {
585 break;
586 }
587
588 /* Fall through */
589 /*lint -fallthrough */
590
591 case AML_INT_EVAL_SUBTREE_OP:
592
593 status =
594 acpi_ds_eval_data_object_operands
595 (walk_state, op,
596 acpi_ns_get_attached_object(op->common.
597 parent->common.
598 node));
599 break;
600
601 default:
602
603 status =
604 acpi_ds_eval_data_object_operands
605 (walk_state, op, NULL);
606 break;
607 }
608
609 /*
610 * If a result object was returned from above, push it on the
611 * current result stack
612 */
613 if (walk_state->result_obj) {
614 status =
615 acpi_ds_result_push(walk_state->result_obj,
616 walk_state);
617 }
618 break;
619
620 case AML_TYPE_NAMED_FIELD:
621 case AML_TYPE_NAMED_COMPLEX:
622 case AML_TYPE_NAMED_SIMPLE:
623 case AML_TYPE_NAMED_NO_OBJ:
624
625 status = acpi_ds_load2_end_op(walk_state);
626 if (ACPI_FAILURE(status)) {
627 break;
628 }
629
630 if (op->common.aml_opcode == AML_REGION_OP) {
631 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
632 "Executing OpRegion Address/Length Op=%p\n",
633 op));
634
635 status =
636 acpi_ds_eval_region_operands(walk_state,
637 op);
638 if (ACPI_FAILURE(status)) {
639 break;
640 }
641 } else if (op->common.aml_opcode == AML_DATA_REGION_OP) {
642 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
643 "Executing DataTableRegion Strings Op=%p\n",
644 op));
645
646 status =
647 acpi_ds_eval_table_region_operands
648 (walk_state, op);
649 if (ACPI_FAILURE(status)) {
650 break;
651 }
652 } else if (op->common.aml_opcode == AML_BANK_FIELD_OP) {
653 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
654 "Executing BankField Op=%p\n",
655 op));
656
657 status =
658 acpi_ds_eval_bank_field_operands(walk_state,
659 op);
660 if (ACPI_FAILURE(status)) {
661 break;
662 }
663 }
664 break;
665
666 case AML_TYPE_UNDEFINED:
667
668 ACPI_ERROR((AE_INFO,
669 "Undefined opcode type Op=%p", op));
670 return_ACPI_STATUS(AE_NOT_IMPLEMENTED);
671
672 case AML_TYPE_BOGUS:
673
674 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
675 "Internal opcode=%X type Op=%p\n",
676 walk_state->opcode, op));
677 break;
678
679 default:
680
681 ACPI_ERROR((AE_INFO,
682 "Unimplemented opcode, class=%X type=%X Opcode=%X Op=%p",
683 op_class, op_type, op->common.aml_opcode,
684 op));
685
686 status = AE_NOT_IMPLEMENTED;
687 break;
688 }
689 }
690
691 /*
692 * ACPI 2.0 support for 64-bit integers: Truncate numeric
693 * result value if we are executing from a 32-bit ACPI table
694 */
695 acpi_ex_truncate_for32bit_table(walk_state->result_obj);
696
697 /*
698 * Check if we just completed the evaluation of a
699 * conditional predicate
700 */
701 if ((ACPI_SUCCESS(status)) &&
702 (walk_state->control_state) &&
703 (walk_state->control_state->common.state ==
704 ACPI_CONTROL_PREDICATE_EXECUTING) &&
705 (walk_state->control_state->control.predicate_op == op)) {
706 status =
707 acpi_ds_get_predicate_value(walk_state,
708 walk_state->result_obj);
709 walk_state->result_obj = NULL;
710 }
711
712 cleanup:
713
714 if (walk_state->result_obj) {
715
716 /* Break to debugger to display result */
717
718 ACPI_DEBUGGER_EXEC(acpi_db_display_result_object
719 (walk_state->result_obj, walk_state));
720
721 /*
722 * Delete the result op if and only if:
723 * Parent will not use the result -- such as any
724 * non-nested type2 op in a method (parent will be method)
725 */
726 acpi_ds_delete_result_if_not_used(op, walk_state->result_obj,
727 walk_state);
728 }
729#ifdef _UNDER_DEVELOPMENT
730
731 if (walk_state->parser_state.aml == walk_state->parser_state.aml_end) {
732 acpi_db_method_end(walk_state);
733 }
734#endif
735
736 /* Invoke exception handler on error */
737
738 if (ACPI_FAILURE(status)) {
739 status = acpi_ds_method_error(status, walk_state);
740 }
741
742 /* Always clear the object stack */
743
744 walk_state->num_operands = 0;
745 return_ACPI_STATUS(status);
746}
diff --git a/drivers/acpi/acpica/dswload.c b/drivers/acpi/acpica/dswload.c
new file mode 100644
index 00000000000..2d71ceda3d5
--- /dev/null
+++ b/drivers/acpi/acpica/dswload.c
@@ -0,0 +1,1203 @@
1/******************************************************************************
2 *
3 * Module Name: dswload - Dispatcher namespace load callbacks
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46#include <acpi/acparser.h>
47#include <acpi/amlcode.h>
48#include <acpi/acdispat.h>
49#include <acpi/acinterp.h>
50#include <acpi/acnamesp.h>
51#include <acpi/acevents.h>
52
53#ifdef ACPI_ASL_COMPILER
54#include <acpi/acdisasm.h>
55#endif
56
57#define _COMPONENT ACPI_DISPATCHER
58ACPI_MODULE_NAME("dswload")
59
60/*******************************************************************************
61 *
62 * FUNCTION: acpi_ds_init_callbacks
63 *
64 * PARAMETERS: walk_state - Current state of the parse tree walk
65 * pass_number - 1, 2, or 3
66 *
67 * RETURN: Status
68 *
69 * DESCRIPTION: Init walk state callbacks
70 *
71 ******************************************************************************/
72acpi_status
73acpi_ds_init_callbacks(struct acpi_walk_state *walk_state, u32 pass_number)
74{
75
76 switch (pass_number) {
77 case 1:
78 walk_state->parse_flags = ACPI_PARSE_LOAD_PASS1 |
79 ACPI_PARSE_DELETE_TREE;
80 walk_state->descending_callback = acpi_ds_load1_begin_op;
81 walk_state->ascending_callback = acpi_ds_load1_end_op;
82 break;
83
84 case 2:
85 walk_state->parse_flags = ACPI_PARSE_LOAD_PASS1 |
86 ACPI_PARSE_DELETE_TREE;
87 walk_state->descending_callback = acpi_ds_load2_begin_op;
88 walk_state->ascending_callback = acpi_ds_load2_end_op;
89 break;
90
91 case 3:
92#ifndef ACPI_NO_METHOD_EXECUTION
93 walk_state->parse_flags |= ACPI_PARSE_EXECUTE |
94 ACPI_PARSE_DELETE_TREE;
95 walk_state->descending_callback = acpi_ds_exec_begin_op;
96 walk_state->ascending_callback = acpi_ds_exec_end_op;
97#endif
98 break;
99
100 default:
101 return (AE_BAD_PARAMETER);
102 }
103
104 return (AE_OK);
105}
106
107/*******************************************************************************
108 *
109 * FUNCTION: acpi_ds_load1_begin_op
110 *
111 * PARAMETERS: walk_state - Current state of the parse tree walk
112 * out_op - Where to return op if a new one is created
113 *
114 * RETURN: Status
115 *
116 * DESCRIPTION: Descending callback used during the loading of ACPI tables.
117 *
118 ******************************************************************************/
119
120acpi_status
121acpi_ds_load1_begin_op(struct acpi_walk_state * walk_state,
122 union acpi_parse_object ** out_op)
123{
124 union acpi_parse_object *op;
125 struct acpi_namespace_node *node;
126 acpi_status status;
127 acpi_object_type object_type;
128 char *path;
129 u32 flags;
130
131 ACPI_FUNCTION_TRACE(ds_load1_begin_op);
132
133 op = walk_state->op;
134 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op,
135 walk_state));
136
137 /* We are only interested in opcodes that have an associated name */
138
139 if (op) {
140 if (!(walk_state->op_info->flags & AML_NAMED)) {
141 *out_op = op;
142 return_ACPI_STATUS(AE_OK);
143 }
144
145 /* Check if this object has already been installed in the namespace */
146
147 if (op->common.node) {
148 *out_op = op;
149 return_ACPI_STATUS(AE_OK);
150 }
151 }
152
153 path = acpi_ps_get_next_namestring(&walk_state->parser_state);
154
155 /* Map the raw opcode into an internal object type */
156
157 object_type = walk_state->op_info->object_type;
158
159 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
160 "State=%p Op=%p [%s]\n", walk_state, op,
161 acpi_ut_get_type_name(object_type)));
162
163 switch (walk_state->opcode) {
164 case AML_SCOPE_OP:
165
166 /*
167 * The target name of the Scope() operator must exist at this point so
168 * that we can actually open the scope to enter new names underneath it.
169 * Allow search-to-root for single namesegs.
170 */
171 status =
172 acpi_ns_lookup(walk_state->scope_info, path, object_type,
173 ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
174 walk_state, &(node));
175#ifdef ACPI_ASL_COMPILER
176 if (status == AE_NOT_FOUND) {
177 /*
178 * Table disassembly:
179 * Target of Scope() not found. Generate an External for it, and
180 * insert the name into the namespace.
181 */
182 acpi_dm_add_to_external_list(path, ACPI_TYPE_DEVICE, 0);
183 status =
184 acpi_ns_lookup(walk_state->scope_info, path,
185 object_type, ACPI_IMODE_LOAD_PASS1,
186 ACPI_NS_SEARCH_PARENT, walk_state,
187 &node);
188 }
189#endif
190 if (ACPI_FAILURE(status)) {
191 ACPI_ERROR_NAMESPACE(path, status);
192 return_ACPI_STATUS(status);
193 }
194
195 /*
196 * Check to make sure that the target is
197 * one of the opcodes that actually opens a scope
198 */
199 switch (node->type) {
200 case ACPI_TYPE_ANY:
201 case ACPI_TYPE_LOCAL_SCOPE: /* Scope */
202 case ACPI_TYPE_DEVICE:
203 case ACPI_TYPE_POWER:
204 case ACPI_TYPE_PROCESSOR:
205 case ACPI_TYPE_THERMAL:
206
207 /* These are acceptable types */
208 break;
209
210 case ACPI_TYPE_INTEGER:
211 case ACPI_TYPE_STRING:
212 case ACPI_TYPE_BUFFER:
213
214 /*
215 * These types we will allow, but we will change the type. This
216 * enables some existing code of the form:
217 *
218 * Name (DEB, 0)
219 * Scope (DEB) { ... }
220 *
221 * Note: silently change the type here. On the second pass, we will report
222 * a warning
223 */
224 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
225 "Type override - [%4.4s] had invalid type (%s) for Scope operator, changed to (Scope)\n",
226 path,
227 acpi_ut_get_type_name(node->type)));
228
229 node->type = ACPI_TYPE_ANY;
230 walk_state->scope_info->common.value = ACPI_TYPE_ANY;
231 break;
232
233 default:
234
235 /* All other types are an error */
236
237 ACPI_ERROR((AE_INFO,
238 "Invalid type (%s) for target of Scope operator [%4.4s] (Cannot override)",
239 acpi_ut_get_type_name(node->type), path));
240
241 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
242 }
243 break;
244
245 default:
246 /*
247 * For all other named opcodes, we will enter the name into
248 * the namespace.
249 *
250 * Setup the search flags.
251 * Since we are entering a name into the namespace, we do not want to
252 * enable the search-to-root upsearch.
253 *
254 * There are only two conditions where it is acceptable that the name
255 * already exists:
256 * 1) the Scope() operator can reopen a scoping object that was
257 * previously defined (Scope, Method, Device, etc.)
258 * 2) Whenever we are parsing a deferred opcode (op_region, Buffer,
259 * buffer_field, or Package), the name of the object is already
260 * in the namespace.
261 */
262 if (walk_state->deferred_node) {
263
264 /* This name is already in the namespace, get the node */
265
266 node = walk_state->deferred_node;
267 status = AE_OK;
268 break;
269 }
270
271 /*
272 * If we are executing a method, do not create any namespace objects
273 * during the load phase, only during execution.
274 */
275 if (walk_state->method_node) {
276 node = NULL;
277 status = AE_OK;
278 break;
279 }
280
281 flags = ACPI_NS_NO_UPSEARCH;
282 if ((walk_state->opcode != AML_SCOPE_OP) &&
283 (!(walk_state->parse_flags & ACPI_PARSE_DEFERRED_OP))) {
284 flags |= ACPI_NS_ERROR_IF_FOUND;
285 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
286 "[%s] Cannot already exist\n",
287 acpi_ut_get_type_name(object_type)));
288 } else {
289 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
290 "[%s] Both Find or Create allowed\n",
291 acpi_ut_get_type_name(object_type)));
292 }
293
294 /*
295 * Enter the named type into the internal namespace. We enter the name
296 * as we go downward in the parse tree. Any necessary subobjects that
297 * involve arguments to the opcode must be created as we go back up the
298 * parse tree later.
299 */
300 status =
301 acpi_ns_lookup(walk_state->scope_info, path, object_type,
302 ACPI_IMODE_LOAD_PASS1, flags, walk_state,
303 &node);
304 if (ACPI_FAILURE(status)) {
305 if (status == AE_ALREADY_EXISTS) {
306
307 /* The name already exists in this scope */
308
309 if (node->flags & ANOBJ_IS_EXTERNAL) {
310 /*
311 * Allow one create on an object or segment that was
312 * previously declared External
313 */
314 node->flags &= ~ANOBJ_IS_EXTERNAL;
315 node->type = (u8) object_type;
316
317 /* Just retyped a node, probably will need to open a scope */
318
319 if (acpi_ns_opens_scope(object_type)) {
320 status =
321 acpi_ds_scope_stack_push
322 (node, object_type,
323 walk_state);
324 if (ACPI_FAILURE(status)) {
325 return_ACPI_STATUS
326 (status);
327 }
328 }
329
330 status = AE_OK;
331 }
332 }
333
334 if (ACPI_FAILURE(status)) {
335 ACPI_ERROR_NAMESPACE(path, status);
336 return_ACPI_STATUS(status);
337 }
338 }
339 break;
340 }
341
342 /* Common exit */
343
344 if (!op) {
345
346 /* Create a new op */
347
348 op = acpi_ps_alloc_op(walk_state->opcode);
349 if (!op) {
350 return_ACPI_STATUS(AE_NO_MEMORY);
351 }
352 }
353
354 /* Initialize the op */
355
356#if (defined (ACPI_NO_METHOD_EXECUTION) || defined (ACPI_CONSTANT_EVAL_ONLY))
357 op->named.path = ACPI_CAST_PTR(u8, path);
358#endif
359
360 if (node) {
361 /*
362 * Put the Node in the "op" object that the parser uses, so we
363 * can get it again quickly when this scope is closed
364 */
365 op->common.node = node;
366 op->named.name = node->name.integer;
367 }
368
369 acpi_ps_append_arg(acpi_ps_get_parent_scope(&walk_state->parser_state),
370 op);
371 *out_op = op;
372 return_ACPI_STATUS(status);
373}
374
375/*******************************************************************************
376 *
377 * FUNCTION: acpi_ds_load1_end_op
378 *
379 * PARAMETERS: walk_state - Current state of the parse tree walk
380 *
381 * RETURN: Status
382 *
383 * DESCRIPTION: Ascending callback used during the loading of the namespace,
384 * both control methods and everything else.
385 *
386 ******************************************************************************/
387
388acpi_status acpi_ds_load1_end_op(struct acpi_walk_state *walk_state)
389{
390 union acpi_parse_object *op;
391 acpi_object_type object_type;
392 acpi_status status = AE_OK;
393
394 ACPI_FUNCTION_TRACE(ds_load1_end_op);
395
396 op = walk_state->op;
397 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op,
398 walk_state));
399
400 /* We are only interested in opcodes that have an associated name */
401
402 if (!(walk_state->op_info->flags & (AML_NAMED | AML_FIELD))) {
403 return_ACPI_STATUS(AE_OK);
404 }
405
406 /* Get the object type to determine if we should pop the scope */
407
408 object_type = walk_state->op_info->object_type;
409
410#ifndef ACPI_NO_METHOD_EXECUTION
411 if (walk_state->op_info->flags & AML_FIELD) {
412 /*
413 * If we are executing a method, do not create any namespace objects
414 * during the load phase, only during execution.
415 */
416 if (!walk_state->method_node) {
417 if (walk_state->opcode == AML_FIELD_OP ||
418 walk_state->opcode == AML_BANK_FIELD_OP ||
419 walk_state->opcode == AML_INDEX_FIELD_OP) {
420 status =
421 acpi_ds_init_field_objects(op, walk_state);
422 }
423 }
424 return_ACPI_STATUS(status);
425 }
426
427 /*
428 * If we are executing a method, do not create any namespace objects
429 * during the load phase, only during execution.
430 */
431 if (!walk_state->method_node) {
432 if (op->common.aml_opcode == AML_REGION_OP) {
433 status =
434 acpi_ex_create_region(op->named.data,
435 op->named.length,
436 (acpi_adr_space_type) ((op->
437 common.
438 value.
439 arg)->
440 common.
441 value.
442 integer),
443 walk_state);
444 if (ACPI_FAILURE(status)) {
445 return_ACPI_STATUS(status);
446 }
447 } else if (op->common.aml_opcode == AML_DATA_REGION_OP) {
448 status =
449 acpi_ex_create_region(op->named.data,
450 op->named.length,
451 REGION_DATA_TABLE,
452 walk_state);
453 if (ACPI_FAILURE(status)) {
454 return_ACPI_STATUS(status);
455 }
456 }
457 }
458#endif
459
460 if (op->common.aml_opcode == AML_NAME_OP) {
461
462 /* For Name opcode, get the object type from the argument */
463
464 if (op->common.value.arg) {
465 object_type = (acpi_ps_get_opcode_info((op->common.
466 value.arg)->
467 common.
468 aml_opcode))->
469 object_type;
470
471 /* Set node type if we have a namespace node */
472
473 if (op->common.node) {
474 op->common.node->type = (u8) object_type;
475 }
476 }
477 }
478
479 /*
480 * If we are executing a method, do not create any namespace objects
481 * during the load phase, only during execution.
482 */
483 if (!walk_state->method_node) {
484 if (op->common.aml_opcode == AML_METHOD_OP) {
485 /*
486 * method_op pkg_length name_string method_flags term_list
487 *
488 * Note: We must create the method node/object pair as soon as we
489 * see the method declaration. This allows later pass1 parsing
490 * of invocations of the method (need to know the number of
491 * arguments.)
492 */
493 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
494 "LOADING-Method: State=%p Op=%p NamedObj=%p\n",
495 walk_state, op, op->named.node));
496
497 if (!acpi_ns_get_attached_object(op->named.node)) {
498 walk_state->operands[0] =
499 ACPI_CAST_PTR(void, op->named.node);
500 walk_state->num_operands = 1;
501
502 status =
503 acpi_ds_create_operands(walk_state,
504 op->common.value.
505 arg);
506 if (ACPI_SUCCESS(status)) {
507 status =
508 acpi_ex_create_method(op->named.
509 data,
510 op->named.
511 length,
512 walk_state);
513 }
514
515 walk_state->operands[0] = NULL;
516 walk_state->num_operands = 0;
517
518 if (ACPI_FAILURE(status)) {
519 return_ACPI_STATUS(status);
520 }
521 }
522 }
523 }
524
525 /* Pop the scope stack (only if loading a table) */
526
527 if (!walk_state->method_node && acpi_ns_opens_scope(object_type)) {
528 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
529 "(%s): Popping scope for Op %p\n",
530 acpi_ut_get_type_name(object_type), op));
531
532 status = acpi_ds_scope_stack_pop(walk_state);
533 }
534
535 return_ACPI_STATUS(status);
536}
537
538/*******************************************************************************
539 *
540 * FUNCTION: acpi_ds_load2_begin_op
541 *
542 * PARAMETERS: walk_state - Current state of the parse tree walk
543 * out_op - Wher to return op if a new one is created
544 *
545 * RETURN: Status
546 *
547 * DESCRIPTION: Descending callback used during the loading of ACPI tables.
548 *
549 ******************************************************************************/
550
551acpi_status
552acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state,
553 union acpi_parse_object **out_op)
554{
555 union acpi_parse_object *op;
556 struct acpi_namespace_node *node;
557 acpi_status status;
558 acpi_object_type object_type;
559 char *buffer_ptr;
560 u32 flags;
561
562 ACPI_FUNCTION_TRACE(ds_load2_begin_op);
563
564 op = walk_state->op;
565 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op,
566 walk_state));
567
568 if (op) {
569 if ((walk_state->control_state) &&
570 (walk_state->control_state->common.state ==
571 ACPI_CONTROL_CONDITIONAL_EXECUTING)) {
572
573 /* We are executing a while loop outside of a method */
574
575 status = acpi_ds_exec_begin_op(walk_state, out_op);
576 return_ACPI_STATUS(status);
577 }
578
579 /* We only care about Namespace opcodes here */
580
581 if ((!(walk_state->op_info->flags & AML_NSOPCODE) &&
582 (walk_state->opcode != AML_INT_NAMEPATH_OP)) ||
583 (!(walk_state->op_info->flags & AML_NAMED))) {
584#ifdef ACPI_ENABLE_MODULE_LEVEL_CODE
585 if ((walk_state->op_info->class == AML_CLASS_EXECUTE) ||
586 (walk_state->op_info->class == AML_CLASS_CONTROL)) {
587 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
588 "Begin/EXEC: %s (fl %8.8X)\n",
589 walk_state->op_info->name,
590 walk_state->op_info->flags));
591
592 /* Executing a type1 or type2 opcode outside of a method */
593
594 status =
595 acpi_ds_exec_begin_op(walk_state, out_op);
596 return_ACPI_STATUS(status);
597 }
598#endif
599 return_ACPI_STATUS(AE_OK);
600 }
601
602 /* Get the name we are going to enter or lookup in the namespace */
603
604 if (walk_state->opcode == AML_INT_NAMEPATH_OP) {
605
606 /* For Namepath op, get the path string */
607
608 buffer_ptr = op->common.value.string;
609 if (!buffer_ptr) {
610
611 /* No name, just exit */
612
613 return_ACPI_STATUS(AE_OK);
614 }
615 } else {
616 /* Get name from the op */
617
618 buffer_ptr = ACPI_CAST_PTR(char, &op->named.name);
619 }
620 } else {
621 /* Get the namestring from the raw AML */
622
623 buffer_ptr =
624 acpi_ps_get_next_namestring(&walk_state->parser_state);
625 }
626
627 /* Map the opcode into an internal object type */
628
629 object_type = walk_state->op_info->object_type;
630
631 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
632 "State=%p Op=%p Type=%X\n", walk_state, op,
633 object_type));
634
635 switch (walk_state->opcode) {
636 case AML_FIELD_OP:
637 case AML_BANK_FIELD_OP:
638 case AML_INDEX_FIELD_OP:
639
640 node = NULL;
641 status = AE_OK;
642 break;
643
644 case AML_INT_NAMEPATH_OP:
645 /*
646 * The name_path is an object reference to an existing object.
647 * Don't enter the name into the namespace, but look it up
648 * for use later.
649 */
650 status =
651 acpi_ns_lookup(walk_state->scope_info, buffer_ptr,
652 object_type, ACPI_IMODE_EXECUTE,
653 ACPI_NS_SEARCH_PARENT, walk_state, &(node));
654 break;
655
656 case AML_SCOPE_OP:
657 /*
658 * The Path is an object reference to an existing object.
659 * Don't enter the name into the namespace, but look it up
660 * for use later.
661 */
662 status =
663 acpi_ns_lookup(walk_state->scope_info, buffer_ptr,
664 object_type, ACPI_IMODE_EXECUTE,
665 ACPI_NS_SEARCH_PARENT, walk_state, &(node));
666 if (ACPI_FAILURE(status)) {
667#ifdef ACPI_ASL_COMPILER
668 if (status == AE_NOT_FOUND) {
669 status = AE_OK;
670 } else {
671 ACPI_ERROR_NAMESPACE(buffer_ptr, status);
672 }
673#else
674 ACPI_ERROR_NAMESPACE(buffer_ptr, status);
675#endif
676 return_ACPI_STATUS(status);
677 }
678
679 /*
680 * We must check to make sure that the target is
681 * one of the opcodes that actually opens a scope
682 */
683 switch (node->type) {
684 case ACPI_TYPE_ANY:
685 case ACPI_TYPE_LOCAL_SCOPE: /* Scope */
686 case ACPI_TYPE_DEVICE:
687 case ACPI_TYPE_POWER:
688 case ACPI_TYPE_PROCESSOR:
689 case ACPI_TYPE_THERMAL:
690
691 /* These are acceptable types */
692 break;
693
694 case ACPI_TYPE_INTEGER:
695 case ACPI_TYPE_STRING:
696 case ACPI_TYPE_BUFFER:
697
698 /*
699 * These types we will allow, but we will change the type. This
700 * enables some existing code of the form:
701 *
702 * Name (DEB, 0)
703 * Scope (DEB) { ... }
704 */
705 ACPI_WARNING((AE_INFO,
706 "Type override - [%4.4s] had invalid type (%s) for Scope operator, changed to (Scope)",
707 buffer_ptr,
708 acpi_ut_get_type_name(node->type)));
709
710 node->type = ACPI_TYPE_ANY;
711 walk_state->scope_info->common.value = ACPI_TYPE_ANY;
712 break;
713
714 default:
715
716 /* All other types are an error */
717
718 ACPI_ERROR((AE_INFO,
719 "Invalid type (%s) for target of Scope operator [%4.4s]",
720 acpi_ut_get_type_name(node->type),
721 buffer_ptr));
722
723 return (AE_AML_OPERAND_TYPE);
724 }
725 break;
726
727 default:
728
729 /* All other opcodes */
730
731 if (op && op->common.node) {
732
733 /* This op/node was previously entered into the namespace */
734
735 node = op->common.node;
736
737 if (acpi_ns_opens_scope(object_type)) {
738 status =
739 acpi_ds_scope_stack_push(node, object_type,
740 walk_state);
741 if (ACPI_FAILURE(status)) {
742 return_ACPI_STATUS(status);
743 }
744 }
745
746 return_ACPI_STATUS(AE_OK);
747 }
748
749 /*
750 * Enter the named type into the internal namespace. We enter the name
751 * as we go downward in the parse tree. Any necessary subobjects that
752 * involve arguments to the opcode must be created as we go back up the
753 * parse tree later.
754 *
755 * Note: Name may already exist if we are executing a deferred opcode.
756 */
757 if (walk_state->deferred_node) {
758
759 /* This name is already in the namespace, get the node */
760
761 node = walk_state->deferred_node;
762 status = AE_OK;
763 break;
764 }
765
766 flags = ACPI_NS_NO_UPSEARCH;
767 if (walk_state->pass_number == ACPI_IMODE_EXECUTE) {
768
769 /* Execution mode, node cannot already exist, node is temporary */
770
771 flags |= (ACPI_NS_ERROR_IF_FOUND | ACPI_NS_TEMPORARY);
772 }
773
774 /* Add new entry or lookup existing entry */
775
776 status =
777 acpi_ns_lookup(walk_state->scope_info, buffer_ptr,
778 object_type, ACPI_IMODE_LOAD_PASS2, flags,
779 walk_state, &node);
780
781 if (ACPI_SUCCESS(status) && (flags & ACPI_NS_TEMPORARY)) {
782 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
783 "***New Node [%4.4s] %p is temporary\n",
784 acpi_ut_get_node_name(node), node));
785 }
786 break;
787 }
788
789 if (ACPI_FAILURE(status)) {
790 ACPI_ERROR_NAMESPACE(buffer_ptr, status);
791 return_ACPI_STATUS(status);
792 }
793
794 if (!op) {
795
796 /* Create a new op */
797
798 op = acpi_ps_alloc_op(walk_state->opcode);
799 if (!op) {
800 return_ACPI_STATUS(AE_NO_MEMORY);
801 }
802
803 /* Initialize the new op */
804
805 if (node) {
806 op->named.name = node->name.integer;
807 }
808 *out_op = op;
809 }
810
811 /*
812 * Put the Node in the "op" object that the parser uses, so we
813 * can get it again quickly when this scope is closed
814 */
815 op->common.node = node;
816 return_ACPI_STATUS(status);
817}
818
819/*******************************************************************************
820 *
821 * FUNCTION: acpi_ds_load2_end_op
822 *
823 * PARAMETERS: walk_state - Current state of the parse tree walk
824 *
825 * RETURN: Status
826 *
827 * DESCRIPTION: Ascending callback used during the loading of the namespace,
828 * both control methods and everything else.
829 *
830 ******************************************************************************/
831
832acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state)
833{
834 union acpi_parse_object *op;
835 acpi_status status = AE_OK;
836 acpi_object_type object_type;
837 struct acpi_namespace_node *node;
838 union acpi_parse_object *arg;
839 struct acpi_namespace_node *new_node;
840#ifndef ACPI_NO_METHOD_EXECUTION
841 u32 i;
842 u8 region_space;
843#endif
844
845 ACPI_FUNCTION_TRACE(ds_load2_end_op);
846
847 op = walk_state->op;
848 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Opcode [%s] Op %p State %p\n",
849 walk_state->op_info->name, op, walk_state));
850
851 /* Check if opcode had an associated namespace object */
852
853 if (!(walk_state->op_info->flags & AML_NSOBJECT)) {
854#ifndef ACPI_NO_METHOD_EXECUTION
855#ifdef ACPI_ENABLE_MODULE_LEVEL_CODE
856 /* No namespace object. Executable opcode? */
857
858 if ((walk_state->op_info->class == AML_CLASS_EXECUTE) ||
859 (walk_state->op_info->class == AML_CLASS_CONTROL)) {
860 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
861 "End/EXEC: %s (fl %8.8X)\n",
862 walk_state->op_info->name,
863 walk_state->op_info->flags));
864
865 /* Executing a type1 or type2 opcode outside of a method */
866
867 status = acpi_ds_exec_end_op(walk_state);
868 return_ACPI_STATUS(status);
869 }
870#endif
871#endif
872 return_ACPI_STATUS(AE_OK);
873 }
874
875 if (op->common.aml_opcode == AML_SCOPE_OP) {
876 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
877 "Ending scope Op=%p State=%p\n", op,
878 walk_state));
879 }
880
881 object_type = walk_state->op_info->object_type;
882
883 /*
884 * Get the Node/name from the earlier lookup
885 * (It was saved in the *op structure)
886 */
887 node = op->common.node;
888
889 /*
890 * Put the Node on the object stack (Contains the ACPI Name of
891 * this object)
892 */
893 walk_state->operands[0] = (void *)node;
894 walk_state->num_operands = 1;
895
896 /* Pop the scope stack */
897
898 if (acpi_ns_opens_scope(object_type) &&
899 (op->common.aml_opcode != AML_INT_METHODCALL_OP)) {
900 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
901 "(%s) Popping scope for Op %p\n",
902 acpi_ut_get_type_name(object_type), op));
903
904 status = acpi_ds_scope_stack_pop(walk_state);
905 if (ACPI_FAILURE(status)) {
906 goto cleanup;
907 }
908 }
909
910 /*
911 * Named operations are as follows:
912 *
913 * AML_ALIAS
914 * AML_BANKFIELD
915 * AML_CREATEBITFIELD
916 * AML_CREATEBYTEFIELD
917 * AML_CREATEDWORDFIELD
918 * AML_CREATEFIELD
919 * AML_CREATEQWORDFIELD
920 * AML_CREATEWORDFIELD
921 * AML_DATA_REGION
922 * AML_DEVICE
923 * AML_EVENT
924 * AML_FIELD
925 * AML_INDEXFIELD
926 * AML_METHOD
927 * AML_METHODCALL
928 * AML_MUTEX
929 * AML_NAME
930 * AML_NAMEDFIELD
931 * AML_OPREGION
932 * AML_POWERRES
933 * AML_PROCESSOR
934 * AML_SCOPE
935 * AML_THERMALZONE
936 */
937
938 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
939 "Create-Load [%s] State=%p Op=%p NamedObj=%p\n",
940 acpi_ps_get_opcode_name(op->common.aml_opcode),
941 walk_state, op, node));
942
943 /* Decode the opcode */
944
945 arg = op->common.value.arg;
946
947 switch (walk_state->op_info->type) {
948#ifndef ACPI_NO_METHOD_EXECUTION
949
950 case AML_TYPE_CREATE_FIELD:
951 /*
952 * Create the field object, but the field buffer and index must
953 * be evaluated later during the execution phase
954 */
955 status = acpi_ds_create_buffer_field(op, walk_state);
956 break;
957
958 case AML_TYPE_NAMED_FIELD:
959 /*
960 * If we are executing a method, initialize the field
961 */
962 if (walk_state->method_node) {
963 status = acpi_ds_init_field_objects(op, walk_state);
964 }
965
966 switch (op->common.aml_opcode) {
967 case AML_INDEX_FIELD_OP:
968
969 status =
970 acpi_ds_create_index_field(op,
971 (acpi_handle) arg->
972 common.node, walk_state);
973 break;
974
975 case AML_BANK_FIELD_OP:
976
977 status =
978 acpi_ds_create_bank_field(op, arg->common.node,
979 walk_state);
980 break;
981
982 case AML_FIELD_OP:
983
984 status =
985 acpi_ds_create_field(op, arg->common.node,
986 walk_state);
987 break;
988
989 default:
990 /* All NAMED_FIELD opcodes must be handled above */
991 break;
992 }
993 break;
994
995 case AML_TYPE_NAMED_SIMPLE:
996
997 status = acpi_ds_create_operands(walk_state, arg);
998 if (ACPI_FAILURE(status)) {
999 goto cleanup;
1000 }
1001
1002 switch (op->common.aml_opcode) {
1003 case AML_PROCESSOR_OP:
1004
1005 status = acpi_ex_create_processor(walk_state);
1006 break;
1007
1008 case AML_POWER_RES_OP:
1009
1010 status = acpi_ex_create_power_resource(walk_state);
1011 break;
1012
1013 case AML_MUTEX_OP:
1014
1015 status = acpi_ex_create_mutex(walk_state);
1016 break;
1017
1018 case AML_EVENT_OP:
1019
1020 status = acpi_ex_create_event(walk_state);
1021 break;
1022
1023 case AML_ALIAS_OP:
1024
1025 status = acpi_ex_create_alias(walk_state);
1026 break;
1027
1028 default:
1029 /* Unknown opcode */
1030
1031 status = AE_OK;
1032 goto cleanup;
1033 }
1034
1035 /* Delete operands */
1036
1037 for (i = 1; i < walk_state->num_operands; i++) {
1038 acpi_ut_remove_reference(walk_state->operands[i]);
1039 walk_state->operands[i] = NULL;
1040 }
1041
1042 break;
1043#endif /* ACPI_NO_METHOD_EXECUTION */
1044
1045 case AML_TYPE_NAMED_COMPLEX:
1046
1047 switch (op->common.aml_opcode) {
1048#ifndef ACPI_NO_METHOD_EXECUTION
1049 case AML_REGION_OP:
1050 case AML_DATA_REGION_OP:
1051
1052 if (op->common.aml_opcode == AML_REGION_OP) {
1053 region_space = (acpi_adr_space_type)
1054 ((op->common.value.arg)->common.value.
1055 integer);
1056 } else {
1057 region_space = REGION_DATA_TABLE;
1058 }
1059
1060 /*
1061 * If we are executing a method, initialize the region
1062 */
1063 if (walk_state->method_node) {
1064 status =
1065 acpi_ex_create_region(op->named.data,
1066 op->named.length,
1067 region_space,
1068 walk_state);
1069 if (ACPI_FAILURE(status)) {
1070 return (status);
1071 }
1072 }
1073
1074 /*
1075 * The op_region is not fully parsed at this time. Only valid
1076 * argument is the space_id. (We must save the address of the
1077 * AML of the address and length operands)
1078 */
1079
1080 /*
1081 * If we have a valid region, initialize it
1082 * Namespace is NOT locked at this point.
1083 */
1084 status =
1085 acpi_ev_initialize_region
1086 (acpi_ns_get_attached_object(node), FALSE);
1087 if (ACPI_FAILURE(status)) {
1088 /*
1089 * If AE_NOT_EXIST is returned, it is not fatal
1090 * because many regions get created before a handler
1091 * is installed for said region.
1092 */
1093 if (AE_NOT_EXIST == status) {
1094 status = AE_OK;
1095 }
1096 }
1097 break;
1098
1099 case AML_NAME_OP:
1100
1101 status = acpi_ds_create_node(walk_state, node, op);
1102 break;
1103
1104 case AML_METHOD_OP:
1105 /*
1106 * method_op pkg_length name_string method_flags term_list
1107 *
1108 * Note: We must create the method node/object pair as soon as we
1109 * see the method declaration. This allows later pass1 parsing
1110 * of invocations of the method (need to know the number of
1111 * arguments.)
1112 */
1113 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
1114 "LOADING-Method: State=%p Op=%p NamedObj=%p\n",
1115 walk_state, op, op->named.node));
1116
1117 if (!acpi_ns_get_attached_object(op->named.node)) {
1118 walk_state->operands[0] =
1119 ACPI_CAST_PTR(void, op->named.node);
1120 walk_state->num_operands = 1;
1121
1122 status =
1123 acpi_ds_create_operands(walk_state,
1124 op->common.value.
1125 arg);
1126 if (ACPI_SUCCESS(status)) {
1127 status =
1128 acpi_ex_create_method(op->named.
1129 data,
1130 op->named.
1131 length,
1132 walk_state);
1133 }
1134 walk_state->operands[0] = NULL;
1135 walk_state->num_operands = 0;
1136
1137 if (ACPI_FAILURE(status)) {
1138 return_ACPI_STATUS(status);
1139 }
1140 }
1141 break;
1142
1143#endif /* ACPI_NO_METHOD_EXECUTION */
1144
1145 default:
1146 /* All NAMED_COMPLEX opcodes must be handled above */
1147 break;
1148 }
1149 break;
1150
1151 case AML_CLASS_INTERNAL:
1152
1153 /* case AML_INT_NAMEPATH_OP: */
1154 break;
1155
1156 case AML_CLASS_METHOD_CALL:
1157
1158 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
1159 "RESOLVING-MethodCall: State=%p Op=%p NamedObj=%p\n",
1160 walk_state, op, node));
1161
1162 /*
1163 * Lookup the method name and save the Node
1164 */
1165 status =
1166 acpi_ns_lookup(walk_state->scope_info,
1167 arg->common.value.string, ACPI_TYPE_ANY,
1168 ACPI_IMODE_LOAD_PASS2,
1169 ACPI_NS_SEARCH_PARENT |
1170 ACPI_NS_DONT_OPEN_SCOPE, walk_state,
1171 &(new_node));
1172 if (ACPI_SUCCESS(status)) {
1173 /*
1174 * Make sure that what we found is indeed a method
1175 * We didn't search for a method on purpose, to see if the name
1176 * would resolve
1177 */
1178 if (new_node->type != ACPI_TYPE_METHOD) {
1179 status = AE_AML_OPERAND_TYPE;
1180 }
1181
1182 /* We could put the returned object (Node) on the object stack for
1183 * later, but for now, we will put it in the "op" object that the
1184 * parser uses, so we can get it again at the end of this scope
1185 */
1186 op->common.node = new_node;
1187 } else {
1188 ACPI_ERROR_NAMESPACE(arg->common.value.string, status);
1189 }
1190 break;
1191
1192 default:
1193 break;
1194 }
1195
1196 cleanup:
1197
1198 /* Remove the Node pushed at the very beginning */
1199
1200 walk_state->operands[0] = NULL;
1201 walk_state->num_operands = 0;
1202 return_ACPI_STATUS(status);
1203}
diff --git a/drivers/acpi/acpica/dswscope.c b/drivers/acpi/acpica/dswscope.c
new file mode 100644
index 00000000000..8030541a49f
--- /dev/null
+++ b/drivers/acpi/acpica/dswscope.c
@@ -0,0 +1,214 @@
1/******************************************************************************
2 *
3 * Module Name: dswscope - Scope stack manipulation
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46#include <acpi/acdispat.h>
47
48#define _COMPONENT ACPI_DISPATCHER
49ACPI_MODULE_NAME("dswscope")
50
51/****************************************************************************
52 *
53 * FUNCTION: acpi_ds_scope_stack_clear
54 *
55 * PARAMETERS: walk_state - Current state
56 *
57 * RETURN: None
58 *
59 * DESCRIPTION: Pop (and free) everything on the scope stack except the
60 * root scope object (which remains at the stack top.)
61 *
62 ***************************************************************************/
63void acpi_ds_scope_stack_clear(struct acpi_walk_state *walk_state)
64{
65 union acpi_generic_state *scope_info;
66
67 ACPI_FUNCTION_NAME(ds_scope_stack_clear);
68
69 while (walk_state->scope_info) {
70
71 /* Pop a scope off the stack */
72
73 scope_info = walk_state->scope_info;
74 walk_state->scope_info = scope_info->scope.next;
75
76 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
77 "Popped object type (%s)\n",
78 acpi_ut_get_type_name(scope_info->common.
79 value)));
80 acpi_ut_delete_generic_state(scope_info);
81 }
82}
83
84/****************************************************************************
85 *
86 * FUNCTION: acpi_ds_scope_stack_push
87 *
88 * PARAMETERS: Node - Name to be made current
89 * Type - Type of frame being pushed
90 * walk_state - Current state
91 *
92 * RETURN: Status
93 *
94 * DESCRIPTION: Push the current scope on the scope stack, and make the
95 * passed Node current.
96 *
97 ***************************************************************************/
98
99acpi_status
100acpi_ds_scope_stack_push(struct acpi_namespace_node *node,
101 acpi_object_type type,
102 struct acpi_walk_state *walk_state)
103{
104 union acpi_generic_state *scope_info;
105 union acpi_generic_state *old_scope_info;
106
107 ACPI_FUNCTION_TRACE(ds_scope_stack_push);
108
109 if (!node) {
110
111 /* Invalid scope */
112
113 ACPI_ERROR((AE_INFO, "Null scope parameter"));
114 return_ACPI_STATUS(AE_BAD_PARAMETER);
115 }
116
117 /* Make sure object type is valid */
118
119 if (!acpi_ut_valid_object_type(type)) {
120 ACPI_WARNING((AE_INFO, "Invalid object type: 0x%X", type));
121 }
122
123 /* Allocate a new scope object */
124
125 scope_info = acpi_ut_create_generic_state();
126 if (!scope_info) {
127 return_ACPI_STATUS(AE_NO_MEMORY);
128 }
129
130 /* Init new scope object */
131
132 scope_info->common.descriptor_type = ACPI_DESC_TYPE_STATE_WSCOPE;
133 scope_info->scope.node = node;
134 scope_info->common.value = (u16) type;
135
136 walk_state->scope_depth++;
137
138 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
139 "[%.2d] Pushed scope ",
140 (u32) walk_state->scope_depth));
141
142 old_scope_info = walk_state->scope_info;
143 if (old_scope_info) {
144 ACPI_DEBUG_PRINT_RAW((ACPI_DB_EXEC,
145 "[%4.4s] (%s)",
146 acpi_ut_get_node_name(old_scope_info->
147 scope.node),
148 acpi_ut_get_type_name(old_scope_info->
149 common.value)));
150 } else {
151 ACPI_DEBUG_PRINT_RAW((ACPI_DB_EXEC, "[\\___] (%s)", "ROOT"));
152 }
153
154 ACPI_DEBUG_PRINT_RAW((ACPI_DB_EXEC,
155 ", New scope -> [%4.4s] (%s)\n",
156 acpi_ut_get_node_name(scope_info->scope.node),
157 acpi_ut_get_type_name(scope_info->common.value)));
158
159 /* Push new scope object onto stack */
160
161 acpi_ut_push_generic_state(&walk_state->scope_info, scope_info);
162 return_ACPI_STATUS(AE_OK);
163}
164
165/****************************************************************************
166 *
167 * FUNCTION: acpi_ds_scope_stack_pop
168 *
169 * PARAMETERS: walk_state - Current state
170 *
171 * RETURN: Status
172 *
173 * DESCRIPTION: Pop the scope stack once.
174 *
175 ***************************************************************************/
176
177acpi_status acpi_ds_scope_stack_pop(struct acpi_walk_state *walk_state)
178{
179 union acpi_generic_state *scope_info;
180 union acpi_generic_state *new_scope_info;
181
182 ACPI_FUNCTION_TRACE(ds_scope_stack_pop);
183
184 /*
185 * Pop scope info object off the stack.
186 */
187 scope_info = acpi_ut_pop_generic_state(&walk_state->scope_info);
188 if (!scope_info) {
189 return_ACPI_STATUS(AE_STACK_UNDERFLOW);
190 }
191
192 walk_state->scope_depth--;
193
194 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
195 "[%.2d] Popped scope [%4.4s] (%s), New scope -> ",
196 (u32) walk_state->scope_depth,
197 acpi_ut_get_node_name(scope_info->scope.node),
198 acpi_ut_get_type_name(scope_info->common.value)));
199
200 new_scope_info = walk_state->scope_info;
201 if (new_scope_info) {
202 ACPI_DEBUG_PRINT_RAW((ACPI_DB_EXEC,
203 "[%4.4s] (%s)\n",
204 acpi_ut_get_node_name(new_scope_info->
205 scope.node),
206 acpi_ut_get_type_name(new_scope_info->
207 common.value)));
208 } else {
209 ACPI_DEBUG_PRINT_RAW((ACPI_DB_EXEC, "[\\___] (ROOT)\n"));
210 }
211
212 acpi_ut_delete_generic_state(scope_info);
213 return_ACPI_STATUS(AE_OK);
214}
diff --git a/drivers/acpi/acpica/dswstate.c b/drivers/acpi/acpica/dswstate.c
new file mode 100644
index 00000000000..a7543c43c15
--- /dev/null
+++ b/drivers/acpi/acpica/dswstate.c
@@ -0,0 +1,753 @@
1/******************************************************************************
2 *
3 * Module Name: dswstate - Dispatcher parse tree walk management routines
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46#include <acpi/acparser.h>
47#include <acpi/acdispat.h>
48#include <acpi/acnamesp.h>
49
50#define _COMPONENT ACPI_DISPATCHER
51ACPI_MODULE_NAME("dswstate")
52
53 /* Local prototypes */
54static acpi_status acpi_ds_result_stack_push(struct acpi_walk_state *ws);
55static acpi_status acpi_ds_result_stack_pop(struct acpi_walk_state *ws);
56
57/*******************************************************************************
58 *
59 * FUNCTION: acpi_ds_result_pop
60 *
61 * PARAMETERS: Object - Where to return the popped object
62 * walk_state - Current Walk state
63 *
64 * RETURN: Status
65 *
66 * DESCRIPTION: Pop an object off the top of this walk's result stack
67 *
68 ******************************************************************************/
69
70acpi_status
71acpi_ds_result_pop(union acpi_operand_object **object,
72 struct acpi_walk_state *walk_state)
73{
74 u32 index;
75 union acpi_generic_state *state;
76 acpi_status status;
77
78 ACPI_FUNCTION_NAME(ds_result_pop);
79
80 state = walk_state->results;
81
82 /* Incorrect state of result stack */
83
84 if (state && !walk_state->result_count) {
85 ACPI_ERROR((AE_INFO, "No results on result stack"));
86 return (AE_AML_INTERNAL);
87 }
88
89 if (!state && walk_state->result_count) {
90 ACPI_ERROR((AE_INFO, "No result state for result stack"));
91 return (AE_AML_INTERNAL);
92 }
93
94 /* Empty result stack */
95
96 if (!state) {
97 ACPI_ERROR((AE_INFO, "Result stack is empty! State=%p",
98 walk_state));
99 return (AE_AML_NO_RETURN_VALUE);
100 }
101
102 /* Return object of the top element and clean that top element result stack */
103
104 walk_state->result_count--;
105 index = walk_state->result_count % ACPI_RESULTS_FRAME_OBJ_NUM;
106
107 *object = state->results.obj_desc[index];
108 if (!*object) {
109 ACPI_ERROR((AE_INFO,
110 "No result objects on result stack, State=%p",
111 walk_state));
112 return (AE_AML_NO_RETURN_VALUE);
113 }
114
115 state->results.obj_desc[index] = NULL;
116 if (index == 0) {
117 status = acpi_ds_result_stack_pop(walk_state);
118 if (ACPI_FAILURE(status)) {
119 return (status);
120 }
121 }
122
123 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
124 "Obj=%p [%s] Index=%X State=%p Num=%X\n", *object,
125 acpi_ut_get_object_type_name(*object),
126 index, walk_state, walk_state->result_count));
127
128 return (AE_OK);
129}
130
131/*******************************************************************************
132 *
133 * FUNCTION: acpi_ds_result_push
134 *
135 * PARAMETERS: Object - Where to return the popped object
136 * walk_state - Current Walk state
137 *
138 * RETURN: Status
139 *
140 * DESCRIPTION: Push an object onto the current result stack
141 *
142 ******************************************************************************/
143
144acpi_status
145acpi_ds_result_push(union acpi_operand_object * object,
146 struct acpi_walk_state * walk_state)
147{
148 union acpi_generic_state *state;
149 acpi_status status;
150 u32 index;
151
152 ACPI_FUNCTION_NAME(ds_result_push);
153
154 if (walk_state->result_count > walk_state->result_size) {
155 ACPI_ERROR((AE_INFO, "Result stack is full"));
156 return (AE_AML_INTERNAL);
157 } else if (walk_state->result_count == walk_state->result_size) {
158
159 /* Extend the result stack */
160
161 status = acpi_ds_result_stack_push(walk_state);
162 if (ACPI_FAILURE(status)) {
163 ACPI_ERROR((AE_INFO,
164 "Failed to extend the result stack"));
165 return (status);
166 }
167 }
168
169 if (!(walk_state->result_count < walk_state->result_size)) {
170 ACPI_ERROR((AE_INFO, "No free elements in result stack"));
171 return (AE_AML_INTERNAL);
172 }
173
174 state = walk_state->results;
175 if (!state) {
176 ACPI_ERROR((AE_INFO, "No result stack frame during push"));
177 return (AE_AML_INTERNAL);
178 }
179
180 if (!object) {
181 ACPI_ERROR((AE_INFO,
182 "Null Object! Obj=%p State=%p Num=%X",
183 object, walk_state, walk_state->result_count));
184 return (AE_BAD_PARAMETER);
185 }
186
187 /* Assign the address of object to the top free element of result stack */
188
189 index = walk_state->result_count % ACPI_RESULTS_FRAME_OBJ_NUM;
190 state->results.obj_desc[index] = object;
191 walk_state->result_count++;
192
193 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Obj=%p [%s] State=%p Num=%X Cur=%X\n",
194 object,
195 acpi_ut_get_object_type_name((union
196 acpi_operand_object *)
197 object), walk_state,
198 walk_state->result_count,
199 walk_state->current_result));
200
201 return (AE_OK);
202}
203
204/*******************************************************************************
205 *
206 * FUNCTION: acpi_ds_result_stack_push
207 *
208 * PARAMETERS: walk_state - Current Walk state
209 *
210 * RETURN: Status
211 *
212 * DESCRIPTION: Push an object onto the walk_state result stack
213 *
214 ******************************************************************************/
215
216static acpi_status acpi_ds_result_stack_push(struct acpi_walk_state *walk_state)
217{
218 union acpi_generic_state *state;
219
220 ACPI_FUNCTION_NAME(ds_result_stack_push);
221
222 /* Check for stack overflow */
223
224 if (((u32) walk_state->result_size + ACPI_RESULTS_FRAME_OBJ_NUM) >
225 ACPI_RESULTS_OBJ_NUM_MAX) {
226 ACPI_ERROR((AE_INFO, "Result stack overflow: State=%p Num=%X",
227 walk_state, walk_state->result_size));
228 return (AE_STACK_OVERFLOW);
229 }
230
231 state = acpi_ut_create_generic_state();
232 if (!state) {
233 return (AE_NO_MEMORY);
234 }
235
236 state->common.descriptor_type = ACPI_DESC_TYPE_STATE_RESULT;
237 acpi_ut_push_generic_state(&walk_state->results, state);
238
239 /* Increase the length of the result stack by the length of frame */
240
241 walk_state->result_size += ACPI_RESULTS_FRAME_OBJ_NUM;
242
243 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Results=%p State=%p\n",
244 state, walk_state));
245
246 return (AE_OK);
247}
248
249/*******************************************************************************
250 *
251 * FUNCTION: acpi_ds_result_stack_pop
252 *
253 * PARAMETERS: walk_state - Current Walk state
254 *
255 * RETURN: Status
256 *
257 * DESCRIPTION: Pop an object off of the walk_state result stack
258 *
259 ******************************************************************************/
260
261static acpi_status acpi_ds_result_stack_pop(struct acpi_walk_state *walk_state)
262{
263 union acpi_generic_state *state;
264
265 ACPI_FUNCTION_NAME(ds_result_stack_pop);
266
267 /* Check for stack underflow */
268
269 if (walk_state->results == NULL) {
270 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
271 "Result stack underflow - State=%p\n",
272 walk_state));
273 return (AE_AML_NO_OPERAND);
274 }
275
276 if (walk_state->result_size < ACPI_RESULTS_FRAME_OBJ_NUM) {
277 ACPI_ERROR((AE_INFO, "Insufficient result stack size"));
278 return (AE_AML_INTERNAL);
279 }
280
281 state = acpi_ut_pop_generic_state(&walk_state->results);
282 acpi_ut_delete_generic_state(state);
283
284 /* Decrease the length of result stack by the length of frame */
285
286 walk_state->result_size -= ACPI_RESULTS_FRAME_OBJ_NUM;
287
288 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
289 "Result=%p RemainingResults=%X State=%p\n",
290 state, walk_state->result_count, walk_state));
291
292 return (AE_OK);
293}
294
295/*******************************************************************************
296 *
297 * FUNCTION: acpi_ds_obj_stack_push
298 *
299 * PARAMETERS: Object - Object to push
300 * walk_state - Current Walk state
301 *
302 * RETURN: Status
303 *
304 * DESCRIPTION: Push an object onto this walk's object/operand stack
305 *
306 ******************************************************************************/
307
308acpi_status
309acpi_ds_obj_stack_push(void *object, struct acpi_walk_state * walk_state)
310{
311 ACPI_FUNCTION_NAME(ds_obj_stack_push);
312
313 /* Check for stack overflow */
314
315 if (walk_state->num_operands >= ACPI_OBJ_NUM_OPERANDS) {
316 ACPI_ERROR((AE_INFO,
317 "Object stack overflow! Obj=%p State=%p #Ops=%X",
318 object, walk_state, walk_state->num_operands));
319 return (AE_STACK_OVERFLOW);
320 }
321
322 /* Put the object onto the stack */
323
324 walk_state->operands[walk_state->operand_index] = object;
325 walk_state->num_operands++;
326
327 /* For the usual order of filling the operand stack */
328
329 walk_state->operand_index++;
330
331 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Obj=%p [%s] State=%p #Ops=%X\n",
332 object,
333 acpi_ut_get_object_type_name((union
334 acpi_operand_object *)
335 object), walk_state,
336 walk_state->num_operands));
337
338 return (AE_OK);
339}
340
341/*******************************************************************************
342 *
343 * FUNCTION: acpi_ds_obj_stack_pop
344 *
345 * PARAMETERS: pop_count - Number of objects/entries to pop
346 * walk_state - Current Walk state
347 *
348 * RETURN: Status
349 *
350 * DESCRIPTION: Pop this walk's object stack. Objects on the stack are NOT
351 * deleted by this routine.
352 *
353 ******************************************************************************/
354
355acpi_status
356acpi_ds_obj_stack_pop(u32 pop_count, struct acpi_walk_state * walk_state)
357{
358 u32 i;
359
360 ACPI_FUNCTION_NAME(ds_obj_stack_pop);
361
362 for (i = 0; i < pop_count; i++) {
363
364 /* Check for stack underflow */
365
366 if (walk_state->num_operands == 0) {
367 ACPI_ERROR((AE_INFO,
368 "Object stack underflow! Count=%X State=%p #Ops=%X",
369 pop_count, walk_state,
370 walk_state->num_operands));
371 return (AE_STACK_UNDERFLOW);
372 }
373
374 /* Just set the stack entry to null */
375
376 walk_state->num_operands--;
377 walk_state->operands[walk_state->num_operands] = NULL;
378 }
379
380 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Count=%X State=%p #Ops=%X\n",
381 pop_count, walk_state, walk_state->num_operands));
382
383 return (AE_OK);
384}
385
386/*******************************************************************************
387 *
388 * FUNCTION: acpi_ds_obj_stack_pop_and_delete
389 *
390 * PARAMETERS: pop_count - Number of objects/entries to pop
391 * walk_state - Current Walk state
392 *
393 * RETURN: Status
394 *
395 * DESCRIPTION: Pop this walk's object stack and delete each object that is
396 * popped off.
397 *
398 ******************************************************************************/
399
400void
401acpi_ds_obj_stack_pop_and_delete(u32 pop_count,
402 struct acpi_walk_state *walk_state)
403{
404 s32 i;
405 union acpi_operand_object *obj_desc;
406
407 ACPI_FUNCTION_NAME(ds_obj_stack_pop_and_delete);
408
409 if (pop_count == 0) {
410 return;
411 }
412
413 for (i = (s32) pop_count - 1; i >= 0; i--) {
414 if (walk_state->num_operands == 0) {
415 return;
416 }
417
418 /* Pop the stack and delete an object if present in this stack entry */
419
420 walk_state->num_operands--;
421 obj_desc = walk_state->operands[i];
422 if (obj_desc) {
423 acpi_ut_remove_reference(walk_state->operands[i]);
424 walk_state->operands[i] = NULL;
425 }
426 }
427
428 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Count=%X State=%p #Ops=%X\n",
429 pop_count, walk_state, walk_state->num_operands));
430}
431
432/*******************************************************************************
433 *
434 * FUNCTION: acpi_ds_get_current_walk_state
435 *
436 * PARAMETERS: Thread - Get current active state for this Thread
437 *
438 * RETURN: Pointer to the current walk state
439 *
440 * DESCRIPTION: Get the walk state that is at the head of the list (the "current"
441 * walk state.)
442 *
443 ******************************************************************************/
444
445struct acpi_walk_state *acpi_ds_get_current_walk_state(struct acpi_thread_state
446 *thread)
447{
448 ACPI_FUNCTION_NAME(ds_get_current_walk_state);
449
450 if (!thread) {
451 return (NULL);
452 }
453
454 ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "Current WalkState %p\n",
455 thread->walk_state_list));
456
457 return (thread->walk_state_list);
458}
459
460/*******************************************************************************
461 *
462 * FUNCTION: acpi_ds_push_walk_state
463 *
464 * PARAMETERS: walk_state - State to push
465 * Thread - Thread state object
466 *
467 * RETURN: None
468 *
469 * DESCRIPTION: Place the Thread state at the head of the state list
470 *
471 ******************************************************************************/
472
473void
474acpi_ds_push_walk_state(struct acpi_walk_state *walk_state,
475 struct acpi_thread_state *thread)
476{
477 ACPI_FUNCTION_TRACE(ds_push_walk_state);
478
479 walk_state->next = thread->walk_state_list;
480 thread->walk_state_list = walk_state;
481
482 return_VOID;
483}
484
485/*******************************************************************************
486 *
487 * FUNCTION: acpi_ds_pop_walk_state
488 *
489 * PARAMETERS: Thread - Current thread state
490 *
491 * RETURN: A walk_state object popped from the thread's stack
492 *
493 * DESCRIPTION: Remove and return the walkstate object that is at the head of
494 * the walk stack for the given walk list. NULL indicates that
495 * the list is empty.
496 *
497 ******************************************************************************/
498
499struct acpi_walk_state *acpi_ds_pop_walk_state(struct acpi_thread_state *thread)
500{
501 struct acpi_walk_state *walk_state;
502
503 ACPI_FUNCTION_TRACE(ds_pop_walk_state);
504
505 walk_state = thread->walk_state_list;
506
507 if (walk_state) {
508
509 /* Next walk state becomes the current walk state */
510
511 thread->walk_state_list = walk_state->next;
512
513 /*
514 * Don't clear the NEXT field, this serves as an indicator
515 * that there is a parent WALK STATE
516 * Do Not: walk_state->Next = NULL;
517 */
518 }
519
520 return_PTR(walk_state);
521}
522
523/*******************************************************************************
524 *
525 * FUNCTION: acpi_ds_create_walk_state
526 *
527 * PARAMETERS: owner_id - ID for object creation
528 * Origin - Starting point for this walk
529 * method_desc - Method object
530 * Thread - Current thread state
531 *
532 * RETURN: Pointer to the new walk state.
533 *
534 * DESCRIPTION: Allocate and initialize a new walk state. The current walk
535 * state is set to this new state.
536 *
537 ******************************************************************************/
538
539struct acpi_walk_state *acpi_ds_create_walk_state(acpi_owner_id owner_id, union acpi_parse_object
540 *origin, union acpi_operand_object
541 *method_desc, struct acpi_thread_state
542 *thread)
543{
544 struct acpi_walk_state *walk_state;
545
546 ACPI_FUNCTION_TRACE(ds_create_walk_state);
547
548 walk_state = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_walk_state));
549 if (!walk_state) {
550 return_PTR(NULL);
551 }
552
553 walk_state->descriptor_type = ACPI_DESC_TYPE_WALK;
554 walk_state->method_desc = method_desc;
555 walk_state->owner_id = owner_id;
556 walk_state->origin = origin;
557 walk_state->thread = thread;
558
559 walk_state->parser_state.start_op = origin;
560
561 /* Init the method args/local */
562
563#if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY))
564 acpi_ds_method_data_init(walk_state);
565#endif
566
567 /* Put the new state at the head of the walk list */
568
569 if (thread) {
570 acpi_ds_push_walk_state(walk_state, thread);
571 }
572
573 return_PTR(walk_state);
574}
575
576/*******************************************************************************
577 *
578 * FUNCTION: acpi_ds_init_aml_walk
579 *
580 * PARAMETERS: walk_state - New state to be initialized
581 * Op - Current parse op
582 * method_node - Control method NS node, if any
583 * aml_start - Start of AML
584 * aml_length - Length of AML
585 * Info - Method info block (params, etc.)
586 * pass_number - 1, 2, or 3
587 *
588 * RETURN: Status
589 *
590 * DESCRIPTION: Initialize a walk state for a pass 1 or 2 parse tree walk
591 *
592 ******************************************************************************/
593
594acpi_status
595acpi_ds_init_aml_walk(struct acpi_walk_state *walk_state,
596 union acpi_parse_object *op,
597 struct acpi_namespace_node *method_node,
598 u8 * aml_start,
599 u32 aml_length,
600 struct acpi_evaluate_info *info, u8 pass_number)
601{
602 acpi_status status;
603 struct acpi_parse_state *parser_state = &walk_state->parser_state;
604 union acpi_parse_object *extra_op;
605
606 ACPI_FUNCTION_TRACE(ds_init_aml_walk);
607
608 walk_state->parser_state.aml =
609 walk_state->parser_state.aml_start = aml_start;
610 walk_state->parser_state.aml_end =
611 walk_state->parser_state.pkg_end = aml_start + aml_length;
612
613 /* The next_op of the next_walk will be the beginning of the method */
614
615 walk_state->next_op = NULL;
616 walk_state->pass_number = pass_number;
617
618 if (info) {
619 walk_state->params = info->parameters;
620 walk_state->caller_return_desc = &info->return_object;
621 }
622
623 status = acpi_ps_init_scope(&walk_state->parser_state, op);
624 if (ACPI_FAILURE(status)) {
625 return_ACPI_STATUS(status);
626 }
627
628 if (method_node) {
629 walk_state->parser_state.start_node = method_node;
630 walk_state->walk_type = ACPI_WALK_METHOD;
631 walk_state->method_node = method_node;
632 walk_state->method_desc =
633 acpi_ns_get_attached_object(method_node);
634
635 /* Push start scope on scope stack and make it current */
636
637 status =
638 acpi_ds_scope_stack_push(method_node, ACPI_TYPE_METHOD,
639 walk_state);
640 if (ACPI_FAILURE(status)) {
641 return_ACPI_STATUS(status);
642 }
643
644 /* Init the method arguments */
645
646 status = acpi_ds_method_data_init_args(walk_state->params,
647 ACPI_METHOD_NUM_ARGS,
648 walk_state);
649 if (ACPI_FAILURE(status)) {
650 return_ACPI_STATUS(status);
651 }
652 } else {
653 /*
654 * Setup the current scope.
655 * Find a Named Op that has a namespace node associated with it.
656 * search upwards from this Op. Current scope is the first
657 * Op with a namespace node.
658 */
659 extra_op = parser_state->start_op;
660 while (extra_op && !extra_op->common.node) {
661 extra_op = extra_op->common.parent;
662 }
663
664 if (!extra_op) {
665 parser_state->start_node = NULL;
666 } else {
667 parser_state->start_node = extra_op->common.node;
668 }
669
670 if (parser_state->start_node) {
671
672 /* Push start scope on scope stack and make it current */
673
674 status =
675 acpi_ds_scope_stack_push(parser_state->start_node,
676 parser_state->start_node->
677 type, walk_state);
678 if (ACPI_FAILURE(status)) {
679 return_ACPI_STATUS(status);
680 }
681 }
682 }
683
684 status = acpi_ds_init_callbacks(walk_state, pass_number);
685 return_ACPI_STATUS(status);
686}
687
688/*******************************************************************************
689 *
690 * FUNCTION: acpi_ds_delete_walk_state
691 *
692 * PARAMETERS: walk_state - State to delete
693 *
694 * RETURN: Status
695 *
696 * DESCRIPTION: Delete a walk state including all internal data structures
697 *
698 ******************************************************************************/
699
700void acpi_ds_delete_walk_state(struct acpi_walk_state *walk_state)
701{
702 union acpi_generic_state *state;
703
704 ACPI_FUNCTION_TRACE_PTR(ds_delete_walk_state, walk_state);
705
706 if (!walk_state) {
707 return;
708 }
709
710 if (walk_state->descriptor_type != ACPI_DESC_TYPE_WALK) {
711 ACPI_ERROR((AE_INFO, "%p is not a valid walk state",
712 walk_state));
713 return;
714 }
715
716 /* There should not be any open scopes */
717
718 if (walk_state->parser_state.scope) {
719 ACPI_ERROR((AE_INFO, "%p walk still has a scope list",
720 walk_state));
721 acpi_ps_cleanup_scope(&walk_state->parser_state);
722 }
723
724 /* Always must free any linked control states */
725
726 while (walk_state->control_state) {
727 state = walk_state->control_state;
728 walk_state->control_state = state->common.next;
729
730 acpi_ut_delete_generic_state(state);
731 }
732
733 /* Always must free any linked parse states */
734
735 while (walk_state->scope_info) {
736 state = walk_state->scope_info;
737 walk_state->scope_info = state->common.next;
738
739 acpi_ut_delete_generic_state(state);
740 }
741
742 /* Always must free any stacked result states */
743
744 while (walk_state->results) {
745 state = walk_state->results;
746 walk_state->results = state->common.next;
747
748 acpi_ut_delete_generic_state(state);
749 }
750
751 ACPI_FREE(walk_state);
752 return_VOID;
753}
diff --git a/drivers/acpi/acpica/evevent.c b/drivers/acpi/acpica/evevent.c
new file mode 100644
index 00000000000..86bf08365da
--- /dev/null
+++ b/drivers/acpi/acpica/evevent.c
@@ -0,0 +1,313 @@
1/******************************************************************************
2 *
3 * Module Name: evevent - Fixed Event handling and dispatch
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46#include <acpi/acevents.h>
47
48#define _COMPONENT ACPI_EVENTS
49ACPI_MODULE_NAME("evevent")
50
51/* Local prototypes */
52static acpi_status acpi_ev_fixed_event_initialize(void);
53
54static u32 acpi_ev_fixed_event_dispatch(u32 event);
55
56/*******************************************************************************
57 *
58 * FUNCTION: acpi_ev_initialize_events
59 *
60 * PARAMETERS: None
61 *
62 * RETURN: Status
63 *
64 * DESCRIPTION: Initialize global data structures for ACPI events (Fixed, GPE)
65 *
66 ******************************************************************************/
67
68acpi_status acpi_ev_initialize_events(void)
69{
70 acpi_status status;
71
72 ACPI_FUNCTION_TRACE(ev_initialize_events);
73
74 /*
75 * Initialize the Fixed and General Purpose Events. This is done prior to
76 * enabling SCIs to prevent interrupts from occurring before the handlers
77 * are installed.
78 */
79 status = acpi_ev_fixed_event_initialize();
80 if (ACPI_FAILURE(status)) {
81 ACPI_EXCEPTION((AE_INFO, status,
82 "Unable to initialize fixed events"));
83 return_ACPI_STATUS(status);
84 }
85
86 status = acpi_ev_gpe_initialize();
87 if (ACPI_FAILURE(status)) {
88 ACPI_EXCEPTION((AE_INFO, status,
89 "Unable to initialize general purpose events"));
90 return_ACPI_STATUS(status);
91 }
92
93 return_ACPI_STATUS(status);
94}
95
96/*******************************************************************************
97 *
98 * FUNCTION: acpi_ev_install_fadt_gpes
99 *
100 * PARAMETERS: None
101 *
102 * RETURN: Status
103 *
104 * DESCRIPTION: Completes initialization of the FADT-defined GPE blocks
105 * (0 and 1). This causes the _PRW methods to be run, so the HW
106 * must be fully initialized at this point, including global lock
107 * support.
108 *
109 ******************************************************************************/
110
111acpi_status acpi_ev_install_fadt_gpes(void)
112{
113 acpi_status status;
114
115 ACPI_FUNCTION_TRACE(ev_install_fadt_gpes);
116
117 /* Namespace must be locked */
118
119 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
120 if (ACPI_FAILURE(status)) {
121 return (status);
122 }
123
124 /* FADT GPE Block 0 */
125
126 (void)acpi_ev_initialize_gpe_block(acpi_gbl_fadt_gpe_device,
127 acpi_gbl_gpe_fadt_blocks[0]);
128
129 /* FADT GPE Block 1 */
130
131 (void)acpi_ev_initialize_gpe_block(acpi_gbl_fadt_gpe_device,
132 acpi_gbl_gpe_fadt_blocks[1]);
133
134 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
135 return_ACPI_STATUS(AE_OK);
136}
137
138/*******************************************************************************
139 *
140 * FUNCTION: acpi_ev_install_xrupt_handlers
141 *
142 * PARAMETERS: None
143 *
144 * RETURN: Status
145 *
146 * DESCRIPTION: Install interrupt handlers for the SCI and Global Lock
147 *
148 ******************************************************************************/
149
150acpi_status acpi_ev_install_xrupt_handlers(void)
151{
152 acpi_status status;
153
154 ACPI_FUNCTION_TRACE(ev_install_xrupt_handlers);
155
156 /* Install the SCI handler */
157
158 status = acpi_ev_install_sci_handler();
159 if (ACPI_FAILURE(status)) {
160 ACPI_EXCEPTION((AE_INFO, status,
161 "Unable to install System Control Interrupt handler"));
162 return_ACPI_STATUS(status);
163 }
164
165 /* Install the handler for the Global Lock */
166
167 status = acpi_ev_init_global_lock_handler();
168 if (ACPI_FAILURE(status)) {
169 ACPI_EXCEPTION((AE_INFO, status,
170 "Unable to initialize Global Lock handler"));
171 return_ACPI_STATUS(status);
172 }
173
174 acpi_gbl_events_initialized = TRUE;
175 return_ACPI_STATUS(status);
176}
177
178/*******************************************************************************
179 *
180 * FUNCTION: acpi_ev_fixed_event_initialize
181 *
182 * PARAMETERS: None
183 *
184 * RETURN: Status
185 *
186 * DESCRIPTION: Install the fixed event handlers and enable the fixed events.
187 *
188 ******************************************************************************/
189
190static acpi_status acpi_ev_fixed_event_initialize(void)
191{
192 u32 i;
193 acpi_status status;
194
195 /*
196 * Initialize the structure that keeps track of fixed event handlers and
197 * enable the fixed events.
198 */
199 for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) {
200 acpi_gbl_fixed_event_handlers[i].handler = NULL;
201 acpi_gbl_fixed_event_handlers[i].context = NULL;
202
203 /* Enable the fixed event */
204
205 if (acpi_gbl_fixed_event_info[i].enable_register_id != 0xFF) {
206 status =
207 acpi_set_register(acpi_gbl_fixed_event_info[i].
208 enable_register_id, 0);
209 if (ACPI_FAILURE(status)) {
210 return (status);
211 }
212 }
213 }
214
215 return (AE_OK);
216}
217
218/*******************************************************************************
219 *
220 * FUNCTION: acpi_ev_fixed_event_detect
221 *
222 * PARAMETERS: None
223 *
224 * RETURN: INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED
225 *
226 * DESCRIPTION: Checks the PM status register for active fixed events
227 *
228 ******************************************************************************/
229
230u32 acpi_ev_fixed_event_detect(void)
231{
232 u32 int_status = ACPI_INTERRUPT_NOT_HANDLED;
233 u32 fixed_status;
234 u32 fixed_enable;
235 u32 i;
236
237 ACPI_FUNCTION_NAME(ev_fixed_event_detect);
238
239 /*
240 * Read the fixed feature status and enable registers, as all the cases
241 * depend on their values. Ignore errors here.
242 */
243 (void)acpi_hw_register_read(ACPI_REGISTER_PM1_STATUS, &fixed_status);
244 (void)acpi_hw_register_read(ACPI_REGISTER_PM1_ENABLE, &fixed_enable);
245
246 ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS,
247 "Fixed Event Block: Enable %08X Status %08X\n",
248 fixed_enable, fixed_status));
249
250 /*
251 * Check for all possible Fixed Events and dispatch those that are active
252 */
253 for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) {
254
255 /* Both the status and enable bits must be on for this event */
256
257 if ((fixed_status & acpi_gbl_fixed_event_info[i].
258 status_bit_mask)
259 && (fixed_enable & acpi_gbl_fixed_event_info[i].
260 enable_bit_mask)) {
261
262 /* Found an active (signalled) event */
263 acpi_os_fixed_event_count(i);
264 int_status |= acpi_ev_fixed_event_dispatch(i);
265 }
266 }
267
268 return (int_status);
269}
270
271/*******************************************************************************
272 *
273 * FUNCTION: acpi_ev_fixed_event_dispatch
274 *
275 * PARAMETERS: Event - Event type
276 *
277 * RETURN: INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED
278 *
279 * DESCRIPTION: Clears the status bit for the requested event, calls the
280 * handler that previously registered for the event.
281 *
282 ******************************************************************************/
283
284static u32 acpi_ev_fixed_event_dispatch(u32 event)
285{
286
287 ACPI_FUNCTION_ENTRY();
288
289 /* Clear the status bit */
290
291 (void)acpi_set_register(acpi_gbl_fixed_event_info[event].
292 status_register_id, 1);
293
294 /*
295 * Make sure we've got a handler. If not, report an error. The event is
296 * disabled to prevent further interrupts.
297 */
298 if (NULL == acpi_gbl_fixed_event_handlers[event].handler) {
299 (void)acpi_set_register(acpi_gbl_fixed_event_info[event].
300 enable_register_id, 0);
301
302 ACPI_ERROR((AE_INFO,
303 "No installed handler for fixed event [%08X]",
304 event));
305
306 return (ACPI_INTERRUPT_NOT_HANDLED);
307 }
308
309 /* Invoke the Fixed Event handler */
310
311 return ((acpi_gbl_fixed_event_handlers[event].
312 handler) (acpi_gbl_fixed_event_handlers[event].context));
313}
diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c
new file mode 100644
index 00000000000..d9779608dbd
--- /dev/null
+++ b/drivers/acpi/acpica/evgpe.c
@@ -0,0 +1,722 @@
1/******************************************************************************
2 *
3 * Module Name: evgpe - General Purpose Event handling and dispatch
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46#include <acpi/acevents.h>
47#include <acpi/acnamesp.h>
48
49#define _COMPONENT ACPI_EVENTS
50ACPI_MODULE_NAME("evgpe")
51
52/* Local prototypes */
53static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context);
54
55/*******************************************************************************
56 *
57 * FUNCTION: acpi_ev_set_gpe_type
58 *
59 * PARAMETERS: gpe_event_info - GPE to set
60 * Type - New type
61 *
62 * RETURN: Status
63 *
64 * DESCRIPTION: Sets the new type for the GPE (wake, run, or wake/run)
65 *
66 ******************************************************************************/
67
68acpi_status
69acpi_ev_set_gpe_type(struct acpi_gpe_event_info *gpe_event_info, u8 type)
70{
71 acpi_status status;
72
73 ACPI_FUNCTION_TRACE(ev_set_gpe_type);
74
75 /* Validate type and update register enable masks */
76
77 switch (type) {
78 case ACPI_GPE_TYPE_WAKE:
79 case ACPI_GPE_TYPE_RUNTIME:
80 case ACPI_GPE_TYPE_WAKE_RUN:
81 break;
82
83 default:
84 return_ACPI_STATUS(AE_BAD_PARAMETER);
85 }
86
87 /* Disable the GPE if currently enabled */
88
89 status = acpi_ev_disable_gpe(gpe_event_info);
90
91 /* Type was validated above */
92
93 gpe_event_info->flags &= ~ACPI_GPE_TYPE_MASK; /* Clear type bits */
94 gpe_event_info->flags |= type; /* Insert type */
95 return_ACPI_STATUS(status);
96}
97
98/*******************************************************************************
99 *
100 * FUNCTION: acpi_ev_update_gpe_enable_masks
101 *
102 * PARAMETERS: gpe_event_info - GPE to update
103 * Type - What to do: ACPI_GPE_DISABLE or
104 * ACPI_GPE_ENABLE
105 *
106 * RETURN: Status
107 *
108 * DESCRIPTION: Updates GPE register enable masks based on the GPE type
109 *
110 ******************************************************************************/
111
112acpi_status
113acpi_ev_update_gpe_enable_masks(struct acpi_gpe_event_info *gpe_event_info,
114 u8 type)
115{
116 struct acpi_gpe_register_info *gpe_register_info;
117 u8 register_bit;
118
119 ACPI_FUNCTION_TRACE(ev_update_gpe_enable_masks);
120
121 gpe_register_info = gpe_event_info->register_info;
122 if (!gpe_register_info) {
123 return_ACPI_STATUS(AE_NOT_EXIST);
124 }
125 register_bit = (u8)
126 (1 <<
127 (gpe_event_info->gpe_number - gpe_register_info->base_gpe_number));
128
129 /* 1) Disable case. Simply clear all enable bits */
130
131 if (type == ACPI_GPE_DISABLE) {
132 ACPI_CLEAR_BIT(gpe_register_info->enable_for_wake,
133 register_bit);
134 ACPI_CLEAR_BIT(gpe_register_info->enable_for_run, register_bit);
135 return_ACPI_STATUS(AE_OK);
136 }
137
138 /* 2) Enable case. Set/Clear the appropriate enable bits */
139
140 switch (gpe_event_info->flags & ACPI_GPE_TYPE_MASK) {
141 case ACPI_GPE_TYPE_WAKE:
142 ACPI_SET_BIT(gpe_register_info->enable_for_wake, register_bit);
143 ACPI_CLEAR_BIT(gpe_register_info->enable_for_run, register_bit);
144 break;
145
146 case ACPI_GPE_TYPE_RUNTIME:
147 ACPI_CLEAR_BIT(gpe_register_info->enable_for_wake,
148 register_bit);
149 ACPI_SET_BIT(gpe_register_info->enable_for_run, register_bit);
150 break;
151
152 case ACPI_GPE_TYPE_WAKE_RUN:
153 ACPI_SET_BIT(gpe_register_info->enable_for_wake, register_bit);
154 ACPI_SET_BIT(gpe_register_info->enable_for_run, register_bit);
155 break;
156
157 default:
158 return_ACPI_STATUS(AE_BAD_PARAMETER);
159 }
160
161 return_ACPI_STATUS(AE_OK);
162}
163
164/*******************************************************************************
165 *
166 * FUNCTION: acpi_ev_enable_gpe
167 *
168 * PARAMETERS: gpe_event_info - GPE to enable
169 * write_to_hardware - Enable now, or just mark data structs
170 * (WAKE GPEs should be deferred)
171 *
172 * RETURN: Status
173 *
174 * DESCRIPTION: Enable a GPE based on the GPE type
175 *
176 ******************************************************************************/
177
178acpi_status
179acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info,
180 u8 write_to_hardware)
181{
182 acpi_status status;
183
184 ACPI_FUNCTION_TRACE(ev_enable_gpe);
185
186 /* Make sure HW enable masks are updated */
187
188 status =
189 acpi_ev_update_gpe_enable_masks(gpe_event_info, ACPI_GPE_ENABLE);
190 if (ACPI_FAILURE(status)) {
191 return_ACPI_STATUS(status);
192 }
193
194 /* Mark wake-enabled or HW enable, or both */
195
196 switch (gpe_event_info->flags & ACPI_GPE_TYPE_MASK) {
197 case ACPI_GPE_TYPE_WAKE:
198
199 ACPI_SET_BIT(gpe_event_info->flags, ACPI_GPE_WAKE_ENABLED);
200 break;
201
202 case ACPI_GPE_TYPE_WAKE_RUN:
203
204 ACPI_SET_BIT(gpe_event_info->flags, ACPI_GPE_WAKE_ENABLED);
205
206 /*lint -fallthrough */
207
208 case ACPI_GPE_TYPE_RUNTIME:
209
210 ACPI_SET_BIT(gpe_event_info->flags, ACPI_GPE_RUN_ENABLED);
211
212 if (write_to_hardware) {
213
214 /* Clear the GPE (of stale events), then enable it */
215
216 status = acpi_hw_clear_gpe(gpe_event_info);
217 if (ACPI_FAILURE(status)) {
218 return_ACPI_STATUS(status);
219 }
220
221 /* Enable the requested runtime GPE */
222
223 status = acpi_hw_write_gpe_enable_reg(gpe_event_info);
224 }
225 break;
226
227 default:
228 return_ACPI_STATUS(AE_BAD_PARAMETER);
229 }
230
231 return_ACPI_STATUS(AE_OK);
232}
233
234/*******************************************************************************
235 *
236 * FUNCTION: acpi_ev_disable_gpe
237 *
238 * PARAMETERS: gpe_event_info - GPE to disable
239 *
240 * RETURN: Status
241 *
242 * DESCRIPTION: Disable a GPE based on the GPE type
243 *
244 ******************************************************************************/
245
246acpi_status acpi_ev_disable_gpe(struct acpi_gpe_event_info *gpe_event_info)
247{
248 acpi_status status;
249
250 ACPI_FUNCTION_TRACE(ev_disable_gpe);
251
252 /* Make sure HW enable masks are updated */
253
254 status =
255 acpi_ev_update_gpe_enable_masks(gpe_event_info, ACPI_GPE_DISABLE);
256 if (ACPI_FAILURE(status)) {
257 return_ACPI_STATUS(status);
258 }
259
260 /* Clear the appropriate enabled flags for this GPE */
261
262 switch (gpe_event_info->flags & ACPI_GPE_TYPE_MASK) {
263 case ACPI_GPE_TYPE_WAKE:
264 ACPI_CLEAR_BIT(gpe_event_info->flags, ACPI_GPE_WAKE_ENABLED);
265 break;
266
267 case ACPI_GPE_TYPE_WAKE_RUN:
268 ACPI_CLEAR_BIT(gpe_event_info->flags, ACPI_GPE_WAKE_ENABLED);
269
270 /* fallthrough */
271
272 case ACPI_GPE_TYPE_RUNTIME:
273
274 /* Disable the requested runtime GPE */
275
276 ACPI_CLEAR_BIT(gpe_event_info->flags, ACPI_GPE_RUN_ENABLED);
277 break;
278
279 default:
280 break;
281 }
282
283 /*
284 * Even if we don't know the GPE type, make sure that we always
285 * disable it. low_disable_gpe will just clear the enable bit for this
286 * GPE and write it. It will not write out the current GPE enable mask,
287 * since this may inadvertently enable GPEs too early, if a rogue GPE has
288 * come in during ACPICA initialization - possibly as a result of AML or
289 * other code that has enabled the GPE.
290 */
291 status = acpi_hw_low_disable_gpe(gpe_event_info);
292 return_ACPI_STATUS(status);
293}
294
295/*******************************************************************************
296 *
297 * FUNCTION: acpi_ev_get_gpe_event_info
298 *
299 * PARAMETERS: gpe_device - Device node. NULL for GPE0/GPE1
300 * gpe_number - Raw GPE number
301 *
302 * RETURN: A GPE event_info struct. NULL if not a valid GPE
303 *
304 * DESCRIPTION: Returns the event_info struct associated with this GPE.
305 * Validates the gpe_block and the gpe_number
306 *
307 * Should be called only when the GPE lists are semaphore locked
308 * and not subject to change.
309 *
310 ******************************************************************************/
311
312struct acpi_gpe_event_info *acpi_ev_get_gpe_event_info(acpi_handle gpe_device,
313 u32 gpe_number)
314{
315 union acpi_operand_object *obj_desc;
316 struct acpi_gpe_block_info *gpe_block;
317 u32 i;
318
319 ACPI_FUNCTION_ENTRY();
320
321 /* A NULL gpe_block means use the FADT-defined GPE block(s) */
322
323 if (!gpe_device) {
324
325 /* Examine GPE Block 0 and 1 (These blocks are permanent) */
326
327 for (i = 0; i < ACPI_MAX_GPE_BLOCKS; i++) {
328 gpe_block = acpi_gbl_gpe_fadt_blocks[i];
329 if (gpe_block) {
330 if ((gpe_number >= gpe_block->block_base_number)
331 && (gpe_number <
332 gpe_block->block_base_number +
333 (gpe_block->register_count * 8))) {
334 return (&gpe_block->
335 event_info[gpe_number -
336 gpe_block->
337 block_base_number]);
338 }
339 }
340 }
341
342 /* The gpe_number was not in the range of either FADT GPE block */
343
344 return (NULL);
345 }
346
347 /* A Non-NULL gpe_device means this is a GPE Block Device */
348
349 obj_desc = acpi_ns_get_attached_object((struct acpi_namespace_node *)
350 gpe_device);
351 if (!obj_desc || !obj_desc->device.gpe_block) {
352 return (NULL);
353 }
354
355 gpe_block = obj_desc->device.gpe_block;
356
357 if ((gpe_number >= gpe_block->block_base_number) &&
358 (gpe_number <
359 gpe_block->block_base_number + (gpe_block->register_count * 8))) {
360 return (&gpe_block->
361 event_info[gpe_number - gpe_block->block_base_number]);
362 }
363
364 return (NULL);
365}
366
367/*******************************************************************************
368 *
369 * FUNCTION: acpi_ev_gpe_detect
370 *
371 * PARAMETERS: gpe_xrupt_list - Interrupt block for this interrupt.
372 * Can have multiple GPE blocks attached.
373 *
374 * RETURN: INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED
375 *
376 * DESCRIPTION: Detect if any GP events have occurred. This function is
377 * executed at interrupt level.
378 *
379 ******************************************************************************/
380
381u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list)
382{
383 acpi_status status;
384 struct acpi_gpe_block_info *gpe_block;
385 struct acpi_gpe_register_info *gpe_register_info;
386 u32 int_status = ACPI_INTERRUPT_NOT_HANDLED;
387 u8 enabled_status_byte;
388 u32 status_reg;
389 u32 enable_reg;
390 acpi_cpu_flags flags;
391 u32 i;
392 u32 j;
393
394 ACPI_FUNCTION_NAME(ev_gpe_detect);
395
396 /* Check for the case where there are no GPEs */
397
398 if (!gpe_xrupt_list) {
399 return (int_status);
400 }
401
402 /*
403 * We need to obtain the GPE lock for both the data structs and registers
404 * Note: Not necessary to obtain the hardware lock, since the GPE
405 * registers are owned by the gpe_lock.
406 */
407 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
408
409 /* Examine all GPE blocks attached to this interrupt level */
410
411 gpe_block = gpe_xrupt_list->gpe_block_list_head;
412 while (gpe_block) {
413 /*
414 * Read all of the 8-bit GPE status and enable registers in this GPE
415 * block, saving all of them. Find all currently active GP events.
416 */
417 for (i = 0; i < gpe_block->register_count; i++) {
418
419 /* Get the next status/enable pair */
420
421 gpe_register_info = &gpe_block->register_info[i];
422
423 /* Read the Status Register */
424
425 status =
426 acpi_read(&status_reg,
427 &gpe_register_info->status_address);
428 if (ACPI_FAILURE(status)) {
429 goto unlock_and_exit;
430 }
431
432 /* Read the Enable Register */
433
434 status =
435 acpi_read(&enable_reg,
436 &gpe_register_info->enable_address);
437 if (ACPI_FAILURE(status)) {
438 goto unlock_and_exit;
439 }
440
441 ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS,
442 "Read GPE Register at GPE%X: Status=%02X, Enable=%02X\n",
443 gpe_register_info->base_gpe_number,
444 status_reg, enable_reg));
445
446 /* Check if there is anything active at all in this register */
447
448 enabled_status_byte = (u8) (status_reg & enable_reg);
449 if (!enabled_status_byte) {
450
451 /* No active GPEs in this register, move on */
452
453 continue;
454 }
455
456 /* Now look at the individual GPEs in this byte register */
457
458 for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) {
459
460 /* Examine one GPE bit */
461
462 if (enabled_status_byte & (1 << j)) {
463 /*
464 * Found an active GPE. Dispatch the event to a handler
465 * or method.
466 */
467 int_status |=
468 acpi_ev_gpe_dispatch(&gpe_block->
469 event_info[((acpi_size) i * ACPI_GPE_REGISTER_WIDTH) + j], j + gpe_register_info->base_gpe_number);
470 }
471 }
472 }
473
474 gpe_block = gpe_block->next;
475 }
476
477 unlock_and_exit:
478
479 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
480 return (int_status);
481}
482
483/*******************************************************************************
484 *
485 * FUNCTION: acpi_ev_asynch_execute_gpe_method
486 *
487 * PARAMETERS: Context (gpe_event_info) - Info for this GPE
488 *
489 * RETURN: None
490 *
491 * DESCRIPTION: Perform the actual execution of a GPE control method. This
492 * function is called from an invocation of acpi_os_execute and
493 * therefore does NOT execute at interrupt level - so that
494 * the control method itself is not executed in the context of
495 * an interrupt handler.
496 *
497 ******************************************************************************/
498static void acpi_ev_asynch_enable_gpe(void *context);
499
500static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)
501{
502 struct acpi_gpe_event_info *gpe_event_info = (void *)context;
503 acpi_status status;
504 struct acpi_gpe_event_info local_gpe_event_info;
505 struct acpi_evaluate_info *info;
506
507 ACPI_FUNCTION_TRACE(ev_asynch_execute_gpe_method);
508
509 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
510 if (ACPI_FAILURE(status)) {
511 return_VOID;
512 }
513
514 /* Must revalidate the gpe_number/gpe_block */
515
516 if (!acpi_ev_valid_gpe_event(gpe_event_info)) {
517 status = acpi_ut_release_mutex(ACPI_MTX_EVENTS);
518 return_VOID;
519 }
520
521 /* Set the GPE flags for return to enabled state */
522
523 (void)acpi_ev_enable_gpe(gpe_event_info, FALSE);
524
525 /*
526 * Take a snapshot of the GPE info for this level - we copy the info to
527 * prevent a race condition with remove_handler/remove_block.
528 */
529 ACPI_MEMCPY(&local_gpe_event_info, gpe_event_info,
530 sizeof(struct acpi_gpe_event_info));
531
532 status = acpi_ut_release_mutex(ACPI_MTX_EVENTS);
533 if (ACPI_FAILURE(status)) {
534 return_VOID;
535 }
536
537 /*
538 * Must check for control method type dispatch one more time to avoid a
539 * race with ev_gpe_install_handler
540 */
541 if ((local_gpe_event_info.flags & ACPI_GPE_DISPATCH_MASK) ==
542 ACPI_GPE_DISPATCH_METHOD) {
543
544 /* Allocate the evaluation information block */
545
546 info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
547 if (!info) {
548 status = AE_NO_MEMORY;
549 } else {
550 /*
551 * Invoke the GPE Method (_Lxx, _Exx) i.e., evaluate the _Lxx/_Exx
552 * control method that corresponds to this GPE
553 */
554 info->prefix_node =
555 local_gpe_event_info.dispatch.method_node;
556 info->flags = ACPI_IGNORE_RETURN_VALUE;
557
558 status = acpi_ns_evaluate(info);
559 ACPI_FREE(info);
560 }
561
562 if (ACPI_FAILURE(status)) {
563 ACPI_EXCEPTION((AE_INFO, status,
564 "while evaluating GPE method [%4.4s]",
565 acpi_ut_get_node_name
566 (local_gpe_event_info.dispatch.
567 method_node)));
568 }
569 }
570 /* Defer enabling of GPE until all notify handlers are done */
571 acpi_os_execute(OSL_NOTIFY_HANDLER, acpi_ev_asynch_enable_gpe,
572 gpe_event_info);
573 return_VOID;
574}
575
576static void acpi_ev_asynch_enable_gpe(void *context)
577{
578 struct acpi_gpe_event_info *gpe_event_info = context;
579 acpi_status status;
580 if ((gpe_event_info->flags & ACPI_GPE_XRUPT_TYPE_MASK) ==
581 ACPI_GPE_LEVEL_TRIGGERED) {
582 /*
583 * GPE is level-triggered, we clear the GPE status bit after handling
584 * the event.
585 */
586 status = acpi_hw_clear_gpe(gpe_event_info);
587 if (ACPI_FAILURE(status)) {
588 return_VOID;
589 }
590 }
591
592 /* Enable this GPE */
593 (void)acpi_hw_write_gpe_enable_reg(gpe_event_info);
594 return_VOID;
595}
596
597/*******************************************************************************
598 *
599 * FUNCTION: acpi_ev_gpe_dispatch
600 *
601 * PARAMETERS: gpe_event_info - Info for this GPE
602 * gpe_number - Number relative to the parent GPE block
603 *
604 * RETURN: INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED
605 *
606 * DESCRIPTION: Dispatch a General Purpose Event to either a function (e.g. EC)
607 * or method (e.g. _Lxx/_Exx) handler.
608 *
609 * This function executes at interrupt level.
610 *
611 ******************************************************************************/
612
613u32
614acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number)
615{
616 acpi_status status;
617
618 ACPI_FUNCTION_TRACE(ev_gpe_dispatch);
619
620 acpi_os_gpe_count(gpe_number);
621
622 /*
623 * If edge-triggered, clear the GPE status bit now. Note that
624 * level-triggered events are cleared after the GPE is serviced.
625 */
626 if ((gpe_event_info->flags & ACPI_GPE_XRUPT_TYPE_MASK) ==
627 ACPI_GPE_EDGE_TRIGGERED) {
628 status = acpi_hw_clear_gpe(gpe_event_info);
629 if (ACPI_FAILURE(status)) {
630 ACPI_EXCEPTION((AE_INFO, status,
631 "Unable to clear GPE[%2X]",
632 gpe_number));
633 return_UINT32(ACPI_INTERRUPT_NOT_HANDLED);
634 }
635 }
636
637 /*
638 * Dispatch the GPE to either an installed handler, or the control method
639 * associated with this GPE (_Lxx or _Exx). If a handler exists, we invoke
640 * it and do not attempt to run the method. If there is neither a handler
641 * nor a method, we disable this GPE to prevent further such pointless
642 * events from firing.
643 */
644 switch (gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) {
645 case ACPI_GPE_DISPATCH_HANDLER:
646
647 /*
648 * Invoke the installed handler (at interrupt level)
649 * Ignore return status for now.
650 * TBD: leave GPE disabled on error?
651 */
652 (void)gpe_event_info->dispatch.handler->address(gpe_event_info->
653 dispatch.
654 handler->
655 context);
656
657 /* It is now safe to clear level-triggered events. */
658
659 if ((gpe_event_info->flags & ACPI_GPE_XRUPT_TYPE_MASK) ==
660 ACPI_GPE_LEVEL_TRIGGERED) {
661 status = acpi_hw_clear_gpe(gpe_event_info);
662 if (ACPI_FAILURE(status)) {
663 ACPI_EXCEPTION((AE_INFO, status,
664 "Unable to clear GPE[%2X]",
665 gpe_number));
666 return_UINT32(ACPI_INTERRUPT_NOT_HANDLED);
667 }
668 }
669 break;
670
671 case ACPI_GPE_DISPATCH_METHOD:
672
673 /*
674 * Disable the GPE, so it doesn't keep firing before the method has a
675 * chance to run (it runs asynchronously with interrupts enabled).
676 */
677 status = acpi_ev_disable_gpe(gpe_event_info);
678 if (ACPI_FAILURE(status)) {
679 ACPI_EXCEPTION((AE_INFO, status,
680 "Unable to disable GPE[%2X]",
681 gpe_number));
682 return_UINT32(ACPI_INTERRUPT_NOT_HANDLED);
683 }
684
685 /*
686 * Execute the method associated with the GPE
687 * NOTE: Level-triggered GPEs are cleared after the method completes.
688 */
689 status = acpi_os_execute(OSL_GPE_HANDLER,
690 acpi_ev_asynch_execute_gpe_method,
691 gpe_event_info);
692 if (ACPI_FAILURE(status)) {
693 ACPI_EXCEPTION((AE_INFO, status,
694 "Unable to queue handler for GPE[%2X] - event disabled",
695 gpe_number));
696 }
697 break;
698
699 default:
700
701 /* No handler or method to run! */
702
703 ACPI_ERROR((AE_INFO,
704 "No handler or method for GPE[%2X], disabling event",
705 gpe_number));
706
707 /*
708 * Disable the GPE. The GPE will remain disabled until the ACPICA
709 * Core Subsystem is restarted, or a handler is installed.
710 */
711 status = acpi_ev_disable_gpe(gpe_event_info);
712 if (ACPI_FAILURE(status)) {
713 ACPI_EXCEPTION((AE_INFO, status,
714 "Unable to disable GPE[%2X]",
715 gpe_number));
716 return_UINT32(ACPI_INTERRUPT_NOT_HANDLED);
717 }
718 break;
719 }
720
721 return_UINT32(ACPI_INTERRUPT_HANDLED);
722}
diff --git a/drivers/acpi/acpica/evgpeblk.c b/drivers/acpi/acpica/evgpeblk.c
new file mode 100644
index 00000000000..2a8d1856038
--- /dev/null
+++ b/drivers/acpi/acpica/evgpeblk.c
@@ -0,0 +1,1227 @@
1/******************************************************************************
2 *
3 * Module Name: evgpeblk - GPE block creation and initialization.
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46#include <acpi/acevents.h>
47#include <acpi/acnamesp.h>
48
49#define _COMPONENT ACPI_EVENTS
50ACPI_MODULE_NAME("evgpeblk")
51
52/* Local prototypes */
53static acpi_status
54acpi_ev_save_method_info(acpi_handle obj_handle,
55 u32 level, void *obj_desc, void **return_value);
56
57static acpi_status
58acpi_ev_match_prw_and_gpe(acpi_handle obj_handle,
59 u32 level, void *info, void **return_value);
60
61static struct acpi_gpe_xrupt_info *acpi_ev_get_gpe_xrupt_block(u32
62 interrupt_number);
63
64static acpi_status
65acpi_ev_delete_gpe_xrupt(struct acpi_gpe_xrupt_info *gpe_xrupt);
66
67static acpi_status
68acpi_ev_install_gpe_block(struct acpi_gpe_block_info *gpe_block,
69 u32 interrupt_number);
70
71static acpi_status
72acpi_ev_create_gpe_info_blocks(struct acpi_gpe_block_info *gpe_block);
73
74/*******************************************************************************
75 *
76 * FUNCTION: acpi_ev_valid_gpe_event
77 *
78 * PARAMETERS: gpe_event_info - Info for this GPE
79 *
80 * RETURN: TRUE if the gpe_event is valid
81 *
82 * DESCRIPTION: Validate a GPE event. DO NOT CALL FROM INTERRUPT LEVEL.
83 * Should be called only when the GPE lists are semaphore locked
84 * and not subject to change.
85 *
86 ******************************************************************************/
87
88u8 acpi_ev_valid_gpe_event(struct acpi_gpe_event_info *gpe_event_info)
89{
90 struct acpi_gpe_xrupt_info *gpe_xrupt_block;
91 struct acpi_gpe_block_info *gpe_block;
92
93 ACPI_FUNCTION_ENTRY();
94
95 /* No need for spin lock since we are not changing any list elements */
96
97 /* Walk the GPE interrupt levels */
98
99 gpe_xrupt_block = acpi_gbl_gpe_xrupt_list_head;
100 while (gpe_xrupt_block) {
101 gpe_block = gpe_xrupt_block->gpe_block_list_head;
102
103 /* Walk the GPE blocks on this interrupt level */
104
105 while (gpe_block) {
106 if ((&gpe_block->event_info[0] <= gpe_event_info) &&
107 (&gpe_block->
108 event_info[((acpi_size) gpe_block->
109 register_count) * 8] >
110 gpe_event_info)) {
111 return (TRUE);
112 }
113
114 gpe_block = gpe_block->next;
115 }
116
117 gpe_xrupt_block = gpe_xrupt_block->next;
118 }
119
120 return (FALSE);
121}
122
123/*******************************************************************************
124 *
125 * FUNCTION: acpi_ev_walk_gpe_list
126 *
127 * PARAMETERS: gpe_walk_callback - Routine called for each GPE block
128 * Context - Value passed to callback
129 *
130 * RETURN: Status
131 *
132 * DESCRIPTION: Walk the GPE lists.
133 *
134 ******************************************************************************/
135
136acpi_status
137acpi_ev_walk_gpe_list(acpi_gpe_callback gpe_walk_callback, void *context)
138{
139 struct acpi_gpe_block_info *gpe_block;
140 struct acpi_gpe_xrupt_info *gpe_xrupt_info;
141 acpi_status status = AE_OK;
142 acpi_cpu_flags flags;
143
144 ACPI_FUNCTION_TRACE(ev_walk_gpe_list);
145
146 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
147
148 /* Walk the interrupt level descriptor list */
149
150 gpe_xrupt_info = acpi_gbl_gpe_xrupt_list_head;
151 while (gpe_xrupt_info) {
152
153 /* Walk all Gpe Blocks attached to this interrupt level */
154
155 gpe_block = gpe_xrupt_info->gpe_block_list_head;
156 while (gpe_block) {
157
158 /* One callback per GPE block */
159
160 status =
161 gpe_walk_callback(gpe_xrupt_info, gpe_block,
162 context);
163 if (ACPI_FAILURE(status)) {
164 if (status == AE_CTRL_END) { /* Callback abort */
165 status = AE_OK;
166 }
167 goto unlock_and_exit;
168 }
169
170 gpe_block = gpe_block->next;
171 }
172
173 gpe_xrupt_info = gpe_xrupt_info->next;
174 }
175
176 unlock_and_exit:
177 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
178 return_ACPI_STATUS(status);
179}
180
181/*******************************************************************************
182 *
183 * FUNCTION: acpi_ev_delete_gpe_handlers
184 *
185 * PARAMETERS: gpe_xrupt_info - GPE Interrupt info
186 * gpe_block - Gpe Block info
187 *
188 * RETURN: Status
189 *
190 * DESCRIPTION: Delete all Handler objects found in the GPE data structs.
191 * Used only prior to termination.
192 *
193 ******************************************************************************/
194
195acpi_status
196acpi_ev_delete_gpe_handlers(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
197 struct acpi_gpe_block_info *gpe_block,
198 void *context)
199{
200 struct acpi_gpe_event_info *gpe_event_info;
201 u32 i;
202 u32 j;
203
204 ACPI_FUNCTION_TRACE(ev_delete_gpe_handlers);
205
206 /* Examine each GPE Register within the block */
207
208 for (i = 0; i < gpe_block->register_count; i++) {
209
210 /* Now look at the individual GPEs in this byte register */
211
212 for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) {
213 gpe_event_info =
214 &gpe_block->
215 event_info[((acpi_size) i *
216 ACPI_GPE_REGISTER_WIDTH) + j];
217
218 if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) ==
219 ACPI_GPE_DISPATCH_HANDLER) {
220 ACPI_FREE(gpe_event_info->dispatch.handler);
221 gpe_event_info->dispatch.handler = NULL;
222 gpe_event_info->flags &=
223 ~ACPI_GPE_DISPATCH_MASK;
224 }
225 }
226 }
227
228 return_ACPI_STATUS(AE_OK);
229}
230
231/*******************************************************************************
232 *
233 * FUNCTION: acpi_ev_save_method_info
234 *
235 * PARAMETERS: Callback from walk_namespace
236 *
237 * RETURN: Status
238 *
239 * DESCRIPTION: Called from acpi_walk_namespace. Expects each object to be a
240 * control method under the _GPE portion of the namespace.
241 * Extract the name and GPE type from the object, saving this
242 * information for quick lookup during GPE dispatch
243 *
244 * The name of each GPE control method is of the form:
245 * "_Lxx" or "_Exx"
246 * Where:
247 * L - means that the GPE is level triggered
248 * E - means that the GPE is edge triggered
249 * xx - is the GPE number [in HEX]
250 *
251 ******************************************************************************/
252
253static acpi_status
254acpi_ev_save_method_info(acpi_handle obj_handle,
255 u32 level, void *obj_desc, void **return_value)
256{
257 struct acpi_gpe_block_info *gpe_block = (void *)obj_desc;
258 struct acpi_gpe_event_info *gpe_event_info;
259 u32 gpe_number;
260 char name[ACPI_NAME_SIZE + 1];
261 u8 type;
262 acpi_status status;
263
264 ACPI_FUNCTION_TRACE(ev_save_method_info);
265
266 /*
267 * _Lxx and _Exx GPE method support
268 *
269 * 1) Extract the name from the object and convert to a string
270 */
271 ACPI_MOVE_32_TO_32(name,
272 &((struct acpi_namespace_node *)obj_handle)->name.
273 integer);
274 name[ACPI_NAME_SIZE] = 0;
275
276 /*
277 * 2) Edge/Level determination is based on the 2nd character
278 * of the method name
279 *
280 * NOTE: Default GPE type is RUNTIME. May be changed later to WAKE
281 * if a _PRW object is found that points to this GPE.
282 */
283 switch (name[1]) {
284 case 'L':
285 type = ACPI_GPE_LEVEL_TRIGGERED;
286 break;
287
288 case 'E':
289 type = ACPI_GPE_EDGE_TRIGGERED;
290 break;
291
292 default:
293 /* Unknown method type, just ignore it! */
294
295 ACPI_DEBUG_PRINT((ACPI_DB_LOAD,
296 "Ignoring unknown GPE method type: %s (name not of form _Lxx or _Exx)",
297 name));
298 return_ACPI_STATUS(AE_OK);
299 }
300
301 /* Convert the last two characters of the name to the GPE Number */
302
303 gpe_number = ACPI_STRTOUL(&name[2], NULL, 16);
304 if (gpe_number == ACPI_UINT32_MAX) {
305
306 /* Conversion failed; invalid method, just ignore it */
307
308 ACPI_DEBUG_PRINT((ACPI_DB_LOAD,
309 "Could not extract GPE number from name: %s (name is not of form _Lxx or _Exx)",
310 name));
311 return_ACPI_STATUS(AE_OK);
312 }
313
314 /* Ensure that we have a valid GPE number for this GPE block */
315
316 if ((gpe_number < gpe_block->block_base_number) ||
317 (gpe_number >=
318 (gpe_block->block_base_number +
319 (gpe_block->register_count * 8)))) {
320 /*
321 * Not valid for this GPE block, just ignore it. However, it may be
322 * valid for a different GPE block, since GPE0 and GPE1 methods both
323 * appear under \_GPE.
324 */
325 return_ACPI_STATUS(AE_OK);
326 }
327
328 /*
329 * Now we can add this information to the gpe_event_info block for use
330 * during dispatch of this GPE. Default type is RUNTIME, although this may
331 * change when the _PRW methods are executed later.
332 */
333 gpe_event_info =
334 &gpe_block->event_info[gpe_number - gpe_block->block_base_number];
335
336 gpe_event_info->flags = (u8)
337 (type | ACPI_GPE_DISPATCH_METHOD | ACPI_GPE_TYPE_RUNTIME);
338
339 gpe_event_info->dispatch.method_node =
340 (struct acpi_namespace_node *)obj_handle;
341
342 /* Update enable mask, but don't enable the HW GPE as of yet */
343
344 status = acpi_ev_enable_gpe(gpe_event_info, FALSE);
345
346 ACPI_DEBUG_PRINT((ACPI_DB_LOAD,
347 "Registered GPE method %s as GPE number 0x%.2X\n",
348 name, gpe_number));
349 return_ACPI_STATUS(status);
350}
351
352/*******************************************************************************
353 *
354 * FUNCTION: acpi_ev_match_prw_and_gpe
355 *
356 * PARAMETERS: Callback from walk_namespace
357 *
358 * RETURN: Status. NOTE: We ignore errors so that the _PRW walk is
359 * not aborted on a single _PRW failure.
360 *
361 * DESCRIPTION: Called from acpi_walk_namespace. Expects each object to be a
362 * Device. Run the _PRW method. If present, extract the GPE
363 * number and mark the GPE as a WAKE GPE.
364 *
365 ******************************************************************************/
366
367static acpi_status
368acpi_ev_match_prw_and_gpe(acpi_handle obj_handle,
369 u32 level, void *info, void **return_value)
370{
371 struct acpi_gpe_walk_info *gpe_info = (void *)info;
372 struct acpi_namespace_node *gpe_device;
373 struct acpi_gpe_block_info *gpe_block;
374 struct acpi_namespace_node *target_gpe_device;
375 struct acpi_gpe_event_info *gpe_event_info;
376 union acpi_operand_object *pkg_desc;
377 union acpi_operand_object *obj_desc;
378 u32 gpe_number;
379 acpi_status status;
380
381 ACPI_FUNCTION_TRACE(ev_match_prw_and_gpe);
382
383 /* Check for a _PRW method under this device */
384
385 status = acpi_ut_evaluate_object(obj_handle, METHOD_NAME__PRW,
386 ACPI_BTYPE_PACKAGE, &pkg_desc);
387 if (ACPI_FAILURE(status)) {
388
389 /* Ignore all errors from _PRW, we don't want to abort the subsystem */
390
391 return_ACPI_STATUS(AE_OK);
392 }
393
394 /* The returned _PRW package must have at least two elements */
395
396 if (pkg_desc->package.count < 2) {
397 goto cleanup;
398 }
399
400 /* Extract pointers from the input context */
401
402 gpe_device = gpe_info->gpe_device;
403 gpe_block = gpe_info->gpe_block;
404
405 /*
406 * The _PRW object must return a package, we are only interested in the
407 * first element
408 */
409 obj_desc = pkg_desc->package.elements[0];
410
411 if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {
412
413 /* Use FADT-defined GPE device (from definition of _PRW) */
414
415 target_gpe_device = acpi_gbl_fadt_gpe_device;
416
417 /* Integer is the GPE number in the FADT described GPE blocks */
418
419 gpe_number = (u32) obj_desc->integer.value;
420 } else if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_PACKAGE) {
421
422 /* Package contains a GPE reference and GPE number within a GPE block */
423
424 if ((obj_desc->package.count < 2) ||
425 (ACPI_GET_OBJECT_TYPE(obj_desc->package.elements[0]) !=
426 ACPI_TYPE_LOCAL_REFERENCE)
427 || (ACPI_GET_OBJECT_TYPE(obj_desc->package.elements[1]) !=
428 ACPI_TYPE_INTEGER)) {
429 goto cleanup;
430 }
431
432 /* Get GPE block reference and decode */
433
434 target_gpe_device =
435 obj_desc->package.elements[0]->reference.node;
436 gpe_number = (u32) obj_desc->package.elements[1]->integer.value;
437 } else {
438 /* Unknown type, just ignore it */
439
440 goto cleanup;
441 }
442
443 /*
444 * Is this GPE within this block?
445 *
446 * TRUE if and only if these conditions are true:
447 * 1) The GPE devices match.
448 * 2) The GPE index(number) is within the range of the Gpe Block
449 * associated with the GPE device.
450 */
451 if ((gpe_device == target_gpe_device) &&
452 (gpe_number >= gpe_block->block_base_number) &&
453 (gpe_number <
454 gpe_block->block_base_number + (gpe_block->register_count * 8))) {
455 gpe_event_info =
456 &gpe_block->event_info[gpe_number -
457 gpe_block->block_base_number];
458
459 /* Mark GPE for WAKE-ONLY but WAKE_DISABLED */
460
461 gpe_event_info->flags &=
462 ~(ACPI_GPE_WAKE_ENABLED | ACPI_GPE_RUN_ENABLED);
463
464 status =
465 acpi_ev_set_gpe_type(gpe_event_info, ACPI_GPE_TYPE_WAKE);
466 if (ACPI_FAILURE(status)) {
467 goto cleanup;
468 }
469
470 status =
471 acpi_ev_update_gpe_enable_masks(gpe_event_info,
472 ACPI_GPE_DISABLE);
473 }
474
475 cleanup:
476 acpi_ut_remove_reference(pkg_desc);
477 return_ACPI_STATUS(AE_OK);
478}
479
480/*******************************************************************************
481 *
482 * FUNCTION: acpi_ev_get_gpe_xrupt_block
483 *
484 * PARAMETERS: interrupt_number - Interrupt for a GPE block
485 *
486 * RETURN: A GPE interrupt block
487 *
488 * DESCRIPTION: Get or Create a GPE interrupt block. There is one interrupt
489 * block per unique interrupt level used for GPEs. Should be
490 * called only when the GPE lists are semaphore locked and not
491 * subject to change.
492 *
493 ******************************************************************************/
494
495static struct acpi_gpe_xrupt_info *acpi_ev_get_gpe_xrupt_block(u32
496 interrupt_number)
497{
498 struct acpi_gpe_xrupt_info *next_gpe_xrupt;
499 struct acpi_gpe_xrupt_info *gpe_xrupt;
500 acpi_status status;
501 acpi_cpu_flags flags;
502
503 ACPI_FUNCTION_TRACE(ev_get_gpe_xrupt_block);
504
505 /* No need for lock since we are not changing any list elements here */
506
507 next_gpe_xrupt = acpi_gbl_gpe_xrupt_list_head;
508 while (next_gpe_xrupt) {
509 if (next_gpe_xrupt->interrupt_number == interrupt_number) {
510 return_PTR(next_gpe_xrupt);
511 }
512
513 next_gpe_xrupt = next_gpe_xrupt->next;
514 }
515
516 /* Not found, must allocate a new xrupt descriptor */
517
518 gpe_xrupt = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_gpe_xrupt_info));
519 if (!gpe_xrupt) {
520 return_PTR(NULL);
521 }
522
523 gpe_xrupt->interrupt_number = interrupt_number;
524
525 /* Install new interrupt descriptor with spin lock */
526
527 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
528 if (acpi_gbl_gpe_xrupt_list_head) {
529 next_gpe_xrupt = acpi_gbl_gpe_xrupt_list_head;
530 while (next_gpe_xrupt->next) {
531 next_gpe_xrupt = next_gpe_xrupt->next;
532 }
533
534 next_gpe_xrupt->next = gpe_xrupt;
535 gpe_xrupt->previous = next_gpe_xrupt;
536 } else {
537 acpi_gbl_gpe_xrupt_list_head = gpe_xrupt;
538 }
539 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
540
541 /* Install new interrupt handler if not SCI_INT */
542
543 if (interrupt_number != acpi_gbl_FADT.sci_interrupt) {
544 status = acpi_os_install_interrupt_handler(interrupt_number,
545 acpi_ev_gpe_xrupt_handler,
546 gpe_xrupt);
547 if (ACPI_FAILURE(status)) {
548 ACPI_ERROR((AE_INFO,
549 "Could not install GPE interrupt handler at level 0x%X",
550 interrupt_number));
551 return_PTR(NULL);
552 }
553 }
554
555 return_PTR(gpe_xrupt);
556}
557
558/*******************************************************************************
559 *
560 * FUNCTION: acpi_ev_delete_gpe_xrupt
561 *
562 * PARAMETERS: gpe_xrupt - A GPE interrupt info block
563 *
564 * RETURN: Status
565 *
566 * DESCRIPTION: Remove and free a gpe_xrupt block. Remove an associated
567 * interrupt handler if not the SCI interrupt.
568 *
569 ******************************************************************************/
570
571static acpi_status
572acpi_ev_delete_gpe_xrupt(struct acpi_gpe_xrupt_info *gpe_xrupt)
573{
574 acpi_status status;
575 acpi_cpu_flags flags;
576
577 ACPI_FUNCTION_TRACE(ev_delete_gpe_xrupt);
578
579 /* We never want to remove the SCI interrupt handler */
580
581 if (gpe_xrupt->interrupt_number == acpi_gbl_FADT.sci_interrupt) {
582 gpe_xrupt->gpe_block_list_head = NULL;
583 return_ACPI_STATUS(AE_OK);
584 }
585
586 /* Disable this interrupt */
587
588 status =
589 acpi_os_remove_interrupt_handler(gpe_xrupt->interrupt_number,
590 acpi_ev_gpe_xrupt_handler);
591 if (ACPI_FAILURE(status)) {
592 return_ACPI_STATUS(status);
593 }
594
595 /* Unlink the interrupt block with lock */
596
597 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
598 if (gpe_xrupt->previous) {
599 gpe_xrupt->previous->next = gpe_xrupt->next;
600 } else {
601 /* No previous, update list head */
602
603 acpi_gbl_gpe_xrupt_list_head = gpe_xrupt->next;
604 }
605
606 if (gpe_xrupt->next) {
607 gpe_xrupt->next->previous = gpe_xrupt->previous;
608 }
609 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
610
611 /* Free the block */
612
613 ACPI_FREE(gpe_xrupt);
614 return_ACPI_STATUS(AE_OK);
615}
616
617/*******************************************************************************
618 *
619 * FUNCTION: acpi_ev_install_gpe_block
620 *
621 * PARAMETERS: gpe_block - New GPE block
622 * interrupt_number - Xrupt to be associated with this
623 * GPE block
624 *
625 * RETURN: Status
626 *
627 * DESCRIPTION: Install new GPE block with mutex support
628 *
629 ******************************************************************************/
630
631static acpi_status
632acpi_ev_install_gpe_block(struct acpi_gpe_block_info *gpe_block,
633 u32 interrupt_number)
634{
635 struct acpi_gpe_block_info *next_gpe_block;
636 struct acpi_gpe_xrupt_info *gpe_xrupt_block;
637 acpi_status status;
638 acpi_cpu_flags flags;
639
640 ACPI_FUNCTION_TRACE(ev_install_gpe_block);
641
642 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
643 if (ACPI_FAILURE(status)) {
644 return_ACPI_STATUS(status);
645 }
646
647 gpe_xrupt_block = acpi_ev_get_gpe_xrupt_block(interrupt_number);
648 if (!gpe_xrupt_block) {
649 status = AE_NO_MEMORY;
650 goto unlock_and_exit;
651 }
652
653 /* Install the new block at the end of the list with lock */
654
655 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
656 if (gpe_xrupt_block->gpe_block_list_head) {
657 next_gpe_block = gpe_xrupt_block->gpe_block_list_head;
658 while (next_gpe_block->next) {
659 next_gpe_block = next_gpe_block->next;
660 }
661
662 next_gpe_block->next = gpe_block;
663 gpe_block->previous = next_gpe_block;
664 } else {
665 gpe_xrupt_block->gpe_block_list_head = gpe_block;
666 }
667
668 gpe_block->xrupt_block = gpe_xrupt_block;
669 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
670
671 unlock_and_exit:
672 status = acpi_ut_release_mutex(ACPI_MTX_EVENTS);
673 return_ACPI_STATUS(status);
674}
675
676/*******************************************************************************
677 *
678 * FUNCTION: acpi_ev_delete_gpe_block
679 *
680 * PARAMETERS: gpe_block - Existing GPE block
681 *
682 * RETURN: Status
683 *
684 * DESCRIPTION: Remove a GPE block
685 *
686 ******************************************************************************/
687
688acpi_status acpi_ev_delete_gpe_block(struct acpi_gpe_block_info *gpe_block)
689{
690 acpi_status status;
691 acpi_cpu_flags flags;
692
693 ACPI_FUNCTION_TRACE(ev_install_gpe_block);
694
695 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
696 if (ACPI_FAILURE(status)) {
697 return_ACPI_STATUS(status);
698 }
699
700 /* Disable all GPEs in this block */
701
702 status =
703 acpi_hw_disable_gpe_block(gpe_block->xrupt_block, gpe_block, NULL);
704
705 if (!gpe_block->previous && !gpe_block->next) {
706
707 /* This is the last gpe_block on this interrupt */
708
709 status = acpi_ev_delete_gpe_xrupt(gpe_block->xrupt_block);
710 if (ACPI_FAILURE(status)) {
711 goto unlock_and_exit;
712 }
713 } else {
714 /* Remove the block on this interrupt with lock */
715
716 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
717 if (gpe_block->previous) {
718 gpe_block->previous->next = gpe_block->next;
719 } else {
720 gpe_block->xrupt_block->gpe_block_list_head =
721 gpe_block->next;
722 }
723
724 if (gpe_block->next) {
725 gpe_block->next->previous = gpe_block->previous;
726 }
727 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
728 }
729
730 acpi_current_gpe_count -=
731 gpe_block->register_count * ACPI_GPE_REGISTER_WIDTH;
732
733 /* Free the gpe_block */
734
735 ACPI_FREE(gpe_block->register_info);
736 ACPI_FREE(gpe_block->event_info);
737 ACPI_FREE(gpe_block);
738
739 unlock_and_exit:
740 status = acpi_ut_release_mutex(ACPI_MTX_EVENTS);
741 return_ACPI_STATUS(status);
742}
743
744/*******************************************************************************
745 *
746 * FUNCTION: acpi_ev_create_gpe_info_blocks
747 *
748 * PARAMETERS: gpe_block - New GPE block
749 *
750 * RETURN: Status
751 *
752 * DESCRIPTION: Create the register_info and event_info blocks for this GPE block
753 *
754 ******************************************************************************/
755
756static acpi_status
757acpi_ev_create_gpe_info_blocks(struct acpi_gpe_block_info *gpe_block)
758{
759 struct acpi_gpe_register_info *gpe_register_info = NULL;
760 struct acpi_gpe_event_info *gpe_event_info = NULL;
761 struct acpi_gpe_event_info *this_event;
762 struct acpi_gpe_register_info *this_register;
763 u32 i;
764 u32 j;
765 acpi_status status;
766
767 ACPI_FUNCTION_TRACE(ev_create_gpe_info_blocks);
768
769 /* Allocate the GPE register information block */
770
771 gpe_register_info = ACPI_ALLOCATE_ZEROED((acpi_size) gpe_block->
772 register_count *
773 sizeof(struct
774 acpi_gpe_register_info));
775 if (!gpe_register_info) {
776 ACPI_ERROR((AE_INFO,
777 "Could not allocate the GpeRegisterInfo table"));
778 return_ACPI_STATUS(AE_NO_MEMORY);
779 }
780
781 /*
782 * Allocate the GPE event_info block. There are eight distinct GPEs
783 * per register. Initialization to zeros is sufficient.
784 */
785 gpe_event_info = ACPI_ALLOCATE_ZEROED(((acpi_size) gpe_block->
786 register_count *
787 ACPI_GPE_REGISTER_WIDTH) *
788 sizeof(struct
789 acpi_gpe_event_info));
790 if (!gpe_event_info) {
791 ACPI_ERROR((AE_INFO,
792 "Could not allocate the GpeEventInfo table"));
793 status = AE_NO_MEMORY;
794 goto error_exit;
795 }
796
797 /* Save the new Info arrays in the GPE block */
798
799 gpe_block->register_info = gpe_register_info;
800 gpe_block->event_info = gpe_event_info;
801
802 /*
803 * Initialize the GPE Register and Event structures. A goal of these
804 * tables is to hide the fact that there are two separate GPE register
805 * sets in a given GPE hardware block, the status registers occupy the
806 * first half, and the enable registers occupy the second half.
807 */
808 this_register = gpe_register_info;
809 this_event = gpe_event_info;
810
811 for (i = 0; i < gpe_block->register_count; i++) {
812
813 /* Init the register_info for this GPE register (8 GPEs) */
814
815 this_register->base_gpe_number =
816 (u8) (gpe_block->block_base_number +
817 (i * ACPI_GPE_REGISTER_WIDTH));
818
819 this_register->status_address.address =
820 gpe_block->block_address.address + i;
821
822 this_register->enable_address.address =
823 gpe_block->block_address.address + i +
824 gpe_block->register_count;
825
826 this_register->status_address.space_id =
827 gpe_block->block_address.space_id;
828 this_register->enable_address.space_id =
829 gpe_block->block_address.space_id;
830 this_register->status_address.bit_width =
831 ACPI_GPE_REGISTER_WIDTH;
832 this_register->enable_address.bit_width =
833 ACPI_GPE_REGISTER_WIDTH;
834 this_register->status_address.bit_offset = 0;
835 this_register->enable_address.bit_offset = 0;
836
837 /* Init the event_info for each GPE within this register */
838
839 for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) {
840 this_event->gpe_number =
841 (u8) (this_register->base_gpe_number + j);
842 this_event->register_info = this_register;
843 this_event++;
844 }
845
846 /* Disable all GPEs within this register */
847
848 status = acpi_write(0x00, &this_register->enable_address);
849 if (ACPI_FAILURE(status)) {
850 goto error_exit;
851 }
852
853 /* Clear any pending GPE events within this register */
854
855 status = acpi_write(0xFF, &this_register->status_address);
856 if (ACPI_FAILURE(status)) {
857 goto error_exit;
858 }
859
860 this_register++;
861 }
862
863 return_ACPI_STATUS(AE_OK);
864
865 error_exit:
866 if (gpe_register_info) {
867 ACPI_FREE(gpe_register_info);
868 }
869 if (gpe_event_info) {
870 ACPI_FREE(gpe_event_info);
871 }
872
873 return_ACPI_STATUS(status);
874}
875
876/*******************************************************************************
877 *
878 * FUNCTION: acpi_ev_create_gpe_block
879 *
880 * PARAMETERS: gpe_device - Handle to the parent GPE block
881 * gpe_block_address - Address and space_iD
882 * register_count - Number of GPE register pairs in the block
883 * gpe_block_base_number - Starting GPE number for the block
884 * interrupt_number - H/W interrupt for the block
885 * return_gpe_block - Where the new block descriptor is returned
886 *
887 * RETURN: Status
888 *
889 * DESCRIPTION: Create and Install a block of GPE registers. All GPEs within
890 * the block are disabled at exit.
891 * Note: Assumes namespace is locked.
892 *
893 ******************************************************************************/
894
895acpi_status
896acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device,
897 struct acpi_generic_address *gpe_block_address,
898 u32 register_count,
899 u8 gpe_block_base_number,
900 u32 interrupt_number,
901 struct acpi_gpe_block_info **return_gpe_block)
902{
903 acpi_status status;
904 struct acpi_gpe_block_info *gpe_block;
905
906 ACPI_FUNCTION_TRACE(ev_create_gpe_block);
907
908 if (!register_count) {
909 return_ACPI_STATUS(AE_OK);
910 }
911
912 /* Allocate a new GPE block */
913
914 gpe_block = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_gpe_block_info));
915 if (!gpe_block) {
916 return_ACPI_STATUS(AE_NO_MEMORY);
917 }
918
919 /* Initialize the new GPE block */
920
921 gpe_block->node = gpe_device;
922 gpe_block->register_count = register_count;
923 gpe_block->block_base_number = gpe_block_base_number;
924
925 ACPI_MEMCPY(&gpe_block->block_address, gpe_block_address,
926 sizeof(struct acpi_generic_address));
927
928 /*
929 * Create the register_info and event_info sub-structures
930 * Note: disables and clears all GPEs in the block
931 */
932 status = acpi_ev_create_gpe_info_blocks(gpe_block);
933 if (ACPI_FAILURE(status)) {
934 ACPI_FREE(gpe_block);
935 return_ACPI_STATUS(status);
936 }
937
938 /* Install the new block in the global lists */
939
940 status = acpi_ev_install_gpe_block(gpe_block, interrupt_number);
941 if (ACPI_FAILURE(status)) {
942 ACPI_FREE(gpe_block);
943 return_ACPI_STATUS(status);
944 }
945
946 /* Find all GPE methods (_Lxx, _Exx) for this block */
947
948 status = acpi_ns_walk_namespace(ACPI_TYPE_METHOD, gpe_device,
949 ACPI_UINT32_MAX, ACPI_NS_WALK_NO_UNLOCK,
950 acpi_ev_save_method_info, gpe_block,
951 NULL);
952
953 /* Return the new block */
954
955 if (return_gpe_block) {
956 (*return_gpe_block) = gpe_block;
957 }
958
959 ACPI_DEBUG_PRINT((ACPI_DB_INIT,
960 "GPE %02X to %02X [%4.4s] %u regs on int 0x%X\n",
961 (u32) gpe_block->block_base_number,
962 (u32) (gpe_block->block_base_number +
963 ((gpe_block->register_count *
964 ACPI_GPE_REGISTER_WIDTH) - 1)),
965 gpe_device->name.ascii, gpe_block->register_count,
966 interrupt_number));
967
968 /* Update global count of currently available GPEs */
969
970 acpi_current_gpe_count += register_count * ACPI_GPE_REGISTER_WIDTH;
971 return_ACPI_STATUS(AE_OK);
972}
973
974/*******************************************************************************
975 *
976 * FUNCTION: acpi_ev_initialize_gpe_block
977 *
978 * PARAMETERS: gpe_device - Handle to the parent GPE block
979 * gpe_block - Gpe Block info
980 *
981 * RETURN: Status
982 *
983 * DESCRIPTION: Initialize and enable a GPE block. First find and run any
984 * _PRT methods associated with the block, then enable the
985 * appropriate GPEs.
986 * Note: Assumes namespace is locked.
987 *
988 ******************************************************************************/
989
990acpi_status
991acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device,
992 struct acpi_gpe_block_info *gpe_block)
993{
994 acpi_status status;
995 struct acpi_gpe_event_info *gpe_event_info;
996 struct acpi_gpe_walk_info gpe_info;
997 u32 wake_gpe_count;
998 u32 gpe_enabled_count;
999 u32 i;
1000 u32 j;
1001
1002 ACPI_FUNCTION_TRACE(ev_initialize_gpe_block);
1003
1004 /* Ignore a null GPE block (e.g., if no GPE block 1 exists) */
1005
1006 if (!gpe_block) {
1007 return_ACPI_STATUS(AE_OK);
1008 }
1009
1010 /*
1011 * Runtime option: Should wake GPEs be enabled at runtime? The default
1012 * is no, they should only be enabled just as the machine goes to sleep.
1013 */
1014 if (acpi_gbl_leave_wake_gpes_disabled) {
1015 /*
1016 * Differentiate runtime vs wake GPEs, via the _PRW control methods.
1017 * Each GPE that has one or more _PRWs that reference it is by
1018 * definition a wake GPE and will not be enabled while the machine
1019 * is running.
1020 */
1021 gpe_info.gpe_block = gpe_block;
1022 gpe_info.gpe_device = gpe_device;
1023
1024 status =
1025 acpi_ns_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
1026 ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK,
1027 acpi_ev_match_prw_and_gpe, &gpe_info,
1028 NULL);
1029 }
1030
1031 /*
1032 * Enable all GPEs in this block that have these attributes:
1033 * 1) are "runtime" or "run/wake" GPEs, and
1034 * 2) have a corresponding _Lxx or _Exx method
1035 *
1036 * Any other GPEs within this block must be enabled via the acpi_enable_gpe()
1037 * external interface.
1038 */
1039 wake_gpe_count = 0;
1040 gpe_enabled_count = 0;
1041
1042 for (i = 0; i < gpe_block->register_count; i++) {
1043 for (j = 0; j < 8; j++) {
1044
1045 /* Get the info block for this particular GPE */
1046
1047 gpe_event_info =
1048 &gpe_block->
1049 event_info[((acpi_size) i *
1050 ACPI_GPE_REGISTER_WIDTH) + j];
1051
1052 if (((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) ==
1053 ACPI_GPE_DISPATCH_METHOD)
1054 && (gpe_event_info->flags & ACPI_GPE_TYPE_RUNTIME)) {
1055 gpe_enabled_count++;
1056 }
1057
1058 if (gpe_event_info->flags & ACPI_GPE_TYPE_WAKE) {
1059 wake_gpe_count++;
1060 }
1061 }
1062 }
1063
1064 ACPI_DEBUG_PRINT((ACPI_DB_INIT,
1065 "Found %u Wake, Enabled %u Runtime GPEs in this block\n",
1066 wake_gpe_count, gpe_enabled_count));
1067
1068 /* Enable all valid runtime GPEs found above */
1069
1070 status = acpi_hw_enable_runtime_gpe_block(NULL, gpe_block, NULL);
1071 if (ACPI_FAILURE(status)) {
1072 ACPI_ERROR((AE_INFO, "Could not enable GPEs in GpeBlock %p",
1073 gpe_block));
1074 }
1075
1076 return_ACPI_STATUS(status);
1077}
1078
1079/*******************************************************************************
1080 *
1081 * FUNCTION: acpi_ev_gpe_initialize
1082 *
1083 * PARAMETERS: None
1084 *
1085 * RETURN: Status
1086 *
1087 * DESCRIPTION: Initialize the GPE data structures
1088 *
1089 ******************************************************************************/
1090
1091acpi_status acpi_ev_gpe_initialize(void)
1092{
1093 u32 register_count0 = 0;
1094 u32 register_count1 = 0;
1095 u32 gpe_number_max = 0;
1096 acpi_status status;
1097
1098 ACPI_FUNCTION_TRACE(ev_gpe_initialize);
1099
1100 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
1101 if (ACPI_FAILURE(status)) {
1102 return_ACPI_STATUS(status);
1103 }
1104
1105 /*
1106 * Initialize the GPE Block(s) defined in the FADT
1107 *
1108 * Why the GPE register block lengths are divided by 2: From the ACPI Spec,
1109 * section "General-Purpose Event Registers", we have:
1110 *
1111 * "Each register block contains two registers of equal length
1112 * GPEx_STS and GPEx_EN (where x is 0 or 1). The length of the
1113 * GPE0_STS and GPE0_EN registers is equal to half the GPE0_LEN
1114 * The length of the GPE1_STS and GPE1_EN registers is equal to
1115 * half the GPE1_LEN. If a generic register block is not supported
1116 * then its respective block pointer and block length values in the
1117 * FADT table contain zeros. The GPE0_LEN and GPE1_LEN do not need
1118 * to be the same size."
1119 */
1120
1121 /*
1122 * Determine the maximum GPE number for this machine.
1123 *
1124 * Note: both GPE0 and GPE1 are optional, and either can exist without
1125 * the other.
1126 *
1127 * If EITHER the register length OR the block address are zero, then that
1128 * particular block is not supported.
1129 */
1130 if (acpi_gbl_FADT.gpe0_block_length &&
1131 acpi_gbl_FADT.xgpe0_block.address) {
1132
1133 /* GPE block 0 exists (has both length and address > 0) */
1134
1135 register_count0 = (u16) (acpi_gbl_FADT.gpe0_block_length / 2);
1136
1137 gpe_number_max =
1138 (register_count0 * ACPI_GPE_REGISTER_WIDTH) - 1;
1139
1140 /* Install GPE Block 0 */
1141
1142 status = acpi_ev_create_gpe_block(acpi_gbl_fadt_gpe_device,
1143 &acpi_gbl_FADT.xgpe0_block,
1144 register_count0, 0,
1145 acpi_gbl_FADT.sci_interrupt,
1146 &acpi_gbl_gpe_fadt_blocks[0]);
1147
1148 if (ACPI_FAILURE(status)) {
1149 ACPI_EXCEPTION((AE_INFO, status,
1150 "Could not create GPE Block 0"));
1151 }
1152 }
1153
1154 if (acpi_gbl_FADT.gpe1_block_length &&
1155 acpi_gbl_FADT.xgpe1_block.address) {
1156
1157 /* GPE block 1 exists (has both length and address > 0) */
1158
1159 register_count1 = (u16) (acpi_gbl_FADT.gpe1_block_length / 2);
1160
1161 /* Check for GPE0/GPE1 overlap (if both banks exist) */
1162
1163 if ((register_count0) &&
1164 (gpe_number_max >= acpi_gbl_FADT.gpe1_base)) {
1165 ACPI_ERROR((AE_INFO,
1166 "GPE0 block (GPE 0 to %d) overlaps the GPE1 block (GPE %d to %d) - Ignoring GPE1",
1167 gpe_number_max, acpi_gbl_FADT.gpe1_base,
1168 acpi_gbl_FADT.gpe1_base +
1169 ((register_count1 *
1170 ACPI_GPE_REGISTER_WIDTH) - 1)));
1171
1172 /* Ignore GPE1 block by setting the register count to zero */
1173
1174 register_count1 = 0;
1175 } else {
1176 /* Install GPE Block 1 */
1177
1178 status =
1179 acpi_ev_create_gpe_block(acpi_gbl_fadt_gpe_device,
1180 &acpi_gbl_FADT.xgpe1_block,
1181 register_count1,
1182 acpi_gbl_FADT.gpe1_base,
1183 acpi_gbl_FADT.
1184 sci_interrupt,
1185 &acpi_gbl_gpe_fadt_blocks
1186 [1]);
1187
1188 if (ACPI_FAILURE(status)) {
1189 ACPI_EXCEPTION((AE_INFO, status,
1190 "Could not create GPE Block 1"));
1191 }
1192
1193 /*
1194 * GPE0 and GPE1 do not have to be contiguous in the GPE number
1195 * space. However, GPE0 always starts at GPE number zero.
1196 */
1197 gpe_number_max = acpi_gbl_FADT.gpe1_base +
1198 ((register_count1 * ACPI_GPE_REGISTER_WIDTH) - 1);
1199 }
1200 }
1201
1202 /* Exit if there are no GPE registers */
1203
1204 if ((register_count0 + register_count1) == 0) {
1205
1206 /* GPEs are not required by ACPI, this is OK */
1207
1208 ACPI_DEBUG_PRINT((ACPI_DB_INIT,
1209 "There are no GPE blocks defined in the FADT\n"));
1210 status = AE_OK;
1211 goto cleanup;
1212 }
1213
1214 /* Check for Max GPE number out-of-range */
1215
1216 if (gpe_number_max > ACPI_GPE_MAX) {
1217 ACPI_ERROR((AE_INFO,
1218 "Maximum GPE number from FADT is too large: 0x%X",
1219 gpe_number_max));
1220 status = AE_BAD_VALUE;
1221 goto cleanup;
1222 }
1223
1224 cleanup:
1225 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
1226 return_ACPI_STATUS(AE_OK);
1227}
diff --git a/drivers/acpi/acpica/evmisc.c b/drivers/acpi/acpica/evmisc.c
new file mode 100644
index 00000000000..16f2c1a0016
--- /dev/null
+++ b/drivers/acpi/acpica/evmisc.c
@@ -0,0 +1,621 @@
1/******************************************************************************
2 *
3 * Module Name: evmisc - Miscellaneous event manager support functions
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46#include <acpi/acevents.h>
47#include <acpi/acnamesp.h>
48#include <acpi/acinterp.h>
49
50#define _COMPONENT ACPI_EVENTS
51ACPI_MODULE_NAME("evmisc")
52
53/* Local prototypes */
54static void ACPI_SYSTEM_XFACE acpi_ev_notify_dispatch(void *context);
55
56static u32 acpi_ev_global_lock_handler(void *context);
57
58static acpi_status acpi_ev_remove_global_lock_handler(void);
59
60/*******************************************************************************
61 *
62 * FUNCTION: acpi_ev_is_notify_object
63 *
64 * PARAMETERS: Node - Node to check
65 *
66 * RETURN: TRUE if notifies allowed on this object
67 *
68 * DESCRIPTION: Check type of node for a object that supports notifies.
69 *
70 * TBD: This could be replaced by a flag bit in the node.
71 *
72 ******************************************************************************/
73
74u8 acpi_ev_is_notify_object(struct acpi_namespace_node *node)
75{
76 switch (node->type) {
77 case ACPI_TYPE_DEVICE:
78 case ACPI_TYPE_PROCESSOR:
79 case ACPI_TYPE_THERMAL:
80 /*
81 * These are the ONLY objects that can receive ACPI notifications
82 */
83 return (TRUE);
84
85 default:
86 return (FALSE);
87 }
88}
89
90/*******************************************************************************
91 *
92 * FUNCTION: acpi_ev_queue_notify_request
93 *
94 * PARAMETERS: Node - NS node for the notified object
95 * notify_value - Value from the Notify() request
96 *
97 * RETURN: Status
98 *
99 * DESCRIPTION: Dispatch a device notification event to a previously
100 * installed handler.
101 *
102 ******************************************************************************/
103
104acpi_status
105acpi_ev_queue_notify_request(struct acpi_namespace_node * node,
106 u32 notify_value)
107{
108 union acpi_operand_object *obj_desc;
109 union acpi_operand_object *handler_obj = NULL;
110 union acpi_generic_state *notify_info;
111 acpi_status status = AE_OK;
112
113 ACPI_FUNCTION_NAME(ev_queue_notify_request);
114
115 /*
116 * For value 3 (Ejection Request), some device method may need to be run.
117 * For value 2 (Device Wake) if _PRW exists, the _PS0 method may need
118 * to be run.
119 * For value 0x80 (Status Change) on the power button or sleep button,
120 * initiate soft-off or sleep operation?
121 */
122 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
123 "Dispatching Notify on [%4.4s] Node %p Value 0x%2.2X (%s)\n",
124 acpi_ut_get_node_name(node), node, notify_value,
125 acpi_ut_get_notify_name(notify_value)));
126
127 /* Get the notify object attached to the NS Node */
128
129 obj_desc = acpi_ns_get_attached_object(node);
130 if (obj_desc) {
131
132 /* We have the notify object, Get the right handler */
133
134 switch (node->type) {
135
136 /* Notify allowed only on these types */
137
138 case ACPI_TYPE_DEVICE:
139 case ACPI_TYPE_THERMAL:
140 case ACPI_TYPE_PROCESSOR:
141
142 if (notify_value <= ACPI_MAX_SYS_NOTIFY) {
143 handler_obj =
144 obj_desc->common_notify.system_notify;
145 } else {
146 handler_obj =
147 obj_desc->common_notify.device_notify;
148 }
149 break;
150
151 default:
152
153 /* All other types are not supported */
154
155 return (AE_TYPE);
156 }
157 }
158
159 /*
160 * If there is any handler to run, schedule the dispatcher.
161 * Check for:
162 * 1) Global system notify handler
163 * 2) Global device notify handler
164 * 3) Per-device notify handler
165 */
166 if ((acpi_gbl_system_notify.handler
167 && (notify_value <= ACPI_MAX_SYS_NOTIFY))
168 || (acpi_gbl_device_notify.handler
169 && (notify_value > ACPI_MAX_SYS_NOTIFY)) || handler_obj) {
170 notify_info = acpi_ut_create_generic_state();
171 if (!notify_info) {
172 return (AE_NO_MEMORY);
173 }
174
175 if (!handler_obj) {
176 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
177 "Executing system notify handler for Notify (%4.4s, %X) node %p\n",
178 acpi_ut_get_node_name(node),
179 notify_value, node));
180 }
181
182 notify_info->common.descriptor_type =
183 ACPI_DESC_TYPE_STATE_NOTIFY;
184 notify_info->notify.node = node;
185 notify_info->notify.value = (u16) notify_value;
186 notify_info->notify.handler_obj = handler_obj;
187
188 status =
189 acpi_os_execute(OSL_NOTIFY_HANDLER, acpi_ev_notify_dispatch,
190 notify_info);
191 if (ACPI_FAILURE(status)) {
192 acpi_ut_delete_generic_state(notify_info);
193 }
194 } else {
195 /* There is no notify handler (per-device or system) for this device */
196
197 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
198 "No notify handler for Notify (%4.4s, %X) node %p\n",
199 acpi_ut_get_node_name(node), notify_value,
200 node));
201 }
202
203 return (status);
204}
205
206/*******************************************************************************
207 *
208 * FUNCTION: acpi_ev_notify_dispatch
209 *
210 * PARAMETERS: Context - To be passed to the notify handler
211 *
212 * RETURN: None.
213 *
214 * DESCRIPTION: Dispatch a device notification event to a previously
215 * installed handler.
216 *
217 ******************************************************************************/
218
219static void ACPI_SYSTEM_XFACE acpi_ev_notify_dispatch(void *context)
220{
221 union acpi_generic_state *notify_info =
222 (union acpi_generic_state *)context;
223 acpi_notify_handler global_handler = NULL;
224 void *global_context = NULL;
225 union acpi_operand_object *handler_obj;
226
227 ACPI_FUNCTION_ENTRY();
228
229 /*
230 * We will invoke a global notify handler if installed. This is done
231 * _before_ we invoke the per-device handler attached to the device.
232 */
233 if (notify_info->notify.value <= ACPI_MAX_SYS_NOTIFY) {
234
235 /* Global system notification handler */
236
237 if (acpi_gbl_system_notify.handler) {
238 global_handler = acpi_gbl_system_notify.handler;
239 global_context = acpi_gbl_system_notify.context;
240 }
241 } else {
242 /* Global driver notification handler */
243
244 if (acpi_gbl_device_notify.handler) {
245 global_handler = acpi_gbl_device_notify.handler;
246 global_context = acpi_gbl_device_notify.context;
247 }
248 }
249
250 /* Invoke the system handler first, if present */
251
252 if (global_handler) {
253 global_handler(notify_info->notify.node,
254 notify_info->notify.value, global_context);
255 }
256
257 /* Now invoke the per-device handler, if present */
258
259 handler_obj = notify_info->notify.handler_obj;
260 if (handler_obj) {
261 handler_obj->notify.handler(notify_info->notify.node,
262 notify_info->notify.value,
263 handler_obj->notify.context);
264 }
265
266 /* All done with the info object */
267
268 acpi_ut_delete_generic_state(notify_info);
269}
270
271/*******************************************************************************
272 *
273 * FUNCTION: acpi_ev_global_lock_handler
274 *
275 * PARAMETERS: Context - From thread interface, not used
276 *
277 * RETURN: ACPI_INTERRUPT_HANDLED
278 *
279 * DESCRIPTION: Invoked directly from the SCI handler when a global lock
280 * release interrupt occurs. Attempt to acquire the global lock,
281 * if successful, signal the thread waiting for the lock.
282 *
283 * NOTE: Assumes that the semaphore can be signaled from interrupt level. If
284 * this is not possible for some reason, a separate thread will have to be
285 * scheduled to do this.
286 *
287 ******************************************************************************/
288
289static u32 acpi_ev_global_lock_handler(void *context)
290{
291 u8 acquired = FALSE;
292
293 /*
294 * Attempt to get the lock.
295 *
296 * If we don't get it now, it will be marked pending and we will
297 * take another interrupt when it becomes free.
298 */
299 ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_FACS, acquired);
300 if (acquired) {
301
302 /* Got the lock, now wake all threads waiting for it */
303
304 acpi_gbl_global_lock_acquired = TRUE;
305 /* Send a unit to the semaphore */
306
307 if (ACPI_FAILURE
308 (acpi_os_signal_semaphore
309 (acpi_gbl_global_lock_semaphore, 1))) {
310 ACPI_ERROR((AE_INFO,
311 "Could not signal Global Lock semaphore"));
312 }
313 }
314
315 return (ACPI_INTERRUPT_HANDLED);
316}
317
318/*******************************************************************************
319 *
320 * FUNCTION: acpi_ev_init_global_lock_handler
321 *
322 * PARAMETERS: None
323 *
324 * RETURN: Status
325 *
326 * DESCRIPTION: Install a handler for the global lock release event
327 *
328 ******************************************************************************/
329
330acpi_status acpi_ev_init_global_lock_handler(void)
331{
332 acpi_status status;
333
334 ACPI_FUNCTION_TRACE(ev_init_global_lock_handler);
335
336 /* Attempt installation of the global lock handler */
337
338 status = acpi_install_fixed_event_handler(ACPI_EVENT_GLOBAL,
339 acpi_ev_global_lock_handler,
340 NULL);
341
342 /*
343 * If the global lock does not exist on this platform, the attempt to
344 * enable GBL_STATUS will fail (the GBL_ENABLE bit will not stick).
345 * Map to AE_OK, but mark global lock as not present. Any attempt to
346 * actually use the global lock will be flagged with an error.
347 */
348 if (status == AE_NO_HARDWARE_RESPONSE) {
349 ACPI_ERROR((AE_INFO,
350 "No response from Global Lock hardware, disabling lock"));
351
352 acpi_gbl_global_lock_present = FALSE;
353 return_ACPI_STATUS(AE_OK);
354 }
355
356 acpi_gbl_global_lock_present = TRUE;
357 return_ACPI_STATUS(status);
358}
359
360/*******************************************************************************
361 *
362 * FUNCTION: acpi_ev_remove_global_lock_handler
363 *
364 * PARAMETERS: None
365 *
366 * RETURN: Status
367 *
368 * DESCRIPTION: Remove the handler for the Global Lock
369 *
370 ******************************************************************************/
371
372static acpi_status acpi_ev_remove_global_lock_handler(void)
373{
374 acpi_status status;
375
376 ACPI_FUNCTION_TRACE(ev_remove_global_lock_handler);
377
378 acpi_gbl_global_lock_present = FALSE;
379 status = acpi_remove_fixed_event_handler(ACPI_EVENT_GLOBAL,
380 acpi_ev_global_lock_handler);
381
382 return_ACPI_STATUS(status);
383}
384
385/******************************************************************************
386 *
387 * FUNCTION: acpi_ev_acquire_global_lock
388 *
389 * PARAMETERS: Timeout - Max time to wait for the lock, in millisec.
390 *
391 * RETURN: Status
392 *
393 * DESCRIPTION: Attempt to gain ownership of the Global Lock.
394 *
395 * MUTEX: Interpreter must be locked
396 *
397 * Note: The original implementation allowed multiple threads to "acquire" the
398 * Global Lock, and the OS would hold the lock until the last thread had
399 * released it. However, this could potentially starve the BIOS out of the
400 * lock, especially in the case where there is a tight handshake between the
401 * Embedded Controller driver and the BIOS. Therefore, this implementation
402 * allows only one thread to acquire the HW Global Lock at a time, and makes
403 * the global lock appear as a standard mutex on the OS side.
404 *
405 *****************************************************************************/
406static acpi_thread_id acpi_ev_global_lock_thread_id;
407static int acpi_ev_global_lock_acquired;
408
409acpi_status acpi_ev_acquire_global_lock(u16 timeout)
410{
411 acpi_status status = AE_OK;
412 u8 acquired = FALSE;
413
414 ACPI_FUNCTION_TRACE(ev_acquire_global_lock);
415
416 /*
417 * Only one thread can acquire the GL at a time, the global_lock_mutex
418 * enforces this. This interface releases the interpreter if we must wait.
419 */
420 status = acpi_ex_system_wait_mutex(
421 acpi_gbl_global_lock_mutex->mutex.os_mutex, 0);
422 if (status == AE_TIME) {
423 if (acpi_ev_global_lock_thread_id == acpi_os_get_thread_id()) {
424 acpi_ev_global_lock_acquired++;
425 return AE_OK;
426 }
427 }
428
429 if (ACPI_FAILURE(status)) {
430 status = acpi_ex_system_wait_mutex(
431 acpi_gbl_global_lock_mutex->mutex.os_mutex,
432 timeout);
433 }
434 if (ACPI_FAILURE(status)) {
435 return_ACPI_STATUS(status);
436 }
437
438 acpi_ev_global_lock_thread_id = acpi_os_get_thread_id();
439 acpi_ev_global_lock_acquired++;
440
441 /*
442 * Update the global lock handle and check for wraparound. The handle is
443 * only used for the external global lock interfaces, but it is updated
444 * here to properly handle the case where a single thread may acquire the
445 * lock via both the AML and the acpi_acquire_global_lock interfaces. The
446 * handle is therefore updated on the first acquire from a given thread
447 * regardless of where the acquisition request originated.
448 */
449 acpi_gbl_global_lock_handle++;
450 if (acpi_gbl_global_lock_handle == 0) {
451 acpi_gbl_global_lock_handle = 1;
452 }
453
454 /*
455 * Make sure that a global lock actually exists. If not, just treat the
456 * lock as a standard mutex.
457 */
458 if (!acpi_gbl_global_lock_present) {
459 acpi_gbl_global_lock_acquired = TRUE;
460 return_ACPI_STATUS(AE_OK);
461 }
462
463 /* Attempt to acquire the actual hardware lock */
464
465 ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_FACS, acquired);
466 if (acquired) {
467
468 /* We got the lock */
469
470 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
471 "Acquired hardware Global Lock\n"));
472
473 acpi_gbl_global_lock_acquired = TRUE;
474 return_ACPI_STATUS(AE_OK);
475 }
476
477 /*
478 * Did not get the lock. The pending bit was set above, and we must now
479 * wait until we get the global lock released interrupt.
480 */
481 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Waiting for hardware Global Lock\n"));
482
483 /*
484 * Wait for handshake with the global lock interrupt handler.
485 * This interface releases the interpreter if we must wait.
486 */
487 status = acpi_ex_system_wait_semaphore(acpi_gbl_global_lock_semaphore,
488 ACPI_WAIT_FOREVER);
489
490 return_ACPI_STATUS(status);
491}
492
493/*******************************************************************************
494 *
495 * FUNCTION: acpi_ev_release_global_lock
496 *
497 * PARAMETERS: None
498 *
499 * RETURN: Status
500 *
501 * DESCRIPTION: Releases ownership of the Global Lock.
502 *
503 ******************************************************************************/
504
505acpi_status acpi_ev_release_global_lock(void)
506{
507 u8 pending = FALSE;
508 acpi_status status = AE_OK;
509
510 ACPI_FUNCTION_TRACE(ev_release_global_lock);
511
512 /* Lock must be already acquired */
513
514 if (!acpi_gbl_global_lock_acquired) {
515 ACPI_WARNING((AE_INFO,
516 "Cannot release the ACPI Global Lock, it has not been acquired"));
517 return_ACPI_STATUS(AE_NOT_ACQUIRED);
518 }
519
520 acpi_ev_global_lock_acquired--;
521 if (acpi_ev_global_lock_acquired > 0) {
522 return AE_OK;
523 }
524
525 if (acpi_gbl_global_lock_present) {
526
527 /* Allow any thread to release the lock */
528
529 ACPI_RELEASE_GLOBAL_LOCK(acpi_gbl_FACS, pending);
530
531 /*
532 * If the pending bit was set, we must write GBL_RLS to the control
533 * register
534 */
535 if (pending) {
536 status =
537 acpi_set_register(ACPI_BITREG_GLOBAL_LOCK_RELEASE,
538 1);
539 }
540
541 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
542 "Released hardware Global Lock\n"));
543 }
544
545 acpi_gbl_global_lock_acquired = FALSE;
546
547 /* Release the local GL mutex */
548 acpi_ev_global_lock_thread_id = NULL;
549 acpi_ev_global_lock_acquired = 0;
550 acpi_os_release_mutex(acpi_gbl_global_lock_mutex->mutex.os_mutex);
551 return_ACPI_STATUS(status);
552}
553
554/******************************************************************************
555 *
556 * FUNCTION: acpi_ev_terminate
557 *
558 * PARAMETERS: none
559 *
560 * RETURN: none
561 *
562 * DESCRIPTION: Disable events and free memory allocated for table storage.
563 *
564 ******************************************************************************/
565
566void acpi_ev_terminate(void)
567{
568 u32 i;
569 acpi_status status;
570
571 ACPI_FUNCTION_TRACE(ev_terminate);
572
573 if (acpi_gbl_events_initialized) {
574 /*
575 * Disable all event-related functionality. In all cases, on error,
576 * print a message but obviously we don't abort.
577 */
578
579 /* Disable all fixed events */
580
581 for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) {
582 status = acpi_disable_event(i, 0);
583 if (ACPI_FAILURE(status)) {
584 ACPI_ERROR((AE_INFO,
585 "Could not disable fixed event %d",
586 (u32) i));
587 }
588 }
589
590 /* Disable all GPEs in all GPE blocks */
591
592 status = acpi_ev_walk_gpe_list(acpi_hw_disable_gpe_block, NULL);
593
594 /* Remove SCI handler */
595
596 status = acpi_ev_remove_sci_handler();
597 if (ACPI_FAILURE(status)) {
598 ACPI_ERROR((AE_INFO, "Could not remove SCI handler"));
599 }
600
601 status = acpi_ev_remove_global_lock_handler();
602 if (ACPI_FAILURE(status)) {
603 ACPI_ERROR((AE_INFO,
604 "Could not remove Global Lock handler"));
605 }
606 }
607
608 /* Deallocate all handler objects installed within GPE info structs */
609
610 status = acpi_ev_walk_gpe_list(acpi_ev_delete_gpe_handlers, NULL);
611
612 /* Return to original mode if necessary */
613
614 if (acpi_gbl_original_mode == ACPI_SYS_MODE_LEGACY) {
615 status = acpi_disable();
616 if (ACPI_FAILURE(status)) {
617 ACPI_WARNING((AE_INFO, "AcpiDisable failed"));
618 }
619 }
620 return_VOID;
621}
diff --git a/drivers/acpi/acpica/evregion.c b/drivers/acpi/acpica/evregion.c
new file mode 100644
index 00000000000..7346093f43e
--- /dev/null
+++ b/drivers/acpi/acpica/evregion.c
@@ -0,0 +1,1070 @@
1/******************************************************************************
2 *
3 * Module Name: evregion - ACPI address_space (op_region) handler dispatch
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46#include <acpi/acevents.h>
47#include <acpi/acnamesp.h>
48#include <acpi/acinterp.h>
49
50#define _COMPONENT ACPI_EVENTS
51ACPI_MODULE_NAME("evregion")
52
53/* Local prototypes */
54static acpi_status
55acpi_ev_reg_run(acpi_handle obj_handle,
56 u32 level, void *context, void **return_value);
57
58static acpi_status
59acpi_ev_install_handler(acpi_handle obj_handle,
60 u32 level, void *context, void **return_value);
61
62/* These are the address spaces that will get default handlers */
63
64#define ACPI_NUM_DEFAULT_SPACES 4
65
66static u8 acpi_gbl_default_address_spaces[ACPI_NUM_DEFAULT_SPACES] = {
67 ACPI_ADR_SPACE_SYSTEM_MEMORY,
68 ACPI_ADR_SPACE_SYSTEM_IO,
69 ACPI_ADR_SPACE_PCI_CONFIG,
70 ACPI_ADR_SPACE_DATA_TABLE
71};
72
73/*******************************************************************************
74 *
75 * FUNCTION: acpi_ev_install_region_handlers
76 *
77 * PARAMETERS: None
78 *
79 * RETURN: Status
80 *
81 * DESCRIPTION: Installs the core subsystem default address space handlers.
82 *
83 ******************************************************************************/
84
85acpi_status acpi_ev_install_region_handlers(void)
86{
87 acpi_status status;
88 u32 i;
89
90 ACPI_FUNCTION_TRACE(ev_install_region_handlers);
91
92 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
93 if (ACPI_FAILURE(status)) {
94 return_ACPI_STATUS(status);
95 }
96
97 /*
98 * All address spaces (PCI Config, EC, SMBus) are scope dependent and
99 * registration must occur for a specific device.
100 *
101 * In the case of the system memory and IO address spaces there is
102 * currently no device associated with the address space. For these we
103 * use the root.
104 *
105 * We install the default PCI config space handler at the root so that
106 * this space is immediately available even though the we have not
107 * enumerated all the PCI Root Buses yet. This is to conform to the ACPI
108 * specification which states that the PCI config space must be always
109 * available -- even though we are nowhere near ready to find the PCI root
110 * buses at this point.
111 *
112 * NOTE: We ignore AE_ALREADY_EXISTS because this means that a handler
113 * has already been installed (via acpi_install_address_space_handler).
114 * Similar for AE_SAME_HANDLER.
115 */
116 for (i = 0; i < ACPI_NUM_DEFAULT_SPACES; i++) {
117 status = acpi_ev_install_space_handler(acpi_gbl_root_node,
118 acpi_gbl_default_address_spaces
119 [i],
120 ACPI_DEFAULT_HANDLER,
121 NULL, NULL);
122 switch (status) {
123 case AE_OK:
124 case AE_SAME_HANDLER:
125 case AE_ALREADY_EXISTS:
126
127 /* These exceptions are all OK */
128
129 status = AE_OK;
130 break;
131
132 default:
133
134 goto unlock_and_exit;
135 }
136 }
137
138 unlock_and_exit:
139 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
140 return_ACPI_STATUS(status);
141}
142
143/*******************************************************************************
144 *
145 * FUNCTION: acpi_ev_initialize_op_regions
146 *
147 * PARAMETERS: None
148 *
149 * RETURN: Status
150 *
151 * DESCRIPTION: Execute _REG methods for all Operation Regions that have
152 * an installed default region handler.
153 *
154 ******************************************************************************/
155
156acpi_status acpi_ev_initialize_op_regions(void)
157{
158 acpi_status status;
159 u32 i;
160
161 ACPI_FUNCTION_TRACE(ev_initialize_op_regions);
162
163 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
164 if (ACPI_FAILURE(status)) {
165 return_ACPI_STATUS(status);
166 }
167
168 /* Run the _REG methods for op_regions in each default address space */
169
170 for (i = 0; i < ACPI_NUM_DEFAULT_SPACES; i++) {
171 /*
172 * TBD: Make sure handler is the DEFAULT handler, otherwise
173 * _REG will have already been run.
174 */
175 status = acpi_ev_execute_reg_methods(acpi_gbl_root_node,
176 acpi_gbl_default_address_spaces
177 [i]);
178 }
179
180 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
181 return_ACPI_STATUS(status);
182}
183
184/*******************************************************************************
185 *
186 * FUNCTION: acpi_ev_execute_reg_method
187 *
188 * PARAMETERS: region_obj - Region object
189 * Function - Passed to _REG: On (1) or Off (0)
190 *
191 * RETURN: Status
192 *
193 * DESCRIPTION: Execute _REG method for a region
194 *
195 ******************************************************************************/
196
197acpi_status
198acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function)
199{
200 struct acpi_evaluate_info *info;
201 union acpi_operand_object *args[3];
202 union acpi_operand_object *region_obj2;
203 acpi_status status;
204
205 ACPI_FUNCTION_TRACE(ev_execute_reg_method);
206
207 region_obj2 = acpi_ns_get_secondary_object(region_obj);
208 if (!region_obj2) {
209 return_ACPI_STATUS(AE_NOT_EXIST);
210 }
211
212 if (region_obj2->extra.method_REG == NULL) {
213 return_ACPI_STATUS(AE_OK);
214 }
215
216 /* Allocate and initialize the evaluation information block */
217
218 info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
219 if (!info) {
220 return_ACPI_STATUS(AE_NO_MEMORY);
221 }
222
223 info->prefix_node = region_obj2->extra.method_REG;
224 info->pathname = NULL;
225 info->parameters = args;
226 info->flags = ACPI_IGNORE_RETURN_VALUE;
227
228 /*
229 * The _REG method has two arguments:
230 *
231 * Arg0 - Integer:
232 * Operation region space ID Same value as region_obj->Region.space_id
233 *
234 * Arg1 - Integer:
235 * connection status 1 for connecting the handler, 0 for disconnecting
236 * the handler (Passed as a parameter)
237 */
238 args[0] = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
239 if (!args[0]) {
240 status = AE_NO_MEMORY;
241 goto cleanup1;
242 }
243
244 args[1] = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
245 if (!args[1]) {
246 status = AE_NO_MEMORY;
247 goto cleanup2;
248 }
249
250 /* Setup the parameter objects */
251
252 args[0]->integer.value = region_obj->region.space_id;
253 args[1]->integer.value = function;
254 args[2] = NULL;
255
256 /* Execute the method, no return value */
257
258 ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname
259 (ACPI_TYPE_METHOD, info->prefix_node, NULL));
260
261 status = acpi_ns_evaluate(info);
262 acpi_ut_remove_reference(args[1]);
263
264 cleanup2:
265 acpi_ut_remove_reference(args[0]);
266
267 cleanup1:
268 ACPI_FREE(info);
269 return_ACPI_STATUS(status);
270}
271
272/*******************************************************************************
273 *
274 * FUNCTION: acpi_ev_address_space_dispatch
275 *
276 * PARAMETERS: region_obj - Internal region object
277 * Function - Read or Write operation
278 * Address - Where in the space to read or write
279 * bit_width - Field width in bits (8, 16, 32, or 64)
280 * Value - Pointer to in or out value, must be
281 * full 64-bit acpi_integer
282 *
283 * RETURN: Status
284 *
285 * DESCRIPTION: Dispatch an address space or operation region access to
286 * a previously installed handler.
287 *
288 ******************************************************************************/
289
290acpi_status
291acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj,
292 u32 function,
293 acpi_physical_address address,
294 u32 bit_width, acpi_integer * value)
295{
296 acpi_status status;
297 acpi_adr_space_handler handler;
298 acpi_adr_space_setup region_setup;
299 union acpi_operand_object *handler_desc;
300 union acpi_operand_object *region_obj2;
301 void *region_context = NULL;
302
303 ACPI_FUNCTION_TRACE(ev_address_space_dispatch);
304
305 region_obj2 = acpi_ns_get_secondary_object(region_obj);
306 if (!region_obj2) {
307 return_ACPI_STATUS(AE_NOT_EXIST);
308 }
309
310 /* Ensure that there is a handler associated with this region */
311
312 handler_desc = region_obj->region.handler;
313 if (!handler_desc) {
314 ACPI_ERROR((AE_INFO,
315 "No handler for Region [%4.4s] (%p) [%s]",
316 acpi_ut_get_node_name(region_obj->region.node),
317 region_obj,
318 acpi_ut_get_region_name(region_obj->region.
319 space_id)));
320
321 return_ACPI_STATUS(AE_NOT_EXIST);
322 }
323
324 /*
325 * It may be the case that the region has never been initialized.
326 * Some types of regions require special init code
327 */
328 if (!(region_obj->region.flags & AOPOBJ_SETUP_COMPLETE)) {
329
330 /* This region has not been initialized yet, do it */
331
332 region_setup = handler_desc->address_space.setup;
333 if (!region_setup) {
334
335 /* No initialization routine, exit with error */
336
337 ACPI_ERROR((AE_INFO,
338 "No init routine for region(%p) [%s]",
339 region_obj,
340 acpi_ut_get_region_name(region_obj->region.
341 space_id)));
342 return_ACPI_STATUS(AE_NOT_EXIST);
343 }
344
345 /*
346 * We must exit the interpreter because the region setup will
347 * potentially execute control methods (for example, the _REG method
348 * for this region)
349 */
350 acpi_ex_exit_interpreter();
351
352 status = region_setup(region_obj, ACPI_REGION_ACTIVATE,
353 handler_desc->address_space.context,
354 &region_context);
355
356 /* Re-enter the interpreter */
357
358 acpi_ex_enter_interpreter();
359
360 /* Check for failure of the Region Setup */
361
362 if (ACPI_FAILURE(status)) {
363 ACPI_EXCEPTION((AE_INFO, status,
364 "During region initialization: [%s]",
365 acpi_ut_get_region_name(region_obj->
366 region.
367 space_id)));
368 return_ACPI_STATUS(status);
369 }
370
371 /* Region initialization may have been completed by region_setup */
372
373 if (!(region_obj->region.flags & AOPOBJ_SETUP_COMPLETE)) {
374 region_obj->region.flags |= AOPOBJ_SETUP_COMPLETE;
375
376 if (region_obj2->extra.region_context) {
377
378 /* The handler for this region was already installed */
379
380 ACPI_FREE(region_context);
381 } else {
382 /*
383 * Save the returned context for use in all accesses to
384 * this particular region
385 */
386 region_obj2->extra.region_context =
387 region_context;
388 }
389 }
390 }
391
392 /* We have everything we need, we can invoke the address space handler */
393
394 handler = handler_desc->address_space.handler;
395
396 ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
397 "Handler %p (@%p) Address %8.8X%8.8X [%s]\n",
398 &region_obj->region.handler->address_space, handler,
399 ACPI_FORMAT_NATIVE_UINT(address),
400 acpi_ut_get_region_name(region_obj->region.
401 space_id)));
402
403 if (!(handler_desc->address_space.handler_flags &
404 ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) {
405 /*
406 * For handlers other than the default (supplied) handlers, we must
407 * exit the interpreter because the handler *might* block -- we don't
408 * know what it will do, so we can't hold the lock on the intepreter.
409 */
410 acpi_ex_exit_interpreter();
411 }
412
413 /* Call the handler */
414
415 status = handler(function, address, bit_width, value,
416 handler_desc->address_space.context,
417 region_obj2->extra.region_context);
418
419 if (ACPI_FAILURE(status)) {
420 ACPI_EXCEPTION((AE_INFO, status, "Returned by Handler for [%s]",
421 acpi_ut_get_region_name(region_obj->region.
422 space_id)));
423 }
424
425 if (!(handler_desc->address_space.handler_flags &
426 ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) {
427 /*
428 * We just returned from a non-default handler, we must re-enter the
429 * interpreter
430 */
431 acpi_ex_enter_interpreter();
432 }
433
434 return_ACPI_STATUS(status);
435}
436
437/*******************************************************************************
438 *
439 * FUNCTION: acpi_ev_detach_region
440 *
441 * PARAMETERS: region_obj - Region Object
442 * acpi_ns_is_locked - Namespace Region Already Locked?
443 *
444 * RETURN: None
445 *
446 * DESCRIPTION: Break the association between the handler and the region
447 * this is a two way association.
448 *
449 ******************************************************************************/
450
451void
452acpi_ev_detach_region(union acpi_operand_object *region_obj,
453 u8 acpi_ns_is_locked)
454{
455 union acpi_operand_object *handler_obj;
456 union acpi_operand_object *obj_desc;
457 union acpi_operand_object **last_obj_ptr;
458 acpi_adr_space_setup region_setup;
459 void **region_context;
460 union acpi_operand_object *region_obj2;
461 acpi_status status;
462
463 ACPI_FUNCTION_TRACE(ev_detach_region);
464
465 region_obj2 = acpi_ns_get_secondary_object(region_obj);
466 if (!region_obj2) {
467 return_VOID;
468 }
469 region_context = &region_obj2->extra.region_context;
470
471 /* Get the address handler from the region object */
472
473 handler_obj = region_obj->region.handler;
474 if (!handler_obj) {
475
476 /* This region has no handler, all done */
477
478 return_VOID;
479 }
480
481 /* Find this region in the handler's list */
482
483 obj_desc = handler_obj->address_space.region_list;
484 last_obj_ptr = &handler_obj->address_space.region_list;
485
486 while (obj_desc) {
487
488 /* Is this the correct Region? */
489
490 if (obj_desc == region_obj) {
491 ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
492 "Removing Region %p from address handler %p\n",
493 region_obj, handler_obj));
494
495 /* This is it, remove it from the handler's list */
496
497 *last_obj_ptr = obj_desc->region.next;
498 obj_desc->region.next = NULL; /* Must clear field */
499
500 if (acpi_ns_is_locked) {
501 status =
502 acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
503 if (ACPI_FAILURE(status)) {
504 return_VOID;
505 }
506 }
507
508 /* Now stop region accesses by executing the _REG method */
509
510 status = acpi_ev_execute_reg_method(region_obj, 0);
511 if (ACPI_FAILURE(status)) {
512 ACPI_EXCEPTION((AE_INFO, status,
513 "from region _REG, [%s]",
514 acpi_ut_get_region_name
515 (region_obj->region.space_id)));
516 }
517
518 if (acpi_ns_is_locked) {
519 status =
520 acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
521 if (ACPI_FAILURE(status)) {
522 return_VOID;
523 }
524 }
525
526 /*
527 * If the region has been activated, call the setup handler with
528 * the deactivate notification
529 */
530 if (region_obj->region.flags & AOPOBJ_SETUP_COMPLETE) {
531 region_setup = handler_obj->address_space.setup;
532 status =
533 region_setup(region_obj,
534 ACPI_REGION_DEACTIVATE,
535 handler_obj->address_space.
536 context, region_context);
537
538 /* Init routine may fail, Just ignore errors */
539
540 if (ACPI_FAILURE(status)) {
541 ACPI_EXCEPTION((AE_INFO, status,
542 "from region handler - deactivate, [%s]",
543 acpi_ut_get_region_name
544 (region_obj->region.
545 space_id)));
546 }
547
548 region_obj->region.flags &=
549 ~(AOPOBJ_SETUP_COMPLETE);
550 }
551
552 /*
553 * Remove handler reference in the region
554 *
555 * NOTE: this doesn't mean that the region goes away, the region
556 * is just inaccessible as indicated to the _REG method
557 *
558 * If the region is on the handler's list, this must be the
559 * region's handler
560 */
561 region_obj->region.handler = NULL;
562 acpi_ut_remove_reference(handler_obj);
563
564 return_VOID;
565 }
566
567 /* Walk the linked list of handlers */
568
569 last_obj_ptr = &obj_desc->region.next;
570 obj_desc = obj_desc->region.next;
571 }
572
573 /* If we get here, the region was not in the handler's region list */
574
575 ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
576 "Cannot remove region %p from address handler %p\n",
577 region_obj, handler_obj));
578
579 return_VOID;
580}
581
582/*******************************************************************************
583 *
584 * FUNCTION: acpi_ev_attach_region
585 *
586 * PARAMETERS: handler_obj - Handler Object
587 * region_obj - Region Object
588 * acpi_ns_is_locked - Namespace Region Already Locked?
589 *
590 * RETURN: None
591 *
592 * DESCRIPTION: Create the association between the handler and the region
593 * this is a two way association.
594 *
595 ******************************************************************************/
596
597acpi_status
598acpi_ev_attach_region(union acpi_operand_object *handler_obj,
599 union acpi_operand_object *region_obj,
600 u8 acpi_ns_is_locked)
601{
602
603 ACPI_FUNCTION_TRACE(ev_attach_region);
604
605 ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
606 "Adding Region [%4.4s] %p to address handler %p [%s]\n",
607 acpi_ut_get_node_name(region_obj->region.node),
608 region_obj, handler_obj,
609 acpi_ut_get_region_name(region_obj->region.
610 space_id)));
611
612 /* Link this region to the front of the handler's list */
613
614 region_obj->region.next = handler_obj->address_space.region_list;
615 handler_obj->address_space.region_list = region_obj;
616
617 /* Install the region's handler */
618
619 if (region_obj->region.handler) {
620 return_ACPI_STATUS(AE_ALREADY_EXISTS);
621 }
622
623 region_obj->region.handler = handler_obj;
624 acpi_ut_add_reference(handler_obj);
625
626 return_ACPI_STATUS(AE_OK);
627}
628
629/*******************************************************************************
630 *
631 * FUNCTION: acpi_ev_install_handler
632 *
633 * PARAMETERS: walk_namespace callback
634 *
635 * DESCRIPTION: This routine installs an address handler into objects that are
636 * of type Region or Device.
637 *
638 * If the Object is a Device, and the device has a handler of
639 * the same type then the search is terminated in that branch.
640 *
641 * This is because the existing handler is closer in proximity
642 * to any more regions than the one we are trying to install.
643 *
644 ******************************************************************************/
645
646static acpi_status
647acpi_ev_install_handler(acpi_handle obj_handle,
648 u32 level, void *context, void **return_value)
649{
650 union acpi_operand_object *handler_obj;
651 union acpi_operand_object *next_handler_obj;
652 union acpi_operand_object *obj_desc;
653 struct acpi_namespace_node *node;
654 acpi_status status;
655
656 ACPI_FUNCTION_NAME(ev_install_handler);
657
658 handler_obj = (union acpi_operand_object *)context;
659
660 /* Parameter validation */
661
662 if (!handler_obj) {
663 return (AE_OK);
664 }
665
666 /* Convert and validate the device handle */
667
668 node = acpi_ns_map_handle_to_node(obj_handle);
669 if (!node) {
670 return (AE_BAD_PARAMETER);
671 }
672
673 /*
674 * We only care about regions and objects that are allowed to have
675 * address space handlers
676 */
677 if ((node->type != ACPI_TYPE_DEVICE) &&
678 (node->type != ACPI_TYPE_REGION) && (node != acpi_gbl_root_node)) {
679 return (AE_OK);
680 }
681
682 /* Check for an existing internal object */
683
684 obj_desc = acpi_ns_get_attached_object(node);
685 if (!obj_desc) {
686
687 /* No object, just exit */
688
689 return (AE_OK);
690 }
691
692 /* Devices are handled different than regions */
693
694 if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_DEVICE) {
695
696 /* Check if this Device already has a handler for this address space */
697
698 next_handler_obj = obj_desc->device.handler;
699 while (next_handler_obj) {
700
701 /* Found a handler, is it for the same address space? */
702
703 if (next_handler_obj->address_space.space_id ==
704 handler_obj->address_space.space_id) {
705 ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
706 "Found handler for region [%s] in device %p(%p) handler %p\n",
707 acpi_ut_get_region_name
708 (handler_obj->address_space.
709 space_id), obj_desc,
710 next_handler_obj,
711 handler_obj));
712
713 /*
714 * Since the object we found it on was a device, then it
715 * means that someone has already installed a handler for
716 * the branch of the namespace from this device on. Just
717 * bail out telling the walk routine to not traverse this
718 * branch. This preserves the scoping rule for handlers.
719 */
720 return (AE_CTRL_DEPTH);
721 }
722
723 /* Walk the linked list of handlers attached to this device */
724
725 next_handler_obj = next_handler_obj->address_space.next;
726 }
727
728 /*
729 * As long as the device didn't have a handler for this space we
730 * don't care about it. We just ignore it and proceed.
731 */
732 return (AE_OK);
733 }
734
735 /* Object is a Region */
736
737 if (obj_desc->region.space_id != handler_obj->address_space.space_id) {
738
739 /* This region is for a different address space, just ignore it */
740
741 return (AE_OK);
742 }
743
744 /*
745 * Now we have a region and it is for the handler's address space type.
746 *
747 * First disconnect region for any previous handler (if any)
748 */
749 acpi_ev_detach_region(obj_desc, FALSE);
750
751 /* Connect the region to the new handler */
752
753 status = acpi_ev_attach_region(handler_obj, obj_desc, FALSE);
754 return (status);
755}
756
757/*******************************************************************************
758 *
759 * FUNCTION: acpi_ev_install_space_handler
760 *
761 * PARAMETERS: Node - Namespace node for the device
762 * space_id - The address space ID
763 * Handler - Address of the handler
764 * Setup - Address of the setup function
765 * Context - Value passed to the handler on each access
766 *
767 * RETURN: Status
768 *
769 * DESCRIPTION: Install a handler for all op_regions of a given space_id.
770 * Assumes namespace is locked
771 *
772 ******************************************************************************/
773
774acpi_status
775acpi_ev_install_space_handler(struct acpi_namespace_node * node,
776 acpi_adr_space_type space_id,
777 acpi_adr_space_handler handler,
778 acpi_adr_space_setup setup, void *context)
779{
780 union acpi_operand_object *obj_desc;
781 union acpi_operand_object *handler_obj;
782 acpi_status status;
783 acpi_object_type type;
784 u8 flags = 0;
785
786 ACPI_FUNCTION_TRACE(ev_install_space_handler);
787
788 /*
789 * This registration is valid for only the types below and the root. This
790 * is where the default handlers get placed.
791 */
792 if ((node->type != ACPI_TYPE_DEVICE) &&
793 (node->type != ACPI_TYPE_PROCESSOR) &&
794 (node->type != ACPI_TYPE_THERMAL) && (node != acpi_gbl_root_node)) {
795 status = AE_BAD_PARAMETER;
796 goto unlock_and_exit;
797 }
798
799 if (handler == ACPI_DEFAULT_HANDLER) {
800 flags = ACPI_ADDR_HANDLER_DEFAULT_INSTALLED;
801
802 switch (space_id) {
803 case ACPI_ADR_SPACE_SYSTEM_MEMORY:
804 handler = acpi_ex_system_memory_space_handler;
805 setup = acpi_ev_system_memory_region_setup;
806 break;
807
808 case ACPI_ADR_SPACE_SYSTEM_IO:
809 handler = acpi_ex_system_io_space_handler;
810 setup = acpi_ev_io_space_region_setup;
811 break;
812
813 case ACPI_ADR_SPACE_PCI_CONFIG:
814 handler = acpi_ex_pci_config_space_handler;
815 setup = acpi_ev_pci_config_region_setup;
816 break;
817
818 case ACPI_ADR_SPACE_CMOS:
819 handler = acpi_ex_cmos_space_handler;
820 setup = acpi_ev_cmos_region_setup;
821 break;
822
823 case ACPI_ADR_SPACE_PCI_BAR_TARGET:
824 handler = acpi_ex_pci_bar_space_handler;
825 setup = acpi_ev_pci_bar_region_setup;
826 break;
827
828 case ACPI_ADR_SPACE_DATA_TABLE:
829 handler = acpi_ex_data_table_space_handler;
830 setup = NULL;
831 break;
832
833 default:
834 status = AE_BAD_PARAMETER;
835 goto unlock_and_exit;
836 }
837 }
838
839 /* If the caller hasn't specified a setup routine, use the default */
840
841 if (!setup) {
842 setup = acpi_ev_default_region_setup;
843 }
844
845 /* Check for an existing internal object */
846
847 obj_desc = acpi_ns_get_attached_object(node);
848 if (obj_desc) {
849 /*
850 * The attached device object already exists. Make sure the handler
851 * is not already installed.
852 */
853 handler_obj = obj_desc->device.handler;
854
855 /* Walk the handler list for this device */
856
857 while (handler_obj) {
858
859 /* Same space_id indicates a handler already installed */
860
861 if (handler_obj->address_space.space_id == space_id) {
862 if (handler_obj->address_space.handler ==
863 handler) {
864 /*
865 * It is (relatively) OK to attempt to install the SAME
866 * handler twice. This can easily happen with the
867 * PCI_Config space.
868 */
869 status = AE_SAME_HANDLER;
870 goto unlock_and_exit;
871 } else {
872 /* A handler is already installed */
873
874 status = AE_ALREADY_EXISTS;
875 }
876 goto unlock_and_exit;
877 }
878
879 /* Walk the linked list of handlers */
880
881 handler_obj = handler_obj->address_space.next;
882 }
883 } else {
884 ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
885 "Creating object on Device %p while installing handler\n",
886 node));
887
888 /* obj_desc does not exist, create one */
889
890 if (node->type == ACPI_TYPE_ANY) {
891 type = ACPI_TYPE_DEVICE;
892 } else {
893 type = node->type;
894 }
895
896 obj_desc = acpi_ut_create_internal_object(type);
897 if (!obj_desc) {
898 status = AE_NO_MEMORY;
899 goto unlock_and_exit;
900 }
901
902 /* Init new descriptor */
903
904 obj_desc->common.type = (u8) type;
905
906 /* Attach the new object to the Node */
907
908 status = acpi_ns_attach_object(node, obj_desc, type);
909
910 /* Remove local reference to the object */
911
912 acpi_ut_remove_reference(obj_desc);
913
914 if (ACPI_FAILURE(status)) {
915 goto unlock_and_exit;
916 }
917 }
918
919 ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
920 "Installing address handler for region %s(%X) on Device %4.4s %p(%p)\n",
921 acpi_ut_get_region_name(space_id), space_id,
922 acpi_ut_get_node_name(node), node, obj_desc));
923
924 /*
925 * Install the handler
926 *
927 * At this point there is no existing handler. Just allocate the object
928 * for the handler and link it into the list.
929 */
930 handler_obj =
931 acpi_ut_create_internal_object(ACPI_TYPE_LOCAL_ADDRESS_HANDLER);
932 if (!handler_obj) {
933 status = AE_NO_MEMORY;
934 goto unlock_and_exit;
935 }
936
937 /* Init handler obj */
938
939 handler_obj->address_space.space_id = (u8) space_id;
940 handler_obj->address_space.handler_flags = flags;
941 handler_obj->address_space.region_list = NULL;
942 handler_obj->address_space.node = node;
943 handler_obj->address_space.handler = handler;
944 handler_obj->address_space.context = context;
945 handler_obj->address_space.setup = setup;
946
947 /* Install at head of Device.address_space list */
948
949 handler_obj->address_space.next = obj_desc->device.handler;
950
951 /*
952 * The Device object is the first reference on the handler_obj.
953 * Each region that uses the handler adds a reference.
954 */
955 obj_desc->device.handler = handler_obj;
956
957 /*
958 * Walk the namespace finding all of the regions this
959 * handler will manage.
960 *
961 * Start at the device and search the branch toward
962 * the leaf nodes until either the leaf is encountered or
963 * a device is detected that has an address handler of the
964 * same type.
965 *
966 * In either case, back up and search down the remainder
967 * of the branch
968 */
969 status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, node, ACPI_UINT32_MAX,
970 ACPI_NS_WALK_UNLOCK,
971 acpi_ev_install_handler, handler_obj,
972 NULL);
973
974 unlock_and_exit:
975 return_ACPI_STATUS(status);
976}
977
978/*******************************************************************************
979 *
980 * FUNCTION: acpi_ev_execute_reg_methods
981 *
982 * PARAMETERS: Node - Namespace node for the device
983 * space_id - The address space ID
984 *
985 * RETURN: Status
986 *
987 * DESCRIPTION: Run all _REG methods for the input Space ID;
988 * Note: assumes namespace is locked, or system init time.
989 *
990 ******************************************************************************/
991
992acpi_status
993acpi_ev_execute_reg_methods(struct acpi_namespace_node *node,
994 acpi_adr_space_type space_id)
995{
996 acpi_status status;
997
998 ACPI_FUNCTION_TRACE(ev_execute_reg_methods);
999
1000 /*
1001 * Run all _REG methods for all Operation Regions for this space ID. This
1002 * is a separate walk in order to handle any interdependencies between
1003 * regions and _REG methods. (i.e. handlers must be installed for all
1004 * regions of this Space ID before we can run any _REG methods)
1005 */
1006 status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, node, ACPI_UINT32_MAX,
1007 ACPI_NS_WALK_UNLOCK, acpi_ev_reg_run,
1008 &space_id, NULL);
1009
1010 return_ACPI_STATUS(status);
1011}
1012
1013/*******************************************************************************
1014 *
1015 * FUNCTION: acpi_ev_reg_run
1016 *
1017 * PARAMETERS: walk_namespace callback
1018 *
1019 * DESCRIPTION: Run _REG method for region objects of the requested space_iD
1020 *
1021 ******************************************************************************/
1022
1023static acpi_status
1024acpi_ev_reg_run(acpi_handle obj_handle,
1025 u32 level, void *context, void **return_value)
1026{
1027 union acpi_operand_object *obj_desc;
1028 struct acpi_namespace_node *node;
1029 acpi_adr_space_type space_id;
1030 acpi_status status;
1031
1032 space_id = *ACPI_CAST_PTR(acpi_adr_space_type, context);
1033
1034 /* Convert and validate the device handle */
1035
1036 node = acpi_ns_map_handle_to_node(obj_handle);
1037 if (!node) {
1038 return (AE_BAD_PARAMETER);
1039 }
1040
1041 /*
1042 * We only care about regions.and objects that are allowed to have address
1043 * space handlers
1044 */
1045 if ((node->type != ACPI_TYPE_REGION) && (node != acpi_gbl_root_node)) {
1046 return (AE_OK);
1047 }
1048
1049 /* Check for an existing internal object */
1050
1051 obj_desc = acpi_ns_get_attached_object(node);
1052 if (!obj_desc) {
1053
1054 /* No object, just exit */
1055
1056 return (AE_OK);
1057 }
1058
1059 /* Object is a Region */
1060
1061 if (obj_desc->region.space_id != space_id) {
1062
1063 /* This region is for a different address space, just ignore it */
1064
1065 return (AE_OK);
1066 }
1067
1068 status = acpi_ev_execute_reg_method(obj_desc, 1);
1069 return (status);
1070}
diff --git a/drivers/acpi/acpica/evrgnini.c b/drivers/acpi/acpica/evrgnini.c
new file mode 100644
index 00000000000..1b7f9fdbef1
--- /dev/null
+++ b/drivers/acpi/acpica/evrgnini.c
@@ -0,0 +1,684 @@
1/******************************************************************************
2 *
3 * Module Name: evrgnini- ACPI address_space (op_region) init
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46#include <acpi/acevents.h>
47#include <acpi/acnamesp.h>
48
49#define _COMPONENT ACPI_EVENTS
50ACPI_MODULE_NAME("evrgnini")
51
52/* Local prototypes */
53static u8 acpi_ev_match_pci_root_bridge(char *id);
54
55static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node);
56
57/*******************************************************************************
58 *
59 * FUNCTION: acpi_ev_system_memory_region_setup
60 *
61 * PARAMETERS: Handle - Region we are interested in
62 * Function - Start or stop
63 * handler_context - Address space handler context
64 * region_context - Region specific context
65 *
66 * RETURN: Status
67 *
68 * DESCRIPTION: Setup a system_memory operation region
69 *
70 ******************************************************************************/
71
72acpi_status
73acpi_ev_system_memory_region_setup(acpi_handle handle,
74 u32 function,
75 void *handler_context, void **region_context)
76{
77 union acpi_operand_object *region_desc =
78 (union acpi_operand_object *)handle;
79 struct acpi_mem_space_context *local_region_context;
80
81 ACPI_FUNCTION_TRACE(ev_system_memory_region_setup);
82
83 if (function == ACPI_REGION_DEACTIVATE) {
84 if (*region_context) {
85 local_region_context =
86 (struct acpi_mem_space_context *)*region_context;
87
88 /* Delete a cached mapping if present */
89
90 if (local_region_context->mapped_length) {
91 acpi_os_unmap_memory(local_region_context->
92 mapped_logical_address,
93 local_region_context->
94 mapped_length);
95 }
96 ACPI_FREE(local_region_context);
97 *region_context = NULL;
98 }
99 return_ACPI_STATUS(AE_OK);
100 }
101
102 /* Create a new context */
103
104 local_region_context =
105 ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_mem_space_context));
106 if (!(local_region_context)) {
107 return_ACPI_STATUS(AE_NO_MEMORY);
108 }
109
110 /* Save the region length and address for use in the handler */
111
112 local_region_context->length = region_desc->region.length;
113 local_region_context->address = region_desc->region.address;
114
115 *region_context = local_region_context;
116 return_ACPI_STATUS(AE_OK);
117}
118
119/*******************************************************************************
120 *
121 * FUNCTION: acpi_ev_io_space_region_setup
122 *
123 * PARAMETERS: Handle - Region we are interested in
124 * Function - Start or stop
125 * handler_context - Address space handler context
126 * region_context - Region specific context
127 *
128 * RETURN: Status
129 *
130 * DESCRIPTION: Setup a IO operation region
131 *
132 ******************************************************************************/
133
134acpi_status
135acpi_ev_io_space_region_setup(acpi_handle handle,
136 u32 function,
137 void *handler_context, void **region_context)
138{
139 ACPI_FUNCTION_TRACE(ev_io_space_region_setup);
140
141 if (function == ACPI_REGION_DEACTIVATE) {
142 *region_context = NULL;
143 } else {
144 *region_context = handler_context;
145 }
146
147 return_ACPI_STATUS(AE_OK);
148}
149
150/*******************************************************************************
151 *
152 * FUNCTION: acpi_ev_pci_config_region_setup
153 *
154 * PARAMETERS: Handle - Region we are interested in
155 * Function - Start or stop
156 * handler_context - Address space handler context
157 * region_context - Region specific context
158 *
159 * RETURN: Status
160 *
161 * DESCRIPTION: Setup a PCI_Config operation region
162 *
163 * MUTEX: Assumes namespace is not locked
164 *
165 ******************************************************************************/
166
167acpi_status
168acpi_ev_pci_config_region_setup(acpi_handle handle,
169 u32 function,
170 void *handler_context, void **region_context)
171{
172 acpi_status status = AE_OK;
173 acpi_integer pci_value;
174 struct acpi_pci_id *pci_id = *region_context;
175 union acpi_operand_object *handler_obj;
176 struct acpi_namespace_node *parent_node;
177 struct acpi_namespace_node *pci_root_node;
178 struct acpi_namespace_node *pci_device_node;
179 union acpi_operand_object *region_obj =
180 (union acpi_operand_object *)handle;
181
182 ACPI_FUNCTION_TRACE(ev_pci_config_region_setup);
183
184 handler_obj = region_obj->region.handler;
185 if (!handler_obj) {
186 /*
187 * No installed handler. This shouldn't happen because the dispatch
188 * routine checks before we get here, but we check again just in case.
189 */
190 ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
191 "Attempting to init a region %p, with no handler\n",
192 region_obj));
193 return_ACPI_STATUS(AE_NOT_EXIST);
194 }
195
196 *region_context = NULL;
197 if (function == ACPI_REGION_DEACTIVATE) {
198 if (pci_id) {
199 ACPI_FREE(pci_id);
200 }
201 return_ACPI_STATUS(status);
202 }
203
204 parent_node = acpi_ns_get_parent_node(region_obj->region.node);
205
206 /*
207 * Get the _SEG and _BBN values from the device upon which the handler
208 * is installed.
209 *
210 * We need to get the _SEG and _BBN objects relative to the PCI BUS device.
211 * This is the device the handler has been registered to handle.
212 */
213
214 /*
215 * If the address_space.Node is still pointing to the root, we need
216 * to scan upward for a PCI Root bridge and re-associate the op_region
217 * handlers with that device.
218 */
219 if (handler_obj->address_space.node == acpi_gbl_root_node) {
220
221 /* Start search from the parent object */
222
223 pci_root_node = parent_node;
224 while (pci_root_node != acpi_gbl_root_node) {
225
226 /* Get the _HID/_CID in order to detect a root_bridge */
227
228 if (acpi_ev_is_pci_root_bridge(pci_root_node)) {
229
230 /* Install a handler for this PCI root bridge */
231
232 status =
233 acpi_install_address_space_handler((acpi_handle) pci_root_node, ACPI_ADR_SPACE_PCI_CONFIG, ACPI_DEFAULT_HANDLER, NULL, NULL);
234 if (ACPI_FAILURE(status)) {
235 if (status == AE_SAME_HANDLER) {
236 /*
237 * It is OK if the handler is already installed on the
238 * root bridge. Still need to return a context object
239 * for the new PCI_Config operation region, however.
240 */
241 status = AE_OK;
242 } else {
243 ACPI_EXCEPTION((AE_INFO, status,
244 "Could not install PciConfig handler for Root Bridge %4.4s",
245 acpi_ut_get_node_name
246 (pci_root_node)));
247 }
248 }
249 break;
250 }
251
252 pci_root_node = acpi_ns_get_parent_node(pci_root_node);
253 }
254
255 /* PCI root bridge not found, use namespace root node */
256 } else {
257 pci_root_node = handler_obj->address_space.node;
258 }
259
260 /*
261 * If this region is now initialized, we are done.
262 * (install_address_space_handler could have initialized it)
263 */
264 if (region_obj->region.flags & AOPOBJ_SETUP_COMPLETE) {
265 return_ACPI_STATUS(AE_OK);
266 }
267
268 /* Region is still not initialized. Create a new context */
269
270 pci_id = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_pci_id));
271 if (!pci_id) {
272 return_ACPI_STATUS(AE_NO_MEMORY);
273 }
274
275 /*
276 * For PCI_Config space access, we need the segment, bus, device and
277 * function numbers. Acquire them here.
278 *
279 * Find the parent device object. (This allows the operation region to be
280 * within a subscope under the device, such as a control method.)
281 */
282 pci_device_node = region_obj->region.node;
283 while (pci_device_node && (pci_device_node->type != ACPI_TYPE_DEVICE)) {
284 pci_device_node = acpi_ns_get_parent_node(pci_device_node);
285 }
286
287 if (!pci_device_node) {
288 ACPI_FREE(pci_id);
289 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
290 }
291
292 /*
293 * Get the PCI device and function numbers from the _ADR object contained
294 * in the parent's scope.
295 */
296 status =
297 acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR, pci_device_node,
298 &pci_value);
299
300 /*
301 * The default is zero, and since the allocation above zeroed the data,
302 * just do nothing on failure.
303 */
304 if (ACPI_SUCCESS(status)) {
305 pci_id->device = ACPI_HIWORD(ACPI_LODWORD(pci_value));
306 pci_id->function = ACPI_LOWORD(ACPI_LODWORD(pci_value));
307 }
308
309 /* The PCI segment number comes from the _SEG method */
310
311 status =
312 acpi_ut_evaluate_numeric_object(METHOD_NAME__SEG, pci_root_node,
313 &pci_value);
314 if (ACPI_SUCCESS(status)) {
315 pci_id->segment = ACPI_LOWORD(pci_value);
316 }
317
318 /* The PCI bus number comes from the _BBN method */
319
320 status =
321 acpi_ut_evaluate_numeric_object(METHOD_NAME__BBN, pci_root_node,
322 &pci_value);
323 if (ACPI_SUCCESS(status)) {
324 pci_id->bus = ACPI_LOWORD(pci_value);
325 }
326
327 /* Complete this device's pci_id */
328
329 acpi_os_derive_pci_id(pci_root_node, region_obj->region.node, &pci_id);
330
331 *region_context = pci_id;
332 return_ACPI_STATUS(AE_OK);
333}
334
335/*******************************************************************************
336 *
337 * FUNCTION: acpi_ev_match_pci_root_bridge
338 *
339 * PARAMETERS: Id - The HID/CID in string format
340 *
341 * RETURN: TRUE if the Id is a match for a PCI/PCI-Express Root Bridge
342 *
343 * DESCRIPTION: Determine if the input ID is a PCI Root Bridge ID.
344 *
345 ******************************************************************************/
346
347static u8 acpi_ev_match_pci_root_bridge(char *id)
348{
349
350 /*
351 * Check if this is a PCI root.
352 * ACPI 3.0+: check for a PCI Express root also.
353 */
354 if (!(ACPI_STRNCMP(id,
355 PCI_ROOT_HID_STRING,
356 sizeof(PCI_ROOT_HID_STRING))) ||
357 !(ACPI_STRNCMP(id,
358 PCI_EXPRESS_ROOT_HID_STRING,
359 sizeof(PCI_EXPRESS_ROOT_HID_STRING)))) {
360 return (TRUE);
361 }
362
363 return (FALSE);
364}
365
366/*******************************************************************************
367 *
368 * FUNCTION: acpi_ev_is_pci_root_bridge
369 *
370 * PARAMETERS: Node - Device node being examined
371 *
372 * RETURN: TRUE if device is a PCI/PCI-Express Root Bridge
373 *
374 * DESCRIPTION: Determine if the input device represents a PCI Root Bridge by
375 * examining the _HID and _CID for the device.
376 *
377 ******************************************************************************/
378
379static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node)
380{
381 acpi_status status;
382 struct acpica_device_id hid;
383 struct acpi_compatible_id_list *cid;
384 u32 i;
385
386 /* Get the _HID and check for a PCI Root Bridge */
387
388 status = acpi_ut_execute_HID(node, &hid);
389 if (ACPI_FAILURE(status)) {
390 return (FALSE);
391 }
392
393 if (acpi_ev_match_pci_root_bridge(hid.value)) {
394 return (TRUE);
395 }
396
397 /* The _HID did not match. Get the _CID and check for a PCI Root Bridge */
398
399 status = acpi_ut_execute_CID(node, &cid);
400 if (ACPI_FAILURE(status)) {
401 return (FALSE);
402 }
403
404 /* Check all _CIDs in the returned list */
405
406 for (i = 0; i < cid->count; i++) {
407 if (acpi_ev_match_pci_root_bridge(cid->id[i].value)) {
408 ACPI_FREE(cid);
409 return (TRUE);
410 }
411 }
412
413 ACPI_FREE(cid);
414 return (FALSE);
415}
416
417/*******************************************************************************
418 *
419 * FUNCTION: acpi_ev_pci_bar_region_setup
420 *
421 * PARAMETERS: Handle - Region we are interested in
422 * Function - Start or stop
423 * handler_context - Address space handler context
424 * region_context - Region specific context
425 *
426 * RETURN: Status
427 *
428 * DESCRIPTION: Setup a pci_bAR operation region
429 *
430 * MUTEX: Assumes namespace is not locked
431 *
432 ******************************************************************************/
433
434acpi_status
435acpi_ev_pci_bar_region_setup(acpi_handle handle,
436 u32 function,
437 void *handler_context, void **region_context)
438{
439 ACPI_FUNCTION_TRACE(ev_pci_bar_region_setup);
440
441 return_ACPI_STATUS(AE_OK);
442}
443
444/*******************************************************************************
445 *
446 * FUNCTION: acpi_ev_cmos_region_setup
447 *
448 * PARAMETERS: Handle - Region we are interested in
449 * Function - Start or stop
450 * handler_context - Address space handler context
451 * region_context - Region specific context
452 *
453 * RETURN: Status
454 *
455 * DESCRIPTION: Setup a CMOS operation region
456 *
457 * MUTEX: Assumes namespace is not locked
458 *
459 ******************************************************************************/
460
461acpi_status
462acpi_ev_cmos_region_setup(acpi_handle handle,
463 u32 function,
464 void *handler_context, void **region_context)
465{
466 ACPI_FUNCTION_TRACE(ev_cmos_region_setup);
467
468 return_ACPI_STATUS(AE_OK);
469}
470
471/*******************************************************************************
472 *
473 * FUNCTION: acpi_ev_default_region_setup
474 *
475 * PARAMETERS: Handle - Region we are interested in
476 * Function - Start or stop
477 * handler_context - Address space handler context
478 * region_context - Region specific context
479 *
480 * RETURN: Status
481 *
482 * DESCRIPTION: Default region initialization
483 *
484 ******************************************************************************/
485
486acpi_status
487acpi_ev_default_region_setup(acpi_handle handle,
488 u32 function,
489 void *handler_context, void **region_context)
490{
491 ACPI_FUNCTION_TRACE(ev_default_region_setup);
492
493 if (function == ACPI_REGION_DEACTIVATE) {
494 *region_context = NULL;
495 } else {
496 *region_context = handler_context;
497 }
498
499 return_ACPI_STATUS(AE_OK);
500}
501
502/*******************************************************************************
503 *
504 * FUNCTION: acpi_ev_initialize_region
505 *
506 * PARAMETERS: region_obj - Region we are initializing
507 * acpi_ns_locked - Is namespace locked?
508 *
509 * RETURN: Status
510 *
511 * DESCRIPTION: Initializes the region, finds any _REG methods and saves them
512 * for execution at a later time
513 *
514 * Get the appropriate address space handler for a newly
515 * created region.
516 *
517 * This also performs address space specific initialization. For
518 * example, PCI regions must have an _ADR object that contains
519 * a PCI address in the scope of the definition. This address is
520 * required to perform an access to PCI config space.
521 *
522 * MUTEX: Interpreter should be unlocked, because we may run the _REG
523 * method for this region.
524 *
525 ******************************************************************************/
526
527acpi_status
528acpi_ev_initialize_region(union acpi_operand_object *region_obj,
529 u8 acpi_ns_locked)
530{
531 union acpi_operand_object *handler_obj;
532 union acpi_operand_object *obj_desc;
533 acpi_adr_space_type space_id;
534 struct acpi_namespace_node *node;
535 acpi_status status;
536 struct acpi_namespace_node *method_node;
537 acpi_name *reg_name_ptr = (acpi_name *) METHOD_NAME__REG;
538 union acpi_operand_object *region_obj2;
539
540 ACPI_FUNCTION_TRACE_U32(ev_initialize_region, acpi_ns_locked);
541
542 if (!region_obj) {
543 return_ACPI_STATUS(AE_BAD_PARAMETER);
544 }
545
546 if (region_obj->common.flags & AOPOBJ_OBJECT_INITIALIZED) {
547 return_ACPI_STATUS(AE_OK);
548 }
549
550 region_obj2 = acpi_ns_get_secondary_object(region_obj);
551 if (!region_obj2) {
552 return_ACPI_STATUS(AE_NOT_EXIST);
553 }
554
555 node = acpi_ns_get_parent_node(region_obj->region.node);
556 space_id = region_obj->region.space_id;
557
558 /* Setup defaults */
559
560 region_obj->region.handler = NULL;
561 region_obj2->extra.method_REG = NULL;
562 region_obj->common.flags &= ~(AOPOBJ_SETUP_COMPLETE);
563 region_obj->common.flags |= AOPOBJ_OBJECT_INITIALIZED;
564
565 /* Find any "_REG" method associated with this region definition */
566
567 status =
568 acpi_ns_search_one_scope(*reg_name_ptr, node, ACPI_TYPE_METHOD,
569 &method_node);
570 if (ACPI_SUCCESS(status)) {
571 /*
572 * The _REG method is optional and there can be only one per region
573 * definition. This will be executed when the handler is attached
574 * or removed
575 */
576 region_obj2->extra.method_REG = method_node;
577 }
578
579 /*
580 * The following loop depends upon the root Node having no parent
581 * ie: acpi_gbl_root_node->parent_entry being set to NULL
582 */
583 while (node) {
584
585 /* Check to see if a handler exists */
586
587 handler_obj = NULL;
588 obj_desc = acpi_ns_get_attached_object(node);
589 if (obj_desc) {
590
591 /* Can only be a handler if the object exists */
592
593 switch (node->type) {
594 case ACPI_TYPE_DEVICE:
595
596 handler_obj = obj_desc->device.handler;
597 break;
598
599 case ACPI_TYPE_PROCESSOR:
600
601 handler_obj = obj_desc->processor.handler;
602 break;
603
604 case ACPI_TYPE_THERMAL:
605
606 handler_obj = obj_desc->thermal_zone.handler;
607 break;
608
609 default:
610 /* Ignore other objects */
611 break;
612 }
613
614 while (handler_obj) {
615
616 /* Is this handler of the correct type? */
617
618 if (handler_obj->address_space.space_id ==
619 space_id) {
620
621 /* Found correct handler */
622
623 ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
624 "Found handler %p for region %p in obj %p\n",
625 handler_obj,
626 region_obj,
627 obj_desc));
628
629 status =
630 acpi_ev_attach_region(handler_obj,
631 region_obj,
632 acpi_ns_locked);
633
634 /*
635 * Tell all users that this region is usable by running the _REG
636 * method
637 */
638 if (acpi_ns_locked) {
639 status =
640 acpi_ut_release_mutex
641 (ACPI_MTX_NAMESPACE);
642 if (ACPI_FAILURE(status)) {
643 return_ACPI_STATUS
644 (status);
645 }
646 }
647
648 status =
649 acpi_ev_execute_reg_method
650 (region_obj, 1);
651
652 if (acpi_ns_locked) {
653 status =
654 acpi_ut_acquire_mutex
655 (ACPI_MTX_NAMESPACE);
656 if (ACPI_FAILURE(status)) {
657 return_ACPI_STATUS
658 (status);
659 }
660 }
661
662 return_ACPI_STATUS(AE_OK);
663 }
664
665 /* Try next handler in the list */
666
667 handler_obj = handler_obj->address_space.next;
668 }
669 }
670
671 /* This node does not have the handler we need; Pop up one level */
672
673 node = acpi_ns_get_parent_node(node);
674 }
675
676 /* If we get here, there is no handler for this region */
677
678 ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
679 "No handler for RegionType %s(%X) (RegionObj %p)\n",
680 acpi_ut_get_region_name(space_id), space_id,
681 region_obj));
682
683 return_ACPI_STATUS(AE_NOT_EXIST);
684}
diff --git a/drivers/acpi/acpica/evsci.c b/drivers/acpi/acpica/evsci.c
new file mode 100644
index 00000000000..18dce10c5fb
--- /dev/null
+++ b/drivers/acpi/acpica/evsci.c
@@ -0,0 +1,183 @@
1/*******************************************************************************
2 *
3 * Module Name: evsci - System Control Interrupt configuration and
4 * legacy to ACPI mode state transition functions
5 *
6 ******************************************************************************/
7
8/*
9 * Copyright (C) 2000 - 2008, Intel Corp.
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions, and the following disclaimer,
17 * without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 * substantially similar to the "NO WARRANTY" disclaimer below
20 * ("Disclaimer") and any redistribution must be conditioned upon
21 * including a substantially similar Disclaimer requirement for further
22 * binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 * of any contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
30 *
31 * NO WARRANTY
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
43 */
44
45#include <acpi/acpi.h>
46#include <acpi/accommon.h>
47#include <acpi/acevents.h>
48
49#define _COMPONENT ACPI_EVENTS
50ACPI_MODULE_NAME("evsci")
51
52/* Local prototypes */
53static u32 ACPI_SYSTEM_XFACE acpi_ev_sci_xrupt_handler(void *context);
54
55/*******************************************************************************
56 *
57 * FUNCTION: acpi_ev_sci_xrupt_handler
58 *
59 * PARAMETERS: Context - Calling Context
60 *
61 * RETURN: Status code indicates whether interrupt was handled.
62 *
63 * DESCRIPTION: Interrupt handler that will figure out what function or
64 * control method to call to deal with a SCI.
65 *
66 ******************************************************************************/
67
68static u32 ACPI_SYSTEM_XFACE acpi_ev_sci_xrupt_handler(void *context)
69{
70 struct acpi_gpe_xrupt_info *gpe_xrupt_list = context;
71 u32 interrupt_handled = ACPI_INTERRUPT_NOT_HANDLED;
72
73 ACPI_FUNCTION_TRACE(ev_sci_xrupt_handler);
74
75 /*
76 * We are guaranteed by the ACPI CA initialization/shutdown code that
77 * if this interrupt handler is installed, ACPI is enabled.
78 */
79
80 /*
81 * Fixed Events:
82 * Check for and dispatch any Fixed Events that have occurred
83 */
84 interrupt_handled |= acpi_ev_fixed_event_detect();
85
86 /*
87 * General Purpose Events:
88 * Check for and dispatch any GPEs that have occurred
89 */
90 interrupt_handled |= acpi_ev_gpe_detect(gpe_xrupt_list);
91
92 return_UINT32(interrupt_handled);
93}
94
95/*******************************************************************************
96 *
97 * FUNCTION: acpi_ev_gpe_xrupt_handler
98 *
99 * PARAMETERS: Context - Calling Context
100 *
101 * RETURN: Status code indicates whether interrupt was handled.
102 *
103 * DESCRIPTION: Handler for GPE Block Device interrupts
104 *
105 ******************************************************************************/
106
107u32 ACPI_SYSTEM_XFACE acpi_ev_gpe_xrupt_handler(void *context)
108{
109 struct acpi_gpe_xrupt_info *gpe_xrupt_list = context;
110 u32 interrupt_handled = ACPI_INTERRUPT_NOT_HANDLED;
111
112 ACPI_FUNCTION_TRACE(ev_gpe_xrupt_handler);
113
114 /*
115 * We are guaranteed by the ACPI CA initialization/shutdown code that
116 * if this interrupt handler is installed, ACPI is enabled.
117 */
118
119 /* GPEs: Check for and dispatch any GPEs that have occurred */
120
121 interrupt_handled |= acpi_ev_gpe_detect(gpe_xrupt_list);
122
123 return_UINT32(interrupt_handled);
124}
125
126/******************************************************************************
127 *
128 * FUNCTION: acpi_ev_install_sci_handler
129 *
130 * PARAMETERS: none
131 *
132 * RETURN: Status
133 *
134 * DESCRIPTION: Installs SCI handler.
135 *
136 ******************************************************************************/
137
138u32 acpi_ev_install_sci_handler(void)
139{
140 u32 status = AE_OK;
141
142 ACPI_FUNCTION_TRACE(ev_install_sci_handler);
143
144 status =
145 acpi_os_install_interrupt_handler((u32) acpi_gbl_FADT.sci_interrupt,
146 acpi_ev_sci_xrupt_handler,
147 acpi_gbl_gpe_xrupt_list_head);
148 return_ACPI_STATUS(status);
149}
150
151/******************************************************************************
152 *
153 * FUNCTION: acpi_ev_remove_sci_handler
154 *
155 * PARAMETERS: none
156 *
157 * RETURN: E_OK if handler uninstalled OK, E_ERROR if handler was not
158 * installed to begin with
159 *
160 * DESCRIPTION: Remove the SCI interrupt handler. No further SCIs will be
161 * taken.
162 *
163 * Note: It doesn't seem important to disable all events or set the event
164 * enable registers to their original values. The OS should disable
165 * the SCI interrupt level when the handler is removed, so no more
166 * events will come in.
167 *
168 ******************************************************************************/
169
170acpi_status acpi_ev_remove_sci_handler(void)
171{
172 acpi_status status;
173
174 ACPI_FUNCTION_TRACE(ev_remove_sci_handler);
175
176 /* Just let the OS remove the handler and disable the level */
177
178 status =
179 acpi_os_remove_interrupt_handler((u32) acpi_gbl_FADT.sci_interrupt,
180 acpi_ev_sci_xrupt_handler);
181
182 return_ACPI_STATUS(status);
183}
diff --git a/drivers/acpi/acpica/evxface.c b/drivers/acpi/acpica/evxface.c
new file mode 100644
index 00000000000..3b6a069f5b0
--- /dev/null
+++ b/drivers/acpi/acpica/evxface.c
@@ -0,0 +1,821 @@
1/******************************************************************************
2 *
3 * Module Name: evxface - External interfaces for ACPI events
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46#include <acpi/acnamesp.h>
47#include <acpi/acevents.h>
48#include <acpi/acinterp.h>
49
50#define _COMPONENT ACPI_EVENTS
51ACPI_MODULE_NAME("evxface")
52
53/*******************************************************************************
54 *
55 * FUNCTION: acpi_install_exception_handler
56 *
57 * PARAMETERS: Handler - Pointer to the handler function for the
58 * event
59 *
60 * RETURN: Status
61 *
62 * DESCRIPTION: Saves the pointer to the handler function
63 *
64 ******************************************************************************/
65#ifdef ACPI_FUTURE_USAGE
66acpi_status acpi_install_exception_handler(acpi_exception_handler handler)
67{
68 acpi_status status;
69
70 ACPI_FUNCTION_TRACE(acpi_install_exception_handler);
71
72 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
73 if (ACPI_FAILURE(status)) {
74 return_ACPI_STATUS(status);
75 }
76
77 /* Don't allow two handlers. */
78
79 if (acpi_gbl_exception_handler) {
80 status = AE_ALREADY_EXISTS;
81 goto cleanup;
82 }
83
84 /* Install the handler */
85
86 acpi_gbl_exception_handler = handler;
87
88 cleanup:
89 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
90 return_ACPI_STATUS(status);
91}
92
93ACPI_EXPORT_SYMBOL(acpi_install_exception_handler)
94#endif /* ACPI_FUTURE_USAGE */
95/*******************************************************************************
96 *
97 * FUNCTION: acpi_install_fixed_event_handler
98 *
99 * PARAMETERS: Event - Event type to enable.
100 * Handler - Pointer to the handler function for the
101 * event
102 * Context - Value passed to the handler on each GPE
103 *
104 * RETURN: Status
105 *
106 * DESCRIPTION: Saves the pointer to the handler function and then enables the
107 * event.
108 *
109 ******************************************************************************/
110acpi_status
111acpi_install_fixed_event_handler(u32 event,
112 acpi_event_handler handler, void *context)
113{
114 acpi_status status;
115
116 ACPI_FUNCTION_TRACE(acpi_install_fixed_event_handler);
117
118 /* Parameter validation */
119
120 if (event > ACPI_EVENT_MAX) {
121 return_ACPI_STATUS(AE_BAD_PARAMETER);
122 }
123
124 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
125 if (ACPI_FAILURE(status)) {
126 return_ACPI_STATUS(status);
127 }
128
129 /* Don't allow two handlers. */
130
131 if (NULL != acpi_gbl_fixed_event_handlers[event].handler) {
132 status = AE_ALREADY_EXISTS;
133 goto cleanup;
134 }
135
136 /* Install the handler before enabling the event */
137
138 acpi_gbl_fixed_event_handlers[event].handler = handler;
139 acpi_gbl_fixed_event_handlers[event].context = context;
140
141 status = acpi_clear_event(event);
142 if (ACPI_SUCCESS(status))
143 status = acpi_enable_event(event, 0);
144 if (ACPI_FAILURE(status)) {
145 ACPI_WARNING((AE_INFO, "Could not enable fixed event %X",
146 event));
147
148 /* Remove the handler */
149
150 acpi_gbl_fixed_event_handlers[event].handler = NULL;
151 acpi_gbl_fixed_event_handlers[event].context = NULL;
152 } else {
153 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
154 "Enabled fixed event %X, Handler=%p\n", event,
155 handler));
156 }
157
158 cleanup:
159 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
160 return_ACPI_STATUS(status);
161}
162
163ACPI_EXPORT_SYMBOL(acpi_install_fixed_event_handler)
164
165/*******************************************************************************
166 *
167 * FUNCTION: acpi_remove_fixed_event_handler
168 *
169 * PARAMETERS: Event - Event type to disable.
170 * Handler - Address of the handler
171 *
172 * RETURN: Status
173 *
174 * DESCRIPTION: Disables the event and unregisters the event handler.
175 *
176 ******************************************************************************/
177acpi_status
178acpi_remove_fixed_event_handler(u32 event, acpi_event_handler handler)
179{
180 acpi_status status = AE_OK;
181
182 ACPI_FUNCTION_TRACE(acpi_remove_fixed_event_handler);
183
184 /* Parameter validation */
185
186 if (event > ACPI_EVENT_MAX) {
187 return_ACPI_STATUS(AE_BAD_PARAMETER);
188 }
189
190 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
191 if (ACPI_FAILURE(status)) {
192 return_ACPI_STATUS(status);
193 }
194
195 /* Disable the event before removing the handler */
196
197 status = acpi_disable_event(event, 0);
198
199 /* Always Remove the handler */
200
201 acpi_gbl_fixed_event_handlers[event].handler = NULL;
202 acpi_gbl_fixed_event_handlers[event].context = NULL;
203
204 if (ACPI_FAILURE(status)) {
205 ACPI_WARNING((AE_INFO,
206 "Could not write to fixed event enable register %X",
207 event));
208 } else {
209 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Disabled fixed event %X\n",
210 event));
211 }
212
213 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
214 return_ACPI_STATUS(status);
215}
216
217ACPI_EXPORT_SYMBOL(acpi_remove_fixed_event_handler)
218
219/*******************************************************************************
220 *
221 * FUNCTION: acpi_install_notify_handler
222 *
223 * PARAMETERS: Device - The device for which notifies will be handled
224 * handler_type - The type of handler:
225 * ACPI_SYSTEM_NOTIFY: system_handler (00-7f)
226 * ACPI_DEVICE_NOTIFY: driver_handler (80-ff)
227 * ACPI_ALL_NOTIFY: both system and device
228 * Handler - Address of the handler
229 * Context - Value passed to the handler on each GPE
230 *
231 * RETURN: Status
232 *
233 * DESCRIPTION: Install a handler for notifies on an ACPI device
234 *
235 ******************************************************************************/
236acpi_status
237acpi_install_notify_handler(acpi_handle device,
238 u32 handler_type,
239 acpi_notify_handler handler, void *context)
240{
241 union acpi_operand_object *obj_desc;
242 union acpi_operand_object *notify_obj;
243 struct acpi_namespace_node *node;
244 acpi_status status;
245
246 ACPI_FUNCTION_TRACE(acpi_install_notify_handler);
247
248 /* Parameter validation */
249
250 if ((!device) ||
251 (!handler) || (handler_type > ACPI_MAX_NOTIFY_HANDLER_TYPE)) {
252 return_ACPI_STATUS(AE_BAD_PARAMETER);
253 }
254
255 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
256 if (ACPI_FAILURE(status)) {
257 return_ACPI_STATUS(status);
258 }
259
260 /* Convert and validate the device handle */
261
262 node = acpi_ns_map_handle_to_node(device);
263 if (!node) {
264 status = AE_BAD_PARAMETER;
265 goto unlock_and_exit;
266 }
267
268 /*
269 * Root Object:
270 * Registering a notify handler on the root object indicates that the
271 * caller wishes to receive notifications for all objects. Note that
272 * only one <external> global handler can be regsitered (per notify type).
273 */
274 if (device == ACPI_ROOT_OBJECT) {
275
276 /* Make sure the handler is not already installed */
277
278 if (((handler_type & ACPI_SYSTEM_NOTIFY) &&
279 acpi_gbl_system_notify.handler) ||
280 ((handler_type & ACPI_DEVICE_NOTIFY) &&
281 acpi_gbl_device_notify.handler)) {
282 status = AE_ALREADY_EXISTS;
283 goto unlock_and_exit;
284 }
285
286 if (handler_type & ACPI_SYSTEM_NOTIFY) {
287 acpi_gbl_system_notify.node = node;
288 acpi_gbl_system_notify.handler = handler;
289 acpi_gbl_system_notify.context = context;
290 }
291
292 if (handler_type & ACPI_DEVICE_NOTIFY) {
293 acpi_gbl_device_notify.node = node;
294 acpi_gbl_device_notify.handler = handler;
295 acpi_gbl_device_notify.context = context;
296 }
297
298 /* Global notify handler installed */
299 }
300
301 /*
302 * All Other Objects:
303 * Caller will only receive notifications specific to the target object.
304 * Note that only certain object types can receive notifications.
305 */
306 else {
307 /* Notifies allowed on this object? */
308
309 if (!acpi_ev_is_notify_object(node)) {
310 status = AE_TYPE;
311 goto unlock_and_exit;
312 }
313
314 /* Check for an existing internal object */
315
316 obj_desc = acpi_ns_get_attached_object(node);
317 if (obj_desc) {
318
319 /* Object exists - make sure there's no handler */
320
321 if (((handler_type & ACPI_SYSTEM_NOTIFY) &&
322 obj_desc->common_notify.system_notify) ||
323 ((handler_type & ACPI_DEVICE_NOTIFY) &&
324 obj_desc->common_notify.device_notify)) {
325 status = AE_ALREADY_EXISTS;
326 goto unlock_and_exit;
327 }
328 } else {
329 /* Create a new object */
330
331 obj_desc = acpi_ut_create_internal_object(node->type);
332 if (!obj_desc) {
333 status = AE_NO_MEMORY;
334 goto unlock_and_exit;
335 }
336
337 /* Attach new object to the Node */
338
339 status =
340 acpi_ns_attach_object(device, obj_desc, node->type);
341
342 /* Remove local reference to the object */
343
344 acpi_ut_remove_reference(obj_desc);
345 if (ACPI_FAILURE(status)) {
346 goto unlock_and_exit;
347 }
348 }
349
350 /* Install the handler */
351
352 notify_obj =
353 acpi_ut_create_internal_object(ACPI_TYPE_LOCAL_NOTIFY);
354 if (!notify_obj) {
355 status = AE_NO_MEMORY;
356 goto unlock_and_exit;
357 }
358
359 notify_obj->notify.node = node;
360 notify_obj->notify.handler = handler;
361 notify_obj->notify.context = context;
362
363 if (handler_type & ACPI_SYSTEM_NOTIFY) {
364 obj_desc->common_notify.system_notify = notify_obj;
365 }
366
367 if (handler_type & ACPI_DEVICE_NOTIFY) {
368 obj_desc->common_notify.device_notify = notify_obj;
369 }
370
371 if (handler_type == ACPI_ALL_NOTIFY) {
372
373 /* Extra ref if installed in both */
374
375 acpi_ut_add_reference(notify_obj);
376 }
377 }
378
379 unlock_and_exit:
380 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
381 return_ACPI_STATUS(status);
382}
383
384ACPI_EXPORT_SYMBOL(acpi_install_notify_handler)
385
386/*******************************************************************************
387 *
388 * FUNCTION: acpi_remove_notify_handler
389 *
390 * PARAMETERS: Device - The device for which notifies will be handled
391 * handler_type - The type of handler:
392 * ACPI_SYSTEM_NOTIFY: system_handler (00-7f)
393 * ACPI_DEVICE_NOTIFY: driver_handler (80-ff)
394 * ACPI_ALL_NOTIFY: both system and device
395 * Handler - Address of the handler
396 *
397 * RETURN: Status
398 *
399 * DESCRIPTION: Remove a handler for notifies on an ACPI device
400 *
401 ******************************************************************************/
402acpi_status
403acpi_remove_notify_handler(acpi_handle device,
404 u32 handler_type, acpi_notify_handler handler)
405{
406 union acpi_operand_object *notify_obj;
407 union acpi_operand_object *obj_desc;
408 struct acpi_namespace_node *node;
409 acpi_status status;
410
411 ACPI_FUNCTION_TRACE(acpi_remove_notify_handler);
412
413 /* Parameter validation */
414
415 if ((!device) ||
416 (!handler) || (handler_type > ACPI_MAX_NOTIFY_HANDLER_TYPE)) {
417 status = AE_BAD_PARAMETER;
418 goto exit;
419 }
420
421 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
422 if (ACPI_FAILURE(status)) {
423 goto exit;
424 }
425
426 /* Convert and validate the device handle */
427
428 node = acpi_ns_map_handle_to_node(device);
429 if (!node) {
430 status = AE_BAD_PARAMETER;
431 goto unlock_and_exit;
432 }
433
434 /* Root Object */
435
436 if (device == ACPI_ROOT_OBJECT) {
437 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
438 "Removing notify handler for namespace root object\n"));
439
440 if (((handler_type & ACPI_SYSTEM_NOTIFY) &&
441 !acpi_gbl_system_notify.handler) ||
442 ((handler_type & ACPI_DEVICE_NOTIFY) &&
443 !acpi_gbl_device_notify.handler)) {
444 status = AE_NOT_EXIST;
445 goto unlock_and_exit;
446 }
447
448 /* Make sure all deferred tasks are completed */
449
450 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
451 acpi_os_wait_events_complete(NULL);
452 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
453 if (ACPI_FAILURE(status)) {
454 goto exit;
455 }
456
457 if (handler_type & ACPI_SYSTEM_NOTIFY) {
458 acpi_gbl_system_notify.node = NULL;
459 acpi_gbl_system_notify.handler = NULL;
460 acpi_gbl_system_notify.context = NULL;
461 }
462
463 if (handler_type & ACPI_DEVICE_NOTIFY) {
464 acpi_gbl_device_notify.node = NULL;
465 acpi_gbl_device_notify.handler = NULL;
466 acpi_gbl_device_notify.context = NULL;
467 }
468 }
469
470 /* All Other Objects */
471
472 else {
473 /* Notifies allowed on this object? */
474
475 if (!acpi_ev_is_notify_object(node)) {
476 status = AE_TYPE;
477 goto unlock_and_exit;
478 }
479
480 /* Check for an existing internal object */
481
482 obj_desc = acpi_ns_get_attached_object(node);
483 if (!obj_desc) {
484 status = AE_NOT_EXIST;
485 goto unlock_and_exit;
486 }
487
488 /* Object exists - make sure there's an existing handler */
489
490 if (handler_type & ACPI_SYSTEM_NOTIFY) {
491 notify_obj = obj_desc->common_notify.system_notify;
492 if (!notify_obj) {
493 status = AE_NOT_EXIST;
494 goto unlock_and_exit;
495 }
496
497 if (notify_obj->notify.handler != handler) {
498 status = AE_BAD_PARAMETER;
499 goto unlock_and_exit;
500 }
501 /* Make sure all deferred tasks are completed */
502
503 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
504 acpi_os_wait_events_complete(NULL);
505 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
506 if (ACPI_FAILURE(status)) {
507 goto exit;
508 }
509
510 /* Remove the handler */
511 obj_desc->common_notify.system_notify = NULL;
512 acpi_ut_remove_reference(notify_obj);
513 }
514
515 if (handler_type & ACPI_DEVICE_NOTIFY) {
516 notify_obj = obj_desc->common_notify.device_notify;
517 if (!notify_obj) {
518 status = AE_NOT_EXIST;
519 goto unlock_and_exit;
520 }
521
522 if (notify_obj->notify.handler != handler) {
523 status = AE_BAD_PARAMETER;
524 goto unlock_and_exit;
525 }
526 /* Make sure all deferred tasks are completed */
527
528 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
529 acpi_os_wait_events_complete(NULL);
530 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
531 if (ACPI_FAILURE(status)) {
532 goto exit;
533 }
534
535 /* Remove the handler */
536 obj_desc->common_notify.device_notify = NULL;
537 acpi_ut_remove_reference(notify_obj);
538 }
539 }
540
541 unlock_and_exit:
542 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
543 exit:
544 if (ACPI_FAILURE(status))
545 ACPI_EXCEPTION((AE_INFO, status, "Removing notify handler"));
546 return_ACPI_STATUS(status);
547}
548
549ACPI_EXPORT_SYMBOL(acpi_remove_notify_handler)
550
551/*******************************************************************************
552 *
553 * FUNCTION: acpi_install_gpe_handler
554 *
555 * PARAMETERS: gpe_device - Namespace node for the GPE (NULL for FADT
556 * defined GPEs)
557 * gpe_number - The GPE number within the GPE block
558 * Type - Whether this GPE should be treated as an
559 * edge- or level-triggered interrupt.
560 * Address - Address of the handler
561 * Context - Value passed to the handler on each GPE
562 *
563 * RETURN: Status
564 *
565 * DESCRIPTION: Install a handler for a General Purpose Event.
566 *
567 ******************************************************************************/
568acpi_status
569acpi_install_gpe_handler(acpi_handle gpe_device,
570 u32 gpe_number,
571 u32 type, acpi_event_handler address, void *context)
572{
573 struct acpi_gpe_event_info *gpe_event_info;
574 struct acpi_handler_info *handler;
575 acpi_status status;
576 acpi_cpu_flags flags;
577
578 ACPI_FUNCTION_TRACE(acpi_install_gpe_handler);
579
580 /* Parameter validation */
581
582 if ((!address) || (type > ACPI_GPE_XRUPT_TYPE_MASK)) {
583 status = AE_BAD_PARAMETER;
584 goto exit;
585 }
586
587 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
588 if (ACPI_FAILURE(status)) {
589 goto exit;
590 }
591
592 /* Ensure that we have a valid GPE number */
593
594 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
595 if (!gpe_event_info) {
596 status = AE_BAD_PARAMETER;
597 goto unlock_and_exit;
598 }
599
600 /* Make sure that there isn't a handler there already */
601
602 if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) ==
603 ACPI_GPE_DISPATCH_HANDLER) {
604 status = AE_ALREADY_EXISTS;
605 goto unlock_and_exit;
606 }
607
608 /* Allocate and init handler object */
609
610 handler = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_handler_info));
611 if (!handler) {
612 status = AE_NO_MEMORY;
613 goto unlock_and_exit;
614 }
615
616 handler->address = address;
617 handler->context = context;
618 handler->method_node = gpe_event_info->dispatch.method_node;
619
620 /* Disable the GPE before installing the handler */
621
622 status = acpi_ev_disable_gpe(gpe_event_info);
623 if (ACPI_FAILURE(status)) {
624 goto unlock_and_exit;
625 }
626
627 /* Install the handler */
628
629 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
630 gpe_event_info->dispatch.handler = handler;
631
632 /* Setup up dispatch flags to indicate handler (vs. method) */
633
634 gpe_event_info->flags &= ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK); /* Clear bits */
635 gpe_event_info->flags |= (u8) (type | ACPI_GPE_DISPATCH_HANDLER);
636
637 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
638
639 unlock_and_exit:
640 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
641 exit:
642 if (ACPI_FAILURE(status))
643 ACPI_EXCEPTION((AE_INFO, status,
644 "Installing notify handler failed"));
645 return_ACPI_STATUS(status);
646}
647
648ACPI_EXPORT_SYMBOL(acpi_install_gpe_handler)
649
650/*******************************************************************************
651 *
652 * FUNCTION: acpi_remove_gpe_handler
653 *
654 * PARAMETERS: gpe_device - Namespace node for the GPE (NULL for FADT
655 * defined GPEs)
656 * gpe_number - The event to remove a handler
657 * Address - Address of the handler
658 *
659 * RETURN: Status
660 *
661 * DESCRIPTION: Remove a handler for a General Purpose acpi_event.
662 *
663 ******************************************************************************/
664acpi_status
665acpi_remove_gpe_handler(acpi_handle gpe_device,
666 u32 gpe_number, acpi_event_handler address)
667{
668 struct acpi_gpe_event_info *gpe_event_info;
669 struct acpi_handler_info *handler;
670 acpi_status status;
671 acpi_cpu_flags flags;
672
673 ACPI_FUNCTION_TRACE(acpi_remove_gpe_handler);
674
675 /* Parameter validation */
676
677 if (!address) {
678 return_ACPI_STATUS(AE_BAD_PARAMETER);
679 }
680
681 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
682 if (ACPI_FAILURE(status)) {
683 return_ACPI_STATUS(status);
684 }
685
686 /* Ensure that we have a valid GPE number */
687
688 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
689 if (!gpe_event_info) {
690 status = AE_BAD_PARAMETER;
691 goto unlock_and_exit;
692 }
693
694 /* Make sure that a handler is indeed installed */
695
696 if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) !=
697 ACPI_GPE_DISPATCH_HANDLER) {
698 status = AE_NOT_EXIST;
699 goto unlock_and_exit;
700 }
701
702 /* Make sure that the installed handler is the same */
703
704 if (gpe_event_info->dispatch.handler->address != address) {
705 status = AE_BAD_PARAMETER;
706 goto unlock_and_exit;
707 }
708
709 /* Disable the GPE before removing the handler */
710
711 status = acpi_ev_disable_gpe(gpe_event_info);
712 if (ACPI_FAILURE(status)) {
713 goto unlock_and_exit;
714 }
715
716 /* Make sure all deferred tasks are completed */
717
718 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
719 acpi_os_wait_events_complete(NULL);
720 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
721 if (ACPI_FAILURE(status)) {
722 return_ACPI_STATUS(status);
723 }
724
725 /* Remove the handler */
726
727 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
728 handler = gpe_event_info->dispatch.handler;
729
730 /* Restore Method node (if any), set dispatch flags */
731
732 gpe_event_info->dispatch.method_node = handler->method_node;
733 gpe_event_info->flags &= ~ACPI_GPE_DISPATCH_MASK; /* Clear bits */
734 if (handler->method_node) {
735 gpe_event_info->flags |= ACPI_GPE_DISPATCH_METHOD;
736 }
737 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
738
739 /* Now we can free the handler object */
740
741 ACPI_FREE(handler);
742
743 unlock_and_exit:
744 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
745 return_ACPI_STATUS(status);
746}
747
748ACPI_EXPORT_SYMBOL(acpi_remove_gpe_handler)
749
750/*******************************************************************************
751 *
752 * FUNCTION: acpi_acquire_global_lock
753 *
754 * PARAMETERS: Timeout - How long the caller is willing to wait
755 * Handle - Where the handle to the lock is returned
756 * (if acquired)
757 *
758 * RETURN: Status
759 *
760 * DESCRIPTION: Acquire the ACPI Global Lock
761 *
762 * Note: Allows callers with the same thread ID to acquire the global lock
763 * multiple times. In other words, externally, the behavior of the global lock
764 * is identical to an AML mutex. On the first acquire, a new handle is
765 * returned. On any subsequent calls to acquire by the same thread, the same
766 * handle is returned.
767 *
768 ******************************************************************************/
769acpi_status acpi_acquire_global_lock(u16 timeout, u32 * handle)
770{
771 acpi_status status;
772
773 if (!handle) {
774 return (AE_BAD_PARAMETER);
775 }
776
777 /* Must lock interpreter to prevent race conditions */
778
779 acpi_ex_enter_interpreter();
780
781 status = acpi_ex_acquire_mutex_object(timeout,
782 acpi_gbl_global_lock_mutex,
783 acpi_os_get_thread_id());
784
785 if (ACPI_SUCCESS(status)) {
786
787 /* Return the global lock handle (updated in acpi_ev_acquire_global_lock) */
788
789 *handle = acpi_gbl_global_lock_handle;
790 }
791
792 acpi_ex_exit_interpreter();
793 return (status);
794}
795
796ACPI_EXPORT_SYMBOL(acpi_acquire_global_lock)
797
798/*******************************************************************************
799 *
800 * FUNCTION: acpi_release_global_lock
801 *
802 * PARAMETERS: Handle - Returned from acpi_acquire_global_lock
803 *
804 * RETURN: Status
805 *
806 * DESCRIPTION: Release the ACPI Global Lock. The handle must be valid.
807 *
808 ******************************************************************************/
809acpi_status acpi_release_global_lock(u32 handle)
810{
811 acpi_status status;
812
813 if (!handle || (handle != acpi_gbl_global_lock_handle)) {
814 return (AE_NOT_ACQUIRED);
815 }
816
817 status = acpi_ex_release_mutex_object(acpi_gbl_global_lock_mutex);
818 return (status);
819}
820
821ACPI_EXPORT_SYMBOL(acpi_release_global_lock)
diff --git a/drivers/acpi/acpica/evxfevnt.c b/drivers/acpi/acpica/evxfevnt.c
new file mode 100644
index 00000000000..f33cc30cb6b
--- /dev/null
+++ b/drivers/acpi/acpica/evxfevnt.c
@@ -0,0 +1,871 @@
1/******************************************************************************
2 *
3 * Module Name: evxfevnt - External Interfaces, ACPI event disable/enable
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46#include <acpi/acevents.h>
47#include <acpi/acnamesp.h>
48#include <acpi/actables.h>
49
50#define _COMPONENT ACPI_EVENTS
51ACPI_MODULE_NAME("evxfevnt")
52
53/* Local prototypes */
54acpi_status
55acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
56 struct acpi_gpe_block_info *gpe_block, void *context);
57
58/*******************************************************************************
59 *
60 * FUNCTION: acpi_enable
61 *
62 * PARAMETERS: None
63 *
64 * RETURN: Status
65 *
66 * DESCRIPTION: Transfers the system into ACPI mode.
67 *
68 ******************************************************************************/
69
70acpi_status acpi_enable(void)
71{
72 acpi_status status = AE_OK;
73
74 ACPI_FUNCTION_TRACE(acpi_enable);
75
76 /* ACPI tables must be present */
77
78 if (!acpi_tb_tables_loaded()) {
79 return_ACPI_STATUS(AE_NO_ACPI_TABLES);
80 }
81
82 /* Check current mode */
83
84 if (acpi_hw_get_mode() == ACPI_SYS_MODE_ACPI) {
85 ACPI_DEBUG_PRINT((ACPI_DB_INIT,
86 "System is already in ACPI mode\n"));
87 } else {
88 /* Transition to ACPI mode */
89
90 status = acpi_hw_set_mode(ACPI_SYS_MODE_ACPI);
91 if (ACPI_FAILURE(status)) {
92 ACPI_ERROR((AE_INFO,
93 "Could not transition to ACPI mode"));
94 return_ACPI_STATUS(status);
95 }
96
97 ACPI_DEBUG_PRINT((ACPI_DB_INIT,
98 "Transition to ACPI mode successful\n"));
99 }
100
101 return_ACPI_STATUS(status);
102}
103
104ACPI_EXPORT_SYMBOL(acpi_enable)
105
106/*******************************************************************************
107 *
108 * FUNCTION: acpi_disable
109 *
110 * PARAMETERS: None
111 *
112 * RETURN: Status
113 *
114 * DESCRIPTION: Transfers the system into LEGACY (non-ACPI) mode.
115 *
116 ******************************************************************************/
117acpi_status acpi_disable(void)
118{
119 acpi_status status = AE_OK;
120
121 ACPI_FUNCTION_TRACE(acpi_disable);
122
123 if (acpi_hw_get_mode() == ACPI_SYS_MODE_LEGACY) {
124 ACPI_DEBUG_PRINT((ACPI_DB_INIT,
125 "System is already in legacy (non-ACPI) mode\n"));
126 } else {
127 /* Transition to LEGACY mode */
128
129 status = acpi_hw_set_mode(ACPI_SYS_MODE_LEGACY);
130
131 if (ACPI_FAILURE(status)) {
132 ACPI_ERROR((AE_INFO,
133 "Could not exit ACPI mode to legacy mode"));
134 return_ACPI_STATUS(status);
135 }
136
137 ACPI_DEBUG_PRINT((ACPI_DB_INIT, "ACPI mode disabled\n"));
138 }
139
140 return_ACPI_STATUS(status);
141}
142
143ACPI_EXPORT_SYMBOL(acpi_disable)
144
145/*******************************************************************************
146 *
147 * FUNCTION: acpi_enable_event
148 *
149 * PARAMETERS: Event - The fixed eventto be enabled
150 * Flags - Reserved
151 *
152 * RETURN: Status
153 *
154 * DESCRIPTION: Enable an ACPI event (fixed)
155 *
156 ******************************************************************************/
157acpi_status acpi_enable_event(u32 event, u32 flags)
158{
159 acpi_status status = AE_OK;
160 u32 value;
161
162 ACPI_FUNCTION_TRACE(acpi_enable_event);
163
164 /* Decode the Fixed Event */
165
166 if (event > ACPI_EVENT_MAX) {
167 return_ACPI_STATUS(AE_BAD_PARAMETER);
168 }
169
170 /*
171 * Enable the requested fixed event (by writing a one to the enable
172 * register bit)
173 */
174 status =
175 acpi_set_register(acpi_gbl_fixed_event_info[event].
176 enable_register_id, 1);
177 if (ACPI_FAILURE(status)) {
178 return_ACPI_STATUS(status);
179 }
180
181 /* Make sure that the hardware responded */
182
183 status =
184 acpi_get_register(acpi_gbl_fixed_event_info[event].
185 enable_register_id, &value);
186 if (ACPI_FAILURE(status)) {
187 return_ACPI_STATUS(status);
188 }
189
190 if (value != 1) {
191 ACPI_ERROR((AE_INFO,
192 "Could not enable %s event",
193 acpi_ut_get_event_name(event)));
194 return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE);
195 }
196
197 return_ACPI_STATUS(status);
198}
199
200ACPI_EXPORT_SYMBOL(acpi_enable_event)
201
202/*******************************************************************************
203 *
204 * FUNCTION: acpi_set_gpe_type
205 *
206 * PARAMETERS: gpe_device - Parent GPE Device
207 * gpe_number - GPE level within the GPE block
208 * Type - New GPE type
209 *
210 * RETURN: Status
211 *
212 * DESCRIPTION: Set the type of an individual GPE
213 *
214 ******************************************************************************/
215acpi_status acpi_set_gpe_type(acpi_handle gpe_device, u32 gpe_number, u8 type)
216{
217 acpi_status status = AE_OK;
218 struct acpi_gpe_event_info *gpe_event_info;
219
220 ACPI_FUNCTION_TRACE(acpi_set_gpe_type);
221
222 /* Ensure that we have a valid GPE number */
223
224 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
225 if (!gpe_event_info) {
226 status = AE_BAD_PARAMETER;
227 goto unlock_and_exit;
228 }
229
230 if ((gpe_event_info->flags & ACPI_GPE_TYPE_MASK) == type) {
231 return_ACPI_STATUS(AE_OK);
232 }
233
234 /* Set the new type (will disable GPE if currently enabled) */
235
236 status = acpi_ev_set_gpe_type(gpe_event_info, type);
237
238 unlock_and_exit:
239 return_ACPI_STATUS(status);
240}
241
242ACPI_EXPORT_SYMBOL(acpi_set_gpe_type)
243
244/*******************************************************************************
245 *
246 * FUNCTION: acpi_enable_gpe
247 *
248 * PARAMETERS: gpe_device - Parent GPE Device
249 * gpe_number - GPE level within the GPE block
250 * Flags - Just enable, or also wake enable?
251 * Called from ISR or not
252 *
253 * RETURN: Status
254 *
255 * DESCRIPTION: Enable an ACPI event (general purpose)
256 *
257 ******************************************************************************/
258acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number)
259{
260 acpi_status status = AE_OK;
261 acpi_cpu_flags flags;
262 struct acpi_gpe_event_info *gpe_event_info;
263
264 ACPI_FUNCTION_TRACE(acpi_enable_gpe);
265
266 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
267
268 /* Ensure that we have a valid GPE number */
269
270 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
271 if (!gpe_event_info) {
272 status = AE_BAD_PARAMETER;
273 goto unlock_and_exit;
274 }
275
276 /* Perform the enable */
277
278 status = acpi_ev_enable_gpe(gpe_event_info, TRUE);
279
280 unlock_and_exit:
281 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
282 return_ACPI_STATUS(status);
283}
284
285ACPI_EXPORT_SYMBOL(acpi_enable_gpe)
286
287/*******************************************************************************
288 *
289 * FUNCTION: acpi_disable_gpe
290 *
291 * PARAMETERS: gpe_device - Parent GPE Device
292 * gpe_number - GPE level within the GPE block
293 * Flags - Just disable, or also wake disable?
294 * Called from ISR or not
295 *
296 * RETURN: Status
297 *
298 * DESCRIPTION: Disable an ACPI event (general purpose)
299 *
300 ******************************************************************************/
301acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number)
302{
303 acpi_status status = AE_OK;
304 acpi_cpu_flags flags;
305 struct acpi_gpe_event_info *gpe_event_info;
306
307 ACPI_FUNCTION_TRACE(acpi_disable_gpe);
308
309 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
310 /* Ensure that we have a valid GPE number */
311
312 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
313 if (!gpe_event_info) {
314 status = AE_BAD_PARAMETER;
315 goto unlock_and_exit;
316 }
317
318 status = acpi_ev_disable_gpe(gpe_event_info);
319
320unlock_and_exit:
321 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
322 return_ACPI_STATUS(status);
323}
324
325ACPI_EXPORT_SYMBOL(acpi_disable_gpe)
326
327/*******************************************************************************
328 *
329 * FUNCTION: acpi_disable_event
330 *
331 * PARAMETERS: Event - The fixed eventto be enabled
332 * Flags - Reserved
333 *
334 * RETURN: Status
335 *
336 * DESCRIPTION: Disable an ACPI event (fixed)
337 *
338 ******************************************************************************/
339acpi_status acpi_disable_event(u32 event, u32 flags)
340{
341 acpi_status status = AE_OK;
342 u32 value;
343
344 ACPI_FUNCTION_TRACE(acpi_disable_event);
345
346 /* Decode the Fixed Event */
347
348 if (event > ACPI_EVENT_MAX) {
349 return_ACPI_STATUS(AE_BAD_PARAMETER);
350 }
351
352 /*
353 * Disable the requested fixed event (by writing a zero to the enable
354 * register bit)
355 */
356 status =
357 acpi_set_register(acpi_gbl_fixed_event_info[event].
358 enable_register_id, 0);
359 if (ACPI_FAILURE(status)) {
360 return_ACPI_STATUS(status);
361 }
362
363 status =
364 acpi_get_register(acpi_gbl_fixed_event_info[event].
365 enable_register_id, &value);
366 if (ACPI_FAILURE(status)) {
367 return_ACPI_STATUS(status);
368 }
369
370 if (value != 0) {
371 ACPI_ERROR((AE_INFO,
372 "Could not disable %s events",
373 acpi_ut_get_event_name(event)));
374 return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE);
375 }
376
377 return_ACPI_STATUS(status);
378}
379
380ACPI_EXPORT_SYMBOL(acpi_disable_event)
381
382/*******************************************************************************
383 *
384 * FUNCTION: acpi_clear_event
385 *
386 * PARAMETERS: Event - The fixed event to be cleared
387 *
388 * RETURN: Status
389 *
390 * DESCRIPTION: Clear an ACPI event (fixed)
391 *
392 ******************************************************************************/
393acpi_status acpi_clear_event(u32 event)
394{
395 acpi_status status = AE_OK;
396
397 ACPI_FUNCTION_TRACE(acpi_clear_event);
398
399 /* Decode the Fixed Event */
400
401 if (event > ACPI_EVENT_MAX) {
402 return_ACPI_STATUS(AE_BAD_PARAMETER);
403 }
404
405 /*
406 * Clear the requested fixed event (By writing a one to the status
407 * register bit)
408 */
409 status =
410 acpi_set_register(acpi_gbl_fixed_event_info[event].
411 status_register_id, 1);
412
413 return_ACPI_STATUS(status);
414}
415
416ACPI_EXPORT_SYMBOL(acpi_clear_event)
417
418/*******************************************************************************
419 *
420 * FUNCTION: acpi_clear_gpe
421 *
422 * PARAMETERS: gpe_device - Parent GPE Device
423 * gpe_number - GPE level within the GPE block
424 * Flags - Called from an ISR or not
425 *
426 * RETURN: Status
427 *
428 * DESCRIPTION: Clear an ACPI event (general purpose)
429 *
430 ******************************************************************************/
431acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags)
432{
433 acpi_status status = AE_OK;
434 struct acpi_gpe_event_info *gpe_event_info;
435
436 ACPI_FUNCTION_TRACE(acpi_clear_gpe);
437
438 /* Use semaphore lock if not executing at interrupt level */
439
440 if (flags & ACPI_NOT_ISR) {
441 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
442 if (ACPI_FAILURE(status)) {
443 return_ACPI_STATUS(status);
444 }
445 }
446
447 /* Ensure that we have a valid GPE number */
448
449 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
450 if (!gpe_event_info) {
451 status = AE_BAD_PARAMETER;
452 goto unlock_and_exit;
453 }
454
455 status = acpi_hw_clear_gpe(gpe_event_info);
456
457 unlock_and_exit:
458 if (flags & ACPI_NOT_ISR) {
459 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
460 }
461 return_ACPI_STATUS(status);
462}
463
464ACPI_EXPORT_SYMBOL(acpi_clear_gpe)
465/*******************************************************************************
466 *
467 * FUNCTION: acpi_get_event_status
468 *
469 * PARAMETERS: Event - The fixed event
470 * event_status - Where the current status of the event will
471 * be returned
472 *
473 * RETURN: Status
474 *
475 * DESCRIPTION: Obtains and returns the current status of the event
476 *
477 ******************************************************************************/
478acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status)
479{
480 acpi_status status = AE_OK;
481 u32 value;
482
483 ACPI_FUNCTION_TRACE(acpi_get_event_status);
484
485 if (!event_status) {
486 return_ACPI_STATUS(AE_BAD_PARAMETER);
487 }
488
489 /* Decode the Fixed Event */
490
491 if (event > ACPI_EVENT_MAX) {
492 return_ACPI_STATUS(AE_BAD_PARAMETER);
493 }
494
495 /* Get the status of the requested fixed event */
496
497 status =
498 acpi_get_register(acpi_gbl_fixed_event_info[event].
499 enable_register_id, &value);
500 if (ACPI_FAILURE(status))
501 return_ACPI_STATUS(status);
502
503 *event_status = value;
504
505 status =
506 acpi_get_register(acpi_gbl_fixed_event_info[event].
507 status_register_id, &value);
508 if (ACPI_FAILURE(status))
509 return_ACPI_STATUS(status);
510
511 if (value)
512 *event_status |= ACPI_EVENT_FLAG_SET;
513
514 if (acpi_gbl_fixed_event_handlers[event].handler)
515 *event_status |= ACPI_EVENT_FLAG_HANDLE;
516
517 return_ACPI_STATUS(status);
518}
519
520ACPI_EXPORT_SYMBOL(acpi_get_event_status)
521
522/*******************************************************************************
523 *
524 * FUNCTION: acpi_get_gpe_status
525 *
526 * PARAMETERS: gpe_device - Parent GPE Device
527 * gpe_number - GPE level within the GPE block
528 * Flags - Called from an ISR or not
529 * event_status - Where the current status of the event will
530 * be returned
531 *
532 * RETURN: Status
533 *
534 * DESCRIPTION: Get status of an event (general purpose)
535 *
536 ******************************************************************************/
537acpi_status
538acpi_get_gpe_status(acpi_handle gpe_device,
539 u32 gpe_number, u32 flags, acpi_event_status * event_status)
540{
541 acpi_status status = AE_OK;
542 struct acpi_gpe_event_info *gpe_event_info;
543
544 ACPI_FUNCTION_TRACE(acpi_get_gpe_status);
545
546 /* Use semaphore lock if not executing at interrupt level */
547
548 if (flags & ACPI_NOT_ISR) {
549 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
550 if (ACPI_FAILURE(status)) {
551 return_ACPI_STATUS(status);
552 }
553 }
554
555 /* Ensure that we have a valid GPE number */
556
557 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
558 if (!gpe_event_info) {
559 status = AE_BAD_PARAMETER;
560 goto unlock_and_exit;
561 }
562
563 /* Obtain status on the requested GPE number */
564
565 status = acpi_hw_get_gpe_status(gpe_event_info, event_status);
566
567 if (gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK)
568 *event_status |= ACPI_EVENT_FLAG_HANDLE;
569
570 unlock_and_exit:
571 if (flags & ACPI_NOT_ISR) {
572 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
573 }
574 return_ACPI_STATUS(status);
575}
576
577ACPI_EXPORT_SYMBOL(acpi_get_gpe_status)
578/*******************************************************************************
579 *
580 * FUNCTION: acpi_install_gpe_block
581 *
582 * PARAMETERS: gpe_device - Handle to the parent GPE Block Device
583 * gpe_block_address - Address and space_iD
584 * register_count - Number of GPE register pairs in the block
585 * interrupt_number - H/W interrupt for the block
586 *
587 * RETURN: Status
588 *
589 * DESCRIPTION: Create and Install a block of GPE registers
590 *
591 ******************************************************************************/
592acpi_status
593acpi_install_gpe_block(acpi_handle gpe_device,
594 struct acpi_generic_address *gpe_block_address,
595 u32 register_count, u32 interrupt_number)
596{
597 acpi_status status;
598 union acpi_operand_object *obj_desc;
599 struct acpi_namespace_node *node;
600 struct acpi_gpe_block_info *gpe_block;
601
602 ACPI_FUNCTION_TRACE(acpi_install_gpe_block);
603
604 if ((!gpe_device) || (!gpe_block_address) || (!register_count)) {
605 return_ACPI_STATUS(AE_BAD_PARAMETER);
606 }
607
608 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
609 if (ACPI_FAILURE(status)) {
610 return (status);
611 }
612
613 node = acpi_ns_map_handle_to_node(gpe_device);
614 if (!node) {
615 status = AE_BAD_PARAMETER;
616 goto unlock_and_exit;
617 }
618
619 /*
620 * For user-installed GPE Block Devices, the gpe_block_base_number
621 * is always zero
622 */
623 status =
624 acpi_ev_create_gpe_block(node, gpe_block_address, register_count, 0,
625 interrupt_number, &gpe_block);
626 if (ACPI_FAILURE(status)) {
627 goto unlock_and_exit;
628 }
629
630 /* Run the _PRW methods and enable the GPEs */
631
632 status = acpi_ev_initialize_gpe_block(node, gpe_block);
633 if (ACPI_FAILURE(status)) {
634 goto unlock_and_exit;
635 }
636
637 /* Get the device_object attached to the node */
638
639 obj_desc = acpi_ns_get_attached_object(node);
640 if (!obj_desc) {
641
642 /* No object, create a new one */
643
644 obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_DEVICE);
645 if (!obj_desc) {
646 status = AE_NO_MEMORY;
647 goto unlock_and_exit;
648 }
649
650 status =
651 acpi_ns_attach_object(node, obj_desc, ACPI_TYPE_DEVICE);
652
653 /* Remove local reference to the object */
654
655 acpi_ut_remove_reference(obj_desc);
656
657 if (ACPI_FAILURE(status)) {
658 goto unlock_and_exit;
659 }
660 }
661
662 /* Install the GPE block in the device_object */
663
664 obj_desc->device.gpe_block = gpe_block;
665
666 unlock_and_exit:
667 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
668 return_ACPI_STATUS(status);
669}
670
671ACPI_EXPORT_SYMBOL(acpi_install_gpe_block)
672
673/*******************************************************************************
674 *
675 * FUNCTION: acpi_remove_gpe_block
676 *
677 * PARAMETERS: gpe_device - Handle to the parent GPE Block Device
678 *
679 * RETURN: Status
680 *
681 * DESCRIPTION: Remove a previously installed block of GPE registers
682 *
683 ******************************************************************************/
684acpi_status acpi_remove_gpe_block(acpi_handle gpe_device)
685{
686 union acpi_operand_object *obj_desc;
687 acpi_status status;
688 struct acpi_namespace_node *node;
689
690 ACPI_FUNCTION_TRACE(acpi_remove_gpe_block);
691
692 if (!gpe_device) {
693 return_ACPI_STATUS(AE_BAD_PARAMETER);
694 }
695
696 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
697 if (ACPI_FAILURE(status)) {
698 return (status);
699 }
700
701 node = acpi_ns_map_handle_to_node(gpe_device);
702 if (!node) {
703 status = AE_BAD_PARAMETER;
704 goto unlock_and_exit;
705 }
706
707 /* Get the device_object attached to the node */
708
709 obj_desc = acpi_ns_get_attached_object(node);
710 if (!obj_desc || !obj_desc->device.gpe_block) {
711 return_ACPI_STATUS(AE_NULL_OBJECT);
712 }
713
714 /* Delete the GPE block (but not the device_object) */
715
716 status = acpi_ev_delete_gpe_block(obj_desc->device.gpe_block);
717 if (ACPI_SUCCESS(status)) {
718 obj_desc->device.gpe_block = NULL;
719 }
720
721 unlock_and_exit:
722 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
723 return_ACPI_STATUS(status);
724}
725
726ACPI_EXPORT_SYMBOL(acpi_remove_gpe_block)
727
728/*******************************************************************************
729 *
730 * FUNCTION: acpi_get_gpe_device
731 *
732 * PARAMETERS: Index - System GPE index (0-current_gpe_count)
733 * gpe_device - Where the parent GPE Device is returned
734 *
735 * RETURN: Status
736 *
737 * DESCRIPTION: Obtain the GPE device associated with the input index. A NULL
738 * gpe device indicates that the gpe number is contained in one of
739 * the FADT-defined gpe blocks. Otherwise, the GPE block device.
740 *
741 ******************************************************************************/
742acpi_status
743acpi_get_gpe_device(u32 index, acpi_handle *gpe_device)
744{
745 struct acpi_gpe_device_info info;
746 acpi_status status;
747
748 ACPI_FUNCTION_TRACE(acpi_get_gpe_device);
749
750 if (!gpe_device) {
751 return_ACPI_STATUS(AE_BAD_PARAMETER);
752 }
753
754 if (index >= acpi_current_gpe_count) {
755 return_ACPI_STATUS(AE_NOT_EXIST);
756 }
757
758 /* Setup and walk the GPE list */
759
760 info.index = index;
761 info.status = AE_NOT_EXIST;
762 info.gpe_device = NULL;
763 info.next_block_base_index = 0;
764
765 status = acpi_ev_walk_gpe_list(acpi_ev_get_gpe_device, &info);
766 if (ACPI_FAILURE(status)) {
767 return_ACPI_STATUS(status);
768 }
769
770 *gpe_device = info.gpe_device;
771 return_ACPI_STATUS(info.status);
772}
773
774ACPI_EXPORT_SYMBOL(acpi_get_gpe_device)
775
776/*******************************************************************************
777 *
778 * FUNCTION: acpi_ev_get_gpe_device
779 *
780 * PARAMETERS: GPE_WALK_CALLBACK
781 *
782 * RETURN: Status
783 *
784 * DESCRIPTION: Matches the input GPE index (0-current_gpe_count) with a GPE
785 * block device. NULL if the GPE is one of the FADT-defined GPEs.
786 *
787 ******************************************************************************/
788acpi_status
789acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
790 struct acpi_gpe_block_info *gpe_block, void *context)
791{
792 struct acpi_gpe_device_info *info = context;
793
794 /* Increment Index by the number of GPEs in this block */
795
796 info->next_block_base_index +=
797 (gpe_block->register_count * ACPI_GPE_REGISTER_WIDTH);
798
799 if (info->index < info->next_block_base_index) {
800 /*
801 * The GPE index is within this block, get the node. Leave the node
802 * NULL for the FADT-defined GPEs
803 */
804 if ((gpe_block->node)->type == ACPI_TYPE_DEVICE) {
805 info->gpe_device = gpe_block->node;
806 }
807
808 info->status = AE_OK;
809 return (AE_CTRL_END);
810 }
811
812 return (AE_OK);
813}
814
815/******************************************************************************
816 *
817 * FUNCTION: acpi_disable_all_gpes
818 *
819 * PARAMETERS: None
820 *
821 * RETURN: Status
822 *
823 * DESCRIPTION: Disable and clear all GPEs in all GPE blocks
824 *
825 ******************************************************************************/
826
827acpi_status acpi_disable_all_gpes(void)
828{
829 acpi_status status;
830
831 ACPI_FUNCTION_TRACE(acpi_disable_all_gpes);
832
833 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
834 if (ACPI_FAILURE(status)) {
835 return_ACPI_STATUS(status);
836 }
837
838 status = acpi_hw_disable_all_gpes();
839 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
840
841 return_ACPI_STATUS(status);
842}
843
844/******************************************************************************
845 *
846 * FUNCTION: acpi_enable_all_runtime_gpes
847 *
848 * PARAMETERS: None
849 *
850 * RETURN: Status
851 *
852 * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks
853 *
854 ******************************************************************************/
855
856acpi_status acpi_enable_all_runtime_gpes(void)
857{
858 acpi_status status;
859
860 ACPI_FUNCTION_TRACE(acpi_enable_all_runtime_gpes);
861
862 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
863 if (ACPI_FAILURE(status)) {
864 return_ACPI_STATUS(status);
865 }
866
867 status = acpi_hw_enable_all_runtime_gpes();
868 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
869
870 return_ACPI_STATUS(status);
871}
diff --git a/drivers/acpi/acpica/evxfregn.c b/drivers/acpi/acpica/evxfregn.c
new file mode 100644
index 00000000000..b8633947391
--- /dev/null
+++ b/drivers/acpi/acpica/evxfregn.c
@@ -0,0 +1,254 @@
1/******************************************************************************
2 *
3 * Module Name: evxfregn - External Interfaces, ACPI Operation Regions and
4 * Address Spaces.
5 *
6 *****************************************************************************/
7
8/*
9 * Copyright (C) 2000 - 2008, Intel Corp.
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions, and the following disclaimer,
17 * without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 * substantially similar to the "NO WARRANTY" disclaimer below
20 * ("Disclaimer") and any redistribution must be conditioned upon
21 * including a substantially similar Disclaimer requirement for further
22 * binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 * of any contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
30 *
31 * NO WARRANTY
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
43 */
44
45#include <acpi/acpi.h>
46#include <acpi/accommon.h>
47#include <acpi/acnamesp.h>
48#include <acpi/acevents.h>
49
50#define _COMPONENT ACPI_EVENTS
51ACPI_MODULE_NAME("evxfregn")
52
53/*******************************************************************************
54 *
55 * FUNCTION: acpi_install_address_space_handler
56 *
57 * PARAMETERS: Device - Handle for the device
58 * space_id - The address space ID
59 * Handler - Address of the handler
60 * Setup - Address of the setup function
61 * Context - Value passed to the handler on each access
62 *
63 * RETURN: Status
64 *
65 * DESCRIPTION: Install a handler for all op_regions of a given space_id.
66 *
67 ******************************************************************************/
68acpi_status
69acpi_install_address_space_handler(acpi_handle device,
70 acpi_adr_space_type space_id,
71 acpi_adr_space_handler handler,
72 acpi_adr_space_setup setup, void *context)
73{
74 struct acpi_namespace_node *node;
75 acpi_status status;
76
77 ACPI_FUNCTION_TRACE(acpi_install_address_space_handler);
78
79 /* Parameter validation */
80
81 if (!device) {
82 return_ACPI_STATUS(AE_BAD_PARAMETER);
83 }
84
85 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
86 if (ACPI_FAILURE(status)) {
87 return_ACPI_STATUS(status);
88 }
89
90 /* Convert and validate the device handle */
91
92 node = acpi_ns_map_handle_to_node(device);
93 if (!node) {
94 status = AE_BAD_PARAMETER;
95 goto unlock_and_exit;
96 }
97
98 /* Install the handler for all Regions for this Space ID */
99
100 status =
101 acpi_ev_install_space_handler(node, space_id, handler, setup,
102 context);
103 if (ACPI_FAILURE(status)) {
104 goto unlock_and_exit;
105 }
106
107 /* Run all _REG methods for this address space */
108
109 status = acpi_ev_execute_reg_methods(node, space_id);
110
111 unlock_and_exit:
112 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
113 return_ACPI_STATUS(status);
114}
115
116ACPI_EXPORT_SYMBOL(acpi_install_address_space_handler)
117
118/*******************************************************************************
119 *
120 * FUNCTION: acpi_remove_address_space_handler
121 *
122 * PARAMETERS: Device - Handle for the device
123 * space_id - The address space ID
124 * Handler - Address of the handler
125 *
126 * RETURN: Status
127 *
128 * DESCRIPTION: Remove a previously installed handler.
129 *
130 ******************************************************************************/
131acpi_status
132acpi_remove_address_space_handler(acpi_handle device,
133 acpi_adr_space_type space_id,
134 acpi_adr_space_handler handler)
135{
136 union acpi_operand_object *obj_desc;
137 union acpi_operand_object *handler_obj;
138 union acpi_operand_object *region_obj;
139 union acpi_operand_object **last_obj_ptr;
140 struct acpi_namespace_node *node;
141 acpi_status status;
142
143 ACPI_FUNCTION_TRACE(acpi_remove_address_space_handler);
144
145 /* Parameter validation */
146
147 if (!device) {
148 return_ACPI_STATUS(AE_BAD_PARAMETER);
149 }
150
151 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
152 if (ACPI_FAILURE(status)) {
153 return_ACPI_STATUS(status);
154 }
155
156 /* Convert and validate the device handle */
157
158 node = acpi_ns_map_handle_to_node(device);
159 if (!node ||
160 ((node->type != ACPI_TYPE_DEVICE) &&
161 (node->type != ACPI_TYPE_PROCESSOR) &&
162 (node->type != ACPI_TYPE_THERMAL) &&
163 (node != acpi_gbl_root_node))) {
164 status = AE_BAD_PARAMETER;
165 goto unlock_and_exit;
166 }
167
168 /* Make sure the internal object exists */
169
170 obj_desc = acpi_ns_get_attached_object(node);
171 if (!obj_desc) {
172 status = AE_NOT_EXIST;
173 goto unlock_and_exit;
174 }
175
176 /* Find the address handler the user requested */
177
178 handler_obj = obj_desc->device.handler;
179 last_obj_ptr = &obj_desc->device.handler;
180 while (handler_obj) {
181
182 /* We have a handler, see if user requested this one */
183
184 if (handler_obj->address_space.space_id == space_id) {
185
186 /* Handler must be the same as the installed handler */
187
188 if (handler_obj->address_space.handler != handler) {
189 status = AE_BAD_PARAMETER;
190 goto unlock_and_exit;
191 }
192
193 /* Matched space_id, first dereference this in the Regions */
194
195 ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
196 "Removing address handler %p(%p) for region %s on Device %p(%p)\n",
197 handler_obj, handler,
198 acpi_ut_get_region_name(space_id),
199 node, obj_desc));
200
201 region_obj = handler_obj->address_space.region_list;
202
203 /* Walk the handler's region list */
204
205 while (region_obj) {
206 /*
207 * First disassociate the handler from the region.
208 *
209 * NOTE: this doesn't mean that the region goes away
210 * The region is just inaccessible as indicated to
211 * the _REG method
212 */
213 acpi_ev_detach_region(region_obj, TRUE);
214
215 /*
216 * Walk the list: Just grab the head because the
217 * detach_region removed the previous head.
218 */
219 region_obj =
220 handler_obj->address_space.region_list;
221
222 }
223
224 /* Remove this Handler object from the list */
225
226 *last_obj_ptr = handler_obj->address_space.next;
227
228 /* Now we can delete the handler object */
229
230 acpi_ut_remove_reference(handler_obj);
231 goto unlock_and_exit;
232 }
233
234 /* Walk the linked list of handlers */
235
236 last_obj_ptr = &handler_obj->address_space.next;
237 handler_obj = handler_obj->address_space.next;
238 }
239
240 /* The handler does not exist */
241
242 ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
243 "Unable to remove address handler %p for %s(%X), DevNode %p, obj %p\n",
244 handler, acpi_ut_get_region_name(space_id), space_id,
245 node, obj_desc));
246
247 status = AE_NOT_EXIST;
248
249 unlock_and_exit:
250 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
251 return_ACPI_STATUS(status);
252}
253
254ACPI_EXPORT_SYMBOL(acpi_remove_address_space_handler)
diff --git a/drivers/acpi/acpica/exconfig.c b/drivers/acpi/acpica/exconfig.c
new file mode 100644
index 00000000000..be32d0105fe
--- /dev/null
+++ b/drivers/acpi/acpica/exconfig.c
@@ -0,0 +1,536 @@
1/******************************************************************************
2 *
3 * Module Name: exconfig - Namespace reconfiguration (Load/Unload opcodes)
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46#include <acpi/acinterp.h>
47#include <acpi/acnamesp.h>
48#include <acpi/actables.h>
49#include <acpi/acdispat.h>
50
51#define _COMPONENT ACPI_EXECUTER
52ACPI_MODULE_NAME("exconfig")
53
54/* Local prototypes */
55static acpi_status
56acpi_ex_add_table(u32 table_index,
57 struct acpi_namespace_node *parent_node,
58 union acpi_operand_object **ddb_handle);
59
60/*******************************************************************************
61 *
62 * FUNCTION: acpi_ex_add_table
63 *
64 * PARAMETERS: Table - Pointer to raw table
65 * parent_node - Where to load the table (scope)
66 * ddb_handle - Where to return the table handle.
67 *
68 * RETURN: Status
69 *
70 * DESCRIPTION: Common function to Install and Load an ACPI table with a
71 * returned table handle.
72 *
73 ******************************************************************************/
74
75static acpi_status
76acpi_ex_add_table(u32 table_index,
77 struct acpi_namespace_node *parent_node,
78 union acpi_operand_object **ddb_handle)
79{
80 acpi_status status;
81 union acpi_operand_object *obj_desc;
82
83 ACPI_FUNCTION_TRACE(ex_add_table);
84
85 /* Create an object to be the table handle */
86
87 obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_LOCAL_REFERENCE);
88 if (!obj_desc) {
89 return_ACPI_STATUS(AE_NO_MEMORY);
90 }
91
92 /* Init the table handle */
93
94 obj_desc->reference.class = ACPI_REFCLASS_TABLE;
95 *ddb_handle = obj_desc;
96
97 /* Install the new table into the local data structures */
98
99 obj_desc->reference.value = table_index;
100
101 /* Add the table to the namespace */
102
103 status = acpi_ns_load_table(table_index, parent_node);
104 if (ACPI_FAILURE(status)) {
105 acpi_ut_remove_reference(obj_desc);
106 *ddb_handle = NULL;
107 }
108
109 return_ACPI_STATUS(status);
110}
111
112/*******************************************************************************
113 *
114 * FUNCTION: acpi_ex_load_table_op
115 *
116 * PARAMETERS: walk_state - Current state with operands
117 * return_desc - Where to store the return object
118 *
119 * RETURN: Status
120 *
121 * DESCRIPTION: Load an ACPI table from the RSDT/XSDT
122 *
123 ******************************************************************************/
124
125acpi_status
126acpi_ex_load_table_op(struct acpi_walk_state *walk_state,
127 union acpi_operand_object **return_desc)
128{
129 acpi_status status;
130 union acpi_operand_object **operand = &walk_state->operands[0];
131 struct acpi_namespace_node *parent_node;
132 struct acpi_namespace_node *start_node;
133 struct acpi_namespace_node *parameter_node = NULL;
134 union acpi_operand_object *ddb_handle;
135 struct acpi_table_header *table;
136 u32 table_index;
137
138 ACPI_FUNCTION_TRACE(ex_load_table_op);
139
140 /* Validate lengths for the signature_string, OEMIDString, OEMtable_iD */
141
142 if ((operand[0]->string.length > ACPI_NAME_SIZE) ||
143 (operand[1]->string.length > ACPI_OEM_ID_SIZE) ||
144 (operand[2]->string.length > ACPI_OEM_TABLE_ID_SIZE)) {
145 return_ACPI_STATUS(AE_BAD_PARAMETER);
146 }
147
148 /* Find the ACPI table in the RSDT/XSDT */
149
150 status = acpi_tb_find_table(operand[0]->string.pointer,
151 operand[1]->string.pointer,
152 operand[2]->string.pointer, &table_index);
153 if (ACPI_FAILURE(status)) {
154 if (status != AE_NOT_FOUND) {
155 return_ACPI_STATUS(status);
156 }
157
158 /* Table not found, return an Integer=0 and AE_OK */
159
160 ddb_handle = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
161 if (!ddb_handle) {
162 return_ACPI_STATUS(AE_NO_MEMORY);
163 }
164
165 ddb_handle->integer.value = 0;
166 *return_desc = ddb_handle;
167
168 return_ACPI_STATUS(AE_OK);
169 }
170
171 /* Default nodes */
172
173 start_node = walk_state->scope_info->scope.node;
174 parent_node = acpi_gbl_root_node;
175
176 /* root_path (optional parameter) */
177
178 if (operand[3]->string.length > 0) {
179 /*
180 * Find the node referenced by the root_path_string. This is the
181 * location within the namespace where the table will be loaded.
182 */
183 status =
184 acpi_ns_get_node(start_node, operand[3]->string.pointer,
185 ACPI_NS_SEARCH_PARENT, &parent_node);
186 if (ACPI_FAILURE(status)) {
187 return_ACPI_STATUS(status);
188 }
189 }
190
191 /* parameter_path (optional parameter) */
192
193 if (operand[4]->string.length > 0) {
194 if ((operand[4]->string.pointer[0] != '\\') &&
195 (operand[4]->string.pointer[0] != '^')) {
196 /*
197 * Path is not absolute, so it will be relative to the node
198 * referenced by the root_path_string (or the NS root if omitted)
199 */
200 start_node = parent_node;
201 }
202
203 /* Find the node referenced by the parameter_path_string */
204
205 status =
206 acpi_ns_get_node(start_node, operand[4]->string.pointer,
207 ACPI_NS_SEARCH_PARENT, &parameter_node);
208 if (ACPI_FAILURE(status)) {
209 return_ACPI_STATUS(status);
210 }
211 }
212
213 /* Load the table into the namespace */
214
215 status = acpi_ex_add_table(table_index, parent_node, &ddb_handle);
216 if (ACPI_FAILURE(status)) {
217 return_ACPI_STATUS(status);
218 }
219
220 /* Parameter Data (optional) */
221
222 if (parameter_node) {
223
224 /* Store the parameter data into the optional parameter object */
225
226 status = acpi_ex_store(operand[5],
227 ACPI_CAST_PTR(union acpi_operand_object,
228 parameter_node),
229 walk_state);
230 if (ACPI_FAILURE(status)) {
231 (void)acpi_ex_unload_table(ddb_handle);
232 return_ACPI_STATUS(status);
233 }
234 }
235
236 status = acpi_get_table_by_index(table_index, &table);
237 if (ACPI_SUCCESS(status)) {
238 ACPI_INFO((AE_INFO,
239 "Dynamic OEM Table Load - [%.4s] OemId [%.6s] OemTableId [%.8s]",
240 table->signature, table->oem_id,
241 table->oem_table_id));
242 }
243
244 /* Invoke table handler if present */
245
246 if (acpi_gbl_table_handler) {
247 (void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_LOAD, table,
248 acpi_gbl_table_handler_context);
249 }
250
251 *return_desc = ddb_handle;
252 return_ACPI_STATUS(status);
253}
254
255/*******************************************************************************
256 *
257 * FUNCTION: acpi_ex_load_op
258 *
259 * PARAMETERS: obj_desc - Region or Buffer/Field where the table will be
260 * obtained
261 * Target - Where a handle to the table will be stored
262 * walk_state - Current state
263 *
264 * RETURN: Status
265 *
266 * DESCRIPTION: Load an ACPI table from a field or operation region
267 *
268 * NOTE: Region Fields (Field, bank_field, index_fields) are resolved to buffer
269 * objects before this code is reached.
270 *
271 * If source is an operation region, it must refer to system_memory, as
272 * per the ACPI specification.
273 *
274 ******************************************************************************/
275
276acpi_status
277acpi_ex_load_op(union acpi_operand_object *obj_desc,
278 union acpi_operand_object *target,
279 struct acpi_walk_state *walk_state)
280{
281 union acpi_operand_object *ddb_handle;
282 struct acpi_table_header *table;
283 struct acpi_table_desc table_desc;
284 u32 table_index;
285 acpi_status status;
286 u32 length;
287
288 ACPI_FUNCTION_TRACE(ex_load_op);
289
290 ACPI_MEMSET(&table_desc, 0, sizeof(struct acpi_table_desc));
291
292 /* Source Object can be either an op_region or a Buffer/Field */
293
294 switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
295 case ACPI_TYPE_REGION:
296
297 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
298 "Load table from Region %p\n", obj_desc));
299
300 /* Region must be system_memory (from ACPI spec) */
301
302 if (obj_desc->region.space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) {
303 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
304 }
305
306 /*
307 * If the Region Address and Length have not been previously evaluated,
308 * evaluate them now and save the results.
309 */
310 if (!(obj_desc->common.flags & AOPOBJ_DATA_VALID)) {
311 status = acpi_ds_get_region_arguments(obj_desc);
312 if (ACPI_FAILURE(status)) {
313 return_ACPI_STATUS(status);
314 }
315 }
316
317 /*
318 * Map the table header and get the actual table length. The region
319 * length is not guaranteed to be the same as the table length.
320 */
321 table = acpi_os_map_memory(obj_desc->region.address,
322 sizeof(struct acpi_table_header));
323 if (!table) {
324 return_ACPI_STATUS(AE_NO_MEMORY);
325 }
326
327 length = table->length;
328 acpi_os_unmap_memory(table, sizeof(struct acpi_table_header));
329
330 /* Must have at least an ACPI table header */
331
332 if (length < sizeof(struct acpi_table_header)) {
333 return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH);
334 }
335
336 /*
337 * The memory region is not guaranteed to remain stable and we must
338 * copy the table to a local buffer. For example, the memory region
339 * is corrupted after suspend on some machines. Dynamically loaded
340 * tables are usually small, so this overhead is minimal.
341 */
342
343 /* Allocate a buffer for the table */
344
345 table_desc.pointer = ACPI_ALLOCATE(length);
346 if (!table_desc.pointer) {
347 return_ACPI_STATUS(AE_NO_MEMORY);
348 }
349
350 /* Map the entire table and copy it */
351
352 table = acpi_os_map_memory(obj_desc->region.address, length);
353 if (!table) {
354 ACPI_FREE(table_desc.pointer);
355 return_ACPI_STATUS(AE_NO_MEMORY);
356 }
357
358 ACPI_MEMCPY(table_desc.pointer, table, length);
359 acpi_os_unmap_memory(table, length);
360
361 table_desc.address = obj_desc->region.address;
362 break;
363
364 case ACPI_TYPE_BUFFER: /* Buffer or resolved region_field */
365
366 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
367 "Load table from Buffer or Field %p\n",
368 obj_desc));
369
370 /* Must have at least an ACPI table header */
371
372 if (obj_desc->buffer.length < sizeof(struct acpi_table_header)) {
373 return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH);
374 }
375
376 /* Get the actual table length from the table header */
377
378 table =
379 ACPI_CAST_PTR(struct acpi_table_header,
380 obj_desc->buffer.pointer);
381 length = table->length;
382
383 /* Table cannot extend beyond the buffer */
384
385 if (length > obj_desc->buffer.length) {
386 return_ACPI_STATUS(AE_AML_BUFFER_LIMIT);
387 }
388 if (length < sizeof(struct acpi_table_header)) {
389 return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH);
390 }
391
392 /*
393 * Copy the table from the buffer because the buffer could be modified
394 * or even deleted in the future
395 */
396 table_desc.pointer = ACPI_ALLOCATE(length);
397 if (!table_desc.pointer) {
398 return_ACPI_STATUS(AE_NO_MEMORY);
399 }
400
401 ACPI_MEMCPY(table_desc.pointer, table, length);
402 table_desc.address = ACPI_TO_INTEGER(table_desc.pointer);
403 break;
404
405 default:
406 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
407 }
408
409 /* Validate table checksum (will not get validated in tb_add_table) */
410
411 status = acpi_tb_verify_checksum(table_desc.pointer, length);
412 if (ACPI_FAILURE(status)) {
413 ACPI_FREE(table_desc.pointer);
414 return_ACPI_STATUS(status);
415 }
416
417 /* Complete the table descriptor */
418
419 table_desc.length = length;
420 table_desc.flags = ACPI_TABLE_ORIGIN_ALLOCATED;
421
422 /* Install the new table into the local data structures */
423
424 status = acpi_tb_add_table(&table_desc, &table_index);
425 if (ACPI_FAILURE(status)) {
426 goto cleanup;
427 }
428
429 /*
430 * Add the table to the namespace.
431 *
432 * Note: Load the table objects relative to the root of the namespace.
433 * This appears to go against the ACPI specification, but we do it for
434 * compatibility with other ACPI implementations.
435 */
436 status =
437 acpi_ex_add_table(table_index, acpi_gbl_root_node, &ddb_handle);
438 if (ACPI_FAILURE(status)) {
439
440 /* On error, table_ptr was deallocated above */
441
442 return_ACPI_STATUS(status);
443 }
444
445 /* Store the ddb_handle into the Target operand */
446
447 status = acpi_ex_store(ddb_handle, target, walk_state);
448 if (ACPI_FAILURE(status)) {
449 (void)acpi_ex_unload_table(ddb_handle);
450
451 /* table_ptr was deallocated above */
452
453 acpi_ut_remove_reference(ddb_handle);
454 return_ACPI_STATUS(status);
455 }
456
457 /* Invoke table handler if present */
458
459 if (acpi_gbl_table_handler) {
460 (void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_LOAD,
461 table_desc.pointer,
462 acpi_gbl_table_handler_context);
463 }
464
465 cleanup:
466 if (ACPI_FAILURE(status)) {
467
468 /* Delete allocated table buffer */
469
470 acpi_tb_delete_table(&table_desc);
471 }
472 return_ACPI_STATUS(status);
473}
474
475/*******************************************************************************
476 *
477 * FUNCTION: acpi_ex_unload_table
478 *
479 * PARAMETERS: ddb_handle - Handle to a previously loaded table
480 *
481 * RETURN: Status
482 *
483 * DESCRIPTION: Unload an ACPI table
484 *
485 ******************************************************************************/
486
487acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle)
488{
489 acpi_status status = AE_OK;
490 union acpi_operand_object *table_desc = ddb_handle;
491 u32 table_index;
492 struct acpi_table_header *table;
493
494 ACPI_FUNCTION_TRACE(ex_unload_table);
495
496 /*
497 * Validate the handle
498 * Although the handle is partially validated in acpi_ex_reconfiguration(),
499 * when it calls acpi_ex_resolve_operands(), the handle is more completely
500 * validated here.
501 */
502 if ((!ddb_handle) ||
503 (ACPI_GET_DESCRIPTOR_TYPE(ddb_handle) != ACPI_DESC_TYPE_OPERAND) ||
504 (ACPI_GET_OBJECT_TYPE(ddb_handle) != ACPI_TYPE_LOCAL_REFERENCE)) {
505 return_ACPI_STATUS(AE_BAD_PARAMETER);
506 }
507
508 /* Get the table index from the ddb_handle */
509
510 table_index = table_desc->reference.value;
511
512 /* Invoke table handler if present */
513
514 if (acpi_gbl_table_handler) {
515 status = acpi_get_table_by_index(table_index, &table);
516 if (ACPI_SUCCESS(status)) {
517 (void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_UNLOAD,
518 table,
519 acpi_gbl_table_handler_context);
520 }
521 }
522
523 /*
524 * Delete the entire namespace under this table Node
525 * (Offset contains the table_id)
526 */
527 acpi_tb_delete_namespace_by_owner(table_index);
528 (void)acpi_tb_release_owner_id(table_index);
529
530 acpi_tb_set_table_loaded_flag(table_index, FALSE);
531
532 /* Table unloaded, remove a reference to the ddb_handle object */
533
534 acpi_ut_remove_reference(ddb_handle);
535 return_ACPI_STATUS(AE_OK);
536}
diff --git a/drivers/acpi/acpica/exconvrt.c b/drivers/acpi/acpica/exconvrt.c
new file mode 100644
index 00000000000..caeead439e8
--- /dev/null
+++ b/drivers/acpi/acpica/exconvrt.c
@@ -0,0 +1,692 @@
1/******************************************************************************
2 *
3 * Module Name: exconvrt - Object conversion routines
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46#include <acpi/acinterp.h>
47#include <acpi/amlcode.h>
48
49#define _COMPONENT ACPI_EXECUTER
50ACPI_MODULE_NAME("exconvrt")
51
52/* Local prototypes */
53static u32
54acpi_ex_convert_to_ascii(acpi_integer integer,
55 u16 base, u8 * string, u8 max_length);
56
57/*******************************************************************************
58 *
59 * FUNCTION: acpi_ex_convert_to_integer
60 *
61 * PARAMETERS: obj_desc - Object to be converted. Must be an
62 * Integer, Buffer, or String
63 * result_desc - Where the new Integer object is returned
64 * Flags - Used for string conversion
65 *
66 * RETURN: Status
67 *
68 * DESCRIPTION: Convert an ACPI Object to an integer.
69 *
70 ******************************************************************************/
71
72acpi_status
73acpi_ex_convert_to_integer(union acpi_operand_object *obj_desc,
74 union acpi_operand_object **result_desc, u32 flags)
75{
76 union acpi_operand_object *return_desc;
77 u8 *pointer;
78 acpi_integer result;
79 u32 i;
80 u32 count;
81 acpi_status status;
82
83 ACPI_FUNCTION_TRACE_PTR(ex_convert_to_integer, obj_desc);
84
85 switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
86 case ACPI_TYPE_INTEGER:
87
88 /* No conversion necessary */
89
90 *result_desc = obj_desc;
91 return_ACPI_STATUS(AE_OK);
92
93 case ACPI_TYPE_BUFFER:
94 case ACPI_TYPE_STRING:
95
96 /* Note: Takes advantage of common buffer/string fields */
97
98 pointer = obj_desc->buffer.pointer;
99 count = obj_desc->buffer.length;
100 break;
101
102 default:
103 return_ACPI_STATUS(AE_TYPE);
104 }
105
106 /*
107 * Convert the buffer/string to an integer. Note that both buffers and
108 * strings are treated as raw data - we don't convert ascii to hex for
109 * strings.
110 *
111 * There are two terminating conditions for the loop:
112 * 1) The size of an integer has been reached, or
113 * 2) The end of the buffer or string has been reached
114 */
115 result = 0;
116
117 /* String conversion is different than Buffer conversion */
118
119 switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
120 case ACPI_TYPE_STRING:
121
122 /*
123 * Convert string to an integer - for most cases, the string must be
124 * hexadecimal as per the ACPI specification. The only exception (as
125 * of ACPI 3.0) is that the to_integer() operator allows both decimal
126 * and hexadecimal strings (hex prefixed with "0x").
127 */
128 status = acpi_ut_strtoul64((char *)pointer, flags, &result);
129 if (ACPI_FAILURE(status)) {
130 return_ACPI_STATUS(status);
131 }
132 break;
133
134 case ACPI_TYPE_BUFFER:
135
136 /* Check for zero-length buffer */
137
138 if (!count) {
139 return_ACPI_STATUS(AE_AML_BUFFER_LIMIT);
140 }
141
142 /* Transfer no more than an integer's worth of data */
143
144 if (count > acpi_gbl_integer_byte_width) {
145 count = acpi_gbl_integer_byte_width;
146 }
147
148 /*
149 * Convert buffer to an integer - we simply grab enough raw data
150 * from the buffer to fill an integer
151 */
152 for (i = 0; i < count; i++) {
153 /*
154 * Get next byte and shift it into the Result.
155 * Little endian is used, meaning that the first byte of the buffer
156 * is the LSB of the integer
157 */
158 result |= (((acpi_integer) pointer[i]) << (i * 8));
159 }
160 break;
161
162 default:
163
164 /* No other types can get here */
165 break;
166 }
167
168 /* Create a new integer */
169
170 return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
171 if (!return_desc) {
172 return_ACPI_STATUS(AE_NO_MEMORY);
173 }
174
175 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Converted value: %8.8X%8.8X\n",
176 ACPI_FORMAT_UINT64(result)));
177
178 /* Save the Result */
179
180 return_desc->integer.value = result;
181 acpi_ex_truncate_for32bit_table(return_desc);
182 *result_desc = return_desc;
183 return_ACPI_STATUS(AE_OK);
184}
185
186/*******************************************************************************
187 *
188 * FUNCTION: acpi_ex_convert_to_buffer
189 *
190 * PARAMETERS: obj_desc - Object to be converted. Must be an
191 * Integer, Buffer, or String
192 * result_desc - Where the new buffer object is returned
193 *
194 * RETURN: Status
195 *
196 * DESCRIPTION: Convert an ACPI Object to a Buffer
197 *
198 ******************************************************************************/
199
200acpi_status
201acpi_ex_convert_to_buffer(union acpi_operand_object *obj_desc,
202 union acpi_operand_object **result_desc)
203{
204 union acpi_operand_object *return_desc;
205 u8 *new_buf;
206
207 ACPI_FUNCTION_TRACE_PTR(ex_convert_to_buffer, obj_desc);
208
209 switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
210 case ACPI_TYPE_BUFFER:
211
212 /* No conversion necessary */
213
214 *result_desc = obj_desc;
215 return_ACPI_STATUS(AE_OK);
216
217 case ACPI_TYPE_INTEGER:
218
219 /*
220 * Create a new Buffer object.
221 * Need enough space for one integer
222 */
223 return_desc =
224 acpi_ut_create_buffer_object(acpi_gbl_integer_byte_width);
225 if (!return_desc) {
226 return_ACPI_STATUS(AE_NO_MEMORY);
227 }
228
229 /* Copy the integer to the buffer, LSB first */
230
231 new_buf = return_desc->buffer.pointer;
232 ACPI_MEMCPY(new_buf,
233 &obj_desc->integer.value,
234 acpi_gbl_integer_byte_width);
235 break;
236
237 case ACPI_TYPE_STRING:
238
239 /*
240 * Create a new Buffer object
241 * Size will be the string length
242 *
243 * NOTE: Add one to the string length to include the null terminator.
244 * The ACPI spec is unclear on this subject, but there is existing
245 * ASL/AML code that depends on the null being transferred to the new
246 * buffer.
247 */
248 return_desc = acpi_ut_create_buffer_object((acpi_size)
249 obj_desc->string.
250 length + 1);
251 if (!return_desc) {
252 return_ACPI_STATUS(AE_NO_MEMORY);
253 }
254
255 /* Copy the string to the buffer */
256
257 new_buf = return_desc->buffer.pointer;
258 ACPI_STRNCPY((char *)new_buf, (char *)obj_desc->string.pointer,
259 obj_desc->string.length);
260 break;
261
262 default:
263 return_ACPI_STATUS(AE_TYPE);
264 }
265
266 /* Mark buffer initialized */
267
268 return_desc->common.flags |= AOPOBJ_DATA_VALID;
269 *result_desc = return_desc;
270 return_ACPI_STATUS(AE_OK);
271}
272
273/*******************************************************************************
274 *
275 * FUNCTION: acpi_ex_convert_to_ascii
276 *
277 * PARAMETERS: Integer - Value to be converted
278 * Base - ACPI_STRING_DECIMAL or ACPI_STRING_HEX
279 * String - Where the string is returned
280 * data_width - Size of data item to be converted, in bytes
281 *
282 * RETURN: Actual string length
283 *
284 * DESCRIPTION: Convert an ACPI Integer to a hex or decimal string
285 *
286 ******************************************************************************/
287
288static u32
289acpi_ex_convert_to_ascii(acpi_integer integer,
290 u16 base, u8 * string, u8 data_width)
291{
292 acpi_integer digit;
293 u32 i;
294 u32 j;
295 u32 k = 0;
296 u32 hex_length;
297 u32 decimal_length;
298 u32 remainder;
299 u8 supress_zeros;
300
301 ACPI_FUNCTION_ENTRY();
302
303 switch (base) {
304 case 10:
305
306 /* Setup max length for the decimal number */
307
308 switch (data_width) {
309 case 1:
310 decimal_length = ACPI_MAX8_DECIMAL_DIGITS;
311 break;
312
313 case 4:
314 decimal_length = ACPI_MAX32_DECIMAL_DIGITS;
315 break;
316
317 case 8:
318 default:
319 decimal_length = ACPI_MAX64_DECIMAL_DIGITS;
320 break;
321 }
322
323 supress_zeros = TRUE; /* No leading zeros */
324 remainder = 0;
325
326 for (i = decimal_length; i > 0; i--) {
327
328 /* Divide by nth factor of 10 */
329
330 digit = integer;
331 for (j = 0; j < i; j++) {
332 (void)acpi_ut_short_divide(digit, 10, &digit,
333 &remainder);
334 }
335
336 /* Handle leading zeros */
337
338 if (remainder != 0) {
339 supress_zeros = FALSE;
340 }
341
342 if (!supress_zeros) {
343 string[k] = (u8) (ACPI_ASCII_ZERO + remainder);
344 k++;
345 }
346 }
347 break;
348
349 case 16:
350
351 /* hex_length: 2 ascii hex chars per data byte */
352
353 hex_length = ACPI_MUL_2(data_width);
354 for (i = 0, j = (hex_length - 1); i < hex_length; i++, j--) {
355
356 /* Get one hex digit, most significant digits first */
357
358 string[k] =
359 (u8) acpi_ut_hex_to_ascii_char(integer,
360 ACPI_MUL_4(j));
361 k++;
362 }
363 break;
364
365 default:
366 return (0);
367 }
368
369 /*
370 * Since leading zeros are suppressed, we must check for the case where
371 * the integer equals 0
372 *
373 * Finally, null terminate the string and return the length
374 */
375 if (!k) {
376 string[0] = ACPI_ASCII_ZERO;
377 k = 1;
378 }
379
380 string[k] = 0;
381 return ((u32) k);
382}
383
384/*******************************************************************************
385 *
386 * FUNCTION: acpi_ex_convert_to_string
387 *
388 * PARAMETERS: obj_desc - Object to be converted. Must be an
389 * Integer, Buffer, or String
390 * result_desc - Where the string object is returned
391 * Type - String flags (base and conversion type)
392 *
393 * RETURN: Status
394 *
395 * DESCRIPTION: Convert an ACPI Object to a string
396 *
397 ******************************************************************************/
398
399acpi_status
400acpi_ex_convert_to_string(union acpi_operand_object * obj_desc,
401 union acpi_operand_object ** result_desc, u32 type)
402{
403 union acpi_operand_object *return_desc;
404 u8 *new_buf;
405 u32 i;
406 u32 string_length = 0;
407 u16 base = 16;
408 u8 separator = ',';
409
410 ACPI_FUNCTION_TRACE_PTR(ex_convert_to_string, obj_desc);
411
412 switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
413 case ACPI_TYPE_STRING:
414
415 /* No conversion necessary */
416
417 *result_desc = obj_desc;
418 return_ACPI_STATUS(AE_OK);
419
420 case ACPI_TYPE_INTEGER:
421
422 switch (type) {
423 case ACPI_EXPLICIT_CONVERT_DECIMAL:
424
425 /* Make room for maximum decimal number */
426
427 string_length = ACPI_MAX_DECIMAL_DIGITS;
428 base = 10;
429 break;
430
431 default:
432
433 /* Two hex string characters for each integer byte */
434
435 string_length = ACPI_MUL_2(acpi_gbl_integer_byte_width);
436 break;
437 }
438
439 /*
440 * Create a new String
441 * Need enough space for one ASCII integer (plus null terminator)
442 */
443 return_desc =
444 acpi_ut_create_string_object((acpi_size) string_length);
445 if (!return_desc) {
446 return_ACPI_STATUS(AE_NO_MEMORY);
447 }
448
449 new_buf = return_desc->buffer.pointer;
450
451 /* Convert integer to string */
452
453 string_length =
454 acpi_ex_convert_to_ascii(obj_desc->integer.value, base,
455 new_buf,
456 acpi_gbl_integer_byte_width);
457
458 /* Null terminate at the correct place */
459
460 return_desc->string.length = string_length;
461 new_buf[string_length] = 0;
462 break;
463
464 case ACPI_TYPE_BUFFER:
465
466 /* Setup string length, base, and separator */
467
468 switch (type) {
469 case ACPI_EXPLICIT_CONVERT_DECIMAL: /* Used by to_decimal_string */
470 /*
471 * From ACPI: "If Data is a buffer, it is converted to a string of
472 * decimal values separated by commas."
473 */
474 base = 10;
475
476 /*
477 * Calculate the final string length. Individual string values
478 * are variable length (include separator for each)
479 */
480 for (i = 0; i < obj_desc->buffer.length; i++) {
481 if (obj_desc->buffer.pointer[i] >= 100) {
482 string_length += 4;
483 } else if (obj_desc->buffer.pointer[i] >= 10) {
484 string_length += 3;
485 } else {
486 string_length += 2;
487 }
488 }
489 break;
490
491 case ACPI_IMPLICIT_CONVERT_HEX:
492 /*
493 * From the ACPI spec:
494 *"The entire contents of the buffer are converted to a string of
495 * two-character hexadecimal numbers, each separated by a space."
496 */
497 separator = ' ';
498 string_length = (obj_desc->buffer.length * 3);
499 break;
500
501 case ACPI_EXPLICIT_CONVERT_HEX: /* Used by to_hex_string */
502 /*
503 * From ACPI: "If Data is a buffer, it is converted to a string of
504 * hexadecimal values separated by commas."
505 */
506 string_length = (obj_desc->buffer.length * 3);
507 break;
508
509 default:
510 return_ACPI_STATUS(AE_BAD_PARAMETER);
511 }
512
513 /*
514 * Create a new string object and string buffer
515 * (-1 because of extra separator included in string_length from above)
516 * Allow creation of zero-length strings from zero-length buffers.
517 */
518 if (string_length) {
519 string_length--;
520 }
521
522 return_desc = acpi_ut_create_string_object((acpi_size)
523 string_length);
524 if (!return_desc) {
525 return_ACPI_STATUS(AE_NO_MEMORY);
526 }
527
528 new_buf = return_desc->buffer.pointer;
529
530 /*
531 * Convert buffer bytes to hex or decimal values
532 * (separated by commas or spaces)
533 */
534 for (i = 0; i < obj_desc->buffer.length; i++) {
535 new_buf += acpi_ex_convert_to_ascii((acpi_integer)
536 obj_desc->buffer.
537 pointer[i], base,
538 new_buf, 1);
539 *new_buf++ = separator; /* each separated by a comma or space */
540 }
541
542 /*
543 * Null terminate the string
544 * (overwrites final comma/space from above)
545 */
546 if (obj_desc->buffer.length) {
547 new_buf--;
548 }
549 *new_buf = 0;
550 break;
551
552 default:
553 return_ACPI_STATUS(AE_TYPE);
554 }
555
556 *result_desc = return_desc;
557 return_ACPI_STATUS(AE_OK);
558}
559
560/*******************************************************************************
561 *
562 * FUNCTION: acpi_ex_convert_to_target_type
563 *
564 * PARAMETERS: destination_type - Current type of the destination
565 * source_desc - Source object to be converted.
566 * result_desc - Where the converted object is returned
567 * walk_state - Current method state
568 *
569 * RETURN: Status
570 *
571 * DESCRIPTION: Implements "implicit conversion" rules for storing an object.
572 *
573 ******************************************************************************/
574
575acpi_status
576acpi_ex_convert_to_target_type(acpi_object_type destination_type,
577 union acpi_operand_object *source_desc,
578 union acpi_operand_object **result_desc,
579 struct acpi_walk_state *walk_state)
580{
581 acpi_status status = AE_OK;
582
583 ACPI_FUNCTION_TRACE(ex_convert_to_target_type);
584
585 /* Default behavior */
586
587 *result_desc = source_desc;
588
589 /*
590 * If required by the target,
591 * perform implicit conversion on the source before we store it.
592 */
593 switch (GET_CURRENT_ARG_TYPE(walk_state->op_info->runtime_args)) {
594 case ARGI_SIMPLE_TARGET:
595 case ARGI_FIXED_TARGET:
596 case ARGI_INTEGER_REF: /* Handles Increment, Decrement cases */
597
598 switch (destination_type) {
599 case ACPI_TYPE_LOCAL_REGION_FIELD:
600 /*
601 * Named field can always handle conversions
602 */
603 break;
604
605 default:
606 /* No conversion allowed for these types */
607
608 if (destination_type !=
609 ACPI_GET_OBJECT_TYPE(source_desc)) {
610 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
611 "Explicit operator, will store (%s) over existing type (%s)\n",
612 acpi_ut_get_object_type_name
613 (source_desc),
614 acpi_ut_get_type_name
615 (destination_type)));
616 status = AE_TYPE;
617 }
618 }
619 break;
620
621 case ARGI_TARGETREF:
622
623 switch (destination_type) {
624 case ACPI_TYPE_INTEGER:
625 case ACPI_TYPE_BUFFER_FIELD:
626 case ACPI_TYPE_LOCAL_BANK_FIELD:
627 case ACPI_TYPE_LOCAL_INDEX_FIELD:
628 /*
629 * These types require an Integer operand. We can convert
630 * a Buffer or a String to an Integer if necessary.
631 */
632 status =
633 acpi_ex_convert_to_integer(source_desc, result_desc,
634 16);
635 break;
636
637 case ACPI_TYPE_STRING:
638 /*
639 * The operand must be a String. We can convert an
640 * Integer or Buffer if necessary
641 */
642 status =
643 acpi_ex_convert_to_string(source_desc, result_desc,
644 ACPI_IMPLICIT_CONVERT_HEX);
645 break;
646
647 case ACPI_TYPE_BUFFER:
648 /*
649 * The operand must be a Buffer. We can convert an
650 * Integer or String if necessary
651 */
652 status =
653 acpi_ex_convert_to_buffer(source_desc, result_desc);
654 break;
655
656 default:
657 ACPI_ERROR((AE_INFO,
658 "Bad destination type during conversion: %X",
659 destination_type));
660 status = AE_AML_INTERNAL;
661 break;
662 }
663 break;
664
665 case ARGI_REFERENCE:
666 /*
667 * create_xxxx_field cases - we are storing the field object into the name
668 */
669 break;
670
671 default:
672 ACPI_ERROR((AE_INFO,
673 "Unknown Target type ID 0x%X AmlOpcode %X DestType %s",
674 GET_CURRENT_ARG_TYPE(walk_state->op_info->
675 runtime_args),
676 walk_state->opcode,
677 acpi_ut_get_type_name(destination_type)));
678 status = AE_AML_INTERNAL;
679 }
680
681 /*
682 * Source-to-Target conversion semantics:
683 *
684 * If conversion to the target type cannot be performed, then simply
685 * overwrite the target with the new object and type.
686 */
687 if (status == AE_TYPE) {
688 status = AE_OK;
689 }
690
691 return_ACPI_STATUS(status);
692}
diff --git a/drivers/acpi/acpica/excreate.c b/drivers/acpi/acpica/excreate.c
new file mode 100644
index 00000000000..5aa65a214fc
--- /dev/null
+++ b/drivers/acpi/acpica/excreate.c
@@ -0,0 +1,522 @@
1/******************************************************************************
2 *
3 * Module Name: excreate - Named object creation
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46#include <acpi/acinterp.h>
47#include <acpi/amlcode.h>
48#include <acpi/acnamesp.h>
49
50#define _COMPONENT ACPI_EXECUTER
51ACPI_MODULE_NAME("excreate")
52#ifndef ACPI_NO_METHOD_EXECUTION
53/*******************************************************************************
54 *
55 * FUNCTION: acpi_ex_create_alias
56 *
57 * PARAMETERS: walk_state - Current state, contains operands
58 *
59 * RETURN: Status
60 *
61 * DESCRIPTION: Create a new named alias
62 *
63 ******************************************************************************/
64acpi_status acpi_ex_create_alias(struct acpi_walk_state *walk_state)
65{
66 struct acpi_namespace_node *target_node;
67 struct acpi_namespace_node *alias_node;
68 acpi_status status = AE_OK;
69
70 ACPI_FUNCTION_TRACE(ex_create_alias);
71
72 /* Get the source/alias operands (both namespace nodes) */
73
74 alias_node = (struct acpi_namespace_node *)walk_state->operands[0];
75 target_node = (struct acpi_namespace_node *)walk_state->operands[1];
76
77 if ((target_node->type == ACPI_TYPE_LOCAL_ALIAS) ||
78 (target_node->type == ACPI_TYPE_LOCAL_METHOD_ALIAS)) {
79 /*
80 * Dereference an existing alias so that we don't create a chain
81 * of aliases. With this code, we guarantee that an alias is
82 * always exactly one level of indirection away from the
83 * actual aliased name.
84 */
85 target_node =
86 ACPI_CAST_PTR(struct acpi_namespace_node,
87 target_node->object);
88 }
89
90 /*
91 * For objects that can never change (i.e., the NS node will
92 * permanently point to the same object), we can simply attach
93 * the object to the new NS node. For other objects (such as
94 * Integers, buffers, etc.), we have to point the Alias node
95 * to the original Node.
96 */
97 switch (target_node->type) {
98
99 /* For these types, the sub-object can change dynamically via a Store */
100
101 case ACPI_TYPE_INTEGER:
102 case ACPI_TYPE_STRING:
103 case ACPI_TYPE_BUFFER:
104 case ACPI_TYPE_PACKAGE:
105 case ACPI_TYPE_BUFFER_FIELD:
106
107 /*
108 * These types open a new scope, so we need the NS node in order to access
109 * any children.
110 */
111 case ACPI_TYPE_DEVICE:
112 case ACPI_TYPE_POWER:
113 case ACPI_TYPE_PROCESSOR:
114 case ACPI_TYPE_THERMAL:
115 case ACPI_TYPE_LOCAL_SCOPE:
116
117 /*
118 * The new alias has the type ALIAS and points to the original
119 * NS node, not the object itself.
120 */
121 alias_node->type = ACPI_TYPE_LOCAL_ALIAS;
122 alias_node->object =
123 ACPI_CAST_PTR(union acpi_operand_object, target_node);
124 break;
125
126 case ACPI_TYPE_METHOD:
127
128 /*
129 * Control method aliases need to be differentiated
130 */
131 alias_node->type = ACPI_TYPE_LOCAL_METHOD_ALIAS;
132 alias_node->object =
133 ACPI_CAST_PTR(union acpi_operand_object, target_node);
134 break;
135
136 default:
137
138 /* Attach the original source object to the new Alias Node */
139
140 /*
141 * The new alias assumes the type of the target, and it points
142 * to the same object. The reference count of the object has an
143 * additional reference to prevent deletion out from under either the
144 * target node or the alias Node
145 */
146 status = acpi_ns_attach_object(alias_node,
147 acpi_ns_get_attached_object
148 (target_node),
149 target_node->type);
150 break;
151 }
152
153 /* Since both operands are Nodes, we don't need to delete them */
154
155 return_ACPI_STATUS(status);
156}
157
158/*******************************************************************************
159 *
160 * FUNCTION: acpi_ex_create_event
161 *
162 * PARAMETERS: walk_state - Current state
163 *
164 * RETURN: Status
165 *
166 * DESCRIPTION: Create a new event object
167 *
168 ******************************************************************************/
169
170acpi_status acpi_ex_create_event(struct acpi_walk_state *walk_state)
171{
172 acpi_status status;
173 union acpi_operand_object *obj_desc;
174
175 ACPI_FUNCTION_TRACE(ex_create_event);
176
177 obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_EVENT);
178 if (!obj_desc) {
179 status = AE_NO_MEMORY;
180 goto cleanup;
181 }
182
183 /*
184 * Create the actual OS semaphore, with zero initial units -- meaning
185 * that the event is created in an unsignalled state
186 */
187 status = acpi_os_create_semaphore(ACPI_NO_UNIT_LIMIT, 0,
188 &obj_desc->event.os_semaphore);
189 if (ACPI_FAILURE(status)) {
190 goto cleanup;
191 }
192
193 /* Attach object to the Node */
194
195 status =
196 acpi_ns_attach_object((struct acpi_namespace_node *)walk_state->
197 operands[0], obj_desc, ACPI_TYPE_EVENT);
198
199 cleanup:
200 /*
201 * Remove local reference to the object (on error, will cause deletion
202 * of both object and semaphore if present.)
203 */
204 acpi_ut_remove_reference(obj_desc);
205 return_ACPI_STATUS(status);
206}
207
208/*******************************************************************************
209 *
210 * FUNCTION: acpi_ex_create_mutex
211 *
212 * PARAMETERS: walk_state - Current state
213 *
214 * RETURN: Status
215 *
216 * DESCRIPTION: Create a new mutex object
217 *
218 * Mutex (Name[0], sync_level[1])
219 *
220 ******************************************************************************/
221
222acpi_status acpi_ex_create_mutex(struct acpi_walk_state *walk_state)
223{
224 acpi_status status = AE_OK;
225 union acpi_operand_object *obj_desc;
226
227 ACPI_FUNCTION_TRACE_PTR(ex_create_mutex, ACPI_WALK_OPERANDS);
228
229 /* Create the new mutex object */
230
231 obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_MUTEX);
232 if (!obj_desc) {
233 status = AE_NO_MEMORY;
234 goto cleanup;
235 }
236
237 /* Create the actual OS Mutex */
238
239 status = acpi_os_create_mutex(&obj_desc->mutex.os_mutex);
240 if (ACPI_FAILURE(status)) {
241 goto cleanup;
242 }
243
244 /* Init object and attach to NS node */
245
246 obj_desc->mutex.sync_level =
247 (u8) walk_state->operands[1]->integer.value;
248 obj_desc->mutex.node =
249 (struct acpi_namespace_node *)walk_state->operands[0];
250
251 status =
252 acpi_ns_attach_object(obj_desc->mutex.node, obj_desc,
253 ACPI_TYPE_MUTEX);
254
255 cleanup:
256 /*
257 * Remove local reference to the object (on error, will cause deletion
258 * of both object and semaphore if present.)
259 */
260 acpi_ut_remove_reference(obj_desc);
261 return_ACPI_STATUS(status);
262}
263
264/*******************************************************************************
265 *
266 * FUNCTION: acpi_ex_create_region
267 *
268 * PARAMETERS: aml_start - Pointer to the region declaration AML
269 * aml_length - Max length of the declaration AML
270 * region_space - space_iD for the region
271 * walk_state - Current state
272 *
273 * RETURN: Status
274 *
275 * DESCRIPTION: Create a new operation region object
276 *
277 ******************************************************************************/
278
279acpi_status
280acpi_ex_create_region(u8 * aml_start,
281 u32 aml_length,
282 u8 region_space, struct acpi_walk_state *walk_state)
283{
284 acpi_status status;
285 union acpi_operand_object *obj_desc;
286 struct acpi_namespace_node *node;
287 union acpi_operand_object *region_obj2;
288
289 ACPI_FUNCTION_TRACE(ex_create_region);
290
291 /* Get the Namespace Node */
292
293 node = walk_state->op->common.node;
294
295 /*
296 * If the region object is already attached to this node,
297 * just return
298 */
299 if (acpi_ns_get_attached_object(node)) {
300 return_ACPI_STATUS(AE_OK);
301 }
302
303 /*
304 * Space ID must be one of the predefined IDs, or in the user-defined
305 * range
306 */
307 if ((region_space >= ACPI_NUM_PREDEFINED_REGIONS) &&
308 (region_space < ACPI_USER_REGION_BEGIN)) {
309 ACPI_ERROR((AE_INFO, "Invalid AddressSpace type %X",
310 region_space));
311 return_ACPI_STATUS(AE_AML_INVALID_SPACE_ID);
312 }
313
314 ACPI_DEBUG_PRINT((ACPI_DB_LOAD, "Region Type - %s (%X)\n",
315 acpi_ut_get_region_name(region_space), region_space));
316
317 /* Create the region descriptor */
318
319 obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_REGION);
320 if (!obj_desc) {
321 status = AE_NO_MEMORY;
322 goto cleanup;
323 }
324
325 /*
326 * Remember location in AML stream of address & length
327 * operands since they need to be evaluated at run time.
328 */
329 region_obj2 = obj_desc->common.next_object;
330 region_obj2->extra.aml_start = aml_start;
331 region_obj2->extra.aml_length = aml_length;
332
333 /* Init the region from the operands */
334
335 obj_desc->region.space_id = region_space;
336 obj_desc->region.address = 0;
337 obj_desc->region.length = 0;
338 obj_desc->region.node = node;
339
340 /* Install the new region object in the parent Node */
341
342 status = acpi_ns_attach_object(node, obj_desc, ACPI_TYPE_REGION);
343
344 cleanup:
345
346 /* Remove local reference to the object */
347
348 acpi_ut_remove_reference(obj_desc);
349 return_ACPI_STATUS(status);
350}
351
352/*******************************************************************************
353 *
354 * FUNCTION: acpi_ex_create_processor
355 *
356 * PARAMETERS: walk_state - Current state
357 *
358 * RETURN: Status
359 *
360 * DESCRIPTION: Create a new processor object and populate the fields
361 *
362 * Processor (Name[0], cpu_iD[1], pblock_addr[2], pblock_length[3])
363 *
364 ******************************************************************************/
365
366acpi_status acpi_ex_create_processor(struct acpi_walk_state *walk_state)
367{
368 union acpi_operand_object **operand = &walk_state->operands[0];
369 union acpi_operand_object *obj_desc;
370 acpi_status status;
371
372 ACPI_FUNCTION_TRACE_PTR(ex_create_processor, walk_state);
373
374 /* Create the processor object */
375
376 obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_PROCESSOR);
377 if (!obj_desc) {
378 return_ACPI_STATUS(AE_NO_MEMORY);
379 }
380
381 /* Initialize the processor object from the operands */
382
383 obj_desc->processor.proc_id = (u8) operand[1]->integer.value;
384 obj_desc->processor.length = (u8) operand[3]->integer.value;
385 obj_desc->processor.address =
386 (acpi_io_address) operand[2]->integer.value;
387
388 /* Install the processor object in the parent Node */
389
390 status = acpi_ns_attach_object((struct acpi_namespace_node *)operand[0],
391 obj_desc, ACPI_TYPE_PROCESSOR);
392
393 /* Remove local reference to the object */
394
395 acpi_ut_remove_reference(obj_desc);
396 return_ACPI_STATUS(status);
397}
398
399/*******************************************************************************
400 *
401 * FUNCTION: acpi_ex_create_power_resource
402 *
403 * PARAMETERS: walk_state - Current state
404 *
405 * RETURN: Status
406 *
407 * DESCRIPTION: Create a new power_resource object and populate the fields
408 *
409 * power_resource (Name[0], system_level[1], resource_order[2])
410 *
411 ******************************************************************************/
412
413acpi_status acpi_ex_create_power_resource(struct acpi_walk_state *walk_state)
414{
415 union acpi_operand_object **operand = &walk_state->operands[0];
416 acpi_status status;
417 union acpi_operand_object *obj_desc;
418
419 ACPI_FUNCTION_TRACE_PTR(ex_create_power_resource, walk_state);
420
421 /* Create the power resource object */
422
423 obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_POWER);
424 if (!obj_desc) {
425 return_ACPI_STATUS(AE_NO_MEMORY);
426 }
427
428 /* Initialize the power object from the operands */
429
430 obj_desc->power_resource.system_level = (u8) operand[1]->integer.value;
431 obj_desc->power_resource.resource_order =
432 (u16) operand[2]->integer.value;
433
434 /* Install the power resource object in the parent Node */
435
436 status = acpi_ns_attach_object((struct acpi_namespace_node *)operand[0],
437 obj_desc, ACPI_TYPE_POWER);
438
439 /* Remove local reference to the object */
440
441 acpi_ut_remove_reference(obj_desc);
442 return_ACPI_STATUS(status);
443}
444#endif
445
446/*******************************************************************************
447 *
448 * FUNCTION: acpi_ex_create_method
449 *
450 * PARAMETERS: aml_start - First byte of the method's AML
451 * aml_length - AML byte count for this method
452 * walk_state - Current state
453 *
454 * RETURN: Status
455 *
456 * DESCRIPTION: Create a new method object
457 *
458 ******************************************************************************/
459
460acpi_status
461acpi_ex_create_method(u8 * aml_start,
462 u32 aml_length, struct acpi_walk_state *walk_state)
463{
464 union acpi_operand_object **operand = &walk_state->operands[0];
465 union acpi_operand_object *obj_desc;
466 acpi_status status;
467 u8 method_flags;
468
469 ACPI_FUNCTION_TRACE_PTR(ex_create_method, walk_state);
470
471 /* Create a new method object */
472
473 obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_METHOD);
474 if (!obj_desc) {
475 status = AE_NO_MEMORY;
476 goto exit;
477 }
478
479 /* Save the method's AML pointer and length */
480
481 obj_desc->method.aml_start = aml_start;
482 obj_desc->method.aml_length = aml_length;
483
484 /*
485 * Disassemble the method flags. Split off the Arg Count
486 * for efficiency
487 */
488 method_flags = (u8) operand[1]->integer.value;
489
490 obj_desc->method.method_flags =
491 (u8) (method_flags & ~AML_METHOD_ARG_COUNT);
492 obj_desc->method.param_count =
493 (u8) (method_flags & AML_METHOD_ARG_COUNT);
494
495 /*
496 * Get the sync_level. If method is serialized, a mutex will be
497 * created for this method when it is parsed.
498 */
499 if (method_flags & AML_METHOD_SERIALIZED) {
500 /*
501 * ACPI 1.0: sync_level = 0
502 * ACPI 2.0: sync_level = sync_level in method declaration
503 */
504 obj_desc->method.sync_level = (u8)
505 ((method_flags & AML_METHOD_SYNCH_LEVEL) >> 4);
506 }
507
508 /* Attach the new object to the method Node */
509
510 status = acpi_ns_attach_object((struct acpi_namespace_node *)operand[0],
511 obj_desc, ACPI_TYPE_METHOD);
512
513 /* Remove local reference to the object */
514
515 acpi_ut_remove_reference(obj_desc);
516
517 exit:
518 /* Remove a reference to the operand */
519
520 acpi_ut_remove_reference(operand[1]);
521 return_ACPI_STATUS(status);
522}
diff --git a/drivers/acpi/acpica/exdump.c b/drivers/acpi/acpica/exdump.c
new file mode 100644
index 00000000000..8241b9eff6c
--- /dev/null
+++ b/drivers/acpi/acpica/exdump.c
@@ -0,0 +1,1060 @@
1/******************************************************************************
2 *
3 * Module Name: exdump - Interpreter debug output routines
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46#include <acpi/acinterp.h>
47#include <acpi/amlcode.h>
48#include <acpi/acnamesp.h>
49
50#define _COMPONENT ACPI_EXECUTER
51ACPI_MODULE_NAME("exdump")
52
53/*
54 * The following routines are used for debug output only
55 */
56#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
57/* Local prototypes */
58static void acpi_ex_out_string(char *title, char *value);
59
60static void acpi_ex_out_pointer(char *title, void *value);
61
62static void
63acpi_ex_dump_object(union acpi_operand_object *obj_desc,
64 struct acpi_exdump_info *info);
65
66static void acpi_ex_dump_reference_obj(union acpi_operand_object *obj_desc);
67
68static void
69acpi_ex_dump_package_obj(union acpi_operand_object *obj_desc,
70 u32 level, u32 index);
71
72/*******************************************************************************
73 *
74 * Object Descriptor info tables
75 *
76 * Note: The first table entry must be an INIT opcode and must contain
77 * the table length (number of table entries)
78 *
79 ******************************************************************************/
80
81static struct acpi_exdump_info acpi_ex_dump_integer[2] = {
82 {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_integer), NULL},
83 {ACPI_EXD_UINT64, ACPI_EXD_OFFSET(integer.value), "Value"}
84};
85
86static struct acpi_exdump_info acpi_ex_dump_string[4] = {
87 {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_string), NULL},
88 {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(string.length), "Length"},
89 {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(string.pointer), "Pointer"},
90 {ACPI_EXD_STRING, 0, NULL}
91};
92
93static struct acpi_exdump_info acpi_ex_dump_buffer[5] = {
94 {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_buffer), NULL},
95 {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(buffer.length), "Length"},
96 {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(buffer.pointer), "Pointer"},
97 {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(buffer.node), "Parent Node"},
98 {ACPI_EXD_BUFFER, 0, NULL}
99};
100
101static struct acpi_exdump_info acpi_ex_dump_package[5] = {
102 {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_package), NULL},
103 {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(package.flags), "Flags"},
104 {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(package.count), "Elements"},
105 {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(package.elements), "Element List"},
106 {ACPI_EXD_PACKAGE, 0, NULL}
107};
108
109static struct acpi_exdump_info acpi_ex_dump_device[4] = {
110 {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_device), NULL},
111 {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(device.handler), "Handler"},
112 {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(device.system_notify),
113 "System Notify"},
114 {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(device.device_notify),
115 "Device Notify"}
116};
117
118static struct acpi_exdump_info acpi_ex_dump_event[2] = {
119 {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_event), NULL},
120 {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(event.os_semaphore), "OsSemaphore"}
121};
122
123static struct acpi_exdump_info acpi_ex_dump_method[8] = {
124 {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_method), NULL},
125 {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.param_count), "ParamCount"},
126 {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.sync_level), "Sync Level"},
127 {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(method.mutex), "Mutex"},
128 {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.owner_id), "Owner Id"},
129 {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.thread_count), "Thread Count"},
130 {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(method.aml_length), "Aml Length"},
131 {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(method.aml_start), "Aml Start"}
132};
133
134static struct acpi_exdump_info acpi_ex_dump_mutex[5] = {
135 {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_mutex), NULL},
136 {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(mutex.sync_level), "Sync Level"},
137 {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(mutex.owner_thread), "Owner Thread"},
138 {ACPI_EXD_UINT16, ACPI_EXD_OFFSET(mutex.acquisition_depth),
139 "Acquire Depth"},
140 {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(mutex.os_mutex), "OsMutex"}
141};
142
143static struct acpi_exdump_info acpi_ex_dump_region[7] = {
144 {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_region), NULL},
145 {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(region.space_id), "Space Id"},
146 {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(region.flags), "Flags"},
147 {ACPI_EXD_ADDRESS, ACPI_EXD_OFFSET(region.address), "Address"},
148 {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(region.length), "Length"},
149 {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(region.handler), "Handler"},
150 {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(region.next), "Next"}
151};
152
153static struct acpi_exdump_info acpi_ex_dump_power[5] = {
154 {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_power), NULL},
155 {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(power_resource.system_level),
156 "System Level"},
157 {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(power_resource.resource_order),
158 "Resource Order"},
159 {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(power_resource.system_notify),
160 "System Notify"},
161 {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(power_resource.device_notify),
162 "Device Notify"}
163};
164
165static struct acpi_exdump_info acpi_ex_dump_processor[7] = {
166 {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_processor), NULL},
167 {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(processor.proc_id), "Processor ID"},
168 {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(processor.length), "Length"},
169 {ACPI_EXD_ADDRESS, ACPI_EXD_OFFSET(processor.address), "Address"},
170 {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(processor.system_notify),
171 "System Notify"},
172 {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(processor.device_notify),
173 "Device Notify"},
174 {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(processor.handler), "Handler"}
175};
176
177static struct acpi_exdump_info acpi_ex_dump_thermal[4] = {
178 {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_thermal), NULL},
179 {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(thermal_zone.system_notify),
180 "System Notify"},
181 {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(thermal_zone.device_notify),
182 "Device Notify"},
183 {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(thermal_zone.handler), "Handler"}
184};
185
186static struct acpi_exdump_info acpi_ex_dump_buffer_field[3] = {
187 {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_buffer_field), NULL},
188 {ACPI_EXD_FIELD, 0, NULL},
189 {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(buffer_field.buffer_obj),
190 "Buffer Object"}
191};
192
193static struct acpi_exdump_info acpi_ex_dump_region_field[3] = {
194 {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_region_field), NULL},
195 {ACPI_EXD_FIELD, 0, NULL},
196 {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(field.region_obj), "Region Object"}
197};
198
199static struct acpi_exdump_info acpi_ex_dump_bank_field[5] = {
200 {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_bank_field), NULL},
201 {ACPI_EXD_FIELD, 0, NULL},
202 {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(bank_field.value), "Value"},
203 {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(bank_field.region_obj),
204 "Region Object"},
205 {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(bank_field.bank_obj), "Bank Object"}
206};
207
208static struct acpi_exdump_info acpi_ex_dump_index_field[5] = {
209 {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_bank_field), NULL},
210 {ACPI_EXD_FIELD, 0, NULL},
211 {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(index_field.value), "Value"},
212 {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(index_field.index_obj),
213 "Index Object"},
214 {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(index_field.data_obj), "Data Object"}
215};
216
217static struct acpi_exdump_info acpi_ex_dump_reference[8] = {
218 {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_reference), NULL},
219 {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(reference.class), "Class"},
220 {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(reference.target_type), "Target Type"},
221 {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(reference.value), "Value"},
222 {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(reference.object), "Object Desc"},
223 {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(reference.node), "Node"},
224 {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(reference.where), "Where"},
225 {ACPI_EXD_REFERENCE, 0, NULL}
226};
227
228static struct acpi_exdump_info acpi_ex_dump_address_handler[6] = {
229 {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_address_handler),
230 NULL},
231 {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(address_space.space_id), "Space Id"},
232 {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(address_space.next), "Next"},
233 {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(address_space.region_list),
234 "Region List"},
235 {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(address_space.node), "Node"},
236 {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(address_space.context), "Context"}
237};
238
239static struct acpi_exdump_info acpi_ex_dump_notify[3] = {
240 {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_notify), NULL},
241 {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(notify.node), "Node"},
242 {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(notify.context), "Context"}
243};
244
245/* Miscellaneous tables */
246
247static struct acpi_exdump_info acpi_ex_dump_common[4] = {
248 {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_common), NULL},
249 {ACPI_EXD_TYPE, 0, NULL},
250 {ACPI_EXD_UINT16, ACPI_EXD_OFFSET(common.reference_count),
251 "Reference Count"},
252 {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(common.flags), "Flags"}
253};
254
255static struct acpi_exdump_info acpi_ex_dump_field_common[7] = {
256 {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_field_common), NULL},
257 {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(common_field.field_flags),
258 "Field Flags"},
259 {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(common_field.access_byte_width),
260 "Access Byte Width"},
261 {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(common_field.bit_length),
262 "Bit Length"},
263 {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(common_field.start_field_bit_offset),
264 "Field Bit Offset"},
265 {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(common_field.base_byte_offset),
266 "Base Byte Offset"},
267 {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(common_field.node), "Parent Node"}
268};
269
270static struct acpi_exdump_info acpi_ex_dump_node[5] = {
271 {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_node), NULL},
272 {ACPI_EXD_UINT8, ACPI_EXD_NSOFFSET(flags), "Flags"},
273 {ACPI_EXD_UINT8, ACPI_EXD_NSOFFSET(owner_id), "Owner Id"},
274 {ACPI_EXD_POINTER, ACPI_EXD_NSOFFSET(child), "Child List"},
275 {ACPI_EXD_POINTER, ACPI_EXD_NSOFFSET(peer), "Next Peer"}
276};
277
278/* Dispatch table, indexed by object type */
279
280static struct acpi_exdump_info *acpi_ex_dump_info[] = {
281 NULL,
282 acpi_ex_dump_integer,
283 acpi_ex_dump_string,
284 acpi_ex_dump_buffer,
285 acpi_ex_dump_package,
286 NULL,
287 acpi_ex_dump_device,
288 acpi_ex_dump_event,
289 acpi_ex_dump_method,
290 acpi_ex_dump_mutex,
291 acpi_ex_dump_region,
292 acpi_ex_dump_power,
293 acpi_ex_dump_processor,
294 acpi_ex_dump_thermal,
295 acpi_ex_dump_buffer_field,
296 NULL,
297 NULL,
298 acpi_ex_dump_region_field,
299 acpi_ex_dump_bank_field,
300 acpi_ex_dump_index_field,
301 acpi_ex_dump_reference,
302 NULL,
303 NULL,
304 acpi_ex_dump_notify,
305 acpi_ex_dump_address_handler,
306 NULL,
307 NULL,
308 NULL
309};
310
311/*******************************************************************************
312 *
313 * FUNCTION: acpi_ex_dump_object
314 *
315 * PARAMETERS: obj_desc - Descriptor to dump
316 * Info - Info table corresponding to this object
317 * type
318 *
319 * RETURN: None
320 *
321 * DESCRIPTION: Walk the info table for this object
322 *
323 ******************************************************************************/
324
325static void
326acpi_ex_dump_object(union acpi_operand_object *obj_desc,
327 struct acpi_exdump_info *info)
328{
329 u8 *target;
330 char *name;
331 u8 count;
332
333 if (!info) {
334 acpi_os_printf
335 ("ExDumpObject: Display not implemented for object type %s\n",
336 acpi_ut_get_object_type_name(obj_desc));
337 return;
338 }
339
340 /* First table entry must contain the table length (# of table entries) */
341
342 count = info->offset;
343
344 while (count) {
345 target = ACPI_ADD_PTR(u8, obj_desc, info->offset);
346 name = info->name;
347
348 switch (info->opcode) {
349 case ACPI_EXD_INIT:
350 break;
351
352 case ACPI_EXD_TYPE:
353 acpi_ex_out_string("Type",
354 acpi_ut_get_object_type_name
355 (obj_desc));
356 break;
357
358 case ACPI_EXD_UINT8:
359
360 acpi_os_printf("%20s : %2.2X\n", name, *target);
361 break;
362
363 case ACPI_EXD_UINT16:
364
365 acpi_os_printf("%20s : %4.4X\n", name,
366 ACPI_GET16(target));
367 break;
368
369 case ACPI_EXD_UINT32:
370
371 acpi_os_printf("%20s : %8.8X\n", name,
372 ACPI_GET32(target));
373 break;
374
375 case ACPI_EXD_UINT64:
376
377 acpi_os_printf("%20s : %8.8X%8.8X\n", "Value",
378 ACPI_FORMAT_UINT64(ACPI_GET64(target)));
379 break;
380
381 case ACPI_EXD_POINTER:
382 case ACPI_EXD_ADDRESS:
383
384 acpi_ex_out_pointer(name,
385 *ACPI_CAST_PTR(void *, target));
386 break;
387
388 case ACPI_EXD_STRING:
389
390 acpi_ut_print_string(obj_desc->string.pointer,
391 ACPI_UINT8_MAX);
392 acpi_os_printf("\n");
393 break;
394
395 case ACPI_EXD_BUFFER:
396
397 ACPI_DUMP_BUFFER(obj_desc->buffer.pointer,
398 obj_desc->buffer.length);
399 break;
400
401 case ACPI_EXD_PACKAGE:
402
403 /* Dump the package contents */
404
405 acpi_os_printf("\nPackage Contents:\n");
406 acpi_ex_dump_package_obj(obj_desc, 0, 0);
407 break;
408
409 case ACPI_EXD_FIELD:
410
411 acpi_ex_dump_object(obj_desc,
412 acpi_ex_dump_field_common);
413 break;
414
415 case ACPI_EXD_REFERENCE:
416
417 acpi_ex_out_string("Class Name",
418 (char *)
419 acpi_ut_get_reference_name
420 (obj_desc));
421 acpi_ex_dump_reference_obj(obj_desc);
422 break;
423
424 default:
425 acpi_os_printf("**** Invalid table opcode [%X] ****\n",
426 info->opcode);
427 return;
428 }
429
430 info++;
431 count--;
432 }
433}
434
435/*******************************************************************************
436 *
437 * FUNCTION: acpi_ex_dump_operand
438 *
439 * PARAMETERS: *obj_desc - Pointer to entry to be dumped
440 * Depth - Current nesting depth
441 *
442 * RETURN: None
443 *
444 * DESCRIPTION: Dump an operand object
445 *
446 ******************************************************************************/
447
448void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth)
449{
450 u32 length;
451 u32 index;
452
453 ACPI_FUNCTION_NAME(ex_dump_operand)
454
455 if (!((ACPI_LV_EXEC & acpi_dbg_level)
456 && (_COMPONENT & acpi_dbg_layer))) {
457 return;
458 }
459
460 if (!obj_desc) {
461
462 /* This could be a null element of a package */
463
464 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Null Object Descriptor\n"));
465 return;
466 }
467
468 if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) == ACPI_DESC_TYPE_NAMED) {
469 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "%p Namespace Node: ",
470 obj_desc));
471 ACPI_DUMP_ENTRY(obj_desc, ACPI_LV_EXEC);
472 return;
473 }
474
475 if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) != ACPI_DESC_TYPE_OPERAND) {
476 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
477 "%p is not a node or operand object: [%s]\n",
478 obj_desc,
479 acpi_ut_get_descriptor_name(obj_desc)));
480 ACPI_DUMP_BUFFER(obj_desc, sizeof(union acpi_operand_object));
481 return;
482 }
483
484 /* obj_desc is a valid object */
485
486 if (depth > 0) {
487 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "%*s[%u] %p ",
488 depth, " ", depth, obj_desc));
489 } else {
490 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "%p ", obj_desc));
491 }
492
493 /* Decode object type */
494
495 switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
496 case ACPI_TYPE_LOCAL_REFERENCE:
497
498 acpi_os_printf("Reference: [%s] ",
499 acpi_ut_get_reference_name(obj_desc));
500
501 switch (obj_desc->reference.class) {
502 case ACPI_REFCLASS_DEBUG:
503
504 acpi_os_printf("\n");
505 break;
506
507 case ACPI_REFCLASS_INDEX:
508
509 acpi_os_printf("%p\n", obj_desc->reference.object);
510 break;
511
512 case ACPI_REFCLASS_TABLE:
513
514 acpi_os_printf("Table Index %X\n",
515 obj_desc->reference.value);
516 break;
517
518 case ACPI_REFCLASS_REFOF:
519
520 acpi_os_printf("%p [%s]\n", obj_desc->reference.object,
521 acpi_ut_get_type_name(((union
522 acpi_operand_object
523 *)
524 obj_desc->
525 reference.
526 object)->common.
527 type));
528 break;
529
530 case ACPI_REFCLASS_ARG:
531
532 acpi_os_printf("%X", obj_desc->reference.value);
533
534 if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {
535
536 /* Value is an Integer */
537
538 acpi_os_printf(" value is [%8.8X%8.8x]",
539 ACPI_FORMAT_UINT64(obj_desc->
540 integer.
541 value));
542 }
543
544 acpi_os_printf("\n");
545 break;
546
547 case ACPI_REFCLASS_LOCAL:
548
549 acpi_os_printf("%X", obj_desc->reference.value);
550
551 if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {
552
553 /* Value is an Integer */
554
555 acpi_os_printf(" value is [%8.8X%8.8x]",
556 ACPI_FORMAT_UINT64(obj_desc->
557 integer.
558 value));
559 }
560
561 acpi_os_printf("\n");
562 break;
563
564 case ACPI_REFCLASS_NAME:
565
566 acpi_os_printf("- [%4.4s]\n",
567 obj_desc->reference.node->name.ascii);
568 break;
569
570 default: /* Unknown reference class */
571
572 acpi_os_printf("%2.2X\n", obj_desc->reference.class);
573 break;
574 }
575 break;
576
577 case ACPI_TYPE_BUFFER:
578
579 acpi_os_printf("Buffer length %.2X @ %p\n",
580 obj_desc->buffer.length,
581 obj_desc->buffer.pointer);
582
583 /* Debug only -- dump the buffer contents */
584
585 if (obj_desc->buffer.pointer) {
586 length = obj_desc->buffer.length;
587 if (length > 128) {
588 length = 128;
589 }
590
591 acpi_os_printf
592 ("Buffer Contents: (displaying length 0x%.2X)\n",
593 length);
594 ACPI_DUMP_BUFFER(obj_desc->buffer.pointer, length);
595 }
596 break;
597
598 case ACPI_TYPE_INTEGER:
599
600 acpi_os_printf("Integer %8.8X%8.8X\n",
601 ACPI_FORMAT_UINT64(obj_desc->integer.value));
602 break;
603
604 case ACPI_TYPE_PACKAGE:
605
606 acpi_os_printf("Package [Len %X] ElementArray %p\n",
607 obj_desc->package.count,
608 obj_desc->package.elements);
609
610 /*
611 * If elements exist, package element pointer is valid,
612 * and debug_level exceeds 1, dump package's elements.
613 */
614 if (obj_desc->package.count &&
615 obj_desc->package.elements && acpi_dbg_level > 1) {
616 for (index = 0; index < obj_desc->package.count;
617 index++) {
618 acpi_ex_dump_operand(obj_desc->package.
619 elements[index],
620 depth + 1);
621 }
622 }
623 break;
624
625 case ACPI_TYPE_REGION:
626
627 acpi_os_printf("Region %s (%X)",
628 acpi_ut_get_region_name(obj_desc->region.
629 space_id),
630 obj_desc->region.space_id);
631
632 /*
633 * If the address and length have not been evaluated,
634 * don't print them.
635 */
636 if (!(obj_desc->region.flags & AOPOBJ_DATA_VALID)) {
637 acpi_os_printf("\n");
638 } else {
639 acpi_os_printf(" base %8.8X%8.8X Length %X\n",
640 ACPI_FORMAT_NATIVE_UINT(obj_desc->region.
641 address),
642 obj_desc->region.length);
643 }
644 break;
645
646 case ACPI_TYPE_STRING:
647
648 acpi_os_printf("String length %X @ %p ",
649 obj_desc->string.length,
650 obj_desc->string.pointer);
651
652 acpi_ut_print_string(obj_desc->string.pointer, ACPI_UINT8_MAX);
653 acpi_os_printf("\n");
654 break;
655
656 case ACPI_TYPE_LOCAL_BANK_FIELD:
657
658 acpi_os_printf("BankField\n");
659 break;
660
661 case ACPI_TYPE_LOCAL_REGION_FIELD:
662
663 acpi_os_printf
664 ("RegionField: Bits=%X AccWidth=%X Lock=%X Update=%X at byte=%X bit=%X of below:\n",
665 obj_desc->field.bit_length,
666 obj_desc->field.access_byte_width,
667 obj_desc->field.field_flags & AML_FIELD_LOCK_RULE_MASK,
668 obj_desc->field.field_flags & AML_FIELD_UPDATE_RULE_MASK,
669 obj_desc->field.base_byte_offset,
670 obj_desc->field.start_field_bit_offset);
671
672 acpi_ex_dump_operand(obj_desc->field.region_obj, depth + 1);
673 break;
674
675 case ACPI_TYPE_LOCAL_INDEX_FIELD:
676
677 acpi_os_printf("IndexField\n");
678 break;
679
680 case ACPI_TYPE_BUFFER_FIELD:
681
682 acpi_os_printf("BufferField: %X bits at byte %X bit %X of\n",
683 obj_desc->buffer_field.bit_length,
684 obj_desc->buffer_field.base_byte_offset,
685 obj_desc->buffer_field.start_field_bit_offset);
686
687 if (!obj_desc->buffer_field.buffer_obj) {
688 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "*NULL*\n"));
689 } else
690 if (ACPI_GET_OBJECT_TYPE(obj_desc->buffer_field.buffer_obj)
691 != ACPI_TYPE_BUFFER) {
692 acpi_os_printf("*not a Buffer*\n");
693 } else {
694 acpi_ex_dump_operand(obj_desc->buffer_field.buffer_obj,
695 depth + 1);
696 }
697 break;
698
699 case ACPI_TYPE_EVENT:
700
701 acpi_os_printf("Event\n");
702 break;
703
704 case ACPI_TYPE_METHOD:
705
706 acpi_os_printf("Method(%X) @ %p:%X\n",
707 obj_desc->method.param_count,
708 obj_desc->method.aml_start,
709 obj_desc->method.aml_length);
710 break;
711
712 case ACPI_TYPE_MUTEX:
713
714 acpi_os_printf("Mutex\n");
715 break;
716
717 case ACPI_TYPE_DEVICE:
718
719 acpi_os_printf("Device\n");
720 break;
721
722 case ACPI_TYPE_POWER:
723
724 acpi_os_printf("Power\n");
725 break;
726
727 case ACPI_TYPE_PROCESSOR:
728
729 acpi_os_printf("Processor\n");
730 break;
731
732 case ACPI_TYPE_THERMAL:
733
734 acpi_os_printf("Thermal\n");
735 break;
736
737 default:
738 /* Unknown Type */
739
740 acpi_os_printf("Unknown Type %X\n",
741 ACPI_GET_OBJECT_TYPE(obj_desc));
742 break;
743 }
744
745 return;
746}
747
748/*******************************************************************************
749 *
750 * FUNCTION: acpi_ex_dump_operands
751 *
752 * PARAMETERS: Operands - A list of Operand objects
753 * opcode_name - AML opcode name
754 * num_operands - Operand count for this opcode
755 *
756 * DESCRIPTION: Dump the operands associated with the opcode
757 *
758 ******************************************************************************/
759
760void
761acpi_ex_dump_operands(union acpi_operand_object **operands,
762 const char *opcode_name, u32 num_operands)
763{
764 ACPI_FUNCTION_NAME(ex_dump_operands);
765
766 if (!opcode_name) {
767 opcode_name = "UNKNOWN";
768 }
769
770 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
771 "**** Start operand dump for opcode [%s], %d operands\n",
772 opcode_name, num_operands));
773
774 if (num_operands == 0) {
775 num_operands = 1;
776 }
777
778 /* Dump the individual operands */
779
780 while (num_operands) {
781 acpi_ex_dump_operand(*operands, 0);
782 operands++;
783 num_operands--;
784 }
785
786 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
787 "**** End operand dump for [%s]\n", opcode_name));
788 return;
789}
790
791/*******************************************************************************
792 *
793 * FUNCTION: acpi_ex_out* functions
794 *
795 * PARAMETERS: Title - Descriptive text
796 * Value - Value to be displayed
797 *
798 * DESCRIPTION: Object dump output formatting functions. These functions
799 * reduce the number of format strings required and keeps them
800 * all in one place for easy modification.
801 *
802 ******************************************************************************/
803
804static void acpi_ex_out_string(char *title, char *value)
805{
806 acpi_os_printf("%20s : %s\n", title, value);
807}
808
809static void acpi_ex_out_pointer(char *title, void *value)
810{
811 acpi_os_printf("%20s : %p\n", title, value);
812}
813
814/*******************************************************************************
815 *
816 * FUNCTION: acpi_ex_dump_namespace_node
817 *
818 * PARAMETERS: Node - Descriptor to dump
819 * Flags - Force display if TRUE
820 *
821 * DESCRIPTION: Dumps the members of the given.Node
822 *
823 ******************************************************************************/
824
825void acpi_ex_dump_namespace_node(struct acpi_namespace_node *node, u32 flags)
826{
827
828 ACPI_FUNCTION_ENTRY();
829
830 if (!flags) {
831 if (!((ACPI_LV_OBJECTS & acpi_dbg_level)
832 && (_COMPONENT & acpi_dbg_layer))) {
833 return;
834 }
835 }
836
837 acpi_os_printf("%20s : %4.4s\n", "Name", acpi_ut_get_node_name(node));
838 acpi_ex_out_string("Type", acpi_ut_get_type_name(node->type));
839 acpi_ex_out_pointer("Attached Object",
840 acpi_ns_get_attached_object(node));
841 acpi_ex_out_pointer("Parent", acpi_ns_get_parent_node(node));
842
843 acpi_ex_dump_object(ACPI_CAST_PTR(union acpi_operand_object, node),
844 acpi_ex_dump_node);
845}
846
847/*******************************************************************************
848 *
849 * FUNCTION: acpi_ex_dump_reference_obj
850 *
851 * PARAMETERS: Object - Descriptor to dump
852 *
853 * DESCRIPTION: Dumps a reference object
854 *
855 ******************************************************************************/
856
857static void acpi_ex_dump_reference_obj(union acpi_operand_object *obj_desc)
858{
859 struct acpi_buffer ret_buf;
860 acpi_status status;
861
862 ret_buf.length = ACPI_ALLOCATE_LOCAL_BUFFER;
863
864 if (obj_desc->reference.class == ACPI_REFCLASS_NAME) {
865 acpi_os_printf(" %p ", obj_desc->reference.node);
866
867 status =
868 acpi_ns_handle_to_pathname(obj_desc->reference.node,
869 &ret_buf);
870 if (ACPI_FAILURE(status)) {
871 acpi_os_printf(" Could not convert name to pathname\n");
872 } else {
873 acpi_os_printf("%s\n", (char *)ret_buf.pointer);
874 ACPI_FREE(ret_buf.pointer);
875 }
876 } else if (obj_desc->reference.object) {
877 if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) ==
878 ACPI_DESC_TYPE_OPERAND) {
879 acpi_os_printf(" Target: %p",
880 obj_desc->reference.object);
881 if (obj_desc->reference.class == ACPI_REFCLASS_TABLE) {
882 acpi_os_printf(" Table Index: %X\n",
883 obj_desc->reference.value);
884 } else {
885 acpi_os_printf(" Target: %p [%s]\n",
886 obj_desc->reference.object,
887 acpi_ut_get_type_name(((union
888 acpi_operand_object
889 *)
890 obj_desc->
891 reference.
892 object)->
893 common.
894 type));
895 }
896 } else {
897 acpi_os_printf(" Target: %p\n",
898 obj_desc->reference.object);
899 }
900 }
901}
902
903/*******************************************************************************
904 *
905 * FUNCTION: acpi_ex_dump_package_obj
906 *
907 * PARAMETERS: obj_desc - Descriptor to dump
908 * Level - Indentation Level
909 * Index - Package index for this object
910 *
911 * DESCRIPTION: Dumps the elements of the package
912 *
913 ******************************************************************************/
914
915static void
916acpi_ex_dump_package_obj(union acpi_operand_object *obj_desc,
917 u32 level, u32 index)
918{
919 u32 i;
920
921 /* Indentation and index output */
922
923 if (level > 0) {
924 for (i = 0; i < level; i++) {
925 acpi_os_printf(" ");
926 }
927
928 acpi_os_printf("[%.2d] ", index);
929 }
930
931 acpi_os_printf("%p ", obj_desc);
932
933 /* Null package elements are allowed */
934
935 if (!obj_desc) {
936 acpi_os_printf("[Null Object]\n");
937 return;
938 }
939
940 /* Packages may only contain a few object types */
941
942 switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
943 case ACPI_TYPE_INTEGER:
944
945 acpi_os_printf("[Integer] = %8.8X%8.8X\n",
946 ACPI_FORMAT_UINT64(obj_desc->integer.value));
947 break;
948
949 case ACPI_TYPE_STRING:
950
951 acpi_os_printf("[String] Value: ");
952 for (i = 0; i < obj_desc->string.length; i++) {
953 acpi_os_printf("%c", obj_desc->string.pointer[i]);
954 }
955 acpi_os_printf("\n");
956 break;
957
958 case ACPI_TYPE_BUFFER:
959
960 acpi_os_printf("[Buffer] Length %.2X = ",
961 obj_desc->buffer.length);
962 if (obj_desc->buffer.length) {
963 acpi_ut_dump_buffer(ACPI_CAST_PTR
964 (u8, obj_desc->buffer.pointer),
965 obj_desc->buffer.length,
966 DB_DWORD_DISPLAY, _COMPONENT);
967 } else {
968 acpi_os_printf("\n");
969 }
970 break;
971
972 case ACPI_TYPE_PACKAGE:
973
974 acpi_os_printf("[Package] Contains %d Elements:\n",
975 obj_desc->package.count);
976
977 for (i = 0; i < obj_desc->package.count; i++) {
978 acpi_ex_dump_package_obj(obj_desc->package.elements[i],
979 level + 1, i);
980 }
981 break;
982
983 case ACPI_TYPE_LOCAL_REFERENCE:
984
985 acpi_os_printf("[Object Reference] Type [%s] %2.2X",
986 acpi_ut_get_reference_name(obj_desc),
987 obj_desc->reference.class);
988 acpi_ex_dump_reference_obj(obj_desc);
989 break;
990
991 default:
992
993 acpi_os_printf("[Unknown Type] %X\n",
994 ACPI_GET_OBJECT_TYPE(obj_desc));
995 break;
996 }
997}
998
999/*******************************************************************************
1000 *
1001 * FUNCTION: acpi_ex_dump_object_descriptor
1002 *
1003 * PARAMETERS: obj_desc - Descriptor to dump
1004 * Flags - Force display if TRUE
1005 *
1006 * DESCRIPTION: Dumps the members of the object descriptor given.
1007 *
1008 ******************************************************************************/
1009
1010void
1011acpi_ex_dump_object_descriptor(union acpi_operand_object *obj_desc, u32 flags)
1012{
1013 ACPI_FUNCTION_TRACE(ex_dump_object_descriptor);
1014
1015 if (!obj_desc) {
1016 return_VOID;
1017 }
1018
1019 if (!flags) {
1020 if (!((ACPI_LV_OBJECTS & acpi_dbg_level)
1021 && (_COMPONENT & acpi_dbg_layer))) {
1022 return_VOID;
1023 }
1024 }
1025
1026 if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) == ACPI_DESC_TYPE_NAMED) {
1027 acpi_ex_dump_namespace_node((struct acpi_namespace_node *)
1028 obj_desc, flags);
1029
1030 acpi_os_printf("\nAttached Object (%p):\n",
1031 ((struct acpi_namespace_node *)obj_desc)->
1032 object);
1033
1034 acpi_ex_dump_object_descriptor(((struct acpi_namespace_node *)
1035 obj_desc)->object, flags);
1036 return_VOID;
1037 }
1038
1039 if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) != ACPI_DESC_TYPE_OPERAND) {
1040 acpi_os_printf
1041 ("ExDumpObjectDescriptor: %p is not an ACPI operand object: [%s]\n",
1042 obj_desc, acpi_ut_get_descriptor_name(obj_desc));
1043 return_VOID;
1044 }
1045
1046 if (obj_desc->common.type > ACPI_TYPE_NS_NODE_MAX) {
1047 return_VOID;
1048 }
1049
1050 /* Common Fields */
1051
1052 acpi_ex_dump_object(obj_desc, acpi_ex_dump_common);
1053
1054 /* Object-specific fields */
1055
1056 acpi_ex_dump_object(obj_desc, acpi_ex_dump_info[obj_desc->common.type]);
1057 return_VOID;
1058}
1059
1060#endif
diff --git a/drivers/acpi/acpica/exfield.c b/drivers/acpi/acpica/exfield.c
new file mode 100644
index 00000000000..7b6df031039
--- /dev/null
+++ b/drivers/acpi/acpica/exfield.c
@@ -0,0 +1,340 @@
1/******************************************************************************
2 *
3 * Module Name: exfield - ACPI AML (p-code) execution - field manipulation
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46#include <acpi/acdispat.h>
47#include <acpi/acinterp.h>
48
49#define _COMPONENT ACPI_EXECUTER
50ACPI_MODULE_NAME("exfield")
51
52/*******************************************************************************
53 *
54 * FUNCTION: acpi_ex_read_data_from_field
55 *
56 * PARAMETERS: walk_state - Current execution state
57 * obj_desc - The named field
58 * ret_buffer_desc - Where the return data object is stored
59 *
60 * RETURN: Status
61 *
62 * DESCRIPTION: Read from a named field. Returns either an Integer or a
63 * Buffer, depending on the size of the field.
64 *
65 ******************************************************************************/
66acpi_status
67acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state,
68 union acpi_operand_object *obj_desc,
69 union acpi_operand_object **ret_buffer_desc)
70{
71 acpi_status status;
72 union acpi_operand_object *buffer_desc;
73 acpi_size length;
74 void *buffer;
75
76 ACPI_FUNCTION_TRACE_PTR(ex_read_data_from_field, obj_desc);
77
78 /* Parameter validation */
79
80 if (!obj_desc) {
81 return_ACPI_STATUS(AE_AML_NO_OPERAND);
82 }
83 if (!ret_buffer_desc) {
84 return_ACPI_STATUS(AE_BAD_PARAMETER);
85 }
86
87 if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_BUFFER_FIELD) {
88 /*
89 * If the buffer_field arguments have not been previously evaluated,
90 * evaluate them now and save the results.
91 */
92 if (!(obj_desc->common.flags & AOPOBJ_DATA_VALID)) {
93 status = acpi_ds_get_buffer_field_arguments(obj_desc);
94 if (ACPI_FAILURE(status)) {
95 return_ACPI_STATUS(status);
96 }
97 }
98 } else
99 if ((ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_REGION_FIELD)
100 && (obj_desc->field.region_obj->region.space_id ==
101 ACPI_ADR_SPACE_SMBUS)) {
102 /*
103 * This is an SMBus read. We must create a buffer to hold the data
104 * and directly access the region handler.
105 */
106 buffer_desc =
107 acpi_ut_create_buffer_object(ACPI_SMBUS_BUFFER_SIZE);
108 if (!buffer_desc) {
109 return_ACPI_STATUS(AE_NO_MEMORY);
110 }
111
112 /* Lock entire transaction if requested */
113
114 acpi_ex_acquire_global_lock(obj_desc->common_field.field_flags);
115
116 /*
117 * Perform the read.
118 * Note: Smbus protocol value is passed in upper 16-bits of Function
119 */
120 status = acpi_ex_access_region(obj_desc, 0,
121 ACPI_CAST_PTR(acpi_integer,
122 buffer_desc->
123 buffer.pointer),
124 ACPI_READ | (obj_desc->field.
125 attribute << 16));
126 acpi_ex_release_global_lock(obj_desc->common_field.field_flags);
127 goto exit;
128 }
129
130 /*
131 * Allocate a buffer for the contents of the field.
132 *
133 * If the field is larger than the size of an acpi_integer, create
134 * a BUFFER to hold it. Otherwise, use an INTEGER. This allows
135 * the use of arithmetic operators on the returned value if the
136 * field size is equal or smaller than an Integer.
137 *
138 * Note: Field.length is in bits.
139 */
140 length =
141 (acpi_size) ACPI_ROUND_BITS_UP_TO_BYTES(obj_desc->field.bit_length);
142 if (length > acpi_gbl_integer_byte_width) {
143
144 /* Field is too large for an Integer, create a Buffer instead */
145
146 buffer_desc = acpi_ut_create_buffer_object(length);
147 if (!buffer_desc) {
148 return_ACPI_STATUS(AE_NO_MEMORY);
149 }
150 buffer = buffer_desc->buffer.pointer;
151 } else {
152 /* Field will fit within an Integer (normal case) */
153
154 buffer_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
155 if (!buffer_desc) {
156 return_ACPI_STATUS(AE_NO_MEMORY);
157 }
158
159 length = acpi_gbl_integer_byte_width;
160 buffer_desc->integer.value = 0;
161 buffer = &buffer_desc->integer.value;
162 }
163
164 ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
165 "FieldRead [TO]: Obj %p, Type %X, Buf %p, ByteLen %X\n",
166 obj_desc, ACPI_GET_OBJECT_TYPE(obj_desc), buffer,
167 (u32) length));
168 ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
169 "FieldRead [FROM]: BitLen %X, BitOff %X, ByteOff %X\n",
170 obj_desc->common_field.bit_length,
171 obj_desc->common_field.start_field_bit_offset,
172 obj_desc->common_field.base_byte_offset));
173
174 /* Lock entire transaction if requested */
175
176 acpi_ex_acquire_global_lock(obj_desc->common_field.field_flags);
177
178 /* Read from the field */
179
180 status = acpi_ex_extract_from_field(obj_desc, buffer, (u32) length);
181 acpi_ex_release_global_lock(obj_desc->common_field.field_flags);
182
183 exit:
184 if (ACPI_FAILURE(status)) {
185 acpi_ut_remove_reference(buffer_desc);
186 } else {
187 *ret_buffer_desc = buffer_desc;
188 }
189
190 return_ACPI_STATUS(status);
191}
192
193/*******************************************************************************
194 *
195 * FUNCTION: acpi_ex_write_data_to_field
196 *
197 * PARAMETERS: source_desc - Contains data to write
198 * obj_desc - The named field
199 * result_desc - Where the return value is returned, if any
200 *
201 * RETURN: Status
202 *
203 * DESCRIPTION: Write to a named field
204 *
205 ******************************************************************************/
206
207acpi_status
208acpi_ex_write_data_to_field(union acpi_operand_object *source_desc,
209 union acpi_operand_object *obj_desc,
210 union acpi_operand_object **result_desc)
211{
212 acpi_status status;
213 u32 length;
214 void *buffer;
215 union acpi_operand_object *buffer_desc;
216
217 ACPI_FUNCTION_TRACE_PTR(ex_write_data_to_field, obj_desc);
218
219 /* Parameter validation */
220
221 if (!source_desc || !obj_desc) {
222 return_ACPI_STATUS(AE_AML_NO_OPERAND);
223 }
224
225 if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_BUFFER_FIELD) {
226 /*
227 * If the buffer_field arguments have not been previously evaluated,
228 * evaluate them now and save the results.
229 */
230 if (!(obj_desc->common.flags & AOPOBJ_DATA_VALID)) {
231 status = acpi_ds_get_buffer_field_arguments(obj_desc);
232 if (ACPI_FAILURE(status)) {
233 return_ACPI_STATUS(status);
234 }
235 }
236 } else
237 if ((ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_REGION_FIELD)
238 && (obj_desc->field.region_obj->region.space_id ==
239 ACPI_ADR_SPACE_SMBUS)) {
240 /*
241 * This is an SMBus write. We will bypass the entire field mechanism
242 * and handoff the buffer directly to the handler.
243 *
244 * Source must be a buffer of sufficient size (ACPI_SMBUS_BUFFER_SIZE).
245 */
246 if (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_BUFFER) {
247 ACPI_ERROR((AE_INFO,
248 "SMBus write requires Buffer, found type %s",
249 acpi_ut_get_object_type_name(source_desc)));
250
251 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
252 }
253
254 if (source_desc->buffer.length < ACPI_SMBUS_BUFFER_SIZE) {
255 ACPI_ERROR((AE_INFO,
256 "SMBus write requires Buffer of length %X, found length %X",
257 ACPI_SMBUS_BUFFER_SIZE,
258 source_desc->buffer.length));
259
260 return_ACPI_STATUS(AE_AML_BUFFER_LIMIT);
261 }
262
263 buffer_desc =
264 acpi_ut_create_buffer_object(ACPI_SMBUS_BUFFER_SIZE);
265 if (!buffer_desc) {
266 return_ACPI_STATUS(AE_NO_MEMORY);
267 }
268
269 buffer = buffer_desc->buffer.pointer;
270 ACPI_MEMCPY(buffer, source_desc->buffer.pointer,
271 ACPI_SMBUS_BUFFER_SIZE);
272
273 /* Lock entire transaction if requested */
274
275 acpi_ex_acquire_global_lock(obj_desc->common_field.field_flags);
276
277 /*
278 * Perform the write (returns status and perhaps data in the
279 * same buffer)
280 * Note: SMBus protocol type is passed in upper 16-bits of Function.
281 */
282 status = acpi_ex_access_region(obj_desc, 0,
283 (acpi_integer *) buffer,
284 ACPI_WRITE | (obj_desc->field.
285 attribute << 16));
286 acpi_ex_release_global_lock(obj_desc->common_field.field_flags);
287
288 *result_desc = buffer_desc;
289 return_ACPI_STATUS(status);
290 }
291
292 /* Get a pointer to the data to be written */
293
294 switch (ACPI_GET_OBJECT_TYPE(source_desc)) {
295 case ACPI_TYPE_INTEGER:
296 buffer = &source_desc->integer.value;
297 length = sizeof(source_desc->integer.value);
298 break;
299
300 case ACPI_TYPE_BUFFER:
301 buffer = source_desc->buffer.pointer;
302 length = source_desc->buffer.length;
303 break;
304
305 case ACPI_TYPE_STRING:
306 buffer = source_desc->string.pointer;
307 length = source_desc->string.length;
308 break;
309
310 default:
311 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
312 }
313
314 ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
315 "FieldWrite [FROM]: Obj %p (%s:%X), Buf %p, ByteLen %X\n",
316 source_desc,
317 acpi_ut_get_type_name(ACPI_GET_OBJECT_TYPE
318 (source_desc)),
319 ACPI_GET_OBJECT_TYPE(source_desc), buffer, length));
320
321 ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
322 "FieldWrite [TO]: Obj %p (%s:%X), BitLen %X, BitOff %X, ByteOff %X\n",
323 obj_desc,
324 acpi_ut_get_type_name(ACPI_GET_OBJECT_TYPE(obj_desc)),
325 ACPI_GET_OBJECT_TYPE(obj_desc),
326 obj_desc->common_field.bit_length,
327 obj_desc->common_field.start_field_bit_offset,
328 obj_desc->common_field.base_byte_offset));
329
330 /* Lock entire transaction if requested */
331
332 acpi_ex_acquire_global_lock(obj_desc->common_field.field_flags);
333
334 /* Write to the field */
335
336 status = acpi_ex_insert_into_field(obj_desc, buffer, length);
337 acpi_ex_release_global_lock(obj_desc->common_field.field_flags);
338
339 return_ACPI_STATUS(status);
340}
diff --git a/drivers/acpi/acpica/exfldio.c b/drivers/acpi/acpica/exfldio.c
new file mode 100644
index 00000000000..33cd17a1064
--- /dev/null
+++ b/drivers/acpi/acpica/exfldio.c
@@ -0,0 +1,961 @@
1/******************************************************************************
2 *
3 * Module Name: exfldio - Aml Field I/O
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46#include <acpi/acinterp.h>
47#include <acpi/amlcode.h>
48#include <acpi/acevents.h>
49#include <acpi/acdispat.h>
50
51#define _COMPONENT ACPI_EXECUTER
52ACPI_MODULE_NAME("exfldio")
53
54/* Local prototypes */
55static acpi_status
56acpi_ex_field_datum_io(union acpi_operand_object *obj_desc,
57 u32 field_datum_byte_offset,
58 acpi_integer * value, u32 read_write);
59
60static u8
61acpi_ex_register_overflow(union acpi_operand_object *obj_desc,
62 acpi_integer value);
63
64static acpi_status
65acpi_ex_setup_region(union acpi_operand_object *obj_desc,
66 u32 field_datum_byte_offset);
67
68/*******************************************************************************
69 *
70 * FUNCTION: acpi_ex_setup_region
71 *
72 * PARAMETERS: obj_desc - Field to be read or written
73 * field_datum_byte_offset - Byte offset of this datum within the
74 * parent field
75 *
76 * RETURN: Status
77 *
78 * DESCRIPTION: Common processing for acpi_ex_extract_from_field and
79 * acpi_ex_insert_into_field. Initialize the Region if necessary and
80 * validate the request.
81 *
82 ******************************************************************************/
83
84static acpi_status
85acpi_ex_setup_region(union acpi_operand_object *obj_desc,
86 u32 field_datum_byte_offset)
87{
88 acpi_status status = AE_OK;
89 union acpi_operand_object *rgn_desc;
90
91 ACPI_FUNCTION_TRACE_U32(ex_setup_region, field_datum_byte_offset);
92
93 rgn_desc = obj_desc->common_field.region_obj;
94
95 /* We must have a valid region */
96
97 if (ACPI_GET_OBJECT_TYPE(rgn_desc) != ACPI_TYPE_REGION) {
98 ACPI_ERROR((AE_INFO, "Needed Region, found type %X (%s)",
99 ACPI_GET_OBJECT_TYPE(rgn_desc),
100 acpi_ut_get_object_type_name(rgn_desc)));
101
102 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
103 }
104
105 /*
106 * If the Region Address and Length have not been previously evaluated,
107 * evaluate them now and save the results.
108 */
109 if (!(rgn_desc->common.flags & AOPOBJ_DATA_VALID)) {
110 status = acpi_ds_get_region_arguments(rgn_desc);
111 if (ACPI_FAILURE(status)) {
112 return_ACPI_STATUS(status);
113 }
114 }
115
116 /* Exit if Address/Length have been disallowed by the host OS */
117
118 if (rgn_desc->common.flags & AOPOBJ_INVALID) {
119 return_ACPI_STATUS(AE_AML_ILLEGAL_ADDRESS);
120 }
121
122 /*
123 * Exit now for SMBus address space, it has a non-linear address space
124 * and the request cannot be directly validated
125 */
126 if (rgn_desc->region.space_id == ACPI_ADR_SPACE_SMBUS) {
127
128 /* SMBus has a non-linear address space */
129
130 return_ACPI_STATUS(AE_OK);
131 }
132#ifdef ACPI_UNDER_DEVELOPMENT
133 /*
134 * If the Field access is any_acc, we can now compute the optimal
135 * access (because we know know the length of the parent region)
136 */
137 if (!(obj_desc->common.flags & AOPOBJ_DATA_VALID)) {
138 if (ACPI_FAILURE(status)) {
139 return_ACPI_STATUS(status);
140 }
141 }
142#endif
143
144 /*
145 * Validate the request. The entire request from the byte offset for a
146 * length of one field datum (access width) must fit within the region.
147 * (Region length is specified in bytes)
148 */
149 if (rgn_desc->region.length <
150 (obj_desc->common_field.base_byte_offset +
151 field_datum_byte_offset +
152 obj_desc->common_field.access_byte_width)) {
153 if (acpi_gbl_enable_interpreter_slack) {
154 /*
155 * Slack mode only: We will go ahead and allow access to this
156 * field if it is within the region length rounded up to the next
157 * access width boundary. acpi_size cast for 64-bit compile.
158 */
159 if (ACPI_ROUND_UP(rgn_desc->region.length,
160 obj_desc->common_field.
161 access_byte_width) >=
162 ((acpi_size) obj_desc->common_field.
163 base_byte_offset +
164 obj_desc->common_field.access_byte_width +
165 field_datum_byte_offset)) {
166 return_ACPI_STATUS(AE_OK);
167 }
168 }
169
170 if (rgn_desc->region.length <
171 obj_desc->common_field.access_byte_width) {
172 /*
173 * This is the case where the access_type (acc_word, etc.) is wider
174 * than the region itself. For example, a region of length one
175 * byte, and a field with Dword access specified.
176 */
177 ACPI_ERROR((AE_INFO,
178 "Field [%4.4s] access width (%d bytes) too large for region [%4.4s] (length %X)",
179 acpi_ut_get_node_name(obj_desc->
180 common_field.node),
181 obj_desc->common_field.access_byte_width,
182 acpi_ut_get_node_name(rgn_desc->region.
183 node),
184 rgn_desc->region.length));
185 }
186
187 /*
188 * Offset rounded up to next multiple of field width
189 * exceeds region length, indicate an error
190 */
191 ACPI_ERROR((AE_INFO,
192 "Field [%4.4s] Base+Offset+Width %X+%X+%X is beyond end of region [%4.4s] (length %X)",
193 acpi_ut_get_node_name(obj_desc->common_field.node),
194 obj_desc->common_field.base_byte_offset,
195 field_datum_byte_offset,
196 obj_desc->common_field.access_byte_width,
197 acpi_ut_get_node_name(rgn_desc->region.node),
198 rgn_desc->region.length));
199
200 return_ACPI_STATUS(AE_AML_REGION_LIMIT);
201 }
202
203 return_ACPI_STATUS(AE_OK);
204}
205
206/*******************************************************************************
207 *
208 * FUNCTION: acpi_ex_access_region
209 *
210 * PARAMETERS: obj_desc - Field to be read
211 * field_datum_byte_offset - Byte offset of this datum within the
212 * parent field
213 * Value - Where to store value (must at least
214 * the size of acpi_integer)
215 * Function - Read or Write flag plus other region-
216 * dependent flags
217 *
218 * RETURN: Status
219 *
220 * DESCRIPTION: Read or Write a single field datum to an Operation Region.
221 *
222 ******************************************************************************/
223
224acpi_status
225acpi_ex_access_region(union acpi_operand_object *obj_desc,
226 u32 field_datum_byte_offset,
227 acpi_integer * value, u32 function)
228{
229 acpi_status status;
230 union acpi_operand_object *rgn_desc;
231 acpi_physical_address address;
232
233 ACPI_FUNCTION_TRACE(ex_access_region);
234
235 /*
236 * Ensure that the region operands are fully evaluated and verify
237 * the validity of the request
238 */
239 status = acpi_ex_setup_region(obj_desc, field_datum_byte_offset);
240 if (ACPI_FAILURE(status)) {
241 return_ACPI_STATUS(status);
242 }
243
244 /*
245 * The physical address of this field datum is:
246 *
247 * 1) The base of the region, plus
248 * 2) The base offset of the field, plus
249 * 3) The current offset into the field
250 */
251 rgn_desc = obj_desc->common_field.region_obj;
252 address = rgn_desc->region.address +
253 obj_desc->common_field.base_byte_offset + field_datum_byte_offset;
254
255 if ((function & ACPI_IO_MASK) == ACPI_READ) {
256 ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, "[READ]"));
257 } else {
258 ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, "[WRITE]"));
259 }
260
261 ACPI_DEBUG_PRINT_RAW((ACPI_DB_BFIELD,
262 " Region [%s:%X], Width %X, ByteBase %X, Offset %X at %p\n",
263 acpi_ut_get_region_name(rgn_desc->region.
264 space_id),
265 rgn_desc->region.space_id,
266 obj_desc->common_field.access_byte_width,
267 obj_desc->common_field.base_byte_offset,
268 field_datum_byte_offset, ACPI_CAST_PTR(void,
269 address)));
270
271 /* Invoke the appropriate address_space/op_region handler */
272
273 status = acpi_ev_address_space_dispatch(rgn_desc, function,
274 address,
275 ACPI_MUL_8(obj_desc->
276 common_field.
277 access_byte_width),
278 value);
279
280 if (ACPI_FAILURE(status)) {
281 if (status == AE_NOT_IMPLEMENTED) {
282 ACPI_ERROR((AE_INFO,
283 "Region %s(%X) not implemented",
284 acpi_ut_get_region_name(rgn_desc->region.
285 space_id),
286 rgn_desc->region.space_id));
287 } else if (status == AE_NOT_EXIST) {
288 ACPI_ERROR((AE_INFO,
289 "Region %s(%X) has no handler",
290 acpi_ut_get_region_name(rgn_desc->region.
291 space_id),
292 rgn_desc->region.space_id));
293 }
294 }
295
296 return_ACPI_STATUS(status);
297}
298
299/*******************************************************************************
300 *
301 * FUNCTION: acpi_ex_register_overflow
302 *
303 * PARAMETERS: obj_desc - Register(Field) to be written
304 * Value - Value to be stored
305 *
306 * RETURN: TRUE if value overflows the field, FALSE otherwise
307 *
308 * DESCRIPTION: Check if a value is out of range of the field being written.
309 * Used to check if the values written to Index and Bank registers
310 * are out of range. Normally, the value is simply truncated
311 * to fit the field, but this case is most likely a serious
312 * coding error in the ASL.
313 *
314 ******************************************************************************/
315
316static u8
317acpi_ex_register_overflow(union acpi_operand_object *obj_desc,
318 acpi_integer value)
319{
320
321 if (obj_desc->common_field.bit_length >= ACPI_INTEGER_BIT_SIZE) {
322 /*
323 * The field is large enough to hold the maximum integer, so we can
324 * never overflow it.
325 */
326 return (FALSE);
327 }
328
329 if (value >= ((acpi_integer) 1 << obj_desc->common_field.bit_length)) {
330 /*
331 * The Value is larger than the maximum value that can fit into
332 * the register.
333 */
334 return (TRUE);
335 }
336
337 /* The Value will fit into the field with no truncation */
338
339 return (FALSE);
340}
341
342/*******************************************************************************
343 *
344 * FUNCTION: acpi_ex_field_datum_io
345 *
346 * PARAMETERS: obj_desc - Field to be read
347 * field_datum_byte_offset - Byte offset of this datum within the
348 * parent field
349 * Value - Where to store value (must be 64 bits)
350 * read_write - Read or Write flag
351 *
352 * RETURN: Status
353 *
354 * DESCRIPTION: Read or Write a single datum of a field. The field_type is
355 * demultiplexed here to handle the different types of fields
356 * (buffer_field, region_field, index_field, bank_field)
357 *
358 ******************************************************************************/
359
360static acpi_status
361acpi_ex_field_datum_io(union acpi_operand_object *obj_desc,
362 u32 field_datum_byte_offset,
363 acpi_integer * value, u32 read_write)
364{
365 acpi_status status;
366 acpi_integer local_value;
367
368 ACPI_FUNCTION_TRACE_U32(ex_field_datum_io, field_datum_byte_offset);
369
370 if (read_write == ACPI_READ) {
371 if (!value) {
372 local_value = 0;
373
374 /* To support reads without saving return value */
375 value = &local_value;
376 }
377
378 /* Clear the entire return buffer first, [Very Important!] */
379
380 *value = 0;
381 }
382
383 /*
384 * The four types of fields are:
385 *
386 * buffer_field - Read/write from/to a Buffer
387 * region_field - Read/write from/to a Operation Region.
388 * bank_field - Write to a Bank Register, then read/write from/to an
389 * operation_region
390 * index_field - Write to an Index Register, then read/write from/to a
391 * Data Register
392 */
393 switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
394 case ACPI_TYPE_BUFFER_FIELD:
395 /*
396 * If the buffer_field arguments have not been previously evaluated,
397 * evaluate them now and save the results.
398 */
399 if (!(obj_desc->common.flags & AOPOBJ_DATA_VALID)) {
400 status = acpi_ds_get_buffer_field_arguments(obj_desc);
401 if (ACPI_FAILURE(status)) {
402 return_ACPI_STATUS(status);
403 }
404 }
405
406 if (read_write == ACPI_READ) {
407 /*
408 * Copy the data from the source buffer.
409 * Length is the field width in bytes.
410 */
411 ACPI_MEMCPY(value,
412 (obj_desc->buffer_field.buffer_obj)->buffer.
413 pointer +
414 obj_desc->buffer_field.base_byte_offset +
415 field_datum_byte_offset,
416 obj_desc->common_field.access_byte_width);
417 } else {
418 /*
419 * Copy the data to the target buffer.
420 * Length is the field width in bytes.
421 */
422 ACPI_MEMCPY((obj_desc->buffer_field.buffer_obj)->buffer.
423 pointer +
424 obj_desc->buffer_field.base_byte_offset +
425 field_datum_byte_offset, value,
426 obj_desc->common_field.access_byte_width);
427 }
428
429 status = AE_OK;
430 break;
431
432 case ACPI_TYPE_LOCAL_BANK_FIELD:
433
434 /*
435 * Ensure that the bank_value is not beyond the capacity of
436 * the register
437 */
438 if (acpi_ex_register_overflow(obj_desc->bank_field.bank_obj,
439 (acpi_integer) obj_desc->
440 bank_field.value)) {
441 return_ACPI_STATUS(AE_AML_REGISTER_LIMIT);
442 }
443
444 /*
445 * For bank_fields, we must write the bank_value to the bank_register
446 * (itself a region_field) before we can access the data.
447 */
448 status =
449 acpi_ex_insert_into_field(obj_desc->bank_field.bank_obj,
450 &obj_desc->bank_field.value,
451 sizeof(obj_desc->bank_field.
452 value));
453 if (ACPI_FAILURE(status)) {
454 return_ACPI_STATUS(status);
455 }
456
457 /*
458 * Now that the Bank has been selected, fall through to the
459 * region_field case and write the datum to the Operation Region
460 */
461
462 /*lint -fallthrough */
463
464 case ACPI_TYPE_LOCAL_REGION_FIELD:
465 /*
466 * For simple region_fields, we just directly access the owning
467 * Operation Region.
468 */
469 status =
470 acpi_ex_access_region(obj_desc, field_datum_byte_offset,
471 value, read_write);
472 break;
473
474 case ACPI_TYPE_LOCAL_INDEX_FIELD:
475
476 /*
477 * Ensure that the index_value is not beyond the capacity of
478 * the register
479 */
480 if (acpi_ex_register_overflow(obj_desc->index_field.index_obj,
481 (acpi_integer) obj_desc->
482 index_field.value)) {
483 return_ACPI_STATUS(AE_AML_REGISTER_LIMIT);
484 }
485
486 /* Write the index value to the index_register (itself a region_field) */
487
488 field_datum_byte_offset += obj_desc->index_field.value;
489
490 ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
491 "Write to Index Register: Value %8.8X\n",
492 field_datum_byte_offset));
493
494 status =
495 acpi_ex_insert_into_field(obj_desc->index_field.index_obj,
496 &field_datum_byte_offset,
497 sizeof(field_datum_byte_offset));
498 if (ACPI_FAILURE(status)) {
499 return_ACPI_STATUS(status);
500 }
501
502 if (read_write == ACPI_READ) {
503
504 /* Read the datum from the data_register */
505
506 ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
507 "Read from Data Register\n"));
508
509 status =
510 acpi_ex_extract_from_field(obj_desc->index_field.
511 data_obj, value,
512 sizeof(acpi_integer));
513 } else {
514 /* Write the datum to the data_register */
515
516 ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
517 "Write to Data Register: Value %8.8X%8.8X\n",
518 ACPI_FORMAT_UINT64(*value)));
519
520 status =
521 acpi_ex_insert_into_field(obj_desc->index_field.
522 data_obj, value,
523 sizeof(acpi_integer));
524 }
525 break;
526
527 default:
528
529 ACPI_ERROR((AE_INFO, "Wrong object type in field I/O %X",
530 ACPI_GET_OBJECT_TYPE(obj_desc)));
531 status = AE_AML_INTERNAL;
532 break;
533 }
534
535 if (ACPI_SUCCESS(status)) {
536 if (read_write == ACPI_READ) {
537 ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
538 "Value Read %8.8X%8.8X, Width %d\n",
539 ACPI_FORMAT_UINT64(*value),
540 obj_desc->common_field.
541 access_byte_width));
542 } else {
543 ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
544 "Value Written %8.8X%8.8X, Width %d\n",
545 ACPI_FORMAT_UINT64(*value),
546 obj_desc->common_field.
547 access_byte_width));
548 }
549 }
550
551 return_ACPI_STATUS(status);
552}
553
554/*******************************************************************************
555 *
556 * FUNCTION: acpi_ex_write_with_update_rule
557 *
558 * PARAMETERS: obj_desc - Field to be written
559 * Mask - bitmask within field datum
560 * field_value - Value to write
561 * field_datum_byte_offset - Offset of datum within field
562 *
563 * RETURN: Status
564 *
565 * DESCRIPTION: Apply the field update rule to a field write
566 *
567 ******************************************************************************/
568
569acpi_status
570acpi_ex_write_with_update_rule(union acpi_operand_object *obj_desc,
571 acpi_integer mask,
572 acpi_integer field_value,
573 u32 field_datum_byte_offset)
574{
575 acpi_status status = AE_OK;
576 acpi_integer merged_value;
577 acpi_integer current_value;
578
579 ACPI_FUNCTION_TRACE_U32(ex_write_with_update_rule, mask);
580
581 /* Start with the new bits */
582
583 merged_value = field_value;
584
585 /* If the mask is all ones, we don't need to worry about the update rule */
586
587 if (mask != ACPI_INTEGER_MAX) {
588
589 /* Decode the update rule */
590
591 switch (obj_desc->common_field.
592 field_flags & AML_FIELD_UPDATE_RULE_MASK) {
593 case AML_FIELD_UPDATE_PRESERVE:
594 /*
595 * Check if update rule needs to be applied (not if mask is all
596 * ones) The left shift drops the bits we want to ignore.
597 */
598 if ((~mask << (ACPI_MUL_8(sizeof(mask)) -
599 ACPI_MUL_8(obj_desc->common_field.
600 access_byte_width))) != 0) {
601 /*
602 * Read the current contents of the byte/word/dword containing
603 * the field, and merge with the new field value.
604 */
605 status =
606 acpi_ex_field_datum_io(obj_desc,
607 field_datum_byte_offset,
608 &current_value,
609 ACPI_READ);
610 if (ACPI_FAILURE(status)) {
611 return_ACPI_STATUS(status);
612 }
613
614 merged_value |= (current_value & ~mask);
615 }
616 break;
617
618 case AML_FIELD_UPDATE_WRITE_AS_ONES:
619
620 /* Set positions outside the field to all ones */
621
622 merged_value |= ~mask;
623 break;
624
625 case AML_FIELD_UPDATE_WRITE_AS_ZEROS:
626
627 /* Set positions outside the field to all zeros */
628
629 merged_value &= mask;
630 break;
631
632 default:
633
634 ACPI_ERROR((AE_INFO,
635 "Unknown UpdateRule value: %X",
636 (obj_desc->common_field.
637 field_flags &
638 AML_FIELD_UPDATE_RULE_MASK)));
639 return_ACPI_STATUS(AE_AML_OPERAND_VALUE);
640 }
641 }
642
643 ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
644 "Mask %8.8X%8.8X, DatumOffset %X, Width %X, Value %8.8X%8.8X, MergedValue %8.8X%8.8X\n",
645 ACPI_FORMAT_UINT64(mask),
646 field_datum_byte_offset,
647 obj_desc->common_field.access_byte_width,
648 ACPI_FORMAT_UINT64(field_value),
649 ACPI_FORMAT_UINT64(merged_value)));
650
651 /* Write the merged value */
652
653 status = acpi_ex_field_datum_io(obj_desc, field_datum_byte_offset,
654 &merged_value, ACPI_WRITE);
655
656 return_ACPI_STATUS(status);
657}
658
659/*******************************************************************************
660 *
661 * FUNCTION: acpi_ex_extract_from_field
662 *
663 * PARAMETERS: obj_desc - Field to be read
664 * Buffer - Where to store the field data
665 * buffer_length - Length of Buffer
666 *
667 * RETURN: Status
668 *
669 * DESCRIPTION: Retrieve the current value of the given field
670 *
671 ******************************************************************************/
672
673acpi_status
674acpi_ex_extract_from_field(union acpi_operand_object *obj_desc,
675 void *buffer, u32 buffer_length)
676{
677 acpi_status status;
678 acpi_integer raw_datum;
679 acpi_integer merged_datum;
680 u32 field_offset = 0;
681 u32 buffer_offset = 0;
682 u32 buffer_tail_bits;
683 u32 datum_count;
684 u32 field_datum_count;
685 u32 i;
686
687 ACPI_FUNCTION_TRACE(ex_extract_from_field);
688
689 /* Validate target buffer and clear it */
690
691 if (buffer_length <
692 ACPI_ROUND_BITS_UP_TO_BYTES(obj_desc->common_field.bit_length)) {
693 ACPI_ERROR((AE_INFO,
694 "Field size %X (bits) is too large for buffer (%X)",
695 obj_desc->common_field.bit_length, buffer_length));
696
697 return_ACPI_STATUS(AE_BUFFER_OVERFLOW);
698 }
699 ACPI_MEMSET(buffer, 0, buffer_length);
700
701 /* Compute the number of datums (access width data items) */
702
703 datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length,
704 obj_desc->common_field.access_bit_width);
705 field_datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length +
706 obj_desc->common_field.
707 start_field_bit_offset,
708 obj_desc->common_field.
709 access_bit_width);
710
711 /* Priming read from the field */
712
713 status =
714 acpi_ex_field_datum_io(obj_desc, field_offset, &raw_datum,
715 ACPI_READ);
716 if (ACPI_FAILURE(status)) {
717 return_ACPI_STATUS(status);
718 }
719 merged_datum =
720 raw_datum >> obj_desc->common_field.start_field_bit_offset;
721
722 /* Read the rest of the field */
723
724 for (i = 1; i < field_datum_count; i++) {
725
726 /* Get next input datum from the field */
727
728 field_offset += obj_desc->common_field.access_byte_width;
729 status = acpi_ex_field_datum_io(obj_desc, field_offset,
730 &raw_datum, ACPI_READ);
731 if (ACPI_FAILURE(status)) {
732 return_ACPI_STATUS(status);
733 }
734
735 /*
736 * Merge with previous datum if necessary.
737 *
738 * Note: Before the shift, check if the shift value will be larger than
739 * the integer size. If so, there is no need to perform the operation.
740 * This avoids the differences in behavior between different compilers
741 * concerning shift values larger than the target data width.
742 */
743 if ((obj_desc->common_field.access_bit_width -
744 obj_desc->common_field.start_field_bit_offset) <
745 ACPI_INTEGER_BIT_SIZE) {
746 merged_datum |=
747 raw_datum << (obj_desc->common_field.
748 access_bit_width -
749 obj_desc->common_field.
750 start_field_bit_offset);
751 }
752
753 if (i == datum_count) {
754 break;
755 }
756
757 /* Write merged datum to target buffer */
758
759 ACPI_MEMCPY(((char *)buffer) + buffer_offset, &merged_datum,
760 ACPI_MIN(obj_desc->common_field.access_byte_width,
761 buffer_length - buffer_offset));
762
763 buffer_offset += obj_desc->common_field.access_byte_width;
764 merged_datum =
765 raw_datum >> obj_desc->common_field.start_field_bit_offset;
766 }
767
768 /* Mask off any extra bits in the last datum */
769
770 buffer_tail_bits = obj_desc->common_field.bit_length %
771 obj_desc->common_field.access_bit_width;
772 if (buffer_tail_bits) {
773 merged_datum &= ACPI_MASK_BITS_ABOVE(buffer_tail_bits);
774 }
775
776 /* Write the last datum to the buffer */
777
778 ACPI_MEMCPY(((char *)buffer) + buffer_offset, &merged_datum,
779 ACPI_MIN(obj_desc->common_field.access_byte_width,
780 buffer_length - buffer_offset));
781
782 return_ACPI_STATUS(AE_OK);
783}
784
785/*******************************************************************************
786 *
787 * FUNCTION: acpi_ex_insert_into_field
788 *
789 * PARAMETERS: obj_desc - Field to be written
790 * Buffer - Data to be written
791 * buffer_length - Length of Buffer
792 *
793 * RETURN: Status
794 *
795 * DESCRIPTION: Store the Buffer contents into the given field
796 *
797 ******************************************************************************/
798
799acpi_status
800acpi_ex_insert_into_field(union acpi_operand_object *obj_desc,
801 void *buffer, u32 buffer_length)
802{
803 acpi_status status;
804 acpi_integer mask;
805 acpi_integer width_mask;
806 acpi_integer merged_datum;
807 acpi_integer raw_datum = 0;
808 u32 field_offset = 0;
809 u32 buffer_offset = 0;
810 u32 buffer_tail_bits;
811 u32 datum_count;
812 u32 field_datum_count;
813 u32 i;
814 u32 required_length;
815 void *new_buffer;
816
817 ACPI_FUNCTION_TRACE(ex_insert_into_field);
818
819 /* Validate input buffer */
820
821 new_buffer = NULL;
822 required_length =
823 ACPI_ROUND_BITS_UP_TO_BYTES(obj_desc->common_field.bit_length);
824 /*
825 * We must have a buffer that is at least as long as the field
826 * we are writing to. This is because individual fields are
827 * indivisible and partial writes are not supported -- as per
828 * the ACPI specification.
829 */
830 if (buffer_length < required_length) {
831
832 /* We need to create a new buffer */
833
834 new_buffer = ACPI_ALLOCATE_ZEROED(required_length);
835 if (!new_buffer) {
836 return_ACPI_STATUS(AE_NO_MEMORY);
837 }
838
839 /*
840 * Copy the original data to the new buffer, starting
841 * at Byte zero. All unused (upper) bytes of the
842 * buffer will be 0.
843 */
844 ACPI_MEMCPY((char *)new_buffer, (char *)buffer, buffer_length);
845 buffer = new_buffer;
846 buffer_length = required_length;
847 }
848
849 /*
850 * Create the bitmasks used for bit insertion.
851 * Note: This if/else is used to bypass compiler differences with the
852 * shift operator
853 */
854 if (obj_desc->common_field.access_bit_width == ACPI_INTEGER_BIT_SIZE) {
855 width_mask = ACPI_INTEGER_MAX;
856 } else {
857 width_mask =
858 ACPI_MASK_BITS_ABOVE(obj_desc->common_field.
859 access_bit_width);
860 }
861
862 mask = width_mask &
863 ACPI_MASK_BITS_BELOW(obj_desc->common_field.start_field_bit_offset);
864
865 /* Compute the number of datums (access width data items) */
866
867 datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length,
868 obj_desc->common_field.access_bit_width);
869
870 field_datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length +
871 obj_desc->common_field.
872 start_field_bit_offset,
873 obj_desc->common_field.
874 access_bit_width);
875
876 /* Get initial Datum from the input buffer */
877
878 ACPI_MEMCPY(&raw_datum, buffer,
879 ACPI_MIN(obj_desc->common_field.access_byte_width,
880 buffer_length - buffer_offset));
881
882 merged_datum =
883 raw_datum << obj_desc->common_field.start_field_bit_offset;
884
885 /* Write the entire field */
886
887 for (i = 1; i < field_datum_count; i++) {
888
889 /* Write merged datum to the target field */
890
891 merged_datum &= mask;
892 status = acpi_ex_write_with_update_rule(obj_desc, mask,
893 merged_datum,
894 field_offset);
895 if (ACPI_FAILURE(status)) {
896 goto exit;
897 }
898
899 field_offset += obj_desc->common_field.access_byte_width;
900
901 /*
902 * Start new output datum by merging with previous input datum
903 * if necessary.
904 *
905 * Note: Before the shift, check if the shift value will be larger than
906 * the integer size. If so, there is no need to perform the operation.
907 * This avoids the differences in behavior between different compilers
908 * concerning shift values larger than the target data width.
909 */
910 if ((obj_desc->common_field.access_bit_width -
911 obj_desc->common_field.start_field_bit_offset) <
912 ACPI_INTEGER_BIT_SIZE) {
913 merged_datum =
914 raw_datum >> (obj_desc->common_field.
915 access_bit_width -
916 obj_desc->common_field.
917 start_field_bit_offset);
918 } else {
919 merged_datum = 0;
920 }
921
922 mask = width_mask;
923
924 if (i == datum_count) {
925 break;
926 }
927
928 /* Get the next input datum from the buffer */
929
930 buffer_offset += obj_desc->common_field.access_byte_width;
931 ACPI_MEMCPY(&raw_datum, ((char *)buffer) + buffer_offset,
932 ACPI_MIN(obj_desc->common_field.access_byte_width,
933 buffer_length - buffer_offset));
934 merged_datum |=
935 raw_datum << obj_desc->common_field.start_field_bit_offset;
936 }
937
938 /* Mask off any extra bits in the last datum */
939
940 buffer_tail_bits = (obj_desc->common_field.bit_length +
941 obj_desc->common_field.start_field_bit_offset) %
942 obj_desc->common_field.access_bit_width;
943 if (buffer_tail_bits) {
944 mask &= ACPI_MASK_BITS_ABOVE(buffer_tail_bits);
945 }
946
947 /* Write the last datum to the field */
948
949 merged_datum &= mask;
950 status = acpi_ex_write_with_update_rule(obj_desc,
951 mask, merged_datum,
952 field_offset);
953
954 exit:
955 /* Free temporary buffer if we used one */
956
957 if (new_buffer) {
958 ACPI_FREE(new_buffer);
959 }
960 return_ACPI_STATUS(status);
961}
diff --git a/drivers/acpi/acpica/exmisc.c b/drivers/acpi/acpica/exmisc.c
new file mode 100644
index 00000000000..e445463de8a
--- /dev/null
+++ b/drivers/acpi/acpica/exmisc.c
@@ -0,0 +1,726 @@
1
2/******************************************************************************
3 *
4 * Module Name: exmisc - ACPI AML (p-code) execution - specific opcodes
5 *
6 *****************************************************************************/
7
8/*
9 * Copyright (C) 2000 - 2008, Intel Corp.
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions, and the following disclaimer,
17 * without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 * substantially similar to the "NO WARRANTY" disclaimer below
20 * ("Disclaimer") and any redistribution must be conditioned upon
21 * including a substantially similar Disclaimer requirement for further
22 * binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 * of any contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
30 *
31 * NO WARRANTY
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
43 */
44
45#include <acpi/acpi.h>
46#include <acpi/accommon.h>
47#include <acpi/acinterp.h>
48#include <acpi/amlcode.h>
49#include <acpi/amlresrc.h>
50
51#define _COMPONENT ACPI_EXECUTER
52ACPI_MODULE_NAME("exmisc")
53
54/*******************************************************************************
55 *
56 * FUNCTION: acpi_ex_get_object_reference
57 *
58 * PARAMETERS: obj_desc - Create a reference to this object
59 * return_desc - Where to store the reference
60 * walk_state - Current state
61 *
62 * RETURN: Status
63 *
64 * DESCRIPTION: Obtain and return a "reference" to the target object
65 * Common code for the ref_of_op and the cond_ref_of_op.
66 *
67 ******************************************************************************/
68acpi_status
69acpi_ex_get_object_reference(union acpi_operand_object *obj_desc,
70 union acpi_operand_object **return_desc,
71 struct acpi_walk_state *walk_state)
72{
73 union acpi_operand_object *reference_obj;
74 union acpi_operand_object *referenced_obj;
75
76 ACPI_FUNCTION_TRACE_PTR(ex_get_object_reference, obj_desc);
77
78 *return_desc = NULL;
79
80 switch (ACPI_GET_DESCRIPTOR_TYPE(obj_desc)) {
81 case ACPI_DESC_TYPE_OPERAND:
82
83 if (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_LOCAL_REFERENCE) {
84 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
85 }
86
87 /*
88 * Must be a reference to a Local or Arg
89 */
90 switch (obj_desc->reference.class) {
91 case ACPI_REFCLASS_LOCAL:
92 case ACPI_REFCLASS_ARG:
93 case ACPI_REFCLASS_DEBUG:
94
95 /* The referenced object is the pseudo-node for the local/arg */
96
97 referenced_obj = obj_desc->reference.object;
98 break;
99
100 default:
101
102 ACPI_ERROR((AE_INFO, "Unknown Reference Class %2.2X",
103 obj_desc->reference.class));
104 return_ACPI_STATUS(AE_AML_INTERNAL);
105 }
106 break;
107
108 case ACPI_DESC_TYPE_NAMED:
109
110 /*
111 * A named reference that has already been resolved to a Node
112 */
113 referenced_obj = obj_desc;
114 break;
115
116 default:
117
118 ACPI_ERROR((AE_INFO, "Invalid descriptor type %X",
119 ACPI_GET_DESCRIPTOR_TYPE(obj_desc)));
120 return_ACPI_STATUS(AE_TYPE);
121 }
122
123 /* Create a new reference object */
124
125 reference_obj =
126 acpi_ut_create_internal_object(ACPI_TYPE_LOCAL_REFERENCE);
127 if (!reference_obj) {
128 return_ACPI_STATUS(AE_NO_MEMORY);
129 }
130
131 reference_obj->reference.class = ACPI_REFCLASS_REFOF;
132 reference_obj->reference.object = referenced_obj;
133 *return_desc = reference_obj;
134
135 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
136 "Object %p Type [%s], returning Reference %p\n",
137 obj_desc, acpi_ut_get_object_type_name(obj_desc),
138 *return_desc));
139
140 return_ACPI_STATUS(AE_OK);
141}
142
143/*******************************************************************************
144 *
145 * FUNCTION: acpi_ex_concat_template
146 *
147 * PARAMETERS: Operand0 - First source object
148 * Operand1 - Second source object
149 * actual_return_desc - Where to place the return object
150 * walk_state - Current walk state
151 *
152 * RETURN: Status
153 *
154 * DESCRIPTION: Concatenate two resource templates
155 *
156 ******************************************************************************/
157
158acpi_status
159acpi_ex_concat_template(union acpi_operand_object *operand0,
160 union acpi_operand_object *operand1,
161 union acpi_operand_object **actual_return_desc,
162 struct acpi_walk_state *walk_state)
163{
164 acpi_status status;
165 union acpi_operand_object *return_desc;
166 u8 *new_buf;
167 u8 *end_tag;
168 acpi_size length0;
169 acpi_size length1;
170 acpi_size new_length;
171
172 ACPI_FUNCTION_TRACE(ex_concat_template);
173
174 /*
175 * Find the end_tag descriptor in each resource template.
176 * Note1: returned pointers point TO the end_tag, not past it.
177 * Note2: zero-length buffers are allowed; treated like one end_tag
178 */
179
180 /* Get the length of the first resource template */
181
182 status = acpi_ut_get_resource_end_tag(operand0, &end_tag);
183 if (ACPI_FAILURE(status)) {
184 return_ACPI_STATUS(status);
185 }
186
187 length0 = ACPI_PTR_DIFF(end_tag, operand0->buffer.pointer);
188
189 /* Get the length of the second resource template */
190
191 status = acpi_ut_get_resource_end_tag(operand1, &end_tag);
192 if (ACPI_FAILURE(status)) {
193 return_ACPI_STATUS(status);
194 }
195
196 length1 = ACPI_PTR_DIFF(end_tag, operand1->buffer.pointer);
197
198 /* Combine both lengths, minimum size will be 2 for end_tag */
199
200 new_length = length0 + length1 + sizeof(struct aml_resource_end_tag);
201
202 /* Create a new buffer object for the result (with one end_tag) */
203
204 return_desc = acpi_ut_create_buffer_object(new_length);
205 if (!return_desc) {
206 return_ACPI_STATUS(AE_NO_MEMORY);
207 }
208
209 /*
210 * Copy the templates to the new buffer, 0 first, then 1 follows. One
211 * end_tag descriptor is copied from Operand1.
212 */
213 new_buf = return_desc->buffer.pointer;
214 ACPI_MEMCPY(new_buf, operand0->buffer.pointer, length0);
215 ACPI_MEMCPY(new_buf + length0, operand1->buffer.pointer, length1);
216
217 /* Insert end_tag and set the checksum to zero, means "ignore checksum" */
218
219 new_buf[new_length - 1] = 0;
220 new_buf[new_length - 2] = ACPI_RESOURCE_NAME_END_TAG | 1;
221
222 /* Return the completed resource template */
223
224 *actual_return_desc = return_desc;
225 return_ACPI_STATUS(AE_OK);
226}
227
228/*******************************************************************************
229 *
230 * FUNCTION: acpi_ex_do_concatenate
231 *
232 * PARAMETERS: Operand0 - First source object
233 * Operand1 - Second source object
234 * actual_return_desc - Where to place the return object
235 * walk_state - Current walk state
236 *
237 * RETURN: Status
238 *
239 * DESCRIPTION: Concatenate two objects OF THE SAME TYPE.
240 *
241 ******************************************************************************/
242
243acpi_status
244acpi_ex_do_concatenate(union acpi_operand_object *operand0,
245 union acpi_operand_object *operand1,
246 union acpi_operand_object **actual_return_desc,
247 struct acpi_walk_state *walk_state)
248{
249 union acpi_operand_object *local_operand1 = operand1;
250 union acpi_operand_object *return_desc;
251 char *new_buf;
252 acpi_status status;
253
254 ACPI_FUNCTION_TRACE(ex_do_concatenate);
255
256 /*
257 * Convert the second operand if necessary. The first operand
258 * determines the type of the second operand, (See the Data Types
259 * section of the ACPI specification.) Both object types are
260 * guaranteed to be either Integer/String/Buffer by the operand
261 * resolution mechanism.
262 */
263 switch (ACPI_GET_OBJECT_TYPE(operand0)) {
264 case ACPI_TYPE_INTEGER:
265 status =
266 acpi_ex_convert_to_integer(operand1, &local_operand1, 16);
267 break;
268
269 case ACPI_TYPE_STRING:
270 status = acpi_ex_convert_to_string(operand1, &local_operand1,
271 ACPI_IMPLICIT_CONVERT_HEX);
272 break;
273
274 case ACPI_TYPE_BUFFER:
275 status = acpi_ex_convert_to_buffer(operand1, &local_operand1);
276 break;
277
278 default:
279 ACPI_ERROR((AE_INFO, "Invalid object type: %X",
280 ACPI_GET_OBJECT_TYPE(operand0)));
281 status = AE_AML_INTERNAL;
282 }
283
284 if (ACPI_FAILURE(status)) {
285 goto cleanup;
286 }
287
288 /*
289 * Both operands are now known to be the same object type
290 * (Both are Integer, String, or Buffer), and we can now perform the
291 * concatenation.
292 */
293
294 /*
295 * There are three cases to handle:
296 *
297 * 1) Two Integers concatenated to produce a new Buffer
298 * 2) Two Strings concatenated to produce a new String
299 * 3) Two Buffers concatenated to produce a new Buffer
300 */
301 switch (ACPI_GET_OBJECT_TYPE(operand0)) {
302 case ACPI_TYPE_INTEGER:
303
304 /* Result of two Integers is a Buffer */
305 /* Need enough buffer space for two integers */
306
307 return_desc = acpi_ut_create_buffer_object((acpi_size)
308 ACPI_MUL_2
309 (acpi_gbl_integer_byte_width));
310 if (!return_desc) {
311 status = AE_NO_MEMORY;
312 goto cleanup;
313 }
314
315 new_buf = (char *)return_desc->buffer.pointer;
316
317 /* Copy the first integer, LSB first */
318
319 ACPI_MEMCPY(new_buf, &operand0->integer.value,
320 acpi_gbl_integer_byte_width);
321
322 /* Copy the second integer (LSB first) after the first */
323
324 ACPI_MEMCPY(new_buf + acpi_gbl_integer_byte_width,
325 &local_operand1->integer.value,
326 acpi_gbl_integer_byte_width);
327 break;
328
329 case ACPI_TYPE_STRING:
330
331 /* Result of two Strings is a String */
332
333 return_desc = acpi_ut_create_string_object(((acpi_size)
334 operand0->string.
335 length +
336 local_operand1->
337 string.length));
338 if (!return_desc) {
339 status = AE_NO_MEMORY;
340 goto cleanup;
341 }
342
343 new_buf = return_desc->string.pointer;
344
345 /* Concatenate the strings */
346
347 ACPI_STRCPY(new_buf, operand0->string.pointer);
348 ACPI_STRCPY(new_buf + operand0->string.length,
349 local_operand1->string.pointer);
350 break;
351
352 case ACPI_TYPE_BUFFER:
353
354 /* Result of two Buffers is a Buffer */
355
356 return_desc = acpi_ut_create_buffer_object(((acpi_size)
357 operand0->buffer.
358 length +
359 local_operand1->
360 buffer.length));
361 if (!return_desc) {
362 status = AE_NO_MEMORY;
363 goto cleanup;
364 }
365
366 new_buf = (char *)return_desc->buffer.pointer;
367
368 /* Concatenate the buffers */
369
370 ACPI_MEMCPY(new_buf, operand0->buffer.pointer,
371 operand0->buffer.length);
372 ACPI_MEMCPY(new_buf + operand0->buffer.length,
373 local_operand1->buffer.pointer,
374 local_operand1->buffer.length);
375 break;
376
377 default:
378
379 /* Invalid object type, should not happen here */
380
381 ACPI_ERROR((AE_INFO, "Invalid object type: %X",
382 ACPI_GET_OBJECT_TYPE(operand0)));
383 status = AE_AML_INTERNAL;
384 goto cleanup;
385 }
386
387 *actual_return_desc = return_desc;
388
389 cleanup:
390 if (local_operand1 != operand1) {
391 acpi_ut_remove_reference(local_operand1);
392 }
393 return_ACPI_STATUS(status);
394}
395
396/*******************************************************************************
397 *
398 * FUNCTION: acpi_ex_do_math_op
399 *
400 * PARAMETERS: Opcode - AML opcode
401 * Integer0 - Integer operand #0
402 * Integer1 - Integer operand #1
403 *
404 * RETURN: Integer result of the operation
405 *
406 * DESCRIPTION: Execute a math AML opcode. The purpose of having all of the
407 * math functions here is to prevent a lot of pointer dereferencing
408 * to obtain the operands.
409 *
410 ******************************************************************************/
411
412acpi_integer
413acpi_ex_do_math_op(u16 opcode, acpi_integer integer0, acpi_integer integer1)
414{
415
416 ACPI_FUNCTION_ENTRY();
417
418 switch (opcode) {
419 case AML_ADD_OP: /* Add (Integer0, Integer1, Result) */
420
421 return (integer0 + integer1);
422
423 case AML_BIT_AND_OP: /* And (Integer0, Integer1, Result) */
424
425 return (integer0 & integer1);
426
427 case AML_BIT_NAND_OP: /* NAnd (Integer0, Integer1, Result) */
428
429 return (~(integer0 & integer1));
430
431 case AML_BIT_OR_OP: /* Or (Integer0, Integer1, Result) */
432
433 return (integer0 | integer1);
434
435 case AML_BIT_NOR_OP: /* NOr (Integer0, Integer1, Result) */
436
437 return (~(integer0 | integer1));
438
439 case AML_BIT_XOR_OP: /* XOr (Integer0, Integer1, Result) */
440
441 return (integer0 ^ integer1);
442
443 case AML_MULTIPLY_OP: /* Multiply (Integer0, Integer1, Result) */
444
445 return (integer0 * integer1);
446
447 case AML_SHIFT_LEFT_OP: /* shift_left (Operand, shift_count, Result) */
448
449 /*
450 * We need to check if the shiftcount is larger than the integer bit
451 * width since the behavior of this is not well-defined in the C language.
452 */
453 if (integer1 >= acpi_gbl_integer_bit_width) {
454 return (0);
455 }
456 return (integer0 << integer1);
457
458 case AML_SHIFT_RIGHT_OP: /* shift_right (Operand, shift_count, Result) */
459
460 /*
461 * We need to check if the shiftcount is larger than the integer bit
462 * width since the behavior of this is not well-defined in the C language.
463 */
464 if (integer1 >= acpi_gbl_integer_bit_width) {
465 return (0);
466 }
467 return (integer0 >> integer1);
468
469 case AML_SUBTRACT_OP: /* Subtract (Integer0, Integer1, Result) */
470
471 return (integer0 - integer1);
472
473 default:
474
475 return (0);
476 }
477}
478
479/*******************************************************************************
480 *
481 * FUNCTION: acpi_ex_do_logical_numeric_op
482 *
483 * PARAMETERS: Opcode - AML opcode
484 * Integer0 - Integer operand #0
485 * Integer1 - Integer operand #1
486 * logical_result - TRUE/FALSE result of the operation
487 *
488 * RETURN: Status
489 *
490 * DESCRIPTION: Execute a logical "Numeric" AML opcode. For these Numeric
491 * operators (LAnd and LOr), both operands must be integers.
492 *
493 * Note: cleanest machine code seems to be produced by the code
494 * below, rather than using statements of the form:
495 * Result = (Integer0 && Integer1);
496 *
497 ******************************************************************************/
498
499acpi_status
500acpi_ex_do_logical_numeric_op(u16 opcode,
501 acpi_integer integer0,
502 acpi_integer integer1, u8 * logical_result)
503{
504 acpi_status status = AE_OK;
505 u8 local_result = FALSE;
506
507 ACPI_FUNCTION_TRACE(ex_do_logical_numeric_op);
508
509 switch (opcode) {
510 case AML_LAND_OP: /* LAnd (Integer0, Integer1) */
511
512 if (integer0 && integer1) {
513 local_result = TRUE;
514 }
515 break;
516
517 case AML_LOR_OP: /* LOr (Integer0, Integer1) */
518
519 if (integer0 || integer1) {
520 local_result = TRUE;
521 }
522 break;
523
524 default:
525 status = AE_AML_INTERNAL;
526 break;
527 }
528
529 /* Return the logical result and status */
530
531 *logical_result = local_result;
532 return_ACPI_STATUS(status);
533}
534
535/*******************************************************************************
536 *
537 * FUNCTION: acpi_ex_do_logical_op
538 *
539 * PARAMETERS: Opcode - AML opcode
540 * Operand0 - operand #0
541 * Operand1 - operand #1
542 * logical_result - TRUE/FALSE result of the operation
543 *
544 * RETURN: Status
545 *
546 * DESCRIPTION: Execute a logical AML opcode. The purpose of having all of the
547 * functions here is to prevent a lot of pointer dereferencing
548 * to obtain the operands and to simplify the generation of the
549 * logical value. For the Numeric operators (LAnd and LOr), both
550 * operands must be integers. For the other logical operators,
551 * operands can be any combination of Integer/String/Buffer. The
552 * first operand determines the type to which the second operand
553 * will be converted.
554 *
555 * Note: cleanest machine code seems to be produced by the code
556 * below, rather than using statements of the form:
557 * Result = (Operand0 == Operand1);
558 *
559 ******************************************************************************/
560
561acpi_status
562acpi_ex_do_logical_op(u16 opcode,
563 union acpi_operand_object *operand0,
564 union acpi_operand_object *operand1, u8 * logical_result)
565{
566 union acpi_operand_object *local_operand1 = operand1;
567 acpi_integer integer0;
568 acpi_integer integer1;
569 u32 length0;
570 u32 length1;
571 acpi_status status = AE_OK;
572 u8 local_result = FALSE;
573 int compare;
574
575 ACPI_FUNCTION_TRACE(ex_do_logical_op);
576
577 /*
578 * Convert the second operand if necessary. The first operand
579 * determines the type of the second operand, (See the Data Types
580 * section of the ACPI 3.0+ specification.) Both object types are
581 * guaranteed to be either Integer/String/Buffer by the operand
582 * resolution mechanism.
583 */
584 switch (ACPI_GET_OBJECT_TYPE(operand0)) {
585 case ACPI_TYPE_INTEGER:
586 status =
587 acpi_ex_convert_to_integer(operand1, &local_operand1, 16);
588 break;
589
590 case ACPI_TYPE_STRING:
591 status = acpi_ex_convert_to_string(operand1, &local_operand1,
592 ACPI_IMPLICIT_CONVERT_HEX);
593 break;
594
595 case ACPI_TYPE_BUFFER:
596 status = acpi_ex_convert_to_buffer(operand1, &local_operand1);
597 break;
598
599 default:
600 status = AE_AML_INTERNAL;
601 break;
602 }
603
604 if (ACPI_FAILURE(status)) {
605 goto cleanup;
606 }
607
608 /*
609 * Two cases: 1) Both Integers, 2) Both Strings or Buffers
610 */
611 if (ACPI_GET_OBJECT_TYPE(operand0) == ACPI_TYPE_INTEGER) {
612 /*
613 * 1) Both operands are of type integer
614 * Note: local_operand1 may have changed above
615 */
616 integer0 = operand0->integer.value;
617 integer1 = local_operand1->integer.value;
618
619 switch (opcode) {
620 case AML_LEQUAL_OP: /* LEqual (Operand0, Operand1) */
621
622 if (integer0 == integer1) {
623 local_result = TRUE;
624 }
625 break;
626
627 case AML_LGREATER_OP: /* LGreater (Operand0, Operand1) */
628
629 if (integer0 > integer1) {
630 local_result = TRUE;
631 }
632 break;
633
634 case AML_LLESS_OP: /* LLess (Operand0, Operand1) */
635
636 if (integer0 < integer1) {
637 local_result = TRUE;
638 }
639 break;
640
641 default:
642 status = AE_AML_INTERNAL;
643 break;
644 }
645 } else {
646 /*
647 * 2) Both operands are Strings or both are Buffers
648 * Note: Code below takes advantage of common Buffer/String
649 * object fields. local_operand1 may have changed above. Use
650 * memcmp to handle nulls in buffers.
651 */
652 length0 = operand0->buffer.length;
653 length1 = local_operand1->buffer.length;
654
655 /* Lexicographic compare: compare the data bytes */
656
657 compare = ACPI_MEMCMP(operand0->buffer.pointer,
658 local_operand1->buffer.pointer,
659 (length0 > length1) ? length1 : length0);
660
661 switch (opcode) {
662 case AML_LEQUAL_OP: /* LEqual (Operand0, Operand1) */
663
664 /* Length and all bytes must be equal */
665
666 if ((length0 == length1) && (compare == 0)) {
667
668 /* Length and all bytes match ==> TRUE */
669
670 local_result = TRUE;
671 }
672 break;
673
674 case AML_LGREATER_OP: /* LGreater (Operand0, Operand1) */
675
676 if (compare > 0) {
677 local_result = TRUE;
678 goto cleanup; /* TRUE */
679 }
680 if (compare < 0) {
681 goto cleanup; /* FALSE */
682 }
683
684 /* Bytes match (to shortest length), compare lengths */
685
686 if (length0 > length1) {
687 local_result = TRUE;
688 }
689 break;
690
691 case AML_LLESS_OP: /* LLess (Operand0, Operand1) */
692
693 if (compare > 0) {
694 goto cleanup; /* FALSE */
695 }
696 if (compare < 0) {
697 local_result = TRUE;
698 goto cleanup; /* TRUE */
699 }
700
701 /* Bytes match (to shortest length), compare lengths */
702
703 if (length0 < length1) {
704 local_result = TRUE;
705 }
706 break;
707
708 default:
709 status = AE_AML_INTERNAL;
710 break;
711 }
712 }
713
714 cleanup:
715
716 /* New object was created if implicit conversion performed - delete */
717
718 if (local_operand1 != operand1) {
719 acpi_ut_remove_reference(local_operand1);
720 }
721
722 /* Return the logical result and status */
723
724 *logical_result = local_result;
725 return_ACPI_STATUS(status);
726}
diff --git a/drivers/acpi/acpica/exmutex.c b/drivers/acpi/acpica/exmutex.c
new file mode 100644
index 00000000000..f86bcee8d65
--- /dev/null
+++ b/drivers/acpi/acpica/exmutex.c
@@ -0,0 +1,474 @@
1
2/******************************************************************************
3 *
4 * Module Name: exmutex - ASL Mutex Acquire/Release functions
5 *
6 *****************************************************************************/
7
8/*
9 * Copyright (C) 2000 - 2008, Intel Corp.
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions, and the following disclaimer,
17 * without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 * substantially similar to the "NO WARRANTY" disclaimer below
20 * ("Disclaimer") and any redistribution must be conditioned upon
21 * including a substantially similar Disclaimer requirement for further
22 * binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 * of any contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
30 *
31 * NO WARRANTY
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
43 */
44
45#include <acpi/acpi.h>
46#include <acpi/accommon.h>
47#include <acpi/acinterp.h>
48#include <acpi/acevents.h>
49
50#define _COMPONENT ACPI_EXECUTER
51ACPI_MODULE_NAME("exmutex")
52
53/* Local prototypes */
54static void
55acpi_ex_link_mutex(union acpi_operand_object *obj_desc,
56 struct acpi_thread_state *thread);
57
58/*******************************************************************************
59 *
60 * FUNCTION: acpi_ex_unlink_mutex
61 *
62 * PARAMETERS: obj_desc - The mutex to be unlinked
63 *
64 * RETURN: None
65 *
66 * DESCRIPTION: Remove a mutex from the "AcquiredMutex" list
67 *
68 ******************************************************************************/
69
70void acpi_ex_unlink_mutex(union acpi_operand_object *obj_desc)
71{
72 struct acpi_thread_state *thread = obj_desc->mutex.owner_thread;
73
74 if (!thread) {
75 return;
76 }
77
78 /* Doubly linked list */
79
80 if (obj_desc->mutex.next) {
81 (obj_desc->mutex.next)->mutex.prev = obj_desc->mutex.prev;
82 }
83
84 if (obj_desc->mutex.prev) {
85 (obj_desc->mutex.prev)->mutex.next = obj_desc->mutex.next;
86 } else {
87 thread->acquired_mutex_list = obj_desc->mutex.next;
88 }
89}
90
91/*******************************************************************************
92 *
93 * FUNCTION: acpi_ex_link_mutex
94 *
95 * PARAMETERS: obj_desc - The mutex to be linked
96 * Thread - Current executing thread object
97 *
98 * RETURN: None
99 *
100 * DESCRIPTION: Add a mutex to the "AcquiredMutex" list for this walk
101 *
102 ******************************************************************************/
103
104static void
105acpi_ex_link_mutex(union acpi_operand_object *obj_desc,
106 struct acpi_thread_state *thread)
107{
108 union acpi_operand_object *list_head;
109
110 list_head = thread->acquired_mutex_list;
111
112 /* This object will be the first object in the list */
113
114 obj_desc->mutex.prev = NULL;
115 obj_desc->mutex.next = list_head;
116
117 /* Update old first object to point back to this object */
118
119 if (list_head) {
120 list_head->mutex.prev = obj_desc;
121 }
122
123 /* Update list head */
124
125 thread->acquired_mutex_list = obj_desc;
126}
127
128/*******************************************************************************
129 *
130 * FUNCTION: acpi_ex_acquire_mutex_object
131 *
132 * PARAMETERS: time_desc - Timeout in milliseconds
133 * obj_desc - Mutex object
134 * Thread - Current thread state
135 *
136 * RETURN: Status
137 *
138 * DESCRIPTION: Acquire an AML mutex, low-level interface. Provides a common
139 * path that supports multiple acquires by the same thread.
140 *
141 * MUTEX: Interpreter must be locked
142 *
143 * NOTE: This interface is called from three places:
144 * 1) From acpi_ex_acquire_mutex, via an AML Acquire() operator
145 * 2) From acpi_ex_acquire_global_lock when an AML Field access requires the
146 * global lock
147 * 3) From the external interface, acpi_acquire_global_lock
148 *
149 ******************************************************************************/
150
151acpi_status
152acpi_ex_acquire_mutex_object(u16 timeout,
153 union acpi_operand_object *obj_desc,
154 acpi_thread_id thread_id)
155{
156 acpi_status status;
157
158 ACPI_FUNCTION_TRACE_PTR(ex_acquire_mutex_object, obj_desc);
159
160 if (!obj_desc) {
161 return_ACPI_STATUS(AE_BAD_PARAMETER);
162 }
163
164 /* Support for multiple acquires by the owning thread */
165
166 if (obj_desc->mutex.thread_id == thread_id) {
167 /*
168 * The mutex is already owned by this thread, just increment the
169 * acquisition depth
170 */
171 obj_desc->mutex.acquisition_depth++;
172 return_ACPI_STATUS(AE_OK);
173 }
174
175 /* Acquire the mutex, wait if necessary. Special case for Global Lock */
176
177 if (obj_desc == acpi_gbl_global_lock_mutex) {
178 status = acpi_ev_acquire_global_lock(timeout);
179 } else {
180 status = acpi_ex_system_wait_mutex(obj_desc->mutex.os_mutex,
181 timeout);
182 }
183
184 if (ACPI_FAILURE(status)) {
185
186 /* Includes failure from a timeout on time_desc */
187
188 return_ACPI_STATUS(status);
189 }
190
191 /* Acquired the mutex: update mutex object */
192
193 obj_desc->mutex.thread_id = thread_id;
194 obj_desc->mutex.acquisition_depth = 1;
195 obj_desc->mutex.original_sync_level = 0;
196 obj_desc->mutex.owner_thread = NULL; /* Used only for AML Acquire() */
197
198 return_ACPI_STATUS(AE_OK);
199}
200
201/*******************************************************************************
202 *
203 * FUNCTION: acpi_ex_acquire_mutex
204 *
205 * PARAMETERS: time_desc - Timeout integer
206 * obj_desc - Mutex object
207 * walk_state - Current method execution state
208 *
209 * RETURN: Status
210 *
211 * DESCRIPTION: Acquire an AML mutex
212 *
213 ******************************************************************************/
214
215acpi_status
216acpi_ex_acquire_mutex(union acpi_operand_object *time_desc,
217 union acpi_operand_object *obj_desc,
218 struct acpi_walk_state *walk_state)
219{
220 acpi_status status;
221
222 ACPI_FUNCTION_TRACE_PTR(ex_acquire_mutex, obj_desc);
223
224 if (!obj_desc) {
225 return_ACPI_STATUS(AE_BAD_PARAMETER);
226 }
227
228 /* Must have a valid thread ID */
229
230 if (!walk_state->thread) {
231 ACPI_ERROR((AE_INFO,
232 "Cannot acquire Mutex [%4.4s], null thread info",
233 acpi_ut_get_node_name(obj_desc->mutex.node)));
234 return_ACPI_STATUS(AE_AML_INTERNAL);
235 }
236
237 /*
238 * Current sync level must be less than or equal to the sync level of the
239 * mutex. This mechanism provides some deadlock prevention
240 */
241 if (walk_state->thread->current_sync_level > obj_desc->mutex.sync_level) {
242 ACPI_ERROR((AE_INFO,
243 "Cannot acquire Mutex [%4.4s], current SyncLevel is too large (%d)",
244 acpi_ut_get_node_name(obj_desc->mutex.node),
245 walk_state->thread->current_sync_level));
246 return_ACPI_STATUS(AE_AML_MUTEX_ORDER);
247 }
248
249 status = acpi_ex_acquire_mutex_object((u16) time_desc->integer.value,
250 obj_desc,
251 walk_state->thread->thread_id);
252 if (ACPI_SUCCESS(status) && obj_desc->mutex.acquisition_depth == 1) {
253
254 /* Save Thread object, original/current sync levels */
255
256 obj_desc->mutex.owner_thread = walk_state->thread;
257 obj_desc->mutex.original_sync_level =
258 walk_state->thread->current_sync_level;
259 walk_state->thread->current_sync_level =
260 obj_desc->mutex.sync_level;
261
262 /* Link the mutex to the current thread for force-unlock at method exit */
263
264 acpi_ex_link_mutex(obj_desc, walk_state->thread);
265 }
266
267 return_ACPI_STATUS(status);
268}
269
270/*******************************************************************************
271 *
272 * FUNCTION: acpi_ex_release_mutex_object
273 *
274 * PARAMETERS: obj_desc - The object descriptor for this op
275 *
276 * RETURN: Status
277 *
278 * DESCRIPTION: Release a previously acquired Mutex, low level interface.
279 * Provides a common path that supports multiple releases (after
280 * previous multiple acquires) by the same thread.
281 *
282 * MUTEX: Interpreter must be locked
283 *
284 * NOTE: This interface is called from three places:
285 * 1) From acpi_ex_release_mutex, via an AML Acquire() operator
286 * 2) From acpi_ex_release_global_lock when an AML Field access requires the
287 * global lock
288 * 3) From the external interface, acpi_release_global_lock
289 *
290 ******************************************************************************/
291
292acpi_status acpi_ex_release_mutex_object(union acpi_operand_object *obj_desc)
293{
294 acpi_status status = AE_OK;
295
296 ACPI_FUNCTION_TRACE(ex_release_mutex_object);
297
298 if (obj_desc->mutex.acquisition_depth == 0) {
299 return (AE_NOT_ACQUIRED);
300 }
301
302 /* Match multiple Acquires with multiple Releases */
303
304 obj_desc->mutex.acquisition_depth--;
305 if (obj_desc->mutex.acquisition_depth != 0) {
306
307 /* Just decrement the depth and return */
308
309 return_ACPI_STATUS(AE_OK);
310 }
311
312 if (obj_desc->mutex.owner_thread) {
313
314 /* Unlink the mutex from the owner's list */
315
316 acpi_ex_unlink_mutex(obj_desc);
317 obj_desc->mutex.owner_thread = NULL;
318 }
319
320 /* Release the mutex, special case for Global Lock */
321
322 if (obj_desc == acpi_gbl_global_lock_mutex) {
323 status = acpi_ev_release_global_lock();
324 } else {
325 acpi_os_release_mutex(obj_desc->mutex.os_mutex);
326 }
327
328 /* Clear mutex info */
329
330 obj_desc->mutex.thread_id = NULL;
331 return_ACPI_STATUS(status);
332}
333
334/*******************************************************************************
335 *
336 * FUNCTION: acpi_ex_release_mutex
337 *
338 * PARAMETERS: obj_desc - The object descriptor for this op
339 * walk_state - Current method execution state
340 *
341 * RETURN: Status
342 *
343 * DESCRIPTION: Release a previously acquired Mutex.
344 *
345 ******************************************************************************/
346
347acpi_status
348acpi_ex_release_mutex(union acpi_operand_object *obj_desc,
349 struct acpi_walk_state *walk_state)
350{
351 acpi_status status = AE_OK;
352
353 ACPI_FUNCTION_TRACE(ex_release_mutex);
354
355 if (!obj_desc) {
356 return_ACPI_STATUS(AE_BAD_PARAMETER);
357 }
358
359 /* The mutex must have been previously acquired in order to release it */
360
361 if (!obj_desc->mutex.owner_thread) {
362 ACPI_ERROR((AE_INFO,
363 "Cannot release Mutex [%4.4s], not acquired",
364 acpi_ut_get_node_name(obj_desc->mutex.node)));
365 return_ACPI_STATUS(AE_AML_MUTEX_NOT_ACQUIRED);
366 }
367
368 /*
369 * The Mutex is owned, but this thread must be the owner.
370 * Special case for Global Lock, any thread can release
371 */
372 if ((obj_desc->mutex.owner_thread->thread_id !=
373 walk_state->thread->thread_id)
374 && (obj_desc != acpi_gbl_global_lock_mutex)) {
375 ACPI_ERROR((AE_INFO,
376 "Thread %lX cannot release Mutex [%4.4s] acquired by thread %lX",
377 (unsigned long)walk_state->thread->thread_id,
378 acpi_ut_get_node_name(obj_desc->mutex.node),
379 (unsigned long)obj_desc->mutex.owner_thread->
380 thread_id));
381 return_ACPI_STATUS(AE_AML_NOT_OWNER);
382 }
383
384 /* Must have a valid thread ID */
385
386 if (!walk_state->thread) {
387 ACPI_ERROR((AE_INFO,
388 "Cannot release Mutex [%4.4s], null thread info",
389 acpi_ut_get_node_name(obj_desc->mutex.node)));
390 return_ACPI_STATUS(AE_AML_INTERNAL);
391 }
392
393 /*
394 * The sync level of the mutex must be less than or equal to the current
395 * sync level
396 */
397 if (obj_desc->mutex.sync_level > walk_state->thread->current_sync_level) {
398 ACPI_ERROR((AE_INFO,
399 "Cannot release Mutex [%4.4s], SyncLevel mismatch: mutex %d current %d",
400 acpi_ut_get_node_name(obj_desc->mutex.node),
401 obj_desc->mutex.sync_level,
402 walk_state->thread->current_sync_level));
403 return_ACPI_STATUS(AE_AML_MUTEX_ORDER);
404 }
405
406 status = acpi_ex_release_mutex_object(obj_desc);
407
408 if (obj_desc->mutex.acquisition_depth == 0) {
409
410 /* Restore the original sync_level */
411
412 walk_state->thread->current_sync_level =
413 obj_desc->mutex.original_sync_level;
414 }
415 return_ACPI_STATUS(status);
416}
417
418/*******************************************************************************
419 *
420 * FUNCTION: acpi_ex_release_all_mutexes
421 *
422 * PARAMETERS: Thread - Current executing thread object
423 *
424 * RETURN: Status
425 *
426 * DESCRIPTION: Release all mutexes held by this thread
427 *
428 * NOTE: This function is called as the thread is exiting the interpreter.
429 * Mutexes are not released when an individual control method is exited, but
430 * only when the parent thread actually exits the interpreter. This allows one
431 * method to acquire a mutex, and a different method to release it, as long as
432 * this is performed underneath a single parent control method.
433 *
434 ******************************************************************************/
435
436void acpi_ex_release_all_mutexes(struct acpi_thread_state *thread)
437{
438 union acpi_operand_object *next = thread->acquired_mutex_list;
439 union acpi_operand_object *obj_desc;
440
441 ACPI_FUNCTION_ENTRY();
442
443 /* Traverse the list of owned mutexes, releasing each one */
444
445 while (next) {
446 obj_desc = next;
447 next = obj_desc->mutex.next;
448
449 obj_desc->mutex.prev = NULL;
450 obj_desc->mutex.next = NULL;
451 obj_desc->mutex.acquisition_depth = 0;
452
453 /* Release the mutex, special case for Global Lock */
454
455 if (obj_desc == acpi_gbl_global_lock_mutex) {
456
457 /* Ignore errors */
458
459 (void)acpi_ev_release_global_lock();
460 } else {
461 acpi_os_release_mutex(obj_desc->mutex.os_mutex);
462 }
463
464 /* Mark mutex unowned */
465
466 obj_desc->mutex.owner_thread = NULL;
467 obj_desc->mutex.thread_id = NULL;
468
469 /* Update Thread sync_level (Last mutex is the important one) */
470
471 thread->current_sync_level =
472 obj_desc->mutex.original_sync_level;
473 }
474}
diff --git a/drivers/acpi/acpica/exnames.c b/drivers/acpi/acpica/exnames.c
new file mode 100644
index 00000000000..12d3513531e
--- /dev/null
+++ b/drivers/acpi/acpica/exnames.c
@@ -0,0 +1,436 @@
1
2/******************************************************************************
3 *
4 * Module Name: exnames - interpreter/scanner name load/execute
5 *
6 *****************************************************************************/
7
8/*
9 * Copyright (C) 2000 - 2008, Intel Corp.
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions, and the following disclaimer,
17 * without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 * substantially similar to the "NO WARRANTY" disclaimer below
20 * ("Disclaimer") and any redistribution must be conditioned upon
21 * including a substantially similar Disclaimer requirement for further
22 * binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 * of any contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
30 *
31 * NO WARRANTY
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
43 */
44
45#include <acpi/acpi.h>
46#include <acpi/accommon.h>
47#include <acpi/acinterp.h>
48#include <acpi/amlcode.h>
49
50#define _COMPONENT ACPI_EXECUTER
51ACPI_MODULE_NAME("exnames")
52
53/* Local prototypes */
54static char *acpi_ex_allocate_name_string(u32 prefix_count, u32 num_name_segs);
55
56static acpi_status
57acpi_ex_name_segment(u8 ** in_aml_address, char *name_string);
58
59/*******************************************************************************
60 *
61 * FUNCTION: acpi_ex_allocate_name_string
62 *
63 * PARAMETERS: prefix_count - Count of parent levels. Special cases:
64 * (-1)==root, 0==none
65 * num_name_segs - count of 4-character name segments
66 *
67 * RETURN: A pointer to the allocated string segment. This segment must
68 * be deleted by the caller.
69 *
70 * DESCRIPTION: Allocate a buffer for a name string. Ensure allocated name
71 * string is long enough, and set up prefix if any.
72 *
73 ******************************************************************************/
74
75static char *acpi_ex_allocate_name_string(u32 prefix_count, u32 num_name_segs)
76{
77 char *temp_ptr;
78 char *name_string;
79 u32 size_needed;
80
81 ACPI_FUNCTION_TRACE(ex_allocate_name_string);
82
83 /*
84 * Allow room for all \ and ^ prefixes, all segments and a multi_name_prefix.
85 * Also, one byte for the null terminator.
86 * This may actually be somewhat longer than needed.
87 */
88 if (prefix_count == ACPI_UINT32_MAX) {
89
90 /* Special case for root */
91
92 size_needed = 1 + (ACPI_NAME_SIZE * num_name_segs) + 2 + 1;
93 } else {
94 size_needed =
95 prefix_count + (ACPI_NAME_SIZE * num_name_segs) + 2 + 1;
96 }
97
98 /*
99 * Allocate a buffer for the name.
100 * This buffer must be deleted by the caller!
101 */
102 name_string = ACPI_ALLOCATE(size_needed);
103 if (!name_string) {
104 ACPI_ERROR((AE_INFO,
105 "Could not allocate size %d", size_needed));
106 return_PTR(NULL);
107 }
108
109 temp_ptr = name_string;
110
111 /* Set up Root or Parent prefixes if needed */
112
113 if (prefix_count == ACPI_UINT32_MAX) {
114 *temp_ptr++ = AML_ROOT_PREFIX;
115 } else {
116 while (prefix_count--) {
117 *temp_ptr++ = AML_PARENT_PREFIX;
118 }
119 }
120
121 /* Set up Dual or Multi prefixes if needed */
122
123 if (num_name_segs > 2) {
124
125 /* Set up multi prefixes */
126
127 *temp_ptr++ = AML_MULTI_NAME_PREFIX_OP;
128 *temp_ptr++ = (char)num_name_segs;
129 } else if (2 == num_name_segs) {
130
131 /* Set up dual prefixes */
132
133 *temp_ptr++ = AML_DUAL_NAME_PREFIX;
134 }
135
136 /*
137 * Terminate string following prefixes. acpi_ex_name_segment() will
138 * append the segment(s)
139 */
140 *temp_ptr = 0;
141
142 return_PTR(name_string);
143}
144
145/*******************************************************************************
146 *
147 * FUNCTION: acpi_ex_name_segment
148 *
149 * PARAMETERS: in_aml_address - Pointer to the name in the AML code
150 * name_string - Where to return the name. The name is appended
151 * to any existing string to form a namepath
152 *
153 * RETURN: Status
154 *
155 * DESCRIPTION: Extract an ACPI name (4 bytes) from the AML byte stream
156 *
157 ******************************************************************************/
158
159static acpi_status acpi_ex_name_segment(u8 ** in_aml_address, char *name_string)
160{
161 char *aml_address = (void *)*in_aml_address;
162 acpi_status status = AE_OK;
163 u32 index;
164 char char_buf[5];
165
166 ACPI_FUNCTION_TRACE(ex_name_segment);
167
168 /*
169 * If first character is a digit, then we know that we aren't looking at a
170 * valid name segment
171 */
172 char_buf[0] = *aml_address;
173
174 if ('0' <= char_buf[0] && char_buf[0] <= '9') {
175 ACPI_ERROR((AE_INFO, "Invalid leading digit: %c", char_buf[0]));
176 return_ACPI_STATUS(AE_CTRL_PENDING);
177 }
178
179 ACPI_DEBUG_PRINT((ACPI_DB_LOAD, "Bytes from stream:\n"));
180
181 for (index = 0; (index < ACPI_NAME_SIZE)
182 && (acpi_ut_valid_acpi_char(*aml_address, 0)); index++) {
183 char_buf[index] = *aml_address++;
184 ACPI_DEBUG_PRINT((ACPI_DB_LOAD, "%c\n", char_buf[index]));
185 }
186
187 /* Valid name segment */
188
189 if (index == 4) {
190
191 /* Found 4 valid characters */
192
193 char_buf[4] = '\0';
194
195 if (name_string) {
196 ACPI_STRCAT(name_string, char_buf);
197 ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
198 "Appended to - %s\n", name_string));
199 } else {
200 ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
201 "No Name string - %s\n", char_buf));
202 }
203 } else if (index == 0) {
204 /*
205 * First character was not a valid name character,
206 * so we are looking at something other than a name.
207 */
208 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
209 "Leading character is not alpha: %02Xh (not a name)\n",
210 char_buf[0]));
211 status = AE_CTRL_PENDING;
212 } else {
213 /*
214 * Segment started with one or more valid characters, but fewer than
215 * the required 4
216 */
217 status = AE_AML_BAD_NAME;
218 ACPI_ERROR((AE_INFO,
219 "Bad character %02x in name, at %p",
220 *aml_address, aml_address));
221 }
222
223 *in_aml_address = ACPI_CAST_PTR(u8, aml_address);
224 return_ACPI_STATUS(status);
225}
226
227/*******************************************************************************
228 *
229 * FUNCTION: acpi_ex_get_name_string
230 *
231 * PARAMETERS: data_type - Object type to be associated with this
232 * name
233 * in_aml_address - Pointer to the namestring in the AML code
234 * out_name_string - Where the namestring is returned
235 * out_name_length - Length of the returned string
236 *
237 * RETURN: Status, namestring and length
238 *
239 * DESCRIPTION: Extract a full namepath from the AML byte stream,
240 * including any prefixes.
241 *
242 ******************************************************************************/
243
244acpi_status
245acpi_ex_get_name_string(acpi_object_type data_type,
246 u8 * in_aml_address,
247 char **out_name_string, u32 * out_name_length)
248{
249 acpi_status status = AE_OK;
250 u8 *aml_address = in_aml_address;
251 char *name_string = NULL;
252 u32 num_segments;
253 u32 prefix_count = 0;
254 u8 has_prefix = FALSE;
255
256 ACPI_FUNCTION_TRACE_PTR(ex_get_name_string, aml_address);
257
258 if (ACPI_TYPE_LOCAL_REGION_FIELD == data_type ||
259 ACPI_TYPE_LOCAL_BANK_FIELD == data_type ||
260 ACPI_TYPE_LOCAL_INDEX_FIELD == data_type) {
261
262 /* Disallow prefixes for types associated with field_unit names */
263
264 name_string = acpi_ex_allocate_name_string(0, 1);
265 if (!name_string) {
266 status = AE_NO_MEMORY;
267 } else {
268 status =
269 acpi_ex_name_segment(&aml_address, name_string);
270 }
271 } else {
272 /*
273 * data_type is not a field name.
274 * Examine first character of name for root or parent prefix operators
275 */
276 switch (*aml_address) {
277 case AML_ROOT_PREFIX:
278
279 ACPI_DEBUG_PRINT((ACPI_DB_LOAD,
280 "RootPrefix(\\) at %p\n",
281 aml_address));
282
283 /*
284 * Remember that we have a root_prefix --
285 * see comment in acpi_ex_allocate_name_string()
286 */
287 aml_address++;
288 prefix_count = ACPI_UINT32_MAX;
289 has_prefix = TRUE;
290 break;
291
292 case AML_PARENT_PREFIX:
293
294 /* Increment past possibly multiple parent prefixes */
295
296 do {
297 ACPI_DEBUG_PRINT((ACPI_DB_LOAD,
298 "ParentPrefix (^) at %p\n",
299 aml_address));
300
301 aml_address++;
302 prefix_count++;
303
304 } while (*aml_address == AML_PARENT_PREFIX);
305
306 has_prefix = TRUE;
307 break;
308
309 default:
310
311 /* Not a prefix character */
312
313 break;
314 }
315
316 /* Examine first character of name for name segment prefix operator */
317
318 switch (*aml_address) {
319 case AML_DUAL_NAME_PREFIX:
320
321 ACPI_DEBUG_PRINT((ACPI_DB_LOAD,
322 "DualNamePrefix at %p\n",
323 aml_address));
324
325 aml_address++;
326 name_string =
327 acpi_ex_allocate_name_string(prefix_count, 2);
328 if (!name_string) {
329 status = AE_NO_MEMORY;
330 break;
331 }
332
333 /* Indicate that we processed a prefix */
334
335 has_prefix = TRUE;
336
337 status =
338 acpi_ex_name_segment(&aml_address, name_string);
339 if (ACPI_SUCCESS(status)) {
340 status =
341 acpi_ex_name_segment(&aml_address,
342 name_string);
343 }
344 break;
345
346 case AML_MULTI_NAME_PREFIX_OP:
347
348 ACPI_DEBUG_PRINT((ACPI_DB_LOAD,
349 "MultiNamePrefix at %p\n",
350 aml_address));
351
352 /* Fetch count of segments remaining in name path */
353
354 aml_address++;
355 num_segments = *aml_address;
356
357 name_string =
358 acpi_ex_allocate_name_string(prefix_count,
359 num_segments);
360 if (!name_string) {
361 status = AE_NO_MEMORY;
362 break;
363 }
364
365 /* Indicate that we processed a prefix */
366
367 aml_address++;
368 has_prefix = TRUE;
369
370 while (num_segments &&
371 (status =
372 acpi_ex_name_segment(&aml_address,
373 name_string)) == AE_OK) {
374 num_segments--;
375 }
376
377 break;
378
379 case 0:
380
381 /* null_name valid as of 8-12-98 ASL/AML Grammar Update */
382
383 if (prefix_count == ACPI_UINT32_MAX) {
384 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
385 "NameSeg is \"\\\" followed by NULL\n"));
386 }
387
388 /* Consume the NULL byte */
389
390 aml_address++;
391 name_string =
392 acpi_ex_allocate_name_string(prefix_count, 0);
393 if (!name_string) {
394 status = AE_NO_MEMORY;
395 break;
396 }
397
398 break;
399
400 default:
401
402 /* Name segment string */
403
404 name_string =
405 acpi_ex_allocate_name_string(prefix_count, 1);
406 if (!name_string) {
407 status = AE_NO_MEMORY;
408 break;
409 }
410
411 status =
412 acpi_ex_name_segment(&aml_address, name_string);
413 break;
414 }
415 }
416
417 if (AE_CTRL_PENDING == status && has_prefix) {
418
419 /* Ran out of segments after processing a prefix */
420
421 ACPI_ERROR((AE_INFO, "Malformed Name at %p", name_string));
422 status = AE_AML_BAD_NAME;
423 }
424
425 if (ACPI_FAILURE(status)) {
426 if (name_string) {
427 ACPI_FREE(name_string);
428 }
429 return_ACPI_STATUS(status);
430 }
431
432 *out_name_string = name_string;
433 *out_name_length = (u32) (aml_address - in_aml_address);
434
435 return_ACPI_STATUS(status);
436}
diff --git a/drivers/acpi/acpica/exoparg1.c b/drivers/acpi/acpica/exoparg1.c
new file mode 100644
index 00000000000..52d78b8622b
--- /dev/null
+++ b/drivers/acpi/acpica/exoparg1.c
@@ -0,0 +1,1050 @@
1
2/******************************************************************************
3 *
4 * Module Name: exoparg1 - AML execution - opcodes with 1 argument
5 *
6 *****************************************************************************/
7
8/*
9 * Copyright (C) 2000 - 2008, Intel Corp.
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions, and the following disclaimer,
17 * without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 * substantially similar to the "NO WARRANTY" disclaimer below
20 * ("Disclaimer") and any redistribution must be conditioned upon
21 * including a substantially similar Disclaimer requirement for further
22 * binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 * of any contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
30 *
31 * NO WARRANTY
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
43 */
44
45#include <acpi/acpi.h>
46#include <acpi/accommon.h>
47#include <acpi/acparser.h>
48#include <acpi/acdispat.h>
49#include <acpi/acinterp.h>
50#include <acpi/amlcode.h>
51#include <acpi/acnamesp.h>
52
53#define _COMPONENT ACPI_EXECUTER
54ACPI_MODULE_NAME("exoparg1")
55
56/*!
57 * Naming convention for AML interpreter execution routines.
58 *
59 * The routines that begin execution of AML opcodes are named with a common
60 * convention based upon the number of arguments, the number of target operands,
61 * and whether or not a value is returned:
62 *
63 * AcpiExOpcode_xA_yT_zR
64 *
65 * Where:
66 *
67 * xA - ARGUMENTS: The number of arguments (input operands) that are
68 * required for this opcode type (0 through 6 args).
69 * yT - TARGETS: The number of targets (output operands) that are required
70 * for this opcode type (0, 1, or 2 targets).
71 * zR - RETURN VALUE: Indicates whether this opcode type returns a value
72 * as the function return (0 or 1).
73 *
74 * The AcpiExOpcode* functions are called via the Dispatcher component with
75 * fully resolved operands.
76!*/
77/*******************************************************************************
78 *
79 * FUNCTION: acpi_ex_opcode_0A_0T_1R
80 *
81 * PARAMETERS: walk_state - Current state (contains AML opcode)
82 *
83 * RETURN: Status
84 *
85 * DESCRIPTION: Execute operator with no operands, one return value
86 *
87 ******************************************************************************/
88acpi_status acpi_ex_opcode_0A_0T_1R(struct acpi_walk_state *walk_state)
89{
90 acpi_status status = AE_OK;
91 union acpi_operand_object *return_desc = NULL;
92
93 ACPI_FUNCTION_TRACE_STR(ex_opcode_0A_0T_1R,
94 acpi_ps_get_opcode_name(walk_state->opcode));
95
96 /* Examine the AML opcode */
97
98 switch (walk_state->opcode) {
99 case AML_TIMER_OP: /* Timer () */
100
101 /* Create a return object of type Integer */
102
103 return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
104 if (!return_desc) {
105 status = AE_NO_MEMORY;
106 goto cleanup;
107 }
108 return_desc->integer.value = acpi_os_get_timer();
109 break;
110
111 default: /* Unknown opcode */
112
113 ACPI_ERROR((AE_INFO, "Unknown AML opcode %X",
114 walk_state->opcode));
115 status = AE_AML_BAD_OPCODE;
116 break;
117 }
118
119 cleanup:
120
121 /* Delete return object on error */
122
123 if ((ACPI_FAILURE(status)) || walk_state->result_obj) {
124 acpi_ut_remove_reference(return_desc);
125 walk_state->result_obj = NULL;
126 } else {
127 /* Save the return value */
128
129 walk_state->result_obj = return_desc;
130 }
131
132 return_ACPI_STATUS(status);
133}
134
135/*******************************************************************************
136 *
137 * FUNCTION: acpi_ex_opcode_1A_0T_0R
138 *
139 * PARAMETERS: walk_state - Current state (contains AML opcode)
140 *
141 * RETURN: Status
142 *
143 * DESCRIPTION: Execute Type 1 monadic operator with numeric operand on
144 * object stack
145 *
146 ******************************************************************************/
147
148acpi_status acpi_ex_opcode_1A_0T_0R(struct acpi_walk_state *walk_state)
149{
150 union acpi_operand_object **operand = &walk_state->operands[0];
151 acpi_status status = AE_OK;
152
153 ACPI_FUNCTION_TRACE_STR(ex_opcode_1A_0T_0R,
154 acpi_ps_get_opcode_name(walk_state->opcode));
155
156 /* Examine the AML opcode */
157
158 switch (walk_state->opcode) {
159 case AML_RELEASE_OP: /* Release (mutex_object) */
160
161 status = acpi_ex_release_mutex(operand[0], walk_state);
162 break;
163
164 case AML_RESET_OP: /* Reset (event_object) */
165
166 status = acpi_ex_system_reset_event(operand[0]);
167 break;
168
169 case AML_SIGNAL_OP: /* Signal (event_object) */
170
171 status = acpi_ex_system_signal_event(operand[0]);
172 break;
173
174 case AML_SLEEP_OP: /* Sleep (msec_time) */
175
176 status = acpi_ex_system_do_suspend(operand[0]->integer.value);
177 break;
178
179 case AML_STALL_OP: /* Stall (usec_time) */
180
181 status =
182 acpi_ex_system_do_stall((u32) operand[0]->integer.value);
183 break;
184
185 case AML_UNLOAD_OP: /* Unload (Handle) */
186
187 status = acpi_ex_unload_table(operand[0]);
188 break;
189
190 default: /* Unknown opcode */
191
192 ACPI_ERROR((AE_INFO, "Unknown AML opcode %X",
193 walk_state->opcode));
194 status = AE_AML_BAD_OPCODE;
195 break;
196 }
197
198 return_ACPI_STATUS(status);
199}
200
201/*******************************************************************************
202 *
203 * FUNCTION: acpi_ex_opcode_1A_1T_0R
204 *
205 * PARAMETERS: walk_state - Current state (contains AML opcode)
206 *
207 * RETURN: Status
208 *
209 * DESCRIPTION: Execute opcode with one argument, one target, and no
210 * return value.
211 *
212 ******************************************************************************/
213
214acpi_status acpi_ex_opcode_1A_1T_0R(struct acpi_walk_state *walk_state)
215{
216 acpi_status status = AE_OK;
217 union acpi_operand_object **operand = &walk_state->operands[0];
218
219 ACPI_FUNCTION_TRACE_STR(ex_opcode_1A_1T_0R,
220 acpi_ps_get_opcode_name(walk_state->opcode));
221
222 /* Examine the AML opcode */
223
224 switch (walk_state->opcode) {
225 case AML_LOAD_OP:
226
227 status = acpi_ex_load_op(operand[0], operand[1], walk_state);
228 break;
229
230 default: /* Unknown opcode */
231
232 ACPI_ERROR((AE_INFO, "Unknown AML opcode %X",
233 walk_state->opcode));
234 status = AE_AML_BAD_OPCODE;
235 goto cleanup;
236 }
237
238 cleanup:
239
240 return_ACPI_STATUS(status);
241}
242
243/*******************************************************************************
244 *
245 * FUNCTION: acpi_ex_opcode_1A_1T_1R
246 *
247 * PARAMETERS: walk_state - Current state (contains AML opcode)
248 *
249 * RETURN: Status
250 *
251 * DESCRIPTION: Execute opcode with one argument, one target, and a
252 * return value.
253 *
254 ******************************************************************************/
255
256acpi_status acpi_ex_opcode_1A_1T_1R(struct acpi_walk_state *walk_state)
257{
258 acpi_status status = AE_OK;
259 union acpi_operand_object **operand = &walk_state->operands[0];
260 union acpi_operand_object *return_desc = NULL;
261 union acpi_operand_object *return_desc2 = NULL;
262 u32 temp32;
263 u32 i;
264 acpi_integer power_of_ten;
265 acpi_integer digit;
266
267 ACPI_FUNCTION_TRACE_STR(ex_opcode_1A_1T_1R,
268 acpi_ps_get_opcode_name(walk_state->opcode));
269
270 /* Examine the AML opcode */
271
272 switch (walk_state->opcode) {
273 case AML_BIT_NOT_OP:
274 case AML_FIND_SET_LEFT_BIT_OP:
275 case AML_FIND_SET_RIGHT_BIT_OP:
276 case AML_FROM_BCD_OP:
277 case AML_TO_BCD_OP:
278 case AML_COND_REF_OF_OP:
279
280 /* Create a return object of type Integer for these opcodes */
281
282 return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
283 if (!return_desc) {
284 status = AE_NO_MEMORY;
285 goto cleanup;
286 }
287
288 switch (walk_state->opcode) {
289 case AML_BIT_NOT_OP: /* Not (Operand, Result) */
290
291 return_desc->integer.value = ~operand[0]->integer.value;
292 break;
293
294 case AML_FIND_SET_LEFT_BIT_OP: /* find_set_left_bit (Operand, Result) */
295
296 return_desc->integer.value = operand[0]->integer.value;
297
298 /*
299 * Acpi specification describes Integer type as a little
300 * endian unsigned value, so this boundary condition is valid.
301 */
302 for (temp32 = 0; return_desc->integer.value &&
303 temp32 < ACPI_INTEGER_BIT_SIZE; ++temp32) {
304 return_desc->integer.value >>= 1;
305 }
306
307 return_desc->integer.value = temp32;
308 break;
309
310 case AML_FIND_SET_RIGHT_BIT_OP: /* find_set_right_bit (Operand, Result) */
311
312 return_desc->integer.value = operand[0]->integer.value;
313
314 /*
315 * The Acpi specification describes Integer type as a little
316 * endian unsigned value, so this boundary condition is valid.
317 */
318 for (temp32 = 0; return_desc->integer.value &&
319 temp32 < ACPI_INTEGER_BIT_SIZE; ++temp32) {
320 return_desc->integer.value <<= 1;
321 }
322
323 /* Since the bit position is one-based, subtract from 33 (65) */
324
325 return_desc->integer.value =
326 temp32 ==
327 0 ? 0 : (ACPI_INTEGER_BIT_SIZE + 1) - temp32;
328 break;
329
330 case AML_FROM_BCD_OP: /* from_bcd (BCDValue, Result) */
331
332 /*
333 * The 64-bit ACPI integer can hold 16 4-bit BCD characters
334 * (if table is 32-bit, integer can hold 8 BCD characters)
335 * Convert each 4-bit BCD value
336 */
337 power_of_ten = 1;
338 return_desc->integer.value = 0;
339 digit = operand[0]->integer.value;
340
341 /* Convert each BCD digit (each is one nybble wide) */
342
343 for (i = 0;
344 (i < acpi_gbl_integer_nybble_width) && (digit > 0);
345 i++) {
346
347 /* Get the least significant 4-bit BCD digit */
348
349 temp32 = ((u32) digit) & 0xF;
350
351 /* Check the range of the digit */
352
353 if (temp32 > 9) {
354 ACPI_ERROR((AE_INFO,
355 "BCD digit too large (not decimal): 0x%X",
356 temp32));
357
358 status = AE_AML_NUMERIC_OVERFLOW;
359 goto cleanup;
360 }
361
362 /* Sum the digit into the result with the current power of 10 */
363
364 return_desc->integer.value +=
365 (((acpi_integer) temp32) * power_of_ten);
366
367 /* Shift to next BCD digit */
368
369 digit >>= 4;
370
371 /* Next power of 10 */
372
373 power_of_ten *= 10;
374 }
375 break;
376
377 case AML_TO_BCD_OP: /* to_bcd (Operand, Result) */
378
379 return_desc->integer.value = 0;
380 digit = operand[0]->integer.value;
381
382 /* Each BCD digit is one nybble wide */
383
384 for (i = 0;
385 (i < acpi_gbl_integer_nybble_width) && (digit > 0);
386 i++) {
387 (void)acpi_ut_short_divide(digit, 10, &digit,
388 &temp32);
389
390 /*
391 * Insert the BCD digit that resides in the
392 * remainder from above
393 */
394 return_desc->integer.value |=
395 (((acpi_integer) temp32) << ACPI_MUL_4(i));
396 }
397
398 /* Overflow if there is any data left in Digit */
399
400 if (digit > 0) {
401 ACPI_ERROR((AE_INFO,
402 "Integer too large to convert to BCD: %8.8X%8.8X",
403 ACPI_FORMAT_UINT64(operand[0]->
404 integer.value)));
405 status = AE_AML_NUMERIC_OVERFLOW;
406 goto cleanup;
407 }
408 break;
409
410 case AML_COND_REF_OF_OP: /* cond_ref_of (source_object, Result) */
411
412 /*
413 * This op is a little strange because the internal return value is
414 * different than the return value stored in the result descriptor
415 * (There are really two return values)
416 */
417 if ((struct acpi_namespace_node *)operand[0] ==
418 acpi_gbl_root_node) {
419 /*
420 * This means that the object does not exist in the namespace,
421 * return FALSE
422 */
423 return_desc->integer.value = 0;
424 goto cleanup;
425 }
426
427 /* Get the object reference, store it, and remove our reference */
428
429 status = acpi_ex_get_object_reference(operand[0],
430 &return_desc2,
431 walk_state);
432 if (ACPI_FAILURE(status)) {
433 goto cleanup;
434 }
435
436 status =
437 acpi_ex_store(return_desc2, operand[1], walk_state);
438 acpi_ut_remove_reference(return_desc2);
439
440 /* The object exists in the namespace, return TRUE */
441
442 return_desc->integer.value = ACPI_INTEGER_MAX;
443 goto cleanup;
444
445 default:
446 /* No other opcodes get here */
447 break;
448 }
449 break;
450
451 case AML_STORE_OP: /* Store (Source, Target) */
452
453 /*
454 * A store operand is typically a number, string, buffer or lvalue
455 * Be careful about deleting the source object,
456 * since the object itself may have been stored.
457 */
458 status = acpi_ex_store(operand[0], operand[1], walk_state);
459 if (ACPI_FAILURE(status)) {
460 return_ACPI_STATUS(status);
461 }
462
463 /* It is possible that the Store already produced a return object */
464
465 if (!walk_state->result_obj) {
466 /*
467 * Normally, we would remove a reference on the Operand[0]
468 * parameter; But since it is being used as the internal return
469 * object (meaning we would normally increment it), the two
470 * cancel out, and we simply don't do anything.
471 */
472 walk_state->result_obj = operand[0];
473 walk_state->operands[0] = NULL; /* Prevent deletion */
474 }
475 return_ACPI_STATUS(status);
476
477 /*
478 * ACPI 2.0 Opcodes
479 */
480 case AML_COPY_OP: /* Copy (Source, Target) */
481
482 status =
483 acpi_ut_copy_iobject_to_iobject(operand[0], &return_desc,
484 walk_state);
485 break;
486
487 case AML_TO_DECSTRING_OP: /* to_decimal_string (Data, Result) */
488
489 status = acpi_ex_convert_to_string(operand[0], &return_desc,
490 ACPI_EXPLICIT_CONVERT_DECIMAL);
491 if (return_desc == operand[0]) {
492
493 /* No conversion performed, add ref to handle return value */
494 acpi_ut_add_reference(return_desc);
495 }
496 break;
497
498 case AML_TO_HEXSTRING_OP: /* to_hex_string (Data, Result) */
499
500 status = acpi_ex_convert_to_string(operand[0], &return_desc,
501 ACPI_EXPLICIT_CONVERT_HEX);
502 if (return_desc == operand[0]) {
503
504 /* No conversion performed, add ref to handle return value */
505 acpi_ut_add_reference(return_desc);
506 }
507 break;
508
509 case AML_TO_BUFFER_OP: /* to_buffer (Data, Result) */
510
511 status = acpi_ex_convert_to_buffer(operand[0], &return_desc);
512 if (return_desc == operand[0]) {
513
514 /* No conversion performed, add ref to handle return value */
515 acpi_ut_add_reference(return_desc);
516 }
517 break;
518
519 case AML_TO_INTEGER_OP: /* to_integer (Data, Result) */
520
521 status = acpi_ex_convert_to_integer(operand[0], &return_desc,
522 ACPI_ANY_BASE);
523 if (return_desc == operand[0]) {
524
525 /* No conversion performed, add ref to handle return value */
526 acpi_ut_add_reference(return_desc);
527 }
528 break;
529
530 case AML_SHIFT_LEFT_BIT_OP: /* shift_left_bit (Source, bit_num) */
531 case AML_SHIFT_RIGHT_BIT_OP: /* shift_right_bit (Source, bit_num) */
532
533 /* These are two obsolete opcodes */
534
535 ACPI_ERROR((AE_INFO,
536 "%s is obsolete and not implemented",
537 acpi_ps_get_opcode_name(walk_state->opcode)));
538 status = AE_SUPPORT;
539 goto cleanup;
540
541 default: /* Unknown opcode */
542
543 ACPI_ERROR((AE_INFO, "Unknown AML opcode %X",
544 walk_state->opcode));
545 status = AE_AML_BAD_OPCODE;
546 goto cleanup;
547 }
548
549 if (ACPI_SUCCESS(status)) {
550
551 /* Store the return value computed above into the target object */
552
553 status = acpi_ex_store(return_desc, operand[1], walk_state);
554 }
555
556 cleanup:
557
558 /* Delete return object on error */
559
560 if (ACPI_FAILURE(status)) {
561 acpi_ut_remove_reference(return_desc);
562 }
563
564 /* Save return object on success */
565
566 else if (!walk_state->result_obj) {
567 walk_state->result_obj = return_desc;
568 }
569
570 return_ACPI_STATUS(status);
571}
572
573/*******************************************************************************
574 *
575 * FUNCTION: acpi_ex_opcode_1A_0T_1R
576 *
577 * PARAMETERS: walk_state - Current state (contains AML opcode)
578 *
579 * RETURN: Status
580 *
581 * DESCRIPTION: Execute opcode with one argument, no target, and a return value
582 *
583 ******************************************************************************/
584
585acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state)
586{
587 union acpi_operand_object **operand = &walk_state->operands[0];
588 union acpi_operand_object *temp_desc;
589 union acpi_operand_object *return_desc = NULL;
590 acpi_status status = AE_OK;
591 u32 type;
592 acpi_integer value;
593
594 ACPI_FUNCTION_TRACE_STR(ex_opcode_1A_0T_1R,
595 acpi_ps_get_opcode_name(walk_state->opcode));
596
597 /* Examine the AML opcode */
598
599 switch (walk_state->opcode) {
600 case AML_LNOT_OP: /* LNot (Operand) */
601
602 return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
603 if (!return_desc) {
604 status = AE_NO_MEMORY;
605 goto cleanup;
606 }
607
608 /*
609 * Set result to ONES (TRUE) if Value == 0. Note:
610 * return_desc->Integer.Value is initially == 0 (FALSE) from above.
611 */
612 if (!operand[0]->integer.value) {
613 return_desc->integer.value = ACPI_INTEGER_MAX;
614 }
615 break;
616
617 case AML_DECREMENT_OP: /* Decrement (Operand) */
618 case AML_INCREMENT_OP: /* Increment (Operand) */
619
620 /*
621 * Create a new integer. Can't just get the base integer and
622 * increment it because it may be an Arg or Field.
623 */
624 return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
625 if (!return_desc) {
626 status = AE_NO_MEMORY;
627 goto cleanup;
628 }
629
630 /*
631 * Since we are expecting a Reference operand, it can be either a
632 * NS Node or an internal object.
633 */
634 temp_desc = operand[0];
635 if (ACPI_GET_DESCRIPTOR_TYPE(temp_desc) ==
636 ACPI_DESC_TYPE_OPERAND) {
637
638 /* Internal reference object - prevent deletion */
639
640 acpi_ut_add_reference(temp_desc);
641 }
642
643 /*
644 * Convert the Reference operand to an Integer (This removes a
645 * reference on the Operand[0] object)
646 *
647 * NOTE: We use LNOT_OP here in order to force resolution of the
648 * reference operand to an actual integer.
649 */
650 status =
651 acpi_ex_resolve_operands(AML_LNOT_OP, &temp_desc,
652 walk_state);
653 if (ACPI_FAILURE(status)) {
654 ACPI_EXCEPTION((AE_INFO, status,
655 "While resolving operands for [%s]",
656 acpi_ps_get_opcode_name(walk_state->
657 opcode)));
658
659 goto cleanup;
660 }
661
662 /*
663 * temp_desc is now guaranteed to be an Integer object --
664 * Perform the actual increment or decrement
665 */
666 if (walk_state->opcode == AML_INCREMENT_OP) {
667 return_desc->integer.value =
668 temp_desc->integer.value + 1;
669 } else {
670 return_desc->integer.value =
671 temp_desc->integer.value - 1;
672 }
673
674 /* Finished with this Integer object */
675
676 acpi_ut_remove_reference(temp_desc);
677
678 /*
679 * Store the result back (indirectly) through the original
680 * Reference object
681 */
682 status = acpi_ex_store(return_desc, operand[0], walk_state);
683 break;
684
685 case AML_TYPE_OP: /* object_type (source_object) */
686
687 /*
688 * Note: The operand is not resolved at this point because we want to
689 * get the associated object, not its value. For example, we don't
690 * want to resolve a field_unit to its value, we want the actual
691 * field_unit object.
692 */
693
694 /* Get the type of the base object */
695
696 status =
697 acpi_ex_resolve_multiple(walk_state, operand[0], &type,
698 NULL);
699 if (ACPI_FAILURE(status)) {
700 goto cleanup;
701 }
702
703 /* Allocate a descriptor to hold the type. */
704
705 return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
706 if (!return_desc) {
707 status = AE_NO_MEMORY;
708 goto cleanup;
709 }
710
711 return_desc->integer.value = type;
712 break;
713
714 case AML_SIZE_OF_OP: /* size_of (source_object) */
715
716 /*
717 * Note: The operand is not resolved at this point because we want to
718 * get the associated object, not its value.
719 */
720
721 /* Get the base object */
722
723 status = acpi_ex_resolve_multiple(walk_state,
724 operand[0], &type,
725 &temp_desc);
726 if (ACPI_FAILURE(status)) {
727 goto cleanup;
728 }
729
730 /*
731 * The type of the base object must be integer, buffer, string, or
732 * package. All others are not supported.
733 *
734 * NOTE: Integer is not specifically supported by the ACPI spec,
735 * but is supported implicitly via implicit operand conversion.
736 * rather than bother with conversion, we just use the byte width
737 * global (4 or 8 bytes).
738 */
739 switch (type) {
740 case ACPI_TYPE_INTEGER:
741 value = acpi_gbl_integer_byte_width;
742 break;
743
744 case ACPI_TYPE_STRING:
745 value = temp_desc->string.length;
746 break;
747
748 case ACPI_TYPE_BUFFER:
749
750 /* Buffer arguments may not be evaluated at this point */
751
752 status = acpi_ds_get_buffer_arguments(temp_desc);
753 value = temp_desc->buffer.length;
754 break;
755
756 case ACPI_TYPE_PACKAGE:
757
758 /* Package arguments may not be evaluated at this point */
759
760 status = acpi_ds_get_package_arguments(temp_desc);
761 value = temp_desc->package.count;
762 break;
763
764 default:
765 ACPI_ERROR((AE_INFO,
766 "Operand must be Buffer/Integer/String/Package - found type %s",
767 acpi_ut_get_type_name(type)));
768 status = AE_AML_OPERAND_TYPE;
769 goto cleanup;
770 }
771
772 if (ACPI_FAILURE(status)) {
773 goto cleanup;
774 }
775
776 /*
777 * Now that we have the size of the object, create a result
778 * object to hold the value
779 */
780 return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
781 if (!return_desc) {
782 status = AE_NO_MEMORY;
783 goto cleanup;
784 }
785
786 return_desc->integer.value = value;
787 break;
788
789 case AML_REF_OF_OP: /* ref_of (source_object) */
790
791 status =
792 acpi_ex_get_object_reference(operand[0], &return_desc,
793 walk_state);
794 if (ACPI_FAILURE(status)) {
795 goto cleanup;
796 }
797 break;
798
799 case AML_DEREF_OF_OP: /* deref_of (obj_reference | String) */
800
801 /* Check for a method local or argument, or standalone String */
802
803 if (ACPI_GET_DESCRIPTOR_TYPE(operand[0]) ==
804 ACPI_DESC_TYPE_NAMED) {
805 temp_desc =
806 acpi_ns_get_attached_object((struct
807 acpi_namespace_node *)
808 operand[0]);
809 if (temp_desc
810 &&
811 ((ACPI_GET_OBJECT_TYPE(temp_desc) ==
812 ACPI_TYPE_STRING)
813 || (ACPI_GET_OBJECT_TYPE(temp_desc) ==
814 ACPI_TYPE_LOCAL_REFERENCE))) {
815 operand[0] = temp_desc;
816 acpi_ut_add_reference(temp_desc);
817 } else {
818 status = AE_AML_OPERAND_TYPE;
819 goto cleanup;
820 }
821 } else {
822 switch (ACPI_GET_OBJECT_TYPE(operand[0])) {
823 case ACPI_TYPE_LOCAL_REFERENCE:
824 /*
825 * This is a deref_of (local_x | arg_x)
826 *
827 * Must resolve/dereference the local/arg reference first
828 */
829 switch (operand[0]->reference.class) {
830 case ACPI_REFCLASS_LOCAL:
831 case ACPI_REFCLASS_ARG:
832
833 /* Set Operand[0] to the value of the local/arg */
834
835 status =
836 acpi_ds_method_data_get_value
837 (operand[0]->reference.class,
838 operand[0]->reference.value,
839 walk_state, &temp_desc);
840 if (ACPI_FAILURE(status)) {
841 goto cleanup;
842 }
843
844 /*
845 * Delete our reference to the input object and
846 * point to the object just retrieved
847 */
848 acpi_ut_remove_reference(operand[0]);
849 operand[0] = temp_desc;
850 break;
851
852 case ACPI_REFCLASS_REFOF:
853
854 /* Get the object to which the reference refers */
855
856 temp_desc =
857 operand[0]->reference.object;
858 acpi_ut_remove_reference(operand[0]);
859 operand[0] = temp_desc;
860 break;
861
862 default:
863
864 /* Must be an Index op - handled below */
865 break;
866 }
867 break;
868
869 case ACPI_TYPE_STRING:
870 break;
871
872 default:
873 status = AE_AML_OPERAND_TYPE;
874 goto cleanup;
875 }
876 }
877
878 if (ACPI_GET_DESCRIPTOR_TYPE(operand[0]) !=
879 ACPI_DESC_TYPE_NAMED) {
880 if (ACPI_GET_OBJECT_TYPE(operand[0]) ==
881 ACPI_TYPE_STRING) {
882 /*
883 * This is a deref_of (String). The string is a reference
884 * to a named ACPI object.
885 *
886 * 1) Find the owning Node
887 * 2) Dereference the node to an actual object. Could be a
888 * Field, so we need to resolve the node to a value.
889 */
890 status =
891 acpi_ns_get_node(walk_state->scope_info->
892 scope.node,
893 operand[0]->string.pointer,
894 ACPI_NS_SEARCH_PARENT,
895 ACPI_CAST_INDIRECT_PTR
896 (struct
897 acpi_namespace_node,
898 &return_desc));
899 if (ACPI_FAILURE(status)) {
900 goto cleanup;
901 }
902
903 status =
904 acpi_ex_resolve_node_to_value
905 (ACPI_CAST_INDIRECT_PTR
906 (struct acpi_namespace_node, &return_desc),
907 walk_state);
908 goto cleanup;
909 }
910 }
911
912 /* Operand[0] may have changed from the code above */
913
914 if (ACPI_GET_DESCRIPTOR_TYPE(operand[0]) ==
915 ACPI_DESC_TYPE_NAMED) {
916 /*
917 * This is a deref_of (object_reference)
918 * Get the actual object from the Node (This is the dereference).
919 * This case may only happen when a local_x or arg_x is
920 * dereferenced above.
921 */
922 return_desc = acpi_ns_get_attached_object((struct
923 acpi_namespace_node
924 *)
925 operand[0]);
926 acpi_ut_add_reference(return_desc);
927 } else {
928 /*
929 * This must be a reference object produced by either the
930 * Index() or ref_of() operator
931 */
932 switch (operand[0]->reference.class) {
933 case ACPI_REFCLASS_INDEX:
934
935 /*
936 * The target type for the Index operator must be
937 * either a Buffer or a Package
938 */
939 switch (operand[0]->reference.target_type) {
940 case ACPI_TYPE_BUFFER_FIELD:
941
942 temp_desc =
943 operand[0]->reference.object;
944
945 /*
946 * Create a new object that contains one element of the
947 * buffer -- the element pointed to by the index.
948 *
949 * NOTE: index into a buffer is NOT a pointer to a
950 * sub-buffer of the main buffer, it is only a pointer to a
951 * single element (byte) of the buffer!
952 */
953 return_desc =
954 acpi_ut_create_internal_object
955 (ACPI_TYPE_INTEGER);
956 if (!return_desc) {
957 status = AE_NO_MEMORY;
958 goto cleanup;
959 }
960
961 /*
962 * Since we are returning the value of the buffer at the
963 * indexed location, we don't need to add an additional
964 * reference to the buffer itself.
965 */
966 return_desc->integer.value =
967 temp_desc->buffer.
968 pointer[operand[0]->reference.
969 value];
970 break;
971
972 case ACPI_TYPE_PACKAGE:
973
974 /*
975 * Return the referenced element of the package. We must
976 * add another reference to the referenced object, however.
977 */
978 return_desc =
979 *(operand[0]->reference.where);
980 if (return_desc) {
981 acpi_ut_add_reference
982 (return_desc);
983 }
984 break;
985
986 default:
987
988 ACPI_ERROR((AE_INFO,
989 "Unknown Index TargetType %X in reference object %p",
990 operand[0]->reference.
991 target_type, operand[0]));
992 status = AE_AML_OPERAND_TYPE;
993 goto cleanup;
994 }
995 break;
996
997 case ACPI_REFCLASS_REFOF:
998
999 return_desc = operand[0]->reference.object;
1000
1001 if (ACPI_GET_DESCRIPTOR_TYPE(return_desc) ==
1002 ACPI_DESC_TYPE_NAMED) {
1003 return_desc =
1004 acpi_ns_get_attached_object((struct
1005 acpi_namespace_node
1006 *)
1007 return_desc);
1008 }
1009
1010 /* Add another reference to the object! */
1011
1012 acpi_ut_add_reference(return_desc);
1013 break;
1014
1015 default:
1016 ACPI_ERROR((AE_INFO,
1017 "Unknown class in reference(%p) - %2.2X",
1018 operand[0],
1019 operand[0]->reference.class));
1020
1021 status = AE_TYPE;
1022 goto cleanup;
1023 }
1024 }
1025 break;
1026
1027 default:
1028
1029 ACPI_ERROR((AE_INFO, "Unknown AML opcode %X",
1030 walk_state->opcode));
1031 status = AE_AML_BAD_OPCODE;
1032 goto cleanup;
1033 }
1034
1035 cleanup:
1036
1037 /* Delete return object on error */
1038
1039 if (ACPI_FAILURE(status)) {
1040 acpi_ut_remove_reference(return_desc);
1041 }
1042
1043 /* Save return object on success */
1044
1045 else {
1046 walk_state->result_obj = return_desc;
1047 }
1048
1049 return_ACPI_STATUS(status);
1050}
diff --git a/drivers/acpi/acpica/exoparg2.c b/drivers/acpi/acpica/exoparg2.c
new file mode 100644
index 00000000000..b01980df136
--- /dev/null
+++ b/drivers/acpi/acpica/exoparg2.c
@@ -0,0 +1,605 @@
1/******************************************************************************
2 *
3 * Module Name: exoparg2 - AML execution - opcodes with 2 arguments
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46#include <acpi/acparser.h>
47#include <acpi/acinterp.h>
48#include <acpi/acevents.h>
49#include <acpi/amlcode.h>
50
51#define _COMPONENT ACPI_EXECUTER
52ACPI_MODULE_NAME("exoparg2")
53
54/*!
55 * Naming convention for AML interpreter execution routines.
56 *
57 * The routines that begin execution of AML opcodes are named with a common
58 * convention based upon the number of arguments, the number of target operands,
59 * and whether or not a value is returned:
60 *
61 * AcpiExOpcode_xA_yT_zR
62 *
63 * Where:
64 *
65 * xA - ARGUMENTS: The number of arguments (input operands) that are
66 * required for this opcode type (1 through 6 args).
67 * yT - TARGETS: The number of targets (output operands) that are required
68 * for this opcode type (0, 1, or 2 targets).
69 * zR - RETURN VALUE: Indicates whether this opcode type returns a value
70 * as the function return (0 or 1).
71 *
72 * The AcpiExOpcode* functions are called via the Dispatcher component with
73 * fully resolved operands.
74!*/
75/*******************************************************************************
76 *
77 * FUNCTION: acpi_ex_opcode_2A_0T_0R
78 *
79 * PARAMETERS: walk_state - Current walk state
80 *
81 * RETURN: Status
82 *
83 * DESCRIPTION: Execute opcode with two arguments, no target, and no return
84 * value.
85 *
86 * ALLOCATION: Deletes both operands
87 *
88 ******************************************************************************/
89acpi_status acpi_ex_opcode_2A_0T_0R(struct acpi_walk_state *walk_state)
90{
91 union acpi_operand_object **operand = &walk_state->operands[0];
92 struct acpi_namespace_node *node;
93 u32 value;
94 acpi_status status = AE_OK;
95
96 ACPI_FUNCTION_TRACE_STR(ex_opcode_2A_0T_0R,
97 acpi_ps_get_opcode_name(walk_state->opcode));
98
99 /* Examine the opcode */
100
101 switch (walk_state->opcode) {
102 case AML_NOTIFY_OP: /* Notify (notify_object, notify_value) */
103
104 /* The first operand is a namespace node */
105
106 node = (struct acpi_namespace_node *)operand[0];
107
108 /* Second value is the notify value */
109
110 value = (u32) operand[1]->integer.value;
111
112 /* Are notifies allowed on this object? */
113
114 if (!acpi_ev_is_notify_object(node)) {
115 ACPI_ERROR((AE_INFO,
116 "Unexpected notify object type [%s]",
117 acpi_ut_get_type_name(node->type)));
118
119 status = AE_AML_OPERAND_TYPE;
120 break;
121 }
122#ifdef ACPI_GPE_NOTIFY_CHECK
123 /*
124 * GPE method wake/notify check. Here, we want to ensure that we
125 * don't receive any "DeviceWake" Notifies from a GPE _Lxx or _Exx
126 * GPE method during system runtime. If we do, the GPE is marked
127 * as "wake-only" and disabled.
128 *
129 * 1) Is the Notify() value == device_wake?
130 * 2) Is this a GPE deferred method? (An _Lxx or _Exx method)
131 * 3) Did the original GPE happen at system runtime?
132 * (versus during wake)
133 *
134 * If all three cases are true, this is a wake-only GPE that should
135 * be disabled at runtime.
136 */
137 if (value == 2) { /* device_wake */
138 status =
139 acpi_ev_check_for_wake_only_gpe(walk_state->
140 gpe_event_info);
141 if (ACPI_FAILURE(status)) {
142
143 /* AE_WAKE_ONLY_GPE only error, means ignore this notify */
144
145 return_ACPI_STATUS(AE_OK)
146 }
147 }
148#endif
149
150 /*
151 * Dispatch the notify to the appropriate handler
152 * NOTE: the request is queued for execution after this method
153 * completes. The notify handlers are NOT invoked synchronously
154 * from this thread -- because handlers may in turn run other
155 * control methods.
156 */
157 status = acpi_ev_queue_notify_request(node, value);
158 break;
159
160 default:
161
162 ACPI_ERROR((AE_INFO, "Unknown AML opcode %X",
163 walk_state->opcode));
164 status = AE_AML_BAD_OPCODE;
165 }
166
167 return_ACPI_STATUS(status);
168}
169
170/*******************************************************************************
171 *
172 * FUNCTION: acpi_ex_opcode_2A_2T_1R
173 *
174 * PARAMETERS: walk_state - Current walk state
175 *
176 * RETURN: Status
177 *
178 * DESCRIPTION: Execute a dyadic operator (2 operands) with 2 output targets
179 * and one implicit return value.
180 *
181 ******************************************************************************/
182
183acpi_status acpi_ex_opcode_2A_2T_1R(struct acpi_walk_state *walk_state)
184{
185 union acpi_operand_object **operand = &walk_state->operands[0];
186 union acpi_operand_object *return_desc1 = NULL;
187 union acpi_operand_object *return_desc2 = NULL;
188 acpi_status status;
189
190 ACPI_FUNCTION_TRACE_STR(ex_opcode_2A_2T_1R,
191 acpi_ps_get_opcode_name(walk_state->opcode));
192
193 /* Execute the opcode */
194
195 switch (walk_state->opcode) {
196 case AML_DIVIDE_OP:
197
198 /* Divide (Dividend, Divisor, remainder_result quotient_result) */
199
200 return_desc1 =
201 acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
202 if (!return_desc1) {
203 status = AE_NO_MEMORY;
204 goto cleanup;
205 }
206
207 return_desc2 =
208 acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
209 if (!return_desc2) {
210 status = AE_NO_MEMORY;
211 goto cleanup;
212 }
213
214 /* Quotient to return_desc1, remainder to return_desc2 */
215
216 status = acpi_ut_divide(operand[0]->integer.value,
217 operand[1]->integer.value,
218 &return_desc1->integer.value,
219 &return_desc2->integer.value);
220 if (ACPI_FAILURE(status)) {
221 goto cleanup;
222 }
223 break;
224
225 default:
226
227 ACPI_ERROR((AE_INFO, "Unknown AML opcode %X",
228 walk_state->opcode));
229 status = AE_AML_BAD_OPCODE;
230 goto cleanup;
231 }
232
233 /* Store the results to the target reference operands */
234
235 status = acpi_ex_store(return_desc2, operand[2], walk_state);
236 if (ACPI_FAILURE(status)) {
237 goto cleanup;
238 }
239
240 status = acpi_ex_store(return_desc1, operand[3], walk_state);
241 if (ACPI_FAILURE(status)) {
242 goto cleanup;
243 }
244
245 cleanup:
246 /*
247 * Since the remainder is not returned indirectly, remove a reference to
248 * it. Only the quotient is returned indirectly.
249 */
250 acpi_ut_remove_reference(return_desc2);
251
252 if (ACPI_FAILURE(status)) {
253
254 /* Delete the return object */
255
256 acpi_ut_remove_reference(return_desc1);
257 }
258
259 /* Save return object (the remainder) on success */
260
261 else {
262 walk_state->result_obj = return_desc1;
263 }
264
265 return_ACPI_STATUS(status);
266}
267
268/*******************************************************************************
269 *
270 * FUNCTION: acpi_ex_opcode_2A_1T_1R
271 *
272 * PARAMETERS: walk_state - Current walk state
273 *
274 * RETURN: Status
275 *
276 * DESCRIPTION: Execute opcode with two arguments, one target, and a return
277 * value.
278 *
279 ******************************************************************************/
280
281acpi_status acpi_ex_opcode_2A_1T_1R(struct acpi_walk_state *walk_state)
282{
283 union acpi_operand_object **operand = &walk_state->operands[0];
284 union acpi_operand_object *return_desc = NULL;
285 acpi_integer index;
286 acpi_status status = AE_OK;
287 acpi_size length;
288
289 ACPI_FUNCTION_TRACE_STR(ex_opcode_2A_1T_1R,
290 acpi_ps_get_opcode_name(walk_state->opcode));
291
292 /* Execute the opcode */
293
294 if (walk_state->op_info->flags & AML_MATH) {
295
296 /* All simple math opcodes (add, etc.) */
297
298 return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
299 if (!return_desc) {
300 status = AE_NO_MEMORY;
301 goto cleanup;
302 }
303
304 return_desc->integer.value =
305 acpi_ex_do_math_op(walk_state->opcode,
306 operand[0]->integer.value,
307 operand[1]->integer.value);
308 goto store_result_to_target;
309 }
310
311 switch (walk_state->opcode) {
312 case AML_MOD_OP: /* Mod (Dividend, Divisor, remainder_result (ACPI 2.0) */
313
314 return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
315 if (!return_desc) {
316 status = AE_NO_MEMORY;
317 goto cleanup;
318 }
319
320 /* return_desc will contain the remainder */
321
322 status = acpi_ut_divide(operand[0]->integer.value,
323 operand[1]->integer.value,
324 NULL, &return_desc->integer.value);
325 break;
326
327 case AML_CONCAT_OP: /* Concatenate (Data1, Data2, Result) */
328
329 status = acpi_ex_do_concatenate(operand[0], operand[1],
330 &return_desc, walk_state);
331 break;
332
333 case AML_TO_STRING_OP: /* to_string (Buffer, Length, Result) (ACPI 2.0) */
334
335 /*
336 * Input object is guaranteed to be a buffer at this point (it may have
337 * been converted.) Copy the raw buffer data to a new object of
338 * type String.
339 */
340
341 /*
342 * Get the length of the new string. It is the smallest of:
343 * 1) Length of the input buffer
344 * 2) Max length as specified in the to_string operator
345 * 3) Length of input buffer up to a zero byte (null terminator)
346 *
347 * NOTE: A length of zero is ok, and will create a zero-length, null
348 * terminated string.
349 */
350 length = 0;
351 while ((length < operand[0]->buffer.length) &&
352 (length < operand[1]->integer.value) &&
353 (operand[0]->buffer.pointer[length])) {
354 length++;
355 }
356
357 /* Allocate a new string object */
358
359 return_desc = acpi_ut_create_string_object(length);
360 if (!return_desc) {
361 status = AE_NO_MEMORY;
362 goto cleanup;
363 }
364
365 /*
366 * Copy the raw buffer data with no transform.
367 * (NULL terminated already)
368 */
369 ACPI_MEMCPY(return_desc->string.pointer,
370 operand[0]->buffer.pointer, length);
371 break;
372
373 case AML_CONCAT_RES_OP:
374
375 /* concatenate_res_template (Buffer, Buffer, Result) (ACPI 2.0) */
376
377 status = acpi_ex_concat_template(operand[0], operand[1],
378 &return_desc, walk_state);
379 break;
380
381 case AML_INDEX_OP: /* Index (Source Index Result) */
382
383 /* Create the internal return object */
384
385 return_desc =
386 acpi_ut_create_internal_object(ACPI_TYPE_LOCAL_REFERENCE);
387 if (!return_desc) {
388 status = AE_NO_MEMORY;
389 goto cleanup;
390 }
391
392 /* Initialize the Index reference object */
393
394 index = operand[1]->integer.value;
395 return_desc->reference.value = (u32) index;
396 return_desc->reference.class = ACPI_REFCLASS_INDEX;
397
398 /*
399 * At this point, the Source operand is a String, Buffer, or Package.
400 * Verify that the index is within range.
401 */
402 switch (ACPI_GET_OBJECT_TYPE(operand[0])) {
403 case ACPI_TYPE_STRING:
404
405 if (index >= operand[0]->string.length) {
406 status = AE_AML_STRING_LIMIT;
407 }
408
409 return_desc->reference.target_type =
410 ACPI_TYPE_BUFFER_FIELD;
411 break;
412
413 case ACPI_TYPE_BUFFER:
414
415 if (index >= operand[0]->buffer.length) {
416 status = AE_AML_BUFFER_LIMIT;
417 }
418
419 return_desc->reference.target_type =
420 ACPI_TYPE_BUFFER_FIELD;
421 break;
422
423 case ACPI_TYPE_PACKAGE:
424
425 if (index >= operand[0]->package.count) {
426 status = AE_AML_PACKAGE_LIMIT;
427 }
428
429 return_desc->reference.target_type = ACPI_TYPE_PACKAGE;
430 return_desc->reference.where =
431 &operand[0]->package.elements[index];
432 break;
433
434 default:
435
436 status = AE_AML_INTERNAL;
437 goto cleanup;
438 }
439
440 /* Failure means that the Index was beyond the end of the object */
441
442 if (ACPI_FAILURE(status)) {
443 ACPI_EXCEPTION((AE_INFO, status,
444 "Index (%X%8.8X) is beyond end of object",
445 ACPI_FORMAT_UINT64(index)));
446 goto cleanup;
447 }
448
449 /*
450 * Save the target object and add a reference to it for the life
451 * of the index
452 */
453 return_desc->reference.object = operand[0];
454 acpi_ut_add_reference(operand[0]);
455
456 /* Store the reference to the Target */
457
458 status = acpi_ex_store(return_desc, operand[2], walk_state);
459
460 /* Return the reference */
461
462 walk_state->result_obj = return_desc;
463 goto cleanup;
464
465 default:
466
467 ACPI_ERROR((AE_INFO, "Unknown AML opcode %X",
468 walk_state->opcode));
469 status = AE_AML_BAD_OPCODE;
470 break;
471 }
472
473 store_result_to_target:
474
475 if (ACPI_SUCCESS(status)) {
476 /*
477 * Store the result of the operation (which is now in return_desc) into
478 * the Target descriptor.
479 */
480 status = acpi_ex_store(return_desc, operand[2], walk_state);
481 if (ACPI_FAILURE(status)) {
482 goto cleanup;
483 }
484
485 if (!walk_state->result_obj) {
486 walk_state->result_obj = return_desc;
487 }
488 }
489
490 cleanup:
491
492 /* Delete return object on error */
493
494 if (ACPI_FAILURE(status)) {
495 acpi_ut_remove_reference(return_desc);
496 walk_state->result_obj = NULL;
497 }
498
499 return_ACPI_STATUS(status);
500}
501
502/*******************************************************************************
503 *
504 * FUNCTION: acpi_ex_opcode_2A_0T_1R
505 *
506 * PARAMETERS: walk_state - Current walk state
507 *
508 * RETURN: Status
509 *
510 * DESCRIPTION: Execute opcode with 2 arguments, no target, and a return value
511 *
512 ******************************************************************************/
513
514acpi_status acpi_ex_opcode_2A_0T_1R(struct acpi_walk_state *walk_state)
515{
516 union acpi_operand_object **operand = &walk_state->operands[0];
517 union acpi_operand_object *return_desc = NULL;
518 acpi_status status = AE_OK;
519 u8 logical_result = FALSE;
520
521 ACPI_FUNCTION_TRACE_STR(ex_opcode_2A_0T_1R,
522 acpi_ps_get_opcode_name(walk_state->opcode));
523
524 /* Create the internal return object */
525
526 return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
527 if (!return_desc) {
528 status = AE_NO_MEMORY;
529 goto cleanup;
530 }
531
532 /* Execute the Opcode */
533
534 if (walk_state->op_info->flags & AML_LOGICAL_NUMERIC) {
535
536 /* logical_op (Operand0, Operand1) */
537
538 status = acpi_ex_do_logical_numeric_op(walk_state->opcode,
539 operand[0]->integer.
540 value,
541 operand[1]->integer.
542 value, &logical_result);
543 goto store_logical_result;
544 } else if (walk_state->op_info->flags & AML_LOGICAL) {
545
546 /* logical_op (Operand0, Operand1) */
547
548 status = acpi_ex_do_logical_op(walk_state->opcode, operand[0],
549 operand[1], &logical_result);
550 goto store_logical_result;
551 }
552
553 switch (walk_state->opcode) {
554 case AML_ACQUIRE_OP: /* Acquire (mutex_object, Timeout) */
555
556 status =
557 acpi_ex_acquire_mutex(operand[1], operand[0], walk_state);
558 if (status == AE_TIME) {
559 logical_result = TRUE; /* TRUE = Acquire timed out */
560 status = AE_OK;
561 }
562 break;
563
564 case AML_WAIT_OP: /* Wait (event_object, Timeout) */
565
566 status = acpi_ex_system_wait_event(operand[1], operand[0]);
567 if (status == AE_TIME) {
568 logical_result = TRUE; /* TRUE, Wait timed out */
569 status = AE_OK;
570 }
571 break;
572
573 default:
574
575 ACPI_ERROR((AE_INFO, "Unknown AML opcode %X",
576 walk_state->opcode));
577 status = AE_AML_BAD_OPCODE;
578 goto cleanup;
579 }
580
581 store_logical_result:
582 /*
583 * Set return value to according to logical_result. logical TRUE (all ones)
584 * Default is FALSE (zero)
585 */
586 if (logical_result) {
587 return_desc->integer.value = ACPI_INTEGER_MAX;
588 }
589
590 cleanup:
591
592 /* Delete return object on error */
593
594 if (ACPI_FAILURE(status)) {
595 acpi_ut_remove_reference(return_desc);
596 }
597
598 /* Save return object on success */
599
600 else {
601 walk_state->result_obj = return_desc;
602 }
603
604 return_ACPI_STATUS(status);
605}
diff --git a/drivers/acpi/acpica/exoparg3.c b/drivers/acpi/acpica/exoparg3.c
new file mode 100644
index 00000000000..26dbd5c2c1d
--- /dev/null
+++ b/drivers/acpi/acpica/exoparg3.c
@@ -0,0 +1,273 @@
1
2/******************************************************************************
3 *
4 * Module Name: exoparg3 - AML execution - opcodes with 3 arguments
5 *
6 *****************************************************************************/
7
8/*
9 * Copyright (C) 2000 - 2008, Intel Corp.
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions, and the following disclaimer,
17 * without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 * substantially similar to the "NO WARRANTY" disclaimer below
20 * ("Disclaimer") and any redistribution must be conditioned upon
21 * including a substantially similar Disclaimer requirement for further
22 * binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 * of any contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
30 *
31 * NO WARRANTY
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
43 */
44
45#include <acpi/acpi.h>
46#include <acpi/accommon.h>
47#include <acpi/acinterp.h>
48#include <acpi/acparser.h>
49#include <acpi/amlcode.h>
50
51#define _COMPONENT ACPI_EXECUTER
52ACPI_MODULE_NAME("exoparg3")
53
54/*!
55 * Naming convention for AML interpreter execution routines.
56 *
57 * The routines that begin execution of AML opcodes are named with a common
58 * convention based upon the number of arguments, the number of target operands,
59 * and whether or not a value is returned:
60 *
61 * AcpiExOpcode_xA_yT_zR
62 *
63 * Where:
64 *
65 * xA - ARGUMENTS: The number of arguments (input operands) that are
66 * required for this opcode type (1 through 6 args).
67 * yT - TARGETS: The number of targets (output operands) that are required
68 * for this opcode type (0, 1, or 2 targets).
69 * zR - RETURN VALUE: Indicates whether this opcode type returns a value
70 * as the function return (0 or 1).
71 *
72 * The AcpiExOpcode* functions are called via the Dispatcher component with
73 * fully resolved operands.
74!*/
75/*******************************************************************************
76 *
77 * FUNCTION: acpi_ex_opcode_3A_0T_0R
78 *
79 * PARAMETERS: walk_state - Current walk state
80 *
81 * RETURN: Status
82 *
83 * DESCRIPTION: Execute Triadic operator (3 operands)
84 *
85 ******************************************************************************/
86acpi_status acpi_ex_opcode_3A_0T_0R(struct acpi_walk_state *walk_state)
87{
88 union acpi_operand_object **operand = &walk_state->operands[0];
89 struct acpi_signal_fatal_info *fatal;
90 acpi_status status = AE_OK;
91
92 ACPI_FUNCTION_TRACE_STR(ex_opcode_3A_0T_0R,
93 acpi_ps_get_opcode_name(walk_state->opcode));
94
95 switch (walk_state->opcode) {
96 case AML_FATAL_OP: /* Fatal (fatal_type fatal_code fatal_arg) */
97
98 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
99 "FatalOp: Type %X Code %X Arg %X <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n",
100 (u32) operand[0]->integer.value,
101 (u32) operand[1]->integer.value,
102 (u32) operand[2]->integer.value));
103
104 fatal = ACPI_ALLOCATE(sizeof(struct acpi_signal_fatal_info));
105 if (fatal) {
106 fatal->type = (u32) operand[0]->integer.value;
107 fatal->code = (u32) operand[1]->integer.value;
108 fatal->argument = (u32) operand[2]->integer.value;
109 }
110
111 /* Always signal the OS! */
112
113 status = acpi_os_signal(ACPI_SIGNAL_FATAL, fatal);
114
115 /* Might return while OS is shutting down, just continue */
116
117 ACPI_FREE(fatal);
118 break;
119
120 default:
121
122 ACPI_ERROR((AE_INFO, "Unknown AML opcode %X",
123 walk_state->opcode));
124 status = AE_AML_BAD_OPCODE;
125 goto cleanup;
126 }
127
128 cleanup:
129
130 return_ACPI_STATUS(status);
131}
132
133/*******************************************************************************
134 *
135 * FUNCTION: acpi_ex_opcode_3A_1T_1R
136 *
137 * PARAMETERS: walk_state - Current walk state
138 *
139 * RETURN: Status
140 *
141 * DESCRIPTION: Execute Triadic operator (3 operands)
142 *
143 ******************************************************************************/
144
145acpi_status acpi_ex_opcode_3A_1T_1R(struct acpi_walk_state *walk_state)
146{
147 union acpi_operand_object **operand = &walk_state->operands[0];
148 union acpi_operand_object *return_desc = NULL;
149 char *buffer = NULL;
150 acpi_status status = AE_OK;
151 acpi_integer index;
152 acpi_size length;
153
154 ACPI_FUNCTION_TRACE_STR(ex_opcode_3A_1T_1R,
155 acpi_ps_get_opcode_name(walk_state->opcode));
156
157 switch (walk_state->opcode) {
158 case AML_MID_OP: /* Mid (Source[0], Index[1], Length[2], Result[3]) */
159
160 /*
161 * Create the return object. The Source operand is guaranteed to be
162 * either a String or a Buffer, so just use its type.
163 */
164 return_desc =
165 acpi_ut_create_internal_object(ACPI_GET_OBJECT_TYPE
166 (operand[0]));
167 if (!return_desc) {
168 status = AE_NO_MEMORY;
169 goto cleanup;
170 }
171
172 /* Get the Integer values from the objects */
173
174 index = operand[1]->integer.value;
175 length = (acpi_size) operand[2]->integer.value;
176
177 /*
178 * If the index is beyond the length of the String/Buffer, or if the
179 * requested length is zero, return a zero-length String/Buffer
180 */
181 if (index >= operand[0]->string.length) {
182 length = 0;
183 }
184
185 /* Truncate request if larger than the actual String/Buffer */
186
187 else if ((index + length) > operand[0]->string.length) {
188 length = (acpi_size) operand[0]->string.length -
189 (acpi_size) index;
190 }
191
192 /* Strings always have a sub-pointer, not so for buffers */
193
194 switch (ACPI_GET_OBJECT_TYPE(operand[0])) {
195 case ACPI_TYPE_STRING:
196
197 /* Always allocate a new buffer for the String */
198
199 buffer = ACPI_ALLOCATE_ZEROED((acpi_size) length + 1);
200 if (!buffer) {
201 status = AE_NO_MEMORY;
202 goto cleanup;
203 }
204 break;
205
206 case ACPI_TYPE_BUFFER:
207
208 /* If the requested length is zero, don't allocate a buffer */
209
210 if (length > 0) {
211
212 /* Allocate a new buffer for the Buffer */
213
214 buffer = ACPI_ALLOCATE_ZEROED(length);
215 if (!buffer) {
216 status = AE_NO_MEMORY;
217 goto cleanup;
218 }
219 }
220 break;
221
222 default: /* Should not happen */
223
224 status = AE_AML_OPERAND_TYPE;
225 goto cleanup;
226 }
227
228 if (buffer) {
229
230 /* We have a buffer, copy the portion requested */
231
232 ACPI_MEMCPY(buffer, operand[0]->string.pointer + index,
233 length);
234 }
235
236 /* Set the length of the new String/Buffer */
237
238 return_desc->string.pointer = buffer;
239 return_desc->string.length = (u32) length;
240
241 /* Mark buffer initialized */
242
243 return_desc->buffer.flags |= AOPOBJ_DATA_VALID;
244 break;
245
246 default:
247
248 ACPI_ERROR((AE_INFO, "Unknown AML opcode %X",
249 walk_state->opcode));
250 status = AE_AML_BAD_OPCODE;
251 goto cleanup;
252 }
253
254 /* Store the result in the target */
255
256 status = acpi_ex_store(return_desc, operand[3], walk_state);
257
258 cleanup:
259
260 /* Delete return object on error */
261
262 if (ACPI_FAILURE(status) || walk_state->result_obj) {
263 acpi_ut_remove_reference(return_desc);
264 walk_state->result_obj = NULL;
265 }
266
267 /* Set the return object and exit */
268
269 else {
270 walk_state->result_obj = return_desc;
271 }
272 return_ACPI_STATUS(status);
273}
diff --git a/drivers/acpi/acpica/exoparg6.c b/drivers/acpi/acpica/exoparg6.c
new file mode 100644
index 00000000000..bbbba504979
--- /dev/null
+++ b/drivers/acpi/acpica/exoparg6.c
@@ -0,0 +1,341 @@
1
2/******************************************************************************
3 *
4 * Module Name: exoparg6 - AML execution - opcodes with 6 arguments
5 *
6 *****************************************************************************/
7
8/*
9 * Copyright (C) 2000 - 2008, Intel Corp.
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions, and the following disclaimer,
17 * without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 * substantially similar to the "NO WARRANTY" disclaimer below
20 * ("Disclaimer") and any redistribution must be conditioned upon
21 * including a substantially similar Disclaimer requirement for further
22 * binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 * of any contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
30 *
31 * NO WARRANTY
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
43 */
44
45#include <acpi/acpi.h>
46#include <acpi/accommon.h>
47#include <acpi/acinterp.h>
48#include <acpi/acparser.h>
49#include <acpi/amlcode.h>
50
51#define _COMPONENT ACPI_EXECUTER
52ACPI_MODULE_NAME("exoparg6")
53
54/*!
55 * Naming convention for AML interpreter execution routines.
56 *
57 * The routines that begin execution of AML opcodes are named with a common
58 * convention based upon the number of arguments, the number of target operands,
59 * and whether or not a value is returned:
60 *
61 * AcpiExOpcode_xA_yT_zR
62 *
63 * Where:
64 *
65 * xA - ARGUMENTS: The number of arguments (input operands) that are
66 * required for this opcode type (1 through 6 args).
67 * yT - TARGETS: The number of targets (output operands) that are required
68 * for this opcode type (0, 1, or 2 targets).
69 * zR - RETURN VALUE: Indicates whether this opcode type returns a value
70 * as the function return (0 or 1).
71 *
72 * The AcpiExOpcode* functions are called via the Dispatcher component with
73 * fully resolved operands.
74!*/
75/* Local prototypes */
76static u8
77acpi_ex_do_match(u32 match_op,
78 union acpi_operand_object *package_obj,
79 union acpi_operand_object *match_obj);
80
81/*******************************************************************************
82 *
83 * FUNCTION: acpi_ex_do_match
84 *
85 * PARAMETERS: match_op - The AML match operand
86 * package_obj - Object from the target package
87 * match_obj - Object to be matched
88 *
89 * RETURN: TRUE if the match is successful, FALSE otherwise
90 *
91 * DESCRIPTION: Implements the low-level match for the ASL Match operator.
92 * Package elements will be implicitly converted to the type of
93 * the match object (Integer/Buffer/String).
94 *
95 ******************************************************************************/
96
97static u8
98acpi_ex_do_match(u32 match_op,
99 union acpi_operand_object *package_obj,
100 union acpi_operand_object *match_obj)
101{
102 u8 logical_result = TRUE;
103 acpi_status status;
104
105 /*
106 * Note: Since the package_obj/match_obj ordering is opposite to that of
107 * the standard logical operators, we have to reverse them when we call
108 * do_logical_op in order to make the implicit conversion rules work
109 * correctly. However, this means we have to flip the entire equation
110 * also. A bit ugly perhaps, but overall, better than fussing the
111 * parameters around at runtime, over and over again.
112 *
113 * Below, P[i] refers to the package element, M refers to the Match object.
114 */
115 switch (match_op) {
116 case MATCH_MTR:
117
118 /* Always true */
119
120 break;
121
122 case MATCH_MEQ:
123
124 /*
125 * True if equal: (P[i] == M)
126 * Change to: (M == P[i])
127 */
128 status =
129 acpi_ex_do_logical_op(AML_LEQUAL_OP, match_obj, package_obj,
130 &logical_result);
131 if (ACPI_FAILURE(status)) {
132 return (FALSE);
133 }
134 break;
135
136 case MATCH_MLE:
137
138 /*
139 * True if less than or equal: (P[i] <= M) (P[i] not_greater than M)
140 * Change to: (M >= P[i]) (M not_less than P[i])
141 */
142 status =
143 acpi_ex_do_logical_op(AML_LLESS_OP, match_obj, package_obj,
144 &logical_result);
145 if (ACPI_FAILURE(status)) {
146 return (FALSE);
147 }
148 logical_result = (u8) ! logical_result;
149 break;
150
151 case MATCH_MLT:
152
153 /*
154 * True if less than: (P[i] < M)
155 * Change to: (M > P[i])
156 */
157 status =
158 acpi_ex_do_logical_op(AML_LGREATER_OP, match_obj,
159 package_obj, &logical_result);
160 if (ACPI_FAILURE(status)) {
161 return (FALSE);
162 }
163 break;
164
165 case MATCH_MGE:
166
167 /*
168 * True if greater than or equal: (P[i] >= M) (P[i] not_less than M)
169 * Change to: (M <= P[i]) (M not_greater than P[i])
170 */
171 status =
172 acpi_ex_do_logical_op(AML_LGREATER_OP, match_obj,
173 package_obj, &logical_result);
174 if (ACPI_FAILURE(status)) {
175 return (FALSE);
176 }
177 logical_result = (u8) ! logical_result;
178 break;
179
180 case MATCH_MGT:
181
182 /*
183 * True if greater than: (P[i] > M)
184 * Change to: (M < P[i])
185 */
186 status =
187 acpi_ex_do_logical_op(AML_LLESS_OP, match_obj, package_obj,
188 &logical_result);
189 if (ACPI_FAILURE(status)) {
190 return (FALSE);
191 }
192 break;
193
194 default:
195
196 /* Undefined */
197
198 return (FALSE);
199 }
200
201 return logical_result;
202}
203
204/*******************************************************************************
205 *
206 * FUNCTION: acpi_ex_opcode_6A_0T_1R
207 *
208 * PARAMETERS: walk_state - Current walk state
209 *
210 * RETURN: Status
211 *
212 * DESCRIPTION: Execute opcode with 6 arguments, no target, and a return value
213 *
214 ******************************************************************************/
215
216acpi_status acpi_ex_opcode_6A_0T_1R(struct acpi_walk_state * walk_state)
217{
218 union acpi_operand_object **operand = &walk_state->operands[0];
219 union acpi_operand_object *return_desc = NULL;
220 acpi_status status = AE_OK;
221 acpi_integer index;
222 union acpi_operand_object *this_element;
223
224 ACPI_FUNCTION_TRACE_STR(ex_opcode_6A_0T_1R,
225 acpi_ps_get_opcode_name(walk_state->opcode));
226
227 switch (walk_state->opcode) {
228 case AML_MATCH_OP:
229 /*
230 * Match (search_pkg[0], match_op1[1], match_obj1[2],
231 * match_op2[3], match_obj2[4], start_index[5])
232 */
233
234 /* Validate both Match Term Operators (MTR, MEQ, etc.) */
235
236 if ((operand[1]->integer.value > MAX_MATCH_OPERATOR) ||
237 (operand[3]->integer.value > MAX_MATCH_OPERATOR)) {
238 ACPI_ERROR((AE_INFO, "Match operator out of range"));
239 status = AE_AML_OPERAND_VALUE;
240 goto cleanup;
241 }
242
243 /* Get the package start_index, validate against the package length */
244
245 index = operand[5]->integer.value;
246 if (index >= operand[0]->package.count) {
247 ACPI_ERROR((AE_INFO,
248 "Index (%X%8.8X) beyond package end (%X)",
249 ACPI_FORMAT_UINT64(index),
250 operand[0]->package.count));
251 status = AE_AML_PACKAGE_LIMIT;
252 goto cleanup;
253 }
254
255 /* Create an integer for the return value */
256
257 return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
258 if (!return_desc) {
259 status = AE_NO_MEMORY;
260 goto cleanup;
261
262 }
263
264 /* Default return value if no match found */
265
266 return_desc->integer.value = ACPI_INTEGER_MAX;
267
268 /*
269 * Examine each element until a match is found. Both match conditions
270 * must be satisfied for a match to occur. Within the loop,
271 * "continue" signifies that the current element does not match
272 * and the next should be examined.
273 *
274 * Upon finding a match, the loop will terminate via "break" at
275 * the bottom. If it terminates "normally", match_value will be
276 * ACPI_INTEGER_MAX (Ones) (its initial value) indicating that no
277 * match was found.
278 */
279 for (; index < operand[0]->package.count; index++) {
280
281 /* Get the current package element */
282
283 this_element = operand[0]->package.elements[index];
284
285 /* Treat any uninitialized (NULL) elements as non-matching */
286
287 if (!this_element) {
288 continue;
289 }
290
291 /*
292 * Both match conditions must be satisfied. Execution of a continue
293 * (proceed to next iteration of enclosing for loop) signifies a
294 * non-match.
295 */
296 if (!acpi_ex_do_match((u32) operand[1]->integer.value,
297 this_element, operand[2])) {
298 continue;
299 }
300
301 if (!acpi_ex_do_match((u32) operand[3]->integer.value,
302 this_element, operand[4])) {
303 continue;
304 }
305
306 /* Match found: Index is the return value */
307
308 return_desc->integer.value = index;
309 break;
310 }
311 break;
312
313 case AML_LOAD_TABLE_OP:
314
315 status = acpi_ex_load_table_op(walk_state, &return_desc);
316 break;
317
318 default:
319
320 ACPI_ERROR((AE_INFO, "Unknown AML opcode %X",
321 walk_state->opcode));
322 status = AE_AML_BAD_OPCODE;
323 goto cleanup;
324 }
325
326 cleanup:
327
328 /* Delete return object on error */
329
330 if (ACPI_FAILURE(status)) {
331 acpi_ut_remove_reference(return_desc);
332 }
333
334 /* Save return object on success */
335
336 else {
337 walk_state->result_obj = return_desc;
338 }
339
340 return_ACPI_STATUS(status);
341}
diff --git a/drivers/acpi/acpica/exprep.c b/drivers/acpi/acpica/exprep.c
new file mode 100644
index 00000000000..8f2baa934e9
--- /dev/null
+++ b/drivers/acpi/acpica/exprep.c
@@ -0,0 +1,590 @@
1
2/******************************************************************************
3 *
4 * Module Name: exprep - ACPI AML (p-code) execution - field prep utilities
5 *
6 *****************************************************************************/
7
8/*
9 * Copyright (C) 2000 - 2008, Intel Corp.
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions, and the following disclaimer,
17 * without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 * substantially similar to the "NO WARRANTY" disclaimer below
20 * ("Disclaimer") and any redistribution must be conditioned upon
21 * including a substantially similar Disclaimer requirement for further
22 * binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 * of any contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
30 *
31 * NO WARRANTY
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
43 */
44
45#include <acpi/acpi.h>
46#include <acpi/accommon.h>
47#include <acpi/acinterp.h>
48#include <acpi/amlcode.h>
49#include <acpi/acnamesp.h>
50
51#define _COMPONENT ACPI_EXECUTER
52ACPI_MODULE_NAME("exprep")
53
54/* Local prototypes */
55static u32
56acpi_ex_decode_field_access(union acpi_operand_object *obj_desc,
57 u8 field_flags, u32 * return_byte_alignment);
58
59#ifdef ACPI_UNDER_DEVELOPMENT
60
61static u32
62acpi_ex_generate_access(u32 field_bit_offset,
63 u32 field_bit_length, u32 region_length);
64
65/*******************************************************************************
66 *
67 * FUNCTION: acpi_ex_generate_access
68 *
69 * PARAMETERS: field_bit_offset - Start of field within parent region/buffer
70 * field_bit_length - Length of field in bits
71 * region_length - Length of parent in bytes
72 *
73 * RETURN: Field granularity (8, 16, 32 or 64) and
74 * byte_alignment (1, 2, 3, or 4)
75 *
76 * DESCRIPTION: Generate an optimal access width for fields defined with the
77 * any_acc keyword.
78 *
79 * NOTE: Need to have the region_length in order to check for boundary
80 * conditions (end-of-region). However, the region_length is a deferred
81 * operation. Therefore, to complete this implementation, the generation
82 * of this access width must be deferred until the region length has
83 * been evaluated.
84 *
85 ******************************************************************************/
86
87static u32
88acpi_ex_generate_access(u32 field_bit_offset,
89 u32 field_bit_length, u32 region_length)
90{
91 u32 field_byte_length;
92 u32 field_byte_offset;
93 u32 field_byte_end_offset;
94 u32 access_byte_width;
95 u32 field_start_offset;
96 u32 field_end_offset;
97 u32 minimum_access_width = 0xFFFFFFFF;
98 u32 minimum_accesses = 0xFFFFFFFF;
99 u32 accesses;
100
101 ACPI_FUNCTION_TRACE(ex_generate_access);
102
103 /* Round Field start offset and length to "minimal" byte boundaries */
104
105 field_byte_offset = ACPI_DIV_8(ACPI_ROUND_DOWN(field_bit_offset, 8));
106 field_byte_end_offset = ACPI_DIV_8(ACPI_ROUND_UP(field_bit_length +
107 field_bit_offset, 8));
108 field_byte_length = field_byte_end_offset - field_byte_offset;
109
110 ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
111 "Bit length %d, Bit offset %d\n",
112 field_bit_length, field_bit_offset));
113
114 ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
115 "Byte Length %d, Byte Offset %d, End Offset %d\n",
116 field_byte_length, field_byte_offset,
117 field_byte_end_offset));
118
119 /*
120 * Iterative search for the maximum access width that is both aligned
121 * and does not go beyond the end of the region
122 *
123 * Start at byte_acc and work upwards to qword_acc max. (1,2,4,8 bytes)
124 */
125 for (access_byte_width = 1; access_byte_width <= 8;
126 access_byte_width <<= 1) {
127 /*
128 * 1) Round end offset up to next access boundary and make sure that
129 * this does not go beyond the end of the parent region.
130 * 2) When the Access width is greater than the field_byte_length, we
131 * are done. (This does not optimize for the perfectly aligned
132 * case yet).
133 */
134 if (ACPI_ROUND_UP(field_byte_end_offset, access_byte_width) <=
135 region_length) {
136 field_start_offset =
137 ACPI_ROUND_DOWN(field_byte_offset,
138 access_byte_width) /
139 access_byte_width;
140
141 field_end_offset =
142 ACPI_ROUND_UP((field_byte_length +
143 field_byte_offset),
144 access_byte_width) /
145 access_byte_width;
146
147 accesses = field_end_offset - field_start_offset;
148
149 ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
150 "AccessWidth %d end is within region\n",
151 access_byte_width));
152
153 ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
154 "Field Start %d, Field End %d -- requires %d accesses\n",
155 field_start_offset, field_end_offset,
156 accesses));
157
158 /* Single access is optimal */
159
160 if (accesses <= 1) {
161 ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
162 "Entire field can be accessed with one operation of size %d\n",
163 access_byte_width));
164 return_VALUE(access_byte_width);
165 }
166
167 /*
168 * Fits in the region, but requires more than one read/write.
169 * try the next wider access on next iteration
170 */
171 if (accesses < minimum_accesses) {
172 minimum_accesses = accesses;
173 minimum_access_width = access_byte_width;
174 }
175 } else {
176 ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
177 "AccessWidth %d end is NOT within region\n",
178 access_byte_width));
179 if (access_byte_width == 1) {
180 ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
181 "Field goes beyond end-of-region!\n"));
182
183 /* Field does not fit in the region at all */
184
185 return_VALUE(0);
186 }
187
188 /*
189 * This width goes beyond the end-of-region, back off to
190 * previous access
191 */
192 ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
193 "Backing off to previous optimal access width of %d\n",
194 minimum_access_width));
195 return_VALUE(minimum_access_width);
196 }
197 }
198
199 /*
200 * Could not read/write field with one operation,
201 * just use max access width
202 */
203 ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
204 "Cannot access field in one operation, using width 8\n"));
205 return_VALUE(8);
206}
207#endif /* ACPI_UNDER_DEVELOPMENT */
208
209/*******************************************************************************
210 *
211 * FUNCTION: acpi_ex_decode_field_access
212 *
213 * PARAMETERS: obj_desc - Field object
214 * field_flags - Encoded fieldflags (contains access bits)
215 * return_byte_alignment - Where the byte alignment is returned
216 *
217 * RETURN: Field granularity (8, 16, 32 or 64) and
218 * byte_alignment (1, 2, 3, or 4)
219 *
220 * DESCRIPTION: Decode the access_type bits of a field definition.
221 *
222 ******************************************************************************/
223
224static u32
225acpi_ex_decode_field_access(union acpi_operand_object *obj_desc,
226 u8 field_flags, u32 * return_byte_alignment)
227{
228 u32 access;
229 u32 byte_alignment;
230 u32 bit_length;
231
232 ACPI_FUNCTION_TRACE(ex_decode_field_access);
233
234 access = (field_flags & AML_FIELD_ACCESS_TYPE_MASK);
235
236 switch (access) {
237 case AML_FIELD_ACCESS_ANY:
238
239#ifdef ACPI_UNDER_DEVELOPMENT
240 byte_alignment =
241 acpi_ex_generate_access(obj_desc->common_field.
242 start_field_bit_offset,
243 obj_desc->common_field.bit_length,
244 0xFFFFFFFF
245 /* Temp until we pass region_length as parameter */
246 );
247 bit_length = byte_alignment * 8;
248#endif
249
250 byte_alignment = 1;
251 bit_length = 8;
252 break;
253
254 case AML_FIELD_ACCESS_BYTE:
255 case AML_FIELD_ACCESS_BUFFER: /* ACPI 2.0 (SMBus Buffer) */
256 byte_alignment = 1;
257 bit_length = 8;
258 break;
259
260 case AML_FIELD_ACCESS_WORD:
261 byte_alignment = 2;
262 bit_length = 16;
263 break;
264
265 case AML_FIELD_ACCESS_DWORD:
266 byte_alignment = 4;
267 bit_length = 32;
268 break;
269
270 case AML_FIELD_ACCESS_QWORD: /* ACPI 2.0 */
271 byte_alignment = 8;
272 bit_length = 64;
273 break;
274
275 default:
276 /* Invalid field access type */
277
278 ACPI_ERROR((AE_INFO, "Unknown field access type %X", access));
279 return_UINT32(0);
280 }
281
282 if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_BUFFER_FIELD) {
283 /*
284 * buffer_field access can be on any byte boundary, so the
285 * byte_alignment is always 1 byte -- regardless of any byte_alignment
286 * implied by the field access type.
287 */
288 byte_alignment = 1;
289 }
290
291 *return_byte_alignment = byte_alignment;
292 return_UINT32(bit_length);
293}
294
295/*******************************************************************************
296 *
297 * FUNCTION: acpi_ex_prep_common_field_object
298 *
299 * PARAMETERS: obj_desc - The field object
300 * field_flags - Access, lock_rule, and update_rule.
301 * The format of a field_flag is described
302 * in the ACPI specification
303 * field_attribute - Special attributes (not used)
304 * field_bit_position - Field start position
305 * field_bit_length - Field length in number of bits
306 *
307 * RETURN: Status
308 *
309 * DESCRIPTION: Initialize the areas of the field object that are common
310 * to the various types of fields. Note: This is very "sensitive"
311 * code because we are solving the general case for field
312 * alignment.
313 *
314 ******************************************************************************/
315
316acpi_status
317acpi_ex_prep_common_field_object(union acpi_operand_object *obj_desc,
318 u8 field_flags,
319 u8 field_attribute,
320 u32 field_bit_position, u32 field_bit_length)
321{
322 u32 access_bit_width;
323 u32 byte_alignment;
324 u32 nearest_byte_address;
325
326 ACPI_FUNCTION_TRACE(ex_prep_common_field_object);
327
328 /*
329 * Note: the structure being initialized is the
330 * ACPI_COMMON_FIELD_INFO; No structure fields outside of the common
331 * area are initialized by this procedure.
332 */
333 obj_desc->common_field.field_flags = field_flags;
334 obj_desc->common_field.attribute = field_attribute;
335 obj_desc->common_field.bit_length = field_bit_length;
336
337 /*
338 * Decode the access type so we can compute offsets. The access type gives
339 * two pieces of information - the width of each field access and the
340 * necessary byte_alignment (address granularity) of the access.
341 *
342 * For any_acc, the access_bit_width is the largest width that is both
343 * necessary and possible in an attempt to access the whole field in one
344 * I/O operation. However, for any_acc, the byte_alignment is always one
345 * byte.
346 *
347 * For all Buffer Fields, the byte_alignment is always one byte.
348 *
349 * For all other access types (Byte, Word, Dword, Qword), the Bitwidth is
350 * the same (equivalent) as the byte_alignment.
351 */
352 access_bit_width = acpi_ex_decode_field_access(obj_desc, field_flags,
353 &byte_alignment);
354 if (!access_bit_width) {
355 return_ACPI_STATUS(AE_AML_OPERAND_VALUE);
356 }
357
358 /* Setup width (access granularity) fields */
359
360 obj_desc->common_field.access_byte_width = (u8)
361 ACPI_DIV_8(access_bit_width); /* 1, 2, 4, 8 */
362
363 obj_desc->common_field.access_bit_width = (u8) access_bit_width;
364
365 /*
366 * base_byte_offset is the address of the start of the field within the
367 * region. It is the byte address of the first *datum* (field-width data
368 * unit) of the field. (i.e., the first datum that contains at least the
369 * first *bit* of the field.)
370 *
371 * Note: byte_alignment is always either equal to the access_bit_width or 8
372 * (Byte access), and it defines the addressing granularity of the parent
373 * region or buffer.
374 */
375 nearest_byte_address =
376 ACPI_ROUND_BITS_DOWN_TO_BYTES(field_bit_position);
377 obj_desc->common_field.base_byte_offset = (u32)
378 ACPI_ROUND_DOWN(nearest_byte_address, byte_alignment);
379
380 /*
381 * start_field_bit_offset is the offset of the first bit of the field within
382 * a field datum.
383 */
384 obj_desc->common_field.start_field_bit_offset = (u8)
385 (field_bit_position -
386 ACPI_MUL_8(obj_desc->common_field.base_byte_offset));
387
388 /*
389 * Does the entire field fit within a single field access element? (datum)
390 * (i.e., without crossing a datum boundary)
391 */
392 if ((obj_desc->common_field.start_field_bit_offset +
393 field_bit_length) <= (u16) access_bit_width) {
394 obj_desc->common.flags |= AOPOBJ_SINGLE_DATUM;
395 }
396
397 return_ACPI_STATUS(AE_OK);
398}
399
400/*******************************************************************************
401 *
402 * FUNCTION: acpi_ex_prep_field_value
403 *
404 * PARAMETERS: Info - Contains all field creation info
405 *
406 * RETURN: Status
407 *
408 * DESCRIPTION: Construct an union acpi_operand_object of type def_field and
409 * connect it to the parent Node.
410 *
411 ******************************************************************************/
412
413acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info)
414{
415 union acpi_operand_object *obj_desc;
416 union acpi_operand_object *second_desc = NULL;
417 u32 type;
418 acpi_status status;
419
420 ACPI_FUNCTION_TRACE(ex_prep_field_value);
421
422 /* Parameter validation */
423
424 if (info->field_type != ACPI_TYPE_LOCAL_INDEX_FIELD) {
425 if (!info->region_node) {
426 ACPI_ERROR((AE_INFO, "Null RegionNode"));
427 return_ACPI_STATUS(AE_AML_NO_OPERAND);
428 }
429
430 type = acpi_ns_get_type(info->region_node);
431 if (type != ACPI_TYPE_REGION) {
432 ACPI_ERROR((AE_INFO,
433 "Needed Region, found type %X (%s)",
434 type, acpi_ut_get_type_name(type)));
435
436 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
437 }
438 }
439
440 /* Allocate a new field object */
441
442 obj_desc = acpi_ut_create_internal_object(info->field_type);
443 if (!obj_desc) {
444 return_ACPI_STATUS(AE_NO_MEMORY);
445 }
446
447 /* Initialize areas of the object that are common to all fields */
448
449 obj_desc->common_field.node = info->field_node;
450 status = acpi_ex_prep_common_field_object(obj_desc, info->field_flags,
451 info->attribute,
452 info->field_bit_position,
453 info->field_bit_length);
454 if (ACPI_FAILURE(status)) {
455 acpi_ut_delete_object_desc(obj_desc);
456 return_ACPI_STATUS(status);
457 }
458
459 /* Initialize areas of the object that are specific to the field type */
460
461 switch (info->field_type) {
462 case ACPI_TYPE_LOCAL_REGION_FIELD:
463
464 obj_desc->field.region_obj =
465 acpi_ns_get_attached_object(info->region_node);
466
467 /* An additional reference for the container */
468
469 acpi_ut_add_reference(obj_desc->field.region_obj);
470
471 ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
472 "RegionField: BitOff %X, Off %X, Gran %X, Region %p\n",
473 obj_desc->field.start_field_bit_offset,
474 obj_desc->field.base_byte_offset,
475 obj_desc->field.access_byte_width,
476 obj_desc->field.region_obj));
477 break;
478
479 case ACPI_TYPE_LOCAL_BANK_FIELD:
480
481 obj_desc->bank_field.value = info->bank_value;
482 obj_desc->bank_field.region_obj =
483 acpi_ns_get_attached_object(info->region_node);
484 obj_desc->bank_field.bank_obj =
485 acpi_ns_get_attached_object(info->register_node);
486
487 /* An additional reference for the attached objects */
488
489 acpi_ut_add_reference(obj_desc->bank_field.region_obj);
490 acpi_ut_add_reference(obj_desc->bank_field.bank_obj);
491
492 ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
493 "Bank Field: BitOff %X, Off %X, Gran %X, Region %p, BankReg %p\n",
494 obj_desc->bank_field.start_field_bit_offset,
495 obj_desc->bank_field.base_byte_offset,
496 obj_desc->field.access_byte_width,
497 obj_desc->bank_field.region_obj,
498 obj_desc->bank_field.bank_obj));
499
500 /*
501 * Remember location in AML stream of the field unit
502 * opcode and operands -- since the bank_value
503 * operands must be evaluated.
504 */
505 second_desc = obj_desc->common.next_object;
506 second_desc->extra.aml_start =
507 ACPI_CAST_PTR(union acpi_parse_object,
508 info->data_register_node)->named.data;
509 second_desc->extra.aml_length =
510 ACPI_CAST_PTR(union acpi_parse_object,
511 info->data_register_node)->named.length;
512
513 break;
514
515 case ACPI_TYPE_LOCAL_INDEX_FIELD:
516
517 /* Get the Index and Data registers */
518
519 obj_desc->index_field.index_obj =
520 acpi_ns_get_attached_object(info->register_node);
521 obj_desc->index_field.data_obj =
522 acpi_ns_get_attached_object(info->data_register_node);
523
524 if (!obj_desc->index_field.data_obj
525 || !obj_desc->index_field.index_obj) {
526 ACPI_ERROR((AE_INFO,
527 "Null Index Object during field prep"));
528 acpi_ut_delete_object_desc(obj_desc);
529 return_ACPI_STATUS(AE_AML_INTERNAL);
530 }
531
532 /* An additional reference for the attached objects */
533
534 acpi_ut_add_reference(obj_desc->index_field.data_obj);
535 acpi_ut_add_reference(obj_desc->index_field.index_obj);
536
537 /*
538 * April 2006: Changed to match MS behavior
539 *
540 * The value written to the Index register is the byte offset of the
541 * target field in units of the granularity of the index_field
542 *
543 * Previously, the value was calculated as an index in terms of the
544 * width of the Data register, as below:
545 *
546 * obj_desc->index_field.Value = (u32)
547 * (Info->field_bit_position / ACPI_MUL_8 (
548 * obj_desc->Field.access_byte_width));
549 *
550 * February 2006: Tried value as a byte offset:
551 * obj_desc->index_field.Value = (u32)
552 * ACPI_DIV_8 (Info->field_bit_position);
553 */
554 obj_desc->index_field.value =
555 (u32) ACPI_ROUND_DOWN(ACPI_DIV_8(info->field_bit_position),
556 obj_desc->index_field.
557 access_byte_width);
558
559 ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
560 "IndexField: BitOff %X, Off %X, Value %X, Gran %X, Index %p, Data %p\n",
561 obj_desc->index_field.start_field_bit_offset,
562 obj_desc->index_field.base_byte_offset,
563 obj_desc->index_field.value,
564 obj_desc->field.access_byte_width,
565 obj_desc->index_field.index_obj,
566 obj_desc->index_field.data_obj));
567 break;
568
569 default:
570 /* No other types should get here */
571 break;
572 }
573
574 /*
575 * Store the constructed descriptor (obj_desc) into the parent Node,
576 * preserving the current type of that named_obj.
577 */
578 status = acpi_ns_attach_object(info->field_node, obj_desc,
579 acpi_ns_get_type(info->field_node));
580
581 ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
582 "Set NamedObj %p [%4.4s], ObjDesc %p\n",
583 info->field_node,
584 acpi_ut_get_node_name(info->field_node), obj_desc));
585
586 /* Remove local reference to the object */
587
588 acpi_ut_remove_reference(obj_desc);
589 return_ACPI_STATUS(status);
590}
diff --git a/drivers/acpi/acpica/exregion.c b/drivers/acpi/acpica/exregion.c
new file mode 100644
index 00000000000..ceb269e45ab
--- /dev/null
+++ b/drivers/acpi/acpica/exregion.c
@@ -0,0 +1,499 @@
1
2/******************************************************************************
3 *
4 * Module Name: exregion - ACPI default op_region (address space) handlers
5 *
6 *****************************************************************************/
7
8/*
9 * Copyright (C) 2000 - 2008, Intel Corp.
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions, and the following disclaimer,
17 * without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 * substantially similar to the "NO WARRANTY" disclaimer below
20 * ("Disclaimer") and any redistribution must be conditioned upon
21 * including a substantially similar Disclaimer requirement for further
22 * binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 * of any contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
30 *
31 * NO WARRANTY
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
43 */
44
45#include <acpi/acpi.h>
46#include <acpi/accommon.h>
47#include <acpi/acinterp.h>
48
49#define _COMPONENT ACPI_EXECUTER
50ACPI_MODULE_NAME("exregion")
51
52/*******************************************************************************
53 *
54 * FUNCTION: acpi_ex_system_memory_space_handler
55 *
56 * PARAMETERS: Function - Read or Write operation
57 * Address - Where in the space to read or write
58 * bit_width - Field width in bits (8, 16, or 32)
59 * Value - Pointer to in or out value
60 * handler_context - Pointer to Handler's context
61 * region_context - Pointer to context specific to the
62 * accessed region
63 *
64 * RETURN: Status
65 *
66 * DESCRIPTION: Handler for the System Memory address space (Op Region)
67 *
68 ******************************************************************************/
69acpi_status
70acpi_ex_system_memory_space_handler(u32 function,
71 acpi_physical_address address,
72 u32 bit_width,
73 acpi_integer * value,
74 void *handler_context, void *region_context)
75{
76 acpi_status status = AE_OK;
77 void *logical_addr_ptr = NULL;
78 struct acpi_mem_space_context *mem_info = region_context;
79 u32 length;
80 acpi_size window_size;
81#ifdef ACPI_MISALIGNMENT_NOT_SUPPORTED
82 u32 remainder;
83#endif
84
85 ACPI_FUNCTION_TRACE(ex_system_memory_space_handler);
86
87 /* Validate and translate the bit width */
88
89 switch (bit_width) {
90 case 8:
91 length = 1;
92 break;
93
94 case 16:
95 length = 2;
96 break;
97
98 case 32:
99 length = 4;
100 break;
101
102 case 64:
103 length = 8;
104 break;
105
106 default:
107 ACPI_ERROR((AE_INFO, "Invalid SystemMemory width %d",
108 bit_width));
109 return_ACPI_STATUS(AE_AML_OPERAND_VALUE);
110 }
111
112#ifdef ACPI_MISALIGNMENT_NOT_SUPPORTED
113 /*
114 * Hardware does not support non-aligned data transfers, we must verify
115 * the request.
116 */
117 (void)acpi_ut_short_divide((acpi_integer) address, length, NULL,
118 &remainder);
119 if (remainder != 0) {
120 return_ACPI_STATUS(AE_AML_ALIGNMENT);
121 }
122#endif
123
124 /*
125 * Does the request fit into the cached memory mapping?
126 * Is 1) Address below the current mapping? OR
127 * 2) Address beyond the current mapping?
128 */
129 if ((address < mem_info->mapped_physical_address) ||
130 (((acpi_integer) address + length) > ((acpi_integer)
131 mem_info->
132 mapped_physical_address +
133 mem_info->mapped_length))) {
134 /*
135 * The request cannot be resolved by the current memory mapping;
136 * Delete the existing mapping and create a new one.
137 */
138 if (mem_info->mapped_length) {
139
140 /* Valid mapping, delete it */
141
142 acpi_os_unmap_memory(mem_info->mapped_logical_address,
143 mem_info->mapped_length);
144 }
145
146 /*
147 * Don't attempt to map memory beyond the end of the region, and
148 * constrain the maximum mapping size to something reasonable.
149 */
150 window_size = (acpi_size)
151 ((mem_info->address + mem_info->length) - address);
152
153 if (window_size > ACPI_SYSMEM_REGION_WINDOW_SIZE) {
154 window_size = ACPI_SYSMEM_REGION_WINDOW_SIZE;
155 }
156
157 /* Create a new mapping starting at the address given */
158
159 mem_info->mapped_logical_address =
160 acpi_os_map_memory((acpi_physical_address) address, window_size);
161 if (!mem_info->mapped_logical_address) {
162 ACPI_ERROR((AE_INFO,
163 "Could not map memory at %8.8X%8.8X, size %X",
164 ACPI_FORMAT_NATIVE_UINT(address),
165 (u32) window_size));
166 mem_info->mapped_length = 0;
167 return_ACPI_STATUS(AE_NO_MEMORY);
168 }
169
170 /* Save the physical address and mapping size */
171
172 mem_info->mapped_physical_address = address;
173 mem_info->mapped_length = window_size;
174 }
175
176 /*
177 * Generate a logical pointer corresponding to the address we want to
178 * access
179 */
180 logical_addr_ptr = mem_info->mapped_logical_address +
181 ((acpi_integer) address -
182 (acpi_integer) mem_info->mapped_physical_address);
183
184 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
185 "System-Memory (width %d) R/W %d Address=%8.8X%8.8X\n",
186 bit_width, function,
187 ACPI_FORMAT_NATIVE_UINT(address)));
188
189 /*
190 * Perform the memory read or write
191 *
192 * Note: For machines that do not support non-aligned transfers, the target
193 * address was checked for alignment above. We do not attempt to break the
194 * transfer up into smaller (byte-size) chunks because the AML specifically
195 * asked for a transfer width that the hardware may require.
196 */
197 switch (function) {
198 case ACPI_READ:
199
200 *value = 0;
201 switch (bit_width) {
202 case 8:
203 *value = (acpi_integer) ACPI_GET8(logical_addr_ptr);
204 break;
205
206 case 16:
207 *value = (acpi_integer) ACPI_GET16(logical_addr_ptr);
208 break;
209
210 case 32:
211 *value = (acpi_integer) ACPI_GET32(logical_addr_ptr);
212 break;
213
214 case 64:
215 *value = (acpi_integer) ACPI_GET64(logical_addr_ptr);
216 break;
217
218 default:
219 /* bit_width was already validated */
220 break;
221 }
222 break;
223
224 case ACPI_WRITE:
225
226 switch (bit_width) {
227 case 8:
228 ACPI_SET8(logical_addr_ptr) = (u8) * value;
229 break;
230
231 case 16:
232 ACPI_SET16(logical_addr_ptr) = (u16) * value;
233 break;
234
235 case 32:
236 ACPI_SET32(logical_addr_ptr) = (u32) * value;
237 break;
238
239 case 64:
240 ACPI_SET64(logical_addr_ptr) = (u64) * value;
241 break;
242
243 default:
244 /* bit_width was already validated */
245 break;
246 }
247 break;
248
249 default:
250 status = AE_BAD_PARAMETER;
251 break;
252 }
253
254 return_ACPI_STATUS(status);
255}
256
257/*******************************************************************************
258 *
259 * FUNCTION: acpi_ex_system_io_space_handler
260 *
261 * PARAMETERS: Function - Read or Write operation
262 * Address - Where in the space to read or write
263 * bit_width - Field width in bits (8, 16, or 32)
264 * Value - Pointer to in or out value
265 * handler_context - Pointer to Handler's context
266 * region_context - Pointer to context specific to the
267 * accessed region
268 *
269 * RETURN: Status
270 *
271 * DESCRIPTION: Handler for the System IO address space (Op Region)
272 *
273 ******************************************************************************/
274
275acpi_status
276acpi_ex_system_io_space_handler(u32 function,
277 acpi_physical_address address,
278 u32 bit_width,
279 acpi_integer * value,
280 void *handler_context, void *region_context)
281{
282 acpi_status status = AE_OK;
283 u32 value32;
284
285 ACPI_FUNCTION_TRACE(ex_system_io_space_handler);
286
287 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
288 "System-IO (width %d) R/W %d Address=%8.8X%8.8X\n",
289 bit_width, function,
290 ACPI_FORMAT_NATIVE_UINT(address)));
291
292 /* Decode the function parameter */
293
294 switch (function) {
295 case ACPI_READ:
296
297 status = acpi_os_read_port((acpi_io_address) address,
298 &value32, bit_width);
299 *value = value32;
300 break;
301
302 case ACPI_WRITE:
303
304 status = acpi_os_write_port((acpi_io_address) address,
305 (u32) * value, bit_width);
306 break;
307
308 default:
309 status = AE_BAD_PARAMETER;
310 break;
311 }
312
313 return_ACPI_STATUS(status);
314}
315
316/*******************************************************************************
317 *
318 * FUNCTION: acpi_ex_pci_config_space_handler
319 *
320 * PARAMETERS: Function - Read or Write operation
321 * Address - Where in the space to read or write
322 * bit_width - Field width in bits (8, 16, or 32)
323 * Value - Pointer to in or out value
324 * handler_context - Pointer to Handler's context
325 * region_context - Pointer to context specific to the
326 * accessed region
327 *
328 * RETURN: Status
329 *
330 * DESCRIPTION: Handler for the PCI Config address space (Op Region)
331 *
332 ******************************************************************************/
333
334acpi_status
335acpi_ex_pci_config_space_handler(u32 function,
336 acpi_physical_address address,
337 u32 bit_width,
338 acpi_integer * value,
339 void *handler_context, void *region_context)
340{
341 acpi_status status = AE_OK;
342 struct acpi_pci_id *pci_id;
343 u16 pci_register;
344 u32 value32;
345
346 ACPI_FUNCTION_TRACE(ex_pci_config_space_handler);
347
348 /*
349 * The arguments to acpi_os(Read|Write)pci_configuration are:
350 *
351 * pci_segment is the PCI bus segment range 0-31
352 * pci_bus is the PCI bus number range 0-255
353 * pci_device is the PCI device number range 0-31
354 * pci_function is the PCI device function number
355 * pci_register is the Config space register range 0-255 bytes
356 *
357 * Value - input value for write, output address for read
358 *
359 */
360 pci_id = (struct acpi_pci_id *)region_context;
361 pci_register = (u16) (u32) address;
362
363 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
364 "Pci-Config %d (%d) Seg(%04x) Bus(%04x) Dev(%04x) Func(%04x) Reg(%04x)\n",
365 function, bit_width, pci_id->segment, pci_id->bus,
366 pci_id->device, pci_id->function, pci_register));
367
368 switch (function) {
369 case ACPI_READ:
370
371 status = acpi_os_read_pci_configuration(pci_id, pci_register,
372 &value32, bit_width);
373 *value = value32;
374 break;
375
376 case ACPI_WRITE:
377
378 status = acpi_os_write_pci_configuration(pci_id, pci_register,
379 *value, bit_width);
380 break;
381
382 default:
383
384 status = AE_BAD_PARAMETER;
385 break;
386 }
387
388 return_ACPI_STATUS(status);
389}
390
391/*******************************************************************************
392 *
393 * FUNCTION: acpi_ex_cmos_space_handler
394 *
395 * PARAMETERS: Function - Read or Write operation
396 * Address - Where in the space to read or write
397 * bit_width - Field width in bits (8, 16, or 32)
398 * Value - Pointer to in or out value
399 * handler_context - Pointer to Handler's context
400 * region_context - Pointer to context specific to the
401 * accessed region
402 *
403 * RETURN: Status
404 *
405 * DESCRIPTION: Handler for the CMOS address space (Op Region)
406 *
407 ******************************************************************************/
408
409acpi_status
410acpi_ex_cmos_space_handler(u32 function,
411 acpi_physical_address address,
412 u32 bit_width,
413 acpi_integer * value,
414 void *handler_context, void *region_context)
415{
416 acpi_status status = AE_OK;
417
418 ACPI_FUNCTION_TRACE(ex_cmos_space_handler);
419
420 return_ACPI_STATUS(status);
421}
422
423/*******************************************************************************
424 *
425 * FUNCTION: acpi_ex_pci_bar_space_handler
426 *
427 * PARAMETERS: Function - Read or Write operation
428 * Address - Where in the space to read or write
429 * bit_width - Field width in bits (8, 16, or 32)
430 * Value - Pointer to in or out value
431 * handler_context - Pointer to Handler's context
432 * region_context - Pointer to context specific to the
433 * accessed region
434 *
435 * RETURN: Status
436 *
437 * DESCRIPTION: Handler for the PCI bar_target address space (Op Region)
438 *
439 ******************************************************************************/
440
441acpi_status
442acpi_ex_pci_bar_space_handler(u32 function,
443 acpi_physical_address address,
444 u32 bit_width,
445 acpi_integer * value,
446 void *handler_context, void *region_context)
447{
448 acpi_status status = AE_OK;
449
450 ACPI_FUNCTION_TRACE(ex_pci_bar_space_handler);
451
452 return_ACPI_STATUS(status);
453}
454
455/*******************************************************************************
456 *
457 * FUNCTION: acpi_ex_data_table_space_handler
458 *
459 * PARAMETERS: Function - Read or Write operation
460 * Address - Where in the space to read or write
461 * bit_width - Field width in bits (8, 16, or 32)
462 * Value - Pointer to in or out value
463 * handler_context - Pointer to Handler's context
464 * region_context - Pointer to context specific to the
465 * accessed region
466 *
467 * RETURN: Status
468 *
469 * DESCRIPTION: Handler for the Data Table address space (Op Region)
470 *
471 ******************************************************************************/
472
473acpi_status
474acpi_ex_data_table_space_handler(u32 function,
475 acpi_physical_address address,
476 u32 bit_width,
477 acpi_integer * value,
478 void *handler_context, void *region_context)
479{
480 ACPI_FUNCTION_TRACE(ex_data_table_space_handler);
481
482 /* Perform the memory read or write */
483
484 switch (function) {
485 case ACPI_READ:
486
487 ACPI_MEMCPY(ACPI_CAST_PTR(char, value),
488 ACPI_PHYSADDR_TO_PTR(address),
489 ACPI_DIV_8(bit_width));
490 break;
491
492 case ACPI_WRITE:
493 default:
494
495 return_ACPI_STATUS(AE_SUPPORT);
496 }
497
498 return_ACPI_STATUS(AE_OK);
499}
diff --git a/drivers/acpi/acpica/exresnte.c b/drivers/acpi/acpica/exresnte.c
new file mode 100644
index 00000000000..77df6e490e7
--- /dev/null
+++ b/drivers/acpi/acpica/exresnte.c
@@ -0,0 +1,278 @@
1
2/******************************************************************************
3 *
4 * Module Name: exresnte - AML Interpreter object resolution
5 *
6 *****************************************************************************/
7
8/*
9 * Copyright (C) 2000 - 2008, Intel Corp.
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions, and the following disclaimer,
17 * without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 * substantially similar to the "NO WARRANTY" disclaimer below
20 * ("Disclaimer") and any redistribution must be conditioned upon
21 * including a substantially similar Disclaimer requirement for further
22 * binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 * of any contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
30 *
31 * NO WARRANTY
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
43 */
44
45#include <acpi/acpi.h>
46#include <acpi/accommon.h>
47#include <acpi/acdispat.h>
48#include <acpi/acinterp.h>
49#include <acpi/acnamesp.h>
50
51#define _COMPONENT ACPI_EXECUTER
52ACPI_MODULE_NAME("exresnte")
53
54/*******************************************************************************
55 *
56 * FUNCTION: acpi_ex_resolve_node_to_value
57 *
58 * PARAMETERS: object_ptr - Pointer to a location that contains
59 * a pointer to a NS node, and will receive a
60 * pointer to the resolved object.
61 * walk_state - Current state. Valid only if executing AML
62 * code. NULL if simply resolving an object
63 *
64 * RETURN: Status
65 *
66 * DESCRIPTION: Resolve a Namespace node to a valued object
67 *
68 * Note: for some of the data types, the pointer attached to the Node
69 * can be either a pointer to an actual internal object or a pointer into the
70 * AML stream itself. These types are currently:
71 *
72 * ACPI_TYPE_INTEGER
73 * ACPI_TYPE_STRING
74 * ACPI_TYPE_BUFFER
75 * ACPI_TYPE_MUTEX
76 * ACPI_TYPE_PACKAGE
77 *
78 ******************************************************************************/
79acpi_status
80acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr,
81 struct acpi_walk_state *walk_state)
82{
83 acpi_status status = AE_OK;
84 union acpi_operand_object *source_desc;
85 union acpi_operand_object *obj_desc = NULL;
86 struct acpi_namespace_node *node;
87 acpi_object_type entry_type;
88
89 ACPI_FUNCTION_TRACE(ex_resolve_node_to_value);
90
91 /*
92 * The stack pointer points to a struct acpi_namespace_node (Node). Get the
93 * object that is attached to the Node.
94 */
95 node = *object_ptr;
96 source_desc = acpi_ns_get_attached_object(node);
97 entry_type = acpi_ns_get_type((acpi_handle) node);
98
99 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Entry=%p SourceDesc=%p [%s]\n",
100 node, source_desc,
101 acpi_ut_get_type_name(entry_type)));
102
103 if ((entry_type == ACPI_TYPE_LOCAL_ALIAS) ||
104 (entry_type == ACPI_TYPE_LOCAL_METHOD_ALIAS)) {
105
106 /* There is always exactly one level of indirection */
107
108 node = ACPI_CAST_PTR(struct acpi_namespace_node, node->object);
109 source_desc = acpi_ns_get_attached_object(node);
110 entry_type = acpi_ns_get_type((acpi_handle) node);
111 *object_ptr = node;
112 }
113
114 /*
115 * Several object types require no further processing:
116 * 1) Device/Thermal objects don't have a "real" subobject, return the Node
117 * 2) Method locals and arguments have a pseudo-Node
118 * 3) 10/2007: Added method type to assist with Package construction.
119 */
120 if ((entry_type == ACPI_TYPE_DEVICE) ||
121 (entry_type == ACPI_TYPE_THERMAL) ||
122 (entry_type == ACPI_TYPE_METHOD) ||
123 (node->flags & (ANOBJ_METHOD_ARG | ANOBJ_METHOD_LOCAL))) {
124 return_ACPI_STATUS(AE_OK);
125 }
126
127 if (!source_desc) {
128 ACPI_ERROR((AE_INFO, "No object attached to node %p", node));
129 return_ACPI_STATUS(AE_AML_NO_OPERAND);
130 }
131
132 /*
133 * Action is based on the type of the Node, which indicates the type
134 * of the attached object or pointer
135 */
136 switch (entry_type) {
137 case ACPI_TYPE_PACKAGE:
138
139 if (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_PACKAGE) {
140 ACPI_ERROR((AE_INFO, "Object not a Package, type %s",
141 acpi_ut_get_object_type_name(source_desc)));
142 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
143 }
144
145 status = acpi_ds_get_package_arguments(source_desc);
146 if (ACPI_SUCCESS(status)) {
147
148 /* Return an additional reference to the object */
149
150 obj_desc = source_desc;
151 acpi_ut_add_reference(obj_desc);
152 }
153 break;
154
155 case ACPI_TYPE_BUFFER:
156
157 if (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_BUFFER) {
158 ACPI_ERROR((AE_INFO, "Object not a Buffer, type %s",
159 acpi_ut_get_object_type_name(source_desc)));
160 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
161 }
162
163 status = acpi_ds_get_buffer_arguments(source_desc);
164 if (ACPI_SUCCESS(status)) {
165
166 /* Return an additional reference to the object */
167
168 obj_desc = source_desc;
169 acpi_ut_add_reference(obj_desc);
170 }
171 break;
172
173 case ACPI_TYPE_STRING:
174
175 if (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_STRING) {
176 ACPI_ERROR((AE_INFO, "Object not a String, type %s",
177 acpi_ut_get_object_type_name(source_desc)));
178 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
179 }
180
181 /* Return an additional reference to the object */
182
183 obj_desc = source_desc;
184 acpi_ut_add_reference(obj_desc);
185 break;
186
187 case ACPI_TYPE_INTEGER:
188
189 if (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_INTEGER) {
190 ACPI_ERROR((AE_INFO, "Object not a Integer, type %s",
191 acpi_ut_get_object_type_name(source_desc)));
192 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
193 }
194
195 /* Return an additional reference to the object */
196
197 obj_desc = source_desc;
198 acpi_ut_add_reference(obj_desc);
199 break;
200
201 case ACPI_TYPE_BUFFER_FIELD:
202 case ACPI_TYPE_LOCAL_REGION_FIELD:
203 case ACPI_TYPE_LOCAL_BANK_FIELD:
204 case ACPI_TYPE_LOCAL_INDEX_FIELD:
205
206 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
207 "FieldRead Node=%p SourceDesc=%p Type=%X\n",
208 node, source_desc, entry_type));
209
210 status =
211 acpi_ex_read_data_from_field(walk_state, source_desc,
212 &obj_desc);
213 break;
214
215 /* For these objects, just return the object attached to the Node */
216
217 case ACPI_TYPE_MUTEX:
218 case ACPI_TYPE_POWER:
219 case ACPI_TYPE_PROCESSOR:
220 case ACPI_TYPE_EVENT:
221 case ACPI_TYPE_REGION:
222
223 /* Return an additional reference to the object */
224
225 obj_desc = source_desc;
226 acpi_ut_add_reference(obj_desc);
227 break;
228
229 /* TYPE_ANY is untyped, and thus there is no object associated with it */
230
231 case ACPI_TYPE_ANY:
232
233 ACPI_ERROR((AE_INFO,
234 "Untyped entry %p, no attached object!", node));
235
236 return_ACPI_STATUS(AE_AML_OPERAND_TYPE); /* Cannot be AE_TYPE */
237
238 case ACPI_TYPE_LOCAL_REFERENCE:
239
240 switch (source_desc->reference.class) {
241 case ACPI_REFCLASS_TABLE: /* This is a ddb_handle */
242 case ACPI_REFCLASS_REFOF:
243 case ACPI_REFCLASS_INDEX:
244
245 /* Return an additional reference to the object */
246
247 obj_desc = source_desc;
248 acpi_ut_add_reference(obj_desc);
249 break;
250
251 default:
252 /* No named references are allowed here */
253
254 ACPI_ERROR((AE_INFO,
255 "Unsupported Reference type %X",
256 source_desc->reference.class));
257
258 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
259 }
260 break;
261
262 default:
263
264 /* Default case is for unknown types */
265
266 ACPI_ERROR((AE_INFO,
267 "Node %p - Unknown object type %X",
268 node, entry_type));
269
270 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
271
272 } /* switch (entry_type) */
273
274 /* Return the object descriptor */
275
276 *object_ptr = (void *)obj_desc;
277 return_ACPI_STATUS(status);
278}
diff --git a/drivers/acpi/acpica/exresolv.c b/drivers/acpi/acpica/exresolv.c
new file mode 100644
index 00000000000..42adde01bc9
--- /dev/null
+++ b/drivers/acpi/acpica/exresolv.c
@@ -0,0 +1,551 @@
1
2/******************************************************************************
3 *
4 * Module Name: exresolv - AML Interpreter object resolution
5 *
6 *****************************************************************************/
7
8/*
9 * Copyright (C) 2000 - 2008, Intel Corp.
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions, and the following disclaimer,
17 * without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 * substantially similar to the "NO WARRANTY" disclaimer below
20 * ("Disclaimer") and any redistribution must be conditioned upon
21 * including a substantially similar Disclaimer requirement for further
22 * binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 * of any contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
30 *
31 * NO WARRANTY
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
43 */
44
45#include <acpi/acpi.h>
46#include <acpi/accommon.h>
47#include <acpi/amlcode.h>
48#include <acpi/acdispat.h>
49#include <acpi/acinterp.h>
50#include <acpi/acnamesp.h>
51
52#define _COMPONENT ACPI_EXECUTER
53ACPI_MODULE_NAME("exresolv")
54
55/* Local prototypes */
56static acpi_status
57acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr,
58 struct acpi_walk_state *walk_state);
59
60/*******************************************************************************
61 *
62 * FUNCTION: acpi_ex_resolve_to_value
63 *
64 * PARAMETERS: **stack_ptr - Points to entry on obj_stack, which can
65 * be either an (union acpi_operand_object *)
66 * or an acpi_handle.
67 * walk_state - Current method state
68 *
69 * RETURN: Status
70 *
71 * DESCRIPTION: Convert Reference objects to values
72 *
73 ******************************************************************************/
74
75acpi_status
76acpi_ex_resolve_to_value(union acpi_operand_object **stack_ptr,
77 struct acpi_walk_state *walk_state)
78{
79 acpi_status status;
80
81 ACPI_FUNCTION_TRACE_PTR(ex_resolve_to_value, stack_ptr);
82
83 if (!stack_ptr || !*stack_ptr) {
84 ACPI_ERROR((AE_INFO, "Internal - null pointer"));
85 return_ACPI_STATUS(AE_AML_NO_OPERAND);
86 }
87
88 /*
89 * The entity pointed to by the stack_ptr can be either
90 * 1) A valid union acpi_operand_object, or
91 * 2) A struct acpi_namespace_node (named_obj)
92 */
93 if (ACPI_GET_DESCRIPTOR_TYPE(*stack_ptr) == ACPI_DESC_TYPE_OPERAND) {
94 status = acpi_ex_resolve_object_to_value(stack_ptr, walk_state);
95 if (ACPI_FAILURE(status)) {
96 return_ACPI_STATUS(status);
97 }
98
99 if (!*stack_ptr) {
100 ACPI_ERROR((AE_INFO, "Internal - null pointer"));
101 return_ACPI_STATUS(AE_AML_NO_OPERAND);
102 }
103 }
104
105 /*
106 * Object on the stack may have changed if acpi_ex_resolve_object_to_value()
107 * was called (i.e., we can't use an _else_ here.)
108 */
109 if (ACPI_GET_DESCRIPTOR_TYPE(*stack_ptr) == ACPI_DESC_TYPE_NAMED) {
110 status =
111 acpi_ex_resolve_node_to_value(ACPI_CAST_INDIRECT_PTR
112 (struct acpi_namespace_node,
113 stack_ptr), walk_state);
114 if (ACPI_FAILURE(status)) {
115 return_ACPI_STATUS(status);
116 }
117 }
118
119 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Resolved object %p\n", *stack_ptr));
120 return_ACPI_STATUS(AE_OK);
121}
122
123/*******************************************************************************
124 *
125 * FUNCTION: acpi_ex_resolve_object_to_value
126 *
127 * PARAMETERS: stack_ptr - Pointer to an internal object
128 * walk_state - Current method state
129 *
130 * RETURN: Status
131 *
132 * DESCRIPTION: Retrieve the value from an internal object. The Reference type
133 * uses the associated AML opcode to determine the value.
134 *
135 ******************************************************************************/
136
137static acpi_status
138acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr,
139 struct acpi_walk_state *walk_state)
140{
141 acpi_status status = AE_OK;
142 union acpi_operand_object *stack_desc;
143 union acpi_operand_object *obj_desc = NULL;
144 u8 ref_type;
145
146 ACPI_FUNCTION_TRACE(ex_resolve_object_to_value);
147
148 stack_desc = *stack_ptr;
149
150 /* This is an union acpi_operand_object */
151
152 switch (ACPI_GET_OBJECT_TYPE(stack_desc)) {
153 case ACPI_TYPE_LOCAL_REFERENCE:
154
155 ref_type = stack_desc->reference.class;
156
157 switch (ref_type) {
158 case ACPI_REFCLASS_LOCAL:
159 case ACPI_REFCLASS_ARG:
160
161 /*
162 * Get the local from the method's state info
163 * Note: this increments the local's object reference count
164 */
165 status = acpi_ds_method_data_get_value(ref_type,
166 stack_desc->
167 reference.value,
168 walk_state,
169 &obj_desc);
170 if (ACPI_FAILURE(status)) {
171 return_ACPI_STATUS(status);
172 }
173
174 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
175 "[Arg/Local %X] ValueObj is %p\n",
176 stack_desc->reference.value,
177 obj_desc));
178
179 /*
180 * Now we can delete the original Reference Object and
181 * replace it with the resolved value
182 */
183 acpi_ut_remove_reference(stack_desc);
184 *stack_ptr = obj_desc;
185 break;
186
187 case ACPI_REFCLASS_INDEX:
188
189 switch (stack_desc->reference.target_type) {
190 case ACPI_TYPE_BUFFER_FIELD:
191
192 /* Just return - do not dereference */
193 break;
194
195 case ACPI_TYPE_PACKAGE:
196
197 /* If method call or copy_object - do not dereference */
198
199 if ((walk_state->opcode ==
200 AML_INT_METHODCALL_OP)
201 || (walk_state->opcode == AML_COPY_OP)) {
202 break;
203 }
204
205 /* Otherwise, dereference the package_index to a package element */
206
207 obj_desc = *stack_desc->reference.where;
208 if (obj_desc) {
209 /*
210 * Valid object descriptor, copy pointer to return value
211 * (i.e., dereference the package index)
212 * Delete the ref object, increment the returned object
213 */
214 acpi_ut_remove_reference(stack_desc);
215 acpi_ut_add_reference(obj_desc);
216 *stack_ptr = obj_desc;
217 } else {
218 /*
219 * A NULL object descriptor means an uninitialized element of
220 * the package, can't dereference it
221 */
222 ACPI_ERROR((AE_INFO,
223 "Attempt to dereference an Index to NULL package element Idx=%p",
224 stack_desc));
225 status = AE_AML_UNINITIALIZED_ELEMENT;
226 }
227 break;
228
229 default:
230
231 /* Invalid reference object */
232
233 ACPI_ERROR((AE_INFO,
234 "Unknown TargetType %X in Index/Reference object %p",
235 stack_desc->reference.target_type,
236 stack_desc));
237 status = AE_AML_INTERNAL;
238 break;
239 }
240 break;
241
242 case ACPI_REFCLASS_REFOF:
243 case ACPI_REFCLASS_DEBUG:
244 case ACPI_REFCLASS_TABLE:
245
246 /* Just leave the object as-is, do not dereference */
247
248 break;
249
250 case ACPI_REFCLASS_NAME: /* Reference to a named object */
251
252 /* Dereference the name */
253
254 if ((stack_desc->reference.node->type ==
255 ACPI_TYPE_DEVICE)
256 || (stack_desc->reference.node->type ==
257 ACPI_TYPE_THERMAL)) {
258
259 /* These node types do not have 'real' subobjects */
260
261 *stack_ptr = (void *)stack_desc->reference.node;
262 } else {
263 /* Get the object pointed to by the namespace node */
264
265 *stack_ptr =
266 (stack_desc->reference.node)->object;
267 acpi_ut_add_reference(*stack_ptr);
268 }
269
270 acpi_ut_remove_reference(stack_desc);
271 break;
272
273 default:
274
275 ACPI_ERROR((AE_INFO,
276 "Unknown Reference type %X in %p", ref_type,
277 stack_desc));
278 status = AE_AML_INTERNAL;
279 break;
280 }
281 break;
282
283 case ACPI_TYPE_BUFFER:
284
285 status = acpi_ds_get_buffer_arguments(stack_desc);
286 break;
287
288 case ACPI_TYPE_PACKAGE:
289
290 status = acpi_ds_get_package_arguments(stack_desc);
291 break;
292
293 case ACPI_TYPE_BUFFER_FIELD:
294 case ACPI_TYPE_LOCAL_REGION_FIELD:
295 case ACPI_TYPE_LOCAL_BANK_FIELD:
296 case ACPI_TYPE_LOCAL_INDEX_FIELD:
297
298 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
299 "FieldRead SourceDesc=%p Type=%X\n",
300 stack_desc,
301 ACPI_GET_OBJECT_TYPE(stack_desc)));
302
303 status =
304 acpi_ex_read_data_from_field(walk_state, stack_desc,
305 &obj_desc);
306
307 /* Remove a reference to the original operand, then override */
308
309 acpi_ut_remove_reference(*stack_ptr);
310 *stack_ptr = (void *)obj_desc;
311 break;
312
313 default:
314 break;
315 }
316
317 return_ACPI_STATUS(status);
318}
319
320/*******************************************************************************
321 *
322 * FUNCTION: acpi_ex_resolve_multiple
323 *
324 * PARAMETERS: walk_state - Current state (contains AML opcode)
325 * Operand - Starting point for resolution
326 * return_type - Where the object type is returned
327 * return_desc - Where the resolved object is returned
328 *
329 * RETURN: Status
330 *
331 * DESCRIPTION: Return the base object and type. Traverse a reference list if
332 * necessary to get to the base object.
333 *
334 ******************************************************************************/
335
336acpi_status
337acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state,
338 union acpi_operand_object *operand,
339 acpi_object_type * return_type,
340 union acpi_operand_object **return_desc)
341{
342 union acpi_operand_object *obj_desc = (void *)operand;
343 struct acpi_namespace_node *node;
344 acpi_object_type type;
345 acpi_status status;
346
347 ACPI_FUNCTION_TRACE(acpi_ex_resolve_multiple);
348
349 /* Operand can be either a namespace node or an operand descriptor */
350
351 switch (ACPI_GET_DESCRIPTOR_TYPE(obj_desc)) {
352 case ACPI_DESC_TYPE_OPERAND:
353 type = obj_desc->common.type;
354 break;
355
356 case ACPI_DESC_TYPE_NAMED:
357 type = ((struct acpi_namespace_node *)obj_desc)->type;
358 obj_desc =
359 acpi_ns_get_attached_object((struct acpi_namespace_node *)
360 obj_desc);
361
362 /* If we had an Alias node, use the attached object for type info */
363
364 if (type == ACPI_TYPE_LOCAL_ALIAS) {
365 type = ((struct acpi_namespace_node *)obj_desc)->type;
366 obj_desc =
367 acpi_ns_get_attached_object((struct
368 acpi_namespace_node *)
369 obj_desc);
370 }
371 break;
372
373 default:
374 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
375 }
376
377 /* If type is anything other than a reference, we are done */
378
379 if (type != ACPI_TYPE_LOCAL_REFERENCE) {
380 goto exit;
381 }
382
383 /*
384 * For reference objects created via the ref_of, Index, or Load/load_table
385 * operators, we need to get to the base object (as per the ACPI
386 * specification of the object_type and size_of operators). This means
387 * traversing the list of possibly many nested references.
388 */
389 while (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_REFERENCE) {
390 switch (obj_desc->reference.class) {
391 case ACPI_REFCLASS_REFOF:
392 case ACPI_REFCLASS_NAME:
393
394 /* Dereference the reference pointer */
395
396 if (obj_desc->reference.class == ACPI_REFCLASS_REFOF) {
397 node = obj_desc->reference.object;
398 } else { /* AML_INT_NAMEPATH_OP */
399
400 node = obj_desc->reference.node;
401 }
402
403 /* All "References" point to a NS node */
404
405 if (ACPI_GET_DESCRIPTOR_TYPE(node) !=
406 ACPI_DESC_TYPE_NAMED) {
407 ACPI_ERROR((AE_INFO, "Not a NS node %p [%s]",
408 node,
409 acpi_ut_get_descriptor_name(node)));
410 return_ACPI_STATUS(AE_AML_INTERNAL);
411 }
412
413 /* Get the attached object */
414
415 obj_desc = acpi_ns_get_attached_object(node);
416 if (!obj_desc) {
417
418 /* No object, use the NS node type */
419
420 type = acpi_ns_get_type(node);
421 goto exit;
422 }
423
424 /* Check for circular references */
425
426 if (obj_desc == operand) {
427 return_ACPI_STATUS(AE_AML_CIRCULAR_REFERENCE);
428 }
429 break;
430
431 case ACPI_REFCLASS_INDEX:
432
433 /* Get the type of this reference (index into another object) */
434
435 type = obj_desc->reference.target_type;
436 if (type != ACPI_TYPE_PACKAGE) {
437 goto exit;
438 }
439
440 /*
441 * The main object is a package, we want to get the type
442 * of the individual package element that is referenced by
443 * the index.
444 *
445 * This could of course in turn be another reference object.
446 */
447 obj_desc = *(obj_desc->reference.where);
448 if (!obj_desc) {
449
450 /* NULL package elements are allowed */
451
452 type = 0; /* Uninitialized */
453 goto exit;
454 }
455 break;
456
457 case ACPI_REFCLASS_TABLE:
458
459 type = ACPI_TYPE_DDB_HANDLE;
460 goto exit;
461
462 case ACPI_REFCLASS_LOCAL:
463 case ACPI_REFCLASS_ARG:
464
465 if (return_desc) {
466 status =
467 acpi_ds_method_data_get_value(obj_desc->
468 reference.
469 class,
470 obj_desc->
471 reference.
472 value,
473 walk_state,
474 &obj_desc);
475 if (ACPI_FAILURE(status)) {
476 return_ACPI_STATUS(status);
477 }
478 acpi_ut_remove_reference(obj_desc);
479 } else {
480 status =
481 acpi_ds_method_data_get_node(obj_desc->
482 reference.
483 class,
484 obj_desc->
485 reference.
486 value,
487 walk_state,
488 &node);
489 if (ACPI_FAILURE(status)) {
490 return_ACPI_STATUS(status);
491 }
492
493 obj_desc = acpi_ns_get_attached_object(node);
494 if (!obj_desc) {
495 type = ACPI_TYPE_ANY;
496 goto exit;
497 }
498 }
499 break;
500
501 case ACPI_REFCLASS_DEBUG:
502
503 /* The Debug Object is of type "DebugObject" */
504
505 type = ACPI_TYPE_DEBUG_OBJECT;
506 goto exit;
507
508 default:
509
510 ACPI_ERROR((AE_INFO,
511 "Unknown Reference Class %2.2X",
512 obj_desc->reference.class));
513 return_ACPI_STATUS(AE_AML_INTERNAL);
514 }
515 }
516
517 /*
518 * Now we are guaranteed to have an object that has not been created
519 * via the ref_of or Index operators.
520 */
521 type = ACPI_GET_OBJECT_TYPE(obj_desc);
522
523 exit:
524 /* Convert internal types to external types */
525
526 switch (type) {
527 case ACPI_TYPE_LOCAL_REGION_FIELD:
528 case ACPI_TYPE_LOCAL_BANK_FIELD:
529 case ACPI_TYPE_LOCAL_INDEX_FIELD:
530
531 type = ACPI_TYPE_FIELD_UNIT;
532 break;
533
534 case ACPI_TYPE_LOCAL_SCOPE:
535
536 /* Per ACPI Specification, Scope is untyped */
537
538 type = ACPI_TYPE_ANY;
539 break;
540
541 default:
542 /* No change to Type required */
543 break;
544 }
545
546 *return_type = type;
547 if (return_desc) {
548 *return_desc = obj_desc;
549 }
550 return_ACPI_STATUS(AE_OK);
551}
diff --git a/drivers/acpi/acpica/exresop.c b/drivers/acpi/acpica/exresop.c
new file mode 100644
index 00000000000..7602eaf5c47
--- /dev/null
+++ b/drivers/acpi/acpica/exresop.c
@@ -0,0 +1,701 @@
1
2/******************************************************************************
3 *
4 * Module Name: exresop - AML Interpreter operand/object resolution
5 *
6 *****************************************************************************/
7
8/*
9 * Copyright (C) 2000 - 2008, Intel Corp.
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions, and the following disclaimer,
17 * without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 * substantially similar to the "NO WARRANTY" disclaimer below
20 * ("Disclaimer") and any redistribution must be conditioned upon
21 * including a substantially similar Disclaimer requirement for further
22 * binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 * of any contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
30 *
31 * NO WARRANTY
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
43 */
44
45#include <acpi/acpi.h>
46#include <acpi/accommon.h>
47#include <acpi/amlcode.h>
48#include <acpi/acparser.h>
49#include <acpi/acinterp.h>
50#include <acpi/acnamesp.h>
51
52#define _COMPONENT ACPI_EXECUTER
53ACPI_MODULE_NAME("exresop")
54
55/* Local prototypes */
56static acpi_status
57acpi_ex_check_object_type(acpi_object_type type_needed,
58 acpi_object_type this_type, void *object);
59
60/*******************************************************************************
61 *
62 * FUNCTION: acpi_ex_check_object_type
63 *
64 * PARAMETERS: type_needed Object type needed
65 * this_type Actual object type
66 * Object Object pointer
67 *
68 * RETURN: Status
69 *
70 * DESCRIPTION: Check required type against actual type
71 *
72 ******************************************************************************/
73
74static acpi_status
75acpi_ex_check_object_type(acpi_object_type type_needed,
76 acpi_object_type this_type, void *object)
77{
78 ACPI_FUNCTION_ENTRY();
79
80 if (type_needed == ACPI_TYPE_ANY) {
81
82 /* All types OK, so we don't perform any typechecks */
83
84 return (AE_OK);
85 }
86
87 if (type_needed == ACPI_TYPE_LOCAL_REFERENCE) {
88 /*
89 * Allow the AML "Constant" opcodes (Zero, One, etc.) to be reference
90 * objects and thus allow them to be targets. (As per the ACPI
91 * specification, a store to a constant is a noop.)
92 */
93 if ((this_type == ACPI_TYPE_INTEGER) &&
94 (((union acpi_operand_object *)object)->common.
95 flags & AOPOBJ_AML_CONSTANT)) {
96 return (AE_OK);
97 }
98 }
99
100 if (type_needed != this_type) {
101 ACPI_ERROR((AE_INFO,
102 "Needed type [%s], found [%s] %p",
103 acpi_ut_get_type_name(type_needed),
104 acpi_ut_get_type_name(this_type), object));
105
106 return (AE_AML_OPERAND_TYPE);
107 }
108
109 return (AE_OK);
110}
111
112/*******************************************************************************
113 *
114 * FUNCTION: acpi_ex_resolve_operands
115 *
116 * PARAMETERS: Opcode - Opcode being interpreted
117 * stack_ptr - Pointer to the operand stack to be
118 * resolved
119 * walk_state - Current state
120 *
121 * RETURN: Status
122 *
123 * DESCRIPTION: Convert multiple input operands to the types required by the
124 * target operator.
125 *
126 * Each 5-bit group in arg_types represents one required
127 * operand and indicates the required Type. The corresponding operand
128 * will be converted to the required type if possible, otherwise we
129 * abort with an exception.
130 *
131 ******************************************************************************/
132
133acpi_status
134acpi_ex_resolve_operands(u16 opcode,
135 union acpi_operand_object ** stack_ptr,
136 struct acpi_walk_state * walk_state)
137{
138 union acpi_operand_object *obj_desc;
139 acpi_status status = AE_OK;
140 u8 object_type;
141 u32 arg_types;
142 const struct acpi_opcode_info *op_info;
143 u32 this_arg_type;
144 acpi_object_type type_needed;
145 u16 target_op = 0;
146
147 ACPI_FUNCTION_TRACE_U32(ex_resolve_operands, opcode);
148
149 op_info = acpi_ps_get_opcode_info(opcode);
150 if (op_info->class == AML_CLASS_UNKNOWN) {
151 return_ACPI_STATUS(AE_AML_BAD_OPCODE);
152 }
153
154 arg_types = op_info->runtime_args;
155 if (arg_types == ARGI_INVALID_OPCODE) {
156 ACPI_ERROR((AE_INFO, "Unknown AML opcode %X", opcode));
157
158 return_ACPI_STATUS(AE_AML_INTERNAL);
159 }
160
161 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
162 "Opcode %X [%s] RequiredOperandTypes=%8.8X\n",
163 opcode, op_info->name, arg_types));
164
165 /*
166 * Normal exit is with (arg_types == 0) at end of argument list.
167 * Function will return an exception from within the loop upon
168 * finding an entry which is not (or cannot be converted
169 * to) the required type; if stack underflows; or upon
170 * finding a NULL stack entry (which should not happen).
171 */
172 while (GET_CURRENT_ARG_TYPE(arg_types)) {
173 if (!stack_ptr || !*stack_ptr) {
174 ACPI_ERROR((AE_INFO, "Null stack entry at %p",
175 stack_ptr));
176
177 return_ACPI_STATUS(AE_AML_INTERNAL);
178 }
179
180 /* Extract useful items */
181
182 obj_desc = *stack_ptr;
183
184 /* Decode the descriptor type */
185
186 switch (ACPI_GET_DESCRIPTOR_TYPE(obj_desc)) {
187 case ACPI_DESC_TYPE_NAMED:
188
189 /* Namespace Node */
190
191 object_type =
192 ((struct acpi_namespace_node *)obj_desc)->type;
193
194 /*
195 * Resolve an alias object. The construction of these objects
196 * guarantees that there is only one level of alias indirection;
197 * thus, the attached object is always the aliased namespace node
198 */
199 if (object_type == ACPI_TYPE_LOCAL_ALIAS) {
200 obj_desc =
201 acpi_ns_get_attached_object((struct
202 acpi_namespace_node
203 *)obj_desc);
204 *stack_ptr = obj_desc;
205 object_type =
206 ((struct acpi_namespace_node *)obj_desc)->
207 type;
208 }
209 break;
210
211 case ACPI_DESC_TYPE_OPERAND:
212
213 /* ACPI internal object */
214
215 object_type = ACPI_GET_OBJECT_TYPE(obj_desc);
216
217 /* Check for bad acpi_object_type */
218
219 if (!acpi_ut_valid_object_type(object_type)) {
220 ACPI_ERROR((AE_INFO,
221 "Bad operand object type [%X]",
222 object_type));
223
224 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
225 }
226
227 if (object_type == (u8) ACPI_TYPE_LOCAL_REFERENCE) {
228
229 /* Validate the Reference */
230
231 switch (obj_desc->reference.class) {
232 case ACPI_REFCLASS_DEBUG:
233
234 target_op = AML_DEBUG_OP;
235
236 /*lint -fallthrough */
237
238 case ACPI_REFCLASS_ARG:
239 case ACPI_REFCLASS_LOCAL:
240 case ACPI_REFCLASS_INDEX:
241 case ACPI_REFCLASS_REFOF:
242 case ACPI_REFCLASS_TABLE: /* ddb_handle from LOAD_OP or LOAD_TABLE_OP */
243 case ACPI_REFCLASS_NAME: /* Reference to a named object */
244
245 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
246 "Operand is a Reference, Class [%s] %2.2X\n",
247 acpi_ut_get_reference_name
248 (obj_desc),
249 obj_desc->reference.
250 class));
251 break;
252
253 default:
254
255 ACPI_ERROR((AE_INFO,
256 "Unknown Reference Class %2.2X in %p",
257 obj_desc->reference.class,
258 obj_desc));
259
260 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
261 }
262 }
263 break;
264
265 default:
266
267 /* Invalid descriptor */
268
269 ACPI_ERROR((AE_INFO, "Invalid descriptor %p [%s]",
270 obj_desc,
271 acpi_ut_get_descriptor_name(obj_desc)));
272
273 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
274 }
275
276 /* Get one argument type, point to the next */
277
278 this_arg_type = GET_CURRENT_ARG_TYPE(arg_types);
279 INCREMENT_ARG_LIST(arg_types);
280
281 /*
282 * Handle cases where the object does not need to be
283 * resolved to a value
284 */
285 switch (this_arg_type) {
286 case ARGI_REF_OR_STRING: /* Can be a String or Reference */
287
288 if ((ACPI_GET_DESCRIPTOR_TYPE(obj_desc) ==
289 ACPI_DESC_TYPE_OPERAND)
290 && (ACPI_GET_OBJECT_TYPE(obj_desc) ==
291 ACPI_TYPE_STRING)) {
292 /*
293 * String found - the string references a named object and
294 * must be resolved to a node
295 */
296 goto next_operand;
297 }
298
299 /*
300 * Else not a string - fall through to the normal Reference
301 * case below
302 */
303 /*lint -fallthrough */
304
305 case ARGI_REFERENCE: /* References: */
306 case ARGI_INTEGER_REF:
307 case ARGI_OBJECT_REF:
308 case ARGI_DEVICE_REF:
309 case ARGI_TARGETREF: /* Allows implicit conversion rules before store */
310 case ARGI_FIXED_TARGET: /* No implicit conversion before store to target */
311 case ARGI_SIMPLE_TARGET: /* Name, Local, or Arg - no implicit conversion */
312
313 /*
314 * Need an operand of type ACPI_TYPE_LOCAL_REFERENCE
315 * A Namespace Node is OK as-is
316 */
317 if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) ==
318 ACPI_DESC_TYPE_NAMED) {
319 goto next_operand;
320 }
321
322 status =
323 acpi_ex_check_object_type(ACPI_TYPE_LOCAL_REFERENCE,
324 object_type, obj_desc);
325 if (ACPI_FAILURE(status)) {
326 return_ACPI_STATUS(status);
327 }
328 goto next_operand;
329
330 case ARGI_DATAREFOBJ: /* Store operator only */
331
332 /*
333 * We don't want to resolve index_op reference objects during
334 * a store because this would be an implicit de_ref_of operation.
335 * Instead, we just want to store the reference object.
336 * -- All others must be resolved below.
337 */
338 if ((opcode == AML_STORE_OP) &&
339 (ACPI_GET_OBJECT_TYPE(*stack_ptr) ==
340 ACPI_TYPE_LOCAL_REFERENCE)
341 && ((*stack_ptr)->reference.class == ACPI_REFCLASS_INDEX)) {
342 goto next_operand;
343 }
344 break;
345
346 default:
347 /* All cases covered above */
348 break;
349 }
350
351 /*
352 * Resolve this object to a value
353 */
354 status = acpi_ex_resolve_to_value(stack_ptr, walk_state);
355 if (ACPI_FAILURE(status)) {
356 return_ACPI_STATUS(status);
357 }
358
359 /* Get the resolved object */
360
361 obj_desc = *stack_ptr;
362
363 /*
364 * Check the resulting object (value) type
365 */
366 switch (this_arg_type) {
367 /*
368 * For the simple cases, only one type of resolved object
369 * is allowed
370 */
371 case ARGI_MUTEX:
372
373 /* Need an operand of type ACPI_TYPE_MUTEX */
374
375 type_needed = ACPI_TYPE_MUTEX;
376 break;
377
378 case ARGI_EVENT:
379
380 /* Need an operand of type ACPI_TYPE_EVENT */
381
382 type_needed = ACPI_TYPE_EVENT;
383 break;
384
385 case ARGI_PACKAGE: /* Package */
386
387 /* Need an operand of type ACPI_TYPE_PACKAGE */
388
389 type_needed = ACPI_TYPE_PACKAGE;
390 break;
391
392 case ARGI_ANYTYPE:
393
394 /* Any operand type will do */
395
396 type_needed = ACPI_TYPE_ANY;
397 break;
398
399 case ARGI_DDBHANDLE:
400
401 /* Need an operand of type ACPI_TYPE_DDB_HANDLE */
402
403 type_needed = ACPI_TYPE_LOCAL_REFERENCE;
404 break;
405
406 /*
407 * The more complex cases allow multiple resolved object types
408 */
409 case ARGI_INTEGER:
410
411 /*
412 * Need an operand of type ACPI_TYPE_INTEGER,
413 * But we can implicitly convert from a STRING or BUFFER
414 * Aka - "Implicit Source Operand Conversion"
415 */
416 status =
417 acpi_ex_convert_to_integer(obj_desc, stack_ptr, 16);
418 if (ACPI_FAILURE(status)) {
419 if (status == AE_TYPE) {
420 ACPI_ERROR((AE_INFO,
421 "Needed [Integer/String/Buffer], found [%s] %p",
422 acpi_ut_get_object_type_name
423 (obj_desc), obj_desc));
424
425 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
426 }
427
428 return_ACPI_STATUS(status);
429 }
430
431 if (obj_desc != *stack_ptr) {
432 acpi_ut_remove_reference(obj_desc);
433 }
434 goto next_operand;
435
436 case ARGI_BUFFER:
437
438 /*
439 * Need an operand of type ACPI_TYPE_BUFFER,
440 * But we can implicitly convert from a STRING or INTEGER
441 * Aka - "Implicit Source Operand Conversion"
442 */
443 status = acpi_ex_convert_to_buffer(obj_desc, stack_ptr);
444 if (ACPI_FAILURE(status)) {
445 if (status == AE_TYPE) {
446 ACPI_ERROR((AE_INFO,
447 "Needed [Integer/String/Buffer], found [%s] %p",
448 acpi_ut_get_object_type_name
449 (obj_desc), obj_desc));
450
451 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
452 }
453
454 return_ACPI_STATUS(status);
455 }
456
457 if (obj_desc != *stack_ptr) {
458 acpi_ut_remove_reference(obj_desc);
459 }
460 goto next_operand;
461
462 case ARGI_STRING:
463
464 /*
465 * Need an operand of type ACPI_TYPE_STRING,
466 * But we can implicitly convert from a BUFFER or INTEGER
467 * Aka - "Implicit Source Operand Conversion"
468 */
469 status = acpi_ex_convert_to_string(obj_desc, stack_ptr,
470 ACPI_IMPLICIT_CONVERT_HEX);
471 if (ACPI_FAILURE(status)) {
472 if (status == AE_TYPE) {
473 ACPI_ERROR((AE_INFO,
474 "Needed [Integer/String/Buffer], found [%s] %p",
475 acpi_ut_get_object_type_name
476 (obj_desc), obj_desc));
477
478 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
479 }
480
481 return_ACPI_STATUS(status);
482 }
483
484 if (obj_desc != *stack_ptr) {
485 acpi_ut_remove_reference(obj_desc);
486 }
487 goto next_operand;
488
489 case ARGI_COMPUTEDATA:
490
491 /* Need an operand of type INTEGER, STRING or BUFFER */
492
493 switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
494 case ACPI_TYPE_INTEGER:
495 case ACPI_TYPE_STRING:
496 case ACPI_TYPE_BUFFER:
497
498 /* Valid operand */
499 break;
500
501 default:
502 ACPI_ERROR((AE_INFO,
503 "Needed [Integer/String/Buffer], found [%s] %p",
504 acpi_ut_get_object_type_name
505 (obj_desc), obj_desc));
506
507 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
508 }
509 goto next_operand;
510
511 case ARGI_BUFFER_OR_STRING:
512
513 /* Need an operand of type STRING or BUFFER */
514
515 switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
516 case ACPI_TYPE_STRING:
517 case ACPI_TYPE_BUFFER:
518
519 /* Valid operand */
520 break;
521
522 case ACPI_TYPE_INTEGER:
523
524 /* Highest priority conversion is to type Buffer */
525
526 status =
527 acpi_ex_convert_to_buffer(obj_desc,
528 stack_ptr);
529 if (ACPI_FAILURE(status)) {
530 return_ACPI_STATUS(status);
531 }
532
533 if (obj_desc != *stack_ptr) {
534 acpi_ut_remove_reference(obj_desc);
535 }
536 break;
537
538 default:
539 ACPI_ERROR((AE_INFO,
540 "Needed [Integer/String/Buffer], found [%s] %p",
541 acpi_ut_get_object_type_name
542 (obj_desc), obj_desc));
543
544 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
545 }
546 goto next_operand;
547
548 case ARGI_DATAOBJECT:
549 /*
550 * ARGI_DATAOBJECT is only used by the size_of operator.
551 * Need a buffer, string, package, or ref_of reference.
552 *
553 * The only reference allowed here is a direct reference to
554 * a namespace node.
555 */
556 switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
557 case ACPI_TYPE_PACKAGE:
558 case ACPI_TYPE_STRING:
559 case ACPI_TYPE_BUFFER:
560 case ACPI_TYPE_LOCAL_REFERENCE:
561
562 /* Valid operand */
563 break;
564
565 default:
566 ACPI_ERROR((AE_INFO,
567 "Needed [Buffer/String/Package/Reference], found [%s] %p",
568 acpi_ut_get_object_type_name
569 (obj_desc), obj_desc));
570
571 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
572 }
573 goto next_operand;
574
575 case ARGI_COMPLEXOBJ:
576
577 /* Need a buffer or package or (ACPI 2.0) String */
578
579 switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
580 case ACPI_TYPE_PACKAGE:
581 case ACPI_TYPE_STRING:
582 case ACPI_TYPE_BUFFER:
583
584 /* Valid operand */
585 break;
586
587 default:
588 ACPI_ERROR((AE_INFO,
589 "Needed [Buffer/String/Package], found [%s] %p",
590 acpi_ut_get_object_type_name
591 (obj_desc), obj_desc));
592
593 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
594 }
595 goto next_operand;
596
597 case ARGI_REGION_OR_BUFFER: /* Used by Load() only */
598
599 /* Need an operand of type REGION or a BUFFER (which could be a resolved region field) */
600
601 switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
602 case ACPI_TYPE_BUFFER:
603 case ACPI_TYPE_REGION:
604
605 /* Valid operand */
606 break;
607
608 default:
609 ACPI_ERROR((AE_INFO,
610 "Needed [Region/Buffer], found [%s] %p",
611 acpi_ut_get_object_type_name
612 (obj_desc), obj_desc));
613
614 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
615 }
616 goto next_operand;
617
618 case ARGI_DATAREFOBJ:
619
620 /* Used by the Store() operator only */
621
622 switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
623 case ACPI_TYPE_INTEGER:
624 case ACPI_TYPE_PACKAGE:
625 case ACPI_TYPE_STRING:
626 case ACPI_TYPE_BUFFER:
627 case ACPI_TYPE_BUFFER_FIELD:
628 case ACPI_TYPE_LOCAL_REFERENCE:
629 case ACPI_TYPE_LOCAL_REGION_FIELD:
630 case ACPI_TYPE_LOCAL_BANK_FIELD:
631 case ACPI_TYPE_LOCAL_INDEX_FIELD:
632 case ACPI_TYPE_DDB_HANDLE:
633
634 /* Valid operand */
635 break;
636
637 default:
638
639 if (acpi_gbl_enable_interpreter_slack) {
640 /*
641 * Enable original behavior of Store(), allowing any and all
642 * objects as the source operand. The ACPI spec does not
643 * allow this, however.
644 */
645 break;
646 }
647
648 if (target_op == AML_DEBUG_OP) {
649
650 /* Allow store of any object to the Debug object */
651
652 break;
653 }
654
655 ACPI_ERROR((AE_INFO,
656 "Needed Integer/Buffer/String/Package/Ref/Ddb], found [%s] %p",
657 acpi_ut_get_object_type_name
658 (obj_desc), obj_desc));
659
660 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
661 }
662 goto next_operand;
663
664 default:
665
666 /* Unknown type */
667
668 ACPI_ERROR((AE_INFO,
669 "Internal - Unknown ARGI (required operand) type %X",
670 this_arg_type));
671
672 return_ACPI_STATUS(AE_BAD_PARAMETER);
673 }
674
675 /*
676 * Make sure that the original object was resolved to the
677 * required object type (Simple cases only).
678 */
679 status = acpi_ex_check_object_type(type_needed,
680 ACPI_GET_OBJECT_TYPE
681 (*stack_ptr), *stack_ptr);
682 if (ACPI_FAILURE(status)) {
683 return_ACPI_STATUS(status);
684 }
685
686 next_operand:
687 /*
688 * If more operands needed, decrement stack_ptr to point
689 * to next operand on stack
690 */
691 if (GET_CURRENT_ARG_TYPE(arg_types)) {
692 stack_ptr--;
693 }
694 }
695
696 ACPI_DUMP_OPERANDS(walk_state->operands,
697 acpi_ps_get_opcode_name(opcode),
698 walk_state->num_operands);
699
700 return_ACPI_STATUS(status);
701}
diff --git a/drivers/acpi/acpica/exstore.c b/drivers/acpi/acpica/exstore.c
new file mode 100644
index 00000000000..6f5647fdc00
--- /dev/null
+++ b/drivers/acpi/acpica/exstore.c
@@ -0,0 +1,716 @@
1
2/******************************************************************************
3 *
4 * Module Name: exstore - AML Interpreter object store support
5 *
6 *****************************************************************************/
7
8/*
9 * Copyright (C) 2000 - 2008, Intel Corp.
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions, and the following disclaimer,
17 * without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 * substantially similar to the "NO WARRANTY" disclaimer below
20 * ("Disclaimer") and any redistribution must be conditioned upon
21 * including a substantially similar Disclaimer requirement for further
22 * binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 * of any contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
30 *
31 * NO WARRANTY
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
43 */
44
45#include <acpi/acpi.h>
46#include <acpi/accommon.h>
47#include <acpi/acdispat.h>
48#include <acpi/acinterp.h>
49#include <acpi/amlcode.h>
50#include <acpi/acnamesp.h>
51
52#define _COMPONENT ACPI_EXECUTER
53ACPI_MODULE_NAME("exstore")
54
55/* Local prototypes */
56static void
57acpi_ex_do_debug_object(union acpi_operand_object *source_desc,
58 u32 level, u32 index);
59
60static acpi_status
61acpi_ex_store_object_to_index(union acpi_operand_object *val_desc,
62 union acpi_operand_object *dest_desc,
63 struct acpi_walk_state *walk_state);
64
65/*******************************************************************************
66 *
67 * FUNCTION: acpi_ex_do_debug_object
68 *
69 * PARAMETERS: source_desc - Value to be stored
70 * Level - Indentation level (used for packages)
71 * Index - Current package element, zero if not pkg
72 *
73 * RETURN: None
74 *
75 * DESCRIPTION: Handles stores to the Debug Object.
76 *
77 ******************************************************************************/
78
79static void
80acpi_ex_do_debug_object(union acpi_operand_object *source_desc,
81 u32 level, u32 index)
82{
83 u32 i;
84
85 ACPI_FUNCTION_TRACE_PTR(ex_do_debug_object, source_desc);
86
87 /* Print line header as long as we are not in the middle of an object display */
88
89 if (!((level > 0) && index == 0)) {
90 ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "[ACPI Debug] %*s",
91 level, " "));
92 }
93
94 /* Display index for package output only */
95
96 if (index > 0) {
97 ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT,
98 "(%.2u) ", index - 1));
99 }
100
101 if (!source_desc) {
102 ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "[Null Object]\n"));
103 return_VOID;
104 }
105
106 if (ACPI_GET_DESCRIPTOR_TYPE(source_desc) == ACPI_DESC_TYPE_OPERAND) {
107 ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "%s ",
108 acpi_ut_get_object_type_name
109 (source_desc)));
110
111 if (!acpi_ut_valid_internal_object(source_desc)) {
112 ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT,
113 "%p, Invalid Internal Object!\n",
114 source_desc));
115 return_VOID;
116 }
117 } else if (ACPI_GET_DESCRIPTOR_TYPE(source_desc) ==
118 ACPI_DESC_TYPE_NAMED) {
119 ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "%s: %p\n",
120 acpi_ut_get_type_name(((struct
121 acpi_namespace_node
122 *)source_desc)->
123 type),
124 source_desc));
125 return_VOID;
126 } else {
127 return_VOID;
128 }
129
130 /* source_desc is of type ACPI_DESC_TYPE_OPERAND */
131
132 switch (ACPI_GET_OBJECT_TYPE(source_desc)) {
133 case ACPI_TYPE_INTEGER:
134
135 /* Output correct integer width */
136
137 if (acpi_gbl_integer_byte_width == 4) {
138 ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "0x%8.8X\n",
139 (u32) source_desc->integer.
140 value));
141 } else {
142 ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT,
143 "0x%8.8X%8.8X\n",
144 ACPI_FORMAT_UINT64(source_desc->
145 integer.
146 value)));
147 }
148 break;
149
150 case ACPI_TYPE_BUFFER:
151
152 ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "[0x%.2X]\n",
153 (u32) source_desc->buffer.length));
154 ACPI_DUMP_BUFFER(source_desc->buffer.pointer,
155 (source_desc->buffer.length <
156 256) ? source_desc->buffer.length : 256);
157 break;
158
159 case ACPI_TYPE_STRING:
160
161 ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "[0x%.2X] \"%s\"\n",
162 source_desc->string.length,
163 source_desc->string.pointer));
164 break;
165
166 case ACPI_TYPE_PACKAGE:
167
168 ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT,
169 "[Contains 0x%.2X Elements]\n",
170 source_desc->package.count));
171
172 /* Output the entire contents of the package */
173
174 for (i = 0; i < source_desc->package.count; i++) {
175 acpi_ex_do_debug_object(source_desc->package.
176 elements[i], level + 4, i + 1);
177 }
178 break;
179
180 case ACPI_TYPE_LOCAL_REFERENCE:
181
182 ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "[%s] ",
183 acpi_ut_get_reference_name(source_desc)));
184
185 /* Decode the reference */
186
187 switch (source_desc->reference.class) {
188 case ACPI_REFCLASS_INDEX:
189
190 ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "0x%X\n",
191 source_desc->reference.value));
192 break;
193
194 case ACPI_REFCLASS_TABLE:
195
196 ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT,
197 "Table Index 0x%X\n",
198 source_desc->reference.value));
199 break;
200
201 default:
202 break;
203 }
204
205 ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, " "));
206
207 /* Check for valid node first, then valid object */
208
209 if (source_desc->reference.node) {
210 if (ACPI_GET_DESCRIPTOR_TYPE
211 (source_desc->reference.node) !=
212 ACPI_DESC_TYPE_NAMED) {
213 ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT,
214 " %p - Not a valid namespace node\n",
215 source_desc->reference.
216 node));
217 } else {
218 ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT,
219 "Node %p [%4.4s] ",
220 source_desc->reference.
221 node,
222 (source_desc->reference.
223 node)->name.ascii));
224
225 switch ((source_desc->reference.node)->type) {
226
227 /* These types have no attached object */
228
229 case ACPI_TYPE_DEVICE:
230 acpi_os_printf("Device\n");
231 break;
232
233 case ACPI_TYPE_THERMAL:
234 acpi_os_printf("Thermal Zone\n");
235 break;
236
237 default:
238 acpi_ex_do_debug_object((source_desc->
239 reference.
240 node)->object,
241 level + 4, 0);
242 break;
243 }
244 }
245 } else if (source_desc->reference.object) {
246 if (ACPI_GET_DESCRIPTOR_TYPE
247 (source_desc->reference.object) ==
248 ACPI_DESC_TYPE_NAMED) {
249 acpi_ex_do_debug_object(((struct
250 acpi_namespace_node *)
251 source_desc->reference.
252 object)->object,
253 level + 4, 0);
254 } else {
255 acpi_ex_do_debug_object(source_desc->reference.
256 object, level + 4, 0);
257 }
258 }
259 break;
260
261 default:
262
263 ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "%p\n",
264 source_desc));
265 break;
266 }
267
268 ACPI_DEBUG_PRINT_RAW((ACPI_DB_EXEC, "\n"));
269 return_VOID;
270}
271
272/*******************************************************************************
273 *
274 * FUNCTION: acpi_ex_store
275 *
276 * PARAMETERS: *source_desc - Value to be stored
277 * *dest_desc - Where to store it. Must be an NS node
278 * or an union acpi_operand_object of type
279 * Reference;
280 * walk_state - Current walk state
281 *
282 * RETURN: Status
283 *
284 * DESCRIPTION: Store the value described by source_desc into the location
285 * described by dest_desc. Called by various interpreter
286 * functions to store the result of an operation into
287 * the destination operand -- not just simply the actual "Store"
288 * ASL operator.
289 *
290 ******************************************************************************/
291
292acpi_status
293acpi_ex_store(union acpi_operand_object *source_desc,
294 union acpi_operand_object *dest_desc,
295 struct acpi_walk_state *walk_state)
296{
297 acpi_status status = AE_OK;
298 union acpi_operand_object *ref_desc = dest_desc;
299
300 ACPI_FUNCTION_TRACE_PTR(ex_store, dest_desc);
301
302 /* Validate parameters */
303
304 if (!source_desc || !dest_desc) {
305 ACPI_ERROR((AE_INFO, "Null parameter"));
306 return_ACPI_STATUS(AE_AML_NO_OPERAND);
307 }
308
309 /* dest_desc can be either a namespace node or an ACPI object */
310
311 if (ACPI_GET_DESCRIPTOR_TYPE(dest_desc) == ACPI_DESC_TYPE_NAMED) {
312 /*
313 * Dest is a namespace node,
314 * Storing an object into a Named node.
315 */
316 status = acpi_ex_store_object_to_node(source_desc,
317 (struct
318 acpi_namespace_node *)
319 dest_desc, walk_state,
320 ACPI_IMPLICIT_CONVERSION);
321
322 return_ACPI_STATUS(status);
323 }
324
325 /* Destination object must be a Reference or a Constant object */
326
327 switch (ACPI_GET_OBJECT_TYPE(dest_desc)) {
328 case ACPI_TYPE_LOCAL_REFERENCE:
329 break;
330
331 case ACPI_TYPE_INTEGER:
332
333 /* Allow stores to Constants -- a Noop as per ACPI spec */
334
335 if (dest_desc->common.flags & AOPOBJ_AML_CONSTANT) {
336 return_ACPI_STATUS(AE_OK);
337 }
338
339 /*lint -fallthrough */
340
341 default:
342
343 /* Destination is not a Reference object */
344
345 ACPI_ERROR((AE_INFO,
346 "Target is not a Reference or Constant object - %s [%p]",
347 acpi_ut_get_object_type_name(dest_desc),
348 dest_desc));
349
350 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
351 }
352
353 /*
354 * Examine the Reference class. These cases are handled:
355 *
356 * 1) Store to Name (Change the object associated with a name)
357 * 2) Store to an indexed area of a Buffer or Package
358 * 3) Store to a Method Local or Arg
359 * 4) Store to the debug object
360 */
361 switch (ref_desc->reference.class) {
362 case ACPI_REFCLASS_REFOF:
363
364 /* Storing an object into a Name "container" */
365
366 status = acpi_ex_store_object_to_node(source_desc,
367 ref_desc->reference.
368 object, walk_state,
369 ACPI_IMPLICIT_CONVERSION);
370 break;
371
372 case ACPI_REFCLASS_INDEX:
373
374 /* Storing to an Index (pointer into a packager or buffer) */
375
376 status =
377 acpi_ex_store_object_to_index(source_desc, ref_desc,
378 walk_state);
379 break;
380
381 case ACPI_REFCLASS_LOCAL:
382 case ACPI_REFCLASS_ARG:
383
384 /* Store to a method local/arg */
385
386 status =
387 acpi_ds_store_object_to_local(ref_desc->reference.class,
388 ref_desc->reference.value,
389 source_desc, walk_state);
390 break;
391
392 case ACPI_REFCLASS_DEBUG:
393
394 /*
395 * Storing to the Debug object causes the value stored to be
396 * displayed and otherwise has no effect -- see ACPI Specification
397 */
398 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
399 "**** Write to Debug Object: Object %p %s ****:\n\n",
400 source_desc,
401 acpi_ut_get_object_type_name(source_desc)));
402
403 acpi_ex_do_debug_object(source_desc, 0, 0);
404 break;
405
406 default:
407
408 ACPI_ERROR((AE_INFO, "Unknown Reference Class %2.2X",
409 ref_desc->reference.class));
410 ACPI_DUMP_ENTRY(ref_desc, ACPI_LV_INFO);
411
412 status = AE_AML_INTERNAL;
413 break;
414 }
415
416 return_ACPI_STATUS(status);
417}
418
419/*******************************************************************************
420 *
421 * FUNCTION: acpi_ex_store_object_to_index
422 *
423 * PARAMETERS: *source_desc - Value to be stored
424 * *dest_desc - Named object to receive the value
425 * walk_state - Current walk state
426 *
427 * RETURN: Status
428 *
429 * DESCRIPTION: Store the object to indexed Buffer or Package element
430 *
431 ******************************************************************************/
432
433static acpi_status
434acpi_ex_store_object_to_index(union acpi_operand_object *source_desc,
435 union acpi_operand_object *index_desc,
436 struct acpi_walk_state *walk_state)
437{
438 acpi_status status = AE_OK;
439 union acpi_operand_object *obj_desc;
440 union acpi_operand_object *new_desc;
441 u8 value = 0;
442 u32 i;
443
444 ACPI_FUNCTION_TRACE(ex_store_object_to_index);
445
446 /*
447 * Destination must be a reference pointer, and
448 * must point to either a buffer or a package
449 */
450 switch (index_desc->reference.target_type) {
451 case ACPI_TYPE_PACKAGE:
452 /*
453 * Storing to a package element. Copy the object and replace
454 * any existing object with the new object. No implicit
455 * conversion is performed.
456 *
457 * The object at *(index_desc->Reference.Where) is the
458 * element within the package that is to be modified.
459 * The parent package object is at index_desc->Reference.Object
460 */
461 obj_desc = *(index_desc->reference.where);
462
463 if (ACPI_GET_OBJECT_TYPE(source_desc) ==
464 ACPI_TYPE_LOCAL_REFERENCE
465 && source_desc->reference.class == ACPI_REFCLASS_TABLE) {
466
467 /* This is a DDBHandle, just add a reference to it */
468
469 acpi_ut_add_reference(source_desc);
470 new_desc = source_desc;
471 } else {
472 /* Normal object, copy it */
473
474 status =
475 acpi_ut_copy_iobject_to_iobject(source_desc,
476 &new_desc,
477 walk_state);
478 if (ACPI_FAILURE(status)) {
479 return_ACPI_STATUS(status);
480 }
481 }
482
483 if (obj_desc) {
484
485 /* Decrement reference count by the ref count of the parent package */
486
487 for (i = 0; i < ((union acpi_operand_object *)
488 index_desc->reference.object)->common.
489 reference_count; i++) {
490 acpi_ut_remove_reference(obj_desc);
491 }
492 }
493
494 *(index_desc->reference.where) = new_desc;
495
496 /* Increment ref count by the ref count of the parent package-1 */
497
498 for (i = 1; i < ((union acpi_operand_object *)
499 index_desc->reference.object)->common.
500 reference_count; i++) {
501 acpi_ut_add_reference(new_desc);
502 }
503
504 break;
505
506 case ACPI_TYPE_BUFFER_FIELD:
507
508 /*
509 * Store into a Buffer or String (not actually a real buffer_field)
510 * at a location defined by an Index.
511 *
512 * The first 8-bit element of the source object is written to the
513 * 8-bit Buffer location defined by the Index destination object,
514 * according to the ACPI 2.0 specification.
515 */
516
517 /*
518 * Make sure the target is a Buffer or String. An error should
519 * not happen here, since the reference_object was constructed
520 * by the INDEX_OP code.
521 */
522 obj_desc = index_desc->reference.object;
523 if ((ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_BUFFER) &&
524 (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_STRING)) {
525 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
526 }
527
528 /*
529 * The assignment of the individual elements will be slightly
530 * different for each source type.
531 */
532 switch (ACPI_GET_OBJECT_TYPE(source_desc)) {
533 case ACPI_TYPE_INTEGER:
534
535 /* Use the least-significant byte of the integer */
536
537 value = (u8) (source_desc->integer.value);
538 break;
539
540 case ACPI_TYPE_BUFFER:
541 case ACPI_TYPE_STRING:
542
543 /* Note: Takes advantage of common string/buffer fields */
544
545 value = source_desc->buffer.pointer[0];
546 break;
547
548 default:
549
550 /* All other types are invalid */
551
552 ACPI_ERROR((AE_INFO,
553 "Source must be Integer/Buffer/String type, not %s",
554 acpi_ut_get_object_type_name(source_desc)));
555 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
556 }
557
558 /* Store the source value into the target buffer byte */
559
560 obj_desc->buffer.pointer[index_desc->reference.value] = value;
561 break;
562
563 default:
564 ACPI_ERROR((AE_INFO, "Target is not a Package or BufferField"));
565 status = AE_AML_OPERAND_TYPE;
566 break;
567 }
568
569 return_ACPI_STATUS(status);
570}
571
572/*******************************************************************************
573 *
574 * FUNCTION: acpi_ex_store_object_to_node
575 *
576 * PARAMETERS: source_desc - Value to be stored
577 * Node - Named object to receive the value
578 * walk_state - Current walk state
579 * implicit_conversion - Perform implicit conversion (yes/no)
580 *
581 * RETURN: Status
582 *
583 * DESCRIPTION: Store the object to the named object.
584 *
585 * The Assignment of an object to a named object is handled here
586 * The value passed in will replace the current value (if any)
587 * with the input value.
588 *
589 * When storing into an object the data is converted to the
590 * target object type then stored in the object. This means
591 * that the target object type (for an initialized target) will
592 * not be changed by a store operation.
593 *
594 * Assumes parameters are already validated.
595 *
596 ******************************************************************************/
597
598acpi_status
599acpi_ex_store_object_to_node(union acpi_operand_object *source_desc,
600 struct acpi_namespace_node *node,
601 struct acpi_walk_state *walk_state,
602 u8 implicit_conversion)
603{
604 acpi_status status = AE_OK;
605 union acpi_operand_object *target_desc;
606 union acpi_operand_object *new_desc;
607 acpi_object_type target_type;
608
609 ACPI_FUNCTION_TRACE_PTR(ex_store_object_to_node, source_desc);
610
611 /* Get current type of the node, and object attached to Node */
612
613 target_type = acpi_ns_get_type(node);
614 target_desc = acpi_ns_get_attached_object(node);
615
616 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Storing %p(%s) into node %p(%s)\n",
617 source_desc,
618 acpi_ut_get_object_type_name(source_desc), node,
619 acpi_ut_get_type_name(target_type)));
620
621 /*
622 * Resolve the source object to an actual value
623 * (If it is a reference object)
624 */
625 status = acpi_ex_resolve_object(&source_desc, target_type, walk_state);
626 if (ACPI_FAILURE(status)) {
627 return_ACPI_STATUS(status);
628 }
629
630 /* If no implicit conversion, drop into the default case below */
631
632 if ((!implicit_conversion) ||
633 ((walk_state->opcode == AML_COPY_OP) &&
634 (target_type != ACPI_TYPE_LOCAL_REGION_FIELD) &&
635 (target_type != ACPI_TYPE_LOCAL_BANK_FIELD) &&
636 (target_type != ACPI_TYPE_LOCAL_INDEX_FIELD))) {
637 /*
638 * Force execution of default (no implicit conversion). Note:
639 * copy_object does not perform an implicit conversion, as per the ACPI
640 * spec -- except in case of region/bank/index fields -- because these
641 * objects must retain their original type permanently.
642 */
643 target_type = ACPI_TYPE_ANY;
644 }
645
646 /* Do the actual store operation */
647
648 switch (target_type) {
649 case ACPI_TYPE_BUFFER_FIELD:
650 case ACPI_TYPE_LOCAL_REGION_FIELD:
651 case ACPI_TYPE_LOCAL_BANK_FIELD:
652 case ACPI_TYPE_LOCAL_INDEX_FIELD:
653
654 /* For fields, copy the source data to the target field. */
655
656 status = acpi_ex_write_data_to_field(source_desc, target_desc,
657 &walk_state->result_obj);
658 break;
659
660 case ACPI_TYPE_INTEGER:
661 case ACPI_TYPE_STRING:
662 case ACPI_TYPE_BUFFER:
663
664 /*
665 * These target types are all of type Integer/String/Buffer, and
666 * therefore support implicit conversion before the store.
667 *
668 * Copy and/or convert the source object to a new target object
669 */
670 status =
671 acpi_ex_store_object_to_object(source_desc, target_desc,
672 &new_desc, walk_state);
673 if (ACPI_FAILURE(status)) {
674 return_ACPI_STATUS(status);
675 }
676
677 if (new_desc != target_desc) {
678 /*
679 * Store the new new_desc as the new value of the Name, and set
680 * the Name's type to that of the value being stored in it.
681 * source_desc reference count is incremented by attach_object.
682 *
683 * Note: This may change the type of the node if an explicit store
684 * has been performed such that the node/object type has been
685 * changed.
686 */
687 status =
688 acpi_ns_attach_object(node, new_desc,
689 new_desc->common.type);
690
691 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
692 "Store %s into %s via Convert/Attach\n",
693 acpi_ut_get_object_type_name
694 (source_desc),
695 acpi_ut_get_object_type_name
696 (new_desc)));
697 }
698 break;
699
700 default:
701
702 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
703 "Storing %s (%p) directly into node (%p) with no implicit conversion\n",
704 acpi_ut_get_object_type_name(source_desc),
705 source_desc, node));
706
707 /* No conversions for all other types. Just attach the source object */
708
709 status = acpi_ns_attach_object(node, source_desc,
710 ACPI_GET_OBJECT_TYPE
711 (source_desc));
712 break;
713 }
714
715 return_ACPI_STATUS(status);
716}
diff --git a/drivers/acpi/acpica/exstoren.c b/drivers/acpi/acpica/exstoren.c
new file mode 100644
index 00000000000..ad2047afa46
--- /dev/null
+++ b/drivers/acpi/acpica/exstoren.c
@@ -0,0 +1,304 @@
1
2/******************************************************************************
3 *
4 * Module Name: exstoren - AML Interpreter object store support,
5 * Store to Node (namespace object)
6 *
7 *****************************************************************************/
8
9/*
10 * Copyright (C) 2000 - 2008, Intel Corp.
11 * All rights reserved.
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
15 * are met:
16 * 1. Redistributions of source code must retain the above copyright
17 * notice, this list of conditions, and the following disclaimer,
18 * without modification.
19 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
20 * substantially similar to the "NO WARRANTY" disclaimer below
21 * ("Disclaimer") and any redistribution must be conditioned upon
22 * including a substantially similar Disclaimer requirement for further
23 * binary redistribution.
24 * 3. Neither the names of the above-listed copyright holders nor the names
25 * of any contributors may be used to endorse or promote products derived
26 * from this software without specific prior written permission.
27 *
28 * Alternatively, this software may be distributed under the terms of the
29 * GNU General Public License ("GPL") version 2 as published by the Free
30 * Software Foundation.
31 *
32 * NO WARRANTY
33 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
34 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
35 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
36 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
37 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
38 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
39 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
40 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
41 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
42 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
43 * POSSIBILITY OF SUCH DAMAGES.
44 */
45
46#include <acpi/acpi.h>
47#include <acpi/accommon.h>
48#include <acpi/acinterp.h>
49#include <acpi/amlcode.h>
50
51#define _COMPONENT ACPI_EXECUTER
52ACPI_MODULE_NAME("exstoren")
53
54/*******************************************************************************
55 *
56 * FUNCTION: acpi_ex_resolve_object
57 *
58 * PARAMETERS: source_desc_ptr - Pointer to the source object
59 * target_type - Current type of the target
60 * walk_state - Current walk state
61 *
62 * RETURN: Status, resolved object in source_desc_ptr.
63 *
64 * DESCRIPTION: Resolve an object. If the object is a reference, dereference
65 * it and return the actual object in the source_desc_ptr.
66 *
67 ******************************************************************************/
68acpi_status
69acpi_ex_resolve_object(union acpi_operand_object **source_desc_ptr,
70 acpi_object_type target_type,
71 struct acpi_walk_state *walk_state)
72{
73 union acpi_operand_object *source_desc = *source_desc_ptr;
74 acpi_status status = AE_OK;
75
76 ACPI_FUNCTION_TRACE(ex_resolve_object);
77
78 /* Ensure we have a Target that can be stored to */
79
80 switch (target_type) {
81 case ACPI_TYPE_BUFFER_FIELD:
82 case ACPI_TYPE_LOCAL_REGION_FIELD:
83 case ACPI_TYPE_LOCAL_BANK_FIELD:
84 case ACPI_TYPE_LOCAL_INDEX_FIELD:
85 /*
86 * These cases all require only Integers or values that
87 * can be converted to Integers (Strings or Buffers)
88 */
89
90 case ACPI_TYPE_INTEGER:
91 case ACPI_TYPE_STRING:
92 case ACPI_TYPE_BUFFER:
93
94 /*
95 * Stores into a Field/Region or into a Integer/Buffer/String
96 * are all essentially the same. This case handles the
97 * "interchangeable" types Integer, String, and Buffer.
98 */
99 if (ACPI_GET_OBJECT_TYPE(source_desc) ==
100 ACPI_TYPE_LOCAL_REFERENCE) {
101
102 /* Resolve a reference object first */
103
104 status =
105 acpi_ex_resolve_to_value(source_desc_ptr,
106 walk_state);
107 if (ACPI_FAILURE(status)) {
108 break;
109 }
110 }
111
112 /* For copy_object, no further validation necessary */
113
114 if (walk_state->opcode == AML_COPY_OP) {
115 break;
116 }
117
118 /* Must have a Integer, Buffer, or String */
119
120 if ((ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_INTEGER) &&
121 (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_BUFFER) &&
122 (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_STRING) &&
123 !((ACPI_GET_OBJECT_TYPE(source_desc) ==
124 ACPI_TYPE_LOCAL_REFERENCE)
125 && (source_desc->reference.class ==
126 ACPI_REFCLASS_TABLE))) {
127
128 /* Conversion successful but still not a valid type */
129
130 ACPI_ERROR((AE_INFO,
131 "Cannot assign type %s to %s (must be type Int/Str/Buf)",
132 acpi_ut_get_object_type_name(source_desc),
133 acpi_ut_get_type_name(target_type)));
134 status = AE_AML_OPERAND_TYPE;
135 }
136 break;
137
138 case ACPI_TYPE_LOCAL_ALIAS:
139 case ACPI_TYPE_LOCAL_METHOD_ALIAS:
140
141 /*
142 * All aliases should have been resolved earlier, during the
143 * operand resolution phase.
144 */
145 ACPI_ERROR((AE_INFO, "Store into an unresolved Alias object"));
146 status = AE_AML_INTERNAL;
147 break;
148
149 case ACPI_TYPE_PACKAGE:
150 default:
151
152 /*
153 * All other types than Alias and the various Fields come here,
154 * including the untyped case - ACPI_TYPE_ANY.
155 */
156 break;
157 }
158
159 return_ACPI_STATUS(status);
160}
161
162/*******************************************************************************
163 *
164 * FUNCTION: acpi_ex_store_object_to_object
165 *
166 * PARAMETERS: source_desc - Object to store
167 * dest_desc - Object to receive a copy of the source
168 * new_desc - New object if dest_desc is obsoleted
169 * walk_state - Current walk state
170 *
171 * RETURN: Status
172 *
173 * DESCRIPTION: "Store" an object to another object. This may include
174 * converting the source type to the target type (implicit
175 * conversion), and a copy of the value of the source to
176 * the target.
177 *
178 * The Assignment of an object to another (not named) object
179 * is handled here.
180 * The Source passed in will replace the current value (if any)
181 * with the input value.
182 *
183 * When storing into an object the data is converted to the
184 * target object type then stored in the object. This means
185 * that the target object type (for an initialized target) will
186 * not be changed by a store operation.
187 *
188 * This module allows destination types of Number, String,
189 * Buffer, and Package.
190 *
191 * Assumes parameters are already validated. NOTE: source_desc
192 * resolution (from a reference object) must be performed by
193 * the caller if necessary.
194 *
195 ******************************************************************************/
196
197acpi_status
198acpi_ex_store_object_to_object(union acpi_operand_object *source_desc,
199 union acpi_operand_object *dest_desc,
200 union acpi_operand_object **new_desc,
201 struct acpi_walk_state *walk_state)
202{
203 union acpi_operand_object *actual_src_desc;
204 acpi_status status = AE_OK;
205
206 ACPI_FUNCTION_TRACE_PTR(ex_store_object_to_object, source_desc);
207
208 actual_src_desc = source_desc;
209 if (!dest_desc) {
210 /*
211 * There is no destination object (An uninitialized node or
212 * package element), so we can simply copy the source object
213 * creating a new destination object
214 */
215 status =
216 acpi_ut_copy_iobject_to_iobject(actual_src_desc, new_desc,
217 walk_state);
218 return_ACPI_STATUS(status);
219 }
220
221 if (ACPI_GET_OBJECT_TYPE(source_desc) !=
222 ACPI_GET_OBJECT_TYPE(dest_desc)) {
223 /*
224 * The source type does not match the type of the destination.
225 * Perform the "implicit conversion" of the source to the current type
226 * of the target as per the ACPI specification.
227 *
228 * If no conversion performed, actual_src_desc = source_desc.
229 * Otherwise, actual_src_desc is a temporary object to hold the
230 * converted object.
231 */
232 status =
233 acpi_ex_convert_to_target_type(ACPI_GET_OBJECT_TYPE
234 (dest_desc), source_desc,
235 &actual_src_desc,
236 walk_state);
237 if (ACPI_FAILURE(status)) {
238 return_ACPI_STATUS(status);
239 }
240
241 if (source_desc == actual_src_desc) {
242 /*
243 * No conversion was performed. Return the source_desc as the
244 * new object.
245 */
246 *new_desc = source_desc;
247 return_ACPI_STATUS(AE_OK);
248 }
249 }
250
251 /*
252 * We now have two objects of identical types, and we can perform a
253 * copy of the *value* of the source object.
254 */
255 switch (ACPI_GET_OBJECT_TYPE(dest_desc)) {
256 case ACPI_TYPE_INTEGER:
257
258 dest_desc->integer.value = actual_src_desc->integer.value;
259
260 /* Truncate value if we are executing from a 32-bit ACPI table */
261
262 acpi_ex_truncate_for32bit_table(dest_desc);
263 break;
264
265 case ACPI_TYPE_STRING:
266
267 status =
268 acpi_ex_store_string_to_string(actual_src_desc, dest_desc);
269 break;
270
271 case ACPI_TYPE_BUFFER:
272
273 status =
274 acpi_ex_store_buffer_to_buffer(actual_src_desc, dest_desc);
275 break;
276
277 case ACPI_TYPE_PACKAGE:
278
279 status =
280 acpi_ut_copy_iobject_to_iobject(actual_src_desc, &dest_desc,
281 walk_state);
282 break;
283
284 default:
285 /*
286 * All other types come here.
287 */
288 ACPI_WARNING((AE_INFO, "Store into type %s not implemented",
289 acpi_ut_get_object_type_name(dest_desc)));
290
291 status = AE_NOT_IMPLEMENTED;
292 break;
293 }
294
295 if (actual_src_desc != source_desc) {
296
297 /* Delete the intermediate (temporary) source object */
298
299 acpi_ut_remove_reference(actual_src_desc);
300 }
301
302 *new_desc = dest_desc;
303 return_ACPI_STATUS(status);
304}
diff --git a/drivers/acpi/acpica/exstorob.c b/drivers/acpi/acpica/exstorob.c
new file mode 100644
index 00000000000..a48d580d71c
--- /dev/null
+++ b/drivers/acpi/acpica/exstorob.c
@@ -0,0 +1,209 @@
1
2/******************************************************************************
3 *
4 * Module Name: exstorob - AML Interpreter object store support, store to object
5 *
6 *****************************************************************************/
7
8/*
9 * Copyright (C) 2000 - 2008, Intel Corp.
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions, and the following disclaimer,
17 * without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 * substantially similar to the "NO WARRANTY" disclaimer below
20 * ("Disclaimer") and any redistribution must be conditioned upon
21 * including a substantially similar Disclaimer requirement for further
22 * binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 * of any contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
30 *
31 * NO WARRANTY
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
43 */
44
45#include <acpi/acpi.h>
46#include <acpi/accommon.h>
47#include <acpi/acinterp.h>
48
49#define _COMPONENT ACPI_EXECUTER
50ACPI_MODULE_NAME("exstorob")
51
52/*******************************************************************************
53 *
54 * FUNCTION: acpi_ex_store_buffer_to_buffer
55 *
56 * PARAMETERS: source_desc - Source object to copy
57 * target_desc - Destination object of the copy
58 *
59 * RETURN: Status
60 *
61 * DESCRIPTION: Copy a buffer object to another buffer object.
62 *
63 ******************************************************************************/
64acpi_status
65acpi_ex_store_buffer_to_buffer(union acpi_operand_object *source_desc,
66 union acpi_operand_object *target_desc)
67{
68 u32 length;
69 u8 *buffer;
70
71 ACPI_FUNCTION_TRACE_PTR(ex_store_buffer_to_buffer, source_desc);
72
73 /* We know that source_desc is a buffer by now */
74
75 buffer = ACPI_CAST_PTR(u8, source_desc->buffer.pointer);
76 length = source_desc->buffer.length;
77
78 /*
79 * If target is a buffer of length zero or is a static buffer,
80 * allocate a new buffer of the proper length
81 */
82 if ((target_desc->buffer.length == 0) ||
83 (target_desc->common.flags & AOPOBJ_STATIC_POINTER)) {
84 target_desc->buffer.pointer = ACPI_ALLOCATE(length);
85 if (!target_desc->buffer.pointer) {
86 return_ACPI_STATUS(AE_NO_MEMORY);
87 }
88
89 target_desc->buffer.length = length;
90 }
91
92 /* Copy source buffer to target buffer */
93
94 if (length <= target_desc->buffer.length) {
95
96 /* Clear existing buffer and copy in the new one */
97
98 ACPI_MEMSET(target_desc->buffer.pointer, 0,
99 target_desc->buffer.length);
100 ACPI_MEMCPY(target_desc->buffer.pointer, buffer, length);
101
102#ifdef ACPI_OBSOLETE_BEHAVIOR
103 /*
104 * NOTE: ACPI versions up to 3.0 specified that the buffer must be
105 * truncated if the string is smaller than the buffer. However, "other"
106 * implementations of ACPI never did this and thus became the defacto
107 * standard. ACPI 3.0_a changes this behavior such that the buffer
108 * is no longer truncated.
109 */
110
111 /*
112 * OBSOLETE BEHAVIOR:
113 * If the original source was a string, we must truncate the buffer,
114 * according to the ACPI spec. Integer-to-Buffer and Buffer-to-Buffer
115 * copy must not truncate the original buffer.
116 */
117 if (original_src_type == ACPI_TYPE_STRING) {
118
119 /* Set the new length of the target */
120
121 target_desc->buffer.length = length;
122 }
123#endif
124 } else {
125 /* Truncate the source, copy only what will fit */
126
127 ACPI_MEMCPY(target_desc->buffer.pointer, buffer,
128 target_desc->buffer.length);
129
130 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
131 "Truncating source buffer from %X to %X\n",
132 length, target_desc->buffer.length));
133 }
134
135 /* Copy flags */
136
137 target_desc->buffer.flags = source_desc->buffer.flags;
138 target_desc->common.flags &= ~AOPOBJ_STATIC_POINTER;
139 return_ACPI_STATUS(AE_OK);
140}
141
142/*******************************************************************************
143 *
144 * FUNCTION: acpi_ex_store_string_to_string
145 *
146 * PARAMETERS: source_desc - Source object to copy
147 * target_desc - Destination object of the copy
148 *
149 * RETURN: Status
150 *
151 * DESCRIPTION: Copy a String object to another String object
152 *
153 ******************************************************************************/
154
155acpi_status
156acpi_ex_store_string_to_string(union acpi_operand_object *source_desc,
157 union acpi_operand_object *target_desc)
158{
159 u32 length;
160 u8 *buffer;
161
162 ACPI_FUNCTION_TRACE_PTR(ex_store_string_to_string, source_desc);
163
164 /* We know that source_desc is a string by now */
165
166 buffer = ACPI_CAST_PTR(u8, source_desc->string.pointer);
167 length = source_desc->string.length;
168
169 /*
170 * Replace existing string value if it will fit and the string
171 * pointer is not a static pointer (part of an ACPI table)
172 */
173 if ((length < target_desc->string.length) &&
174 (!(target_desc->common.flags & AOPOBJ_STATIC_POINTER))) {
175 /*
176 * String will fit in existing non-static buffer.
177 * Clear old string and copy in the new one
178 */
179 ACPI_MEMSET(target_desc->string.pointer, 0,
180 (acpi_size) target_desc->string.length + 1);
181 ACPI_MEMCPY(target_desc->string.pointer, buffer, length);
182 } else {
183 /*
184 * Free the current buffer, then allocate a new buffer
185 * large enough to hold the value
186 */
187 if (target_desc->string.pointer &&
188 (!(target_desc->common.flags & AOPOBJ_STATIC_POINTER))) {
189
190 /* Only free if not a pointer into the DSDT */
191
192 ACPI_FREE(target_desc->string.pointer);
193 }
194
195 target_desc->string.pointer = ACPI_ALLOCATE_ZEROED((acpi_size)
196 length + 1);
197 if (!target_desc->string.pointer) {
198 return_ACPI_STATUS(AE_NO_MEMORY);
199 }
200
201 target_desc->common.flags &= ~AOPOBJ_STATIC_POINTER;
202 ACPI_MEMCPY(target_desc->string.pointer, buffer, length);
203 }
204
205 /* Set the new target length */
206
207 target_desc->string.length = length;
208 return_ACPI_STATUS(AE_OK);
209}
diff --git a/drivers/acpi/acpica/exsystem.c b/drivers/acpi/acpica/exsystem.c
new file mode 100644
index 00000000000..a25b2c576eb
--- /dev/null
+++ b/drivers/acpi/acpica/exsystem.c
@@ -0,0 +1,303 @@
1
2/******************************************************************************
3 *
4 * Module Name: exsystem - Interface to OS services
5 *
6 *****************************************************************************/
7
8/*
9 * Copyright (C) 2000 - 2008, Intel Corp.
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions, and the following disclaimer,
17 * without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 * substantially similar to the "NO WARRANTY" disclaimer below
20 * ("Disclaimer") and any redistribution must be conditioned upon
21 * including a substantially similar Disclaimer requirement for further
22 * binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 * of any contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
30 *
31 * NO WARRANTY
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
43 */
44
45#include <acpi/acpi.h>
46#include <acpi/accommon.h>
47#include <acpi/acinterp.h>
48
49#define _COMPONENT ACPI_EXECUTER
50ACPI_MODULE_NAME("exsystem")
51
52/*******************************************************************************
53 *
54 * FUNCTION: acpi_ex_system_wait_semaphore
55 *
56 * PARAMETERS: Semaphore - Semaphore to wait on
57 * Timeout - Max time to wait
58 *
59 * RETURN: Status
60 *
61 * DESCRIPTION: Implements a semaphore wait with a check to see if the
62 * semaphore is available immediately. If it is not, the
63 * interpreter is released before waiting.
64 *
65 ******************************************************************************/
66acpi_status acpi_ex_system_wait_semaphore(acpi_semaphore semaphore, u16 timeout)
67{
68 acpi_status status;
69
70 ACPI_FUNCTION_TRACE(ex_system_wait_semaphore);
71
72 status = acpi_os_wait_semaphore(semaphore, 1, ACPI_DO_NOT_WAIT);
73 if (ACPI_SUCCESS(status)) {
74 return_ACPI_STATUS(status);
75 }
76
77 if (status == AE_TIME) {
78
79 /* We must wait, so unlock the interpreter */
80
81 acpi_ex_relinquish_interpreter();
82
83 status = acpi_os_wait_semaphore(semaphore, 1, timeout);
84
85 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
86 "*** Thread awake after blocking, %s\n",
87 acpi_format_exception(status)));
88
89 /* Reacquire the interpreter */
90
91 acpi_ex_reacquire_interpreter();
92 }
93
94 return_ACPI_STATUS(status);
95}
96
97/*******************************************************************************
98 *
99 * FUNCTION: acpi_ex_system_wait_mutex
100 *
101 * PARAMETERS: Mutex - Mutex to wait on
102 * Timeout - Max time to wait
103 *
104 * RETURN: Status
105 *
106 * DESCRIPTION: Implements a mutex wait with a check to see if the
107 * mutex is available immediately. If it is not, the
108 * interpreter is released before waiting.
109 *
110 ******************************************************************************/
111
112acpi_status acpi_ex_system_wait_mutex(acpi_mutex mutex, u16 timeout)
113{
114 acpi_status status;
115
116 ACPI_FUNCTION_TRACE(ex_system_wait_mutex);
117
118 status = acpi_os_acquire_mutex(mutex, ACPI_DO_NOT_WAIT);
119 if (ACPI_SUCCESS(status)) {
120 return_ACPI_STATUS(status);
121 }
122
123 if (status == AE_TIME) {
124
125 /* We must wait, so unlock the interpreter */
126
127 acpi_ex_relinquish_interpreter();
128
129 status = acpi_os_acquire_mutex(mutex, timeout);
130
131 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
132 "*** Thread awake after blocking, %s\n",
133 acpi_format_exception(status)));
134
135 /* Reacquire the interpreter */
136
137 acpi_ex_reacquire_interpreter();
138 }
139
140 return_ACPI_STATUS(status);
141}
142
143/*******************************************************************************
144 *
145 * FUNCTION: acpi_ex_system_do_stall
146 *
147 * PARAMETERS: how_long - The amount of time to stall,
148 * in microseconds
149 *
150 * RETURN: Status
151 *
152 * DESCRIPTION: Suspend running thread for specified amount of time.
153 * Note: ACPI specification requires that Stall() does not
154 * relinquish the processor, and delays longer than 100 usec
155 * should use Sleep() instead. We allow stalls up to 255 usec
156 * for compatibility with other interpreters and existing BIOSs.
157 *
158 ******************************************************************************/
159
160acpi_status acpi_ex_system_do_stall(u32 how_long)
161{
162 acpi_status status = AE_OK;
163
164 ACPI_FUNCTION_ENTRY();
165
166 if (how_long > 255) { /* 255 microseconds */
167 /*
168 * Longer than 255 usec, this is an error
169 *
170 * (ACPI specifies 100 usec as max, but this gives some slack in
171 * order to support existing BIOSs)
172 */
173 ACPI_ERROR((AE_INFO, "Time parameter is too large (%d)",
174 how_long));
175 status = AE_AML_OPERAND_VALUE;
176 } else {
177 acpi_os_stall(how_long);
178 }
179
180 return (status);
181}
182
183/*******************************************************************************
184 *
185 * FUNCTION: acpi_ex_system_do_suspend
186 *
187 * PARAMETERS: how_long - The amount of time to suspend,
188 * in milliseconds
189 *
190 * RETURN: None
191 *
192 * DESCRIPTION: Suspend running thread for specified amount of time.
193 *
194 ******************************************************************************/
195
196acpi_status acpi_ex_system_do_suspend(acpi_integer how_long)
197{
198 ACPI_FUNCTION_ENTRY();
199
200 /* Since this thread will sleep, we must release the interpreter */
201
202 acpi_ex_relinquish_interpreter();
203
204 acpi_os_sleep(how_long);
205
206 /* And now we must get the interpreter again */
207
208 acpi_ex_reacquire_interpreter();
209 return (AE_OK);
210}
211
212/*******************************************************************************
213 *
214 * FUNCTION: acpi_ex_system_signal_event
215 *
216 * PARAMETERS: obj_desc - The object descriptor for this op
217 *
218 * RETURN: Status
219 *
220 * DESCRIPTION: Provides an access point to perform synchronization operations
221 * within the AML.
222 *
223 ******************************************************************************/
224
225acpi_status acpi_ex_system_signal_event(union acpi_operand_object * obj_desc)
226{
227 acpi_status status = AE_OK;
228
229 ACPI_FUNCTION_TRACE(ex_system_signal_event);
230
231 if (obj_desc) {
232 status =
233 acpi_os_signal_semaphore(obj_desc->event.os_semaphore, 1);
234 }
235
236 return_ACPI_STATUS(status);
237}
238
239/*******************************************************************************
240 *
241 * FUNCTION: acpi_ex_system_wait_event
242 *
243 * PARAMETERS: time_desc - The 'time to delay' object descriptor
244 * obj_desc - The object descriptor for this op
245 *
246 * RETURN: Status
247 *
248 * DESCRIPTION: Provides an access point to perform synchronization operations
249 * within the AML. This operation is a request to wait for an
250 * event.
251 *
252 ******************************************************************************/
253
254acpi_status
255acpi_ex_system_wait_event(union acpi_operand_object *time_desc,
256 union acpi_operand_object *obj_desc)
257{
258 acpi_status status = AE_OK;
259
260 ACPI_FUNCTION_TRACE(ex_system_wait_event);
261
262 if (obj_desc) {
263 status =
264 acpi_ex_system_wait_semaphore(obj_desc->event.os_semaphore,
265 (u16) time_desc->integer.
266 value);
267 }
268
269 return_ACPI_STATUS(status);
270}
271
272/*******************************************************************************
273 *
274 * FUNCTION: acpi_ex_system_reset_event
275 *
276 * PARAMETERS: obj_desc - The object descriptor for this op
277 *
278 * RETURN: Status
279 *
280 * DESCRIPTION: Reset an event to a known state.
281 *
282 ******************************************************************************/
283
284acpi_status acpi_ex_system_reset_event(union acpi_operand_object *obj_desc)
285{
286 acpi_status status = AE_OK;
287 acpi_semaphore temp_semaphore;
288
289 ACPI_FUNCTION_ENTRY();
290
291 /*
292 * We are going to simply delete the existing semaphore and
293 * create a new one!
294 */
295 status =
296 acpi_os_create_semaphore(ACPI_NO_UNIT_LIMIT, 0, &temp_semaphore);
297 if (ACPI_SUCCESS(status)) {
298 (void)acpi_os_delete_semaphore(obj_desc->event.os_semaphore);
299 obj_desc->event.os_semaphore = temp_semaphore;
300 }
301
302 return (status);
303}
diff --git a/drivers/acpi/acpica/exutils.c b/drivers/acpi/acpica/exutils.c
new file mode 100644
index 00000000000..0ecdb70c498
--- /dev/null
+++ b/drivers/acpi/acpica/exutils.c
@@ -0,0 +1,421 @@
1
2/******************************************************************************
3 *
4 * Module Name: exutils - interpreter/scanner utilities
5 *
6 *****************************************************************************/
7
8/*
9 * Copyright (C) 2000 - 2008, Intel Corp.
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions, and the following disclaimer,
17 * without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 * substantially similar to the "NO WARRANTY" disclaimer below
20 * ("Disclaimer") and any redistribution must be conditioned upon
21 * including a substantially similar Disclaimer requirement for further
22 * binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 * of any contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
30 *
31 * NO WARRANTY
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
43 */
44
45/*
46 * DEFINE_AML_GLOBALS is tested in amlcode.h
47 * to determine whether certain global names should be "defined" or only
48 * "declared" in the current compilation. This enhances maintainability
49 * by enabling a single header file to embody all knowledge of the names
50 * in question.
51 *
52 * Exactly one module of any executable should #define DEFINE_GLOBALS
53 * before #including the header files which use this convention. The
54 * names in question will be defined and initialized in that module,
55 * and declared as extern in all other modules which #include those
56 * header files.
57 */
58
59#define DEFINE_AML_GLOBALS
60
61#include <acpi/acpi.h>
62#include <acpi/accommon.h>
63#include <acpi/acinterp.h>
64#include <acpi/amlcode.h>
65
66#define _COMPONENT ACPI_EXECUTER
67ACPI_MODULE_NAME("exutils")
68
69/* Local prototypes */
70static u32 acpi_ex_digits_needed(acpi_integer value, u32 base);
71
72#ifndef ACPI_NO_METHOD_EXECUTION
73/*******************************************************************************
74 *
75 * FUNCTION: acpi_ex_enter_interpreter
76 *
77 * PARAMETERS: None
78 *
79 * RETURN: None
80 *
81 * DESCRIPTION: Enter the interpreter execution region. Failure to enter
82 * the interpreter region is a fatal system error. Used in
83 * conjunction with exit_interpreter.
84 *
85 ******************************************************************************/
86
87void acpi_ex_enter_interpreter(void)
88{
89 acpi_status status;
90
91 ACPI_FUNCTION_TRACE(ex_enter_interpreter);
92
93 status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER);
94 if (ACPI_FAILURE(status)) {
95 ACPI_ERROR((AE_INFO,
96 "Could not acquire AML Interpreter mutex"));
97 }
98
99 return_VOID;
100}
101
102/*******************************************************************************
103 *
104 * FUNCTION: acpi_ex_reacquire_interpreter
105 *
106 * PARAMETERS: None
107 *
108 * RETURN: None
109 *
110 * DESCRIPTION: Reacquire the interpreter execution region from within the
111 * interpreter code. Failure to enter the interpreter region is a
112 * fatal system error. Used in conjuction with
113 * relinquish_interpreter
114 *
115 ******************************************************************************/
116
117void acpi_ex_reacquire_interpreter(void)
118{
119 ACPI_FUNCTION_TRACE(ex_reacquire_interpreter);
120
121 /*
122 * If the global serialized flag is set, do not release the interpreter,
123 * since it was not actually released by acpi_ex_relinquish_interpreter.
124 * This forces the interpreter to be single threaded.
125 */
126 if (!acpi_gbl_all_methods_serialized) {
127 acpi_ex_enter_interpreter();
128 }
129
130 return_VOID;
131}
132
133/*******************************************************************************
134 *
135 * FUNCTION: acpi_ex_exit_interpreter
136 *
137 * PARAMETERS: None
138 *
139 * RETURN: None
140 *
141 * DESCRIPTION: Exit the interpreter execution region. This is the top level
142 * routine used to exit the interpreter when all processing has
143 * been completed.
144 *
145 ******************************************************************************/
146
147void acpi_ex_exit_interpreter(void)
148{
149 acpi_status status;
150
151 ACPI_FUNCTION_TRACE(ex_exit_interpreter);
152
153 status = acpi_ut_release_mutex(ACPI_MTX_INTERPRETER);
154 if (ACPI_FAILURE(status)) {
155 ACPI_ERROR((AE_INFO,
156 "Could not release AML Interpreter mutex"));
157 }
158
159 return_VOID;
160}
161
162/*******************************************************************************
163 *
164 * FUNCTION: acpi_ex_relinquish_interpreter
165 *
166 * PARAMETERS: None
167 *
168 * RETURN: None
169 *
170 * DESCRIPTION: Exit the interpreter execution region, from within the
171 * interpreter - before attempting an operation that will possibly
172 * block the running thread.
173 *
174 * Cases where the interpreter is unlocked internally
175 * 1) Method to be blocked on a Sleep() AML opcode
176 * 2) Method to be blocked on an Acquire() AML opcode
177 * 3) Method to be blocked on a Wait() AML opcode
178 * 4) Method to be blocked to acquire the global lock
179 * 5) Method to be blocked waiting to execute a serialized control method
180 * that is currently executing
181 * 6) About to invoke a user-installed opregion handler
182 *
183 ******************************************************************************/
184
185void acpi_ex_relinquish_interpreter(void)
186{
187 ACPI_FUNCTION_TRACE(ex_relinquish_interpreter);
188
189 /*
190 * If the global serialized flag is set, do not release the interpreter.
191 * This forces the interpreter to be single threaded.
192 */
193 if (!acpi_gbl_all_methods_serialized) {
194 acpi_ex_exit_interpreter();
195 }
196
197 return_VOID;
198}
199
200/*******************************************************************************
201 *
202 * FUNCTION: acpi_ex_truncate_for32bit_table
203 *
204 * PARAMETERS: obj_desc - Object to be truncated
205 *
206 * RETURN: none
207 *
208 * DESCRIPTION: Truncate an ACPI Integer to 32 bits if the execution mode is
209 * 32-bit, as determined by the revision of the DSDT.
210 *
211 ******************************************************************************/
212
213void acpi_ex_truncate_for32bit_table(union acpi_operand_object *obj_desc)
214{
215
216 ACPI_FUNCTION_ENTRY();
217
218 /*
219 * Object must be a valid number and we must be executing
220 * a control method. NS node could be there for AML_INT_NAMEPATH_OP.
221 */
222 if ((!obj_desc) ||
223 (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) != ACPI_DESC_TYPE_OPERAND) ||
224 (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_INTEGER)) {
225 return;
226 }
227
228 if (acpi_gbl_integer_byte_width == 4) {
229 /*
230 * We are running a method that exists in a 32-bit ACPI table.
231 * Truncate the value to 32 bits by zeroing out the upper 32-bit field
232 */
233 obj_desc->integer.value &= (acpi_integer) ACPI_UINT32_MAX;
234 }
235}
236
237/*******************************************************************************
238 *
239 * FUNCTION: acpi_ex_acquire_global_lock
240 *
241 * PARAMETERS: field_flags - Flags with Lock rule:
242 * always_lock or never_lock
243 *
244 * RETURN: None
245 *
246 * DESCRIPTION: Obtain the ACPI hardware Global Lock, only if the field
247 * flags specifiy that it is to be obtained before field access.
248 *
249 ******************************************************************************/
250
251void acpi_ex_acquire_global_lock(u32 field_flags)
252{
253 acpi_status status;
254
255 ACPI_FUNCTION_TRACE(ex_acquire_global_lock);
256
257 /* Only use the lock if the always_lock bit is set */
258
259 if (!(field_flags & AML_FIELD_LOCK_RULE_MASK)) {
260 return_VOID;
261 }
262
263 /* Attempt to get the global lock, wait forever */
264
265 status = acpi_ex_acquire_mutex_object(ACPI_WAIT_FOREVER,
266 acpi_gbl_global_lock_mutex,
267 acpi_os_get_thread_id());
268
269 if (ACPI_FAILURE(status)) {
270 ACPI_EXCEPTION((AE_INFO, status,
271 "Could not acquire Global Lock"));
272 }
273
274 return_VOID;
275}
276
277/*******************************************************************************
278 *
279 * FUNCTION: acpi_ex_release_global_lock
280 *
281 * PARAMETERS: field_flags - Flags with Lock rule:
282 * always_lock or never_lock
283 *
284 * RETURN: None
285 *
286 * DESCRIPTION: Release the ACPI hardware Global Lock
287 *
288 ******************************************************************************/
289
290void acpi_ex_release_global_lock(u32 field_flags)
291{
292 acpi_status status;
293
294 ACPI_FUNCTION_TRACE(ex_release_global_lock);
295
296 /* Only use the lock if the always_lock bit is set */
297
298 if (!(field_flags & AML_FIELD_LOCK_RULE_MASK)) {
299 return_VOID;
300 }
301
302 /* Release the global lock */
303
304 status = acpi_ex_release_mutex_object(acpi_gbl_global_lock_mutex);
305 if (ACPI_FAILURE(status)) {
306
307 /* Report the error, but there isn't much else we can do */
308
309 ACPI_EXCEPTION((AE_INFO, status,
310 "Could not release Global Lock"));
311 }
312
313 return_VOID;
314}
315
316/*******************************************************************************
317 *
318 * FUNCTION: acpi_ex_digits_needed
319 *
320 * PARAMETERS: Value - Value to be represented
321 * Base - Base of representation
322 *
323 * RETURN: The number of digits.
324 *
325 * DESCRIPTION: Calculate the number of digits needed to represent the Value
326 * in the given Base (Radix)
327 *
328 ******************************************************************************/
329
330static u32 acpi_ex_digits_needed(acpi_integer value, u32 base)
331{
332 u32 num_digits;
333 acpi_integer current_value;
334
335 ACPI_FUNCTION_TRACE(ex_digits_needed);
336
337 /* acpi_integer is unsigned, so we don't worry about a '-' prefix */
338
339 if (value == 0) {
340 return_UINT32(1);
341 }
342
343 current_value = value;
344 num_digits = 0;
345
346 /* Count the digits in the requested base */
347
348 while (current_value) {
349 (void)acpi_ut_short_divide(current_value, base, &current_value,
350 NULL);
351 num_digits++;
352 }
353
354 return_UINT32(num_digits);
355}
356
357/*******************************************************************************
358 *
359 * FUNCTION: acpi_ex_eisa_id_to_string
360 *
361 * PARAMETERS: numeric_id - EISA ID to be converted
362 * out_string - Where to put the converted string (8 bytes)
363 *
364 * RETURN: None
365 *
366 * DESCRIPTION: Convert a numeric EISA ID to string representation
367 *
368 ******************************************************************************/
369
370void acpi_ex_eisa_id_to_string(u32 numeric_id, char *out_string)
371{
372 u32 eisa_id;
373
374 ACPI_FUNCTION_ENTRY();
375
376 /* Swap ID to big-endian to get contiguous bits */
377
378 eisa_id = acpi_ut_dword_byte_swap(numeric_id);
379
380 out_string[0] = (char)('@' + (((unsigned long)eisa_id >> 26) & 0x1f));
381 out_string[1] = (char)('@' + ((eisa_id >> 21) & 0x1f));
382 out_string[2] = (char)('@' + ((eisa_id >> 16) & 0x1f));
383 out_string[3] = acpi_ut_hex_to_ascii_char((acpi_integer) eisa_id, 12);
384 out_string[4] = acpi_ut_hex_to_ascii_char((acpi_integer) eisa_id, 8);
385 out_string[5] = acpi_ut_hex_to_ascii_char((acpi_integer) eisa_id, 4);
386 out_string[6] = acpi_ut_hex_to_ascii_char((acpi_integer) eisa_id, 0);
387 out_string[7] = 0;
388}
389
390/*******************************************************************************
391 *
392 * FUNCTION: acpi_ex_unsigned_integer_to_string
393 *
394 * PARAMETERS: Value - Value to be converted
395 * out_string - Where to put the converted string (8 bytes)
396 *
397 * RETURN: None, string
398 *
399 * DESCRIPTION: Convert a number to string representation. Assumes string
400 * buffer is large enough to hold the string.
401 *
402 ******************************************************************************/
403
404void acpi_ex_unsigned_integer_to_string(acpi_integer value, char *out_string)
405{
406 u32 count;
407 u32 digits_needed;
408 u32 remainder;
409
410 ACPI_FUNCTION_ENTRY();
411
412 digits_needed = acpi_ex_digits_needed(value, 10);
413 out_string[digits_needed] = 0;
414
415 for (count = digits_needed; count > 0; count--) {
416 (void)acpi_ut_short_divide(value, 10, &value, &remainder);
417 out_string[count - 1] = (char)('0' + remainder);
418 }
419}
420
421#endif
diff --git a/drivers/acpi/acpica/hwacpi.c b/drivers/acpi/acpica/hwacpi.c
new file mode 100644
index 00000000000..c76e3cd7e74
--- /dev/null
+++ b/drivers/acpi/acpica/hwacpi.c
@@ -0,0 +1,185 @@
1
2/******************************************************************************
3 *
4 * Module Name: hwacpi - ACPI Hardware Initialization/Mode Interface
5 *
6 *****************************************************************************/
7
8/*
9 * Copyright (C) 2000 - 2008, Intel Corp.
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions, and the following disclaimer,
17 * without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 * substantially similar to the "NO WARRANTY" disclaimer below
20 * ("Disclaimer") and any redistribution must be conditioned upon
21 * including a substantially similar Disclaimer requirement for further
22 * binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 * of any contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
30 *
31 * NO WARRANTY
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
43 */
44
45#include <acpi/acpi.h>
46#include <acpi/accommon.h>
47
48#define _COMPONENT ACPI_HARDWARE
49ACPI_MODULE_NAME("hwacpi")
50
51/******************************************************************************
52 *
53 * FUNCTION: acpi_hw_set_mode
54 *
55 * PARAMETERS: Mode - SYS_MODE_ACPI or SYS_MODE_LEGACY
56 *
57 * RETURN: Status
58 *
59 * DESCRIPTION: Transitions the system into the requested mode.
60 *
61 ******************************************************************************/
62acpi_status acpi_hw_set_mode(u32 mode)
63{
64
65 acpi_status status;
66 u32 retry;
67
68 ACPI_FUNCTION_TRACE(hw_set_mode);
69
70 /*
71 * ACPI 2.0 clarified that if SMI_CMD in FADT is zero,
72 * system does not support mode transition.
73 */
74 if (!acpi_gbl_FADT.smi_command) {
75 ACPI_ERROR((AE_INFO,
76 "No SMI_CMD in FADT, mode transition failed"));
77 return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE);
78 }
79
80 /*
81 * ACPI 2.0 clarified the meaning of ACPI_ENABLE and ACPI_DISABLE
82 * in FADT: If it is zero, enabling or disabling is not supported.
83 * As old systems may have used zero for mode transition,
84 * we make sure both the numbers are zero to determine these
85 * transitions are not supported.
86 */
87 if (!acpi_gbl_FADT.acpi_enable && !acpi_gbl_FADT.acpi_disable) {
88 ACPI_ERROR((AE_INFO,
89 "No ACPI mode transition supported in this system (enable/disable both zero)"));
90 return_ACPI_STATUS(AE_OK);
91 }
92
93 switch (mode) {
94 case ACPI_SYS_MODE_ACPI:
95
96 /* BIOS should have disabled ALL fixed and GP events */
97
98 status = acpi_os_write_port(acpi_gbl_FADT.smi_command,
99 (u32) acpi_gbl_FADT.acpi_enable, 8);
100 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
101 "Attempting to enable ACPI mode\n"));
102 break;
103
104 case ACPI_SYS_MODE_LEGACY:
105
106 /*
107 * BIOS should clear all fixed status bits and restore fixed event
108 * enable bits to default
109 */
110 status = acpi_os_write_port(acpi_gbl_FADT.smi_command,
111 (u32) acpi_gbl_FADT.acpi_disable,
112 8);
113 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
114 "Attempting to enable Legacy (non-ACPI) mode\n"));
115 break;
116
117 default:
118 return_ACPI_STATUS(AE_BAD_PARAMETER);
119 }
120
121 if (ACPI_FAILURE(status)) {
122 ACPI_EXCEPTION((AE_INFO, status,
123 "Could not write ACPI mode change"));
124 return_ACPI_STATUS(status);
125 }
126
127 /*
128 * Some hardware takes a LONG time to switch modes. Give them 3 sec to
129 * do so, but allow faster systems to proceed more quickly.
130 */
131 retry = 3000;
132 while (retry) {
133 if (acpi_hw_get_mode() == mode) {
134 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
135 "Mode %X successfully enabled\n",
136 mode));
137 return_ACPI_STATUS(AE_OK);
138 }
139 acpi_os_stall(1000);
140 retry--;
141 }
142
143 ACPI_ERROR((AE_INFO, "Hardware did not change modes"));
144 return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE);
145}
146
147/*******************************************************************************
148 *
149 * FUNCTION: acpi_hw_get_mode
150 *
151 * PARAMETERS: none
152 *
153 * RETURN: SYS_MODE_ACPI or SYS_MODE_LEGACY
154 *
155 * DESCRIPTION: Return current operating state of system. Determined by
156 * querying the SCI_EN bit.
157 *
158 ******************************************************************************/
159
160u32 acpi_hw_get_mode(void)
161{
162 acpi_status status;
163 u32 value;
164
165 ACPI_FUNCTION_TRACE(hw_get_mode);
166
167 /*
168 * ACPI 2.0 clarified that if SMI_CMD in FADT is zero,
169 * system does not support mode transition.
170 */
171 if (!acpi_gbl_FADT.smi_command) {
172 return_UINT32(ACPI_SYS_MODE_ACPI);
173 }
174
175 status = acpi_get_register(ACPI_BITREG_SCI_ENABLE, &value);
176 if (ACPI_FAILURE(status)) {
177 return_UINT32(ACPI_SYS_MODE_LEGACY);
178 }
179
180 if (value) {
181 return_UINT32(ACPI_SYS_MODE_ACPI);
182 } else {
183 return_UINT32(ACPI_SYS_MODE_LEGACY);
184 }
185}
diff --git a/drivers/acpi/acpica/hwgpe.c b/drivers/acpi/acpica/hwgpe.c
new file mode 100644
index 00000000000..2b4a85a839d
--- /dev/null
+++ b/drivers/acpi/acpica/hwgpe.c
@@ -0,0 +1,469 @@
1
2/******************************************************************************
3 *
4 * Module Name: hwgpe - Low level GPE enable/disable/clear functions
5 *
6 *****************************************************************************/
7
8/*
9 * Copyright (C) 2000 - 2008, Intel Corp.
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions, and the following disclaimer,
17 * without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 * substantially similar to the "NO WARRANTY" disclaimer below
20 * ("Disclaimer") and any redistribution must be conditioned upon
21 * including a substantially similar Disclaimer requirement for further
22 * binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 * of any contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
30 *
31 * NO WARRANTY
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
43 */
44
45#include <acpi/acpi.h>
46#include <acpi/accommon.h>
47#include <acpi/acevents.h>
48
49#define _COMPONENT ACPI_HARDWARE
50ACPI_MODULE_NAME("hwgpe")
51
52/* Local prototypes */
53static acpi_status
54acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
55 struct acpi_gpe_block_info *gpe_block,
56 void *context);
57
58/******************************************************************************
59 *
60 * FUNCTION: acpi_hw_low_disable_gpe
61 *
62 * PARAMETERS: gpe_event_info - Info block for the GPE to be disabled
63 *
64 * RETURN: Status
65 *
66 * DESCRIPTION: Disable a single GPE in the enable register.
67 *
68 ******************************************************************************/
69
70acpi_status acpi_hw_low_disable_gpe(struct acpi_gpe_event_info *gpe_event_info)
71{
72 struct acpi_gpe_register_info *gpe_register_info;
73 acpi_status status;
74 u32 enable_mask;
75
76 /* Get the info block for the entire GPE register */
77
78 gpe_register_info = gpe_event_info->register_info;
79 if (!gpe_register_info) {
80 return (AE_NOT_EXIST);
81 }
82
83 /* Get current value of the enable register that contains this GPE */
84
85 status = acpi_read(&enable_mask, &gpe_register_info->enable_address);
86 if (ACPI_FAILURE(status)) {
87 return (status);
88 }
89
90 /* Clear just the bit that corresponds to this GPE */
91
92 ACPI_CLEAR_BIT(enable_mask,
93 ((u32) 1 <<
94 (gpe_event_info->gpe_number -
95 gpe_register_info->base_gpe_number)));
96
97 /* Write the updated enable mask */
98
99 status = acpi_write(enable_mask, &gpe_register_info->enable_address);
100 return (status);
101}
102
103/******************************************************************************
104 *
105 * FUNCTION: acpi_hw_write_gpe_enable_reg
106 *
107 * PARAMETERS: gpe_event_info - Info block for the GPE to be enabled
108 *
109 * RETURN: Status
110 *
111 * DESCRIPTION: Write a GPE enable register. Note: The bit for this GPE must
112 * already be cleared or set in the parent register
113 * enable_for_run mask.
114 *
115 ******************************************************************************/
116
117acpi_status
118acpi_hw_write_gpe_enable_reg(struct acpi_gpe_event_info * gpe_event_info)
119{
120 struct acpi_gpe_register_info *gpe_register_info;
121 acpi_status status;
122
123 ACPI_FUNCTION_ENTRY();
124
125 /* Get the info block for the entire GPE register */
126
127 gpe_register_info = gpe_event_info->register_info;
128 if (!gpe_register_info) {
129 return (AE_NOT_EXIST);
130 }
131
132 /* Write the entire GPE (runtime) enable register */
133
134 status = acpi_write(gpe_register_info->enable_for_run,
135 &gpe_register_info->enable_address);
136
137 return (status);
138}
139
140/******************************************************************************
141 *
142 * FUNCTION: acpi_hw_clear_gpe
143 *
144 * PARAMETERS: gpe_event_info - Info block for the GPE to be cleared
145 *
146 * RETURN: Status
147 *
148 * DESCRIPTION: Clear the status bit for a single GPE.
149 *
150 ******************************************************************************/
151
152acpi_status acpi_hw_clear_gpe(struct acpi_gpe_event_info * gpe_event_info)
153{
154 acpi_status status;
155 u8 register_bit;
156
157 ACPI_FUNCTION_ENTRY();
158
159 register_bit = (u8)
160 (1 <<
161 (gpe_event_info->gpe_number -
162 gpe_event_info->register_info->base_gpe_number));
163
164 /*
165 * Write a one to the appropriate bit in the status register to
166 * clear this GPE.
167 */
168 status = acpi_write(register_bit,
169 &gpe_event_info->register_info->status_address);
170
171 return (status);
172}
173
174/******************************************************************************
175 *
176 * FUNCTION: acpi_hw_get_gpe_status
177 *
178 * PARAMETERS: gpe_event_info - Info block for the GPE to queried
179 * event_status - Where the GPE status is returned
180 *
181 * RETURN: Status
182 *
183 * DESCRIPTION: Return the status of a single GPE.
184 *
185 ******************************************************************************/
186
187acpi_status
188acpi_hw_get_gpe_status(struct acpi_gpe_event_info * gpe_event_info,
189 acpi_event_status * event_status)
190{
191 u32 in_byte;
192 u8 register_bit;
193 struct acpi_gpe_register_info *gpe_register_info;
194 acpi_status status;
195 acpi_event_status local_event_status = 0;
196
197 ACPI_FUNCTION_ENTRY();
198
199 if (!event_status) {
200 return (AE_BAD_PARAMETER);
201 }
202
203 /* Get the info block for the entire GPE register */
204
205 gpe_register_info = gpe_event_info->register_info;
206
207 /* Get the register bitmask for this GPE */
208
209 register_bit = (u8)
210 (1 <<
211 (gpe_event_info->gpe_number -
212 gpe_event_info->register_info->base_gpe_number));
213
214 /* GPE currently enabled? (enabled for runtime?) */
215
216 if (register_bit & gpe_register_info->enable_for_run) {
217 local_event_status |= ACPI_EVENT_FLAG_ENABLED;
218 }
219
220 /* GPE enabled for wake? */
221
222 if (register_bit & gpe_register_info->enable_for_wake) {
223 local_event_status |= ACPI_EVENT_FLAG_WAKE_ENABLED;
224 }
225
226 /* GPE currently active (status bit == 1)? */
227
228 status = acpi_read(&in_byte, &gpe_register_info->status_address);
229 if (ACPI_FAILURE(status)) {
230 goto unlock_and_exit;
231 }
232
233 if (register_bit & in_byte) {
234 local_event_status |= ACPI_EVENT_FLAG_SET;
235 }
236
237 /* Set return value */
238
239 (*event_status) = local_event_status;
240
241 unlock_and_exit:
242 return (status);
243}
244
245/******************************************************************************
246 *
247 * FUNCTION: acpi_hw_disable_gpe_block
248 *
249 * PARAMETERS: gpe_xrupt_info - GPE Interrupt info
250 * gpe_block - Gpe Block info
251 *
252 * RETURN: Status
253 *
254 * DESCRIPTION: Disable all GPEs within a single GPE block
255 *
256 ******************************************************************************/
257
258acpi_status
259acpi_hw_disable_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
260 struct acpi_gpe_block_info *gpe_block, void *context)
261{
262 u32 i;
263 acpi_status status;
264
265 /* Examine each GPE Register within the block */
266
267 for (i = 0; i < gpe_block->register_count; i++) {
268
269 /* Disable all GPEs in this register */
270
271 status =
272 acpi_write(0x00,
273 &gpe_block->register_info[i].enable_address);
274 if (ACPI_FAILURE(status)) {
275 return (status);
276 }
277 }
278
279 return (AE_OK);
280}
281
282/******************************************************************************
283 *
284 * FUNCTION: acpi_hw_clear_gpe_block
285 *
286 * PARAMETERS: gpe_xrupt_info - GPE Interrupt info
287 * gpe_block - Gpe Block info
288 *
289 * RETURN: Status
290 *
291 * DESCRIPTION: Clear status bits for all GPEs within a single GPE block
292 *
293 ******************************************************************************/
294
295acpi_status
296acpi_hw_clear_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
297 struct acpi_gpe_block_info *gpe_block, void *context)
298{
299 u32 i;
300 acpi_status status;
301
302 /* Examine each GPE Register within the block */
303
304 for (i = 0; i < gpe_block->register_count; i++) {
305
306 /* Clear status on all GPEs in this register */
307
308 status =
309 acpi_write(0xFF,
310 &gpe_block->register_info[i].status_address);
311 if (ACPI_FAILURE(status)) {
312 return (status);
313 }
314 }
315
316 return (AE_OK);
317}
318
319/******************************************************************************
320 *
321 * FUNCTION: acpi_hw_enable_runtime_gpe_block
322 *
323 * PARAMETERS: gpe_xrupt_info - GPE Interrupt info
324 * gpe_block - Gpe Block info
325 *
326 * RETURN: Status
327 *
328 * DESCRIPTION: Enable all "runtime" GPEs within a single GPE block. Includes
329 * combination wake/run GPEs.
330 *
331 ******************************************************************************/
332
333acpi_status
334acpi_hw_enable_runtime_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
335 struct acpi_gpe_block_info *gpe_block, void *context)
336{
337 u32 i;
338 acpi_status status;
339
340 /* NOTE: assumes that all GPEs are currently disabled */
341
342 /* Examine each GPE Register within the block */
343
344 for (i = 0; i < gpe_block->register_count; i++) {
345 if (!gpe_block->register_info[i].enable_for_run) {
346 continue;
347 }
348
349 /* Enable all "runtime" GPEs in this register */
350
351 status = acpi_write(gpe_block->register_info[i].enable_for_run,
352 &gpe_block->register_info[i].
353 enable_address);
354 if (ACPI_FAILURE(status)) {
355 return (status);
356 }
357 }
358
359 return (AE_OK);
360}
361
362/******************************************************************************
363 *
364 * FUNCTION: acpi_hw_enable_wakeup_gpe_block
365 *
366 * PARAMETERS: gpe_xrupt_info - GPE Interrupt info
367 * gpe_block - Gpe Block info
368 *
369 * RETURN: Status
370 *
371 * DESCRIPTION: Enable all "wake" GPEs within a single GPE block. Includes
372 * combination wake/run GPEs.
373 *
374 ******************************************************************************/
375
376static acpi_status
377acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
378 struct acpi_gpe_block_info *gpe_block,
379 void *context)
380{
381 u32 i;
382 acpi_status status;
383
384 /* Examine each GPE Register within the block */
385
386 for (i = 0; i < gpe_block->register_count; i++) {
387 if (!gpe_block->register_info[i].enable_for_wake) {
388 continue;
389 }
390
391 /* Enable all "wake" GPEs in this register */
392
393 status = acpi_write(gpe_block->register_info[i].enable_for_wake,
394 &gpe_block->register_info[i].
395 enable_address);
396 if (ACPI_FAILURE(status)) {
397 return (status);
398 }
399 }
400
401 return (AE_OK);
402}
403
404/******************************************************************************
405 *
406 * FUNCTION: acpi_hw_disable_all_gpes
407 *
408 * PARAMETERS: None
409 *
410 * RETURN: Status
411 *
412 * DESCRIPTION: Disable and clear all GPEs in all GPE blocks
413 *
414 ******************************************************************************/
415
416acpi_status acpi_hw_disable_all_gpes(void)
417{
418 acpi_status status;
419
420 ACPI_FUNCTION_TRACE(hw_disable_all_gpes);
421
422 status = acpi_ev_walk_gpe_list(acpi_hw_disable_gpe_block, NULL);
423 status = acpi_ev_walk_gpe_list(acpi_hw_clear_gpe_block, NULL);
424 return_ACPI_STATUS(status);
425}
426
427/******************************************************************************
428 *
429 * FUNCTION: acpi_hw_enable_all_runtime_gpes
430 *
431 * PARAMETERS: None
432 *
433 * RETURN: Status
434 *
435 * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks
436 *
437 ******************************************************************************/
438
439acpi_status acpi_hw_enable_all_runtime_gpes(void)
440{
441 acpi_status status;
442
443 ACPI_FUNCTION_TRACE(hw_enable_all_runtime_gpes);
444
445 status = acpi_ev_walk_gpe_list(acpi_hw_enable_runtime_gpe_block, NULL);
446 return_ACPI_STATUS(status);
447}
448
449/******************************************************************************
450 *
451 * FUNCTION: acpi_hw_enable_all_wakeup_gpes
452 *
453 * PARAMETERS: None
454 *
455 * RETURN: Status
456 *
457 * DESCRIPTION: Enable all "wakeup" GPEs, in all GPE blocks
458 *
459 ******************************************************************************/
460
461acpi_status acpi_hw_enable_all_wakeup_gpes(void)
462{
463 acpi_status status;
464
465 ACPI_FUNCTION_TRACE(hw_enable_all_wakeup_gpes);
466
467 status = acpi_ev_walk_gpe_list(acpi_hw_enable_wakeup_gpe_block, NULL);
468 return_ACPI_STATUS(status);
469}
diff --git a/drivers/acpi/acpica/hwregs.c b/drivers/acpi/acpica/hwregs.c
new file mode 100644
index 00000000000..4bc3bbba6e9
--- /dev/null
+++ b/drivers/acpi/acpica/hwregs.c
@@ -0,0 +1,353 @@
1
2/*******************************************************************************
3 *
4 * Module Name: hwregs - Read/write access functions for the various ACPI
5 * control and status registers.
6 *
7 ******************************************************************************/
8
9/*
10 * Copyright (C) 2000 - 2008, Intel Corp.
11 * All rights reserved.
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
15 * are met:
16 * 1. Redistributions of source code must retain the above copyright
17 * notice, this list of conditions, and the following disclaimer,
18 * without modification.
19 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
20 * substantially similar to the "NO WARRANTY" disclaimer below
21 * ("Disclaimer") and any redistribution must be conditioned upon
22 * including a substantially similar Disclaimer requirement for further
23 * binary redistribution.
24 * 3. Neither the names of the above-listed copyright holders nor the names
25 * of any contributors may be used to endorse or promote products derived
26 * from this software without specific prior written permission.
27 *
28 * Alternatively, this software may be distributed under the terms of the
29 * GNU General Public License ("GPL") version 2 as published by the Free
30 * Software Foundation.
31 *
32 * NO WARRANTY
33 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
34 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
35 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
36 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
37 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
38 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
39 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
40 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
41 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
42 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
43 * POSSIBILITY OF SUCH DAMAGES.
44 */
45
46#include <acpi/acpi.h>
47#include <acpi/accommon.h>
48#include <acpi/acnamesp.h>
49#include <acpi/acevents.h>
50
51#define _COMPONENT ACPI_HARDWARE
52ACPI_MODULE_NAME("hwregs")
53
54/*******************************************************************************
55 *
56 * FUNCTION: acpi_hw_clear_acpi_status
57 *
58 * PARAMETERS: None
59 *
60 * RETURN: Status
61 *
62 * DESCRIPTION: Clears all fixed and general purpose status bits
63 * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED
64 *
65 ******************************************************************************/
66acpi_status acpi_hw_clear_acpi_status(void)
67{
68 acpi_status status;
69 acpi_cpu_flags lock_flags = 0;
70
71 ACPI_FUNCTION_TRACE(hw_clear_acpi_status);
72
73 ACPI_DEBUG_PRINT((ACPI_DB_IO, "About to write %04X to %04X\n",
74 ACPI_BITMASK_ALL_FIXED_STATUS,
75 (u16) acpi_gbl_FADT.xpm1a_event_block.address));
76
77 lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock);
78
79 status = acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS,
80 ACPI_BITMASK_ALL_FIXED_STATUS);
81 if (ACPI_FAILURE(status)) {
82 goto unlock_and_exit;
83 }
84
85 /* Clear the fixed events */
86
87 if (acpi_gbl_FADT.xpm1b_event_block.address) {
88 status = acpi_write(ACPI_BITMASK_ALL_FIXED_STATUS,
89 &acpi_gbl_FADT.xpm1b_event_block);
90 if (ACPI_FAILURE(status)) {
91 goto unlock_and_exit;
92 }
93 }
94
95 /* Clear the GPE Bits in all GPE registers in all GPE blocks */
96
97 status = acpi_ev_walk_gpe_list(acpi_hw_clear_gpe_block, NULL);
98
99 unlock_and_exit:
100 acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags);
101 return_ACPI_STATUS(status);
102}
103
104/*******************************************************************************
105 *
106 * FUNCTION: acpi_hw_get_register_bit_mask
107 *
108 * PARAMETERS: register_id - Index of ACPI Register to access
109 *
110 * RETURN: The bitmask to be used when accessing the register
111 *
112 * DESCRIPTION: Map register_id into a register bitmask.
113 *
114 ******************************************************************************/
115
116struct acpi_bit_register_info *acpi_hw_get_bit_register_info(u32 register_id)
117{
118 ACPI_FUNCTION_ENTRY();
119
120 if (register_id > ACPI_BITREG_MAX) {
121 ACPI_ERROR((AE_INFO, "Invalid BitRegister ID: %X",
122 register_id));
123 return (NULL);
124 }
125
126 return (&acpi_gbl_bit_register_info[register_id]);
127}
128
129/******************************************************************************
130 *
131 * FUNCTION: acpi_hw_register_read
132 *
133 * PARAMETERS: register_id - ACPI Register ID
134 * return_value - Where the register value is returned
135 *
136 * RETURN: Status and the value read.
137 *
138 * DESCRIPTION: Read from the specified ACPI register
139 *
140 ******************************************************************************/
141acpi_status
142acpi_hw_register_read(u32 register_id, u32 * return_value)
143{
144 u32 value1 = 0;
145 u32 value2 = 0;
146 acpi_status status;
147
148 ACPI_FUNCTION_TRACE(hw_register_read);
149
150 switch (register_id) {
151 case ACPI_REGISTER_PM1_STATUS: /* 16-bit access */
152
153 status = acpi_read(&value1, &acpi_gbl_FADT.xpm1a_event_block);
154 if (ACPI_FAILURE(status)) {
155 goto exit;
156 }
157
158 /* PM1B is optional */
159
160 status = acpi_read(&value2, &acpi_gbl_FADT.xpm1b_event_block);
161 value1 |= value2;
162 break;
163
164 case ACPI_REGISTER_PM1_ENABLE: /* 16-bit access */
165
166 status = acpi_read(&value1, &acpi_gbl_xpm1a_enable);
167 if (ACPI_FAILURE(status)) {
168 goto exit;
169 }
170
171 /* PM1B is optional */
172
173 status = acpi_read(&value2, &acpi_gbl_xpm1b_enable);
174 value1 |= value2;
175 break;
176
177 case ACPI_REGISTER_PM1_CONTROL: /* 16-bit access */
178
179 status = acpi_read(&value1, &acpi_gbl_FADT.xpm1a_control_block);
180 if (ACPI_FAILURE(status)) {
181 goto exit;
182 }
183
184 status = acpi_read(&value2, &acpi_gbl_FADT.xpm1b_control_block);
185 value1 |= value2;
186 break;
187
188 case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */
189
190 status = acpi_read(&value1, &acpi_gbl_FADT.xpm2_control_block);
191 break;
192
193 case ACPI_REGISTER_PM_TIMER: /* 32-bit access */
194
195 status = acpi_read(&value1, &acpi_gbl_FADT.xpm_timer_block);
196 break;
197
198 case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */
199
200 status =
201 acpi_os_read_port(acpi_gbl_FADT.smi_command, &value1, 8);
202 break;
203
204 default:
205 ACPI_ERROR((AE_INFO, "Unknown Register ID: %X", register_id));
206 status = AE_BAD_PARAMETER;
207 break;
208 }
209
210 exit:
211
212 if (ACPI_SUCCESS(status)) {
213 *return_value = value1;
214 }
215
216 return_ACPI_STATUS(status);
217}
218
219/******************************************************************************
220 *
221 * FUNCTION: acpi_hw_register_write
222 *
223 * PARAMETERS: register_id - ACPI Register ID
224 * Value - The value to write
225 *
226 * RETURN: Status
227 *
228 * DESCRIPTION: Write to the specified ACPI register
229 *
230 * NOTE: In accordance with the ACPI specification, this function automatically
231 * preserves the value of the following bits, meaning that these bits cannot be
232 * changed via this interface:
233 *
234 * PM1_CONTROL[0] = SCI_EN
235 * PM1_CONTROL[9]
236 * PM1_STATUS[11]
237 *
238 * ACPI References:
239 * 1) Hardware Ignored Bits: When software writes to a register with ignored
240 * bit fields, it preserves the ignored bit fields
241 * 2) SCI_EN: OSPM always preserves this bit position
242 *
243 ******************************************************************************/
244
245acpi_status acpi_hw_register_write(u32 register_id, u32 value)
246{
247 acpi_status status;
248 u32 read_value;
249
250 ACPI_FUNCTION_TRACE(hw_register_write);
251
252 switch (register_id) {
253 case ACPI_REGISTER_PM1_STATUS: /* 16-bit access */
254
255 /* Perform a read first to preserve certain bits (per ACPI spec) */
256
257 status = acpi_hw_register_read(ACPI_REGISTER_PM1_STATUS,
258 &read_value);
259 if (ACPI_FAILURE(status)) {
260 goto exit;
261 }
262
263 /* Insert the bits to be preserved */
264
265 ACPI_INSERT_BITS(value, ACPI_PM1_STATUS_PRESERVED_BITS,
266 read_value);
267
268 /* Now we can write the data */
269
270 status = acpi_write(value, &acpi_gbl_FADT.xpm1a_event_block);
271 if (ACPI_FAILURE(status)) {
272 goto exit;
273 }
274
275 /* PM1B is optional */
276
277 status = acpi_write(value, &acpi_gbl_FADT.xpm1b_event_block);
278 break;
279
280 case ACPI_REGISTER_PM1_ENABLE: /* 16-bit access */
281
282 status = acpi_write(value, &acpi_gbl_xpm1a_enable);
283 if (ACPI_FAILURE(status)) {
284 goto exit;
285 }
286
287 /* PM1B is optional */
288
289 status = acpi_write(value, &acpi_gbl_xpm1b_enable);
290 break;
291
292 case ACPI_REGISTER_PM1_CONTROL: /* 16-bit access */
293
294 /*
295 * Perform a read first to preserve certain bits (per ACPI spec)
296 */
297 status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL,
298 &read_value);
299 if (ACPI_FAILURE(status)) {
300 goto exit;
301 }
302
303 /* Insert the bits to be preserved */
304
305 ACPI_INSERT_BITS(value, ACPI_PM1_CONTROL_PRESERVED_BITS,
306 read_value);
307
308 /* Now we can write the data */
309
310 status = acpi_write(value, &acpi_gbl_FADT.xpm1a_control_block);
311 if (ACPI_FAILURE(status)) {
312 goto exit;
313 }
314
315 status = acpi_write(value, &acpi_gbl_FADT.xpm1b_control_block);
316 break;
317
318 case ACPI_REGISTER_PM1A_CONTROL: /* 16-bit access */
319
320 status = acpi_write(value, &acpi_gbl_FADT.xpm1a_control_block);
321 break;
322
323 case ACPI_REGISTER_PM1B_CONTROL: /* 16-bit access */
324
325 status = acpi_write(value, &acpi_gbl_FADT.xpm1b_control_block);
326 break;
327
328 case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */
329
330 status = acpi_write(value, &acpi_gbl_FADT.xpm2_control_block);
331 break;
332
333 case ACPI_REGISTER_PM_TIMER: /* 32-bit access */
334
335 status = acpi_write(value, &acpi_gbl_FADT.xpm_timer_block);
336 break;
337
338 case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */
339
340 /* SMI_CMD is currently always in IO space */
341
342 status =
343 acpi_os_write_port(acpi_gbl_FADT.smi_command, value, 8);
344 break;
345
346 default:
347 status = AE_BAD_PARAMETER;
348 break;
349 }
350
351 exit:
352 return_ACPI_STATUS(status);
353}
diff --git a/drivers/acpi/acpica/hwsleep.c b/drivers/acpi/acpica/hwsleep.c
new file mode 100644
index 00000000000..54dd3ee0760
--- /dev/null
+++ b/drivers/acpi/acpica/hwsleep.c
@@ -0,0 +1,629 @@
1
2/******************************************************************************
3 *
4 * Name: hwsleep.c - ACPI Hardware Sleep/Wake Interface
5 *
6 *****************************************************************************/
7
8/*
9 * Copyright (C) 2000 - 2008, Intel Corp.
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions, and the following disclaimer,
17 * without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 * substantially similar to the "NO WARRANTY" disclaimer below
20 * ("Disclaimer") and any redistribution must be conditioned upon
21 * including a substantially similar Disclaimer requirement for further
22 * binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 * of any contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
30 *
31 * NO WARRANTY
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
43 */
44
45#include <acpi/acpi.h>
46#include <acpi/accommon.h>
47#include <acpi/actables.h>
48
49#define _COMPONENT ACPI_HARDWARE
50ACPI_MODULE_NAME("hwsleep")
51
52/*******************************************************************************
53 *
54 * FUNCTION: acpi_set_firmware_waking_vector
55 *
56 * PARAMETERS: physical_address - 32-bit physical address of ACPI real mode
57 * entry point.
58 *
59 * RETURN: Status
60 *
61 * DESCRIPTION: Sets the 32-bit firmware_waking_vector field of the FACS
62 *
63 ******************************************************************************/
64acpi_status
65acpi_set_firmware_waking_vector(u32 physical_address)
66{
67 ACPI_FUNCTION_TRACE(acpi_set_firmware_waking_vector);
68
69
70 /*
71 * According to the ACPI specification 2.0c and later, the 64-bit
72 * waking vector should be cleared and the 32-bit waking vector should
73 * be used, unless we want the wake-up code to be called by the BIOS in
74 * Protected Mode. Some systems (for example HP dv5-1004nr) are known
75 * to fail to resume if the 64-bit vector is used.
76 */
77
78 /* Set the 32-bit vector */
79
80 acpi_gbl_FACS->firmware_waking_vector = physical_address;
81
82 /* Clear the 64-bit vector if it exists */
83
84 if ((acpi_gbl_FACS->length > 32) && (acpi_gbl_FACS->version >= 1)) {
85 acpi_gbl_FACS->xfirmware_waking_vector = 0;
86 }
87
88 return_ACPI_STATUS(AE_OK);
89}
90
91ACPI_EXPORT_SYMBOL(acpi_set_firmware_waking_vector)
92
93/*******************************************************************************
94 *
95 * FUNCTION: acpi_set_firmware_waking_vector64
96 *
97 * PARAMETERS: physical_address - 64-bit physical address of ACPI protected
98 * mode entry point.
99 *
100 * RETURN: Status
101 *
102 * DESCRIPTION: Sets the 64-bit X_firmware_waking_vector field of the FACS, if
103 * it exists in the table.
104 *
105 ******************************************************************************/
106acpi_status
107acpi_set_firmware_waking_vector64(u64 physical_address)
108{
109 ACPI_FUNCTION_TRACE(acpi_set_firmware_waking_vector64);
110
111
112 /* Determine if the 64-bit vector actually exists */
113
114 if ((acpi_gbl_FACS->length <= 32) || (acpi_gbl_FACS->version < 1)) {
115 return_ACPI_STATUS(AE_NOT_EXIST);
116 }
117
118 /* Clear 32-bit vector, set the 64-bit X_ vector */
119
120 acpi_gbl_FACS->firmware_waking_vector = 0;
121 acpi_gbl_FACS->xfirmware_waking_vector = physical_address;
122
123 return_ACPI_STATUS(AE_OK);
124}
125
126ACPI_EXPORT_SYMBOL(acpi_set_firmware_waking_vector64)
127
128/*******************************************************************************
129 *
130 * FUNCTION: acpi_enter_sleep_state_prep
131 *
132 * PARAMETERS: sleep_state - Which sleep state to enter
133 *
134 * RETURN: Status
135 *
136 * DESCRIPTION: Prepare to enter a system sleep state (see ACPI 2.0 spec p 231)
137 * This function must execute with interrupts enabled.
138 * We break sleeping into 2 stages so that OSPM can handle
139 * various OS-specific tasks between the two steps.
140 *
141 ******************************************************************************/
142acpi_status acpi_enter_sleep_state_prep(u8 sleep_state)
143{
144 acpi_status status;
145 struct acpi_object_list arg_list;
146 union acpi_object arg;
147
148 ACPI_FUNCTION_TRACE(acpi_enter_sleep_state_prep);
149
150 /*
151 * _PSW methods could be run here to enable wake-on keyboard, LAN, etc.
152 */
153 status = acpi_get_sleep_type_data(sleep_state,
154 &acpi_gbl_sleep_type_a,
155 &acpi_gbl_sleep_type_b);
156 if (ACPI_FAILURE(status)) {
157 return_ACPI_STATUS(status);
158 }
159
160 /* Setup parameter object */
161
162 arg_list.count = 1;
163 arg_list.pointer = &arg;
164
165 arg.type = ACPI_TYPE_INTEGER;
166 arg.integer.value = sleep_state;
167
168 /* Run the _PTS method */
169
170 status = acpi_evaluate_object(NULL, METHOD_NAME__PTS, &arg_list, NULL);
171 if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
172 return_ACPI_STATUS(status);
173 }
174
175 /* Setup the argument to _SST */
176
177 switch (sleep_state) {
178 case ACPI_STATE_S0:
179 arg.integer.value = ACPI_SST_WORKING;
180 break;
181
182 case ACPI_STATE_S1:
183 case ACPI_STATE_S2:
184 case ACPI_STATE_S3:
185 arg.integer.value = ACPI_SST_SLEEPING;
186 break;
187
188 case ACPI_STATE_S4:
189 arg.integer.value = ACPI_SST_SLEEP_CONTEXT;
190 break;
191
192 default:
193 arg.integer.value = ACPI_SST_INDICATOR_OFF; /* Default is off */
194 break;
195 }
196
197 /*
198 * Set the system indicators to show the desired sleep state.
199 * _SST is an optional method (return no error if not found)
200 */
201 status = acpi_evaluate_object(NULL, METHOD_NAME__SST, &arg_list, NULL);
202 if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
203 ACPI_EXCEPTION((AE_INFO, status,
204 "While executing method _SST"));
205 }
206
207 return_ACPI_STATUS(AE_OK);
208}
209
210ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_prep)
211
212/*******************************************************************************
213 *
214 * FUNCTION: acpi_enter_sleep_state
215 *
216 * PARAMETERS: sleep_state - Which sleep state to enter
217 *
218 * RETURN: Status
219 *
220 * DESCRIPTION: Enter a system sleep state (see ACPI 2.0 spec p 231)
221 * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED
222 *
223 ******************************************************************************/
224acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
225{
226 u32 PM1Acontrol;
227 u32 PM1Bcontrol;
228 struct acpi_bit_register_info *sleep_type_reg_info;
229 struct acpi_bit_register_info *sleep_enable_reg_info;
230 u32 in_value;
231 struct acpi_object_list arg_list;
232 union acpi_object arg;
233 acpi_status status;
234
235 ACPI_FUNCTION_TRACE(acpi_enter_sleep_state);
236
237 if ((acpi_gbl_sleep_type_a > ACPI_SLEEP_TYPE_MAX) ||
238 (acpi_gbl_sleep_type_b > ACPI_SLEEP_TYPE_MAX)) {
239 ACPI_ERROR((AE_INFO, "Sleep values out of range: A=%X B=%X",
240 acpi_gbl_sleep_type_a, acpi_gbl_sleep_type_b));
241 return_ACPI_STATUS(AE_AML_OPERAND_VALUE);
242 }
243
244 sleep_type_reg_info =
245 acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_TYPE_A);
246 sleep_enable_reg_info =
247 acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_ENABLE);
248
249 /* Clear wake status */
250
251 status = acpi_set_register(ACPI_BITREG_WAKE_STATUS, 1);
252 if (ACPI_FAILURE(status)) {
253 return_ACPI_STATUS(status);
254 }
255
256 /* Clear all fixed and general purpose status bits */
257
258 status = acpi_hw_clear_acpi_status();
259 if (ACPI_FAILURE(status)) {
260 return_ACPI_STATUS(status);
261 }
262
263 /*
264 * 1) Disable/Clear all GPEs
265 * 2) Enable all wakeup GPEs
266 */
267 status = acpi_hw_disable_all_gpes();
268 if (ACPI_FAILURE(status)) {
269 return_ACPI_STATUS(status);
270 }
271 acpi_gbl_system_awake_and_running = FALSE;
272
273 status = acpi_hw_enable_all_wakeup_gpes();
274 if (ACPI_FAILURE(status)) {
275 return_ACPI_STATUS(status);
276 }
277
278 /* Execute the _GTS method */
279
280 arg_list.count = 1;
281 arg_list.pointer = &arg;
282 arg.type = ACPI_TYPE_INTEGER;
283 arg.integer.value = sleep_state;
284
285 status = acpi_evaluate_object(NULL, METHOD_NAME__GTS, &arg_list, NULL);
286 if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
287 return_ACPI_STATUS(status);
288 }
289
290 /* Get current value of PM1A control */
291
292 status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL, &PM1Acontrol);
293 if (ACPI_FAILURE(status)) {
294 return_ACPI_STATUS(status);
295 }
296 ACPI_DEBUG_PRINT((ACPI_DB_INIT,
297 "Entering sleep state [S%d]\n", sleep_state));
298
299 /* Clear SLP_EN and SLP_TYP fields */
300
301 PM1Acontrol &= ~(sleep_type_reg_info->access_bit_mask |
302 sleep_enable_reg_info->access_bit_mask);
303 PM1Bcontrol = PM1Acontrol;
304
305 /* Insert SLP_TYP bits */
306
307 PM1Acontrol |=
308 (acpi_gbl_sleep_type_a << sleep_type_reg_info->bit_position);
309 PM1Bcontrol |=
310 (acpi_gbl_sleep_type_b << sleep_type_reg_info->bit_position);
311
312 /*
313 * We split the writes of SLP_TYP and SLP_EN to workaround
314 * poorly implemented hardware.
315 */
316
317 /* Write #1: fill in SLP_TYP data */
318
319 status = acpi_hw_register_write(ACPI_REGISTER_PM1A_CONTROL,
320 PM1Acontrol);
321 if (ACPI_FAILURE(status)) {
322 return_ACPI_STATUS(status);
323 }
324
325 status = acpi_hw_register_write(ACPI_REGISTER_PM1B_CONTROL,
326 PM1Bcontrol);
327 if (ACPI_FAILURE(status)) {
328 return_ACPI_STATUS(status);
329 }
330
331 /* Insert SLP_ENABLE bit */
332
333 PM1Acontrol |= sleep_enable_reg_info->access_bit_mask;
334 PM1Bcontrol |= sleep_enable_reg_info->access_bit_mask;
335
336 /* Write #2: SLP_TYP + SLP_EN */
337
338 ACPI_FLUSH_CPU_CACHE();
339
340 status = acpi_hw_register_write(ACPI_REGISTER_PM1A_CONTROL,
341 PM1Acontrol);
342 if (ACPI_FAILURE(status)) {
343 return_ACPI_STATUS(status);
344 }
345
346 status = acpi_hw_register_write(ACPI_REGISTER_PM1B_CONTROL,
347 PM1Bcontrol);
348 if (ACPI_FAILURE(status)) {
349 return_ACPI_STATUS(status);
350 }
351
352 if (sleep_state > ACPI_STATE_S3) {
353 /*
354 * We wanted to sleep > S3, but it didn't happen (by virtue of the
355 * fact that we are still executing!)
356 *
357 * Wait ten seconds, then try again. This is to get S4/S5 to work on
358 * all machines.
359 *
360 * We wait so long to allow chipsets that poll this reg very slowly to
361 * still read the right value. Ideally, this block would go
362 * away entirely.
363 */
364 acpi_os_stall(10000000);
365
366 status = acpi_hw_register_write(ACPI_REGISTER_PM1_CONTROL,
367 sleep_enable_reg_info->
368 access_bit_mask);
369 if (ACPI_FAILURE(status)) {
370 return_ACPI_STATUS(status);
371 }
372 }
373
374 /* Wait until we enter sleep state */
375
376 do {
377 status = acpi_get_register_unlocked(ACPI_BITREG_WAKE_STATUS,
378 &in_value);
379 if (ACPI_FAILURE(status)) {
380 return_ACPI_STATUS(status);
381 }
382
383 /* Spin until we wake */
384
385 } while (!in_value);
386
387 return_ACPI_STATUS(AE_OK);
388}
389
390ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state)
391
392/*******************************************************************************
393 *
394 * FUNCTION: acpi_enter_sleep_state_s4bios
395 *
396 * PARAMETERS: None
397 *
398 * RETURN: Status
399 *
400 * DESCRIPTION: Perform a S4 bios request.
401 * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED
402 *
403 ******************************************************************************/
404acpi_status asmlinkage acpi_enter_sleep_state_s4bios(void)
405{
406 u32 in_value;
407 acpi_status status;
408
409 ACPI_FUNCTION_TRACE(acpi_enter_sleep_state_s4bios);
410
411 status = acpi_set_register(ACPI_BITREG_WAKE_STATUS, 1);
412 if (ACPI_FAILURE(status)) {
413 return_ACPI_STATUS(status);
414 }
415
416 status = acpi_hw_clear_acpi_status();
417 if (ACPI_FAILURE(status)) {
418 return_ACPI_STATUS(status);
419 }
420
421 /*
422 * 1) Disable/Clear all GPEs
423 * 2) Enable all wakeup GPEs
424 */
425 status = acpi_hw_disable_all_gpes();
426 if (ACPI_FAILURE(status)) {
427 return_ACPI_STATUS(status);
428 }
429 acpi_gbl_system_awake_and_running = FALSE;
430
431 status = acpi_hw_enable_all_wakeup_gpes();
432 if (ACPI_FAILURE(status)) {
433 return_ACPI_STATUS(status);
434 }
435
436 ACPI_FLUSH_CPU_CACHE();
437
438 status = acpi_os_write_port(acpi_gbl_FADT.smi_command,
439 (u32) acpi_gbl_FADT.S4bios_request, 8);
440
441 do {
442 acpi_os_stall(1000);
443 status = acpi_get_register(ACPI_BITREG_WAKE_STATUS, &in_value);
444 if (ACPI_FAILURE(status)) {
445 return_ACPI_STATUS(status);
446 }
447 } while (!in_value);
448
449 return_ACPI_STATUS(AE_OK);
450}
451
452ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_s4bios)
453
454/*******************************************************************************
455 *
456 * FUNCTION: acpi_leave_sleep_state_prep
457 *
458 * PARAMETERS: sleep_state - Which sleep state we are exiting
459 *
460 * RETURN: Status
461 *
462 * DESCRIPTION: Perform the first state of OS-independent ACPI cleanup after a
463 * sleep.
464 * Called with interrupts DISABLED.
465 *
466 ******************************************************************************/
467acpi_status acpi_leave_sleep_state_prep(u8 sleep_state)
468{
469 struct acpi_object_list arg_list;
470 union acpi_object arg;
471 acpi_status status;
472 struct acpi_bit_register_info *sleep_type_reg_info;
473 struct acpi_bit_register_info *sleep_enable_reg_info;
474 u32 PM1Acontrol;
475 u32 PM1Bcontrol;
476
477 ACPI_FUNCTION_TRACE(acpi_leave_sleep_state_prep);
478
479 /*
480 * Set SLP_TYPE and SLP_EN to state S0.
481 * This is unclear from the ACPI Spec, but it is required
482 * by some machines.
483 */
484 status = acpi_get_sleep_type_data(ACPI_STATE_S0,
485 &acpi_gbl_sleep_type_a,
486 &acpi_gbl_sleep_type_b);
487 if (ACPI_SUCCESS(status)) {
488 sleep_type_reg_info =
489 acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_TYPE_A);
490 sleep_enable_reg_info =
491 acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_ENABLE);
492
493 /* Get current value of PM1A control */
494
495 status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL,
496 &PM1Acontrol);
497 if (ACPI_SUCCESS(status)) {
498
499 /* Clear SLP_EN and SLP_TYP fields */
500
501 PM1Acontrol &= ~(sleep_type_reg_info->access_bit_mask |
502 sleep_enable_reg_info->
503 access_bit_mask);
504 PM1Bcontrol = PM1Acontrol;
505
506 /* Insert SLP_TYP bits */
507
508 PM1Acontrol |=
509 (acpi_gbl_sleep_type_a << sleep_type_reg_info->
510 bit_position);
511 PM1Bcontrol |=
512 (acpi_gbl_sleep_type_b << sleep_type_reg_info->
513 bit_position);
514
515 /* Just ignore any errors */
516
517 (void)acpi_hw_register_write(ACPI_REGISTER_PM1A_CONTROL,
518 PM1Acontrol);
519 (void)acpi_hw_register_write(ACPI_REGISTER_PM1B_CONTROL,
520 PM1Bcontrol);
521 }
522 }
523
524 /* Execute the _BFS method */
525
526 arg_list.count = 1;
527 arg_list.pointer = &arg;
528 arg.type = ACPI_TYPE_INTEGER;
529 arg.integer.value = sleep_state;
530
531 status = acpi_evaluate_object(NULL, METHOD_NAME__BFS, &arg_list, NULL);
532 if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
533 ACPI_EXCEPTION((AE_INFO, status, "During Method _BFS"));
534 }
535
536 return_ACPI_STATUS(status);
537}
538
539/*******************************************************************************
540 *
541 * FUNCTION: acpi_leave_sleep_state
542 *
543 * PARAMETERS: sleep_state - Which sleep state we just exited
544 *
545 * RETURN: Status
546 *
547 * DESCRIPTION: Perform OS-independent ACPI cleanup after a sleep
548 * Called with interrupts ENABLED.
549 *
550 ******************************************************************************/
551acpi_status acpi_leave_sleep_state(u8 sleep_state)
552{
553 struct acpi_object_list arg_list;
554 union acpi_object arg;
555 acpi_status status;
556
557 ACPI_FUNCTION_TRACE(acpi_leave_sleep_state);
558
559 /* Ensure enter_sleep_state_prep -> enter_sleep_state ordering */
560
561 acpi_gbl_sleep_type_a = ACPI_SLEEP_TYPE_INVALID;
562
563 /* Setup parameter object */
564
565 arg_list.count = 1;
566 arg_list.pointer = &arg;
567 arg.type = ACPI_TYPE_INTEGER;
568
569 /* Ignore any errors from these methods */
570
571 arg.integer.value = ACPI_SST_WAKING;
572 status = acpi_evaluate_object(NULL, METHOD_NAME__SST, &arg_list, NULL);
573 if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
574 ACPI_EXCEPTION((AE_INFO, status, "During Method _SST"));
575 }
576
577 /*
578 * GPEs must be enabled before _WAK is called as GPEs
579 * might get fired there
580 *
581 * Restore the GPEs:
582 * 1) Disable/Clear all GPEs
583 * 2) Enable all runtime GPEs
584 */
585 status = acpi_hw_disable_all_gpes();
586 if (ACPI_FAILURE(status)) {
587 return_ACPI_STATUS(status);
588 }
589 status = acpi_hw_enable_all_runtime_gpes();
590 if (ACPI_FAILURE(status)) {
591 return_ACPI_STATUS(status);
592 }
593
594 arg.integer.value = sleep_state;
595 status = acpi_evaluate_object(NULL, METHOD_NAME__WAK, &arg_list, NULL);
596 if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
597 ACPI_EXCEPTION((AE_INFO, status, "During Method _WAK"));
598 }
599 /* TBD: _WAK "sometimes" returns stuff - do we want to look at it? */
600
601 /*
602 * Some BIOSes assume that WAK_STS will be cleared on resume and use
603 * it to determine whether the system is rebooting or resuming. Clear
604 * it for compatibility.
605 */
606 acpi_set_register(ACPI_BITREG_WAKE_STATUS, 1);
607
608 acpi_gbl_system_awake_and_running = TRUE;
609
610 /* Enable power button */
611
612 (void)
613 acpi_set_register(acpi_gbl_fixed_event_info
614 [ACPI_EVENT_POWER_BUTTON].enable_register_id, 1);
615
616 (void)
617 acpi_set_register(acpi_gbl_fixed_event_info
618 [ACPI_EVENT_POWER_BUTTON].status_register_id, 1);
619
620 arg.integer.value = ACPI_SST_WORKING;
621 status = acpi_evaluate_object(NULL, METHOD_NAME__SST, &arg_list, NULL);
622 if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
623 ACPI_EXCEPTION((AE_INFO, status, "During Method _SST"));
624 }
625
626 return_ACPI_STATUS(status);
627}
628
629ACPI_EXPORT_SYMBOL(acpi_leave_sleep_state)
diff --git a/drivers/acpi/acpica/hwtimer.c b/drivers/acpi/acpica/hwtimer.c
new file mode 100644
index 00000000000..d1eac2aad72
--- /dev/null
+++ b/drivers/acpi/acpica/hwtimer.c
@@ -0,0 +1,188 @@
1
2/******************************************************************************
3 *
4 * Name: hwtimer.c - ACPI Power Management Timer Interface
5 *
6 *****************************************************************************/
7
8/*
9 * Copyright (C) 2000 - 2008, Intel Corp.
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions, and the following disclaimer,
17 * without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 * substantially similar to the "NO WARRANTY" disclaimer below
20 * ("Disclaimer") and any redistribution must be conditioned upon
21 * including a substantially similar Disclaimer requirement for further
22 * binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 * of any contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
30 *
31 * NO WARRANTY
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
43 */
44
45#include <acpi/acpi.h>
46#include <acpi/accommon.h>
47
48#define _COMPONENT ACPI_HARDWARE
49ACPI_MODULE_NAME("hwtimer")
50
51/******************************************************************************
52 *
53 * FUNCTION: acpi_get_timer_resolution
54 *
55 * PARAMETERS: Resolution - Where the resolution is returned
56 *
57 * RETURN: Status and timer resolution
58 *
59 * DESCRIPTION: Obtains resolution of the ACPI PM Timer (24 or 32 bits).
60 *
61 ******************************************************************************/
62acpi_status acpi_get_timer_resolution(u32 * resolution)
63{
64 ACPI_FUNCTION_TRACE(acpi_get_timer_resolution);
65
66 if (!resolution) {
67 return_ACPI_STATUS(AE_BAD_PARAMETER);
68 }
69
70 if ((acpi_gbl_FADT.flags & ACPI_FADT_32BIT_TIMER) == 0) {
71 *resolution = 24;
72 } else {
73 *resolution = 32;
74 }
75
76 return_ACPI_STATUS(AE_OK);
77}
78
79ACPI_EXPORT_SYMBOL(acpi_get_timer_resolution)
80
81/******************************************************************************
82 *
83 * FUNCTION: acpi_get_timer
84 *
85 * PARAMETERS: Ticks - Where the timer value is returned
86 *
87 * RETURN: Status and current timer value (ticks)
88 *
89 * DESCRIPTION: Obtains current value of ACPI PM Timer (in ticks).
90 *
91 ******************************************************************************/
92acpi_status acpi_get_timer(u32 * ticks)
93{
94 acpi_status status;
95
96 ACPI_FUNCTION_TRACE(acpi_get_timer);
97
98 if (!ticks) {
99 return_ACPI_STATUS(AE_BAD_PARAMETER);
100 }
101
102 status =
103 acpi_hw_low_level_read(32, ticks, &acpi_gbl_FADT.xpm_timer_block);
104
105 return_ACPI_STATUS(status);
106}
107
108ACPI_EXPORT_SYMBOL(acpi_get_timer)
109
110/******************************************************************************
111 *
112 * FUNCTION: acpi_get_timer_duration
113 *
114 * PARAMETERS: start_ticks - Starting timestamp
115 * end_ticks - End timestamp
116 * time_elapsed - Where the elapsed time is returned
117 *
118 * RETURN: Status and time_elapsed
119 *
120 * DESCRIPTION: Computes the time elapsed (in microseconds) between two
121 * PM Timer time stamps, taking into account the possibility of
122 * rollovers, the timer resolution, and timer frequency.
123 *
124 * The PM Timer's clock ticks at roughly 3.6 times per
125 * _microsecond_, and its clock continues through Cx state
126 * transitions (unlike many CPU timestamp counters) -- making it
127 * a versatile and accurate timer.
128 *
129 * Note that this function accommodates only a single timer
130 * rollover. Thus for 24-bit timers, this function should only
131 * be used for calculating durations less than ~4.6 seconds
132 * (~20 minutes for 32-bit timers) -- calculations below:
133 *
134 * 2**24 Ticks / 3,600,000 Ticks/Sec = 4.66 sec
135 * 2**32 Ticks / 3,600,000 Ticks/Sec = 1193 sec or 19.88 minutes
136 *
137 ******************************************************************************/
138acpi_status
139acpi_get_timer_duration(u32 start_ticks, u32 end_ticks, u32 * time_elapsed)
140{
141 acpi_status status;
142 u32 delta_ticks;
143 acpi_integer quotient;
144
145 ACPI_FUNCTION_TRACE(acpi_get_timer_duration);
146
147 if (!time_elapsed) {
148 return_ACPI_STATUS(AE_BAD_PARAMETER);
149 }
150
151 /*
152 * Compute Tick Delta:
153 * Handle (max one) timer rollovers on 24-bit versus 32-bit timers.
154 */
155 if (start_ticks < end_ticks) {
156 delta_ticks = end_ticks - start_ticks;
157 } else if (start_ticks > end_ticks) {
158 if ((acpi_gbl_FADT.flags & ACPI_FADT_32BIT_TIMER) == 0) {
159
160 /* 24-bit Timer */
161
162 delta_ticks =
163 (((0x00FFFFFF - start_ticks) +
164 end_ticks) & 0x00FFFFFF);
165 } else {
166 /* 32-bit Timer */
167
168 delta_ticks = (0xFFFFFFFF - start_ticks) + end_ticks;
169 }
170 } else { /* start_ticks == end_ticks */
171
172 *time_elapsed = 0;
173 return_ACPI_STATUS(AE_OK);
174 }
175
176 /*
177 * Compute Duration (Requires a 64-bit multiply and divide):
178 *
179 * time_elapsed = (delta_ticks * 1000000) / PM_TIMER_FREQUENCY;
180 */
181 status = acpi_ut_short_divide(((u64) delta_ticks) * 1000000,
182 PM_TIMER_FREQUENCY, &quotient, NULL);
183
184 *time_elapsed = (u32) quotient;
185 return_ACPI_STATUS(status);
186}
187
188ACPI_EXPORT_SYMBOL(acpi_get_timer_duration)
diff --git a/drivers/acpi/acpica/hwxface.c b/drivers/acpi/acpica/hwxface.c
new file mode 100644
index 00000000000..a4456fc9462
--- /dev/null
+++ b/drivers/acpi/acpica/hwxface.c
@@ -0,0 +1,593 @@
1
2/******************************************************************************
3 *
4 * Module Name: hwxface - Public ACPICA hardware interfaces
5 *
6 *****************************************************************************/
7
8/*
9 * Copyright (C) 2000 - 2008, Intel Corp.
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions, and the following disclaimer,
17 * without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 * substantially similar to the "NO WARRANTY" disclaimer below
20 * ("Disclaimer") and any redistribution must be conditioned upon
21 * including a substantially similar Disclaimer requirement for further
22 * binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 * of any contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
30 *
31 * NO WARRANTY
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
43 */
44
45#include <acpi/acpi.h>
46#include <acpi/accommon.h>
47#include <acpi/acnamesp.h>
48
49#define _COMPONENT ACPI_HARDWARE
50ACPI_MODULE_NAME("hwxface")
51
52/******************************************************************************
53 *
54 * FUNCTION: acpi_reset
55 *
56 * PARAMETERS: None
57 *
58 * RETURN: Status
59 *
60 * DESCRIPTION: Set reset register in memory or IO space. Note: Does not
61 * support reset register in PCI config space, this must be
62 * handled separately.
63 *
64 ******************************************************************************/
65acpi_status acpi_reset(void)
66{
67 struct acpi_generic_address *reset_reg;
68 acpi_status status;
69
70 ACPI_FUNCTION_TRACE(acpi_reset);
71
72 reset_reg = &acpi_gbl_FADT.reset_register;
73
74 /* Check if the reset register is supported */
75
76 if (!(acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER) ||
77 !reset_reg->address) {
78 return_ACPI_STATUS(AE_NOT_EXIST);
79 }
80
81 /* Write the reset value to the reset register */
82
83 status = acpi_write(acpi_gbl_FADT.reset_value, reset_reg);
84 return_ACPI_STATUS(status);
85}
86
87ACPI_EXPORT_SYMBOL(acpi_reset)
88
89/******************************************************************************
90 *
91 * FUNCTION: acpi_read
92 *
93 * PARAMETERS: Value - Where the value is returned
94 * Reg - GAS register structure
95 *
96 * RETURN: Status
97 *
98 * DESCRIPTION: Read from either memory or IO space.
99 *
100 ******************************************************************************/
101acpi_status acpi_read(u32 *value, struct acpi_generic_address *reg)
102{
103 u32 width;
104 u64 address;
105 acpi_status status;
106
107 ACPI_FUNCTION_NAME(acpi_read);
108
109 /*
110 * Must have a valid pointer to a GAS structure, and
111 * a non-zero address within. However, don't return an error
112 * because the PM1A/B code must not fail if B isn't present.
113 */
114 if (!reg) {
115 return (AE_OK);
116 }
117
118 /* Get a local copy of the address. Handles possible alignment issues */
119
120 ACPI_MOVE_64_TO_64(&address, &reg->address);
121 if (!address) {
122 return (AE_OK);
123 }
124
125 /* Supported widths are 8/16/32 */
126
127 width = reg->bit_width;
128 if ((width != 8) && (width != 16) && (width != 32)) {
129 return (AE_SUPPORT);
130 }
131
132 /* Initialize entire 32-bit return value to zero */
133
134 *value = 0;
135
136 /*
137 * Two address spaces supported: Memory or IO.
138 * PCI_Config is not supported here because the GAS struct is insufficient
139 */
140 switch (reg->space_id) {
141 case ACPI_ADR_SPACE_SYSTEM_MEMORY:
142
143 status = acpi_os_read_memory((acpi_physical_address) address,
144 value, width);
145 break;
146
147 case ACPI_ADR_SPACE_SYSTEM_IO:
148
149 status =
150 acpi_os_read_port((acpi_io_address) address, value, width);
151 break;
152
153 default:
154 ACPI_ERROR((AE_INFO,
155 "Unsupported address space: %X", reg->space_id));
156 return (AE_BAD_PARAMETER);
157 }
158
159 ACPI_DEBUG_PRINT((ACPI_DB_IO,
160 "Read: %8.8X width %2d from %8.8X%8.8X (%s)\n",
161 *value, width, ACPI_FORMAT_UINT64(address),
162 acpi_ut_get_region_name(reg->space_id)));
163
164 return (status);
165}
166
167ACPI_EXPORT_SYMBOL(acpi_read)
168
169/******************************************************************************
170 *
171 * FUNCTION: acpi_write
172 *
173 * PARAMETERS: Value - To be written
174 * Reg - GAS register structure
175 *
176 * RETURN: Status
177 *
178 * DESCRIPTION: Write to either memory or IO space.
179 *
180 ******************************************************************************/
181acpi_status acpi_write(u32 value, struct acpi_generic_address *reg)
182{
183 u32 width;
184 u64 address;
185 acpi_status status;
186
187 ACPI_FUNCTION_NAME(acpi_write);
188
189 /*
190 * Must have a valid pointer to a GAS structure, and
191 * a non-zero address within. However, don't return an error
192 * because the PM1A/B code must not fail if B isn't present.
193 */
194 if (!reg) {
195 return (AE_OK);
196 }
197
198 /* Get a local copy of the address. Handles possible alignment issues */
199
200 ACPI_MOVE_64_TO_64(&address, &reg->address);
201 if (!address) {
202 return (AE_OK);
203 }
204
205 /* Supported widths are 8/16/32 */
206
207 width = reg->bit_width;
208 if ((width != 8) && (width != 16) && (width != 32)) {
209 return (AE_SUPPORT);
210 }
211
212 /*
213 * Two address spaces supported: Memory or IO.
214 * PCI_Config is not supported here because the GAS struct is insufficient
215 */
216 switch (reg->space_id) {
217 case ACPI_ADR_SPACE_SYSTEM_MEMORY:
218
219 status = acpi_os_write_memory((acpi_physical_address) address,
220 value, width);
221 break;
222
223 case ACPI_ADR_SPACE_SYSTEM_IO:
224
225 status = acpi_os_write_port((acpi_io_address) address, value,
226 width);
227 break;
228
229 default:
230 ACPI_ERROR((AE_INFO,
231 "Unsupported address space: %X", reg->space_id));
232 return (AE_BAD_PARAMETER);
233 }
234
235 ACPI_DEBUG_PRINT((ACPI_DB_IO,
236 "Wrote: %8.8X width %2d to %8.8X%8.8X (%s)\n",
237 value, width, ACPI_FORMAT_UINT64(address),
238 acpi_ut_get_region_name(reg->space_id)));
239
240 return (status);
241}
242
243ACPI_EXPORT_SYMBOL(acpi_write)
244
245/*******************************************************************************
246 *
247 * FUNCTION: acpi_get_register_unlocked
248 *
249 * PARAMETERS: register_id - ID of ACPI bit_register to access
250 * return_value - Value that was read from the register
251 *
252 * RETURN: Status and the value read from specified Register. Value
253 * returned is normalized to bit0 (is shifted all the way right)
254 *
255 * DESCRIPTION: ACPI bit_register read function. Does not acquire the HW lock.
256 *
257 ******************************************************************************/
258acpi_status acpi_get_register_unlocked(u32 register_id, u32 *return_value)
259{
260 u32 register_value = 0;
261 struct acpi_bit_register_info *bit_reg_info;
262 acpi_status status;
263
264 ACPI_FUNCTION_TRACE(acpi_get_register_unlocked);
265
266 /* Get the info structure corresponding to the requested ACPI Register */
267
268 bit_reg_info = acpi_hw_get_bit_register_info(register_id);
269 if (!bit_reg_info) {
270 return_ACPI_STATUS(AE_BAD_PARAMETER);
271 }
272
273 /* Read from the register */
274
275 status = acpi_hw_register_read(bit_reg_info->parent_register,
276 &register_value);
277
278 if (ACPI_SUCCESS(status)) {
279
280 /* Normalize the value that was read */
281
282 register_value =
283 ((register_value & bit_reg_info->access_bit_mask)
284 >> bit_reg_info->bit_position);
285
286 *return_value = register_value;
287
288 ACPI_DEBUG_PRINT((ACPI_DB_IO, "Read value %8.8X register %X\n",
289 register_value,
290 bit_reg_info->parent_register));
291 }
292
293 return_ACPI_STATUS(status);
294}
295
296ACPI_EXPORT_SYMBOL(acpi_get_register_unlocked)
297
298/*******************************************************************************
299 *
300 * FUNCTION: acpi_get_register
301 *
302 * PARAMETERS: register_id - ID of ACPI bit_register to access
303 * return_value - Value that was read from the register
304 *
305 * RETURN: Status and the value read from specified Register. Value
306 * returned is normalized to bit0 (is shifted all the way right)
307 *
308 * DESCRIPTION: ACPI bit_register read function.
309 *
310 ******************************************************************************/
311acpi_status acpi_get_register(u32 register_id, u32 *return_value)
312{
313 acpi_status status;
314 acpi_cpu_flags flags;
315
316 flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock);
317 status = acpi_get_register_unlocked(register_id, return_value);
318 acpi_os_release_lock(acpi_gbl_hardware_lock, flags);
319
320 return (status);
321}
322
323ACPI_EXPORT_SYMBOL(acpi_get_register)
324
325/*******************************************************************************
326 *
327 * FUNCTION: acpi_set_register
328 *
329 * PARAMETERS: register_id - ID of ACPI bit_register to access
330 * Value - (only used on write) value to write to the
331 * Register, NOT pre-normalized to the bit pos
332 *
333 * RETURN: Status
334 *
335 * DESCRIPTION: ACPI Bit Register write function.
336 *
337 ******************************************************************************/
338acpi_status acpi_set_register(u32 register_id, u32 value)
339{
340 u32 register_value = 0;
341 struct acpi_bit_register_info *bit_reg_info;
342 acpi_status status;
343 acpi_cpu_flags lock_flags;
344
345 ACPI_FUNCTION_TRACE_U32(acpi_set_register, register_id);
346
347 /* Get the info structure corresponding to the requested ACPI Register */
348
349 bit_reg_info = acpi_hw_get_bit_register_info(register_id);
350 if (!bit_reg_info) {
351 ACPI_ERROR((AE_INFO, "Bad ACPI HW RegisterId: %X",
352 register_id));
353 return_ACPI_STATUS(AE_BAD_PARAMETER);
354 }
355
356 lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock);
357
358 /* Always do a register read first so we can insert the new bits */
359
360 status = acpi_hw_register_read(bit_reg_info->parent_register,
361 &register_value);
362 if (ACPI_FAILURE(status)) {
363 goto unlock_and_exit;
364 }
365
366 /*
367 * Decode the Register ID
368 * Register ID = [Register block ID] | [bit ID]
369 *
370 * Check bit ID to fine locate Register offset.
371 * Check Mask to determine Register offset, and then read-write.
372 */
373 switch (bit_reg_info->parent_register) {
374 case ACPI_REGISTER_PM1_STATUS:
375
376 /*
377 * Status Registers are different from the rest. Clear by
378 * writing 1, and writing 0 has no effect. So, the only relevant
379 * information is the single bit we're interested in, all others should
380 * be written as 0 so they will be left unchanged.
381 */
382 value = ACPI_REGISTER_PREPARE_BITS(value,
383 bit_reg_info->bit_position,
384 bit_reg_info->
385 access_bit_mask);
386 if (value) {
387 status =
388 acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS,
389 (u16) value);
390 register_value = 0;
391 }
392 break;
393
394 case ACPI_REGISTER_PM1_ENABLE:
395
396 ACPI_REGISTER_INSERT_VALUE(register_value,
397 bit_reg_info->bit_position,
398 bit_reg_info->access_bit_mask,
399 value);
400
401 status = acpi_hw_register_write(ACPI_REGISTER_PM1_ENABLE,
402 (u16) register_value);
403 break;
404
405 case ACPI_REGISTER_PM1_CONTROL:
406
407 /*
408 * Write the PM1 Control register.
409 * Note that at this level, the fact that there are actually TWO
410 * registers (A and B - and B may not exist) is abstracted.
411 */
412 ACPI_DEBUG_PRINT((ACPI_DB_IO, "PM1 control: Read %X\n",
413 register_value));
414
415 ACPI_REGISTER_INSERT_VALUE(register_value,
416 bit_reg_info->bit_position,
417 bit_reg_info->access_bit_mask,
418 value);
419
420 status = acpi_hw_register_write(ACPI_REGISTER_PM1_CONTROL,
421 (u16) register_value);
422 break;
423
424 case ACPI_REGISTER_PM2_CONTROL:
425
426 status = acpi_hw_register_read(ACPI_REGISTER_PM2_CONTROL,
427 &register_value);
428 if (ACPI_FAILURE(status)) {
429 goto unlock_and_exit;
430 }
431
432 ACPI_DEBUG_PRINT((ACPI_DB_IO,
433 "PM2 control: Read %X from %8.8X%8.8X\n",
434 register_value,
435 ACPI_FORMAT_UINT64(acpi_gbl_FADT.
436 xpm2_control_block.
437 address)));
438
439 ACPI_REGISTER_INSERT_VALUE(register_value,
440 bit_reg_info->bit_position,
441 bit_reg_info->access_bit_mask,
442 value);
443
444 ACPI_DEBUG_PRINT((ACPI_DB_IO,
445 "About to write %4.4X to %8.8X%8.8X\n",
446 register_value,
447 ACPI_FORMAT_UINT64(acpi_gbl_FADT.
448 xpm2_control_block.
449 address)));
450
451 status = acpi_hw_register_write(ACPI_REGISTER_PM2_CONTROL,
452 (u8) (register_value));
453 break;
454
455 default:
456 break;
457 }
458
459 unlock_and_exit:
460
461 acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags);
462
463 /* Normalize the value that was read */
464
465 ACPI_DEBUG_EXEC(register_value =
466 ((register_value & bit_reg_info->access_bit_mask) >>
467 bit_reg_info->bit_position));
468
469 ACPI_DEBUG_PRINT((ACPI_DB_IO,
470 "Set bits: %8.8X actual %8.8X register %X\n", value,
471 register_value, bit_reg_info->parent_register));
472 return_ACPI_STATUS(status);
473}
474
475ACPI_EXPORT_SYMBOL(acpi_set_register)
476
477/*******************************************************************************
478 *
479 * FUNCTION: acpi_get_sleep_type_data
480 *
481 * PARAMETERS: sleep_state - Numeric sleep state
482 * *sleep_type_a - Where SLP_TYPa is returned
483 * *sleep_type_b - Where SLP_TYPb is returned
484 *
485 * RETURN: Status - ACPI status
486 *
487 * DESCRIPTION: Obtain the SLP_TYPa and SLP_TYPb values for the requested sleep
488 * state.
489 *
490 ******************************************************************************/
491acpi_status
492acpi_get_sleep_type_data(u8 sleep_state, u8 *sleep_type_a, u8 *sleep_type_b)
493{
494 acpi_status status = AE_OK;
495 struct acpi_evaluate_info *info;
496
497 ACPI_FUNCTION_TRACE(acpi_get_sleep_type_data);
498
499 /* Validate parameters */
500
501 if ((sleep_state > ACPI_S_STATES_MAX) || !sleep_type_a || !sleep_type_b) {
502 return_ACPI_STATUS(AE_BAD_PARAMETER);
503 }
504
505 /* Allocate the evaluation information block */
506
507 info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
508 if (!info) {
509 return_ACPI_STATUS(AE_NO_MEMORY);
510 }
511
512 info->pathname =
513 ACPI_CAST_PTR(char, acpi_gbl_sleep_state_names[sleep_state]);
514
515 /* Evaluate the namespace object containing the values for this state */
516
517 status = acpi_ns_evaluate(info);
518 if (ACPI_FAILURE(status)) {
519 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
520 "%s while evaluating SleepState [%s]\n",
521 acpi_format_exception(status),
522 info->pathname));
523
524 goto cleanup;
525 }
526
527 /* Must have a return object */
528
529 if (!info->return_object) {
530 ACPI_ERROR((AE_INFO, "No Sleep State object returned from [%s]",
531 info->pathname));
532 status = AE_NOT_EXIST;
533 }
534
535 /* It must be of type Package */
536
537 else if (ACPI_GET_OBJECT_TYPE(info->return_object) != ACPI_TYPE_PACKAGE) {
538 ACPI_ERROR((AE_INFO,
539 "Sleep State return object is not a Package"));
540 status = AE_AML_OPERAND_TYPE;
541 }
542
543 /*
544 * The package must have at least two elements. NOTE (March 2005): This
545 * goes against the current ACPI spec which defines this object as a
546 * package with one encoded DWORD element. However, existing practice
547 * by BIOS vendors seems to be to have 2 or more elements, at least
548 * one per sleep type (A/B).
549 */
550 else if (info->return_object->package.count < 2) {
551 ACPI_ERROR((AE_INFO,
552 "Sleep State return package does not have at least two elements"));
553 status = AE_AML_NO_OPERAND;
554 }
555
556 /* The first two elements must both be of type Integer */
557
558 else if ((ACPI_GET_OBJECT_TYPE(info->return_object->package.elements[0])
559 != ACPI_TYPE_INTEGER) ||
560 (ACPI_GET_OBJECT_TYPE(info->return_object->package.elements[1])
561 != ACPI_TYPE_INTEGER)) {
562 ACPI_ERROR((AE_INFO,
563 "Sleep State return package elements are not both Integers (%s, %s)",
564 acpi_ut_get_object_type_name(info->return_object->
565 package.elements[0]),
566 acpi_ut_get_object_type_name(info->return_object->
567 package.elements[1])));
568 status = AE_AML_OPERAND_TYPE;
569 } else {
570 /* Valid _Sx_ package size, type, and value */
571
572 *sleep_type_a = (u8)
573 (info->return_object->package.elements[0])->integer.value;
574 *sleep_type_b = (u8)
575 (info->return_object->package.elements[1])->integer.value;
576 }
577
578 if (ACPI_FAILURE(status)) {
579 ACPI_EXCEPTION((AE_INFO, status,
580 "While evaluating SleepState [%s], bad Sleep object %p type %s",
581 info->pathname, info->return_object,
582 acpi_ut_get_object_type_name(info->
583 return_object)));
584 }
585
586 acpi_ut_remove_reference(info->return_object);
587
588 cleanup:
589 ACPI_FREE(info);
590 return_ACPI_STATUS(status);
591}
592
593ACPI_EXPORT_SYMBOL(acpi_get_sleep_type_data)
diff --git a/drivers/acpi/acpica/nsaccess.c b/drivers/acpi/acpica/nsaccess.c
new file mode 100644
index 00000000000..7954640e69c
--- /dev/null
+++ b/drivers/acpi/acpica/nsaccess.c
@@ -0,0 +1,676 @@
1/*******************************************************************************
2 *
3 * Module Name: nsaccess - Top-level functions for accessing ACPI namespace
4 *
5 ******************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46#include <acpi/amlcode.h>
47#include <acpi/acnamesp.h>
48#include <acpi/acdispat.h>
49
50#define _COMPONENT ACPI_NAMESPACE
51ACPI_MODULE_NAME("nsaccess")
52
53/*******************************************************************************
54 *
55 * FUNCTION: acpi_ns_root_initialize
56 *
57 * PARAMETERS: None
58 *
59 * RETURN: Status
60 *
61 * DESCRIPTION: Allocate and initialize the default root named objects
62 *
63 * MUTEX: Locks namespace for entire execution
64 *
65 ******************************************************************************/
66acpi_status acpi_ns_root_initialize(void)
67{
68 acpi_status status;
69 const struct acpi_predefined_names *init_val = NULL;
70 struct acpi_namespace_node *new_node;
71 union acpi_operand_object *obj_desc;
72 acpi_string val = NULL;
73
74 ACPI_FUNCTION_TRACE(ns_root_initialize);
75
76 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
77 if (ACPI_FAILURE(status)) {
78 return_ACPI_STATUS(status);
79 }
80
81 /*
82 * The global root ptr is initially NULL, so a non-NULL value indicates
83 * that acpi_ns_root_initialize() has already been called; just return.
84 */
85 if (acpi_gbl_root_node) {
86 status = AE_OK;
87 goto unlock_and_exit;
88 }
89
90 /*
91 * Tell the rest of the subsystem that the root is initialized
92 * (This is OK because the namespace is locked)
93 */
94 acpi_gbl_root_node = &acpi_gbl_root_node_struct;
95
96 /* Enter the pre-defined names in the name table */
97
98 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
99 "Entering predefined entries into namespace\n"));
100
101 for (init_val = acpi_gbl_pre_defined_names; init_val->name; init_val++) {
102
103 /* _OSI is optional for now, will be permanent later */
104
105 if (!ACPI_STRCMP(init_val->name, "_OSI")
106 && !acpi_gbl_create_osi_method) {
107 continue;
108 }
109
110 status = acpi_ns_lookup(NULL, init_val->name, init_val->type,
111 ACPI_IMODE_LOAD_PASS2,
112 ACPI_NS_NO_UPSEARCH, NULL, &new_node);
113
114 if (ACPI_FAILURE(status) || (!new_node)) { /* Must be on same line for code converter */
115 ACPI_EXCEPTION((AE_INFO, status,
116 "Could not create predefined name %s",
117 init_val->name));
118 }
119
120 /*
121 * Name entered successfully.
122 * If entry in pre_defined_names[] specifies an
123 * initial value, create the initial value.
124 */
125 if (init_val->val) {
126 status = acpi_os_predefined_override(init_val, &val);
127 if (ACPI_FAILURE(status)) {
128 ACPI_ERROR((AE_INFO,
129 "Could not override predefined %s",
130 init_val->name));
131 }
132
133 if (!val) {
134 val = init_val->val;
135 }
136
137 /*
138 * Entry requests an initial value, allocate a
139 * descriptor for it.
140 */
141 obj_desc =
142 acpi_ut_create_internal_object(init_val->type);
143 if (!obj_desc) {
144 status = AE_NO_MEMORY;
145 goto unlock_and_exit;
146 }
147
148 /*
149 * Convert value string from table entry to
150 * internal representation. Only types actually
151 * used for initial values are implemented here.
152 */
153 switch (init_val->type) {
154 case ACPI_TYPE_METHOD:
155 obj_desc->method.param_count =
156 (u8) ACPI_TO_INTEGER(val);
157 obj_desc->common.flags |= AOPOBJ_DATA_VALID;
158
159#if defined (ACPI_ASL_COMPILER)
160
161 /* Save the parameter count for the i_aSL compiler */
162
163 new_node->value = obj_desc->method.param_count;
164#else
165 /* Mark this as a very SPECIAL method */
166
167 obj_desc->method.method_flags =
168 AML_METHOD_INTERNAL_ONLY;
169 obj_desc->method.implementation =
170 acpi_ut_osi_implementation;
171#endif
172 break;
173
174 case ACPI_TYPE_INTEGER:
175
176 obj_desc->integer.value = ACPI_TO_INTEGER(val);
177 break;
178
179 case ACPI_TYPE_STRING:
180
181 /*
182 * Build an object around the static string
183 */
184 obj_desc->string.length =
185 (u32) ACPI_STRLEN(val);
186 obj_desc->string.pointer = val;
187 obj_desc->common.flags |= AOPOBJ_STATIC_POINTER;
188 break;
189
190 case ACPI_TYPE_MUTEX:
191
192 obj_desc->mutex.node = new_node;
193 obj_desc->mutex.sync_level =
194 (u8) (ACPI_TO_INTEGER(val) - 1);
195
196 /* Create a mutex */
197
198 status =
199 acpi_os_create_mutex(&obj_desc->mutex.
200 os_mutex);
201 if (ACPI_FAILURE(status)) {
202 acpi_ut_remove_reference(obj_desc);
203 goto unlock_and_exit;
204 }
205
206 /* Special case for ACPI Global Lock */
207
208 if (ACPI_STRCMP(init_val->name, "_GL_") == 0) {
209 acpi_gbl_global_lock_mutex = obj_desc;
210
211 /* Create additional counting semaphore for global lock */
212
213 status =
214 acpi_os_create_semaphore(1, 0,
215 &acpi_gbl_global_lock_semaphore);
216 if (ACPI_FAILURE(status)) {
217 acpi_ut_remove_reference
218 (obj_desc);
219 goto unlock_and_exit;
220 }
221 }
222 break;
223
224 default:
225
226 ACPI_ERROR((AE_INFO,
227 "Unsupported initial type value %X",
228 init_val->type));
229 acpi_ut_remove_reference(obj_desc);
230 obj_desc = NULL;
231 continue;
232 }
233
234 /* Store pointer to value descriptor in the Node */
235
236 status = acpi_ns_attach_object(new_node, obj_desc,
237 ACPI_GET_OBJECT_TYPE
238 (obj_desc));
239
240 /* Remove local reference to the object */
241
242 acpi_ut_remove_reference(obj_desc);
243 }
244 }
245
246 unlock_and_exit:
247 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
248
249 /* Save a handle to "_GPE", it is always present */
250
251 if (ACPI_SUCCESS(status)) {
252 status = acpi_ns_get_node(NULL, "\\_GPE", ACPI_NS_NO_UPSEARCH,
253 &acpi_gbl_fadt_gpe_device);
254 }
255
256 return_ACPI_STATUS(status);
257}
258
259/*******************************************************************************
260 *
261 * FUNCTION: acpi_ns_lookup
262 *
263 * PARAMETERS: scope_info - Current scope info block
264 * Pathname - Search pathname, in internal format
265 * (as represented in the AML stream)
266 * Type - Type associated with name
267 * interpreter_mode - IMODE_LOAD_PASS2 => add name if not found
268 * Flags - Flags describing the search restrictions
269 * walk_state - Current state of the walk
270 * return_node - Where the Node is placed (if found
271 * or created successfully)
272 *
273 * RETURN: Status
274 *
275 * DESCRIPTION: Find or enter the passed name in the name space.
276 * Log an error if name not found in Exec mode.
277 *
278 * MUTEX: Assumes namespace is locked.
279 *
280 ******************************************************************************/
281
282acpi_status
283acpi_ns_lookup(union acpi_generic_state *scope_info,
284 char *pathname,
285 acpi_object_type type,
286 acpi_interpreter_mode interpreter_mode,
287 u32 flags,
288 struct acpi_walk_state *walk_state,
289 struct acpi_namespace_node **return_node)
290{
291 acpi_status status;
292 char *path = pathname;
293 struct acpi_namespace_node *prefix_node;
294 struct acpi_namespace_node *current_node = NULL;
295 struct acpi_namespace_node *this_node = NULL;
296 u32 num_segments;
297 u32 num_carats;
298 acpi_name simple_name;
299 acpi_object_type type_to_check_for;
300 acpi_object_type this_search_type;
301 u32 search_parent_flag = ACPI_NS_SEARCH_PARENT;
302 u32 local_flags;
303
304 ACPI_FUNCTION_TRACE(ns_lookup);
305
306 if (!return_node) {
307 return_ACPI_STATUS(AE_BAD_PARAMETER);
308 }
309
310 local_flags = flags & ~(ACPI_NS_ERROR_IF_FOUND | ACPI_NS_SEARCH_PARENT);
311 *return_node = ACPI_ENTRY_NOT_FOUND;
312 acpi_gbl_ns_lookup_count++;
313
314 if (!acpi_gbl_root_node) {
315 return_ACPI_STATUS(AE_NO_NAMESPACE);
316 }
317
318 /*
319 * Get the prefix scope.
320 * A null scope means use the root scope
321 */
322 if ((!scope_info) || (!scope_info->scope.node)) {
323 ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
324 "Null scope prefix, using root node (%p)\n",
325 acpi_gbl_root_node));
326
327 prefix_node = acpi_gbl_root_node;
328 } else {
329 prefix_node = scope_info->scope.node;
330 if (ACPI_GET_DESCRIPTOR_TYPE(prefix_node) !=
331 ACPI_DESC_TYPE_NAMED) {
332 ACPI_ERROR((AE_INFO, "%p is not a namespace node [%s]",
333 prefix_node,
334 acpi_ut_get_descriptor_name(prefix_node)));
335 return_ACPI_STATUS(AE_AML_INTERNAL);
336 }
337
338 if (!(flags & ACPI_NS_PREFIX_IS_SCOPE)) {
339 /*
340 * This node might not be a actual "scope" node (such as a
341 * Device/Method, etc.) It could be a Package or other object node.
342 * Backup up the tree to find the containing scope node.
343 */
344 while (!acpi_ns_opens_scope(prefix_node->type) &&
345 prefix_node->type != ACPI_TYPE_ANY) {
346 prefix_node =
347 acpi_ns_get_parent_node(prefix_node);
348 }
349 }
350 }
351
352 /* Save type TBD: may be no longer necessary */
353
354 type_to_check_for = type;
355
356 /*
357 * Begin examination of the actual pathname
358 */
359 if (!pathname) {
360
361 /* A Null name_path is allowed and refers to the root */
362
363 num_segments = 0;
364 this_node = acpi_gbl_root_node;
365 path = "";
366
367 ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
368 "Null Pathname (Zero segments), Flags=%X\n",
369 flags));
370 } else {
371 /*
372 * Name pointer is valid (and must be in internal name format)
373 *
374 * Check for scope prefixes:
375 *
376 * As represented in the AML stream, a namepath consists of an
377 * optional scope prefix followed by a name segment part.
378 *
379 * If present, the scope prefix is either a Root Prefix (in
380 * which case the name is fully qualified), or one or more
381 * Parent Prefixes (in which case the name's scope is relative
382 * to the current scope).
383 */
384 if (*path == (u8) AML_ROOT_PREFIX) {
385
386 /* Pathname is fully qualified, start from the root */
387
388 this_node = acpi_gbl_root_node;
389 search_parent_flag = ACPI_NS_NO_UPSEARCH;
390
391 /* Point to name segment part */
392
393 path++;
394
395 ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
396 "Path is absolute from root [%p]\n",
397 this_node));
398 } else {
399 /* Pathname is relative to current scope, start there */
400
401 ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
402 "Searching relative to prefix scope [%4.4s] (%p)\n",
403 acpi_ut_get_node_name(prefix_node),
404 prefix_node));
405
406 /*
407 * Handle multiple Parent Prefixes (carat) by just getting
408 * the parent node for each prefix instance.
409 */
410 this_node = prefix_node;
411 num_carats = 0;
412 while (*path == (u8) AML_PARENT_PREFIX) {
413
414 /* Name is fully qualified, no search rules apply */
415
416 search_parent_flag = ACPI_NS_NO_UPSEARCH;
417 /*
418 * Point past this prefix to the name segment
419 * part or the next Parent Prefix
420 */
421 path++;
422
423 /* Backup to the parent node */
424
425 num_carats++;
426 this_node = acpi_ns_get_parent_node(this_node);
427 if (!this_node) {
428
429 /* Current scope has no parent scope */
430
431 ACPI_ERROR((AE_INFO,
432 "ACPI path has too many parent prefixes (^) - reached beyond root node"));
433 return_ACPI_STATUS(AE_NOT_FOUND);
434 }
435 }
436
437 if (search_parent_flag == ACPI_NS_NO_UPSEARCH) {
438 ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
439 "Search scope is [%4.4s], path has %d carat(s)\n",
440 acpi_ut_get_node_name
441 (this_node), num_carats));
442 }
443 }
444
445 /*
446 * Determine the number of ACPI name segments in this pathname.
447 *
448 * The segment part consists of either:
449 * - A Null name segment (0)
450 * - A dual_name_prefix followed by two 4-byte name segments
451 * - A multi_name_prefix followed by a byte indicating the
452 * number of segments and the segments themselves.
453 * - A single 4-byte name segment
454 *
455 * Examine the name prefix opcode, if any, to determine the number of
456 * segments.
457 */
458 switch (*path) {
459 case 0:
460 /*
461 * Null name after a root or parent prefixes. We already
462 * have the correct target node and there are no name segments.
463 */
464 num_segments = 0;
465 type = this_node->type;
466
467 ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
468 "Prefix-only Pathname (Zero name segments), Flags=%X\n",
469 flags));
470 break;
471
472 case AML_DUAL_NAME_PREFIX:
473
474 /* More than one name_seg, search rules do not apply */
475
476 search_parent_flag = ACPI_NS_NO_UPSEARCH;
477
478 /* Two segments, point to first name segment */
479
480 num_segments = 2;
481 path++;
482
483 ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
484 "Dual Pathname (2 segments, Flags=%X)\n",
485 flags));
486 break;
487
488 case AML_MULTI_NAME_PREFIX_OP:
489
490 /* More than one name_seg, search rules do not apply */
491
492 search_parent_flag = ACPI_NS_NO_UPSEARCH;
493
494 /* Extract segment count, point to first name segment */
495
496 path++;
497 num_segments = (u32) (u8) * path;
498 path++;
499
500 ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
501 "Multi Pathname (%d Segments, Flags=%X)\n",
502 num_segments, flags));
503 break;
504
505 default:
506 /*
507 * Not a Null name, no Dual or Multi prefix, hence there is
508 * only one name segment and Pathname is already pointing to it.
509 */
510 num_segments = 1;
511
512 ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
513 "Simple Pathname (1 segment, Flags=%X)\n",
514 flags));
515 break;
516 }
517
518 ACPI_DEBUG_EXEC(acpi_ns_print_pathname(num_segments, path));
519 }
520
521 /*
522 * Search namespace for each segment of the name. Loop through and
523 * verify (or add to the namespace) each name segment.
524 *
525 * The object type is significant only at the last name
526 * segment. (We don't care about the types along the path, only
527 * the type of the final target object.)
528 */
529 this_search_type = ACPI_TYPE_ANY;
530 current_node = this_node;
531 while (num_segments && current_node) {
532 num_segments--;
533 if (!num_segments) {
534 /*
535 * This is the last segment, enable typechecking
536 */
537 this_search_type = type;
538
539 /*
540 * Only allow automatic parent search (search rules) if the caller
541 * requested it AND we have a single, non-fully-qualified name_seg
542 */
543 if ((search_parent_flag != ACPI_NS_NO_UPSEARCH) &&
544 (flags & ACPI_NS_SEARCH_PARENT)) {
545 local_flags |= ACPI_NS_SEARCH_PARENT;
546 }
547
548 /* Set error flag according to caller */
549
550 if (flags & ACPI_NS_ERROR_IF_FOUND) {
551 local_flags |= ACPI_NS_ERROR_IF_FOUND;
552 }
553 }
554
555 /* Extract one ACPI name from the front of the pathname */
556
557 ACPI_MOVE_32_TO_32(&simple_name, path);
558
559 /* Try to find the single (4 character) ACPI name */
560
561 status =
562 acpi_ns_search_and_enter(simple_name, walk_state,
563 current_node, interpreter_mode,
564 this_search_type, local_flags,
565 &this_node);
566 if (ACPI_FAILURE(status)) {
567 if (status == AE_NOT_FOUND) {
568
569 /* Name not found in ACPI namespace */
570
571 ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
572 "Name [%4.4s] not found in scope [%4.4s] %p\n",
573 (char *)&simple_name,
574 (char *)&current_node->name,
575 current_node));
576 }
577
578 *return_node = this_node;
579 return_ACPI_STATUS(status);
580 }
581
582 /* More segments to follow? */
583
584 if (num_segments > 0) {
585 /*
586 * If we have an alias to an object that opens a scope (such as a
587 * device or processor), we need to dereference the alias here so that
588 * we can access any children of the original node (via the remaining
589 * segments).
590 */
591 if (this_node->type == ACPI_TYPE_LOCAL_ALIAS) {
592 if (!this_node->object) {
593 return_ACPI_STATUS(AE_NOT_EXIST);
594 }
595
596 if (acpi_ns_opens_scope
597 (((struct acpi_namespace_node *)this_node->
598 object)->type)) {
599 this_node =
600 (struct acpi_namespace_node *)
601 this_node->object;
602 }
603 }
604 }
605
606 /* Special handling for the last segment (num_segments == 0) */
607
608 else {
609 /*
610 * Sanity typecheck of the target object:
611 *
612 * If 1) This is the last segment (num_segments == 0)
613 * 2) And we are looking for a specific type
614 * (Not checking for TYPE_ANY)
615 * 3) Which is not an alias
616 * 4) Which is not a local type (TYPE_SCOPE)
617 * 5) And the type of target object is known (not TYPE_ANY)
618 * 6) And target object does not match what we are looking for
619 *
620 * Then we have a type mismatch. Just warn and ignore it.
621 */
622 if ((type_to_check_for != ACPI_TYPE_ANY) &&
623 (type_to_check_for != ACPI_TYPE_LOCAL_ALIAS) &&
624 (type_to_check_for != ACPI_TYPE_LOCAL_METHOD_ALIAS)
625 && (type_to_check_for != ACPI_TYPE_LOCAL_SCOPE)
626 && (this_node->type != ACPI_TYPE_ANY)
627 && (this_node->type != type_to_check_for)) {
628
629 /* Complain about a type mismatch */
630
631 ACPI_WARNING((AE_INFO,
632 "NsLookup: Type mismatch on %4.4s (%s), searching for (%s)",
633 ACPI_CAST_PTR(char, &simple_name),
634 acpi_ut_get_type_name(this_node->
635 type),
636 acpi_ut_get_type_name
637 (type_to_check_for)));
638 }
639
640 /*
641 * If this is the last name segment and we are not looking for a
642 * specific type, but the type of found object is known, use that type
643 * to (later) see if it opens a scope.
644 */
645 if (type == ACPI_TYPE_ANY) {
646 type = this_node->type;
647 }
648 }
649
650 /* Point to next name segment and make this node current */
651
652 path += ACPI_NAME_SIZE;
653 current_node = this_node;
654 }
655
656 /*
657 * Always check if we need to open a new scope
658 */
659 if (!(flags & ACPI_NS_DONT_OPEN_SCOPE) && (walk_state)) {
660 /*
661 * If entry is a type which opens a scope, push the new scope on the
662 * scope stack.
663 */
664 if (acpi_ns_opens_scope(type)) {
665 status =
666 acpi_ds_scope_stack_push(this_node, type,
667 walk_state);
668 if (ACPI_FAILURE(status)) {
669 return_ACPI_STATUS(status);
670 }
671 }
672 }
673
674 *return_node = this_node;
675 return_ACPI_STATUS(AE_OK);
676}
diff --git a/drivers/acpi/acpica/nsalloc.c b/drivers/acpi/acpica/nsalloc.c
new file mode 100644
index 00000000000..cb2afbf4e45
--- /dev/null
+++ b/drivers/acpi/acpica/nsalloc.c
@@ -0,0 +1,497 @@
1/*******************************************************************************
2 *
3 * Module Name: nsalloc - Namespace allocation and deletion utilities
4 *
5 ******************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46#include <acpi/acnamesp.h>
47
48#define _COMPONENT ACPI_NAMESPACE
49ACPI_MODULE_NAME("nsalloc")
50
51/*******************************************************************************
52 *
53 * FUNCTION: acpi_ns_create_node
54 *
55 * PARAMETERS: Name - Name of the new node (4 char ACPI name)
56 *
57 * RETURN: New namespace node (Null on failure)
58 *
59 * DESCRIPTION: Create a namespace node
60 *
61 ******************************************************************************/
62struct acpi_namespace_node *acpi_ns_create_node(u32 name)
63{
64 struct acpi_namespace_node *node;
65#ifdef ACPI_DBG_TRACK_ALLOCATIONS
66 u32 temp;
67#endif
68
69 ACPI_FUNCTION_TRACE(ns_create_node);
70
71 node = acpi_os_acquire_object(acpi_gbl_namespace_cache);
72 if (!node) {
73 return_PTR(NULL);
74 }
75
76 ACPI_MEM_TRACKING(acpi_gbl_ns_node_list->total_allocated++);
77
78#ifdef ACPI_DBG_TRACK_ALLOCATIONS
79 temp =
80 acpi_gbl_ns_node_list->total_allocated -
81 acpi_gbl_ns_node_list->total_freed;
82 if (temp > acpi_gbl_ns_node_list->max_occupied) {
83 acpi_gbl_ns_node_list->max_occupied = temp;
84 }
85#endif
86
87 node->name.integer = name;
88 ACPI_SET_DESCRIPTOR_TYPE(node, ACPI_DESC_TYPE_NAMED);
89 return_PTR(node);
90}
91
92/*******************************************************************************
93 *
94 * FUNCTION: acpi_ns_delete_node
95 *
96 * PARAMETERS: Node - Node to be deleted
97 *
98 * RETURN: None
99 *
100 * DESCRIPTION: Delete a namespace node
101 *
102 ******************************************************************************/
103
104void acpi_ns_delete_node(struct acpi_namespace_node *node)
105{
106 struct acpi_namespace_node *parent_node;
107 struct acpi_namespace_node *prev_node;
108 struct acpi_namespace_node *next_node;
109
110 ACPI_FUNCTION_TRACE_PTR(ns_delete_node, node);
111
112 parent_node = acpi_ns_get_parent_node(node);
113
114 prev_node = NULL;
115 next_node = parent_node->child;
116
117 /* Find the node that is the previous peer in the parent's child list */
118
119 while (next_node != node) {
120 prev_node = next_node;
121 next_node = prev_node->peer;
122 }
123
124 if (prev_node) {
125
126 /* Node is not first child, unlink it */
127
128 prev_node->peer = next_node->peer;
129 if (next_node->flags & ANOBJ_END_OF_PEER_LIST) {
130 prev_node->flags |= ANOBJ_END_OF_PEER_LIST;
131 }
132 } else {
133 /* Node is first child (has no previous peer) */
134
135 if (next_node->flags & ANOBJ_END_OF_PEER_LIST) {
136
137 /* No peers at all */
138
139 parent_node->child = NULL;
140 } else { /* Link peer list to parent */
141
142 parent_node->child = next_node->peer;
143 }
144 }
145
146 ACPI_MEM_TRACKING(acpi_gbl_ns_node_list->total_freed++);
147
148 /*
149 * Detach an object if there is one, then delete the node
150 */
151 acpi_ns_detach_object(node);
152 (void)acpi_os_release_object(acpi_gbl_namespace_cache, node);
153 return_VOID;
154}
155
156/*******************************************************************************
157 *
158 * FUNCTION: acpi_ns_install_node
159 *
160 * PARAMETERS: walk_state - Current state of the walk
161 * parent_node - The parent of the new Node
162 * Node - The new Node to install
163 * Type - ACPI object type of the new Node
164 *
165 * RETURN: None
166 *
167 * DESCRIPTION: Initialize a new namespace node and install it amongst
168 * its peers.
169 *
170 * Note: Current namespace lookup is linear search. This appears
171 * to be sufficient as namespace searches consume only a small
172 * fraction of the execution time of the ACPI subsystem.
173 *
174 ******************************************************************************/
175
176void acpi_ns_install_node(struct acpi_walk_state *walk_state, struct acpi_namespace_node *parent_node, /* Parent */
177 struct acpi_namespace_node *node, /* New Child */
178 acpi_object_type type)
179{
180 acpi_owner_id owner_id = 0;
181 struct acpi_namespace_node *child_node;
182
183 ACPI_FUNCTION_TRACE(ns_install_node);
184
185 /*
186 * Get the owner ID from the Walk state
187 * The owner ID is used to track table deletion and
188 * deletion of objects created by methods
189 */
190 if (walk_state) {
191 owner_id = walk_state->owner_id;
192 }
193
194 /* Link the new entry into the parent and existing children */
195
196 child_node = parent_node->child;
197 if (!child_node) {
198 parent_node->child = node;
199 node->flags |= ANOBJ_END_OF_PEER_LIST;
200 node->peer = parent_node;
201 } else {
202 while (!(child_node->flags & ANOBJ_END_OF_PEER_LIST)) {
203 child_node = child_node->peer;
204 }
205
206 child_node->peer = node;
207
208 /* Clear end-of-list flag */
209
210 child_node->flags &= ~ANOBJ_END_OF_PEER_LIST;
211 node->flags |= ANOBJ_END_OF_PEER_LIST;
212 node->peer = parent_node;
213 }
214
215 /* Init the new entry */
216
217 node->owner_id = owner_id;
218 node->type = (u8) type;
219
220 ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
221 "%4.4s (%s) [Node %p Owner %X] added to %4.4s (%s) [Node %p]\n",
222 acpi_ut_get_node_name(node),
223 acpi_ut_get_type_name(node->type), node, owner_id,
224 acpi_ut_get_node_name(parent_node),
225 acpi_ut_get_type_name(parent_node->type),
226 parent_node));
227
228 return_VOID;
229}
230
231/*******************************************************************************
232 *
233 * FUNCTION: acpi_ns_delete_children
234 *
235 * PARAMETERS: parent_node - Delete this objects children
236 *
237 * RETURN: None.
238 *
239 * DESCRIPTION: Delete all children of the parent object. In other words,
240 * deletes a "scope".
241 *
242 ******************************************************************************/
243
244void acpi_ns_delete_children(struct acpi_namespace_node *parent_node)
245{
246 struct acpi_namespace_node *child_node;
247 struct acpi_namespace_node *next_node;
248 u8 flags;
249
250 ACPI_FUNCTION_TRACE_PTR(ns_delete_children, parent_node);
251
252 if (!parent_node) {
253 return_VOID;
254 }
255
256 /* If no children, all done! */
257
258 child_node = parent_node->child;
259 if (!child_node) {
260 return_VOID;
261 }
262
263 /*
264 * Deallocate all children at this level
265 */
266 do {
267
268 /* Get the things we need */
269
270 next_node = child_node->peer;
271 flags = child_node->flags;
272
273 /* Grandchildren should have all been deleted already */
274
275 if (child_node->child) {
276 ACPI_ERROR((AE_INFO, "Found a grandchild! P=%p C=%p",
277 parent_node, child_node));
278 }
279
280 /* Now we can free this child object */
281
282 ACPI_MEM_TRACKING(acpi_gbl_ns_node_list->total_freed++);
283
284 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
285 "Object %p, Remaining %X\n", child_node,
286 acpi_gbl_current_node_count));
287
288 /*
289 * Detach an object if there is one, then free the child node
290 */
291 acpi_ns_detach_object(child_node);
292
293 /* Now we can delete the node */
294
295 (void)acpi_os_release_object(acpi_gbl_namespace_cache,
296 child_node);
297
298 /* And move on to the next child in the list */
299
300 child_node = next_node;
301
302 } while (!(flags & ANOBJ_END_OF_PEER_LIST));
303
304 /* Clear the parent's child pointer */
305
306 parent_node->child = NULL;
307
308 return_VOID;
309}
310
311/*******************************************************************************
312 *
313 * FUNCTION: acpi_ns_delete_namespace_subtree
314 *
315 * PARAMETERS: parent_node - Root of the subtree to be deleted
316 *
317 * RETURN: None.
318 *
319 * DESCRIPTION: Delete a subtree of the namespace. This includes all objects
320 * stored within the subtree.
321 *
322 ******************************************************************************/
323
324void acpi_ns_delete_namespace_subtree(struct acpi_namespace_node *parent_node)
325{
326 struct acpi_namespace_node *child_node = NULL;
327 u32 level = 1;
328
329 ACPI_FUNCTION_TRACE(ns_delete_namespace_subtree);
330
331 if (!parent_node) {
332 return_VOID;
333 }
334
335 /*
336 * Traverse the tree of objects until we bubble back up
337 * to where we started.
338 */
339 while (level > 0) {
340
341 /* Get the next node in this scope (NULL if none) */
342
343 child_node =
344 acpi_ns_get_next_node(ACPI_TYPE_ANY, parent_node,
345 child_node);
346 if (child_node) {
347
348 /* Found a child node - detach any attached object */
349
350 acpi_ns_detach_object(child_node);
351
352 /* Check if this node has any children */
353
354 if (acpi_ns_get_next_node
355 (ACPI_TYPE_ANY, child_node, NULL)) {
356 /*
357 * There is at least one child of this node,
358 * visit the node
359 */
360 level++;
361 parent_node = child_node;
362 child_node = NULL;
363 }
364 } else {
365 /*
366 * No more children of this parent node.
367 * Move up to the grandparent.
368 */
369 level--;
370
371 /*
372 * Now delete all of the children of this parent
373 * all at the same time.
374 */
375 acpi_ns_delete_children(parent_node);
376
377 /* New "last child" is this parent node */
378
379 child_node = parent_node;
380
381 /* Move up the tree to the grandparent */
382
383 parent_node = acpi_ns_get_parent_node(parent_node);
384 }
385 }
386
387 return_VOID;
388}
389
390/*******************************************************************************
391 *
392 * FUNCTION: acpi_ns_delete_namespace_by_owner
393 *
394 * PARAMETERS: owner_id - All nodes with this owner will be deleted
395 *
396 * RETURN: Status
397 *
398 * DESCRIPTION: Delete entries within the namespace that are owned by a
399 * specific ID. Used to delete entire ACPI tables. All
400 * reference counts are updated.
401 *
402 * MUTEX: Locks namespace during deletion walk.
403 *
404 ******************************************************************************/
405
406void acpi_ns_delete_namespace_by_owner(acpi_owner_id owner_id)
407{
408 struct acpi_namespace_node *child_node;
409 struct acpi_namespace_node *deletion_node;
410 struct acpi_namespace_node *parent_node;
411 u32 level;
412 acpi_status status;
413
414 ACPI_FUNCTION_TRACE_U32(ns_delete_namespace_by_owner, owner_id);
415
416 if (owner_id == 0) {
417 return_VOID;
418 }
419
420 /* Lock namespace for possible update */
421
422 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
423 if (ACPI_FAILURE(status)) {
424 return_VOID;
425 }
426
427 deletion_node = NULL;
428 parent_node = acpi_gbl_root_node;
429 child_node = NULL;
430 level = 1;
431
432 /*
433 * Traverse the tree of nodes until we bubble back up
434 * to where we started.
435 */
436 while (level > 0) {
437 /*
438 * Get the next child of this parent node. When child_node is NULL,
439 * the first child of the parent is returned
440 */
441 child_node =
442 acpi_ns_get_next_node(ACPI_TYPE_ANY, parent_node,
443 child_node);
444
445 if (deletion_node) {
446 acpi_ns_delete_children(deletion_node);
447 acpi_ns_delete_node(deletion_node);
448 deletion_node = NULL;
449 }
450
451 if (child_node) {
452 if (child_node->owner_id == owner_id) {
453
454 /* Found a matching child node - detach any attached object */
455
456 acpi_ns_detach_object(child_node);
457 }
458
459 /* Check if this node has any children */
460
461 if (acpi_ns_get_next_node
462 (ACPI_TYPE_ANY, child_node, NULL)) {
463 /*
464 * There is at least one child of this node,
465 * visit the node
466 */
467 level++;
468 parent_node = child_node;
469 child_node = NULL;
470 } else if (child_node->owner_id == owner_id) {
471 deletion_node = child_node;
472 }
473 } else {
474 /*
475 * No more children of this parent node.
476 * Move up to the grandparent.
477 */
478 level--;
479 if (level != 0) {
480 if (parent_node->owner_id == owner_id) {
481 deletion_node = parent_node;
482 }
483 }
484
485 /* New "last child" is this parent node */
486
487 child_node = parent_node;
488
489 /* Move up the tree to the grandparent */
490
491 parent_node = acpi_ns_get_parent_node(parent_node);
492 }
493 }
494
495 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
496 return_VOID;
497}
diff --git a/drivers/acpi/acpica/nsdump.c b/drivers/acpi/acpica/nsdump.c
new file mode 100644
index 00000000000..48f02e659f2
--- /dev/null
+++ b/drivers/acpi/acpica/nsdump.c
@@ -0,0 +1,709 @@
1/******************************************************************************
2 *
3 * Module Name: nsdump - table dumping routines for debug
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46#include <acpi/acnamesp.h>
47
48#define _COMPONENT ACPI_NAMESPACE
49ACPI_MODULE_NAME("nsdump")
50
51/* Local prototypes */
52#ifdef ACPI_OBSOLETE_FUNCTIONS
53void acpi_ns_dump_root_devices(void);
54
55static acpi_status
56acpi_ns_dump_one_device(acpi_handle obj_handle,
57 u32 level, void *context, void **return_value);
58#endif
59
60#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
61/*******************************************************************************
62 *
63 * FUNCTION: acpi_ns_print_pathname
64 *
65 * PARAMETERS: num_segments - Number of ACPI name segments
66 * Pathname - The compressed (internal) path
67 *
68 * RETURN: None
69 *
70 * DESCRIPTION: Print an object's full namespace pathname
71 *
72 ******************************************************************************/
73
74void acpi_ns_print_pathname(u32 num_segments, char *pathname)
75{
76 u32 i;
77
78 ACPI_FUNCTION_NAME(ns_print_pathname);
79
80 if (!(acpi_dbg_level & ACPI_LV_NAMES)
81 || !(acpi_dbg_layer & ACPI_NAMESPACE)) {
82 return;
83 }
84
85 /* Print the entire name */
86
87 ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "["));
88
89 while (num_segments) {
90 for (i = 0; i < 4; i++) {
91 ACPI_IS_PRINT(pathname[i]) ?
92 acpi_os_printf("%c", pathname[i]) :
93 acpi_os_printf("?");
94 }
95
96 pathname += ACPI_NAME_SIZE;
97 num_segments--;
98 if (num_segments) {
99 acpi_os_printf(".");
100 }
101 }
102
103 acpi_os_printf("]\n");
104}
105
106/*******************************************************************************
107 *
108 * FUNCTION: acpi_ns_dump_pathname
109 *
110 * PARAMETERS: Handle - Object
111 * Msg - Prefix message
112 * Level - Desired debug level
113 * Component - Caller's component ID
114 *
115 * RETURN: None
116 *
117 * DESCRIPTION: Print an object's full namespace pathname
118 * Manages allocation/freeing of a pathname buffer
119 *
120 ******************************************************************************/
121
122void
123acpi_ns_dump_pathname(acpi_handle handle, char *msg, u32 level, u32 component)
124{
125
126 ACPI_FUNCTION_TRACE(ns_dump_pathname);
127
128 /* Do this only if the requested debug level and component are enabled */
129
130 if (!(acpi_dbg_level & level) || !(acpi_dbg_layer & component)) {
131 return_VOID;
132 }
133
134 /* Convert handle to a full pathname and print it (with supplied message) */
135
136 acpi_ns_print_node_pathname(handle, msg);
137 acpi_os_printf("\n");
138 return_VOID;
139}
140
141/*******************************************************************************
142 *
143 * FUNCTION: acpi_ns_dump_one_object
144 *
145 * PARAMETERS: obj_handle - Node to be dumped
146 * Level - Nesting level of the handle
147 * Context - Passed into walk_namespace
148 * return_value - Not used
149 *
150 * RETURN: Status
151 *
152 * DESCRIPTION: Dump a single Node
153 * This procedure is a user_function called by acpi_ns_walk_namespace.
154 *
155 ******************************************************************************/
156
157acpi_status
158acpi_ns_dump_one_object(acpi_handle obj_handle,
159 u32 level, void *context, void **return_value)
160{
161 struct acpi_walk_info *info = (struct acpi_walk_info *)context;
162 struct acpi_namespace_node *this_node;
163 union acpi_operand_object *obj_desc = NULL;
164 acpi_object_type obj_type;
165 acpi_object_type type;
166 u32 bytes_to_dump;
167 u32 dbg_level;
168 u32 i;
169
170 ACPI_FUNCTION_NAME(ns_dump_one_object);
171
172 /* Is output enabled? */
173
174 if (!(acpi_dbg_level & info->debug_level)) {
175 return (AE_OK);
176 }
177
178 if (!obj_handle) {
179 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Null object handle\n"));
180 return (AE_OK);
181 }
182
183 this_node = acpi_ns_map_handle_to_node(obj_handle);
184 type = this_node->type;
185
186 /* Check if the owner matches */
187
188 if ((info->owner_id != ACPI_OWNER_ID_MAX) &&
189 (info->owner_id != this_node->owner_id)) {
190 return (AE_OK);
191 }
192
193 if (!(info->display_type & ACPI_DISPLAY_SHORT)) {
194
195 /* Indent the object according to the level */
196
197 acpi_os_printf("%2d%*s", (u32) level - 1, (int)level * 2, " ");
198
199 /* Check the node type and name */
200
201 if (type > ACPI_TYPE_LOCAL_MAX) {
202 ACPI_WARNING((AE_INFO, "Invalid ACPI Object Type %08X",
203 type));
204 }
205
206 if (!acpi_ut_valid_acpi_name(this_node->name.integer)) {
207 this_node->name.integer =
208 acpi_ut_repair_name(this_node->name.ascii);
209
210 ACPI_WARNING((AE_INFO, "Invalid ACPI Name %08X",
211 this_node->name.integer));
212 }
213
214 acpi_os_printf("%4.4s", acpi_ut_get_node_name(this_node));
215 }
216
217 /*
218 * Now we can print out the pertinent information
219 */
220 acpi_os_printf(" %-12s %p %2.2X ",
221 acpi_ut_get_type_name(type), this_node,
222 this_node->owner_id);
223
224 dbg_level = acpi_dbg_level;
225 acpi_dbg_level = 0;
226 obj_desc = acpi_ns_get_attached_object(this_node);
227 acpi_dbg_level = dbg_level;
228
229 /* Temp nodes are those nodes created by a control method */
230
231 if (this_node->flags & ANOBJ_TEMPORARY) {
232 acpi_os_printf("(T) ");
233 }
234
235 switch (info->display_type & ACPI_DISPLAY_MASK) {
236 case ACPI_DISPLAY_SUMMARY:
237
238 if (!obj_desc) {
239
240 /* No attached object, we are done */
241
242 acpi_os_printf("\n");
243 return (AE_OK);
244 }
245
246 switch (type) {
247 case ACPI_TYPE_PROCESSOR:
248
249 acpi_os_printf("ID %X Len %.4X Addr %p\n",
250 obj_desc->processor.proc_id,
251 obj_desc->processor.length,
252 ACPI_CAST_PTR(void,
253 obj_desc->processor.
254 address));
255 break;
256
257 case ACPI_TYPE_DEVICE:
258
259 acpi_os_printf("Notify Object: %p\n", obj_desc);
260 break;
261
262 case ACPI_TYPE_METHOD:
263
264 acpi_os_printf("Args %X Len %.4X Aml %p\n",
265 (u32) obj_desc->method.param_count,
266 obj_desc->method.aml_length,
267 obj_desc->method.aml_start);
268 break;
269
270 case ACPI_TYPE_INTEGER:
271
272 acpi_os_printf("= %8.8X%8.8X\n",
273 ACPI_FORMAT_UINT64(obj_desc->integer.
274 value));
275 break;
276
277 case ACPI_TYPE_PACKAGE:
278
279 if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
280 acpi_os_printf("Elements %.2X\n",
281 obj_desc->package.count);
282 } else {
283 acpi_os_printf("[Length not yet evaluated]\n");
284 }
285 break;
286
287 case ACPI_TYPE_BUFFER:
288
289 if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
290 acpi_os_printf("Len %.2X",
291 obj_desc->buffer.length);
292
293 /* Dump some of the buffer */
294
295 if (obj_desc->buffer.length > 0) {
296 acpi_os_printf(" =");
297 for (i = 0;
298 (i < obj_desc->buffer.length
299 && i < 12); i++) {
300 acpi_os_printf(" %.2hX",
301 obj_desc->buffer.
302 pointer[i]);
303 }
304 }
305 acpi_os_printf("\n");
306 } else {
307 acpi_os_printf("[Length not yet evaluated]\n");
308 }
309 break;
310
311 case ACPI_TYPE_STRING:
312
313 acpi_os_printf("Len %.2X ", obj_desc->string.length);
314 acpi_ut_print_string(obj_desc->string.pointer, 32);
315 acpi_os_printf("\n");
316 break;
317
318 case ACPI_TYPE_REGION:
319
320 acpi_os_printf("[%s]",
321 acpi_ut_get_region_name(obj_desc->region.
322 space_id));
323 if (obj_desc->region.flags & AOPOBJ_DATA_VALID) {
324 acpi_os_printf(" Addr %8.8X%8.8X Len %.4X\n",
325 ACPI_FORMAT_NATIVE_UINT
326 (obj_desc->region.address),
327 obj_desc->region.length);
328 } else {
329 acpi_os_printf
330 (" [Address/Length not yet evaluated]\n");
331 }
332 break;
333
334 case ACPI_TYPE_LOCAL_REFERENCE:
335
336 acpi_os_printf("[%s]\n",
337 acpi_ut_get_reference_name(obj_desc));
338 break;
339
340 case ACPI_TYPE_BUFFER_FIELD:
341
342 if (obj_desc->buffer_field.buffer_obj &&
343 obj_desc->buffer_field.buffer_obj->buffer.node) {
344 acpi_os_printf("Buf [%4.4s]",
345 acpi_ut_get_node_name(obj_desc->
346 buffer_field.
347 buffer_obj->
348 buffer.
349 node));
350 }
351 break;
352
353 case ACPI_TYPE_LOCAL_REGION_FIELD:
354
355 acpi_os_printf("Rgn [%4.4s]",
356 acpi_ut_get_node_name(obj_desc->
357 common_field.
358 region_obj->region.
359 node));
360 break;
361
362 case ACPI_TYPE_LOCAL_BANK_FIELD:
363
364 acpi_os_printf("Rgn [%4.4s] Bnk [%4.4s]",
365 acpi_ut_get_node_name(obj_desc->
366 common_field.
367 region_obj->region.
368 node),
369 acpi_ut_get_node_name(obj_desc->
370 bank_field.
371 bank_obj->
372 common_field.
373 node));
374 break;
375
376 case ACPI_TYPE_LOCAL_INDEX_FIELD:
377
378 acpi_os_printf("Idx [%4.4s] Dat [%4.4s]",
379 acpi_ut_get_node_name(obj_desc->
380 index_field.
381 index_obj->
382 common_field.node),
383 acpi_ut_get_node_name(obj_desc->
384 index_field.
385 data_obj->
386 common_field.
387 node));
388 break;
389
390 case ACPI_TYPE_LOCAL_ALIAS:
391 case ACPI_TYPE_LOCAL_METHOD_ALIAS:
392
393 acpi_os_printf("Target %4.4s (%p)\n",
394 acpi_ut_get_node_name(obj_desc),
395 obj_desc);
396 break;
397
398 default:
399
400 acpi_os_printf("Object %p\n", obj_desc);
401 break;
402 }
403
404 /* Common field handling */
405
406 switch (type) {
407 case ACPI_TYPE_BUFFER_FIELD:
408 case ACPI_TYPE_LOCAL_REGION_FIELD:
409 case ACPI_TYPE_LOCAL_BANK_FIELD:
410 case ACPI_TYPE_LOCAL_INDEX_FIELD:
411
412 acpi_os_printf(" Off %.3X Len %.2X Acc %.2hd\n",
413 (obj_desc->common_field.
414 base_byte_offset * 8)
415 +
416 obj_desc->common_field.
417 start_field_bit_offset,
418 obj_desc->common_field.bit_length,
419 obj_desc->common_field.
420 access_byte_width);
421 break;
422
423 default:
424 break;
425 }
426 break;
427
428 case ACPI_DISPLAY_OBJECTS:
429
430 acpi_os_printf("O:%p", obj_desc);
431 if (!obj_desc) {
432
433 /* No attached object, we are done */
434
435 acpi_os_printf("\n");
436 return (AE_OK);
437 }
438
439 acpi_os_printf("(R%d)", obj_desc->common.reference_count);
440
441 switch (type) {
442 case ACPI_TYPE_METHOD:
443
444 /* Name is a Method and its AML offset/length are set */
445
446 acpi_os_printf(" M:%p-%X\n", obj_desc->method.aml_start,
447 obj_desc->method.aml_length);
448 break;
449
450 case ACPI_TYPE_INTEGER:
451
452 acpi_os_printf(" I:%8.8X8.8%X\n",
453 ACPI_FORMAT_UINT64(obj_desc->integer.
454 value));
455 break;
456
457 case ACPI_TYPE_STRING:
458
459 acpi_os_printf(" S:%p-%X\n", obj_desc->string.pointer,
460 obj_desc->string.length);
461 break;
462
463 case ACPI_TYPE_BUFFER:
464
465 acpi_os_printf(" B:%p-%X\n", obj_desc->buffer.pointer,
466 obj_desc->buffer.length);
467 break;
468
469 default:
470
471 acpi_os_printf("\n");
472 break;
473 }
474 break;
475
476 default:
477 acpi_os_printf("\n");
478 break;
479 }
480
481 /* If debug turned off, done */
482
483 if (!(acpi_dbg_level & ACPI_LV_VALUES)) {
484 return (AE_OK);
485 }
486
487 /* If there is an attached object, display it */
488
489 dbg_level = acpi_dbg_level;
490 acpi_dbg_level = 0;
491 obj_desc = acpi_ns_get_attached_object(this_node);
492 acpi_dbg_level = dbg_level;
493
494 /* Dump attached objects */
495
496 while (obj_desc) {
497 obj_type = ACPI_TYPE_INVALID;
498 acpi_os_printf("Attached Object %p: ", obj_desc);
499
500 /* Decode the type of attached object and dump the contents */
501
502 switch (ACPI_GET_DESCRIPTOR_TYPE(obj_desc)) {
503 case ACPI_DESC_TYPE_NAMED:
504
505 acpi_os_printf("(Ptr to Node)\n");
506 bytes_to_dump = sizeof(struct acpi_namespace_node);
507 ACPI_DUMP_BUFFER(obj_desc, bytes_to_dump);
508 break;
509
510 case ACPI_DESC_TYPE_OPERAND:
511
512 obj_type = ACPI_GET_OBJECT_TYPE(obj_desc);
513
514 if (obj_type > ACPI_TYPE_LOCAL_MAX) {
515 acpi_os_printf
516 ("(Pointer to ACPI Object type %.2X [UNKNOWN])\n",
517 obj_type);
518 bytes_to_dump = 32;
519 } else {
520 acpi_os_printf
521 ("(Pointer to ACPI Object type %.2X [%s])\n",
522 obj_type, acpi_ut_get_type_name(obj_type));
523 bytes_to_dump =
524 sizeof(union acpi_operand_object);
525 }
526
527 ACPI_DUMP_BUFFER(obj_desc, bytes_to_dump);
528 break;
529
530 default:
531
532 break;
533 }
534
535 /* If value is NOT an internal object, we are done */
536
537 if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) !=
538 ACPI_DESC_TYPE_OPERAND) {
539 goto cleanup;
540 }
541
542 /*
543 * Valid object, get the pointer to next level, if any
544 */
545 switch (obj_type) {
546 case ACPI_TYPE_BUFFER:
547 case ACPI_TYPE_STRING:
548 /*
549 * NOTE: takes advantage of common fields between string/buffer
550 */
551 bytes_to_dump = obj_desc->string.length;
552 obj_desc = (void *)obj_desc->string.pointer;
553 acpi_os_printf("(Buffer/String pointer %p length %X)\n",
554 obj_desc, bytes_to_dump);
555 ACPI_DUMP_BUFFER(obj_desc, bytes_to_dump);
556 goto cleanup;
557
558 case ACPI_TYPE_BUFFER_FIELD:
559 obj_desc =
560 (union acpi_operand_object *)obj_desc->buffer_field.
561 buffer_obj;
562 break;
563
564 case ACPI_TYPE_PACKAGE:
565 obj_desc = (void *)obj_desc->package.elements;
566 break;
567
568 case ACPI_TYPE_METHOD:
569 obj_desc = (void *)obj_desc->method.aml_start;
570 break;
571
572 case ACPI_TYPE_LOCAL_REGION_FIELD:
573 obj_desc = (void *)obj_desc->field.region_obj;
574 break;
575
576 case ACPI_TYPE_LOCAL_BANK_FIELD:
577 obj_desc = (void *)obj_desc->bank_field.region_obj;
578 break;
579
580 case ACPI_TYPE_LOCAL_INDEX_FIELD:
581 obj_desc = (void *)obj_desc->index_field.index_obj;
582 break;
583
584 default:
585 goto cleanup;
586 }
587
588 obj_type = ACPI_TYPE_INVALID; /* Terminate loop after next pass */
589 }
590
591 cleanup:
592 acpi_os_printf("\n");
593 return (AE_OK);
594}
595
596#ifdef ACPI_FUTURE_USAGE
597/*******************************************************************************
598 *
599 * FUNCTION: acpi_ns_dump_objects
600 *
601 * PARAMETERS: Type - Object type to be dumped
602 * display_type - 0 or ACPI_DISPLAY_SUMMARY
603 * max_depth - Maximum depth of dump. Use ACPI_UINT32_MAX
604 * for an effectively unlimited depth.
605 * owner_id - Dump only objects owned by this ID. Use
606 * ACPI_UINT32_MAX to match all owners.
607 * start_handle - Where in namespace to start/end search
608 *
609 * RETURN: None
610 *
611 * DESCRIPTION: Dump typed objects within the loaded namespace.
612 * Uses acpi_ns_walk_namespace in conjunction with acpi_ns_dump_one_object.
613 *
614 ******************************************************************************/
615
616void
617acpi_ns_dump_objects(acpi_object_type type,
618 u8 display_type,
619 u32 max_depth,
620 acpi_owner_id owner_id, acpi_handle start_handle)
621{
622 struct acpi_walk_info info;
623
624 ACPI_FUNCTION_ENTRY();
625
626 info.debug_level = ACPI_LV_TABLES;
627 info.owner_id = owner_id;
628 info.display_type = display_type;
629
630 (void)acpi_ns_walk_namespace(type, start_handle, max_depth,
631 ACPI_NS_WALK_NO_UNLOCK |
632 ACPI_NS_WALK_TEMP_NODES,
633 acpi_ns_dump_one_object, (void *)&info,
634 NULL);
635}
636#endif /* ACPI_FUTURE_USAGE */
637
638/*******************************************************************************
639 *
640 * FUNCTION: acpi_ns_dump_entry
641 *
642 * PARAMETERS: Handle - Node to be dumped
643 * debug_level - Output level
644 *
645 * RETURN: None
646 *
647 * DESCRIPTION: Dump a single Node
648 *
649 ******************************************************************************/
650
651void acpi_ns_dump_entry(acpi_handle handle, u32 debug_level)
652{
653 struct acpi_walk_info info;
654
655 ACPI_FUNCTION_ENTRY();
656
657 info.debug_level = debug_level;
658 info.owner_id = ACPI_OWNER_ID_MAX;
659 info.display_type = ACPI_DISPLAY_SUMMARY;
660
661 (void)acpi_ns_dump_one_object(handle, 1, &info, NULL);
662}
663
664#ifdef ACPI_ASL_COMPILER
665/*******************************************************************************
666 *
667 * FUNCTION: acpi_ns_dump_tables
668 *
669 * PARAMETERS: search_base - Root of subtree to be dumped, or
670 * NS_ALL to dump the entire namespace
671 * max_depth - Maximum depth of dump. Use INT_MAX
672 * for an effectively unlimited depth.
673 *
674 * RETURN: None
675 *
676 * DESCRIPTION: Dump the name space, or a portion of it.
677 *
678 ******************************************************************************/
679
680void acpi_ns_dump_tables(acpi_handle search_base, u32 max_depth)
681{
682 acpi_handle search_handle = search_base;
683
684 ACPI_FUNCTION_TRACE(ns_dump_tables);
685
686 if (!acpi_gbl_root_node) {
687 /*
688 * If the name space has not been initialized,
689 * there is nothing to dump.
690 */
691 ACPI_DEBUG_PRINT((ACPI_DB_TABLES,
692 "namespace not initialized!\n"));
693 return_VOID;
694 }
695
696 if (ACPI_NS_ALL == search_base) {
697
698 /* Entire namespace */
699
700 search_handle = acpi_gbl_root_node;
701 ACPI_DEBUG_PRINT((ACPI_DB_TABLES, "\\\n"));
702 }
703
704 acpi_ns_dump_objects(ACPI_TYPE_ANY, ACPI_DISPLAY_OBJECTS, max_depth,
705 ACPI_OWNER_ID_MAX, search_handle);
706 return_VOID;
707}
708#endif /* _ACPI_ASL_COMPILER */
709#endif /* defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) */
diff --git a/drivers/acpi/acpica/nsdumpdv.c b/drivers/acpi/acpica/nsdumpdv.c
new file mode 100644
index 00000000000..cc3df78258e
--- /dev/null
+++ b/drivers/acpi/acpica/nsdumpdv.c
@@ -0,0 +1,141 @@
1/******************************************************************************
2 *
3 * Module Name: nsdump - table dumping routines for debug
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46
47/* TBD: This entire module is apparently obsolete and should be removed */
48
49#define _COMPONENT ACPI_NAMESPACE
50ACPI_MODULE_NAME("nsdumpdv")
51#ifdef ACPI_OBSOLETE_FUNCTIONS
52#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
53#include <acpi/acnamesp.h>
54/*******************************************************************************
55 *
56 * FUNCTION: acpi_ns_dump_one_device
57 *
58 * PARAMETERS: Handle - Node to be dumped
59 * Level - Nesting level of the handle
60 * Context - Passed into walk_namespace
61 * return_value - Not used
62 *
63 * RETURN: Status
64 *
65 * DESCRIPTION: Dump a single Node that represents a device
66 * This procedure is a user_function called by acpi_ns_walk_namespace.
67 *
68 ******************************************************************************/
69static acpi_status
70acpi_ns_dump_one_device(acpi_handle obj_handle,
71 u32 level, void *context, void **return_value)
72{
73 struct acpi_buffer buffer;
74 struct acpi_device_info *info;
75 acpi_status status;
76 u32 i;
77
78 ACPI_FUNCTION_NAME(ns_dump_one_device);
79
80 status =
81 acpi_ns_dump_one_object(obj_handle, level, context, return_value);
82
83 buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
84 status = acpi_get_object_info(obj_handle, &buffer);
85 if (ACPI_SUCCESS(status)) {
86 info = buffer.pointer;
87 for (i = 0; i < level; i++) {
88 ACPI_DEBUG_PRINT_RAW((ACPI_DB_TABLES, " "));
89 }
90
91 ACPI_DEBUG_PRINT_RAW((ACPI_DB_TABLES,
92 " HID: %s, ADR: %8.8X%8.8X, Status: %X\n",
93 info->hardware_id.value,
94 ACPI_FORMAT_UINT64(info->address),
95 info->current_status));
96 ACPI_FREE(info);
97 }
98
99 return (status);
100}
101
102/*******************************************************************************
103 *
104 * FUNCTION: acpi_ns_dump_root_devices
105 *
106 * PARAMETERS: None
107 *
108 * RETURN: None
109 *
110 * DESCRIPTION: Dump all objects of type "device"
111 *
112 ******************************************************************************/
113
114void acpi_ns_dump_root_devices(void)
115{
116 acpi_handle sys_bus_handle;
117 acpi_status status;
118
119 ACPI_FUNCTION_NAME(ns_dump_root_devices);
120
121 /* Only dump the table if tracing is enabled */
122
123 if (!(ACPI_LV_TABLES & acpi_dbg_level)) {
124 return;
125 }
126
127 status = acpi_get_handle(NULL, ACPI_NS_SYSTEM_BUS, &sys_bus_handle);
128 if (ACPI_FAILURE(status)) {
129 return;
130 }
131
132 ACPI_DEBUG_PRINT((ACPI_DB_TABLES,
133 "Display of all devices in the namespace:\n"));
134
135 status = acpi_ns_walk_namespace(ACPI_TYPE_DEVICE, sys_bus_handle,
136 ACPI_UINT32_MAX, ACPI_NS_WALK_NO_UNLOCK,
137 acpi_ns_dump_one_device, NULL, NULL);
138}
139
140#endif
141#endif
diff --git a/drivers/acpi/acpica/nseval.c b/drivers/acpi/acpica/nseval.c
new file mode 100644
index 00000000000..a8d7764c73b
--- /dev/null
+++ b/drivers/acpi/acpica/nseval.c
@@ -0,0 +1,278 @@
1/*******************************************************************************
2 *
3 * Module Name: nseval - Object evaluation, includes control method execution
4 *
5 ******************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46#include <acpi/acparser.h>
47#include <acpi/acinterp.h>
48#include <acpi/acnamesp.h>
49
50#define _COMPONENT ACPI_NAMESPACE
51ACPI_MODULE_NAME("nseval")
52
53/*******************************************************************************
54 *
55 * FUNCTION: acpi_ns_evaluate
56 *
57 * PARAMETERS: Info - Evaluation info block, contains:
58 * prefix_node - Prefix or Method/Object Node to execute
59 * Pathname - Name of method to execute, If NULL, the
60 * Node is the object to execute
61 * Parameters - List of parameters to pass to the method,
62 * terminated by NULL. Params itself may be
63 * NULL if no parameters are being passed.
64 * return_object - Where to put method's return value (if
65 * any). If NULL, no value is returned.
66 * parameter_type - Type of Parameter list
67 * return_object - Where to put method's return value (if
68 * any). If NULL, no value is returned.
69 * Flags - ACPI_IGNORE_RETURN_VALUE to delete return
70 *
71 * RETURN: Status
72 *
73 * DESCRIPTION: Execute a control method or return the current value of an
74 * ACPI namespace object.
75 *
76 * MUTEX: Locks interpreter
77 *
78 ******************************************************************************/
79acpi_status acpi_ns_evaluate(struct acpi_evaluate_info * info)
80{
81 acpi_status status;
82 struct acpi_namespace_node *node;
83
84 ACPI_FUNCTION_TRACE(ns_evaluate);
85
86 if (!info) {
87 return_ACPI_STATUS(AE_BAD_PARAMETER);
88 }
89
90 /* Initialize the return value to an invalid object */
91
92 info->return_object = NULL;
93 info->param_count = 0;
94
95 /*
96 * Get the actual namespace node for the target object. Handles these cases:
97 *
98 * 1) Null node, Pathname (absolute path)
99 * 2) Node, Pathname (path relative to Node)
100 * 3) Node, Null Pathname
101 */
102 status = acpi_ns_get_node(info->prefix_node, info->pathname,
103 ACPI_NS_NO_UPSEARCH, &info->resolved_node);
104 if (ACPI_FAILURE(status)) {
105 return_ACPI_STATUS(status);
106 }
107
108 /*
109 * For a method alias, we must grab the actual method node so that proper
110 * scoping context will be established before execution.
111 */
112 if (acpi_ns_get_type(info->resolved_node) ==
113 ACPI_TYPE_LOCAL_METHOD_ALIAS) {
114 info->resolved_node =
115 ACPI_CAST_PTR(struct acpi_namespace_node,
116 info->resolved_node->object);
117 }
118
119 ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "%s [%p] Value %p\n", info->pathname,
120 info->resolved_node,
121 acpi_ns_get_attached_object(info->resolved_node)));
122
123 node = info->resolved_node;
124
125 /*
126 * Two major cases here:
127 *
128 * 1) The object is a control method -- execute it
129 * 2) The object is not a method -- just return it's current value
130 */
131 if (acpi_ns_get_type(info->resolved_node) == ACPI_TYPE_METHOD) {
132 /*
133 * 1) Object is a control method - execute it
134 */
135
136 /* Verify that there is a method object associated with this node */
137
138 info->obj_desc =
139 acpi_ns_get_attached_object(info->resolved_node);
140 if (!info->obj_desc) {
141 ACPI_ERROR((AE_INFO,
142 "Control method has no attached sub-object"));
143 return_ACPI_STATUS(AE_NULL_OBJECT);
144 }
145
146 /* Count the number of arguments being passed to the method */
147
148 if (info->parameters) {
149 while (info->parameters[info->param_count]) {
150 if (info->param_count > ACPI_METHOD_MAX_ARG) {
151 return_ACPI_STATUS(AE_LIMIT);
152 }
153 info->param_count++;
154 }
155 }
156
157
158 ACPI_DUMP_PATHNAME(info->resolved_node, "Execute Method:",
159 ACPI_LV_INFO, _COMPONENT);
160
161 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
162 "Method at AML address %p Length %X\n",
163 info->obj_desc->method.aml_start + 1,
164 info->obj_desc->method.aml_length - 1));
165
166 /*
167 * Any namespace deletion must acquire both the namespace and
168 * interpreter locks to ensure that no thread is using the portion of
169 * the namespace that is being deleted.
170 *
171 * Execute the method via the interpreter. The interpreter is locked
172 * here before calling into the AML parser
173 */
174 acpi_ex_enter_interpreter();
175 status = acpi_ps_execute_method(info);
176 acpi_ex_exit_interpreter();
177 } else {
178 /*
179 * 2) Object is not a method, return its current value
180 *
181 * Disallow certain object types. For these, "evaluation" is undefined.
182 */
183 switch (info->resolved_node->type) {
184 case ACPI_TYPE_DEVICE:
185 case ACPI_TYPE_EVENT:
186 case ACPI_TYPE_MUTEX:
187 case ACPI_TYPE_REGION:
188 case ACPI_TYPE_THERMAL:
189 case ACPI_TYPE_LOCAL_SCOPE:
190
191 ACPI_ERROR((AE_INFO,
192 "[%4.4s] Evaluation of object type [%s] is not supported",
193 info->resolved_node->name.ascii,
194 acpi_ut_get_type_name(info->resolved_node->
195 type)));
196
197 return_ACPI_STATUS(AE_TYPE);
198
199 default:
200 break;
201 }
202
203 /*
204 * Objects require additional resolution steps (e.g., the Node may be
205 * a field that must be read, etc.) -- we can't just grab the object
206 * out of the node.
207 *
208 * Use resolve_node_to_value() to get the associated value.
209 *
210 * NOTE: we can get away with passing in NULL for a walk state because
211 * resolved_node is guaranteed to not be a reference to either a method
212 * local or a method argument (because this interface is never called
213 * from a running method.)
214 *
215 * Even though we do not directly invoke the interpreter for object
216 * resolution, we must lock it because we could access an opregion.
217 * The opregion access code assumes that the interpreter is locked.
218 */
219 acpi_ex_enter_interpreter();
220
221 /* Function has a strange interface */
222
223 status =
224 acpi_ex_resolve_node_to_value(&info->resolved_node, NULL);
225 acpi_ex_exit_interpreter();
226
227 /*
228 * If acpi_ex_resolve_node_to_value() succeeded, the return value was placed
229 * in resolved_node.
230 */
231 if (ACPI_SUCCESS(status)) {
232 status = AE_CTRL_RETURN_VALUE;
233 info->return_object =
234 ACPI_CAST_PTR(union acpi_operand_object,
235 info->resolved_node);
236
237 ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
238 "Returning object %p [%s]\n",
239 info->return_object,
240 acpi_ut_get_object_type_name(info->
241 return_object)));
242 }
243 }
244
245 /*
246 * Check input argument count against the ASL-defined count for a method.
247 * Also check predefined names: argument count and return value against
248 * the ACPI specification. Some incorrect return value types are repaired.
249 */
250 (void)acpi_ns_check_predefined_names(node, info->param_count,
251 status, &info->return_object);
252
253 /* Check if there is a return value that must be dealt with */
254
255 if (status == AE_CTRL_RETURN_VALUE) {
256
257 /* If caller does not want the return value, delete it */
258
259 if (info->flags & ACPI_IGNORE_RETURN_VALUE) {
260 acpi_ut_remove_reference(info->return_object);
261 info->return_object = NULL;
262 }
263
264 /* Map AE_CTRL_RETURN_VALUE to AE_OK, we are done with it */
265
266 status = AE_OK;
267 }
268
269 ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
270 "*** Completed evaluation of object %s ***\n",
271 info->pathname));
272
273 /*
274 * Namespace was unlocked by the handling acpi_ns* function, so we
275 * just return
276 */
277 return_ACPI_STATUS(status);
278}
diff --git a/drivers/acpi/acpica/nsinit.c b/drivers/acpi/acpica/nsinit.c
new file mode 100644
index 00000000000..fe470c4b38f
--- /dev/null
+++ b/drivers/acpi/acpica/nsinit.c
@@ -0,0 +1,593 @@
1/******************************************************************************
2 *
3 * Module Name: nsinit - namespace initialization
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46#include <acpi/acnamesp.h>
47#include <acpi/acdispat.h>
48#include <acpi/acinterp.h>
49#include <linux/nmi.h>
50
51#define _COMPONENT ACPI_NAMESPACE
52ACPI_MODULE_NAME("nsinit")
53
54/* Local prototypes */
55static acpi_status
56acpi_ns_init_one_object(acpi_handle obj_handle,
57 u32 level, void *context, void **return_value);
58
59static acpi_status
60acpi_ns_init_one_device(acpi_handle obj_handle,
61 u32 nesting_level, void *context, void **return_value);
62
63static acpi_status
64acpi_ns_find_ini_methods(acpi_handle obj_handle,
65 u32 nesting_level, void *context, void **return_value);
66
67/*******************************************************************************
68 *
69 * FUNCTION: acpi_ns_initialize_objects
70 *
71 * PARAMETERS: None
72 *
73 * RETURN: Status
74 *
75 * DESCRIPTION: Walk the entire namespace and perform any necessary
76 * initialization on the objects found therein
77 *
78 ******************************************************************************/
79
80acpi_status acpi_ns_initialize_objects(void)
81{
82 acpi_status status;
83 struct acpi_init_walk_info info;
84
85 ACPI_FUNCTION_TRACE(ns_initialize_objects);
86
87 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
88 "**** Starting initialization of namespace objects ****\n"));
89 ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
90 "Completing Region/Field/Buffer/Package initialization:"));
91
92 /* Set all init info to zero */
93
94 ACPI_MEMSET(&info, 0, sizeof(struct acpi_init_walk_info));
95
96 /* Walk entire namespace from the supplied root */
97
98 status = acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
99 ACPI_UINT32_MAX, acpi_ns_init_one_object,
100 &info, NULL);
101 if (ACPI_FAILURE(status)) {
102 ACPI_EXCEPTION((AE_INFO, status, "During WalkNamespace"));
103 }
104
105 ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
106 "\nInitialized %hd/%hd Regions %hd/%hd Fields %hd/%hd Buffers %hd/%hd Packages (%hd nodes)\n",
107 info.op_region_init, info.op_region_count,
108 info.field_init, info.field_count,
109 info.buffer_init, info.buffer_count,
110 info.package_init, info.package_count,
111 info.object_count));
112
113 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
114 "%hd Control Methods found\n", info.method_count));
115 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
116 "%hd Op Regions found\n", info.op_region_count));
117
118 return_ACPI_STATUS(AE_OK);
119}
120
121/*******************************************************************************
122 *
123 * FUNCTION: acpi_ns_initialize_devices
124 *
125 * PARAMETERS: None
126 *
127 * RETURN: acpi_status
128 *
129 * DESCRIPTION: Walk the entire namespace and initialize all ACPI devices.
130 * This means running _INI on all present devices.
131 *
132 * Note: We install PCI config space handler on region access,
133 * not here.
134 *
135 ******************************************************************************/
136
137acpi_status acpi_ns_initialize_devices(void)
138{
139 acpi_status status;
140 struct acpi_device_walk_info info;
141
142 ACPI_FUNCTION_TRACE(ns_initialize_devices);
143
144 /* Init counters */
145
146 info.device_count = 0;
147 info.num_STA = 0;
148 info.num_INI = 0;
149
150 ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
151 "Initializing Device/Processor/Thermal objects by executing _INI methods:"));
152
153 /* Tree analysis: find all subtrees that contain _INI methods */
154
155 status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
156 ACPI_UINT32_MAX, FALSE,
157 acpi_ns_find_ini_methods, &info, NULL);
158 if (ACPI_FAILURE(status)) {
159 goto error_exit;
160 }
161
162 /* Allocate the evaluation information block */
163
164 info.evaluate_info =
165 ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
166 if (!info.evaluate_info) {
167 status = AE_NO_MEMORY;
168 goto error_exit;
169 }
170
171 /* Walk namespace to execute all _INIs on present devices */
172
173 status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
174 ACPI_UINT32_MAX, FALSE,
175 acpi_ns_init_one_device, &info, NULL);
176
177 ACPI_FREE(info.evaluate_info);
178 if (ACPI_FAILURE(status)) {
179 goto error_exit;
180 }
181
182 ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
183 "\nExecuted %hd _INI methods requiring %hd _STA executions (examined %hd objects)\n",
184 info.num_INI, info.num_STA, info.device_count));
185
186 return_ACPI_STATUS(status);
187
188 error_exit:
189 ACPI_EXCEPTION((AE_INFO, status, "During device initialization"));
190 return_ACPI_STATUS(status);
191}
192
193/*******************************************************************************
194 *
195 * FUNCTION: acpi_ns_init_one_object
196 *
197 * PARAMETERS: obj_handle - Node
198 * Level - Current nesting level
199 * Context - Points to a init info struct
200 * return_value - Not used
201 *
202 * RETURN: Status
203 *
204 * DESCRIPTION: Callback from acpi_walk_namespace. Invoked for every object
205 * within the namespace.
206 *
207 * Currently, the only objects that require initialization are:
208 * 1) Methods
209 * 2) Op Regions
210 *
211 ******************************************************************************/
212
213static acpi_status
214acpi_ns_init_one_object(acpi_handle obj_handle,
215 u32 level, void *context, void **return_value)
216{
217 acpi_object_type type;
218 acpi_status status = AE_OK;
219 struct acpi_init_walk_info *info =
220 (struct acpi_init_walk_info *)context;
221 struct acpi_namespace_node *node =
222 (struct acpi_namespace_node *)obj_handle;
223 union acpi_operand_object *obj_desc;
224
225 ACPI_FUNCTION_NAME(ns_init_one_object);
226
227 info->object_count++;
228
229 /* And even then, we are only interested in a few object types */
230
231 type = acpi_ns_get_type(obj_handle);
232 obj_desc = acpi_ns_get_attached_object(node);
233 if (!obj_desc) {
234 return (AE_OK);
235 }
236
237 /* Increment counters for object types we are looking for */
238
239 switch (type) {
240 case ACPI_TYPE_REGION:
241 info->op_region_count++;
242 break;
243
244 case ACPI_TYPE_BUFFER_FIELD:
245 info->field_count++;
246 break;
247
248 case ACPI_TYPE_LOCAL_BANK_FIELD:
249 info->field_count++;
250 break;
251
252 case ACPI_TYPE_BUFFER:
253 info->buffer_count++;
254 break;
255
256 case ACPI_TYPE_PACKAGE:
257 info->package_count++;
258 break;
259
260 default:
261
262 /* No init required, just exit now */
263 return (AE_OK);
264 }
265
266 /*
267 * If the object is already initialized, nothing else to do
268 */
269 if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
270 return (AE_OK);
271 }
272
273 /*
274 * Must lock the interpreter before executing AML code
275 */
276 acpi_ex_enter_interpreter();
277
278 /*
279 * Each of these types can contain executable AML code within the
280 * declaration.
281 */
282 switch (type) {
283 case ACPI_TYPE_REGION:
284
285 info->op_region_init++;
286 status = acpi_ds_get_region_arguments(obj_desc);
287 break;
288
289 case ACPI_TYPE_BUFFER_FIELD:
290
291 info->field_init++;
292 status = acpi_ds_get_buffer_field_arguments(obj_desc);
293 break;
294
295 case ACPI_TYPE_LOCAL_BANK_FIELD:
296
297 info->field_init++;
298 status = acpi_ds_get_bank_field_arguments(obj_desc);
299 break;
300
301 case ACPI_TYPE_BUFFER:
302
303 info->buffer_init++;
304 status = acpi_ds_get_buffer_arguments(obj_desc);
305 break;
306
307 case ACPI_TYPE_PACKAGE:
308
309 info->package_init++;
310 status = acpi_ds_get_package_arguments(obj_desc);
311 break;
312
313 default:
314 /* No other types can get here */
315 break;
316 }
317
318 if (ACPI_FAILURE(status)) {
319 ACPI_EXCEPTION((AE_INFO, status,
320 "Could not execute arguments for [%4.4s] (%s)",
321 acpi_ut_get_node_name(node),
322 acpi_ut_get_type_name(type)));
323 }
324
325 /*
326 * Print a dot for each object unless we are going to print the entire
327 * pathname
328 */
329 if (!(acpi_dbg_level & ACPI_LV_INIT_NAMES)) {
330 ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, "."));
331 }
332
333 /*
334 * We ignore errors from above, and always return OK, since we don't want
335 * to abort the walk on any single error.
336 */
337 acpi_ex_exit_interpreter();
338 return (AE_OK);
339}
340
341/*******************************************************************************
342 *
343 * FUNCTION: acpi_ns_find_ini_methods
344 *
345 * PARAMETERS: acpi_walk_callback
346 *
347 * RETURN: acpi_status
348 *
349 * DESCRIPTION: Called during namespace walk. Finds objects named _INI under
350 * device/processor/thermal objects, and marks the entire subtree
351 * with a SUBTREE_HAS_INI flag. This flag is used during the
352 * subsequent device initialization walk to avoid entire subtrees
353 * that do not contain an _INI.
354 *
355 ******************************************************************************/
356
357static acpi_status
358acpi_ns_find_ini_methods(acpi_handle obj_handle,
359 u32 nesting_level, void *context, void **return_value)
360{
361 struct acpi_device_walk_info *info =
362 ACPI_CAST_PTR(struct acpi_device_walk_info, context);
363 struct acpi_namespace_node *node;
364 struct acpi_namespace_node *parent_node;
365
366 /* Keep count of device/processor/thermal objects */
367
368 node = ACPI_CAST_PTR(struct acpi_namespace_node, obj_handle);
369 if ((node->type == ACPI_TYPE_DEVICE) ||
370 (node->type == ACPI_TYPE_PROCESSOR) ||
371 (node->type == ACPI_TYPE_THERMAL)) {
372 info->device_count++;
373 return (AE_OK);
374 }
375
376 /* We are only looking for methods named _INI */
377
378 if (!ACPI_COMPARE_NAME(node->name.ascii, METHOD_NAME__INI)) {
379 return (AE_OK);
380 }
381
382 /*
383 * The only _INI methods that we care about are those that are
384 * present under Device, Processor, and Thermal objects.
385 */
386 parent_node = acpi_ns_get_parent_node(node);
387 switch (parent_node->type) {
388 case ACPI_TYPE_DEVICE:
389 case ACPI_TYPE_PROCESSOR:
390 case ACPI_TYPE_THERMAL:
391
392 /* Mark parent and bubble up the INI present flag to the root */
393
394 while (parent_node) {
395 parent_node->flags |= ANOBJ_SUBTREE_HAS_INI;
396 parent_node = acpi_ns_get_parent_node(parent_node);
397 }
398 break;
399
400 default:
401 break;
402 }
403
404 return (AE_OK);
405}
406
407/*******************************************************************************
408 *
409 * FUNCTION: acpi_ns_init_one_device
410 *
411 * PARAMETERS: acpi_walk_callback
412 *
413 * RETURN: acpi_status
414 *
415 * DESCRIPTION: This is called once per device soon after ACPI is enabled
416 * to initialize each device. It determines if the device is
417 * present, and if so, calls _INI.
418 *
419 ******************************************************************************/
420
421static acpi_status
422acpi_ns_init_one_device(acpi_handle obj_handle,
423 u32 nesting_level, void *context, void **return_value)
424{
425 struct acpi_device_walk_info *walk_info =
426 ACPI_CAST_PTR(struct acpi_device_walk_info, context);
427 struct acpi_evaluate_info *info = walk_info->evaluate_info;
428 u32 flags;
429 acpi_status status;
430 struct acpi_namespace_node *device_node;
431
432 ACPI_FUNCTION_TRACE(ns_init_one_device);
433
434 /* We are interested in Devices, Processors and thermal_zones only */
435
436 device_node = ACPI_CAST_PTR(struct acpi_namespace_node, obj_handle);
437 if ((device_node->type != ACPI_TYPE_DEVICE) &&
438 (device_node->type != ACPI_TYPE_PROCESSOR) &&
439 (device_node->type != ACPI_TYPE_THERMAL)) {
440 return_ACPI_STATUS(AE_OK);
441 }
442
443 /*
444 * Because of an earlier namespace analysis, all subtrees that contain an
445 * _INI method are tagged.
446 *
447 * If this device subtree does not contain any _INI methods, we
448 * can exit now and stop traversing this entire subtree.
449 */
450 if (!(device_node->flags & ANOBJ_SUBTREE_HAS_INI)) {
451 return_ACPI_STATUS(AE_CTRL_DEPTH);
452 }
453
454 /*
455 * Run _STA to determine if this device is present and functioning. We
456 * must know this information for two important reasons (from ACPI spec):
457 *
458 * 1) We can only run _INI if the device is present.
459 * 2) We must abort the device tree walk on this subtree if the device is
460 * not present and is not functional (we will not examine the children)
461 *
462 * The _STA method is not required to be present under the device, we
463 * assume the device is present if _STA does not exist.
464 */
465 ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname
466 (ACPI_TYPE_METHOD, device_node, METHOD_NAME__STA));
467
468 status = acpi_ut_execute_STA(device_node, &flags);
469 if (ACPI_FAILURE(status)) {
470
471 /* Ignore error and move on to next device */
472
473 return_ACPI_STATUS(AE_OK);
474 }
475
476 /*
477 * Flags == -1 means that _STA was not found. In this case, we assume that
478 * the device is both present and functional.
479 *
480 * From the ACPI spec, description of _STA:
481 *
482 * "If a device object (including the processor object) does not have an
483 * _STA object, then OSPM assumes that all of the above bits are set (in
484 * other words, the device is present, ..., and functioning)"
485 */
486 if (flags != ACPI_UINT32_MAX) {
487 walk_info->num_STA++;
488 }
489
490 /*
491 * Examine the PRESENT and FUNCTIONING status bits
492 *
493 * Note: ACPI spec does not seem to specify behavior for the present but
494 * not functioning case, so we assume functioning if present.
495 */
496 if (!(flags & ACPI_STA_DEVICE_PRESENT)) {
497
498 /* Device is not present, we must examine the Functioning bit */
499
500 if (flags & ACPI_STA_DEVICE_FUNCTIONING) {
501 /*
502 * Device is not present but is "functioning". In this case,
503 * we will not run _INI, but we continue to examine the children
504 * of this device.
505 *
506 * From the ACPI spec, description of _STA: (Note - no mention
507 * of whether to run _INI or not on the device in question)
508 *
509 * "_STA may return bit 0 clear (not present) with bit 3 set
510 * (device is functional). This case is used to indicate a valid
511 * device for which no device driver should be loaded (for example,
512 * a bridge device.) Children of this device may be present and
513 * valid. OSPM should continue enumeration below a device whose
514 * _STA returns this bit combination"
515 */
516 return_ACPI_STATUS(AE_OK);
517 } else {
518 /*
519 * Device is not present and is not functioning. We must abort the
520 * walk of this subtree immediately -- don't look at the children
521 * of such a device.
522 *
523 * From the ACPI spec, description of _INI:
524 *
525 * "If the _STA method indicates that the device is not present,
526 * OSPM will not run the _INI and will not examine the children
527 * of the device for _INI methods"
528 */
529 return_ACPI_STATUS(AE_CTRL_DEPTH);
530 }
531 }
532
533 /*
534 * The device is present or is assumed present if no _STA exists.
535 * Run the _INI if it exists (not required to exist)
536 *
537 * Note: We know there is an _INI within this subtree, but it may not be
538 * under this particular device, it may be lower in the branch.
539 */
540 ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname
541 (ACPI_TYPE_METHOD, device_node, METHOD_NAME__INI));
542
543 info->prefix_node = device_node;
544 info->pathname = METHOD_NAME__INI;
545 info->parameters = NULL;
546 info->flags = ACPI_IGNORE_RETURN_VALUE;
547
548 /*
549 * Some hardware relies on this being executed as atomically
550 * as possible (without an NMI being received in the middle of
551 * this) - so disable NMIs and initialize the device:
552 */
553 acpi_nmi_disable();
554 status = acpi_ns_evaluate(info);
555 acpi_nmi_enable();
556
557 if (ACPI_SUCCESS(status)) {
558 walk_info->num_INI++;
559
560 if ((acpi_dbg_level <= ACPI_LV_ALL_EXCEPTIONS) &&
561 (!(acpi_dbg_level & ACPI_LV_INFO))) {
562 ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, "."));
563 }
564 }
565#ifdef ACPI_DEBUG_OUTPUT
566 else if (status != AE_NOT_FOUND) {
567
568 /* Ignore error and move on to next device */
569
570 char *scope_name =
571 acpi_ns_get_external_pathname(info->resolved_node);
572
573 ACPI_EXCEPTION((AE_INFO, status, "during %s._INI execution",
574 scope_name));
575 ACPI_FREE(scope_name);
576 }
577#endif
578
579 /* Ignore errors from above */
580
581 status = AE_OK;
582
583 /*
584 * The _INI method has been run if present; call the Global Initialization
585 * Handler for this device.
586 */
587 if (acpi_gbl_init_handler) {
588 status =
589 acpi_gbl_init_handler(device_node, ACPI_INIT_DEVICE_INI);
590 }
591
592 return_ACPI_STATUS(status);
593}
diff --git a/drivers/acpi/acpica/nsload.c b/drivers/acpi/acpica/nsload.c
new file mode 100644
index 00000000000..a6e92b31a06
--- /dev/null
+++ b/drivers/acpi/acpica/nsload.c
@@ -0,0 +1,315 @@
1/******************************************************************************
2 *
3 * Module Name: nsload - namespace loading/expanding/contracting procedures
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46#include <acpi/acnamesp.h>
47#include <acpi/acdispat.h>
48#include <acpi/actables.h>
49
50#define _COMPONENT ACPI_NAMESPACE
51ACPI_MODULE_NAME("nsload")
52
53/* Local prototypes */
54#ifdef ACPI_FUTURE_IMPLEMENTATION
55acpi_status acpi_ns_unload_namespace(acpi_handle handle);
56
57static acpi_status acpi_ns_delete_subtree(acpi_handle start_handle);
58#endif
59
60#ifndef ACPI_NO_METHOD_EXECUTION
61/*******************************************************************************
62 *
63 * FUNCTION: acpi_ns_load_table
64 *
65 * PARAMETERS: table_index - Index for table to be loaded
66 * Node - Owning NS node
67 *
68 * RETURN: Status
69 *
70 * DESCRIPTION: Load one ACPI table into the namespace
71 *
72 ******************************************************************************/
73
74acpi_status
75acpi_ns_load_table(u32 table_index, struct acpi_namespace_node *node)
76{
77 acpi_status status;
78
79 ACPI_FUNCTION_TRACE(ns_load_table);
80
81 /*
82 * Parse the table and load the namespace with all named
83 * objects found within. Control methods are NOT parsed
84 * at this time. In fact, the control methods cannot be
85 * parsed until the entire namespace is loaded, because
86 * if a control method makes a forward reference (call)
87 * to another control method, we can't continue parsing
88 * because we don't know how many arguments to parse next!
89 */
90 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
91 if (ACPI_FAILURE(status)) {
92 return_ACPI_STATUS(status);
93 }
94
95 /* If table already loaded into namespace, just return */
96
97 if (acpi_tb_is_table_loaded(table_index)) {
98 status = AE_ALREADY_EXISTS;
99 goto unlock;
100 }
101
102 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
103 "**** Loading table into namespace ****\n"));
104
105 status = acpi_tb_allocate_owner_id(table_index);
106 if (ACPI_FAILURE(status)) {
107 goto unlock;
108 }
109
110 status = acpi_ns_parse_table(table_index, node);
111 if (ACPI_SUCCESS(status)) {
112 acpi_tb_set_table_loaded_flag(table_index, TRUE);
113 } else {
114 (void)acpi_tb_release_owner_id(table_index);
115 }
116
117 unlock:
118 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
119
120 if (ACPI_FAILURE(status)) {
121 return_ACPI_STATUS(status);
122 }
123
124 /*
125 * Now we can parse the control methods. We always parse
126 * them here for a sanity check, and if configured for
127 * just-in-time parsing, we delete the control method
128 * parse trees.
129 */
130 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
131 "**** Begin Table Method Parsing and Object Initialization ****\n"));
132
133 status = acpi_ds_initialize_objects(table_index, node);
134
135 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
136 "**** Completed Table Method Parsing and Object Initialization ****\n"));
137
138 return_ACPI_STATUS(status);
139}
140
141#ifdef ACPI_OBSOLETE_FUNCTIONS
142/*******************************************************************************
143 *
144 * FUNCTION: acpi_load_namespace
145 *
146 * PARAMETERS: None
147 *
148 * RETURN: Status
149 *
150 * DESCRIPTION: Load the name space from what ever is pointed to by DSDT.
151 * (DSDT points to either the BIOS or a buffer.)
152 *
153 ******************************************************************************/
154
155acpi_status acpi_ns_load_namespace(void)
156{
157 acpi_status status;
158
159 ACPI_FUNCTION_TRACE(acpi_load_name_space);
160
161 /* There must be at least a DSDT installed */
162
163 if (acpi_gbl_DSDT == NULL) {
164 ACPI_ERROR((AE_INFO, "DSDT is not in memory"));
165 return_ACPI_STATUS(AE_NO_ACPI_TABLES);
166 }
167
168 /*
169 * Load the namespace. The DSDT is required,
170 * but the SSDT and PSDT tables are optional.
171 */
172 status = acpi_ns_load_table_by_type(ACPI_TABLE_ID_DSDT);
173 if (ACPI_FAILURE(status)) {
174 return_ACPI_STATUS(status);
175 }
176
177 /* Ignore exceptions from these */
178
179 (void)acpi_ns_load_table_by_type(ACPI_TABLE_ID_SSDT);
180 (void)acpi_ns_load_table_by_type(ACPI_TABLE_ID_PSDT);
181
182 ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
183 "ACPI Namespace successfully loaded at root %p\n",
184 acpi_gbl_root_node));
185
186 return_ACPI_STATUS(status);
187}
188#endif
189
190#ifdef ACPI_FUTURE_IMPLEMENTATION
191/*******************************************************************************
192 *
193 * FUNCTION: acpi_ns_delete_subtree
194 *
195 * PARAMETERS: start_handle - Handle in namespace where search begins
196 *
197 * RETURNS Status
198 *
199 * DESCRIPTION: Walks the namespace starting at the given handle and deletes
200 * all objects, entries, and scopes in the entire subtree.
201 *
202 * Namespace/Interpreter should be locked or the subsystem should
203 * be in shutdown before this routine is called.
204 *
205 ******************************************************************************/
206
207static acpi_status acpi_ns_delete_subtree(acpi_handle start_handle)
208{
209 acpi_status status;
210 acpi_handle child_handle;
211 acpi_handle parent_handle;
212 acpi_handle next_child_handle;
213 acpi_handle dummy;
214 u32 level;
215
216 ACPI_FUNCTION_TRACE(ns_delete_subtree);
217
218 parent_handle = start_handle;
219 child_handle = NULL;
220 level = 1;
221
222 /*
223 * Traverse the tree of objects until we bubble back up
224 * to where we started.
225 */
226 while (level > 0) {
227
228 /* Attempt to get the next object in this scope */
229
230 status = acpi_get_next_object(ACPI_TYPE_ANY, parent_handle,
231 child_handle, &next_child_handle);
232
233 child_handle = next_child_handle;
234
235 /* Did we get a new object? */
236
237 if (ACPI_SUCCESS(status)) {
238
239 /* Check if this object has any children */
240
241 if (ACPI_SUCCESS
242 (acpi_get_next_object
243 (ACPI_TYPE_ANY, child_handle, NULL, &dummy))) {
244 /*
245 * There is at least one child of this object,
246 * visit the object
247 */
248 level++;
249 parent_handle = child_handle;
250 child_handle = NULL;
251 }
252 } else {
253 /*
254 * No more children in this object, go back up to
255 * the object's parent
256 */
257 level--;
258
259 /* Delete all children now */
260
261 acpi_ns_delete_children(child_handle);
262
263 child_handle = parent_handle;
264 status = acpi_get_parent(parent_handle, &parent_handle);
265 if (ACPI_FAILURE(status)) {
266 return_ACPI_STATUS(status);
267 }
268 }
269 }
270
271 /* Now delete the starting object, and we are done */
272
273 acpi_ns_delete_node(child_handle);
274
275 return_ACPI_STATUS(AE_OK);
276}
277
278/*******************************************************************************
279 *
280 * FUNCTION: acpi_ns_unload_name_space
281 *
282 * PARAMETERS: Handle - Root of namespace subtree to be deleted
283 *
284 * RETURN: Status
285 *
286 * DESCRIPTION: Shrinks the namespace, typically in response to an undocking
287 * event. Deletes an entire subtree starting from (and
288 * including) the given handle.
289 *
290 ******************************************************************************/
291
292acpi_status acpi_ns_unload_namespace(acpi_handle handle)
293{
294 acpi_status status;
295
296 ACPI_FUNCTION_TRACE(ns_unload_name_space);
297
298 /* Parameter validation */
299
300 if (!acpi_gbl_root_node) {
301 return_ACPI_STATUS(AE_NO_NAMESPACE);
302 }
303
304 if (!handle) {
305 return_ACPI_STATUS(AE_BAD_PARAMETER);
306 }
307
308 /* This function does the real work */
309
310 status = acpi_ns_delete_subtree(handle);
311
312 return_ACPI_STATUS(status);
313}
314#endif
315#endif
diff --git a/drivers/acpi/acpica/nsnames.c b/drivers/acpi/acpica/nsnames.c
new file mode 100644
index 00000000000..b7e301848ba
--- /dev/null
+++ b/drivers/acpi/acpica/nsnames.c
@@ -0,0 +1,265 @@
1/*******************************************************************************
2 *
3 * Module Name: nsnames - Name manipulation and search
4 *
5 ******************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46#include <acpi/amlcode.h>
47#include <acpi/acnamesp.h>
48
49#define _COMPONENT ACPI_NAMESPACE
50ACPI_MODULE_NAME("nsnames")
51
52/*******************************************************************************
53 *
54 * FUNCTION: acpi_ns_build_external_path
55 *
56 * PARAMETERS: Node - NS node whose pathname is needed
57 * Size - Size of the pathname
58 * *name_buffer - Where to return the pathname
59 *
60 * RETURN: Status
61 * Places the pathname into the name_buffer, in external format
62 * (name segments separated by path separators)
63 *
64 * DESCRIPTION: Generate a full pathaname
65 *
66 ******************************************************************************/
67acpi_status
68acpi_ns_build_external_path(struct acpi_namespace_node *node,
69 acpi_size size, char *name_buffer)
70{
71 acpi_size index;
72 struct acpi_namespace_node *parent_node;
73
74 ACPI_FUNCTION_ENTRY();
75
76 /* Special case for root */
77
78 index = size - 1;
79 if (index < ACPI_NAME_SIZE) {
80 name_buffer[0] = AML_ROOT_PREFIX;
81 name_buffer[1] = 0;
82 return (AE_OK);
83 }
84
85 /* Store terminator byte, then build name backwards */
86
87 parent_node = node;
88 name_buffer[index] = 0;
89
90 while ((index > ACPI_NAME_SIZE) && (parent_node != acpi_gbl_root_node)) {
91 index -= ACPI_NAME_SIZE;
92
93 /* Put the name into the buffer */
94
95 ACPI_MOVE_32_TO_32((name_buffer + index), &parent_node->name);
96 parent_node = acpi_ns_get_parent_node(parent_node);
97
98 /* Prefix name with the path separator */
99
100 index--;
101 name_buffer[index] = ACPI_PATH_SEPARATOR;
102 }
103
104 /* Overwrite final separator with the root prefix character */
105
106 name_buffer[index] = AML_ROOT_PREFIX;
107
108 if (index != 0) {
109 ACPI_ERROR((AE_INFO,
110 "Could not construct external pathname; index=%X, size=%X, Path=%s",
111 (u32) index, (u32) size, &name_buffer[size]));
112
113 return (AE_BAD_PARAMETER);
114 }
115
116 return (AE_OK);
117}
118
119/*******************************************************************************
120 *
121 * FUNCTION: acpi_ns_get_external_pathname
122 *
123 * PARAMETERS: Node - Namespace node whose pathname is needed
124 *
125 * RETURN: Pointer to storage containing the fully qualified name of
126 * the node, In external format (name segments separated by path
127 * separators.)
128 *
129 * DESCRIPTION: Used for debug printing in acpi_ns_search_table().
130 *
131 ******************************************************************************/
132
133char *acpi_ns_get_external_pathname(struct acpi_namespace_node *node)
134{
135 acpi_status status;
136 char *name_buffer;
137 acpi_size size;
138
139 ACPI_FUNCTION_TRACE_PTR(ns_get_external_pathname, node);
140
141 /* Calculate required buffer size based on depth below root */
142
143 size = acpi_ns_get_pathname_length(node);
144 if (!size) {
145 return_PTR(NULL);
146 }
147
148 /* Allocate a buffer to be returned to caller */
149
150 name_buffer = ACPI_ALLOCATE_ZEROED(size);
151 if (!name_buffer) {
152 ACPI_ERROR((AE_INFO, "Allocation failure"));
153 return_PTR(NULL);
154 }
155
156 /* Build the path in the allocated buffer */
157
158 status = acpi_ns_build_external_path(node, size, name_buffer);
159 if (ACPI_FAILURE(status)) {
160 ACPI_FREE(name_buffer);
161 return_PTR(NULL);
162 }
163
164 return_PTR(name_buffer);
165}
166
167/*******************************************************************************
168 *
169 * FUNCTION: acpi_ns_get_pathname_length
170 *
171 * PARAMETERS: Node - Namespace node
172 *
173 * RETURN: Length of path, including prefix
174 *
175 * DESCRIPTION: Get the length of the pathname string for this node
176 *
177 ******************************************************************************/
178
179acpi_size acpi_ns_get_pathname_length(struct acpi_namespace_node *node)
180{
181 acpi_size size;
182 struct acpi_namespace_node *next_node;
183
184 ACPI_FUNCTION_ENTRY();
185
186 /*
187 * Compute length of pathname as 5 * number of name segments.
188 * Go back up the parent tree to the root
189 */
190 size = 0;
191 next_node = node;
192
193 while (next_node && (next_node != acpi_gbl_root_node)) {
194 if (ACPI_GET_DESCRIPTOR_TYPE(next_node) != ACPI_DESC_TYPE_NAMED) {
195 ACPI_ERROR((AE_INFO,
196 "Invalid Namespace Node (%p) while traversing namespace",
197 next_node));
198 return 0;
199 }
200 size += ACPI_PATH_SEGMENT_LENGTH;
201 next_node = acpi_ns_get_parent_node(next_node);
202 }
203
204 if (!size) {
205 size = 1; /* Root node case */
206 }
207
208 return (size + 1); /* +1 for null string terminator */
209}
210
211/*******************************************************************************
212 *
213 * FUNCTION: acpi_ns_handle_to_pathname
214 *
215 * PARAMETERS: target_handle - Handle of named object whose name is
216 * to be found
217 * Buffer - Where the pathname is returned
218 *
219 * RETURN: Status, Buffer is filled with pathname if status is AE_OK
220 *
221 * DESCRIPTION: Build and return a full namespace pathname
222 *
223 ******************************************************************************/
224
225acpi_status
226acpi_ns_handle_to_pathname(acpi_handle target_handle,
227 struct acpi_buffer * buffer)
228{
229 acpi_status status;
230 struct acpi_namespace_node *node;
231 acpi_size required_size;
232
233 ACPI_FUNCTION_TRACE_PTR(ns_handle_to_pathname, target_handle);
234
235 node = acpi_ns_map_handle_to_node(target_handle);
236 if (!node) {
237 return_ACPI_STATUS(AE_BAD_PARAMETER);
238 }
239
240 /* Determine size required for the caller buffer */
241
242 required_size = acpi_ns_get_pathname_length(node);
243 if (!required_size) {
244 return_ACPI_STATUS(AE_BAD_PARAMETER);
245 }
246
247 /* Validate/Allocate/Clear caller buffer */
248
249 status = acpi_ut_initialize_buffer(buffer, required_size);
250 if (ACPI_FAILURE(status)) {
251 return_ACPI_STATUS(status);
252 }
253
254 /* Build the path in the caller buffer */
255
256 status =
257 acpi_ns_build_external_path(node, required_size, buffer->pointer);
258 if (ACPI_FAILURE(status)) {
259 return_ACPI_STATUS(status);
260 }
261
262 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "%s [%X]\n",
263 (char *)buffer->pointer, (u32) required_size));
264 return_ACPI_STATUS(AE_OK);
265}
diff --git a/drivers/acpi/acpica/nsobject.c b/drivers/acpi/acpica/nsobject.c
new file mode 100644
index 00000000000..ca9edeea27d
--- /dev/null
+++ b/drivers/acpi/acpica/nsobject.c
@@ -0,0 +1,441 @@
1/*******************************************************************************
2 *
3 * Module Name: nsobject - Utilities for objects attached to namespace
4 * table entries
5 *
6 ******************************************************************************/
7
8/*
9 * Copyright (C) 2000 - 2008, Intel Corp.
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions, and the following disclaimer,
17 * without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 * substantially similar to the "NO WARRANTY" disclaimer below
20 * ("Disclaimer") and any redistribution must be conditioned upon
21 * including a substantially similar Disclaimer requirement for further
22 * binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 * of any contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
30 *
31 * NO WARRANTY
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
43 */
44
45#include <acpi/acpi.h>
46#include <acpi/accommon.h>
47#include <acpi/acnamesp.h>
48
49#define _COMPONENT ACPI_NAMESPACE
50ACPI_MODULE_NAME("nsobject")
51
52/*******************************************************************************
53 *
54 * FUNCTION: acpi_ns_attach_object
55 *
56 * PARAMETERS: Node - Parent Node
57 * Object - Object to be attached
58 * Type - Type of object, or ACPI_TYPE_ANY if not
59 * known
60 *
61 * RETURN: Status
62 *
63 * DESCRIPTION: Record the given object as the value associated with the
64 * name whose acpi_handle is passed. If Object is NULL
65 * and Type is ACPI_TYPE_ANY, set the name as having no value.
66 * Note: Future may require that the Node->Flags field be passed
67 * as a parameter.
68 *
69 * MUTEX: Assumes namespace is locked
70 *
71 ******************************************************************************/
72acpi_status
73acpi_ns_attach_object(struct acpi_namespace_node *node,
74 union acpi_operand_object *object, acpi_object_type type)
75{
76 union acpi_operand_object *obj_desc;
77 union acpi_operand_object *last_obj_desc;
78 acpi_object_type object_type = ACPI_TYPE_ANY;
79
80 ACPI_FUNCTION_TRACE(ns_attach_object);
81
82 /*
83 * Parameter validation
84 */
85 if (!node) {
86
87 /* Invalid handle */
88
89 ACPI_ERROR((AE_INFO, "Null NamedObj handle"));
90 return_ACPI_STATUS(AE_BAD_PARAMETER);
91 }
92
93 if (!object && (ACPI_TYPE_ANY != type)) {
94
95 /* Null object */
96
97 ACPI_ERROR((AE_INFO,
98 "Null object, but type not ACPI_TYPE_ANY"));
99 return_ACPI_STATUS(AE_BAD_PARAMETER);
100 }
101
102 if (ACPI_GET_DESCRIPTOR_TYPE(node) != ACPI_DESC_TYPE_NAMED) {
103
104 /* Not a name handle */
105
106 ACPI_ERROR((AE_INFO, "Invalid handle %p [%s]",
107 node, acpi_ut_get_descriptor_name(node)));
108 return_ACPI_STATUS(AE_BAD_PARAMETER);
109 }
110
111 /* Check if this object is already attached */
112
113 if (node->object == object) {
114 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
115 "Obj %p already installed in NameObj %p\n",
116 object, node));
117
118 return_ACPI_STATUS(AE_OK);
119 }
120
121 /* If null object, we will just install it */
122
123 if (!object) {
124 obj_desc = NULL;
125 object_type = ACPI_TYPE_ANY;
126 }
127
128 /*
129 * If the source object is a namespace Node with an attached object,
130 * we will use that (attached) object
131 */
132 else if ((ACPI_GET_DESCRIPTOR_TYPE(object) == ACPI_DESC_TYPE_NAMED) &&
133 ((struct acpi_namespace_node *)object)->object) {
134 /*
135 * Value passed is a name handle and that name has a
136 * non-null value. Use that name's value and type.
137 */
138 obj_desc = ((struct acpi_namespace_node *)object)->object;
139 object_type = ((struct acpi_namespace_node *)object)->type;
140 }
141
142 /*
143 * Otherwise, we will use the parameter object, but we must type
144 * it first
145 */
146 else {
147 obj_desc = (union acpi_operand_object *)object;
148
149 /* Use the given type */
150
151 object_type = type;
152 }
153
154 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Installing %p into Node %p [%4.4s]\n",
155 obj_desc, node, acpi_ut_get_node_name(node)));
156
157 /* Detach an existing attached object if present */
158
159 if (node->object) {
160 acpi_ns_detach_object(node);
161 }
162
163 if (obj_desc) {
164 /*
165 * Must increment the new value's reference count
166 * (if it is an internal object)
167 */
168 acpi_ut_add_reference(obj_desc);
169
170 /*
171 * Handle objects with multiple descriptors - walk
172 * to the end of the descriptor list
173 */
174 last_obj_desc = obj_desc;
175 while (last_obj_desc->common.next_object) {
176 last_obj_desc = last_obj_desc->common.next_object;
177 }
178
179 /* Install the object at the front of the object list */
180
181 last_obj_desc->common.next_object = node->object;
182 }
183
184 node->type = (u8) object_type;
185 node->object = obj_desc;
186
187 return_ACPI_STATUS(AE_OK);
188}
189
190/*******************************************************************************
191 *
192 * FUNCTION: acpi_ns_detach_object
193 *
194 * PARAMETERS: Node - A Namespace node whose object will be detached
195 *
196 * RETURN: None.
197 *
198 * DESCRIPTION: Detach/delete an object associated with a namespace node.
199 * if the object is an allocated object, it is freed.
200 * Otherwise, the field is simply cleared.
201 *
202 ******************************************************************************/
203
204void acpi_ns_detach_object(struct acpi_namespace_node *node)
205{
206 union acpi_operand_object *obj_desc;
207
208 ACPI_FUNCTION_TRACE(ns_detach_object);
209
210 obj_desc = node->object;
211
212 if (!obj_desc ||
213 (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_DATA)) {
214 return_VOID;
215 }
216
217 /* Clear the entry in all cases */
218
219 node->object = NULL;
220 if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) == ACPI_DESC_TYPE_OPERAND) {
221 node->object = obj_desc->common.next_object;
222 if (node->object &&
223 (ACPI_GET_OBJECT_TYPE(node->object) !=
224 ACPI_TYPE_LOCAL_DATA)) {
225 node->object = node->object->common.next_object;
226 }
227 }
228
229 /* Reset the node type to untyped */
230
231 node->type = ACPI_TYPE_ANY;
232
233 ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "Node %p [%4.4s] Object %p\n",
234 node, acpi_ut_get_node_name(node), obj_desc));
235
236 /* Remove one reference on the object (and all subobjects) */
237
238 acpi_ut_remove_reference(obj_desc);
239 return_VOID;
240}
241
242/*******************************************************************************
243 *
244 * FUNCTION: acpi_ns_get_attached_object
245 *
246 * PARAMETERS: Node - Namespace node
247 *
248 * RETURN: Current value of the object field from the Node whose
249 * handle is passed
250 *
251 * DESCRIPTION: Obtain the object attached to a namespace node.
252 *
253 ******************************************************************************/
254
255union acpi_operand_object *acpi_ns_get_attached_object(struct
256 acpi_namespace_node
257 *node)
258{
259 ACPI_FUNCTION_TRACE_PTR(ns_get_attached_object, node);
260
261 if (!node) {
262 ACPI_WARNING((AE_INFO, "Null Node ptr"));
263 return_PTR(NULL);
264 }
265
266 if (!node->object ||
267 ((ACPI_GET_DESCRIPTOR_TYPE(node->object) != ACPI_DESC_TYPE_OPERAND)
268 && (ACPI_GET_DESCRIPTOR_TYPE(node->object) !=
269 ACPI_DESC_TYPE_NAMED))
270 || (ACPI_GET_OBJECT_TYPE(node->object) == ACPI_TYPE_LOCAL_DATA)) {
271 return_PTR(NULL);
272 }
273
274 return_PTR(node->object);
275}
276
277/*******************************************************************************
278 *
279 * FUNCTION: acpi_ns_get_secondary_object
280 *
281 * PARAMETERS: Node - Namespace node
282 *
283 * RETURN: Current value of the object field from the Node whose
284 * handle is passed.
285 *
286 * DESCRIPTION: Obtain a secondary object associated with a namespace node.
287 *
288 ******************************************************************************/
289
290union acpi_operand_object *acpi_ns_get_secondary_object(union
291 acpi_operand_object
292 *obj_desc)
293{
294 ACPI_FUNCTION_TRACE_PTR(ns_get_secondary_object, obj_desc);
295
296 if ((!obj_desc) ||
297 (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_DATA) ||
298 (!obj_desc->common.next_object) ||
299 (ACPI_GET_OBJECT_TYPE(obj_desc->common.next_object) ==
300 ACPI_TYPE_LOCAL_DATA)) {
301 return_PTR(NULL);
302 }
303
304 return_PTR(obj_desc->common.next_object);
305}
306
307/*******************************************************************************
308 *
309 * FUNCTION: acpi_ns_attach_data
310 *
311 * PARAMETERS: Node - Namespace node
312 * Handler - Handler to be associated with the data
313 * Data - Data to be attached
314 *
315 * RETURN: Status
316 *
317 * DESCRIPTION: Low-level attach data. Create and attach a Data object.
318 *
319 ******************************************************************************/
320
321acpi_status
322acpi_ns_attach_data(struct acpi_namespace_node *node,
323 acpi_object_handler handler, void *data)
324{
325 union acpi_operand_object *prev_obj_desc;
326 union acpi_operand_object *obj_desc;
327 union acpi_operand_object *data_desc;
328
329 /* We only allow one attachment per handler */
330
331 prev_obj_desc = NULL;
332 obj_desc = node->object;
333 while (obj_desc) {
334 if ((ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_DATA) &&
335 (obj_desc->data.handler == handler)) {
336 return (AE_ALREADY_EXISTS);
337 }
338
339 prev_obj_desc = obj_desc;
340 obj_desc = obj_desc->common.next_object;
341 }
342
343 /* Create an internal object for the data */
344
345 data_desc = acpi_ut_create_internal_object(ACPI_TYPE_LOCAL_DATA);
346 if (!data_desc) {
347 return (AE_NO_MEMORY);
348 }
349
350 data_desc->data.handler = handler;
351 data_desc->data.pointer = data;
352
353 /* Install the data object */
354
355 if (prev_obj_desc) {
356 prev_obj_desc->common.next_object = data_desc;
357 } else {
358 node->object = data_desc;
359 }
360
361 return (AE_OK);
362}
363
364/*******************************************************************************
365 *
366 * FUNCTION: acpi_ns_detach_data
367 *
368 * PARAMETERS: Node - Namespace node
369 * Handler - Handler associated with the data
370 *
371 * RETURN: Status
372 *
373 * DESCRIPTION: Low-level detach data. Delete the data node, but the caller
374 * is responsible for the actual data.
375 *
376 ******************************************************************************/
377
378acpi_status
379acpi_ns_detach_data(struct acpi_namespace_node * node,
380 acpi_object_handler handler)
381{
382 union acpi_operand_object *obj_desc;
383 union acpi_operand_object *prev_obj_desc;
384
385 prev_obj_desc = NULL;
386 obj_desc = node->object;
387 while (obj_desc) {
388 if ((ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_DATA) &&
389 (obj_desc->data.handler == handler)) {
390 if (prev_obj_desc) {
391 prev_obj_desc->common.next_object =
392 obj_desc->common.next_object;
393 } else {
394 node->object = obj_desc->common.next_object;
395 }
396
397 acpi_ut_remove_reference(obj_desc);
398 return (AE_OK);
399 }
400
401 prev_obj_desc = obj_desc;
402 obj_desc = obj_desc->common.next_object;
403 }
404
405 return (AE_NOT_FOUND);
406}
407
408/*******************************************************************************
409 *
410 * FUNCTION: acpi_ns_get_attached_data
411 *
412 * PARAMETERS: Node - Namespace node
413 * Handler - Handler associated with the data
414 * Data - Where the data is returned
415 *
416 * RETURN: Status
417 *
418 * DESCRIPTION: Low level interface to obtain data previously associated with
419 * a namespace node.
420 *
421 ******************************************************************************/
422
423acpi_status
424acpi_ns_get_attached_data(struct acpi_namespace_node * node,
425 acpi_object_handler handler, void **data)
426{
427 union acpi_operand_object *obj_desc;
428
429 obj_desc = node->object;
430 while (obj_desc) {
431 if ((ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_DATA) &&
432 (obj_desc->data.handler == handler)) {
433 *data = obj_desc->data.pointer;
434 return (AE_OK);
435 }
436
437 obj_desc = obj_desc->common.next_object;
438 }
439
440 return (AE_NOT_FOUND);
441}
diff --git a/drivers/acpi/acpica/nsparse.c b/drivers/acpi/acpica/nsparse.c
new file mode 100644
index 00000000000..bcfcf427c90
--- /dev/null
+++ b/drivers/acpi/acpica/nsparse.c
@@ -0,0 +1,204 @@
1/******************************************************************************
2 *
3 * Module Name: nsparse - namespace interface to AML parser
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46#include <acpi/acnamesp.h>
47#include <acpi/acparser.h>
48#include <acpi/acdispat.h>
49#include <acpi/actables.h>
50
51#define _COMPONENT ACPI_NAMESPACE
52ACPI_MODULE_NAME("nsparse")
53
54/*******************************************************************************
55 *
56 * FUNCTION: ns_one_complete_parse
57 *
58 * PARAMETERS: pass_number - 1 or 2
59 * table_desc - The table to be parsed.
60 *
61 * RETURN: Status
62 *
63 * DESCRIPTION: Perform one complete parse of an ACPI/AML table.
64 *
65 ******************************************************************************/
66acpi_status
67acpi_ns_one_complete_parse(u32 pass_number,
68 u32 table_index,
69 struct acpi_namespace_node *start_node)
70{
71 union acpi_parse_object *parse_root;
72 acpi_status status;
73 u32 aml_length;
74 u8 *aml_start;
75 struct acpi_walk_state *walk_state;
76 struct acpi_table_header *table;
77 acpi_owner_id owner_id;
78
79 ACPI_FUNCTION_TRACE(ns_one_complete_parse);
80
81 status = acpi_tb_get_owner_id(table_index, &owner_id);
82 if (ACPI_FAILURE(status)) {
83 return_ACPI_STATUS(status);
84 }
85
86 /* Create and init a Root Node */
87
88 parse_root = acpi_ps_create_scope_op();
89 if (!parse_root) {
90 return_ACPI_STATUS(AE_NO_MEMORY);
91 }
92
93 /* Create and initialize a new walk state */
94
95 walk_state = acpi_ds_create_walk_state(owner_id, NULL, NULL, NULL);
96 if (!walk_state) {
97 acpi_ps_free_op(parse_root);
98 return_ACPI_STATUS(AE_NO_MEMORY);
99 }
100
101 status = acpi_get_table_by_index(table_index, &table);
102 if (ACPI_FAILURE(status)) {
103 acpi_ds_delete_walk_state(walk_state);
104 acpi_ps_free_op(parse_root);
105 return_ACPI_STATUS(status);
106 }
107
108 /* Table must consist of at least a complete header */
109
110 if (table->length < sizeof(struct acpi_table_header)) {
111 status = AE_BAD_HEADER;
112 } else {
113 aml_start = (u8 *) table + sizeof(struct acpi_table_header);
114 aml_length = table->length - sizeof(struct acpi_table_header);
115 status = acpi_ds_init_aml_walk(walk_state, parse_root, NULL,
116 aml_start, aml_length, NULL,
117 (u8) pass_number);
118 }
119
120 if (ACPI_FAILURE(status)) {
121 acpi_ds_delete_walk_state(walk_state);
122 goto cleanup;
123 }
124
125 /* start_node is the default location to load the table */
126
127 if (start_node && start_node != acpi_gbl_root_node) {
128 status =
129 acpi_ds_scope_stack_push(start_node, ACPI_TYPE_METHOD,
130 walk_state);
131 if (ACPI_FAILURE(status)) {
132 acpi_ds_delete_walk_state(walk_state);
133 goto cleanup;
134 }
135 }
136
137 /* Parse the AML */
138
139 ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "*PARSE* pass %d parse\n",
140 (unsigned)pass_number));
141 status = acpi_ps_parse_aml(walk_state);
142
143 cleanup:
144 acpi_ps_delete_parse_tree(parse_root);
145 return_ACPI_STATUS(status);
146}
147
148/*******************************************************************************
149 *
150 * FUNCTION: acpi_ns_parse_table
151 *
152 * PARAMETERS: table_desc - An ACPI table descriptor for table to parse
153 * start_node - Where to enter the table into the namespace
154 *
155 * RETURN: Status
156 *
157 * DESCRIPTION: Parse AML within an ACPI table and return a tree of ops
158 *
159 ******************************************************************************/
160
161acpi_status
162acpi_ns_parse_table(u32 table_index, struct acpi_namespace_node *start_node)
163{
164 acpi_status status;
165
166 ACPI_FUNCTION_TRACE(ns_parse_table);
167
168 /*
169 * AML Parse, pass 1
170 *
171 * In this pass, we load most of the namespace. Control methods
172 * are not parsed until later. A parse tree is not created. Instead,
173 * each Parser Op subtree is deleted when it is finished. This saves
174 * a great deal of memory, and allows a small cache of parse objects
175 * to service the entire parse. The second pass of the parse then
176 * performs another complete parse of the AML.
177 */
178 ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 1\n"));
179 status =
180 acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS1, table_index,
181 start_node);
182 if (ACPI_FAILURE(status)) {
183 return_ACPI_STATUS(status);
184 }
185
186 /*
187 * AML Parse, pass 2
188 *
189 * In this pass, we resolve forward references and other things
190 * that could not be completed during the first pass.
191 * Another complete parse of the AML is performed, but the
192 * overhead of this is compensated for by the fact that the
193 * parse objects are all cached.
194 */
195 ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 2\n"));
196 status =
197 acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS2, table_index,
198 start_node);
199 if (ACPI_FAILURE(status)) {
200 return_ACPI_STATUS(status);
201 }
202
203 return_ACPI_STATUS(status);
204}
diff --git a/drivers/acpi/acpica/nspredef.c b/drivers/acpi/acpica/nspredef.c
new file mode 100644
index 00000000000..1e682d03f62
--- /dev/null
+++ b/drivers/acpi/acpica/nspredef.c
@@ -0,0 +1,1065 @@
1/******************************************************************************
2 *
3 * Module Name: nspredef - Validation of ACPI predefined methods and objects
4 * $Revision: 1.1 $
5 *
6 *****************************************************************************/
7
8/*
9 * Copyright (C) 2000 - 2008, Intel Corp.
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions, and the following disclaimer,
17 * without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 * substantially similar to the "NO WARRANTY" disclaimer below
20 * ("Disclaimer") and any redistribution must be conditioned upon
21 * including a substantially similar Disclaimer requirement for further
22 * binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 * of any contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
30 *
31 * NO WARRANTY
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
43 */
44
45#include <acpi/acpi.h>
46#include <acpi/accommon.h>
47#include <acpi/acnamesp.h>
48#include <acpi/acpredef.h>
49
50#define _COMPONENT ACPI_NAMESPACE
51ACPI_MODULE_NAME("nspredef")
52
53/*******************************************************************************
54 *
55 * This module validates predefined ACPI objects that appear in the namespace,
56 * at the time they are evaluated (via acpi_evaluate_object). The purpose of this
57 * validation is to detect problems with BIOS-exposed predefined ACPI objects
58 * before the results are returned to the ACPI-related drivers.
59 *
60 * There are several areas that are validated:
61 *
62 * 1) The number of input arguments as defined by the method/object in the
63 * ASL is validated against the ACPI specification.
64 * 2) The type of the return object (if any) is validated against the ACPI
65 * specification.
66 * 3) For returned package objects, the count of package elements is
67 * validated, as well as the type of each package element. Nested
68 * packages are supported.
69 *
70 * For any problems found, a warning message is issued.
71 *
72 ******************************************************************************/
73/* Local prototypes */
74static acpi_status
75acpi_ns_check_package(char *pathname,
76 union acpi_operand_object **return_object_ptr,
77 const union acpi_predefined_info *predefined);
78
79static acpi_status
80acpi_ns_check_package_elements(char *pathname,
81 union acpi_operand_object **elements,
82 u8 type1, u32 count1, u8 type2, u32 count2);
83
84static acpi_status
85acpi_ns_check_object_type(char *pathname,
86 union acpi_operand_object **return_object_ptr,
87 u32 expected_btypes, u32 package_index);
88
89static acpi_status
90acpi_ns_check_reference(char *pathname,
91 union acpi_operand_object *return_object);
92
93static acpi_status
94acpi_ns_repair_object(u32 expected_btypes,
95 u32 package_index,
96 union acpi_operand_object **return_object_ptr);
97
98/*
99 * Names for the types that can be returned by the predefined objects.
100 * Used for warning messages. Must be in the same order as the ACPI_RTYPEs
101 */
102static const char *acpi_rtype_names[] = {
103 "/Integer",
104 "/String",
105 "/Buffer",
106 "/Package",
107 "/Reference",
108};
109
110#define ACPI_NOT_PACKAGE ACPI_UINT32_MAX
111
112/*******************************************************************************
113 *
114 * FUNCTION: acpi_ns_check_predefined_names
115 *
116 * PARAMETERS: Node - Namespace node for the method/object
117 * return_object_ptr - Pointer to the object returned from the
118 * evaluation of a method or object
119 *
120 * RETURN: Status
121 *
122 * DESCRIPTION: Check an ACPI name for a match in the predefined name list.
123 *
124 ******************************************************************************/
125
126acpi_status
127acpi_ns_check_predefined_names(struct acpi_namespace_node *node,
128 u32 user_param_count,
129 acpi_status return_status,
130 union acpi_operand_object **return_object_ptr)
131{
132 union acpi_operand_object *return_object = *return_object_ptr;
133 acpi_status status = AE_OK;
134 const union acpi_predefined_info *predefined;
135 char *pathname;
136
137 /* Match the name for this method/object against the predefined list */
138
139 predefined = acpi_ns_check_for_predefined_name(node);
140
141 /* Get the full pathname to the object, for use in error messages */
142
143 pathname = acpi_ns_get_external_pathname(node);
144 if (!pathname) {
145 pathname = ACPI_CAST_PTR(char, predefined->info.name);
146 }
147
148 /*
149 * Check that the parameter count for this method matches the ASL
150 * definition. For predefined names, ensure that both the caller and
151 * the method itself are in accordance with the ACPI specification.
152 */
153 acpi_ns_check_parameter_count(pathname, node, user_param_count,
154 predefined);
155
156 /* If not a predefined name, we cannot validate the return object */
157
158 if (!predefined) {
159 goto exit;
160 }
161
162 /* If the method failed, we cannot validate the return object */
163
164 if ((return_status != AE_OK) && (return_status != AE_CTRL_RETURN_VALUE)) {
165 goto exit;
166 }
167
168 /*
169 * Only validate the return value on the first successful evaluation of
170 * the method. This ensures that any warnings will only be emitted during
171 * the very first evaluation of the method/object.
172 */
173 if (node->flags & ANOBJ_EVALUATED) {
174 goto exit;
175 }
176
177 /* Mark the node as having been successfully evaluated */
178
179 node->flags |= ANOBJ_EVALUATED;
180
181 /*
182 * If there is no return value, check if we require a return value for
183 * this predefined name. Either one return value is expected, or none,
184 * for both methods and other objects.
185 *
186 * Exit now if there is no return object. Warning if one was expected.
187 */
188 if (!return_object) {
189 if ((predefined->info.expected_btypes) &&
190 (!(predefined->info.expected_btypes & ACPI_RTYPE_NONE))) {
191 ACPI_ERROR((AE_INFO,
192 "%s: Missing expected return value",
193 pathname));
194
195 status = AE_AML_NO_RETURN_VALUE;
196 }
197 goto exit;
198 }
199
200 /*
201 * We have a return value, but if one wasn't expected, just exit, this is
202 * not a problem
203 *
204 * For example, if the "Implicit Return" feature is enabled, methods will
205 * always return a value
206 */
207 if (!predefined->info.expected_btypes) {
208 goto exit;
209 }
210
211 /*
212 * Check that the type of the return object is what is expected for
213 * this predefined name
214 */
215 status = acpi_ns_check_object_type(pathname, return_object_ptr,
216 predefined->info.expected_btypes,
217 ACPI_NOT_PACKAGE);
218 if (ACPI_FAILURE(status)) {
219 goto exit;
220 }
221
222 /* For returned Package objects, check the type of all sub-objects */
223
224 if (ACPI_GET_OBJECT_TYPE(return_object) == ACPI_TYPE_PACKAGE) {
225 status =
226 acpi_ns_check_package(pathname, return_object_ptr,
227 predefined);
228 }
229
230 exit:
231 if (pathname != predefined->info.name) {
232 ACPI_FREE(pathname);
233 }
234
235 return (status);
236}
237
238/*******************************************************************************
239 *
240 * FUNCTION: acpi_ns_check_parameter_count
241 *
242 * PARAMETERS: Pathname - Full pathname to the node (for error msgs)
243 * Node - Namespace node for the method/object
244 * user_param_count - Number of args passed in by the caller
245 * Predefined - Pointer to entry in predefined name table
246 *
247 * RETURN: None
248 *
249 * DESCRIPTION: Check that the declared (in ASL/AML) parameter count for a
250 * predefined name is what is expected (i.e., what is defined in
251 * the ACPI specification for this predefined name.)
252 *
253 ******************************************************************************/
254
255void
256acpi_ns_check_parameter_count(char *pathname,
257 struct acpi_namespace_node *node,
258 u32 user_param_count,
259 const union acpi_predefined_info *predefined)
260{
261 u32 param_count;
262 u32 required_params_current;
263 u32 required_params_old;
264
265 /* Methods have 0-7 parameters. All other types have zero. */
266
267 param_count = 0;
268 if (node->type == ACPI_TYPE_METHOD) {
269 param_count = node->object->method.param_count;
270 }
271
272 /* Argument count check for non-predefined methods/objects */
273
274 if (!predefined) {
275 /*
276 * Warning if too few or too many arguments have been passed by the
277 * caller. An incorrect number of arguments may not cause the method
278 * to fail. However, the method will fail if there are too few
279 * arguments and the method attempts to use one of the missing ones.
280 */
281 if (user_param_count < param_count) {
282 ACPI_WARNING((AE_INFO,
283 "%s: Insufficient arguments - needs %d, found %d",
284 pathname, param_count, user_param_count));
285 } else if (user_param_count > param_count) {
286 ACPI_WARNING((AE_INFO,
287 "%s: Excess arguments - needs %d, found %d",
288 pathname, param_count, user_param_count));
289 }
290 return;
291 }
292
293 /* Allow two different legal argument counts (_SCP, etc.) */
294
295 required_params_current = predefined->info.param_count & 0x0F;
296 required_params_old = predefined->info.param_count >> 4;
297
298 if (user_param_count != ACPI_UINT32_MAX) {
299
300 /* Validate the user-supplied parameter count */
301
302 if ((user_param_count != required_params_current) &&
303 (user_param_count != required_params_old)) {
304 ACPI_WARNING((AE_INFO,
305 "%s: Parameter count mismatch - caller passed %d, ACPI requires %d",
306 pathname, user_param_count,
307 required_params_current));
308 }
309 }
310
311 /*
312 * Only validate the argument count on the first successful evaluation of
313 * the method. This ensures that any warnings will only be emitted during
314 * the very first evaluation of the method/object.
315 */
316 if (node->flags & ANOBJ_EVALUATED) {
317 return;
318 }
319
320 /*
321 * Check that the ASL-defined parameter count is what is expected for
322 * this predefined name.
323 */
324 if ((param_count != required_params_current) &&
325 (param_count != required_params_old)) {
326 ACPI_WARNING((AE_INFO,
327 "%s: Parameter count mismatch - ASL declared %d, ACPI requires %d",
328 pathname, param_count, required_params_current));
329 }
330}
331
332/*******************************************************************************
333 *
334 * FUNCTION: acpi_ns_check_for_predefined_name
335 *
336 * PARAMETERS: Node - Namespace node for the method/object
337 *
338 * RETURN: Pointer to entry in predefined table. NULL indicates not found.
339 *
340 * DESCRIPTION: Check an object name against the predefined object list.
341 *
342 ******************************************************************************/
343
344const union acpi_predefined_info *acpi_ns_check_for_predefined_name(struct
345 acpi_namespace_node
346 *node)
347{
348 const union acpi_predefined_info *this_name;
349
350 /* Quick check for a predefined name, first character must be underscore */
351
352 if (node->name.ascii[0] != '_') {
353 return (NULL);
354 }
355
356 /* Search info table for a predefined method/object name */
357
358 this_name = predefined_names;
359 while (this_name->info.name[0]) {
360 if (ACPI_COMPARE_NAME(node->name.ascii, this_name->info.name)) {
361
362 /* Return pointer to this table entry */
363
364 return (this_name);
365 }
366
367 /*
368 * Skip next entry in the table if this name returns a Package
369 * (next entry contains the package info)
370 */
371 if (this_name->info.expected_btypes & ACPI_RTYPE_PACKAGE) {
372 this_name++;
373 }
374
375 this_name++;
376 }
377
378 return (NULL);
379}
380
381/*******************************************************************************
382 *
383 * FUNCTION: acpi_ns_check_package
384 *
385 * PARAMETERS: Pathname - Full pathname to the node (for error msgs)
386 * return_object_ptr - Pointer to the object returned from the
387 * evaluation of a method or object
388 * Predefined - Pointer to entry in predefined name table
389 *
390 * RETURN: Status
391 *
392 * DESCRIPTION: Check a returned package object for the correct count and
393 * correct type of all sub-objects.
394 *
395 ******************************************************************************/
396
397static acpi_status
398acpi_ns_check_package(char *pathname,
399 union acpi_operand_object **return_object_ptr,
400 const union acpi_predefined_info *predefined)
401{
402 union acpi_operand_object *return_object = *return_object_ptr;
403 const union acpi_predefined_info *package;
404 union acpi_operand_object *sub_package;
405 union acpi_operand_object **elements;
406 union acpi_operand_object **sub_elements;
407 acpi_status status;
408 u32 expected_count;
409 u32 count;
410 u32 i;
411 u32 j;
412
413 ACPI_FUNCTION_NAME(ns_check_package);
414
415 /* The package info for this name is in the next table entry */
416
417 package = predefined + 1;
418
419 ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
420 "%s Validating return Package of Type %X, Count %X\n",
421 pathname, package->ret_info.type,
422 return_object->package.count));
423
424 /* Extract package count and elements array */
425
426 elements = return_object->package.elements;
427 count = return_object->package.count;
428
429 /* The package must have at least one element, else invalid */
430
431 if (!count) {
432 ACPI_WARNING((AE_INFO,
433 "%s: Return Package has no elements (empty)",
434 pathname));
435
436 return (AE_AML_OPERAND_VALUE);
437 }
438
439 /*
440 * Decode the type of the expected package contents
441 *
442 * PTYPE1 packages contain no subpackages
443 * PTYPE2 packages contain sub-packages
444 */
445 switch (package->ret_info.type) {
446 case ACPI_PTYPE1_FIXED:
447
448 /*
449 * The package count is fixed and there are no sub-packages
450 *
451 * If package is too small, exit.
452 * If package is larger than expected, issue warning but continue
453 */
454 expected_count =
455 package->ret_info.count1 + package->ret_info.count2;
456 if (count < expected_count) {
457 goto package_too_small;
458 } else if (count > expected_count) {
459 ACPI_WARNING((AE_INFO,
460 "%s: Return Package is larger than needed - "
461 "found %u, expected %u", pathname, count,
462 expected_count));
463 }
464
465 /* Validate all elements of the returned package */
466
467 status = acpi_ns_check_package_elements(pathname, elements,
468 package->ret_info.
469 object_type1,
470 package->ret_info.
471 count1,
472 package->ret_info.
473 object_type2,
474 package->ret_info.
475 count2);
476 if (ACPI_FAILURE(status)) {
477 return (status);
478 }
479 break;
480
481 case ACPI_PTYPE1_VAR:
482
483 /*
484 * The package count is variable, there are no sub-packages, and all
485 * elements must be of the same type
486 */
487 for (i = 0; i < count; i++) {
488 status = acpi_ns_check_object_type(pathname, elements,
489 package->ret_info.
490 object_type1, i);
491 if (ACPI_FAILURE(status)) {
492 return (status);
493 }
494 elements++;
495 }
496 break;
497
498 case ACPI_PTYPE1_OPTION:
499
500 /*
501 * The package count is variable, there are no sub-packages. There are
502 * a fixed number of required elements, and a variable number of
503 * optional elements.
504 *
505 * Check if package is at least as large as the minimum required
506 */
507 expected_count = package->ret_info3.count;
508 if (count < expected_count) {
509 goto package_too_small;
510 }
511
512 /* Variable number of sub-objects */
513
514 for (i = 0; i < count; i++) {
515 if (i < package->ret_info3.count) {
516
517 /* These are the required package elements (0, 1, or 2) */
518
519 status =
520 acpi_ns_check_object_type(pathname,
521 elements,
522 package->
523 ret_info3.
524 object_type[i],
525 i);
526 if (ACPI_FAILURE(status)) {
527 return (status);
528 }
529 } else {
530 /* These are the optional package elements */
531
532 status =
533 acpi_ns_check_object_type(pathname,
534 elements,
535 package->
536 ret_info3.
537 tail_object_type,
538 i);
539 if (ACPI_FAILURE(status)) {
540 return (status);
541 }
542 }
543 elements++;
544 }
545 break;
546
547 case ACPI_PTYPE2_PKG_COUNT:
548
549 /* First element is the (Integer) count of sub-packages to follow */
550
551 status = acpi_ns_check_object_type(pathname, elements,
552 ACPI_RTYPE_INTEGER, 0);
553 if (ACPI_FAILURE(status)) {
554 return (status);
555 }
556
557 /*
558 * Count cannot be larger than the parent package length, but allow it
559 * to be smaller. The >= accounts for the Integer above.
560 */
561 expected_count = (u32) (*elements)->integer.value;
562 if (expected_count >= count) {
563 goto package_too_small;
564 }
565
566 count = expected_count;
567 elements++;
568
569 /* Now we can walk the sub-packages */
570
571 /*lint -fallthrough */
572
573 case ACPI_PTYPE2:
574 case ACPI_PTYPE2_FIXED:
575 case ACPI_PTYPE2_MIN:
576 case ACPI_PTYPE2_COUNT:
577
578 /*
579 * These types all return a single package that consists of a variable
580 * number of sub-packages
581 */
582 for (i = 0; i < count; i++) {
583 sub_package = *elements;
584 sub_elements = sub_package->package.elements;
585
586 /* Each sub-object must be of type Package */
587
588 status =
589 acpi_ns_check_object_type(pathname, &sub_package,
590 ACPI_RTYPE_PACKAGE, i);
591 if (ACPI_FAILURE(status)) {
592 return (status);
593 }
594
595 /* Examine the different types of sub-packages */
596
597 switch (package->ret_info.type) {
598 case ACPI_PTYPE2:
599 case ACPI_PTYPE2_PKG_COUNT:
600
601 /* Each subpackage has a fixed number of elements */
602
603 expected_count =
604 package->ret_info.count1 +
605 package->ret_info.count2;
606 if (sub_package->package.count !=
607 expected_count) {
608 count = sub_package->package.count;
609 goto package_too_small;
610 }
611
612 status =
613 acpi_ns_check_package_elements(pathname,
614 sub_elements,
615 package->
616 ret_info.
617 object_type1,
618 package->
619 ret_info.
620 count1,
621 package->
622 ret_info.
623 object_type2,
624 package->
625 ret_info.
626 count2);
627 if (ACPI_FAILURE(status)) {
628 return (status);
629 }
630 break;
631
632 case ACPI_PTYPE2_FIXED:
633
634 /* Each sub-package has a fixed length */
635
636 expected_count = package->ret_info2.count;
637 if (sub_package->package.count < expected_count) {
638 count = sub_package->package.count;
639 goto package_too_small;
640 }
641
642 /* Check the type of each sub-package element */
643
644 for (j = 0; j < expected_count; j++) {
645 status =
646 acpi_ns_check_object_type(pathname,
647 &sub_elements[j],
648 package->ret_info2.object_type[j], j);
649 if (ACPI_FAILURE(status)) {
650 return (status);
651 }
652 }
653 break;
654
655 case ACPI_PTYPE2_MIN:
656
657 /* Each sub-package has a variable but minimum length */
658
659 expected_count = package->ret_info.count1;
660 if (sub_package->package.count < expected_count) {
661 count = sub_package->package.count;
662 goto package_too_small;
663 }
664
665 /* Check the type of each sub-package element */
666
667 status =
668 acpi_ns_check_package_elements(pathname,
669 sub_elements,
670 package->
671 ret_info.
672 object_type1,
673 sub_package->
674 package.
675 count, 0, 0);
676 if (ACPI_FAILURE(status)) {
677 return (status);
678 }
679 break;
680
681 case ACPI_PTYPE2_COUNT:
682
683 /* First element is the (Integer) count of elements to follow */
684
685 status =
686 acpi_ns_check_object_type(pathname,
687 sub_elements,
688 ACPI_RTYPE_INTEGER,
689 0);
690 if (ACPI_FAILURE(status)) {
691 return (status);
692 }
693
694 /* Make sure package is large enough for the Count */
695
696 expected_count =
697 (u32) (*sub_elements)->integer.value;
698 if (sub_package->package.count < expected_count) {
699 count = sub_package->package.count;
700 goto package_too_small;
701 }
702
703 /* Check the type of each sub-package element */
704
705 status =
706 acpi_ns_check_package_elements(pathname,
707 (sub_elements
708 + 1),
709 package->
710 ret_info.
711 object_type1,
712 (expected_count
713 - 1), 0, 0);
714 if (ACPI_FAILURE(status)) {
715 return (status);
716 }
717 break;
718
719 default:
720 break;
721 }
722
723 elements++;
724 }
725 break;
726
727 default:
728
729 /* Should not get here if predefined info table is correct */
730
731 ACPI_WARNING((AE_INFO,
732 "%s: Invalid internal return type in table entry: %X",
733 pathname, package->ret_info.type));
734
735 return (AE_AML_INTERNAL);
736 }
737
738 return (AE_OK);
739
740 package_too_small:
741
742 /* Error exit for the case with an incorrect package count */
743
744 ACPI_WARNING((AE_INFO, "%s: Return Package is too small - "
745 "found %u, expected %u", pathname, count,
746 expected_count));
747
748 return (AE_AML_OPERAND_VALUE);
749}
750
751/*******************************************************************************
752 *
753 * FUNCTION: acpi_ns_check_package_elements
754 *
755 * PARAMETERS: Pathname - Full pathname to the node (for error msgs)
756 * Elements - Pointer to the package elements array
757 * Type1 - Object type for first group
758 * Count1 - Count for first group
759 * Type2 - Object type for second group
760 * Count2 - Count for second group
761 *
762 * RETURN: Status
763 *
764 * DESCRIPTION: Check that all elements of a package are of the correct object
765 * type. Supports up to two groups of different object types.
766 *
767 ******************************************************************************/
768
769static acpi_status
770acpi_ns_check_package_elements(char *pathname,
771 union acpi_operand_object **elements,
772 u8 type1, u32 count1, u8 type2, u32 count2)
773{
774 union acpi_operand_object **this_element = elements;
775 acpi_status status;
776 u32 i;
777
778 /*
779 * Up to two groups of package elements are supported by the data
780 * structure. All elements in each group must be of the same type.
781 * The second group can have a count of zero.
782 */
783 for (i = 0; i < count1; i++) {
784 status = acpi_ns_check_object_type(pathname, this_element,
785 type1, i);
786 if (ACPI_FAILURE(status)) {
787 return (status);
788 }
789 this_element++;
790 }
791
792 for (i = 0; i < count2; i++) {
793 status = acpi_ns_check_object_type(pathname, this_element,
794 type2, (i + count1));
795 if (ACPI_FAILURE(status)) {
796 return (status);
797 }
798 this_element++;
799 }
800
801 return (AE_OK);
802}
803
804/*******************************************************************************
805 *
806 * FUNCTION: acpi_ns_check_object_type
807 *
808 * PARAMETERS: Pathname - Full pathname to the node (for error msgs)
809 * return_object_ptr - Pointer to the object returned from the
810 * evaluation of a method or object
811 * expected_btypes - Bitmap of expected return type(s)
812 * package_index - Index of object within parent package (if
813 * applicable - ACPI_NOT_PACKAGE otherwise)
814 *
815 * RETURN: Status
816 *
817 * DESCRIPTION: Check the type of the return object against the expected object
818 * type(s). Use of Btype allows multiple expected object types.
819 *
820 ******************************************************************************/
821
822static acpi_status
823acpi_ns_check_object_type(char *pathname,
824 union acpi_operand_object **return_object_ptr,
825 u32 expected_btypes, u32 package_index)
826{
827 union acpi_operand_object *return_object = *return_object_ptr;
828 acpi_status status = AE_OK;
829 u32 return_btype;
830 char type_buffer[48]; /* Room for 5 types */
831 u32 this_rtype;
832 u32 i;
833 u32 j;
834
835 /*
836 * If we get a NULL return_object here, it is a NULL package element,
837 * and this is always an error.
838 */
839 if (!return_object) {
840 goto type_error_exit;
841 }
842
843 /* A Namespace node should not get here, but make sure */
844
845 if (ACPI_GET_DESCRIPTOR_TYPE(return_object) == ACPI_DESC_TYPE_NAMED) {
846 ACPI_WARNING((AE_INFO,
847 "%s: Invalid return type - Found a Namespace node [%4.4s] type %s",
848 pathname, return_object->node.name.ascii,
849 acpi_ut_get_type_name(return_object->node.type)));
850 return (AE_AML_OPERAND_TYPE);
851 }
852
853 /*
854 * Convert the object type (ACPI_TYPE_xxx) to a bitmapped object type.
855 * The bitmapped type allows multiple possible return types.
856 *
857 * Note, the cases below must handle all of the possible types returned
858 * from all of the predefined names (including elements of returned
859 * packages)
860 */
861 switch (ACPI_GET_OBJECT_TYPE(return_object)) {
862 case ACPI_TYPE_INTEGER:
863 return_btype = ACPI_RTYPE_INTEGER;
864 break;
865
866 case ACPI_TYPE_BUFFER:
867 return_btype = ACPI_RTYPE_BUFFER;
868 break;
869
870 case ACPI_TYPE_STRING:
871 return_btype = ACPI_RTYPE_STRING;
872 break;
873
874 case ACPI_TYPE_PACKAGE:
875 return_btype = ACPI_RTYPE_PACKAGE;
876 break;
877
878 case ACPI_TYPE_LOCAL_REFERENCE:
879 return_btype = ACPI_RTYPE_REFERENCE;
880 break;
881
882 default:
883 /* Not one of the supported objects, must be incorrect */
884
885 goto type_error_exit;
886 }
887
888 /* Is the object one of the expected types? */
889
890 if (!(return_btype & expected_btypes)) {
891
892 /* Type mismatch -- attempt repair of the returned object */
893
894 status = acpi_ns_repair_object(expected_btypes, package_index,
895 return_object_ptr);
896 if (ACPI_SUCCESS(status)) {
897 return (status);
898 }
899 goto type_error_exit;
900 }
901
902 /* For reference objects, check that the reference type is correct */
903
904 if (ACPI_GET_OBJECT_TYPE(return_object) == ACPI_TYPE_LOCAL_REFERENCE) {
905 status = acpi_ns_check_reference(pathname, return_object);
906 }
907
908 return (status);
909
910 type_error_exit:
911
912 /* Create a string with all expected types for this predefined object */
913
914 j = 1;
915 type_buffer[0] = 0;
916 this_rtype = ACPI_RTYPE_INTEGER;
917
918 for (i = 0; i < ACPI_NUM_RTYPES; i++) {
919
920 /* If one of the expected types, concatenate the name of this type */
921
922 if (expected_btypes & this_rtype) {
923 ACPI_STRCAT(type_buffer, &acpi_rtype_names[i][j]);
924 j = 0; /* Use name separator from now on */
925 }
926 this_rtype <<= 1; /* Next Rtype */
927 }
928
929 if (package_index == ACPI_NOT_PACKAGE) {
930 ACPI_WARNING((AE_INFO,
931 "%s: Return type mismatch - found %s, expected %s",
932 pathname,
933 acpi_ut_get_object_type_name(return_object),
934 type_buffer));
935 } else {
936 ACPI_WARNING((AE_INFO,
937 "%s: Return Package type mismatch at index %u - "
938 "found %s, expected %s", pathname, package_index,
939 acpi_ut_get_object_type_name(return_object),
940 type_buffer));
941 }
942
943 return (AE_AML_OPERAND_TYPE);
944}
945
946/*******************************************************************************
947 *
948 * FUNCTION: acpi_ns_check_reference
949 *
950 * PARAMETERS: Pathname - Full pathname to the node (for error msgs)
951 * return_object - Object returned from the evaluation of a
952 * method or object
953 *
954 * RETURN: Status
955 *
956 * DESCRIPTION: Check a returned reference object for the correct reference
957 * type. The only reference type that can be returned from a
958 * predefined method is a named reference. All others are invalid.
959 *
960 ******************************************************************************/
961
962static acpi_status
963acpi_ns_check_reference(char *pathname,
964 union acpi_operand_object *return_object)
965{
966
967 /*
968 * Check the reference object for the correct reference type (opcode).
969 * The only type of reference that can be converted to an union acpi_object is
970 * a reference to a named object (reference class: NAME)
971 */
972 if (return_object->reference.class == ACPI_REFCLASS_NAME) {
973 return (AE_OK);
974 }
975
976 ACPI_WARNING((AE_INFO,
977 "%s: Return type mismatch - unexpected reference object type [%s] %2.2X",
978 pathname, acpi_ut_get_reference_name(return_object),
979 return_object->reference.class));
980
981 return (AE_AML_OPERAND_TYPE);
982}
983
984/*******************************************************************************
985 *
986 * FUNCTION: acpi_ns_repair_object
987 *
988 * PARAMETERS: Pathname - Full pathname to the node (for error msgs)
989 * package_index - Used to determine if target is in a package
990 * return_object_ptr - Pointer to the object returned from the
991 * evaluation of a method or object
992 *
993 * RETURN: Status. AE_OK if repair was successful.
994 *
995 * DESCRIPTION: Attempt to repair/convert a return object of a type that was
996 * not expected.
997 *
998 ******************************************************************************/
999
1000static acpi_status
1001acpi_ns_repair_object(u32 expected_btypes,
1002 u32 package_index,
1003 union acpi_operand_object **return_object_ptr)
1004{
1005 union acpi_operand_object *return_object = *return_object_ptr;
1006 union acpi_operand_object *new_object;
1007 acpi_size length;
1008
1009 switch (ACPI_GET_OBJECT_TYPE(return_object)) {
1010 case ACPI_TYPE_BUFFER:
1011
1012 if (!(expected_btypes & ACPI_RTYPE_STRING)) {
1013 return (AE_AML_OPERAND_TYPE);
1014 }
1015
1016 /*
1017 * Have a Buffer, expected a String, convert. Use a to_string
1018 * conversion, no transform performed on the buffer data. The best
1019 * example of this is the _BIF method, where the string data from
1020 * the battery is often (incorrectly) returned as buffer object(s).
1021 */
1022 length = 0;
1023 while ((length < return_object->buffer.length) &&
1024 (return_object->buffer.pointer[length])) {
1025 length++;
1026 }
1027
1028 /* Allocate a new string object */
1029
1030 new_object = acpi_ut_create_string_object(length);
1031 if (!new_object) {
1032 return (AE_NO_MEMORY);
1033 }
1034
1035 /*
1036 * Copy the raw buffer data with no transform. String is already NULL
1037 * terminated at Length+1.
1038 */
1039 ACPI_MEMCPY(new_object->string.pointer,
1040 return_object->buffer.pointer, length);
1041
1042 /* Install the new return object */
1043
1044 acpi_ut_remove_reference(return_object);
1045 *return_object_ptr = new_object;
1046
1047 /*
1048 * If the object is a package element, we need to:
1049 * 1. Decrement the reference count of the orignal object, it was
1050 * incremented when building the package
1051 * 2. Increment the reference count of the new object, it will be
1052 * decremented when releasing the package
1053 */
1054 if (package_index != ACPI_NOT_PACKAGE) {
1055 acpi_ut_remove_reference(return_object);
1056 acpi_ut_add_reference(new_object);
1057 }
1058 return (AE_OK);
1059
1060 default:
1061 break;
1062 }
1063
1064 return (AE_AML_OPERAND_TYPE);
1065}
diff --git a/drivers/acpi/acpica/nssearch.c b/drivers/acpi/acpica/nssearch.c
new file mode 100644
index 00000000000..a76c731e3ba
--- /dev/null
+++ b/drivers/acpi/acpica/nssearch.c
@@ -0,0 +1,415 @@
1/*******************************************************************************
2 *
3 * Module Name: nssearch - Namespace search
4 *
5 ******************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46#include <acpi/acnamesp.h>
47
48#define _COMPONENT ACPI_NAMESPACE
49ACPI_MODULE_NAME("nssearch")
50
51/* Local prototypes */
52static acpi_status
53acpi_ns_search_parent_tree(u32 target_name,
54 struct acpi_namespace_node *node,
55 acpi_object_type type,
56 struct acpi_namespace_node **return_node);
57
58/*******************************************************************************
59 *
60 * FUNCTION: acpi_ns_search_one_scope
61 *
62 * PARAMETERS: target_name - Ascii ACPI name to search for
63 * parent_node - Starting node where search will begin
64 * Type - Object type to match
65 * return_node - Where the matched Named obj is returned
66 *
67 * RETURN: Status
68 *
69 * DESCRIPTION: Search a single level of the namespace. Performs a
70 * simple search of the specified level, and does not add
71 * entries or search parents.
72 *
73 *
74 * Named object lists are built (and subsequently dumped) in the
75 * order in which the names are encountered during the namespace load;
76 *
77 * All namespace searching is linear in this implementation, but
78 * could be easily modified to support any improved search
79 * algorithm. However, the linear search was chosen for simplicity
80 * and because the trees are small and the other interpreter
81 * execution overhead is relatively high.
82 *
83 * Note: CPU execution analysis has shown that the AML interpreter spends
84 * a very small percentage of its time searching the namespace. Therefore,
85 * the linear search seems to be sufficient, as there would seem to be
86 * little value in improving the search.
87 *
88 ******************************************************************************/
89
90acpi_status
91acpi_ns_search_one_scope(u32 target_name,
92 struct acpi_namespace_node *parent_node,
93 acpi_object_type type,
94 struct acpi_namespace_node **return_node)
95{
96 struct acpi_namespace_node *node;
97
98 ACPI_FUNCTION_TRACE(ns_search_one_scope);
99
100#ifdef ACPI_DEBUG_OUTPUT
101 if (ACPI_LV_NAMES & acpi_dbg_level) {
102 char *scope_name;
103
104 scope_name = acpi_ns_get_external_pathname(parent_node);
105 if (scope_name) {
106 ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
107 "Searching %s (%p) For [%4.4s] (%s)\n",
108 scope_name, parent_node,
109 ACPI_CAST_PTR(char, &target_name),
110 acpi_ut_get_type_name(type)));
111
112 ACPI_FREE(scope_name);
113 }
114 }
115#endif
116
117 /*
118 * Search for name at this namespace level, which is to say that we
119 * must search for the name among the children of this object
120 */
121 node = parent_node->child;
122 while (node) {
123
124 /* Check for match against the name */
125
126 if (node->name.integer == target_name) {
127
128 /* Resolve a control method alias if any */
129
130 if (acpi_ns_get_type(node) ==
131 ACPI_TYPE_LOCAL_METHOD_ALIAS) {
132 node =
133 ACPI_CAST_PTR(struct acpi_namespace_node,
134 node->object);
135 }
136
137 /* Found matching entry */
138
139 ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
140 "Name [%4.4s] (%s) %p found in scope [%4.4s] %p\n",
141 ACPI_CAST_PTR(char, &target_name),
142 acpi_ut_get_type_name(node->type),
143 node,
144 acpi_ut_get_node_name(parent_node),
145 parent_node));
146
147 *return_node = node;
148 return_ACPI_STATUS(AE_OK);
149 }
150
151 /*
152 * The last entry in the list points back to the parent,
153 * so a flag is used to indicate the end-of-list
154 */
155 if (node->flags & ANOBJ_END_OF_PEER_LIST) {
156
157 /* Searched entire list, we are done */
158
159 break;
160 }
161
162 /* Didn't match name, move on to the next peer object */
163
164 node = node->peer;
165 }
166
167 /* Searched entire namespace level, not found */
168
169 ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
170 "Name [%4.4s] (%s) not found in search in scope [%4.4s] %p first child %p\n",
171 ACPI_CAST_PTR(char, &target_name),
172 acpi_ut_get_type_name(type),
173 acpi_ut_get_node_name(parent_node), parent_node,
174 parent_node->child));
175
176 return_ACPI_STATUS(AE_NOT_FOUND);
177}
178
179/*******************************************************************************
180 *
181 * FUNCTION: acpi_ns_search_parent_tree
182 *
183 * PARAMETERS: target_name - Ascii ACPI name to search for
184 * Node - Starting node where search will begin
185 * Type - Object type to match
186 * return_node - Where the matched Node is returned
187 *
188 * RETURN: Status
189 *
190 * DESCRIPTION: Called when a name has not been found in the current namespace
191 * level. Before adding it or giving up, ACPI scope rules require
192 * searching enclosing scopes in cases identified by acpi_ns_local().
193 *
194 * "A name is located by finding the matching name in the current
195 * name space, and then in the parent name space. If the parent
196 * name space does not contain the name, the search continues
197 * recursively until either the name is found or the name space
198 * does not have a parent (the root of the name space). This
199 * indicates that the name is not found" (From ACPI Specification,
200 * section 5.3)
201 *
202 ******************************************************************************/
203
204static acpi_status
205acpi_ns_search_parent_tree(u32 target_name,
206 struct acpi_namespace_node *node,
207 acpi_object_type type,
208 struct acpi_namespace_node **return_node)
209{
210 acpi_status status;
211 struct acpi_namespace_node *parent_node;
212
213 ACPI_FUNCTION_TRACE(ns_search_parent_tree);
214
215 parent_node = acpi_ns_get_parent_node(node);
216
217 /*
218 * If there is no parent (i.e., we are at the root) or type is "local",
219 * we won't be searching the parent tree.
220 */
221 if (!parent_node) {
222 ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "[%4.4s] has no parent\n",
223 ACPI_CAST_PTR(char, &target_name)));
224 return_ACPI_STATUS(AE_NOT_FOUND);
225 }
226
227 if (acpi_ns_local(type)) {
228 ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
229 "[%4.4s] type [%s] must be local to this scope (no parent search)\n",
230 ACPI_CAST_PTR(char, &target_name),
231 acpi_ut_get_type_name(type)));
232 return_ACPI_STATUS(AE_NOT_FOUND);
233 }
234
235 /* Search the parent tree */
236
237 ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
238 "Searching parent [%4.4s] for [%4.4s]\n",
239 acpi_ut_get_node_name(parent_node),
240 ACPI_CAST_PTR(char, &target_name)));
241
242 /*
243 * Search parents until target is found or we have backed up to the root
244 */
245 while (parent_node) {
246 /*
247 * Search parent scope. Use TYPE_ANY because we don't care about the
248 * object type at this point, we only care about the existence of
249 * the actual name we are searching for. Typechecking comes later.
250 */
251 status =
252 acpi_ns_search_one_scope(target_name, parent_node,
253 ACPI_TYPE_ANY, return_node);
254 if (ACPI_SUCCESS(status)) {
255 return_ACPI_STATUS(status);
256 }
257
258 /* Not found here, go up another level (until we reach the root) */
259
260 parent_node = acpi_ns_get_parent_node(parent_node);
261 }
262
263 /* Not found in parent tree */
264
265 return_ACPI_STATUS(AE_NOT_FOUND);
266}
267
268/*******************************************************************************
269 *
270 * FUNCTION: acpi_ns_search_and_enter
271 *
272 * PARAMETERS: target_name - Ascii ACPI name to search for (4 chars)
273 * walk_state - Current state of the walk
274 * Node - Starting node where search will begin
275 * interpreter_mode - Add names only in ACPI_MODE_LOAD_PASS_x.
276 * Otherwise,search only.
277 * Type - Object type to match
278 * Flags - Flags describing the search restrictions
279 * return_node - Where the Node is returned
280 *
281 * RETURN: Status
282 *
283 * DESCRIPTION: Search for a name segment in a single namespace level,
284 * optionally adding it if it is not found. If the passed
285 * Type is not Any and the type previously stored in the
286 * entry was Any (i.e. unknown), update the stored type.
287 *
288 * In ACPI_IMODE_EXECUTE, search only.
289 * In other modes, search and add if not found.
290 *
291 ******************************************************************************/
292
293acpi_status
294acpi_ns_search_and_enter(u32 target_name,
295 struct acpi_walk_state *walk_state,
296 struct acpi_namespace_node *node,
297 acpi_interpreter_mode interpreter_mode,
298 acpi_object_type type,
299 u32 flags, struct acpi_namespace_node **return_node)
300{
301 acpi_status status;
302 struct acpi_namespace_node *new_node;
303
304 ACPI_FUNCTION_TRACE(ns_search_and_enter);
305
306 /* Parameter validation */
307
308 if (!node || !target_name || !return_node) {
309 ACPI_ERROR((AE_INFO,
310 "Null parameter: Node %p Name %X ReturnNode %p",
311 node, target_name, return_node));
312 return_ACPI_STATUS(AE_BAD_PARAMETER);
313 }
314
315 /*
316 * Name must consist of valid ACPI characters. We will repair the name if
317 * necessary because we don't want to abort because of this, but we want
318 * all namespace names to be printable. A warning message is appropriate.
319 *
320 * This issue came up because there are in fact machines that exhibit
321 * this problem, and we want to be able to enable ACPI support for them,
322 * even though there are a few bad names.
323 */
324 if (!acpi_ut_valid_acpi_name(target_name)) {
325 target_name =
326 acpi_ut_repair_name(ACPI_CAST_PTR(char, &target_name));
327
328 /* Report warning only if in strict mode or debug mode */
329
330 if (!acpi_gbl_enable_interpreter_slack) {
331 ACPI_WARNING((AE_INFO,
332 "Found bad character(s) in name, repaired: [%4.4s]\n",
333 ACPI_CAST_PTR(char, &target_name)));
334 } else {
335 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
336 "Found bad character(s) in name, repaired: [%4.4s]\n",
337 ACPI_CAST_PTR(char, &target_name)));
338 }
339 }
340
341 /* Try to find the name in the namespace level specified by the caller */
342
343 *return_node = ACPI_ENTRY_NOT_FOUND;
344 status = acpi_ns_search_one_scope(target_name, node, type, return_node);
345 if (status != AE_NOT_FOUND) {
346 /*
347 * If we found it AND the request specifies that a find is an error,
348 * return the error
349 */
350 if ((status == AE_OK) && (flags & ACPI_NS_ERROR_IF_FOUND)) {
351 status = AE_ALREADY_EXISTS;
352 }
353
354 /* Either found it or there was an error: finished either way */
355
356 return_ACPI_STATUS(status);
357 }
358
359 /*
360 * The name was not found. If we are NOT performing the first pass
361 * (name entry) of loading the namespace, search the parent tree (all the
362 * way to the root if necessary.) We don't want to perform the parent
363 * search when the namespace is actually being loaded. We want to perform
364 * the search when namespace references are being resolved (load pass 2)
365 * and during the execution phase.
366 */
367 if ((interpreter_mode != ACPI_IMODE_LOAD_PASS1) &&
368 (flags & ACPI_NS_SEARCH_PARENT)) {
369 /*
370 * Not found at this level - search parent tree according to the
371 * ACPI specification
372 */
373 status =
374 acpi_ns_search_parent_tree(target_name, node, type,
375 return_node);
376 if (ACPI_SUCCESS(status)) {
377 return_ACPI_STATUS(status);
378 }
379 }
380
381 /* In execute mode, just search, never add names. Exit now */
382
383 if (interpreter_mode == ACPI_IMODE_EXECUTE) {
384 ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
385 "%4.4s Not found in %p [Not adding]\n",
386 ACPI_CAST_PTR(char, &target_name), node));
387
388 return_ACPI_STATUS(AE_NOT_FOUND);
389 }
390
391 /* Create the new named object */
392
393 new_node = acpi_ns_create_node(target_name);
394 if (!new_node) {
395 return_ACPI_STATUS(AE_NO_MEMORY);
396 }
397#ifdef ACPI_ASL_COMPILER
398 /*
399 * Node is an object defined by an External() statement
400 */
401 if (flags & ACPI_NS_EXTERNAL) {
402 new_node->flags |= ANOBJ_IS_EXTERNAL;
403 }
404#endif
405
406 if (flags & ACPI_NS_TEMPORARY) {
407 new_node->flags |= ANOBJ_TEMPORARY;
408 }
409
410 /* Install the new object into the parent's list of children */
411
412 acpi_ns_install_node(walk_state, node, new_node, type);
413 *return_node = new_node;
414 return_ACPI_STATUS(AE_OK);
415}
diff --git a/drivers/acpi/acpica/nsutils.c b/drivers/acpi/acpica/nsutils.c
new file mode 100644
index 00000000000..a443d2805d2
--- /dev/null
+++ b/drivers/acpi/acpica/nsutils.c
@@ -0,0 +1,997 @@
1/******************************************************************************
2 *
3 * Module Name: nsutils - Utilities for accessing ACPI namespace, accessing
4 * parents and siblings and Scope manipulation
5 *
6 *****************************************************************************/
7
8/*
9 * Copyright (C) 2000 - 2008, Intel Corp.
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions, and the following disclaimer,
17 * without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 * substantially similar to the "NO WARRANTY" disclaimer below
20 * ("Disclaimer") and any redistribution must be conditioned upon
21 * including a substantially similar Disclaimer requirement for further
22 * binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 * of any contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
30 *
31 * NO WARRANTY
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
43 */
44
45#include <acpi/acpi.h>
46#include <acpi/accommon.h>
47#include <acpi/acnamesp.h>
48#include <acpi/amlcode.h>
49#include <acpi/actables.h>
50
51#define _COMPONENT ACPI_NAMESPACE
52ACPI_MODULE_NAME("nsutils")
53
54/* Local prototypes */
55static u8 acpi_ns_valid_path_separator(char sep);
56
57#ifdef ACPI_OBSOLETE_FUNCTIONS
58acpi_name acpi_ns_find_parent_name(struct acpi_namespace_node *node_to_search);
59#endif
60
61/*******************************************************************************
62 *
63 * FUNCTION: acpi_ns_report_error
64 *
65 * PARAMETERS: module_name - Caller's module name (for error output)
66 * line_number - Caller's line number (for error output)
67 * internal_name - Name or path of the namespace node
68 * lookup_status - Exception code from NS lookup
69 *
70 * RETURN: None
71 *
72 * DESCRIPTION: Print warning message with full pathname
73 *
74 ******************************************************************************/
75
76void
77acpi_ns_report_error(const char *module_name,
78 u32 line_number,
79 const char *internal_name, acpi_status lookup_status)
80{
81 acpi_status status;
82 u32 bad_name;
83 char *name = NULL;
84
85 acpi_os_printf("ACPI Error (%s-%04d): ", module_name, line_number);
86
87 if (lookup_status == AE_BAD_CHARACTER) {
88
89 /* There is a non-ascii character in the name */
90
91 ACPI_MOVE_32_TO_32(&bad_name, internal_name);
92 acpi_os_printf("[0x%4.4X] (NON-ASCII)", bad_name);
93 } else {
94 /* Convert path to external format */
95
96 status = acpi_ns_externalize_name(ACPI_UINT32_MAX,
97 internal_name, NULL, &name);
98
99 /* Print target name */
100
101 if (ACPI_SUCCESS(status)) {
102 acpi_os_printf("[%s]", name);
103 } else {
104 acpi_os_printf("[COULD NOT EXTERNALIZE NAME]");
105 }
106
107 if (name) {
108 ACPI_FREE(name);
109 }
110 }
111
112 acpi_os_printf(" Namespace lookup failure, %s\n",
113 acpi_format_exception(lookup_status));
114}
115
116/*******************************************************************************
117 *
118 * FUNCTION: acpi_ns_report_method_error
119 *
120 * PARAMETERS: module_name - Caller's module name (for error output)
121 * line_number - Caller's line number (for error output)
122 * Message - Error message to use on failure
123 * prefix_node - Prefix relative to the path
124 * Path - Path to the node (optional)
125 * method_status - Execution status
126 *
127 * RETURN: None
128 *
129 * DESCRIPTION: Print warning message with full pathname
130 *
131 ******************************************************************************/
132
133void
134acpi_ns_report_method_error(const char *module_name,
135 u32 line_number,
136 const char *message,
137 struct acpi_namespace_node *prefix_node,
138 const char *path, acpi_status method_status)
139{
140 acpi_status status;
141 struct acpi_namespace_node *node = prefix_node;
142
143 acpi_os_printf("ACPI Error (%s-%04d): ", module_name, line_number);
144
145 if (path) {
146 status =
147 acpi_ns_get_node(prefix_node, path, ACPI_NS_NO_UPSEARCH,
148 &node);
149 if (ACPI_FAILURE(status)) {
150 acpi_os_printf("[Could not get node by pathname]");
151 }
152 }
153
154 acpi_ns_print_node_pathname(node, message);
155 acpi_os_printf(", %s\n", acpi_format_exception(method_status));
156}
157
158/*******************************************************************************
159 *
160 * FUNCTION: acpi_ns_print_node_pathname
161 *
162 * PARAMETERS: Node - Object
163 * Message - Prefix message
164 *
165 * DESCRIPTION: Print an object's full namespace pathname
166 * Manages allocation/freeing of a pathname buffer
167 *
168 ******************************************************************************/
169
170void
171acpi_ns_print_node_pathname(struct acpi_namespace_node *node,
172 const char *message)
173{
174 struct acpi_buffer buffer;
175 acpi_status status;
176
177 if (!node) {
178 acpi_os_printf("[NULL NAME]");
179 return;
180 }
181
182 /* Convert handle to full pathname and print it (with supplied message) */
183
184 buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
185
186 status = acpi_ns_handle_to_pathname(node, &buffer);
187 if (ACPI_SUCCESS(status)) {
188 if (message) {
189 acpi_os_printf("%s ", message);
190 }
191
192 acpi_os_printf("[%s] (Node %p)", (char *)buffer.pointer, node);
193 ACPI_FREE(buffer.pointer);
194 }
195}
196
197/*******************************************************************************
198 *
199 * FUNCTION: acpi_ns_valid_root_prefix
200 *
201 * PARAMETERS: Prefix - Character to be checked
202 *
203 * RETURN: TRUE if a valid prefix
204 *
205 * DESCRIPTION: Check if a character is a valid ACPI Root prefix
206 *
207 ******************************************************************************/
208
209u8 acpi_ns_valid_root_prefix(char prefix)
210{
211
212 return ((u8) (prefix == '\\'));
213}
214
215/*******************************************************************************
216 *
217 * FUNCTION: acpi_ns_valid_path_separator
218 *
219 * PARAMETERS: Sep - Character to be checked
220 *
221 * RETURN: TRUE if a valid path separator
222 *
223 * DESCRIPTION: Check if a character is a valid ACPI path separator
224 *
225 ******************************************************************************/
226
227static u8 acpi_ns_valid_path_separator(char sep)
228{
229
230 return ((u8) (sep == '.'));
231}
232
233/*******************************************************************************
234 *
235 * FUNCTION: acpi_ns_get_type
236 *
237 * PARAMETERS: Node - Parent Node to be examined
238 *
239 * RETURN: Type field from Node whose handle is passed
240 *
241 * DESCRIPTION: Return the type of a Namespace node
242 *
243 ******************************************************************************/
244
245acpi_object_type acpi_ns_get_type(struct acpi_namespace_node * node)
246{
247 ACPI_FUNCTION_TRACE(ns_get_type);
248
249 if (!node) {
250 ACPI_WARNING((AE_INFO, "Null Node parameter"));
251 return_UINT32(ACPI_TYPE_ANY);
252 }
253
254 return_UINT32((acpi_object_type) node->type);
255}
256
257/*******************************************************************************
258 *
259 * FUNCTION: acpi_ns_local
260 *
261 * PARAMETERS: Type - A namespace object type
262 *
263 * RETURN: LOCAL if names must be found locally in objects of the
264 * passed type, 0 if enclosing scopes should be searched
265 *
266 * DESCRIPTION: Returns scope rule for the given object type.
267 *
268 ******************************************************************************/
269
270u32 acpi_ns_local(acpi_object_type type)
271{
272 ACPI_FUNCTION_TRACE(ns_local);
273
274 if (!acpi_ut_valid_object_type(type)) {
275
276 /* Type code out of range */
277
278 ACPI_WARNING((AE_INFO, "Invalid Object Type %X", type));
279 return_UINT32(ACPI_NS_NORMAL);
280 }
281
282 return_UINT32((u32) acpi_gbl_ns_properties[type] & ACPI_NS_LOCAL);
283}
284
285/*******************************************************************************
286 *
287 * FUNCTION: acpi_ns_get_internal_name_length
288 *
289 * PARAMETERS: Info - Info struct initialized with the
290 * external name pointer.
291 *
292 * RETURN: None
293 *
294 * DESCRIPTION: Calculate the length of the internal (AML) namestring
295 * corresponding to the external (ASL) namestring.
296 *
297 ******************************************************************************/
298
299void acpi_ns_get_internal_name_length(struct acpi_namestring_info *info)
300{
301 const char *next_external_char;
302 u32 i;
303
304 ACPI_FUNCTION_ENTRY();
305
306 next_external_char = info->external_name;
307 info->num_carats = 0;
308 info->num_segments = 0;
309 info->fully_qualified = FALSE;
310
311 /*
312 * For the internal name, the required length is 4 bytes per segment, plus
313 * 1 each for root_prefix, multi_name_prefix_op, segment count, trailing null
314 * (which is not really needed, but no there's harm in putting it there)
315 *
316 * strlen() + 1 covers the first name_seg, which has no path separator
317 */
318 if (acpi_ns_valid_root_prefix(*next_external_char)) {
319 info->fully_qualified = TRUE;
320 next_external_char++;
321
322 /* Skip redundant root_prefix, like \\_SB.PCI0.SBRG.EC0 */
323
324 while (acpi_ns_valid_root_prefix(*next_external_char)) {
325 next_external_char++;
326 }
327 } else {
328 /*
329 * Handle Carat prefixes
330 */
331 while (*next_external_char == '^') {
332 info->num_carats++;
333 next_external_char++;
334 }
335 }
336
337 /*
338 * Determine the number of ACPI name "segments" by counting the number of
339 * path separators within the string. Start with one segment since the
340 * segment count is [(# separators) + 1], and zero separators is ok.
341 */
342 if (*next_external_char) {
343 info->num_segments = 1;
344 for (i = 0; next_external_char[i]; i++) {
345 if (acpi_ns_valid_path_separator(next_external_char[i])) {
346 info->num_segments++;
347 }
348 }
349 }
350
351 info->length = (ACPI_NAME_SIZE * info->num_segments) +
352 4 + info->num_carats;
353
354 info->next_external_char = next_external_char;
355}
356
357/*******************************************************************************
358 *
359 * FUNCTION: acpi_ns_build_internal_name
360 *
361 * PARAMETERS: Info - Info struct fully initialized
362 *
363 * RETURN: Status
364 *
365 * DESCRIPTION: Construct the internal (AML) namestring
366 * corresponding to the external (ASL) namestring.
367 *
368 ******************************************************************************/
369
370acpi_status acpi_ns_build_internal_name(struct acpi_namestring_info *info)
371{
372 u32 num_segments = info->num_segments;
373 char *internal_name = info->internal_name;
374 const char *external_name = info->next_external_char;
375 char *result = NULL;
376 u32 i;
377
378 ACPI_FUNCTION_TRACE(ns_build_internal_name);
379
380 /* Setup the correct prefixes, counts, and pointers */
381
382 if (info->fully_qualified) {
383 internal_name[0] = '\\';
384
385 if (num_segments <= 1) {
386 result = &internal_name[1];
387 } else if (num_segments == 2) {
388 internal_name[1] = AML_DUAL_NAME_PREFIX;
389 result = &internal_name[2];
390 } else {
391 internal_name[1] = AML_MULTI_NAME_PREFIX_OP;
392 internal_name[2] = (char)num_segments;
393 result = &internal_name[3];
394 }
395 } else {
396 /*
397 * Not fully qualified.
398 * Handle Carats first, then append the name segments
399 */
400 i = 0;
401 if (info->num_carats) {
402 for (i = 0; i < info->num_carats; i++) {
403 internal_name[i] = '^';
404 }
405 }
406
407 if (num_segments <= 1) {
408 result = &internal_name[i];
409 } else if (num_segments == 2) {
410 internal_name[i] = AML_DUAL_NAME_PREFIX;
411 result = &internal_name[(acpi_size) i + 1];
412 } else {
413 internal_name[i] = AML_MULTI_NAME_PREFIX_OP;
414 internal_name[(acpi_size) i + 1] = (char)num_segments;
415 result = &internal_name[(acpi_size) i + 2];
416 }
417 }
418
419 /* Build the name (minus path separators) */
420
421 for (; num_segments; num_segments--) {
422 for (i = 0; i < ACPI_NAME_SIZE; i++) {
423 if (acpi_ns_valid_path_separator(*external_name) ||
424 (*external_name == 0)) {
425
426 /* Pad the segment with underscore(s) if segment is short */
427
428 result[i] = '_';
429 } else {
430 /* Convert the character to uppercase and save it */
431
432 result[i] =
433 (char)ACPI_TOUPPER((int)*external_name);
434 external_name++;
435 }
436 }
437
438 /* Now we must have a path separator, or the pathname is bad */
439
440 if (!acpi_ns_valid_path_separator(*external_name) &&
441 (*external_name != 0)) {
442 return_ACPI_STATUS(AE_BAD_PARAMETER);
443 }
444
445 /* Move on the next segment */
446
447 external_name++;
448 result += ACPI_NAME_SIZE;
449 }
450
451 /* Terminate the string */
452
453 *result = 0;
454
455 if (info->fully_qualified) {
456 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
457 "Returning [%p] (abs) \"\\%s\"\n",
458 internal_name, internal_name));
459 } else {
460 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Returning [%p] (rel) \"%s\"\n",
461 internal_name, internal_name));
462 }
463
464 return_ACPI_STATUS(AE_OK);
465}
466
467/*******************************************************************************
468 *
469 * FUNCTION: acpi_ns_internalize_name
470 *
471 * PARAMETERS: *external_name - External representation of name
472 * **Converted Name - Where to return the resulting
473 * internal represention of the name
474 *
475 * RETURN: Status
476 *
477 * DESCRIPTION: Convert an external representation (e.g. "\_PR_.CPU0")
478 * to internal form (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30)
479 *
480 *******************************************************************************/
481
482acpi_status
483acpi_ns_internalize_name(const char *external_name, char **converted_name)
484{
485 char *internal_name;
486 struct acpi_namestring_info info;
487 acpi_status status;
488
489 ACPI_FUNCTION_TRACE(ns_internalize_name);
490
491 if ((!external_name) || (*external_name == 0) || (!converted_name)) {
492 return_ACPI_STATUS(AE_BAD_PARAMETER);
493 }
494
495 /* Get the length of the new internal name */
496
497 info.external_name = external_name;
498 acpi_ns_get_internal_name_length(&info);
499
500 /* We need a segment to store the internal name */
501
502 internal_name = ACPI_ALLOCATE_ZEROED(info.length);
503 if (!internal_name) {
504 return_ACPI_STATUS(AE_NO_MEMORY);
505 }
506
507 /* Build the name */
508
509 info.internal_name = internal_name;
510 status = acpi_ns_build_internal_name(&info);
511 if (ACPI_FAILURE(status)) {
512 ACPI_FREE(internal_name);
513 return_ACPI_STATUS(status);
514 }
515
516 *converted_name = internal_name;
517 return_ACPI_STATUS(AE_OK);
518}
519
520/*******************************************************************************
521 *
522 * FUNCTION: acpi_ns_externalize_name
523 *
524 * PARAMETERS: internal_name_length - Lenth of the internal name below
525 * internal_name - Internal representation of name
526 * converted_name_length - Where the length is returned
527 * converted_name - Where the resulting external name
528 * is returned
529 *
530 * RETURN: Status
531 *
532 * DESCRIPTION: Convert internal name (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30)
533 * to its external (printable) form (e.g. "\_PR_.CPU0")
534 *
535 ******************************************************************************/
536
537acpi_status
538acpi_ns_externalize_name(u32 internal_name_length,
539 const char *internal_name,
540 u32 * converted_name_length, char **converted_name)
541{
542 u32 names_index = 0;
543 u32 num_segments = 0;
544 u32 required_length;
545 u32 prefix_length = 0;
546 u32 i = 0;
547 u32 j = 0;
548
549 ACPI_FUNCTION_TRACE(ns_externalize_name);
550
551 if (!internal_name_length || !internal_name || !converted_name) {
552 return_ACPI_STATUS(AE_BAD_PARAMETER);
553 }
554
555 /*
556 * Check for a prefix (one '\' | one or more '^').
557 */
558 switch (internal_name[0]) {
559 case '\\':
560 prefix_length = 1;
561 break;
562
563 case '^':
564 for (i = 0; i < internal_name_length; i++) {
565 if (internal_name[i] == '^') {
566 prefix_length = i + 1;
567 } else {
568 break;
569 }
570 }
571
572 if (i == internal_name_length) {
573 prefix_length = i;
574 }
575
576 break;
577
578 default:
579 break;
580 }
581
582 /*
583 * Check for object names. Note that there could be 0-255 of these
584 * 4-byte elements.
585 */
586 if (prefix_length < internal_name_length) {
587 switch (internal_name[prefix_length]) {
588 case AML_MULTI_NAME_PREFIX_OP:
589
590 /* <count> 4-byte names */
591
592 names_index = prefix_length + 2;
593 num_segments = (u8)
594 internal_name[(acpi_size) prefix_length + 1];
595 break;
596
597 case AML_DUAL_NAME_PREFIX:
598
599 /* Two 4-byte names */
600
601 names_index = prefix_length + 1;
602 num_segments = 2;
603 break;
604
605 case 0:
606
607 /* null_name */
608
609 names_index = 0;
610 num_segments = 0;
611 break;
612
613 default:
614
615 /* one 4-byte name */
616
617 names_index = prefix_length;
618 num_segments = 1;
619 break;
620 }
621 }
622
623 /*
624 * Calculate the length of converted_name, which equals the length
625 * of the prefix, length of all object names, length of any required
626 * punctuation ('.') between object names, plus the NULL terminator.
627 */
628 required_length = prefix_length + (4 * num_segments) +
629 ((num_segments > 0) ? (num_segments - 1) : 0) + 1;
630
631 /*
632 * Check to see if we're still in bounds. If not, there's a problem
633 * with internal_name (invalid format).
634 */
635 if (required_length > internal_name_length) {
636 ACPI_ERROR((AE_INFO, "Invalid internal name"));
637 return_ACPI_STATUS(AE_BAD_PATHNAME);
638 }
639
640 /*
641 * Build converted_name
642 */
643 *converted_name = ACPI_ALLOCATE_ZEROED(required_length);
644 if (!(*converted_name)) {
645 return_ACPI_STATUS(AE_NO_MEMORY);
646 }
647
648 j = 0;
649
650 for (i = 0; i < prefix_length; i++) {
651 (*converted_name)[j++] = internal_name[i];
652 }
653
654 if (num_segments > 0) {
655 for (i = 0; i < num_segments; i++) {
656 if (i > 0) {
657 (*converted_name)[j++] = '.';
658 }
659
660 (*converted_name)[j++] = internal_name[names_index++];
661 (*converted_name)[j++] = internal_name[names_index++];
662 (*converted_name)[j++] = internal_name[names_index++];
663 (*converted_name)[j++] = internal_name[names_index++];
664 }
665 }
666
667 if (converted_name_length) {
668 *converted_name_length = (u32) required_length;
669 }
670
671 return_ACPI_STATUS(AE_OK);
672}
673
674/*******************************************************************************
675 *
676 * FUNCTION: acpi_ns_map_handle_to_node
677 *
678 * PARAMETERS: Handle - Handle to be converted to an Node
679 *
680 * RETURN: A Name table entry pointer
681 *
682 * DESCRIPTION: Convert a namespace handle to a real Node
683 *
684 * Note: Real integer handles would allow for more verification
685 * and keep all pointers within this subsystem - however this introduces
686 * more (and perhaps unnecessary) overhead.
687 *
688 ******************************************************************************/
689
690struct acpi_namespace_node *acpi_ns_map_handle_to_node(acpi_handle handle)
691{
692
693 ACPI_FUNCTION_ENTRY();
694
695 /*
696 * Simple implementation
697 */
698 if ((!handle) || (handle == ACPI_ROOT_OBJECT)) {
699 return (acpi_gbl_root_node);
700 }
701
702 /* We can at least attempt to verify the handle */
703
704 if (ACPI_GET_DESCRIPTOR_TYPE(handle) != ACPI_DESC_TYPE_NAMED) {
705 return (NULL);
706 }
707
708 return (ACPI_CAST_PTR(struct acpi_namespace_node, handle));
709}
710
711/*******************************************************************************
712 *
713 * FUNCTION: acpi_ns_convert_entry_to_handle
714 *
715 * PARAMETERS: Node - Node to be converted to a Handle
716 *
717 * RETURN: A user handle
718 *
719 * DESCRIPTION: Convert a real Node to a namespace handle
720 *
721 ******************************************************************************/
722
723acpi_handle acpi_ns_convert_entry_to_handle(struct acpi_namespace_node *node)
724{
725
726 /*
727 * Simple implementation for now;
728 */
729 return ((acpi_handle) node);
730
731/* Example future implementation ---------------------
732
733 if (!Node)
734 {
735 return (NULL);
736 }
737
738 if (Node == acpi_gbl_root_node)
739 {
740 return (ACPI_ROOT_OBJECT);
741 }
742
743 return ((acpi_handle) Node);
744------------------------------------------------------*/
745}
746
747/*******************************************************************************
748 *
749 * FUNCTION: acpi_ns_terminate
750 *
751 * PARAMETERS: none
752 *
753 * RETURN: none
754 *
755 * DESCRIPTION: free memory allocated for namespace and ACPI table storage.
756 *
757 ******************************************************************************/
758
759void acpi_ns_terminate(void)
760{
761 union acpi_operand_object *obj_desc;
762
763 ACPI_FUNCTION_TRACE(ns_terminate);
764
765 /*
766 * 1) Free the entire namespace -- all nodes and objects
767 *
768 * Delete all object descriptors attached to namepsace nodes
769 */
770 acpi_ns_delete_namespace_subtree(acpi_gbl_root_node);
771
772 /* Detach any objects attached to the root */
773
774 obj_desc = acpi_ns_get_attached_object(acpi_gbl_root_node);
775 if (obj_desc) {
776 acpi_ns_detach_object(acpi_gbl_root_node);
777 }
778
779 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Namespace freed\n"));
780 return_VOID;
781}
782
783/*******************************************************************************
784 *
785 * FUNCTION: acpi_ns_opens_scope
786 *
787 * PARAMETERS: Type - A valid namespace type
788 *
789 * RETURN: NEWSCOPE if the passed type "opens a name scope" according
790 * to the ACPI specification, else 0
791 *
792 ******************************************************************************/
793
794u32 acpi_ns_opens_scope(acpi_object_type type)
795{
796 ACPI_FUNCTION_TRACE_STR(ns_opens_scope, acpi_ut_get_type_name(type));
797
798 if (!acpi_ut_valid_object_type(type)) {
799
800 /* type code out of range */
801
802 ACPI_WARNING((AE_INFO, "Invalid Object Type %X", type));
803 return_UINT32(ACPI_NS_NORMAL);
804 }
805
806 return_UINT32(((u32) acpi_gbl_ns_properties[type]) & ACPI_NS_NEWSCOPE);
807}
808
809/*******************************************************************************
810 *
811 * FUNCTION: acpi_ns_get_node
812 *
813 * PARAMETERS: *Pathname - Name to be found, in external (ASL) format. The
814 * \ (backslash) and ^ (carat) prefixes, and the
815 * . (period) to separate segments are supported.
816 * prefix_node - Root of subtree to be searched, or NS_ALL for the
817 * root of the name space. If Name is fully
818 * qualified (first s8 is '\'), the passed value
819 * of Scope will not be accessed.
820 * Flags - Used to indicate whether to perform upsearch or
821 * not.
822 * return_node - Where the Node is returned
823 *
824 * DESCRIPTION: Look up a name relative to a given scope and return the
825 * corresponding Node. NOTE: Scope can be null.
826 *
827 * MUTEX: Locks namespace
828 *
829 ******************************************************************************/
830
831acpi_status
832acpi_ns_get_node(struct acpi_namespace_node *prefix_node,
833 const char *pathname,
834 u32 flags, struct acpi_namespace_node **return_node)
835{
836 union acpi_generic_state scope_info;
837 acpi_status status;
838 char *internal_path;
839
840 ACPI_FUNCTION_TRACE_PTR(ns_get_node, pathname);
841
842 if (!pathname) {
843 *return_node = prefix_node;
844 if (!prefix_node) {
845 *return_node = acpi_gbl_root_node;
846 }
847 return_ACPI_STATUS(AE_OK);
848 }
849
850 /* Convert path to internal representation */
851
852 status = acpi_ns_internalize_name(pathname, &internal_path);
853 if (ACPI_FAILURE(status)) {
854 return_ACPI_STATUS(status);
855 }
856
857 /* Must lock namespace during lookup */
858
859 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
860 if (ACPI_FAILURE(status)) {
861 goto cleanup;
862 }
863
864 /* Setup lookup scope (search starting point) */
865
866 scope_info.scope.node = prefix_node;
867
868 /* Lookup the name in the namespace */
869
870 status = acpi_ns_lookup(&scope_info, internal_path, ACPI_TYPE_ANY,
871 ACPI_IMODE_EXECUTE,
872 (flags | ACPI_NS_DONT_OPEN_SCOPE), NULL,
873 return_node);
874 if (ACPI_FAILURE(status)) {
875 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s, %s\n",
876 pathname, acpi_format_exception(status)));
877 }
878
879 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
880
881 cleanup:
882 ACPI_FREE(internal_path);
883 return_ACPI_STATUS(status);
884}
885
886/*******************************************************************************
887 *
888 * FUNCTION: acpi_ns_get_parent_node
889 *
890 * PARAMETERS: Node - Current table entry
891 *
892 * RETURN: Parent entry of the given entry
893 *
894 * DESCRIPTION: Obtain the parent entry for a given entry in the namespace.
895 *
896 ******************************************************************************/
897
898struct acpi_namespace_node *acpi_ns_get_parent_node(struct acpi_namespace_node
899 *node)
900{
901 ACPI_FUNCTION_ENTRY();
902
903 if (!node) {
904 return (NULL);
905 }
906
907 /*
908 * Walk to the end of this peer list. The last entry is marked with a flag
909 * and the peer pointer is really a pointer back to the parent. This saves
910 * putting a parent back pointer in each and every named object!
911 */
912 while (!(node->flags & ANOBJ_END_OF_PEER_LIST)) {
913 node = node->peer;
914 }
915
916 return (node->peer);
917}
918
919/*******************************************************************************
920 *
921 * FUNCTION: acpi_ns_get_next_valid_node
922 *
923 * PARAMETERS: Node - Current table entry
924 *
925 * RETURN: Next valid Node in the linked node list. NULL if no more valid
926 * nodes.
927 *
928 * DESCRIPTION: Find the next valid node within a name table.
929 * Useful for implementing NULL-end-of-list loops.
930 *
931 ******************************************************************************/
932
933struct acpi_namespace_node *acpi_ns_get_next_valid_node(struct
934 acpi_namespace_node
935 *node)
936{
937
938 /* If we are at the end of this peer list, return NULL */
939
940 if (node->flags & ANOBJ_END_OF_PEER_LIST) {
941 return NULL;
942 }
943
944 /* Otherwise just return the next peer */
945
946 return (node->peer);
947}
948
949#ifdef ACPI_OBSOLETE_FUNCTIONS
950/*******************************************************************************
951 *
952 * FUNCTION: acpi_ns_find_parent_name
953 *
954 * PARAMETERS: *child_node - Named Obj whose name is to be found
955 *
956 * RETURN: The ACPI name
957 *
958 * DESCRIPTION: Search for the given obj in its parent scope and return the
959 * name segment, or "????" if the parent name can't be found
960 * (which "should not happen").
961 *
962 ******************************************************************************/
963
964acpi_name acpi_ns_find_parent_name(struct acpi_namespace_node * child_node)
965{
966 struct acpi_namespace_node *parent_node;
967
968 ACPI_FUNCTION_TRACE(ns_find_parent_name);
969
970 if (child_node) {
971
972 /* Valid entry. Get the parent Node */
973
974 parent_node = acpi_ns_get_parent_node(child_node);
975 if (parent_node) {
976 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
977 "Parent of %p [%4.4s] is %p [%4.4s]\n",
978 child_node,
979 acpi_ut_get_node_name(child_node),
980 parent_node,
981 acpi_ut_get_node_name(parent_node)));
982
983 if (parent_node->name.integer) {
984 return_VALUE((acpi_name) parent_node->name.
985 integer);
986 }
987 }
988
989 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
990 "Unable to find parent of %p (%4.4s)\n",
991 child_node,
992 acpi_ut_get_node_name(child_node)));
993 }
994
995 return_VALUE(ACPI_UNKNOWN_NAME);
996}
997#endif
diff --git a/drivers/acpi/acpica/nswalk.c b/drivers/acpi/acpica/nswalk.c
new file mode 100644
index 00000000000..71b83e9807d
--- /dev/null
+++ b/drivers/acpi/acpica/nswalk.c
@@ -0,0 +1,296 @@
1/******************************************************************************
2 *
3 * Module Name: nswalk - Functions for walking the ACPI namespace
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46#include <acpi/acnamesp.h>
47
48#define _COMPONENT ACPI_NAMESPACE
49ACPI_MODULE_NAME("nswalk")
50
51/*******************************************************************************
52 *
53 * FUNCTION: acpi_ns_get_next_node
54 *
55 * PARAMETERS: Type - Type of node to be searched for
56 * parent_node - Parent node whose children we are
57 * getting
58 * child_node - Previous child that was found.
59 * The NEXT child will be returned
60 *
61 * RETURN: struct acpi_namespace_node - Pointer to the NEXT child or NULL if
62 * none is found.
63 *
64 * DESCRIPTION: Return the next peer node within the namespace. If Handle
65 * is valid, Scope is ignored. Otherwise, the first node
66 * within Scope is returned.
67 *
68 ******************************************************************************/
69struct acpi_namespace_node *acpi_ns_get_next_node(acpi_object_type type, struct acpi_namespace_node
70 *parent_node, struct acpi_namespace_node
71 *child_node)
72{
73 struct acpi_namespace_node *next_node = NULL;
74
75 ACPI_FUNCTION_ENTRY();
76
77 if (!child_node) {
78
79 /* It's really the parent's _scope_ that we want */
80
81 next_node = parent_node->child;
82 }
83
84 else {
85 /* Start search at the NEXT node */
86
87 next_node = acpi_ns_get_next_valid_node(child_node);
88 }
89
90 /* If any type is OK, we are done */
91
92 if (type == ACPI_TYPE_ANY) {
93
94 /* next_node is NULL if we are at the end-of-list */
95
96 return (next_node);
97 }
98
99 /* Must search for the node -- but within this scope only */
100
101 while (next_node) {
102
103 /* If type matches, we are done */
104
105 if (next_node->type == type) {
106 return (next_node);
107 }
108
109 /* Otherwise, move on to the next node */
110
111 next_node = acpi_ns_get_next_valid_node(next_node);
112 }
113
114 /* Not found */
115
116 return (NULL);
117}
118
119/*******************************************************************************
120 *
121 * FUNCTION: acpi_ns_walk_namespace
122 *
123 * PARAMETERS: Type - acpi_object_type to search for
124 * start_node - Handle in namespace where search begins
125 * max_depth - Depth to which search is to reach
126 * Flags - Whether to unlock the NS before invoking
127 * the callback routine
128 * user_function - Called when an object of "Type" is found
129 * Context - Passed to user function
130 * return_value - from the user_function if terminated early.
131 * Otherwise, returns NULL.
132 * RETURNS: Status
133 *
134 * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
135 * starting (and ending) at the node specified by start_handle.
136 * The user_function is called whenever a node that matches
137 * the type parameter is found. If the user function returns
138 * a non-zero value, the search is terminated immediately and this
139 * value is returned to the caller.
140 *
141 * The point of this procedure is to provide a generic namespace
142 * walk routine that can be called from multiple places to
143 * provide multiple services; the User Function can be tailored
144 * to each task, whether it is a print function, a compare
145 * function, etc.
146 *
147 ******************************************************************************/
148
149acpi_status
150acpi_ns_walk_namespace(acpi_object_type type,
151 acpi_handle start_node,
152 u32 max_depth,
153 u32 flags,
154 acpi_walk_callback user_function,
155 void *context, void **return_value)
156{
157 acpi_status status;
158 acpi_status mutex_status;
159 struct acpi_namespace_node *child_node;
160 struct acpi_namespace_node *parent_node;
161 acpi_object_type child_type;
162 u32 level;
163
164 ACPI_FUNCTION_TRACE(ns_walk_namespace);
165
166 /* Special case for the namespace Root Node */
167
168 if (start_node == ACPI_ROOT_OBJECT) {
169 start_node = acpi_gbl_root_node;
170 }
171
172 /* Null child means "get first node" */
173
174 parent_node = start_node;
175 child_node = NULL;
176 child_type = ACPI_TYPE_ANY;
177 level = 1;
178
179 /*
180 * Traverse the tree of nodes until we bubble back up to where we
181 * started. When Level is zero, the loop is done because we have
182 * bubbled up to (and passed) the original parent handle (start_entry)
183 */
184 while (level > 0) {
185
186 /* Get the next node in this scope. Null if not found */
187
188 status = AE_OK;
189 child_node =
190 acpi_ns_get_next_node(ACPI_TYPE_ANY, parent_node,
191 child_node);
192 if (child_node) {
193
194 /* Found next child, get the type if we are not searching for ANY */
195
196 if (type != ACPI_TYPE_ANY) {
197 child_type = child_node->type;
198 }
199
200 /*
201 * Ignore all temporary namespace nodes (created during control
202 * method execution) unless told otherwise. These temporary nodes
203 * can cause a race condition because they can be deleted during the
204 * execution of the user function (if the namespace is unlocked before
205 * invocation of the user function.) Only the debugger namespace dump
206 * will examine the temporary nodes.
207 */
208 if ((child_node->flags & ANOBJ_TEMPORARY) &&
209 !(flags & ACPI_NS_WALK_TEMP_NODES)) {
210 status = AE_CTRL_DEPTH;
211 }
212
213 /* Type must match requested type */
214
215 else if (child_type == type) {
216 /*
217 * Found a matching node, invoke the user callback function.
218 * Unlock the namespace if flag is set.
219 */
220 if (flags & ACPI_NS_WALK_UNLOCK) {
221 mutex_status =
222 acpi_ut_release_mutex
223 (ACPI_MTX_NAMESPACE);
224 if (ACPI_FAILURE(mutex_status)) {
225 return_ACPI_STATUS
226 (mutex_status);
227 }
228 }
229
230 status =
231 user_function(child_node, level, context,
232 return_value);
233
234 if (flags & ACPI_NS_WALK_UNLOCK) {
235 mutex_status =
236 acpi_ut_acquire_mutex
237 (ACPI_MTX_NAMESPACE);
238 if (ACPI_FAILURE(mutex_status)) {
239 return_ACPI_STATUS
240 (mutex_status);
241 }
242 }
243
244 switch (status) {
245 case AE_OK:
246 case AE_CTRL_DEPTH:
247
248 /* Just keep going */
249 break;
250
251 case AE_CTRL_TERMINATE:
252
253 /* Exit now, with OK status */
254
255 return_ACPI_STATUS(AE_OK);
256
257 default:
258
259 /* All others are valid exceptions */
260
261 return_ACPI_STATUS(status);
262 }
263 }
264
265 /*
266 * Depth first search: Attempt to go down another level in the
267 * namespace if we are allowed to. Don't go any further if we have
268 * reached the caller specified maximum depth or if the user
269 * function has specified that the maximum depth has been reached.
270 */
271 if ((level < max_depth) && (status != AE_CTRL_DEPTH)) {
272 if (acpi_ns_get_next_node
273 (ACPI_TYPE_ANY, child_node, NULL)) {
274
275 /* There is at least one child of this node, visit it */
276
277 level++;
278 parent_node = child_node;
279 child_node = NULL;
280 }
281 }
282 } else {
283 /*
284 * No more children of this node (acpi_ns_get_next_node failed), go
285 * back upwards in the namespace tree to the node's parent.
286 */
287 level--;
288 child_node = parent_node;
289 parent_node = acpi_ns_get_parent_node(parent_node);
290 }
291 }
292
293 /* Complete walk, not terminated by user function */
294
295 return_ACPI_STATUS(AE_OK);
296}
diff --git a/drivers/acpi/acpica/nsxfeval.c b/drivers/acpi/acpica/nsxfeval.c
new file mode 100644
index 00000000000..598393a04e5
--- /dev/null
+++ b/drivers/acpi/acpica/nsxfeval.c
@@ -0,0 +1,812 @@
1/*******************************************************************************
2 *
3 * Module Name: nsxfeval - Public interfaces to the ACPI subsystem
4 * ACPI Object evaluation interfaces
5 *
6 ******************************************************************************/
7
8/*
9 * Copyright (C) 2000 - 2008, Intel Corp.
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions, and the following disclaimer,
17 * without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 * substantially similar to the "NO WARRANTY" disclaimer below
20 * ("Disclaimer") and any redistribution must be conditioned upon
21 * including a substantially similar Disclaimer requirement for further
22 * binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 * of any contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
30 *
31 * NO WARRANTY
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
43 */
44
45#include <acpi/acpi.h>
46#include <acpi/accommon.h>
47#include <acpi/acnamesp.h>
48#include <acpi/acinterp.h>
49
50#define _COMPONENT ACPI_NAMESPACE
51ACPI_MODULE_NAME("nsxfeval")
52
53/* Local prototypes */
54static void acpi_ns_resolve_references(struct acpi_evaluate_info *info);
55
56#ifdef ACPI_FUTURE_USAGE
57/*******************************************************************************
58 *
59 * FUNCTION: acpi_evaluate_object_typed
60 *
61 * PARAMETERS: Handle - Object handle (optional)
62 * Pathname - Object pathname (optional)
63 * external_params - List of parameters to pass to method,
64 * terminated by NULL. May be NULL
65 * if no parameters are being passed.
66 * return_buffer - Where to put method's return value (if
67 * any). If NULL, no value is returned.
68 * return_type - Expected type of return object
69 *
70 * RETURN: Status
71 *
72 * DESCRIPTION: Find and evaluate the given object, passing the given
73 * parameters if necessary. One of "Handle" or "Pathname" must
74 * be valid (non-null)
75 *
76 ******************************************************************************/
77
78acpi_status
79acpi_evaluate_object_typed(acpi_handle handle,
80 acpi_string pathname,
81 struct acpi_object_list *external_params,
82 struct acpi_buffer *return_buffer,
83 acpi_object_type return_type)
84{
85 acpi_status status;
86 u8 must_free = FALSE;
87
88 ACPI_FUNCTION_TRACE(acpi_evaluate_object_typed);
89
90 /* Return buffer must be valid */
91
92 if (!return_buffer) {
93 return_ACPI_STATUS(AE_BAD_PARAMETER);
94 }
95
96 if (return_buffer->length == ACPI_ALLOCATE_BUFFER) {
97 must_free = TRUE;
98 }
99
100 /* Evaluate the object */
101
102 status =
103 acpi_evaluate_object(handle, pathname, external_params,
104 return_buffer);
105 if (ACPI_FAILURE(status)) {
106 return_ACPI_STATUS(status);
107 }
108
109 /* Type ANY means "don't care" */
110
111 if (return_type == ACPI_TYPE_ANY) {
112 return_ACPI_STATUS(AE_OK);
113 }
114
115 if (return_buffer->length == 0) {
116
117 /* Error because caller specifically asked for a return value */
118
119 ACPI_ERROR((AE_INFO, "No return value"));
120 return_ACPI_STATUS(AE_NULL_OBJECT);
121 }
122
123 /* Examine the object type returned from evaluate_object */
124
125 if (((union acpi_object *)return_buffer->pointer)->type == return_type) {
126 return_ACPI_STATUS(AE_OK);
127 }
128
129 /* Return object type does not match requested type */
130
131 ACPI_ERROR((AE_INFO,
132 "Incorrect return type [%s] requested [%s]",
133 acpi_ut_get_type_name(((union acpi_object *)return_buffer->
134 pointer)->type),
135 acpi_ut_get_type_name(return_type)));
136
137 if (must_free) {
138
139 /* Caller used ACPI_ALLOCATE_BUFFER, free the return buffer */
140
141 ACPI_FREE(return_buffer->pointer);
142 return_buffer->pointer = NULL;
143 }
144
145 return_buffer->length = 0;
146 return_ACPI_STATUS(AE_TYPE);
147}
148
149ACPI_EXPORT_SYMBOL(acpi_evaluate_object_typed)
150#endif /* ACPI_FUTURE_USAGE */
151/*******************************************************************************
152 *
153 * FUNCTION: acpi_evaluate_object
154 *
155 * PARAMETERS: Handle - Object handle (optional)
156 * Pathname - Object pathname (optional)
157 * external_params - List of parameters to pass to method,
158 * terminated by NULL. May be NULL
159 * if no parameters are being passed.
160 * return_buffer - Where to put method's return value (if
161 * any). If NULL, no value is returned.
162 *
163 * RETURN: Status
164 *
165 * DESCRIPTION: Find and evaluate the given object, passing the given
166 * parameters if necessary. One of "Handle" or "Pathname" must
167 * be valid (non-null)
168 *
169 ******************************************************************************/
170acpi_status
171acpi_evaluate_object(acpi_handle handle,
172 acpi_string pathname,
173 struct acpi_object_list *external_params,
174 struct acpi_buffer *return_buffer)
175{
176 acpi_status status;
177 struct acpi_evaluate_info *info;
178 acpi_size buffer_space_needed;
179 u32 i;
180
181 ACPI_FUNCTION_TRACE(acpi_evaluate_object);
182
183 /* Allocate and initialize the evaluation information block */
184
185 info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
186 if (!info) {
187 return_ACPI_STATUS(AE_NO_MEMORY);
188 }
189
190 info->pathname = pathname;
191
192 /* Convert and validate the device handle */
193
194 info->prefix_node = acpi_ns_map_handle_to_node(handle);
195 if (!info->prefix_node) {
196 status = AE_BAD_PARAMETER;
197 goto cleanup;
198 }
199
200 /*
201 * If there are parameters to be passed to a control method, the external
202 * objects must all be converted to internal objects
203 */
204 if (external_params && external_params->count) {
205 /*
206 * Allocate a new parameter block for the internal objects
207 * Add 1 to count to allow for null terminated internal list
208 */
209 info->parameters = ACPI_ALLOCATE_ZEROED(((acpi_size)
210 external_params->
211 count +
212 1) * sizeof(void *));
213 if (!info->parameters) {
214 status = AE_NO_MEMORY;
215 goto cleanup;
216 }
217
218 /* Convert each external object in the list to an internal object */
219
220 for (i = 0; i < external_params->count; i++) {
221 status =
222 acpi_ut_copy_eobject_to_iobject(&external_params->
223 pointer[i],
224 &info->
225 parameters[i]);
226 if (ACPI_FAILURE(status)) {
227 goto cleanup;
228 }
229 }
230 info->parameters[external_params->count] = NULL;
231 }
232
233 /*
234 * Three major cases:
235 * 1) Fully qualified pathname
236 * 2) No handle, not fully qualified pathname (error)
237 * 3) Valid handle
238 */
239 if ((pathname) && (acpi_ns_valid_root_prefix(pathname[0]))) {
240
241 /* The path is fully qualified, just evaluate by name */
242
243 info->prefix_node = NULL;
244 status = acpi_ns_evaluate(info);
245 } else if (!handle) {
246 /*
247 * A handle is optional iff a fully qualified pathname is specified.
248 * Since we've already handled fully qualified names above, this is
249 * an error
250 */
251 if (!pathname) {
252 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
253 "Both Handle and Pathname are NULL"));
254 } else {
255 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
256 "Null Handle with relative pathname [%s]",
257 pathname));
258 }
259
260 status = AE_BAD_PARAMETER;
261 } else {
262 /* We have a namespace a node and a possible relative path */
263
264 status = acpi_ns_evaluate(info);
265 }
266
267 /*
268 * If we are expecting a return value, and all went well above,
269 * copy the return value to an external object.
270 */
271 if (return_buffer) {
272 if (!info->return_object) {
273 return_buffer->length = 0;
274 } else {
275 if (ACPI_GET_DESCRIPTOR_TYPE(info->return_object) ==
276 ACPI_DESC_TYPE_NAMED) {
277 /*
278 * If we received a NS Node as a return object, this means that
279 * the object we are evaluating has nothing interesting to
280 * return (such as a mutex, etc.) We return an error because
281 * these types are essentially unsupported by this interface.
282 * We don't check up front because this makes it easier to add
283 * support for various types at a later date if necessary.
284 */
285 status = AE_TYPE;
286 info->return_object = NULL; /* No need to delete a NS Node */
287 return_buffer->length = 0;
288 }
289
290 if (ACPI_SUCCESS(status)) {
291
292 /* Dereference Index and ref_of references */
293
294 acpi_ns_resolve_references(info);
295
296 /* Get the size of the returned object */
297
298 status =
299 acpi_ut_get_object_size(info->return_object,
300 &buffer_space_needed);
301 if (ACPI_SUCCESS(status)) {
302
303 /* Validate/Allocate/Clear caller buffer */
304
305 status =
306 acpi_ut_initialize_buffer
307 (return_buffer,
308 buffer_space_needed);
309 if (ACPI_FAILURE(status)) {
310 /*
311 * Caller's buffer is too small or a new one can't
312 * be allocated
313 */
314 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
315 "Needed buffer size %X, %s\n",
316 (u32)
317 buffer_space_needed,
318 acpi_format_exception
319 (status)));
320 } else {
321 /* We have enough space for the object, build it */
322
323 status =
324 acpi_ut_copy_iobject_to_eobject
325 (info->return_object,
326 return_buffer);
327 }
328 }
329 }
330 }
331 }
332
333 if (info->return_object) {
334 /*
335 * Delete the internal return object. NOTE: Interpreter must be
336 * locked to avoid race condition.
337 */
338 acpi_ex_enter_interpreter();
339
340 /* Remove one reference on the return object (should delete it) */
341
342 acpi_ut_remove_reference(info->return_object);
343 acpi_ex_exit_interpreter();
344 }
345
346 cleanup:
347
348 /* Free the input parameter list (if we created one) */
349
350 if (info->parameters) {
351
352 /* Free the allocated parameter block */
353
354 acpi_ut_delete_internal_object_list(info->parameters);
355 }
356
357 ACPI_FREE(info);
358 return_ACPI_STATUS(status);
359}
360
361ACPI_EXPORT_SYMBOL(acpi_evaluate_object)
362
363/*******************************************************************************
364 *
365 * FUNCTION: acpi_ns_resolve_references
366 *
367 * PARAMETERS: Info - Evaluation info block
368 *
369 * RETURN: Info->return_object is replaced with the dereferenced object
370 *
371 * DESCRIPTION: Dereference certain reference objects. Called before an
372 * internal return object is converted to an external union acpi_object.
373 *
374 * Performs an automatic dereference of Index and ref_of reference objects.
375 * These reference objects are not supported by the union acpi_object, so this is a
376 * last resort effort to return something useful. Also, provides compatibility
377 * with other ACPI implementations.
378 *
379 * NOTE: does not handle references within returned package objects or nested
380 * references, but this support could be added later if found to be necessary.
381 *
382 ******************************************************************************/
383static void acpi_ns_resolve_references(struct acpi_evaluate_info *info)
384{
385 union acpi_operand_object *obj_desc = NULL;
386 struct acpi_namespace_node *node;
387
388 /* We are interested in reference objects only */
389
390 if (ACPI_GET_OBJECT_TYPE(info->return_object) !=
391 ACPI_TYPE_LOCAL_REFERENCE) {
392 return;
393 }
394
395 /*
396 * Two types of references are supported - those created by Index and
397 * ref_of operators. A name reference (AML_NAMEPATH_OP) can be converted
398 * to an union acpi_object, so it is not dereferenced here. A ddb_handle
399 * (AML_LOAD_OP) cannot be dereferenced, nor can it be converted to
400 * an union acpi_object.
401 */
402 switch (info->return_object->reference.class) {
403 case ACPI_REFCLASS_INDEX:
404
405 obj_desc = *(info->return_object->reference.where);
406 break;
407
408 case ACPI_REFCLASS_REFOF:
409
410 node = info->return_object->reference.object;
411 if (node) {
412 obj_desc = node->object;
413 }
414 break;
415
416 default:
417 return;
418 }
419
420 /* Replace the existing reference object */
421
422 if (obj_desc) {
423 acpi_ut_add_reference(obj_desc);
424 acpi_ut_remove_reference(info->return_object);
425 info->return_object = obj_desc;
426 }
427
428 return;
429}
430
431/*******************************************************************************
432 *
433 * FUNCTION: acpi_walk_namespace
434 *
435 * PARAMETERS: Type - acpi_object_type to search for
436 * start_object - Handle in namespace where search begins
437 * max_depth - Depth to which search is to reach
438 * user_function - Called when an object of "Type" is found
439 * Context - Passed to user function
440 * return_value - Location where return value of
441 * user_function is put if terminated early
442 *
443 * RETURNS Return value from the user_function if terminated early.
444 * Otherwise, returns NULL.
445 *
446 * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
447 * starting (and ending) at the object specified by start_handle.
448 * The user_function is called whenever an object that matches
449 * the type parameter is found. If the user function returns
450 * a non-zero value, the search is terminated immediately and this
451 * value is returned to the caller.
452 *
453 * The point of this procedure is to provide a generic namespace
454 * walk routine that can be called from multiple places to
455 * provide multiple services; the User Function can be tailored
456 * to each task, whether it is a print function, a compare
457 * function, etc.
458 *
459 ******************************************************************************/
460
461acpi_status
462acpi_walk_namespace(acpi_object_type type,
463 acpi_handle start_object,
464 u32 max_depth,
465 acpi_walk_callback user_function,
466 void *context, void **return_value)
467{
468 acpi_status status;
469
470 ACPI_FUNCTION_TRACE(acpi_walk_namespace);
471
472 /* Parameter validation */
473
474 if ((type > ACPI_TYPE_LOCAL_MAX) || (!max_depth) || (!user_function)) {
475 return_ACPI_STATUS(AE_BAD_PARAMETER);
476 }
477
478 /*
479 * Lock the namespace around the walk.
480 * The namespace will be unlocked/locked around each call
481 * to the user function - since this function
482 * must be allowed to make Acpi calls itself.
483 */
484 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
485 if (ACPI_FAILURE(status)) {
486 return_ACPI_STATUS(status);
487 }
488
489 status = acpi_ns_walk_namespace(type, start_object, max_depth,
490 ACPI_NS_WALK_UNLOCK,
491 user_function, context, return_value);
492
493 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
494 return_ACPI_STATUS(status);
495}
496
497ACPI_EXPORT_SYMBOL(acpi_walk_namespace)
498
499/*******************************************************************************
500 *
501 * FUNCTION: acpi_ns_get_device_callback
502 *
503 * PARAMETERS: Callback from acpi_get_device
504 *
505 * RETURN: Status
506 *
507 * DESCRIPTION: Takes callbacks from walk_namespace and filters out all non-
508 * present devices, or if they specified a HID, it filters based
509 * on that.
510 *
511 ******************************************************************************/
512static acpi_status
513acpi_ns_get_device_callback(acpi_handle obj_handle,
514 u32 nesting_level,
515 void *context, void **return_value)
516{
517 struct acpi_get_devices_info *info = context;
518 acpi_status status;
519 struct acpi_namespace_node *node;
520 u32 flags;
521 struct acpica_device_id hid;
522 struct acpi_compatible_id_list *cid;
523 u32 i;
524 int found;
525
526 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
527 if (ACPI_FAILURE(status)) {
528 return (status);
529 }
530
531 node = acpi_ns_map_handle_to_node(obj_handle);
532 status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
533 if (ACPI_FAILURE(status)) {
534 return (status);
535 }
536
537 if (!node) {
538 return (AE_BAD_PARAMETER);
539 }
540
541 /* Run _STA to determine if device is present */
542
543 status = acpi_ut_execute_STA(node, &flags);
544 if (ACPI_FAILURE(status)) {
545 return (AE_CTRL_DEPTH);
546 }
547
548 if (!(flags & ACPI_STA_DEVICE_PRESENT) &&
549 !(flags & ACPI_STA_DEVICE_FUNCTIONING)) {
550 /*
551 * Don't examine the children of the device only when the
552 * device is neither present nor functional. See ACPI spec,
553 * description of _STA for more information.
554 */
555 return (AE_CTRL_DEPTH);
556 }
557
558 /* Filter based on device HID & CID */
559
560 if (info->hid != NULL) {
561 status = acpi_ut_execute_HID(node, &hid);
562 if (status == AE_NOT_FOUND) {
563 return (AE_OK);
564 } else if (ACPI_FAILURE(status)) {
565 return (AE_CTRL_DEPTH);
566 }
567
568 if (ACPI_STRNCMP(hid.value, info->hid, sizeof(hid.value)) != 0) {
569
570 /* Get the list of Compatible IDs */
571
572 status = acpi_ut_execute_CID(node, &cid);
573 if (status == AE_NOT_FOUND) {
574 return (AE_OK);
575 } else if (ACPI_FAILURE(status)) {
576 return (AE_CTRL_DEPTH);
577 }
578
579 /* Walk the CID list */
580
581 found = 0;
582 for (i = 0; i < cid->count; i++) {
583 if (ACPI_STRNCMP(cid->id[i].value, info->hid,
584 sizeof(struct
585 acpi_compatible_id)) ==
586 0) {
587 found = 1;
588 break;
589 }
590 }
591 ACPI_FREE(cid);
592 if (!found)
593 return (AE_OK);
594 }
595 }
596
597 status = info->user_function(obj_handle, nesting_level, info->context,
598 return_value);
599 return (status);
600}
601
602/*******************************************************************************
603 *
604 * FUNCTION: acpi_get_devices
605 *
606 * PARAMETERS: HID - HID to search for. Can be NULL.
607 * user_function - Called when a matching object is found
608 * Context - Passed to user function
609 * return_value - Location where return value of
610 * user_function is put if terminated early
611 *
612 * RETURNS Return value from the user_function if terminated early.
613 * Otherwise, returns NULL.
614 *
615 * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
616 * starting (and ending) at the object specified by start_handle.
617 * The user_function is called whenever an object of type
618 * Device is found. If the user function returns
619 * a non-zero value, the search is terminated immediately and this
620 * value is returned to the caller.
621 *
622 * This is a wrapper for walk_namespace, but the callback performs
623 * additional filtering. Please see acpi_ns_get_device_callback.
624 *
625 ******************************************************************************/
626
627acpi_status
628acpi_get_devices(const char *HID,
629 acpi_walk_callback user_function,
630 void *context, void **return_value)
631{
632 acpi_status status;
633 struct acpi_get_devices_info info;
634
635 ACPI_FUNCTION_TRACE(acpi_get_devices);
636
637 /* Parameter validation */
638
639 if (!user_function) {
640 return_ACPI_STATUS(AE_BAD_PARAMETER);
641 }
642
643 /*
644 * We're going to call their callback from OUR callback, so we need
645 * to know what it is, and their context parameter.
646 */
647 info.hid = HID;
648 info.context = context;
649 info.user_function = user_function;
650
651 /*
652 * Lock the namespace around the walk.
653 * The namespace will be unlocked/locked around each call
654 * to the user function - since this function
655 * must be allowed to make Acpi calls itself.
656 */
657 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
658 if (ACPI_FAILURE(status)) {
659 return_ACPI_STATUS(status);
660 }
661
662 status = acpi_ns_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
663 ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK,
664 acpi_ns_get_device_callback, &info,
665 return_value);
666
667 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
668 return_ACPI_STATUS(status);
669}
670
671ACPI_EXPORT_SYMBOL(acpi_get_devices)
672
673/*******************************************************************************
674 *
675 * FUNCTION: acpi_attach_data
676 *
677 * PARAMETERS: obj_handle - Namespace node
678 * Handler - Handler for this attachment
679 * Data - Pointer to data to be attached
680 *
681 * RETURN: Status
682 *
683 * DESCRIPTION: Attach arbitrary data and handler to a namespace node.
684 *
685 ******************************************************************************/
686acpi_status
687acpi_attach_data(acpi_handle obj_handle,
688 acpi_object_handler handler, void *data)
689{
690 struct acpi_namespace_node *node;
691 acpi_status status;
692
693 /* Parameter validation */
694
695 if (!obj_handle || !handler || !data) {
696 return (AE_BAD_PARAMETER);
697 }
698
699 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
700 if (ACPI_FAILURE(status)) {
701 return (status);
702 }
703
704 /* Convert and validate the handle */
705
706 node = acpi_ns_map_handle_to_node(obj_handle);
707 if (!node) {
708 status = AE_BAD_PARAMETER;
709 goto unlock_and_exit;
710 }
711
712 status = acpi_ns_attach_data(node, handler, data);
713
714 unlock_and_exit:
715 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
716 return (status);
717}
718
719ACPI_EXPORT_SYMBOL(acpi_attach_data)
720
721/*******************************************************************************
722 *
723 * FUNCTION: acpi_detach_data
724 *
725 * PARAMETERS: obj_handle - Namespace node handle
726 * Handler - Handler used in call to acpi_attach_data
727 *
728 * RETURN: Status
729 *
730 * DESCRIPTION: Remove data that was previously attached to a node.
731 *
732 ******************************************************************************/
733acpi_status
734acpi_detach_data(acpi_handle obj_handle, acpi_object_handler handler)
735{
736 struct acpi_namespace_node *node;
737 acpi_status status;
738
739 /* Parameter validation */
740
741 if (!obj_handle || !handler) {
742 return (AE_BAD_PARAMETER);
743 }
744
745 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
746 if (ACPI_FAILURE(status)) {
747 return (status);
748 }
749
750 /* Convert and validate the handle */
751
752 node = acpi_ns_map_handle_to_node(obj_handle);
753 if (!node) {
754 status = AE_BAD_PARAMETER;
755 goto unlock_and_exit;
756 }
757
758 status = acpi_ns_detach_data(node, handler);
759
760 unlock_and_exit:
761 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
762 return (status);
763}
764
765ACPI_EXPORT_SYMBOL(acpi_detach_data)
766
767/*******************************************************************************
768 *
769 * FUNCTION: acpi_get_data
770 *
771 * PARAMETERS: obj_handle - Namespace node
772 * Handler - Handler used in call to attach_data
773 * Data - Where the data is returned
774 *
775 * RETURN: Status
776 *
777 * DESCRIPTION: Retrieve data that was previously attached to a namespace node.
778 *
779 ******************************************************************************/
780acpi_status
781acpi_get_data(acpi_handle obj_handle, acpi_object_handler handler, void **data)
782{
783 struct acpi_namespace_node *node;
784 acpi_status status;
785
786 /* Parameter validation */
787
788 if (!obj_handle || !handler || !data) {
789 return (AE_BAD_PARAMETER);
790 }
791
792 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
793 if (ACPI_FAILURE(status)) {
794 return (status);
795 }
796
797 /* Convert and validate the handle */
798
799 node = acpi_ns_map_handle_to_node(obj_handle);
800 if (!node) {
801 status = AE_BAD_PARAMETER;
802 goto unlock_and_exit;
803 }
804
805 status = acpi_ns_get_attached_data(node, handler, data);
806
807 unlock_and_exit:
808 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
809 return (status);
810}
811
812ACPI_EXPORT_SYMBOL(acpi_get_data)
diff --git a/drivers/acpi/acpica/nsxfname.c b/drivers/acpi/acpica/nsxfname.c
new file mode 100644
index 00000000000..7d5bfa9e9fe
--- /dev/null
+++ b/drivers/acpi/acpica/nsxfname.c
@@ -0,0 +1,360 @@
1/******************************************************************************
2 *
3 * Module Name: nsxfname - Public interfaces to the ACPI subsystem
4 * ACPI Namespace oriented interfaces
5 *
6 *****************************************************************************/
7
8/*
9 * Copyright (C) 2000 - 2008, Intel Corp.
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions, and the following disclaimer,
17 * without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 * substantially similar to the "NO WARRANTY" disclaimer below
20 * ("Disclaimer") and any redistribution must be conditioned upon
21 * including a substantially similar Disclaimer requirement for further
22 * binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 * of any contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
30 *
31 * NO WARRANTY
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
43 */
44
45#include <acpi/acpi.h>
46#include <acpi/accommon.h>
47#include <acpi/acnamesp.h>
48
49#define _COMPONENT ACPI_NAMESPACE
50ACPI_MODULE_NAME("nsxfname")
51
52/******************************************************************************
53 *
54 * FUNCTION: acpi_get_handle
55 *
56 * PARAMETERS: Parent - Object to search under (search scope).
57 * Pathname - Pointer to an asciiz string containing the
58 * name
59 * ret_handle - Where the return handle is returned
60 *
61 * RETURN: Status
62 *
63 * DESCRIPTION: This routine will search for a caller specified name in the
64 * name space. The caller can restrict the search region by
65 * specifying a non NULL parent. The parent value is itself a
66 * namespace handle.
67 *
68 ******************************************************************************/
69acpi_status
70acpi_get_handle(acpi_handle parent,
71 acpi_string pathname, acpi_handle * ret_handle)
72{
73 acpi_status status;
74 struct acpi_namespace_node *node = NULL;
75 struct acpi_namespace_node *prefix_node = NULL;
76
77 ACPI_FUNCTION_ENTRY();
78
79 /* Parameter Validation */
80
81 if (!ret_handle || !pathname) {
82 return (AE_BAD_PARAMETER);
83 }
84
85 /* Convert a parent handle to a prefix node */
86
87 if (parent) {
88 prefix_node = acpi_ns_map_handle_to_node(parent);
89 if (!prefix_node) {
90 return (AE_BAD_PARAMETER);
91 }
92 }
93
94 /*
95 * Valid cases are:
96 * 1) Fully qualified pathname
97 * 2) Parent + Relative pathname
98 *
99 * Error for <null Parent + relative path>
100 */
101 if (acpi_ns_valid_root_prefix(pathname[0])) {
102
103 /* Pathname is fully qualified (starts with '\') */
104
105 /* Special case for root-only, since we can't search for it */
106
107 if (!ACPI_STRCMP(pathname, ACPI_NS_ROOT_PATH)) {
108 *ret_handle =
109 acpi_ns_convert_entry_to_handle(acpi_gbl_root_node);
110 return (AE_OK);
111 }
112 } else if (!prefix_node) {
113
114 /* Relative path with null prefix is disallowed */
115
116 return (AE_BAD_PARAMETER);
117 }
118
119 /* Find the Node and convert to a handle */
120
121 status =
122 acpi_ns_get_node(prefix_node, pathname, ACPI_NS_NO_UPSEARCH, &node);
123 if (ACPI_SUCCESS(status)) {
124 *ret_handle = acpi_ns_convert_entry_to_handle(node);
125 }
126
127 return (status);
128}
129
130ACPI_EXPORT_SYMBOL(acpi_get_handle)
131
132/******************************************************************************
133 *
134 * FUNCTION: acpi_get_name
135 *
136 * PARAMETERS: Handle - Handle to be converted to a pathname
137 * name_type - Full pathname or single segment
138 * Buffer - Buffer for returned path
139 *
140 * RETURN: Pointer to a string containing the fully qualified Name.
141 *
142 * DESCRIPTION: This routine returns the fully qualified name associated with
143 * the Handle parameter. This and the acpi_pathname_to_handle are
144 * complementary functions.
145 *
146 ******************************************************************************/
147acpi_status
148acpi_get_name(acpi_handle handle, u32 name_type, struct acpi_buffer * buffer)
149{
150 acpi_status status;
151 struct acpi_namespace_node *node;
152
153 /* Parameter validation */
154
155 if (name_type > ACPI_NAME_TYPE_MAX) {
156 return (AE_BAD_PARAMETER);
157 }
158
159 status = acpi_ut_validate_buffer(buffer);
160 if (ACPI_FAILURE(status)) {
161 return (status);
162 }
163
164 if (name_type == ACPI_FULL_PATHNAME) {
165
166 /* Get the full pathname (From the namespace root) */
167
168 status = acpi_ns_handle_to_pathname(handle, buffer);
169 return (status);
170 }
171
172 /*
173 * Wants the single segment ACPI name.
174 * Validate handle and convert to a namespace Node
175 */
176 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
177 if (ACPI_FAILURE(status)) {
178 return (status);
179 }
180
181 node = acpi_ns_map_handle_to_node(handle);
182 if (!node) {
183 status = AE_BAD_PARAMETER;
184 goto unlock_and_exit;
185 }
186
187 /* Validate/Allocate/Clear caller buffer */
188
189 status = acpi_ut_initialize_buffer(buffer, ACPI_PATH_SEGMENT_LENGTH);
190 if (ACPI_FAILURE(status)) {
191 goto unlock_and_exit;
192 }
193
194 /* Just copy the ACPI name from the Node and zero terminate it */
195
196 ACPI_STRNCPY(buffer->pointer, acpi_ut_get_node_name(node),
197 ACPI_NAME_SIZE);
198 ((char *)buffer->pointer)[ACPI_NAME_SIZE] = 0;
199 status = AE_OK;
200
201 unlock_and_exit:
202
203 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
204 return (status);
205}
206
207ACPI_EXPORT_SYMBOL(acpi_get_name)
208
209/******************************************************************************
210 *
211 * FUNCTION: acpi_get_object_info
212 *
213 * PARAMETERS: Handle - Object Handle
214 * Buffer - Where the info is returned
215 *
216 * RETURN: Status
217 *
218 * DESCRIPTION: Returns information about an object as gleaned from the
219 * namespace node and possibly by running several standard
220 * control methods (Such as in the case of a device.)
221 *
222 ******************************************************************************/
223acpi_status
224acpi_get_object_info(acpi_handle handle, struct acpi_buffer * buffer)
225{
226 acpi_status status;
227 struct acpi_namespace_node *node;
228 struct acpi_device_info *info;
229 struct acpi_device_info *return_info;
230 struct acpi_compatible_id_list *cid_list = NULL;
231 acpi_size size;
232
233 /* Parameter validation */
234
235 if (!handle || !buffer) {
236 return (AE_BAD_PARAMETER);
237 }
238
239 status = acpi_ut_validate_buffer(buffer);
240 if (ACPI_FAILURE(status)) {
241 return (status);
242 }
243
244 info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_device_info));
245 if (!info) {
246 return (AE_NO_MEMORY);
247 }
248
249 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
250 if (ACPI_FAILURE(status)) {
251 goto cleanup;
252 }
253
254 node = acpi_ns_map_handle_to_node(handle);
255 if (!node) {
256 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
257 status = AE_BAD_PARAMETER;
258 goto cleanup;
259 }
260
261 /* Init return structure */
262
263 size = sizeof(struct acpi_device_info);
264
265 info->type = node->type;
266 info->name = node->name.integer;
267 info->valid = 0;
268
269 if (node->type == ACPI_TYPE_METHOD) {
270 info->param_count = node->object->method.param_count;
271 }
272
273 status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
274 if (ACPI_FAILURE(status)) {
275 goto cleanup;
276 }
277
278 /* If not a device, we are all done */
279
280 if (info->type == ACPI_TYPE_DEVICE) {
281 /*
282 * Get extra info for ACPI Devices objects only:
283 * Run the Device _HID, _UID, _CID, _STA, _ADR and _sx_d methods.
284 *
285 * Note: none of these methods are required, so they may or may
286 * not be present for this device. The Info->Valid bitfield is used
287 * to indicate which methods were found and ran successfully.
288 */
289
290 /* Execute the Device._HID method */
291
292 status = acpi_ut_execute_HID(node, &info->hardware_id);
293 if (ACPI_SUCCESS(status)) {
294 info->valid |= ACPI_VALID_HID;
295 }
296
297 /* Execute the Device._UID method */
298
299 status = acpi_ut_execute_UID(node, &info->unique_id);
300 if (ACPI_SUCCESS(status)) {
301 info->valid |= ACPI_VALID_UID;
302 }
303
304 /* Execute the Device._CID method */
305
306 status = acpi_ut_execute_CID(node, &cid_list);
307 if (ACPI_SUCCESS(status)) {
308 size += cid_list->size;
309 info->valid |= ACPI_VALID_CID;
310 }
311
312 /* Execute the Device._STA method */
313
314 status = acpi_ut_execute_STA(node, &info->current_status);
315 if (ACPI_SUCCESS(status)) {
316 info->valid |= ACPI_VALID_STA;
317 }
318
319 /* Execute the Device._ADR method */
320
321 status = acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR, node,
322 &info->address);
323 if (ACPI_SUCCESS(status)) {
324 info->valid |= ACPI_VALID_ADR;
325 }
326
327 /* Execute the Device._sx_d methods */
328
329 status = acpi_ut_execute_sxds(node, info->highest_dstates);
330 if (ACPI_SUCCESS(status)) {
331 info->valid |= ACPI_VALID_SXDS;
332 }
333 }
334
335 /* Validate/Allocate/Clear caller buffer */
336
337 status = acpi_ut_initialize_buffer(buffer, size);
338 if (ACPI_FAILURE(status)) {
339 goto cleanup;
340 }
341
342 /* Populate the return buffer */
343
344 return_info = buffer->pointer;
345 ACPI_MEMCPY(return_info, info, sizeof(struct acpi_device_info));
346
347 if (cid_list) {
348 ACPI_MEMCPY(&return_info->compatibility_id, cid_list,
349 cid_list->size);
350 }
351
352 cleanup:
353 ACPI_FREE(info);
354 if (cid_list) {
355 ACPI_FREE(cid_list);
356 }
357 return (status);
358}
359
360ACPI_EXPORT_SYMBOL(acpi_get_object_info)
diff --git a/drivers/acpi/acpica/nsxfobj.c b/drivers/acpi/acpica/nsxfobj.c
new file mode 100644
index 00000000000..80e6322d59c
--- /dev/null
+++ b/drivers/acpi/acpica/nsxfobj.c
@@ -0,0 +1,287 @@
1/*******************************************************************************
2 *
3 * Module Name: nsxfobj - Public interfaces to the ACPI subsystem
4 * ACPI Object oriented interfaces
5 *
6 ******************************************************************************/
7
8/*
9 * Copyright (C) 2000 - 2008, Intel Corp.
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions, and the following disclaimer,
17 * without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 * substantially similar to the "NO WARRANTY" disclaimer below
20 * ("Disclaimer") and any redistribution must be conditioned upon
21 * including a substantially similar Disclaimer requirement for further
22 * binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 * of any contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
30 *
31 * NO WARRANTY
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
43 */
44
45#include <acpi/acpi.h>
46#include <acpi/accommon.h>
47#include <acpi/acnamesp.h>
48
49#define _COMPONENT ACPI_NAMESPACE
50ACPI_MODULE_NAME("nsxfobj")
51
52/*******************************************************************************
53 *
54 * FUNCTION: acpi_get_id
55 *
56 * PARAMETERS: Handle - Handle of object whose id is desired
57 * ret_id - Where the id will be placed
58 *
59 * RETURN: Status
60 *
61 * DESCRIPTION: This routine returns the owner id associated with a handle
62 *
63 ******************************************************************************/
64acpi_status acpi_get_id(acpi_handle handle, acpi_owner_id * ret_id)
65{
66 struct acpi_namespace_node *node;
67 acpi_status status;
68
69 /* Parameter Validation */
70
71 if (!ret_id) {
72 return (AE_BAD_PARAMETER);
73 }
74
75 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
76 if (ACPI_FAILURE(status)) {
77 return (status);
78 }
79
80 /* Convert and validate the handle */
81
82 node = acpi_ns_map_handle_to_node(handle);
83 if (!node) {
84 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
85 return (AE_BAD_PARAMETER);
86 }
87
88 *ret_id = node->owner_id;
89
90 status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
91 return (status);
92}
93
94ACPI_EXPORT_SYMBOL(acpi_get_id)
95
96/*******************************************************************************
97 *
98 * FUNCTION: acpi_get_type
99 *
100 * PARAMETERS: Handle - Handle of object whose type is desired
101 * ret_type - Where the type will be placed
102 *
103 * RETURN: Status
104 *
105 * DESCRIPTION: This routine returns the type associatd with a particular handle
106 *
107 ******************************************************************************/
108acpi_status acpi_get_type(acpi_handle handle, acpi_object_type * ret_type)
109{
110 struct acpi_namespace_node *node;
111 acpi_status status;
112
113 /* Parameter Validation */
114
115 if (!ret_type) {
116 return (AE_BAD_PARAMETER);
117 }
118
119 /*
120 * Special case for the predefined Root Node
121 * (return type ANY)
122 */
123 if (handle == ACPI_ROOT_OBJECT) {
124 *ret_type = ACPI_TYPE_ANY;
125 return (AE_OK);
126 }
127
128 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
129 if (ACPI_FAILURE(status)) {
130 return (status);
131 }
132
133 /* Convert and validate the handle */
134
135 node = acpi_ns_map_handle_to_node(handle);
136 if (!node) {
137 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
138 return (AE_BAD_PARAMETER);
139 }
140
141 *ret_type = node->type;
142
143 status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
144 return (status);
145}
146
147ACPI_EXPORT_SYMBOL(acpi_get_type)
148
149/*******************************************************************************
150 *
151 * FUNCTION: acpi_get_parent
152 *
153 * PARAMETERS: Handle - Handle of object whose parent is desired
154 * ret_handle - Where the parent handle will be placed
155 *
156 * RETURN: Status
157 *
158 * DESCRIPTION: Returns a handle to the parent of the object represented by
159 * Handle.
160 *
161 ******************************************************************************/
162acpi_status acpi_get_parent(acpi_handle handle, acpi_handle * ret_handle)
163{
164 struct acpi_namespace_node *node;
165 acpi_status status;
166
167 if (!ret_handle) {
168 return (AE_BAD_PARAMETER);
169 }
170
171 /* Special case for the predefined Root Node (no parent) */
172
173 if (handle == ACPI_ROOT_OBJECT) {
174 return (AE_NULL_ENTRY);
175 }
176
177 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
178 if (ACPI_FAILURE(status)) {
179 return (status);
180 }
181
182 /* Convert and validate the handle */
183
184 node = acpi_ns_map_handle_to_node(handle);
185 if (!node) {
186 status = AE_BAD_PARAMETER;
187 goto unlock_and_exit;
188 }
189
190 /* Get the parent entry */
191
192 *ret_handle =
193 acpi_ns_convert_entry_to_handle(acpi_ns_get_parent_node(node));
194
195 /* Return exception if parent is null */
196
197 if (!acpi_ns_get_parent_node(node)) {
198 status = AE_NULL_ENTRY;
199 }
200
201 unlock_and_exit:
202
203 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
204 return (status);
205}
206
207ACPI_EXPORT_SYMBOL(acpi_get_parent)
208
209/*******************************************************************************
210 *
211 * FUNCTION: acpi_get_next_object
212 *
213 * PARAMETERS: Type - Type of object to be searched for
214 * Parent - Parent object whose children we are getting
215 * last_child - Previous child that was found.
216 * The NEXT child will be returned
217 * ret_handle - Where handle to the next object is placed
218 *
219 * RETURN: Status
220 *
221 * DESCRIPTION: Return the next peer object within the namespace. If Handle is
222 * valid, Scope is ignored. Otherwise, the first object within
223 * Scope is returned.
224 *
225 ******************************************************************************/
226acpi_status
227acpi_get_next_object(acpi_object_type type,
228 acpi_handle parent,
229 acpi_handle child, acpi_handle * ret_handle)
230{
231 acpi_status status;
232 struct acpi_namespace_node *node;
233 struct acpi_namespace_node *parent_node = NULL;
234 struct acpi_namespace_node *child_node = NULL;
235
236 /* Parameter validation */
237
238 if (type > ACPI_TYPE_EXTERNAL_MAX) {
239 return (AE_BAD_PARAMETER);
240 }
241
242 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
243 if (ACPI_FAILURE(status)) {
244 return (status);
245 }
246
247 /* If null handle, use the parent */
248
249 if (!child) {
250
251 /* Start search at the beginning of the specified scope */
252
253 parent_node = acpi_ns_map_handle_to_node(parent);
254 if (!parent_node) {
255 status = AE_BAD_PARAMETER;
256 goto unlock_and_exit;
257 }
258 } else {
259 /* Non-null handle, ignore the parent */
260 /* Convert and validate the handle */
261
262 child_node = acpi_ns_map_handle_to_node(child);
263 if (!child_node) {
264 status = AE_BAD_PARAMETER;
265 goto unlock_and_exit;
266 }
267 }
268
269 /* Internal function does the real work */
270
271 node = acpi_ns_get_next_node(type, parent_node, child_node);
272 if (!node) {
273 status = AE_NOT_FOUND;
274 goto unlock_and_exit;
275 }
276
277 if (ret_handle) {
278 *ret_handle = acpi_ns_convert_entry_to_handle(node);
279 }
280
281 unlock_and_exit:
282
283 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
284 return (status);
285}
286
287ACPI_EXPORT_SYMBOL(acpi_get_next_object)
diff --git a/drivers/acpi/acpica/psargs.c b/drivers/acpi/acpica/psargs.c
new file mode 100644
index 00000000000..852f3a83b2e
--- /dev/null
+++ b/drivers/acpi/acpica/psargs.c
@@ -0,0 +1,752 @@
1/******************************************************************************
2 *
3 * Module Name: psargs - Parse AML opcode arguments
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46#include <acpi/acparser.h>
47#include <acpi/amlcode.h>
48#include <acpi/acnamesp.h>
49#include <acpi/acdispat.h>
50
51#define _COMPONENT ACPI_PARSER
52ACPI_MODULE_NAME("psargs")
53
54/* Local prototypes */
55static u32
56acpi_ps_get_next_package_length(struct acpi_parse_state *parser_state);
57
58static union acpi_parse_object *acpi_ps_get_next_field(struct acpi_parse_state
59 *parser_state);
60
61/*******************************************************************************
62 *
63 * FUNCTION: acpi_ps_get_next_package_length
64 *
65 * PARAMETERS: parser_state - Current parser state object
66 *
67 * RETURN: Decoded package length. On completion, the AML pointer points
68 * past the length byte or bytes.
69 *
70 * DESCRIPTION: Decode and return a package length field.
71 * Note: Largest package length is 28 bits, from ACPI specification
72 *
73 ******************************************************************************/
74
75static u32
76acpi_ps_get_next_package_length(struct acpi_parse_state *parser_state)
77{
78 u8 *aml = parser_state->aml;
79 u32 package_length = 0;
80 u32 byte_count;
81 u8 byte_zero_mask = 0x3F; /* Default [0:5] */
82
83 ACPI_FUNCTION_TRACE(ps_get_next_package_length);
84
85 /*
86 * Byte 0 bits [6:7] contain the number of additional bytes
87 * used to encode the package length, either 0,1,2, or 3
88 */
89 byte_count = (aml[0] >> 6);
90 parser_state->aml += ((acpi_size) byte_count + 1);
91
92 /* Get bytes 3, 2, 1 as needed */
93
94 while (byte_count) {
95 /*
96 * Final bit positions for the package length bytes:
97 * Byte3->[20:27]
98 * Byte2->[12:19]
99 * Byte1->[04:11]
100 * Byte0->[00:03]
101 */
102 package_length |= (aml[byte_count] << ((byte_count << 3) - 4));
103
104 byte_zero_mask = 0x0F; /* Use bits [0:3] of byte 0 */
105 byte_count--;
106 }
107
108 /* Byte 0 is a special case, either bits [0:3] or [0:5] are used */
109
110 package_length |= (aml[0] & byte_zero_mask);
111 return_UINT32(package_length);
112}
113
114/*******************************************************************************
115 *
116 * FUNCTION: acpi_ps_get_next_package_end
117 *
118 * PARAMETERS: parser_state - Current parser state object
119 *
120 * RETURN: Pointer to end-of-package +1
121 *
122 * DESCRIPTION: Get next package length and return a pointer past the end of
123 * the package. Consumes the package length field
124 *
125 ******************************************************************************/
126
127u8 *acpi_ps_get_next_package_end(struct acpi_parse_state *parser_state)
128{
129 u8 *start = parser_state->aml;
130 u32 package_length;
131
132 ACPI_FUNCTION_TRACE(ps_get_next_package_end);
133
134 /* Function below updates parser_state->Aml */
135
136 package_length = acpi_ps_get_next_package_length(parser_state);
137
138 return_PTR(start + package_length); /* end of package */
139}
140
141/*******************************************************************************
142 *
143 * FUNCTION: acpi_ps_get_next_namestring
144 *
145 * PARAMETERS: parser_state - Current parser state object
146 *
147 * RETURN: Pointer to the start of the name string (pointer points into
148 * the AML.
149 *
150 * DESCRIPTION: Get next raw namestring within the AML stream. Handles all name
151 * prefix characters. Set parser state to point past the string.
152 * (Name is consumed from the AML.)
153 *
154 ******************************************************************************/
155
156char *acpi_ps_get_next_namestring(struct acpi_parse_state *parser_state)
157{
158 u8 *start = parser_state->aml;
159 u8 *end = parser_state->aml;
160
161 ACPI_FUNCTION_TRACE(ps_get_next_namestring);
162
163 /* Point past any namestring prefix characters (backslash or carat) */
164
165 while (acpi_ps_is_prefix_char(*end)) {
166 end++;
167 }
168
169 /* Decode the path prefix character */
170
171 switch (*end) {
172 case 0:
173
174 /* null_name */
175
176 if (end == start) {
177 start = NULL;
178 }
179 end++;
180 break;
181
182 case AML_DUAL_NAME_PREFIX:
183
184 /* Two name segments */
185
186 end += 1 + (2 * ACPI_NAME_SIZE);
187 break;
188
189 case AML_MULTI_NAME_PREFIX_OP:
190
191 /* Multiple name segments, 4 chars each, count in next byte */
192
193 end += 2 + (*(end + 1) * ACPI_NAME_SIZE);
194 break;
195
196 default:
197
198 /* Single name segment */
199
200 end += ACPI_NAME_SIZE;
201 break;
202 }
203
204 parser_state->aml = end;
205 return_PTR((char *)start);
206}
207
208/*******************************************************************************
209 *
210 * FUNCTION: acpi_ps_get_next_namepath
211 *
212 * PARAMETERS: parser_state - Current parser state object
213 * Arg - Where the namepath will be stored
214 * arg_count - If the namepath points to a control method
215 * the method's argument is returned here.
216 * possible_method_call - Whether the namepath can possibly be the
217 * start of a method call
218 *
219 * RETURN: Status
220 *
221 * DESCRIPTION: Get next name (if method call, return # of required args).
222 * Names are looked up in the internal namespace to determine
223 * if the name represents a control method. If a method
224 * is found, the number of arguments to the method is returned.
225 * This information is critical for parsing to continue correctly.
226 *
227 ******************************************************************************/
228
229acpi_status
230acpi_ps_get_next_namepath(struct acpi_walk_state *walk_state,
231 struct acpi_parse_state *parser_state,
232 union acpi_parse_object *arg, u8 possible_method_call)
233{
234 acpi_status status;
235 char *path;
236 union acpi_parse_object *name_op;
237 union acpi_operand_object *method_desc;
238 struct acpi_namespace_node *node;
239 u8 *start = parser_state->aml;
240
241 ACPI_FUNCTION_TRACE(ps_get_next_namepath);
242
243 path = acpi_ps_get_next_namestring(parser_state);
244 acpi_ps_init_op(arg, AML_INT_NAMEPATH_OP);
245
246 /* Null path case is allowed, just exit */
247
248 if (!path) {
249 arg->common.value.name = path;
250 return_ACPI_STATUS(AE_OK);
251 }
252
253 /*
254 * Lookup the name in the internal namespace, starting with the current
255 * scope. We don't want to add anything new to the namespace here,
256 * however, so we use MODE_EXECUTE.
257 * Allow searching of the parent tree, but don't open a new scope -
258 * we just want to lookup the object (must be mode EXECUTE to perform
259 * the upsearch)
260 */
261 status = acpi_ns_lookup(walk_state->scope_info, path,
262 ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
263 ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
264 NULL, &node);
265
266 /*
267 * If this name is a control method invocation, we must
268 * setup the method call
269 */
270 if (ACPI_SUCCESS(status) &&
271 possible_method_call && (node->type == ACPI_TYPE_METHOD)) {
272 if (walk_state->opcode == AML_UNLOAD_OP) {
273 /*
274 * acpi_ps_get_next_namestring has increased the AML pointer,
275 * so we need to restore the saved AML pointer for method call.
276 */
277 walk_state->parser_state.aml = start;
278 walk_state->arg_count = 1;
279 acpi_ps_init_op(arg, AML_INT_METHODCALL_OP);
280 return_ACPI_STATUS(AE_OK);
281 }
282
283 /* This name is actually a control method invocation */
284
285 method_desc = acpi_ns_get_attached_object(node);
286 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
287 "Control Method - %p Desc %p Path=%p\n", node,
288 method_desc, path));
289
290 name_op = acpi_ps_alloc_op(AML_INT_NAMEPATH_OP);
291 if (!name_op) {
292 return_ACPI_STATUS(AE_NO_MEMORY);
293 }
294
295 /* Change Arg into a METHOD CALL and attach name to it */
296
297 acpi_ps_init_op(arg, AML_INT_METHODCALL_OP);
298 name_op->common.value.name = path;
299
300 /* Point METHODCALL/NAME to the METHOD Node */
301
302 name_op->common.node = node;
303 acpi_ps_append_arg(arg, name_op);
304
305 if (!method_desc) {
306 ACPI_ERROR((AE_INFO,
307 "Control Method %p has no attached object",
308 node));
309 return_ACPI_STATUS(AE_AML_INTERNAL);
310 }
311
312 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
313 "Control Method - %p Args %X\n",
314 node, method_desc->method.param_count));
315
316 /* Get the number of arguments to expect */
317
318 walk_state->arg_count = method_desc->method.param_count;
319 return_ACPI_STATUS(AE_OK);
320 }
321
322 /*
323 * Special handling if the name was not found during the lookup -
324 * some not_found cases are allowed
325 */
326 if (status == AE_NOT_FOUND) {
327
328 /* 1) not_found is ok during load pass 1/2 (allow forward references) */
329
330 if ((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) !=
331 ACPI_PARSE_EXECUTE) {
332 status = AE_OK;
333 }
334
335 /* 2) not_found during a cond_ref_of(x) is ok by definition */
336
337 else if (walk_state->op->common.aml_opcode ==
338 AML_COND_REF_OF_OP) {
339 status = AE_OK;
340 }
341
342 /*
343 * 3) not_found while building a Package is ok at this point, we
344 * may flag as an error later if slack mode is not enabled.
345 * (Some ASL code depends on allowing this behavior)
346 */
347 else if ((arg->common.parent) &&
348 ((arg->common.parent->common.aml_opcode ==
349 AML_PACKAGE_OP)
350 || (arg->common.parent->common.aml_opcode ==
351 AML_VAR_PACKAGE_OP))) {
352 status = AE_OK;
353 }
354 }
355
356 /* Final exception check (may have been changed from code above) */
357
358 if (ACPI_FAILURE(status)) {
359 ACPI_ERROR_NAMESPACE(path, status);
360
361 if ((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) ==
362 ACPI_PARSE_EXECUTE) {
363
364 /* Report a control method execution error */
365
366 status = acpi_ds_method_error(status, walk_state);
367 }
368 }
369
370 /* Save the namepath */
371
372 arg->common.value.name = path;
373 return_ACPI_STATUS(status);
374}
375
376/*******************************************************************************
377 *
378 * FUNCTION: acpi_ps_get_next_simple_arg
379 *
380 * PARAMETERS: parser_state - Current parser state object
381 * arg_type - The argument type (AML_*_ARG)
382 * Arg - Where the argument is returned
383 *
384 * RETURN: None
385 *
386 * DESCRIPTION: Get the next simple argument (constant, string, or namestring)
387 *
388 ******************************************************************************/
389
390void
391acpi_ps_get_next_simple_arg(struct acpi_parse_state *parser_state,
392 u32 arg_type, union acpi_parse_object *arg)
393{
394 u32 length;
395 u16 opcode;
396 u8 *aml = parser_state->aml;
397
398 ACPI_FUNCTION_TRACE_U32(ps_get_next_simple_arg, arg_type);
399
400 switch (arg_type) {
401 case ARGP_BYTEDATA:
402
403 /* Get 1 byte from the AML stream */
404
405 opcode = AML_BYTE_OP;
406 arg->common.value.integer = (acpi_integer) * aml;
407 length = 1;
408 break;
409
410 case ARGP_WORDDATA:
411
412 /* Get 2 bytes from the AML stream */
413
414 opcode = AML_WORD_OP;
415 ACPI_MOVE_16_TO_64(&arg->common.value.integer, aml);
416 length = 2;
417 break;
418
419 case ARGP_DWORDDATA:
420
421 /* Get 4 bytes from the AML stream */
422
423 opcode = AML_DWORD_OP;
424 ACPI_MOVE_32_TO_64(&arg->common.value.integer, aml);
425 length = 4;
426 break;
427
428 case ARGP_QWORDDATA:
429
430 /* Get 8 bytes from the AML stream */
431
432 opcode = AML_QWORD_OP;
433 ACPI_MOVE_64_TO_64(&arg->common.value.integer, aml);
434 length = 8;
435 break;
436
437 case ARGP_CHARLIST:
438
439 /* Get a pointer to the string, point past the string */
440
441 opcode = AML_STRING_OP;
442 arg->common.value.string = ACPI_CAST_PTR(char, aml);
443
444 /* Find the null terminator */
445
446 length = 0;
447 while (aml[length]) {
448 length++;
449 }
450 length++;
451 break;
452
453 case ARGP_NAME:
454 case ARGP_NAMESTRING:
455
456 acpi_ps_init_op(arg, AML_INT_NAMEPATH_OP);
457 arg->common.value.name =
458 acpi_ps_get_next_namestring(parser_state);
459 return_VOID;
460
461 default:
462
463 ACPI_ERROR((AE_INFO, "Invalid ArgType %X", arg_type));
464 return_VOID;
465 }
466
467 acpi_ps_init_op(arg, opcode);
468 parser_state->aml += length;
469 return_VOID;
470}
471
472/*******************************************************************************
473 *
474 * FUNCTION: acpi_ps_get_next_field
475 *
476 * PARAMETERS: parser_state - Current parser state object
477 *
478 * RETURN: A newly allocated FIELD op
479 *
480 * DESCRIPTION: Get next field (named_field, reserved_field, or access_field)
481 *
482 ******************************************************************************/
483
484static union acpi_parse_object *acpi_ps_get_next_field(struct acpi_parse_state
485 *parser_state)
486{
487 u32 aml_offset = (u32)
488 ACPI_PTR_DIFF(parser_state->aml,
489 parser_state->aml_start);
490 union acpi_parse_object *field;
491 u16 opcode;
492 u32 name;
493
494 ACPI_FUNCTION_TRACE(ps_get_next_field);
495
496 /* Determine field type */
497
498 switch (ACPI_GET8(parser_state->aml)) {
499 default:
500
501 opcode = AML_INT_NAMEDFIELD_OP;
502 break;
503
504 case 0x00:
505
506 opcode = AML_INT_RESERVEDFIELD_OP;
507 parser_state->aml++;
508 break;
509
510 case 0x01:
511
512 opcode = AML_INT_ACCESSFIELD_OP;
513 parser_state->aml++;
514 break;
515 }
516
517 /* Allocate a new field op */
518
519 field = acpi_ps_alloc_op(opcode);
520 if (!field) {
521 return_PTR(NULL);
522 }
523
524 field->common.aml_offset = aml_offset;
525
526 /* Decode the field type */
527
528 switch (opcode) {
529 case AML_INT_NAMEDFIELD_OP:
530
531 /* Get the 4-character name */
532
533 ACPI_MOVE_32_TO_32(&name, parser_state->aml);
534 acpi_ps_set_name(field, name);
535 parser_state->aml += ACPI_NAME_SIZE;
536
537 /* Get the length which is encoded as a package length */
538
539 field->common.value.size =
540 acpi_ps_get_next_package_length(parser_state);
541 break;
542
543 case AML_INT_RESERVEDFIELD_OP:
544
545 /* Get the length which is encoded as a package length */
546
547 field->common.value.size =
548 acpi_ps_get_next_package_length(parser_state);
549 break;
550
551 case AML_INT_ACCESSFIELD_OP:
552
553 /*
554 * Get access_type and access_attrib and merge into the field Op
555 * access_type is first operand, access_attribute is second
556 */
557 field->common.value.integer =
558 (((u32) ACPI_GET8(parser_state->aml) << 8));
559 parser_state->aml++;
560 field->common.value.integer |= ACPI_GET8(parser_state->aml);
561 parser_state->aml++;
562 break;
563
564 default:
565
566 /* Opcode was set in previous switch */
567 break;
568 }
569
570 return_PTR(field);
571}
572
573/*******************************************************************************
574 *
575 * FUNCTION: acpi_ps_get_next_arg
576 *
577 * PARAMETERS: walk_state - Current state
578 * parser_state - Current parser state object
579 * arg_type - The argument type (AML_*_ARG)
580 * return_arg - Where the next arg is returned
581 *
582 * RETURN: Status, and an op object containing the next argument.
583 *
584 * DESCRIPTION: Get next argument (including complex list arguments that require
585 * pushing the parser stack)
586 *
587 ******************************************************************************/
588
589acpi_status
590acpi_ps_get_next_arg(struct acpi_walk_state *walk_state,
591 struct acpi_parse_state *parser_state,
592 u32 arg_type, union acpi_parse_object **return_arg)
593{
594 union acpi_parse_object *arg = NULL;
595 union acpi_parse_object *prev = NULL;
596 union acpi_parse_object *field;
597 u32 subop;
598 acpi_status status = AE_OK;
599
600 ACPI_FUNCTION_TRACE_PTR(ps_get_next_arg, parser_state);
601
602 switch (arg_type) {
603 case ARGP_BYTEDATA:
604 case ARGP_WORDDATA:
605 case ARGP_DWORDDATA:
606 case ARGP_CHARLIST:
607 case ARGP_NAME:
608 case ARGP_NAMESTRING:
609
610 /* Constants, strings, and namestrings are all the same size */
611
612 arg = acpi_ps_alloc_op(AML_BYTE_OP);
613 if (!arg) {
614 return_ACPI_STATUS(AE_NO_MEMORY);
615 }
616 acpi_ps_get_next_simple_arg(parser_state, arg_type, arg);
617 break;
618
619 case ARGP_PKGLENGTH:
620
621 /* Package length, nothing returned */
622
623 parser_state->pkg_end =
624 acpi_ps_get_next_package_end(parser_state);
625 break;
626
627 case ARGP_FIELDLIST:
628
629 if (parser_state->aml < parser_state->pkg_end) {
630
631 /* Non-empty list */
632
633 while (parser_state->aml < parser_state->pkg_end) {
634 field = acpi_ps_get_next_field(parser_state);
635 if (!field) {
636 return_ACPI_STATUS(AE_NO_MEMORY);
637 }
638
639 if (prev) {
640 prev->common.next = field;
641 } else {
642 arg = field;
643 }
644 prev = field;
645 }
646
647 /* Skip to End of byte data */
648
649 parser_state->aml = parser_state->pkg_end;
650 }
651 break;
652
653 case ARGP_BYTELIST:
654
655 if (parser_state->aml < parser_state->pkg_end) {
656
657 /* Non-empty list */
658
659 arg = acpi_ps_alloc_op(AML_INT_BYTELIST_OP);
660 if (!arg) {
661 return_ACPI_STATUS(AE_NO_MEMORY);
662 }
663
664 /* Fill in bytelist data */
665
666 arg->common.value.size = (u32)
667 ACPI_PTR_DIFF(parser_state->pkg_end,
668 parser_state->aml);
669 arg->named.data = parser_state->aml;
670
671 /* Skip to End of byte data */
672
673 parser_state->aml = parser_state->pkg_end;
674 }
675 break;
676
677 case ARGP_TARGET:
678 case ARGP_SUPERNAME:
679 case ARGP_SIMPLENAME:
680
681 subop = acpi_ps_peek_opcode(parser_state);
682 if (subop == 0 ||
683 acpi_ps_is_leading_char(subop) ||
684 acpi_ps_is_prefix_char(subop)) {
685
686 /* null_name or name_string */
687
688 arg = acpi_ps_alloc_op(AML_INT_NAMEPATH_OP);
689 if (!arg) {
690 return_ACPI_STATUS(AE_NO_MEMORY);
691 }
692
693 /* To support super_name arg of Unload */
694
695 if (walk_state->opcode == AML_UNLOAD_OP) {
696 status =
697 acpi_ps_get_next_namepath(walk_state,
698 parser_state, arg,
699 1);
700
701 /*
702 * If the super_name arg of Unload is a method call,
703 * we have restored the AML pointer, just free this Arg
704 */
705 if (arg->common.aml_opcode ==
706 AML_INT_METHODCALL_OP) {
707 acpi_ps_free_op(arg);
708 arg = NULL;
709 }
710 } else {
711 status =
712 acpi_ps_get_next_namepath(walk_state,
713 parser_state, arg,
714 0);
715 }
716 } else {
717 /* Single complex argument, nothing returned */
718
719 walk_state->arg_count = 1;
720 }
721 break;
722
723 case ARGP_DATAOBJ:
724 case ARGP_TERMARG:
725
726 /* Single complex argument, nothing returned */
727
728 walk_state->arg_count = 1;
729 break;
730
731 case ARGP_DATAOBJLIST:
732 case ARGP_TERMLIST:
733 case ARGP_OBJLIST:
734
735 if (parser_state->aml < parser_state->pkg_end) {
736
737 /* Non-empty list of variable arguments, nothing returned */
738
739 walk_state->arg_count = ACPI_VAR_ARGS;
740 }
741 break;
742
743 default:
744
745 ACPI_ERROR((AE_INFO, "Invalid ArgType: %X", arg_type));
746 status = AE_AML_OPERAND_TYPE;
747 break;
748 }
749
750 *return_arg = arg;
751 return_ACPI_STATUS(status);
752}
diff --git a/drivers/acpi/acpica/psloop.c b/drivers/acpi/acpica/psloop.c
new file mode 100644
index 00000000000..fd6648f0d65
--- /dev/null
+++ b/drivers/acpi/acpica/psloop.c
@@ -0,0 +1,1088 @@
1/******************************************************************************
2 *
3 * Module Name: psloop - Main AML parse loop
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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 * Parse the AML and build an operation tree as most interpreters, (such as
46 * Perl) do. Parsing is done by hand rather than with a YACC generated parser
47 * to tightly constrain stack and dynamic memory usage. Parsing is kept
48 * flexible and the code fairly compact by parsing based on a list of AML
49 * opcode templates in aml_op_info[].
50 */
51
52#include <acpi/acpi.h>
53#include <acpi/accommon.h>
54#include <acpi/acparser.h>
55#include <acpi/acdispat.h>
56#include <acpi/amlcode.h>
57
58#define _COMPONENT ACPI_PARSER
59ACPI_MODULE_NAME("psloop")
60
61static u32 acpi_gbl_depth = 0;
62
63/* Local prototypes */
64
65static acpi_status acpi_ps_get_aml_opcode(struct acpi_walk_state *walk_state);
66
67static acpi_status
68acpi_ps_build_named_op(struct acpi_walk_state *walk_state,
69 u8 * aml_op_start,
70 union acpi_parse_object *unnamed_op,
71 union acpi_parse_object **op);
72
73static acpi_status
74acpi_ps_create_op(struct acpi_walk_state *walk_state,
75 u8 * aml_op_start, union acpi_parse_object **new_op);
76
77static acpi_status
78acpi_ps_get_arguments(struct acpi_walk_state *walk_state,
79 u8 * aml_op_start, union acpi_parse_object *op);
80
81static acpi_status
82acpi_ps_complete_op(struct acpi_walk_state *walk_state,
83 union acpi_parse_object **op, acpi_status status);
84
85static acpi_status
86acpi_ps_complete_final_op(struct acpi_walk_state *walk_state,
87 union acpi_parse_object *op, acpi_status status);
88
89/*******************************************************************************
90 *
91 * FUNCTION: acpi_ps_get_aml_opcode
92 *
93 * PARAMETERS: walk_state - Current state
94 *
95 * RETURN: Status
96 *
97 * DESCRIPTION: Extract the next AML opcode from the input stream.
98 *
99 ******************************************************************************/
100
101static acpi_status acpi_ps_get_aml_opcode(struct acpi_walk_state *walk_state)
102{
103
104 ACPI_FUNCTION_TRACE_PTR(ps_get_aml_opcode, walk_state);
105
106 walk_state->aml_offset =
107 (u32) ACPI_PTR_DIFF(walk_state->parser_state.aml,
108 walk_state->parser_state.aml_start);
109 walk_state->opcode = acpi_ps_peek_opcode(&(walk_state->parser_state));
110
111 /*
112 * First cut to determine what we have found:
113 * 1) A valid AML opcode
114 * 2) A name string
115 * 3) An unknown/invalid opcode
116 */
117 walk_state->op_info = acpi_ps_get_opcode_info(walk_state->opcode);
118
119 switch (walk_state->op_info->class) {
120 case AML_CLASS_ASCII:
121 case AML_CLASS_PREFIX:
122 /*
123 * Starts with a valid prefix or ASCII char, this is a name
124 * string. Convert the bare name string to a namepath.
125 */
126 walk_state->opcode = AML_INT_NAMEPATH_OP;
127 walk_state->arg_types = ARGP_NAMESTRING;
128 break;
129
130 case AML_CLASS_UNKNOWN:
131
132 /* The opcode is unrecognized. Just skip unknown opcodes */
133
134 ACPI_ERROR((AE_INFO,
135 "Found unknown opcode %X at AML address %p offset %X, ignoring",
136 walk_state->opcode, walk_state->parser_state.aml,
137 walk_state->aml_offset));
138
139 ACPI_DUMP_BUFFER(walk_state->parser_state.aml, 128);
140
141 /* Assume one-byte bad opcode */
142
143 walk_state->parser_state.aml++;
144 return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE);
145
146 default:
147
148 /* Found opcode info, this is a normal opcode */
149
150 walk_state->parser_state.aml +=
151 acpi_ps_get_opcode_size(walk_state->opcode);
152 walk_state->arg_types = walk_state->op_info->parse_args;
153 break;
154 }
155
156 return_ACPI_STATUS(AE_OK);
157}
158
159/*******************************************************************************
160 *
161 * FUNCTION: acpi_ps_build_named_op
162 *
163 * PARAMETERS: walk_state - Current state
164 * aml_op_start - Begin of named Op in AML
165 * unnamed_op - Early Op (not a named Op)
166 * Op - Returned Op
167 *
168 * RETURN: Status
169 *
170 * DESCRIPTION: Parse a named Op
171 *
172 ******************************************************************************/
173
174static acpi_status
175acpi_ps_build_named_op(struct acpi_walk_state *walk_state,
176 u8 * aml_op_start,
177 union acpi_parse_object *unnamed_op,
178 union acpi_parse_object **op)
179{
180 acpi_status status = AE_OK;
181 union acpi_parse_object *arg = NULL;
182
183 ACPI_FUNCTION_TRACE_PTR(ps_build_named_op, walk_state);
184
185 unnamed_op->common.value.arg = NULL;
186 unnamed_op->common.arg_list_length = 0;
187 unnamed_op->common.aml_opcode = walk_state->opcode;
188
189 /*
190 * Get and append arguments until we find the node that contains
191 * the name (the type ARGP_NAME).
192 */
193 while (GET_CURRENT_ARG_TYPE(walk_state->arg_types) &&
194 (GET_CURRENT_ARG_TYPE(walk_state->arg_types) != ARGP_NAME)) {
195 status =
196 acpi_ps_get_next_arg(walk_state,
197 &(walk_state->parser_state),
198 GET_CURRENT_ARG_TYPE(walk_state->
199 arg_types), &arg);
200 if (ACPI_FAILURE(status)) {
201 return_ACPI_STATUS(status);
202 }
203
204 acpi_ps_append_arg(unnamed_op, arg);
205 INCREMENT_ARG_LIST(walk_state->arg_types);
206 }
207
208 /*
209 * Make sure that we found a NAME and didn't run out of arguments
210 */
211 if (!GET_CURRENT_ARG_TYPE(walk_state->arg_types)) {
212 return_ACPI_STATUS(AE_AML_NO_OPERAND);
213 }
214
215 /* We know that this arg is a name, move to next arg */
216
217 INCREMENT_ARG_LIST(walk_state->arg_types);
218
219 /*
220 * Find the object. This will either insert the object into
221 * the namespace or simply look it up
222 */
223 walk_state->op = NULL;
224
225 status = walk_state->descending_callback(walk_state, op);
226 if (ACPI_FAILURE(status)) {
227 ACPI_EXCEPTION((AE_INFO, status, "During name lookup/catalog"));
228 return_ACPI_STATUS(status);
229 }
230
231 if (!*op) {
232 return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE);
233 }
234
235 status = acpi_ps_next_parse_state(walk_state, *op, status);
236 if (ACPI_FAILURE(status)) {
237 if (status == AE_CTRL_PENDING) {
238 return_ACPI_STATUS(AE_CTRL_PARSE_PENDING);
239 }
240 return_ACPI_STATUS(status);
241 }
242
243 acpi_ps_append_arg(*op, unnamed_op->common.value.arg);
244 acpi_gbl_depth++;
245
246 if ((*op)->common.aml_opcode == AML_REGION_OP ||
247 (*op)->common.aml_opcode == AML_DATA_REGION_OP) {
248 /*
249 * Defer final parsing of an operation_region body, because we don't
250 * have enough info in the first pass to parse it correctly (i.e.,
251 * there may be method calls within the term_arg elements of the body.)
252 *
253 * However, we must continue parsing because the opregion is not a
254 * standalone package -- we don't know where the end is at this point.
255 *
256 * (Length is unknown until parse of the body complete)
257 */
258 (*op)->named.data = aml_op_start;
259 (*op)->named.length = 0;
260 }
261
262 return_ACPI_STATUS(AE_OK);
263}
264
265/*******************************************************************************
266 *
267 * FUNCTION: acpi_ps_create_op
268 *
269 * PARAMETERS: walk_state - Current state
270 * aml_op_start - Op start in AML
271 * new_op - Returned Op
272 *
273 * RETURN: Status
274 *
275 * DESCRIPTION: Get Op from AML
276 *
277 ******************************************************************************/
278
279static acpi_status
280acpi_ps_create_op(struct acpi_walk_state *walk_state,
281 u8 * aml_op_start, union acpi_parse_object **new_op)
282{
283 acpi_status status = AE_OK;
284 union acpi_parse_object *op;
285 union acpi_parse_object *named_op = NULL;
286 union acpi_parse_object *parent_scope;
287 u8 argument_count;
288 const struct acpi_opcode_info *op_info;
289
290 ACPI_FUNCTION_TRACE_PTR(ps_create_op, walk_state);
291
292 status = acpi_ps_get_aml_opcode(walk_state);
293 if (status == AE_CTRL_PARSE_CONTINUE) {
294 return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE);
295 }
296
297 /* Create Op structure and append to parent's argument list */
298
299 walk_state->op_info = acpi_ps_get_opcode_info(walk_state->opcode);
300 op = acpi_ps_alloc_op(walk_state->opcode);
301 if (!op) {
302 return_ACPI_STATUS(AE_NO_MEMORY);
303 }
304
305 if (walk_state->op_info->flags & AML_NAMED) {
306 status =
307 acpi_ps_build_named_op(walk_state, aml_op_start, op,
308 &named_op);
309 acpi_ps_free_op(op);
310 if (ACPI_FAILURE(status)) {
311 return_ACPI_STATUS(status);
312 }
313
314 *new_op = named_op;
315 return_ACPI_STATUS(AE_OK);
316 }
317
318 /* Not a named opcode, just allocate Op and append to parent */
319
320 if (walk_state->op_info->flags & AML_CREATE) {
321 /*
322 * Backup to beginning of create_xXXfield declaration
323 * body_length is unknown until we parse the body
324 */
325 op->named.data = aml_op_start;
326 op->named.length = 0;
327 }
328
329 if (walk_state->opcode == AML_BANK_FIELD_OP) {
330 /*
331 * Backup to beginning of bank_field declaration
332 * body_length is unknown until we parse the body
333 */
334 op->named.data = aml_op_start;
335 op->named.length = 0;
336 }
337
338 parent_scope = acpi_ps_get_parent_scope(&(walk_state->parser_state));
339 acpi_ps_append_arg(parent_scope, op);
340
341 if (parent_scope) {
342 op_info =
343 acpi_ps_get_opcode_info(parent_scope->common.aml_opcode);
344 if (op_info->flags & AML_HAS_TARGET) {
345 argument_count =
346 acpi_ps_get_argument_count(op_info->type);
347 if (parent_scope->common.arg_list_length >
348 argument_count) {
349 op->common.flags |= ACPI_PARSEOP_TARGET;
350 }
351 } else if (parent_scope->common.aml_opcode == AML_INCREMENT_OP) {
352 op->common.flags |= ACPI_PARSEOP_TARGET;
353 }
354 }
355
356 if (walk_state->descending_callback != NULL) {
357 /*
358 * Find the object. This will either insert the object into
359 * the namespace or simply look it up
360 */
361 walk_state->op = *new_op = op;
362
363 status = walk_state->descending_callback(walk_state, &op);
364 status = acpi_ps_next_parse_state(walk_state, op, status);
365 if (status == AE_CTRL_PENDING) {
366 status = AE_CTRL_PARSE_PENDING;
367 }
368 }
369
370 return_ACPI_STATUS(status);
371}
372
373/*******************************************************************************
374 *
375 * FUNCTION: acpi_ps_get_arguments
376 *
377 * PARAMETERS: walk_state - Current state
378 * aml_op_start - Op start in AML
379 * Op - Current Op
380 *
381 * RETURN: Status
382 *
383 * DESCRIPTION: Get arguments for passed Op.
384 *
385 ******************************************************************************/
386
387static acpi_status
388acpi_ps_get_arguments(struct acpi_walk_state *walk_state,
389 u8 * aml_op_start, union acpi_parse_object *op)
390{
391 acpi_status status = AE_OK;
392 union acpi_parse_object *arg = NULL;
393
394 ACPI_FUNCTION_TRACE_PTR(ps_get_arguments, walk_state);
395
396 switch (op->common.aml_opcode) {
397 case AML_BYTE_OP: /* AML_BYTEDATA_ARG */
398 case AML_WORD_OP: /* AML_WORDDATA_ARG */
399 case AML_DWORD_OP: /* AML_DWORDATA_ARG */
400 case AML_QWORD_OP: /* AML_QWORDATA_ARG */
401 case AML_STRING_OP: /* AML_ASCIICHARLIST_ARG */
402
403 /* Fill in constant or string argument directly */
404
405 acpi_ps_get_next_simple_arg(&(walk_state->parser_state),
406 GET_CURRENT_ARG_TYPE(walk_state->
407 arg_types),
408 op);
409 break;
410
411 case AML_INT_NAMEPATH_OP: /* AML_NAMESTRING_ARG */
412
413 status =
414 acpi_ps_get_next_namepath(walk_state,
415 &(walk_state->parser_state), op,
416 1);
417 if (ACPI_FAILURE(status)) {
418 return_ACPI_STATUS(status);
419 }
420
421 walk_state->arg_types = 0;
422 break;
423
424 default:
425 /*
426 * Op is not a constant or string, append each argument to the Op
427 */
428 while (GET_CURRENT_ARG_TYPE(walk_state->arg_types)
429 && !walk_state->arg_count) {
430 walk_state->aml_offset =
431 (u32) ACPI_PTR_DIFF(walk_state->parser_state.aml,
432 walk_state->parser_state.
433 aml_start);
434
435 status =
436 acpi_ps_get_next_arg(walk_state,
437 &(walk_state->parser_state),
438 GET_CURRENT_ARG_TYPE
439 (walk_state->arg_types), &arg);
440 if (ACPI_FAILURE(status)) {
441 return_ACPI_STATUS(status);
442 }
443
444 if (arg) {
445 arg->common.aml_offset = walk_state->aml_offset;
446 acpi_ps_append_arg(op, arg);
447 }
448
449 INCREMENT_ARG_LIST(walk_state->arg_types);
450 }
451
452 /* Special processing for certain opcodes */
453
454 /* TBD (remove): Temporary mechanism to disable this code if needed */
455
456#ifdef ACPI_ENABLE_MODULE_LEVEL_CODE
457
458 if ((walk_state->pass_number <= ACPI_IMODE_LOAD_PASS1) &&
459 ((walk_state->parse_flags & ACPI_PARSE_DISASSEMBLE) == 0)) {
460 /*
461 * We want to skip If/Else/While constructs during Pass1 because we
462 * want to actually conditionally execute the code during Pass2.
463 *
464 * Except for disassembly, where we always want to walk the
465 * If/Else/While packages
466 */
467 switch (op->common.aml_opcode) {
468 case AML_IF_OP:
469 case AML_ELSE_OP:
470 case AML_WHILE_OP:
471
472 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
473 "Pass1: Skipping an If/Else/While body\n"));
474
475 /* Skip body of if/else/while in pass 1 */
476
477 walk_state->parser_state.aml =
478 walk_state->parser_state.pkg_end;
479 walk_state->arg_count = 0;
480 break;
481
482 default:
483 break;
484 }
485 }
486#endif
487
488 switch (op->common.aml_opcode) {
489 case AML_METHOD_OP:
490 /*
491 * Skip parsing of control method because we don't have enough
492 * info in the first pass to parse it correctly.
493 *
494 * Save the length and address of the body
495 */
496 op->named.data = walk_state->parser_state.aml;
497 op->named.length = (u32)
498 (walk_state->parser_state.pkg_end -
499 walk_state->parser_state.aml);
500
501 /* Skip body of method */
502
503 walk_state->parser_state.aml =
504 walk_state->parser_state.pkg_end;
505 walk_state->arg_count = 0;
506 break;
507
508 case AML_BUFFER_OP:
509 case AML_PACKAGE_OP:
510 case AML_VAR_PACKAGE_OP:
511
512 if ((op->common.parent) &&
513 (op->common.parent->common.aml_opcode ==
514 AML_NAME_OP)
515 && (walk_state->pass_number <=
516 ACPI_IMODE_LOAD_PASS2)) {
517 /*
518 * Skip parsing of Buffers and Packages because we don't have
519 * enough info in the first pass to parse them correctly.
520 */
521 op->named.data = aml_op_start;
522 op->named.length = (u32)
523 (walk_state->parser_state.pkg_end -
524 aml_op_start);
525
526 /* Skip body */
527
528 walk_state->parser_state.aml =
529 walk_state->parser_state.pkg_end;
530 walk_state->arg_count = 0;
531 }
532 break;
533
534 case AML_WHILE_OP:
535
536 if (walk_state->control_state) {
537 walk_state->control_state->control.package_end =
538 walk_state->parser_state.pkg_end;
539 }
540 break;
541
542 default:
543
544 /* No action for all other opcodes */
545 break;
546 }
547
548 break;
549 }
550
551 return_ACPI_STATUS(AE_OK);
552}
553
554/*******************************************************************************
555 *
556 * FUNCTION: acpi_ps_complete_op
557 *
558 * PARAMETERS: walk_state - Current state
559 * Op - Returned Op
560 * Status - Parse status before complete Op
561 *
562 * RETURN: Status
563 *
564 * DESCRIPTION: Complete Op
565 *
566 ******************************************************************************/
567
568static acpi_status
569acpi_ps_complete_op(struct acpi_walk_state *walk_state,
570 union acpi_parse_object **op, acpi_status status)
571{
572 acpi_status status2;
573
574 ACPI_FUNCTION_TRACE_PTR(ps_complete_op, walk_state);
575
576 /*
577 * Finished one argument of the containing scope
578 */
579 walk_state->parser_state.scope->parse_scope.arg_count--;
580
581 /* Close this Op (will result in parse subtree deletion) */
582
583 status2 = acpi_ps_complete_this_op(walk_state, *op);
584 if (ACPI_FAILURE(status2)) {
585 return_ACPI_STATUS(status2);
586 }
587
588 *op = NULL;
589
590 switch (status) {
591 case AE_OK:
592 break;
593
594 case AE_CTRL_TRANSFER:
595
596 /* We are about to transfer to a called method */
597
598 walk_state->prev_op = NULL;
599 walk_state->prev_arg_types = walk_state->arg_types;
600 return_ACPI_STATUS(status);
601
602 case AE_CTRL_END:
603
604 acpi_ps_pop_scope(&(walk_state->parser_state), op,
605 &walk_state->arg_types,
606 &walk_state->arg_count);
607
608 if (*op) {
609 walk_state->op = *op;
610 walk_state->op_info =
611 acpi_ps_get_opcode_info((*op)->common.aml_opcode);
612 walk_state->opcode = (*op)->common.aml_opcode;
613
614 status = walk_state->ascending_callback(walk_state);
615 status =
616 acpi_ps_next_parse_state(walk_state, *op, status);
617
618 status2 = acpi_ps_complete_this_op(walk_state, *op);
619 if (ACPI_FAILURE(status2)) {
620 return_ACPI_STATUS(status2);
621 }
622 }
623
624 status = AE_OK;
625 break;
626
627 case AE_CTRL_BREAK:
628 case AE_CTRL_CONTINUE:
629
630 /* Pop off scopes until we find the While */
631
632 while (!(*op) || ((*op)->common.aml_opcode != AML_WHILE_OP)) {
633 acpi_ps_pop_scope(&(walk_state->parser_state), op,
634 &walk_state->arg_types,
635 &walk_state->arg_count);
636 }
637
638 /* Close this iteration of the While loop */
639
640 walk_state->op = *op;
641 walk_state->op_info =
642 acpi_ps_get_opcode_info((*op)->common.aml_opcode);
643 walk_state->opcode = (*op)->common.aml_opcode;
644
645 status = walk_state->ascending_callback(walk_state);
646 status = acpi_ps_next_parse_state(walk_state, *op, status);
647
648 status2 = acpi_ps_complete_this_op(walk_state, *op);
649 if (ACPI_FAILURE(status2)) {
650 return_ACPI_STATUS(status2);
651 }
652
653 status = AE_OK;
654 break;
655
656 case AE_CTRL_TERMINATE:
657
658 /* Clean up */
659 do {
660 if (*op) {
661 status2 =
662 acpi_ps_complete_this_op(walk_state, *op);
663 if (ACPI_FAILURE(status2)) {
664 return_ACPI_STATUS(status2);
665 }
666
667 acpi_ut_delete_generic_state
668 (acpi_ut_pop_generic_state
669 (&walk_state->control_state));
670 }
671
672 acpi_ps_pop_scope(&(walk_state->parser_state), op,
673 &walk_state->arg_types,
674 &walk_state->arg_count);
675
676 } while (*op);
677
678 return_ACPI_STATUS(AE_OK);
679
680 default: /* All other non-AE_OK status */
681
682 do {
683 if (*op) {
684 status2 =
685 acpi_ps_complete_this_op(walk_state, *op);
686 if (ACPI_FAILURE(status2)) {
687 return_ACPI_STATUS(status2);
688 }
689 }
690
691 acpi_ps_pop_scope(&(walk_state->parser_state), op,
692 &walk_state->arg_types,
693 &walk_state->arg_count);
694
695 } while (*op);
696
697#if 0
698 /*
699 * TBD: Cleanup parse ops on error
700 */
701 if (*op == NULL) {
702 acpi_ps_pop_scope(parser_state, op,
703 &walk_state->arg_types,
704 &walk_state->arg_count);
705 }
706#endif
707 walk_state->prev_op = NULL;
708 walk_state->prev_arg_types = walk_state->arg_types;
709 return_ACPI_STATUS(status);
710 }
711
712 /* This scope complete? */
713
714 if (acpi_ps_has_completed_scope(&(walk_state->parser_state))) {
715 acpi_ps_pop_scope(&(walk_state->parser_state), op,
716 &walk_state->arg_types,
717 &walk_state->arg_count);
718 ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "Popped scope, Op=%p\n", *op));
719 } else {
720 *op = NULL;
721 }
722
723 ACPI_PREEMPTION_POINT();
724
725 return_ACPI_STATUS(AE_OK);
726}
727
728/*******************************************************************************
729 *
730 * FUNCTION: acpi_ps_complete_final_op
731 *
732 * PARAMETERS: walk_state - Current state
733 * Op - Current Op
734 * Status - Current parse status before complete last
735 * Op
736 *
737 * RETURN: Status
738 *
739 * DESCRIPTION: Complete last Op.
740 *
741 ******************************************************************************/
742
743static acpi_status
744acpi_ps_complete_final_op(struct acpi_walk_state *walk_state,
745 union acpi_parse_object *op, acpi_status status)
746{
747 acpi_status status2;
748
749 ACPI_FUNCTION_TRACE_PTR(ps_complete_final_op, walk_state);
750
751 /*
752 * Complete the last Op (if not completed), and clear the scope stack.
753 * It is easily possible to end an AML "package" with an unbounded number
754 * of open scopes (such as when several ASL blocks are closed with
755 * sequential closing braces). We want to terminate each one cleanly.
756 */
757 ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "AML package complete at Op %p\n",
758 op));
759 do {
760 if (op) {
761 if (walk_state->ascending_callback != NULL) {
762 walk_state->op = op;
763 walk_state->op_info =
764 acpi_ps_get_opcode_info(op->common.
765 aml_opcode);
766 walk_state->opcode = op->common.aml_opcode;
767
768 status =
769 walk_state->ascending_callback(walk_state);
770 status =
771 acpi_ps_next_parse_state(walk_state, op,
772 status);
773 if (status == AE_CTRL_PENDING) {
774 status =
775 acpi_ps_complete_op(walk_state, &op,
776 AE_OK);
777 if (ACPI_FAILURE(status)) {
778 return_ACPI_STATUS(status);
779 }
780 }
781
782 if (status == AE_CTRL_TERMINATE) {
783 status = AE_OK;
784
785 /* Clean up */
786 do {
787 if (op) {
788 status2 =
789 acpi_ps_complete_this_op
790 (walk_state, op);
791 if (ACPI_FAILURE
792 (status2)) {
793 return_ACPI_STATUS
794 (status2);
795 }
796 }
797
798 acpi_ps_pop_scope(&
799 (walk_state->
800 parser_state),
801 &op,
802 &walk_state->
803 arg_types,
804 &walk_state->
805 arg_count);
806
807 } while (op);
808
809 return_ACPI_STATUS(status);
810 }
811
812 else if (ACPI_FAILURE(status)) {
813
814 /* First error is most important */
815
816 (void)
817 acpi_ps_complete_this_op(walk_state,
818 op);
819 return_ACPI_STATUS(status);
820 }
821 }
822
823 status2 = acpi_ps_complete_this_op(walk_state, op);
824 if (ACPI_FAILURE(status2)) {
825 return_ACPI_STATUS(status2);
826 }
827 }
828
829 acpi_ps_pop_scope(&(walk_state->parser_state), &op,
830 &walk_state->arg_types,
831 &walk_state->arg_count);
832
833 } while (op);
834
835 return_ACPI_STATUS(status);
836}
837
838/*******************************************************************************
839 *
840 * FUNCTION: acpi_ps_parse_loop
841 *
842 * PARAMETERS: walk_state - Current state
843 *
844 * RETURN: Status
845 *
846 * DESCRIPTION: Parse AML (pointed to by the current parser state) and return
847 * a tree of ops.
848 *
849 ******************************************************************************/
850
851acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state)
852{
853 acpi_status status = AE_OK;
854 union acpi_parse_object *op = NULL; /* current op */
855 struct acpi_parse_state *parser_state;
856 u8 *aml_op_start = NULL;
857
858 ACPI_FUNCTION_TRACE_PTR(ps_parse_loop, walk_state);
859
860 if (walk_state->descending_callback == NULL) {
861 return_ACPI_STATUS(AE_BAD_PARAMETER);
862 }
863
864 parser_state = &walk_state->parser_state;
865 walk_state->arg_types = 0;
866
867#if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY))
868
869 if (walk_state->walk_type & ACPI_WALK_METHOD_RESTART) {
870
871 /* We are restarting a preempted control method */
872
873 if (acpi_ps_has_completed_scope(parser_state)) {
874 /*
875 * We must check if a predicate to an IF or WHILE statement
876 * was just completed
877 */
878 if ((parser_state->scope->parse_scope.op) &&
879 ((parser_state->scope->parse_scope.op->common.
880 aml_opcode == AML_IF_OP)
881 || (parser_state->scope->parse_scope.op->common.
882 aml_opcode == AML_WHILE_OP))
883 && (walk_state->control_state)
884 && (walk_state->control_state->common.state ==
885 ACPI_CONTROL_PREDICATE_EXECUTING)) {
886 /*
887 * A predicate was just completed, get the value of the
888 * predicate and branch based on that value
889 */
890 walk_state->op = NULL;
891 status =
892 acpi_ds_get_predicate_value(walk_state,
893 ACPI_TO_POINTER
894 (TRUE));
895 if (ACPI_FAILURE(status)
896 && ((status & AE_CODE_MASK) !=
897 AE_CODE_CONTROL)) {
898 if (status == AE_AML_NO_RETURN_VALUE) {
899 ACPI_EXCEPTION((AE_INFO, status,
900 "Invoked method did not return a value"));
901
902 }
903
904 ACPI_EXCEPTION((AE_INFO, status,
905 "GetPredicate Failed"));
906 return_ACPI_STATUS(status);
907 }
908
909 status =
910 acpi_ps_next_parse_state(walk_state, op,
911 status);
912 }
913
914 acpi_ps_pop_scope(parser_state, &op,
915 &walk_state->arg_types,
916 &walk_state->arg_count);
917 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
918 "Popped scope, Op=%p\n", op));
919 } else if (walk_state->prev_op) {
920
921 /* We were in the middle of an op */
922
923 op = walk_state->prev_op;
924 walk_state->arg_types = walk_state->prev_arg_types;
925 }
926 }
927#endif
928
929 /* Iterative parsing loop, while there is more AML to process: */
930
931 while ((parser_state->aml < parser_state->aml_end) || (op)) {
932 aml_op_start = parser_state->aml;
933 if (!op) {
934 status =
935 acpi_ps_create_op(walk_state, aml_op_start, &op);
936 if (ACPI_FAILURE(status)) {
937 if (status == AE_CTRL_PARSE_CONTINUE) {
938 continue;
939 }
940
941 if (status == AE_CTRL_PARSE_PENDING) {
942 status = AE_OK;
943 }
944
945 status =
946 acpi_ps_complete_op(walk_state, &op,
947 status);
948 if (ACPI_FAILURE(status)) {
949 return_ACPI_STATUS(status);
950 }
951
952 continue;
953 }
954
955 op->common.aml_offset = walk_state->aml_offset;
956
957 if (walk_state->op_info) {
958 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
959 "Opcode %4.4X [%s] Op %p Aml %p AmlOffset %5.5X\n",
960 (u32) op->common.aml_opcode,
961 walk_state->op_info->name, op,
962 parser_state->aml,
963 op->common.aml_offset));
964 }
965 }
966
967 /*
968 * Start arg_count at zero because we don't know if there are
969 * any args yet
970 */
971 walk_state->arg_count = 0;
972
973 /* Are there any arguments that must be processed? */
974
975 if (walk_state->arg_types) {
976
977 /* Get arguments */
978
979 status =
980 acpi_ps_get_arguments(walk_state, aml_op_start, op);
981 if (ACPI_FAILURE(status)) {
982 status =
983 acpi_ps_complete_op(walk_state, &op,
984 status);
985 if (ACPI_FAILURE(status)) {
986 return_ACPI_STATUS(status);
987 }
988
989 continue;
990 }
991 }
992
993 /* Check for arguments that need to be processed */
994
995 if (walk_state->arg_count) {
996 /*
997 * There are arguments (complex ones), push Op and
998 * prepare for argument
999 */
1000 status = acpi_ps_push_scope(parser_state, op,
1001 walk_state->arg_types,
1002 walk_state->arg_count);
1003 if (ACPI_FAILURE(status)) {
1004 status =
1005 acpi_ps_complete_op(walk_state, &op,
1006 status);
1007 if (ACPI_FAILURE(status)) {
1008 return_ACPI_STATUS(status);
1009 }
1010
1011 continue;
1012 }
1013
1014 op = NULL;
1015 continue;
1016 }
1017
1018 /*
1019 * All arguments have been processed -- Op is complete,
1020 * prepare for next
1021 */
1022 walk_state->op_info =
1023 acpi_ps_get_opcode_info(op->common.aml_opcode);
1024 if (walk_state->op_info->flags & AML_NAMED) {
1025 if (acpi_gbl_depth) {
1026 acpi_gbl_depth--;
1027 }
1028
1029 if (op->common.aml_opcode == AML_REGION_OP ||
1030 op->common.aml_opcode == AML_DATA_REGION_OP) {
1031 /*
1032 * Skip parsing of control method or opregion body,
1033 * because we don't have enough info in the first pass
1034 * to parse them correctly.
1035 *
1036 * Completed parsing an op_region declaration, we now
1037 * know the length.
1038 */
1039 op->named.length =
1040 (u32) (parser_state->aml - op->named.data);
1041 }
1042 }
1043
1044 if (walk_state->op_info->flags & AML_CREATE) {
1045 /*
1046 * Backup to beginning of create_xXXfield declaration (1 for
1047 * Opcode)
1048 *
1049 * body_length is unknown until we parse the body
1050 */
1051 op->named.length =
1052 (u32) (parser_state->aml - op->named.data);
1053 }
1054
1055 if (op->common.aml_opcode == AML_BANK_FIELD_OP) {
1056 /*
1057 * Backup to beginning of bank_field declaration
1058 *
1059 * body_length is unknown until we parse the body
1060 */
1061 op->named.length =
1062 (u32) (parser_state->aml - op->named.data);
1063 }
1064
1065 /* This op complete, notify the dispatcher */
1066
1067 if (walk_state->ascending_callback != NULL) {
1068 walk_state->op = op;
1069 walk_state->opcode = op->common.aml_opcode;
1070
1071 status = walk_state->ascending_callback(walk_state);
1072 status =
1073 acpi_ps_next_parse_state(walk_state, op, status);
1074 if (status == AE_CTRL_PENDING) {
1075 status = AE_OK;
1076 }
1077 }
1078
1079 status = acpi_ps_complete_op(walk_state, &op, status);
1080 if (ACPI_FAILURE(status)) {
1081 return_ACPI_STATUS(status);
1082 }
1083
1084 } /* while parser_state->Aml */
1085
1086 status = acpi_ps_complete_final_op(walk_state, op, status);
1087 return_ACPI_STATUS(status);
1088}
diff --git a/drivers/acpi/acpica/psopcode.c b/drivers/acpi/acpica/psopcode.c
new file mode 100644
index 00000000000..3693a121b34
--- /dev/null
+++ b/drivers/acpi/acpica/psopcode.c
@@ -0,0 +1,810 @@
1/******************************************************************************
2 *
3 * Module Name: psopcode - Parser/Interpreter opcode information table
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46#include <acpi/acparser.h>
47#include <acpi/acopcode.h>
48#include <acpi/amlcode.h>
49
50#define _COMPONENT ACPI_PARSER
51ACPI_MODULE_NAME("psopcode")
52
53static const u8 acpi_gbl_argument_count[] =
54 { 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 6 };
55
56/*******************************************************************************
57 *
58 * NAME: acpi_gbl_aml_op_info
59 *
60 * DESCRIPTION: Opcode table. Each entry contains <opcode, type, name, operands>
61 * The name is a simple ascii string, the operand specifier is an
62 * ascii string with one letter per operand. The letter specifies
63 * the operand type.
64 *
65 ******************************************************************************/
66
67/*
68 * Summary of opcode types/flags
69 *
70
71 Opcodes that have associated namespace objects (AML_NSOBJECT flag)
72
73 AML_SCOPE_OP
74 AML_DEVICE_OP
75 AML_THERMAL_ZONE_OP
76 AML_METHOD_OP
77 AML_POWER_RES_OP
78 AML_PROCESSOR_OP
79 AML_FIELD_OP
80 AML_INDEX_FIELD_OP
81 AML_BANK_FIELD_OP
82 AML_NAME_OP
83 AML_ALIAS_OP
84 AML_MUTEX_OP
85 AML_EVENT_OP
86 AML_REGION_OP
87 AML_CREATE_FIELD_OP
88 AML_CREATE_BIT_FIELD_OP
89 AML_CREATE_BYTE_FIELD_OP
90 AML_CREATE_WORD_FIELD_OP
91 AML_CREATE_DWORD_FIELD_OP
92 AML_CREATE_QWORD_FIELD_OP
93 AML_INT_NAMEDFIELD_OP
94 AML_INT_METHODCALL_OP
95 AML_INT_NAMEPATH_OP
96
97 Opcodes that are "namespace" opcodes (AML_NSOPCODE flag)
98
99 AML_SCOPE_OP
100 AML_DEVICE_OP
101 AML_THERMAL_ZONE_OP
102 AML_METHOD_OP
103 AML_POWER_RES_OP
104 AML_PROCESSOR_OP
105 AML_FIELD_OP
106 AML_INDEX_FIELD_OP
107 AML_BANK_FIELD_OP
108 AML_NAME_OP
109 AML_ALIAS_OP
110 AML_MUTEX_OP
111 AML_EVENT_OP
112 AML_REGION_OP
113 AML_INT_NAMEDFIELD_OP
114
115 Opcodes that have an associated namespace node (AML_NSNODE flag)
116
117 AML_SCOPE_OP
118 AML_DEVICE_OP
119 AML_THERMAL_ZONE_OP
120 AML_METHOD_OP
121 AML_POWER_RES_OP
122 AML_PROCESSOR_OP
123 AML_NAME_OP
124 AML_ALIAS_OP
125 AML_MUTEX_OP
126 AML_EVENT_OP
127 AML_REGION_OP
128 AML_CREATE_FIELD_OP
129 AML_CREATE_BIT_FIELD_OP
130 AML_CREATE_BYTE_FIELD_OP
131 AML_CREATE_WORD_FIELD_OP
132 AML_CREATE_DWORD_FIELD_OP
133 AML_CREATE_QWORD_FIELD_OP
134 AML_INT_NAMEDFIELD_OP
135 AML_INT_METHODCALL_OP
136 AML_INT_NAMEPATH_OP
137
138 Opcodes that define named ACPI objects (AML_NAMED flag)
139
140 AML_SCOPE_OP
141 AML_DEVICE_OP
142 AML_THERMAL_ZONE_OP
143 AML_METHOD_OP
144 AML_POWER_RES_OP
145 AML_PROCESSOR_OP
146 AML_NAME_OP
147 AML_ALIAS_OP
148 AML_MUTEX_OP
149 AML_EVENT_OP
150 AML_REGION_OP
151 AML_INT_NAMEDFIELD_OP
152
153 Opcodes that contain executable AML as part of the definition that
154 must be deferred until needed
155
156 AML_METHOD_OP
157 AML_VAR_PACKAGE_OP
158 AML_CREATE_FIELD_OP
159 AML_CREATE_BIT_FIELD_OP
160 AML_CREATE_BYTE_FIELD_OP
161 AML_CREATE_WORD_FIELD_OP
162 AML_CREATE_DWORD_FIELD_OP
163 AML_CREATE_QWORD_FIELD_OP
164 AML_REGION_OP
165 AML_BUFFER_OP
166
167 Field opcodes
168
169 AML_CREATE_FIELD_OP
170 AML_FIELD_OP
171 AML_INDEX_FIELD_OP
172 AML_BANK_FIELD_OP
173
174 Field "Create" opcodes
175
176 AML_CREATE_FIELD_OP
177 AML_CREATE_BIT_FIELD_OP
178 AML_CREATE_BYTE_FIELD_OP
179 AML_CREATE_WORD_FIELD_OP
180 AML_CREATE_DWORD_FIELD_OP
181 AML_CREATE_QWORD_FIELD_OP
182
183 ******************************************************************************/
184
185/*
186 * Master Opcode information table. A summary of everything we know about each
187 * opcode, all in one place.
188 */
189const struct acpi_opcode_info acpi_gbl_aml_op_info[AML_NUM_OPCODES] = {
190/*! [Begin] no source code translation */
191/* Index Name Parser Args Interpreter Args ObjectType Class Type Flags */
192
193/* 00 */ ACPI_OP("Zero", ARGP_ZERO_OP, ARGI_ZERO_OP, ACPI_TYPE_INTEGER,
194 AML_CLASS_ARGUMENT, AML_TYPE_CONSTANT, AML_CONSTANT),
195/* 01 */ ACPI_OP("One", ARGP_ONE_OP, ARGI_ONE_OP, ACPI_TYPE_INTEGER,
196 AML_CLASS_ARGUMENT, AML_TYPE_CONSTANT, AML_CONSTANT),
197/* 02 */ ACPI_OP("Alias", ARGP_ALIAS_OP, ARGI_ALIAS_OP,
198 ACPI_TYPE_LOCAL_ALIAS, AML_CLASS_NAMED_OBJECT,
199 AML_TYPE_NAMED_SIMPLE,
200 AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE |
201 AML_NSNODE | AML_NAMED),
202/* 03 */ ACPI_OP("Name", ARGP_NAME_OP, ARGI_NAME_OP, ACPI_TYPE_ANY,
203 AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_COMPLEX,
204 AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE |
205 AML_NSNODE | AML_NAMED),
206/* 04 */ ACPI_OP("ByteConst", ARGP_BYTE_OP, ARGI_BYTE_OP,
207 ACPI_TYPE_INTEGER, AML_CLASS_ARGUMENT,
208 AML_TYPE_LITERAL, AML_CONSTANT),
209/* 05 */ ACPI_OP("WordConst", ARGP_WORD_OP, ARGI_WORD_OP,
210 ACPI_TYPE_INTEGER, AML_CLASS_ARGUMENT,
211 AML_TYPE_LITERAL, AML_CONSTANT),
212/* 06 */ ACPI_OP("DwordConst", ARGP_DWORD_OP, ARGI_DWORD_OP,
213 ACPI_TYPE_INTEGER, AML_CLASS_ARGUMENT,
214 AML_TYPE_LITERAL, AML_CONSTANT),
215/* 07 */ ACPI_OP("String", ARGP_STRING_OP, ARGI_STRING_OP,
216 ACPI_TYPE_STRING, AML_CLASS_ARGUMENT,
217 AML_TYPE_LITERAL, AML_CONSTANT),
218/* 08 */ ACPI_OP("Scope", ARGP_SCOPE_OP, ARGI_SCOPE_OP,
219 ACPI_TYPE_LOCAL_SCOPE, AML_CLASS_NAMED_OBJECT,
220 AML_TYPE_NAMED_NO_OBJ,
221 AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE |
222 AML_NSNODE | AML_NAMED),
223/* 09 */ ACPI_OP("Buffer", ARGP_BUFFER_OP, ARGI_BUFFER_OP,
224 ACPI_TYPE_BUFFER, AML_CLASS_CREATE,
225 AML_TYPE_CREATE_OBJECT,
226 AML_HAS_ARGS | AML_DEFER | AML_CONSTANT),
227/* 0A */ ACPI_OP("Package", ARGP_PACKAGE_OP, ARGI_PACKAGE_OP,
228 ACPI_TYPE_PACKAGE, AML_CLASS_CREATE,
229 AML_TYPE_CREATE_OBJECT,
230 AML_HAS_ARGS | AML_DEFER | AML_CONSTANT),
231/* 0B */ ACPI_OP("Method", ARGP_METHOD_OP, ARGI_METHOD_OP,
232 ACPI_TYPE_METHOD, AML_CLASS_NAMED_OBJECT,
233 AML_TYPE_NAMED_COMPLEX,
234 AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE |
235 AML_NSNODE | AML_NAMED | AML_DEFER),
236/* 0C */ ACPI_OP("Local0", ARGP_LOCAL0, ARGI_LOCAL0,
237 ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT,
238 AML_TYPE_LOCAL_VARIABLE, 0),
239/* 0D */ ACPI_OP("Local1", ARGP_LOCAL1, ARGI_LOCAL1,
240 ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT,
241 AML_TYPE_LOCAL_VARIABLE, 0),
242/* 0E */ ACPI_OP("Local2", ARGP_LOCAL2, ARGI_LOCAL2,
243 ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT,
244 AML_TYPE_LOCAL_VARIABLE, 0),
245/* 0F */ ACPI_OP("Local3", ARGP_LOCAL3, ARGI_LOCAL3,
246 ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT,
247 AML_TYPE_LOCAL_VARIABLE, 0),
248/* 10 */ ACPI_OP("Local4", ARGP_LOCAL4, ARGI_LOCAL4,
249 ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT,
250 AML_TYPE_LOCAL_VARIABLE, 0),
251/* 11 */ ACPI_OP("Local5", ARGP_LOCAL5, ARGI_LOCAL5,
252 ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT,
253 AML_TYPE_LOCAL_VARIABLE, 0),
254/* 12 */ ACPI_OP("Local6", ARGP_LOCAL6, ARGI_LOCAL6,
255 ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT,
256 AML_TYPE_LOCAL_VARIABLE, 0),
257/* 13 */ ACPI_OP("Local7", ARGP_LOCAL7, ARGI_LOCAL7,
258 ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT,
259 AML_TYPE_LOCAL_VARIABLE, 0),
260/* 14 */ ACPI_OP("Arg0", ARGP_ARG0, ARGI_ARG0,
261 ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT,
262 AML_TYPE_METHOD_ARGUMENT, 0),
263/* 15 */ ACPI_OP("Arg1", ARGP_ARG1, ARGI_ARG1,
264 ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT,
265 AML_TYPE_METHOD_ARGUMENT, 0),
266/* 16 */ ACPI_OP("Arg2", ARGP_ARG2, ARGI_ARG2,
267 ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT,
268 AML_TYPE_METHOD_ARGUMENT, 0),
269/* 17 */ ACPI_OP("Arg3", ARGP_ARG3, ARGI_ARG3,
270 ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT,
271 AML_TYPE_METHOD_ARGUMENT, 0),
272/* 18 */ ACPI_OP("Arg4", ARGP_ARG4, ARGI_ARG4,
273 ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT,
274 AML_TYPE_METHOD_ARGUMENT, 0),
275/* 19 */ ACPI_OP("Arg5", ARGP_ARG5, ARGI_ARG5,
276 ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT,
277 AML_TYPE_METHOD_ARGUMENT, 0),
278/* 1A */ ACPI_OP("Arg6", ARGP_ARG6, ARGI_ARG6,
279 ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT,
280 AML_TYPE_METHOD_ARGUMENT, 0),
281/* 1B */ ACPI_OP("Store", ARGP_STORE_OP, ARGI_STORE_OP, ACPI_TYPE_ANY,
282 AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_1T_1R,
283 AML_FLAGS_EXEC_1A_1T_1R),
284/* 1C */ ACPI_OP("RefOf", ARGP_REF_OF_OP, ARGI_REF_OF_OP, ACPI_TYPE_ANY,
285 AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_1R,
286 AML_FLAGS_EXEC_1A_0T_1R),
287/* 1D */ ACPI_OP("Add", ARGP_ADD_OP, ARGI_ADD_OP, ACPI_TYPE_ANY,
288 AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R,
289 AML_FLAGS_EXEC_2A_1T_1R | AML_MATH | AML_CONSTANT),
290/* 1E */ ACPI_OP("Concatenate", ARGP_CONCAT_OP, ARGI_CONCAT_OP,
291 ACPI_TYPE_ANY, AML_CLASS_EXECUTE,
292 AML_TYPE_EXEC_2A_1T_1R,
293 AML_FLAGS_EXEC_2A_1T_1R | AML_CONSTANT),
294/* 1F */ ACPI_OP("Subtract", ARGP_SUBTRACT_OP, ARGI_SUBTRACT_OP,
295 ACPI_TYPE_ANY, AML_CLASS_EXECUTE,
296 AML_TYPE_EXEC_2A_1T_1R,
297 AML_FLAGS_EXEC_2A_1T_1R | AML_MATH | AML_CONSTANT),
298/* 20 */ ACPI_OP("Increment", ARGP_INCREMENT_OP, ARGI_INCREMENT_OP,
299 ACPI_TYPE_ANY, AML_CLASS_EXECUTE,
300 AML_TYPE_EXEC_1A_0T_1R,
301 AML_FLAGS_EXEC_1A_0T_1R | AML_CONSTANT),
302/* 21 */ ACPI_OP("Decrement", ARGP_DECREMENT_OP, ARGI_DECREMENT_OP,
303 ACPI_TYPE_ANY, AML_CLASS_EXECUTE,
304 AML_TYPE_EXEC_1A_0T_1R,
305 AML_FLAGS_EXEC_1A_0T_1R | AML_CONSTANT),
306/* 22 */ ACPI_OP("Multiply", ARGP_MULTIPLY_OP, ARGI_MULTIPLY_OP,
307 ACPI_TYPE_ANY, AML_CLASS_EXECUTE,
308 AML_TYPE_EXEC_2A_1T_1R,
309 AML_FLAGS_EXEC_2A_1T_1R | AML_MATH | AML_CONSTANT),
310/* 23 */ ACPI_OP("Divide", ARGP_DIVIDE_OP, ARGI_DIVIDE_OP,
311 ACPI_TYPE_ANY, AML_CLASS_EXECUTE,
312 AML_TYPE_EXEC_2A_2T_1R,
313 AML_FLAGS_EXEC_2A_2T_1R | AML_CONSTANT),
314/* 24 */ ACPI_OP("ShiftLeft", ARGP_SHIFT_LEFT_OP, ARGI_SHIFT_LEFT_OP,
315 ACPI_TYPE_ANY, AML_CLASS_EXECUTE,
316 AML_TYPE_EXEC_2A_1T_1R,
317 AML_FLAGS_EXEC_2A_1T_1R | AML_MATH | AML_CONSTANT),
318/* 25 */ ACPI_OP("ShiftRight", ARGP_SHIFT_RIGHT_OP, ARGI_SHIFT_RIGHT_OP,
319 ACPI_TYPE_ANY, AML_CLASS_EXECUTE,
320 AML_TYPE_EXEC_2A_1T_1R,
321 AML_FLAGS_EXEC_2A_1T_1R | AML_MATH | AML_CONSTANT),
322/* 26 */ ACPI_OP("And", ARGP_BIT_AND_OP, ARGI_BIT_AND_OP, ACPI_TYPE_ANY,
323 AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R,
324 AML_FLAGS_EXEC_2A_1T_1R | AML_MATH | AML_CONSTANT),
325/* 27 */ ACPI_OP("NAnd", ARGP_BIT_NAND_OP, ARGI_BIT_NAND_OP,
326 ACPI_TYPE_ANY, AML_CLASS_EXECUTE,
327 AML_TYPE_EXEC_2A_1T_1R,
328 AML_FLAGS_EXEC_2A_1T_1R | AML_MATH | AML_CONSTANT),
329/* 28 */ ACPI_OP("Or", ARGP_BIT_OR_OP, ARGI_BIT_OR_OP, ACPI_TYPE_ANY,
330 AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R,
331 AML_FLAGS_EXEC_2A_1T_1R | AML_MATH | AML_CONSTANT),
332/* 29 */ ACPI_OP("NOr", ARGP_BIT_NOR_OP, ARGI_BIT_NOR_OP, ACPI_TYPE_ANY,
333 AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R,
334 AML_FLAGS_EXEC_2A_1T_1R | AML_MATH | AML_CONSTANT),
335/* 2A */ ACPI_OP("XOr", ARGP_BIT_XOR_OP, ARGI_BIT_XOR_OP, ACPI_TYPE_ANY,
336 AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R,
337 AML_FLAGS_EXEC_2A_1T_1R | AML_MATH | AML_CONSTANT),
338/* 2B */ ACPI_OP("Not", ARGP_BIT_NOT_OP, ARGI_BIT_NOT_OP, ACPI_TYPE_ANY,
339 AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_1T_1R,
340 AML_FLAGS_EXEC_1A_1T_1R | AML_CONSTANT),
341/* 2C */ ACPI_OP("FindSetLeftBit", ARGP_FIND_SET_LEFT_BIT_OP,
342 ARGI_FIND_SET_LEFT_BIT_OP, ACPI_TYPE_ANY,
343 AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_1T_1R,
344 AML_FLAGS_EXEC_1A_1T_1R | AML_CONSTANT),
345/* 2D */ ACPI_OP("FindSetRightBit", ARGP_FIND_SET_RIGHT_BIT_OP,
346 ARGI_FIND_SET_RIGHT_BIT_OP, ACPI_TYPE_ANY,
347 AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_1T_1R,
348 AML_FLAGS_EXEC_1A_1T_1R | AML_CONSTANT),
349/* 2E */ ACPI_OP("DerefOf", ARGP_DEREF_OF_OP, ARGI_DEREF_OF_OP,
350 ACPI_TYPE_ANY, AML_CLASS_EXECUTE,
351 AML_TYPE_EXEC_1A_0T_1R, AML_FLAGS_EXEC_1A_0T_1R),
352/* 2F */ ACPI_OP("Notify", ARGP_NOTIFY_OP, ARGI_NOTIFY_OP,
353 ACPI_TYPE_ANY, AML_CLASS_EXECUTE,
354 AML_TYPE_EXEC_2A_0T_0R, AML_FLAGS_EXEC_2A_0T_0R),
355/* 30 */ ACPI_OP("SizeOf", ARGP_SIZE_OF_OP, ARGI_SIZE_OF_OP,
356 ACPI_TYPE_ANY, AML_CLASS_EXECUTE,
357 AML_TYPE_EXEC_1A_0T_1R,
358 AML_FLAGS_EXEC_1A_0T_1R | AML_NO_OPERAND_RESOLVE),
359/* 31 */ ACPI_OP("Index", ARGP_INDEX_OP, ARGI_INDEX_OP, ACPI_TYPE_ANY,
360 AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R,
361 AML_FLAGS_EXEC_2A_1T_1R),
362/* 32 */ ACPI_OP("Match", ARGP_MATCH_OP, ARGI_MATCH_OP, ACPI_TYPE_ANY,
363 AML_CLASS_EXECUTE, AML_TYPE_EXEC_6A_0T_1R,
364 AML_FLAGS_EXEC_6A_0T_1R | AML_CONSTANT),
365/* 33 */ ACPI_OP("CreateDWordField", ARGP_CREATE_DWORD_FIELD_OP,
366 ARGI_CREATE_DWORD_FIELD_OP,
367 ACPI_TYPE_BUFFER_FIELD, AML_CLASS_CREATE,
368 AML_TYPE_CREATE_FIELD,
369 AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE |
370 AML_DEFER | AML_CREATE),
371/* 34 */ ACPI_OP("CreateWordField", ARGP_CREATE_WORD_FIELD_OP,
372 ARGI_CREATE_WORD_FIELD_OP,
373 ACPI_TYPE_BUFFER_FIELD, AML_CLASS_CREATE,
374 AML_TYPE_CREATE_FIELD,
375 AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE |
376 AML_DEFER | AML_CREATE),
377/* 35 */ ACPI_OP("CreateByteField", ARGP_CREATE_BYTE_FIELD_OP,
378 ARGI_CREATE_BYTE_FIELD_OP,
379 ACPI_TYPE_BUFFER_FIELD, AML_CLASS_CREATE,
380 AML_TYPE_CREATE_FIELD,
381 AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE |
382 AML_DEFER | AML_CREATE),
383/* 36 */ ACPI_OP("CreateBitField", ARGP_CREATE_BIT_FIELD_OP,
384 ARGI_CREATE_BIT_FIELD_OP,
385 ACPI_TYPE_BUFFER_FIELD, AML_CLASS_CREATE,
386 AML_TYPE_CREATE_FIELD,
387 AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE |
388 AML_DEFER | AML_CREATE),
389/* 37 */ ACPI_OP("ObjectType", ARGP_TYPE_OP, ARGI_TYPE_OP,
390 ACPI_TYPE_ANY, AML_CLASS_EXECUTE,
391 AML_TYPE_EXEC_1A_0T_1R,
392 AML_FLAGS_EXEC_1A_0T_1R | AML_NO_OPERAND_RESOLVE),
393/* 38 */ ACPI_OP("LAnd", ARGP_LAND_OP, ARGI_LAND_OP, ACPI_TYPE_ANY,
394 AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_0T_1R,
395 AML_FLAGS_EXEC_2A_0T_1R | AML_LOGICAL_NUMERIC | AML_CONSTANT),
396/* 39 */ ACPI_OP("LOr", ARGP_LOR_OP, ARGI_LOR_OP, ACPI_TYPE_ANY,
397 AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_0T_1R,
398 AML_FLAGS_EXEC_2A_0T_1R | AML_LOGICAL_NUMERIC | AML_CONSTANT),
399/* 3A */ ACPI_OP("LNot", ARGP_LNOT_OP, ARGI_LNOT_OP, ACPI_TYPE_ANY,
400 AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_1R,
401 AML_FLAGS_EXEC_1A_0T_1R | AML_CONSTANT),
402/* 3B */ ACPI_OP("LEqual", ARGP_LEQUAL_OP, ARGI_LEQUAL_OP,
403 ACPI_TYPE_ANY, AML_CLASS_EXECUTE,
404 AML_TYPE_EXEC_2A_0T_1R,
405 AML_FLAGS_EXEC_2A_0T_1R | AML_LOGICAL | AML_CONSTANT),
406/* 3C */ ACPI_OP("LGreater", ARGP_LGREATER_OP, ARGI_LGREATER_OP,
407 ACPI_TYPE_ANY, AML_CLASS_EXECUTE,
408 AML_TYPE_EXEC_2A_0T_1R,
409 AML_FLAGS_EXEC_2A_0T_1R | AML_LOGICAL | AML_CONSTANT),
410/* 3D */ ACPI_OP("LLess", ARGP_LLESS_OP, ARGI_LLESS_OP, ACPI_TYPE_ANY,
411 AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_0T_1R,
412 AML_FLAGS_EXEC_2A_0T_1R | AML_LOGICAL | AML_CONSTANT),
413/* 3E */ ACPI_OP("If", ARGP_IF_OP, ARGI_IF_OP, ACPI_TYPE_ANY,
414 AML_CLASS_CONTROL, AML_TYPE_CONTROL, AML_HAS_ARGS),
415/* 3F */ ACPI_OP("Else", ARGP_ELSE_OP, ARGI_ELSE_OP, ACPI_TYPE_ANY,
416 AML_CLASS_CONTROL, AML_TYPE_CONTROL, AML_HAS_ARGS),
417/* 40 */ ACPI_OP("While", ARGP_WHILE_OP, ARGI_WHILE_OP, ACPI_TYPE_ANY,
418 AML_CLASS_CONTROL, AML_TYPE_CONTROL, AML_HAS_ARGS),
419/* 41 */ ACPI_OP("Noop", ARGP_NOOP_OP, ARGI_NOOP_OP, ACPI_TYPE_ANY,
420 AML_CLASS_CONTROL, AML_TYPE_CONTROL, 0),
421/* 42 */ ACPI_OP("Return", ARGP_RETURN_OP, ARGI_RETURN_OP,
422 ACPI_TYPE_ANY, AML_CLASS_CONTROL,
423 AML_TYPE_CONTROL, AML_HAS_ARGS),
424/* 43 */ ACPI_OP("Break", ARGP_BREAK_OP, ARGI_BREAK_OP, ACPI_TYPE_ANY,
425 AML_CLASS_CONTROL, AML_TYPE_CONTROL, 0),
426/* 44 */ ACPI_OP("BreakPoint", ARGP_BREAK_POINT_OP, ARGI_BREAK_POINT_OP,
427 ACPI_TYPE_ANY, AML_CLASS_CONTROL, AML_TYPE_CONTROL, 0),
428/* 45 */ ACPI_OP("Ones", ARGP_ONES_OP, ARGI_ONES_OP, ACPI_TYPE_INTEGER,
429 AML_CLASS_ARGUMENT, AML_TYPE_CONSTANT, AML_CONSTANT),
430
431/* Prefixed opcodes (Two-byte opcodes with a prefix op) */
432
433/* 46 */ ACPI_OP("Mutex", ARGP_MUTEX_OP, ARGI_MUTEX_OP, ACPI_TYPE_MUTEX,
434 AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_SIMPLE,
435 AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE |
436 AML_NSNODE | AML_NAMED),
437/* 47 */ ACPI_OP("Event", ARGP_EVENT_OP, ARGI_EVENT_OP, ACPI_TYPE_EVENT,
438 AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_SIMPLE,
439 AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED),
440/* 48 */ ACPI_OP("CondRefOf", ARGP_COND_REF_OF_OP, ARGI_COND_REF_OF_OP,
441 ACPI_TYPE_ANY, AML_CLASS_EXECUTE,
442 AML_TYPE_EXEC_1A_1T_1R, AML_FLAGS_EXEC_1A_1T_1R),
443/* 49 */ ACPI_OP("CreateField", ARGP_CREATE_FIELD_OP,
444 ARGI_CREATE_FIELD_OP, ACPI_TYPE_BUFFER_FIELD,
445 AML_CLASS_CREATE, AML_TYPE_CREATE_FIELD,
446 AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE |
447 AML_DEFER | AML_FIELD | AML_CREATE),
448/* 4A */ ACPI_OP("Load", ARGP_LOAD_OP, ARGI_LOAD_OP, ACPI_TYPE_ANY,
449 AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_1T_0R,
450 AML_FLAGS_EXEC_1A_1T_0R),
451/* 4B */ ACPI_OP("Stall", ARGP_STALL_OP, ARGI_STALL_OP, ACPI_TYPE_ANY,
452 AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_0R,
453 AML_FLAGS_EXEC_1A_0T_0R),
454/* 4C */ ACPI_OP("Sleep", ARGP_SLEEP_OP, ARGI_SLEEP_OP, ACPI_TYPE_ANY,
455 AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_0R,
456 AML_FLAGS_EXEC_1A_0T_0R),
457/* 4D */ ACPI_OP("Acquire", ARGP_ACQUIRE_OP, ARGI_ACQUIRE_OP,
458 ACPI_TYPE_ANY, AML_CLASS_EXECUTE,
459 AML_TYPE_EXEC_2A_0T_1R, AML_FLAGS_EXEC_2A_0T_1R),
460/* 4E */ ACPI_OP("Signal", ARGP_SIGNAL_OP, ARGI_SIGNAL_OP,
461 ACPI_TYPE_ANY, AML_CLASS_EXECUTE,
462 AML_TYPE_EXEC_1A_0T_0R, AML_FLAGS_EXEC_1A_0T_0R),
463/* 4F */ ACPI_OP("Wait", ARGP_WAIT_OP, ARGI_WAIT_OP, ACPI_TYPE_ANY,
464 AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_0T_1R,
465 AML_FLAGS_EXEC_2A_0T_1R),
466/* 50 */ ACPI_OP("Reset", ARGP_RESET_OP, ARGI_RESET_OP, ACPI_TYPE_ANY,
467 AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_0R,
468 AML_FLAGS_EXEC_1A_0T_0R),
469/* 51 */ ACPI_OP("Release", ARGP_RELEASE_OP, ARGI_RELEASE_OP,
470 ACPI_TYPE_ANY, AML_CLASS_EXECUTE,
471 AML_TYPE_EXEC_1A_0T_0R, AML_FLAGS_EXEC_1A_0T_0R),
472/* 52 */ ACPI_OP("FromBCD", ARGP_FROM_BCD_OP, ARGI_FROM_BCD_OP,
473 ACPI_TYPE_ANY, AML_CLASS_EXECUTE,
474 AML_TYPE_EXEC_1A_1T_1R,
475 AML_FLAGS_EXEC_1A_1T_1R | AML_CONSTANT),
476/* 53 */ ACPI_OP("ToBCD", ARGP_TO_BCD_OP, ARGI_TO_BCD_OP, ACPI_TYPE_ANY,
477 AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_1T_1R,
478 AML_FLAGS_EXEC_1A_1T_1R | AML_CONSTANT),
479/* 54 */ ACPI_OP("Unload", ARGP_UNLOAD_OP, ARGI_UNLOAD_OP,
480 ACPI_TYPE_ANY, AML_CLASS_EXECUTE,
481 AML_TYPE_EXEC_1A_0T_0R, AML_FLAGS_EXEC_1A_0T_0R),
482/* 55 */ ACPI_OP("Revision", ARGP_REVISION_OP, ARGI_REVISION_OP,
483 ACPI_TYPE_INTEGER, AML_CLASS_ARGUMENT,
484 AML_TYPE_CONSTANT, 0),
485/* 56 */ ACPI_OP("Debug", ARGP_DEBUG_OP, ARGI_DEBUG_OP,
486 ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT,
487 AML_TYPE_CONSTANT, 0),
488/* 57 */ ACPI_OP("Fatal", ARGP_FATAL_OP, ARGI_FATAL_OP, ACPI_TYPE_ANY,
489 AML_CLASS_EXECUTE, AML_TYPE_EXEC_3A_0T_0R,
490 AML_FLAGS_EXEC_3A_0T_0R),
491/* 58 */ ACPI_OP("OperationRegion", ARGP_REGION_OP, ARGI_REGION_OP,
492 ACPI_TYPE_REGION, AML_CLASS_NAMED_OBJECT,
493 AML_TYPE_NAMED_COMPLEX,
494 AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE |
495 AML_NSNODE | AML_NAMED | AML_DEFER),
496/* 59 */ ACPI_OP("Field", ARGP_FIELD_OP, ARGI_FIELD_OP, ACPI_TYPE_ANY,
497 AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_FIELD,
498 AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_FIELD),
499/* 5A */ ACPI_OP("Device", ARGP_DEVICE_OP, ARGI_DEVICE_OP,
500 ACPI_TYPE_DEVICE, AML_CLASS_NAMED_OBJECT,
501 AML_TYPE_NAMED_NO_OBJ,
502 AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE |
503 AML_NSNODE | AML_NAMED),
504/* 5B */ ACPI_OP("Processor", ARGP_PROCESSOR_OP, ARGI_PROCESSOR_OP,
505 ACPI_TYPE_PROCESSOR, AML_CLASS_NAMED_OBJECT,
506 AML_TYPE_NAMED_SIMPLE,
507 AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE |
508 AML_NSNODE | AML_NAMED),
509/* 5C */ ACPI_OP("PowerResource", ARGP_POWER_RES_OP, ARGI_POWER_RES_OP,
510 ACPI_TYPE_POWER, AML_CLASS_NAMED_OBJECT,
511 AML_TYPE_NAMED_SIMPLE,
512 AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE |
513 AML_NSNODE | AML_NAMED),
514/* 5D */ ACPI_OP("ThermalZone", ARGP_THERMAL_ZONE_OP,
515 ARGI_THERMAL_ZONE_OP, ACPI_TYPE_THERMAL,
516 AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_NO_OBJ,
517 AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE |
518 AML_NSNODE | AML_NAMED),
519/* 5E */ ACPI_OP("IndexField", ARGP_INDEX_FIELD_OP, ARGI_INDEX_FIELD_OP,
520 ACPI_TYPE_ANY, AML_CLASS_NAMED_OBJECT,
521 AML_TYPE_NAMED_FIELD,
522 AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_FIELD),
523/* 5F */ ACPI_OP("BankField", ARGP_BANK_FIELD_OP, ARGI_BANK_FIELD_OP,
524 ACPI_TYPE_LOCAL_BANK_FIELD, AML_CLASS_NAMED_OBJECT,
525 AML_TYPE_NAMED_FIELD,
526 AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_FIELD |
527 AML_DEFER),
528
529/* Internal opcodes that map to invalid AML opcodes */
530
531/* 60 */ ACPI_OP("LNotEqual", ARGP_LNOTEQUAL_OP, ARGI_LNOTEQUAL_OP,
532 ACPI_TYPE_ANY, AML_CLASS_INTERNAL,
533 AML_TYPE_BOGUS, AML_HAS_ARGS | AML_CONSTANT),
534/* 61 */ ACPI_OP("LLessEqual", ARGP_LLESSEQUAL_OP, ARGI_LLESSEQUAL_OP,
535 ACPI_TYPE_ANY, AML_CLASS_INTERNAL,
536 AML_TYPE_BOGUS, AML_HAS_ARGS | AML_CONSTANT),
537/* 62 */ ACPI_OP("LGreaterEqual", ARGP_LGREATEREQUAL_OP,
538 ARGI_LGREATEREQUAL_OP, ACPI_TYPE_ANY,
539 AML_CLASS_INTERNAL, AML_TYPE_BOGUS,
540 AML_HAS_ARGS | AML_CONSTANT),
541/* 63 */ ACPI_OP("-NamePath-", ARGP_NAMEPATH_OP, ARGI_NAMEPATH_OP,
542 ACPI_TYPE_LOCAL_REFERENCE, AML_CLASS_ARGUMENT,
543 AML_TYPE_LITERAL, AML_NSOBJECT | AML_NSNODE),
544/* 64 */ ACPI_OP("-MethodCall-", ARGP_METHODCALL_OP, ARGI_METHODCALL_OP,
545 ACPI_TYPE_METHOD, AML_CLASS_METHOD_CALL,
546 AML_TYPE_METHOD_CALL,
547 AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE),
548/* 65 */ ACPI_OP("-ByteList-", ARGP_BYTELIST_OP, ARGI_BYTELIST_OP,
549 ACPI_TYPE_ANY, AML_CLASS_ARGUMENT,
550 AML_TYPE_LITERAL, 0),
551/* 66 */ ACPI_OP("-ReservedField-", ARGP_RESERVEDFIELD_OP,
552 ARGI_RESERVEDFIELD_OP, ACPI_TYPE_ANY,
553 AML_CLASS_INTERNAL, AML_TYPE_BOGUS, 0),
554/* 67 */ ACPI_OP("-NamedField-", ARGP_NAMEDFIELD_OP, ARGI_NAMEDFIELD_OP,
555 ACPI_TYPE_ANY, AML_CLASS_INTERNAL,
556 AML_TYPE_BOGUS,
557 AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE | AML_NAMED),
558/* 68 */ ACPI_OP("-AccessField-", ARGP_ACCESSFIELD_OP,
559 ARGI_ACCESSFIELD_OP, ACPI_TYPE_ANY,
560 AML_CLASS_INTERNAL, AML_TYPE_BOGUS, 0),
561/* 69 */ ACPI_OP("-StaticString", ARGP_STATICSTRING_OP,
562 ARGI_STATICSTRING_OP, ACPI_TYPE_ANY,
563 AML_CLASS_INTERNAL, AML_TYPE_BOGUS, 0),
564/* 6A */ ACPI_OP("-Return Value-", ARG_NONE, ARG_NONE, ACPI_TYPE_ANY,
565 AML_CLASS_RETURN_VALUE, AML_TYPE_RETURN,
566 AML_HAS_ARGS | AML_HAS_RETVAL),
567/* 6B */ ACPI_OP("-UNKNOWN_OP-", ARG_NONE, ARG_NONE, ACPI_TYPE_INVALID,
568 AML_CLASS_UNKNOWN, AML_TYPE_BOGUS, AML_HAS_ARGS),
569/* 6C */ ACPI_OP("-ASCII_ONLY-", ARG_NONE, ARG_NONE, ACPI_TYPE_ANY,
570 AML_CLASS_ASCII, AML_TYPE_BOGUS, AML_HAS_ARGS),
571/* 6D */ ACPI_OP("-PREFIX_ONLY-", ARG_NONE, ARG_NONE, ACPI_TYPE_ANY,
572 AML_CLASS_PREFIX, AML_TYPE_BOGUS, AML_HAS_ARGS),
573
574/* ACPI 2.0 opcodes */
575
576/* 6E */ ACPI_OP("QwordConst", ARGP_QWORD_OP, ARGI_QWORD_OP,
577 ACPI_TYPE_INTEGER, AML_CLASS_ARGUMENT,
578 AML_TYPE_LITERAL, AML_CONSTANT),
579 /* 6F */ ACPI_OP("Package", /* Var */ ARGP_VAR_PACKAGE_OP,
580 ARGI_VAR_PACKAGE_OP, ACPI_TYPE_PACKAGE,
581 AML_CLASS_CREATE, AML_TYPE_CREATE_OBJECT,
582 AML_HAS_ARGS | AML_DEFER),
583/* 70 */ ACPI_OP("ConcatenateResTemplate", ARGP_CONCAT_RES_OP,
584 ARGI_CONCAT_RES_OP, ACPI_TYPE_ANY,
585 AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R,
586 AML_FLAGS_EXEC_2A_1T_1R | AML_CONSTANT),
587/* 71 */ ACPI_OP("Mod", ARGP_MOD_OP, ARGI_MOD_OP, ACPI_TYPE_ANY,
588 AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_1T_1R,
589 AML_FLAGS_EXEC_2A_1T_1R | AML_CONSTANT),
590/* 72 */ ACPI_OP("CreateQWordField", ARGP_CREATE_QWORD_FIELD_OP,
591 ARGI_CREATE_QWORD_FIELD_OP,
592 ACPI_TYPE_BUFFER_FIELD, AML_CLASS_CREATE,
593 AML_TYPE_CREATE_FIELD,
594 AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE |
595 AML_DEFER | AML_CREATE),
596/* 73 */ ACPI_OP("ToBuffer", ARGP_TO_BUFFER_OP, ARGI_TO_BUFFER_OP,
597 ACPI_TYPE_ANY, AML_CLASS_EXECUTE,
598 AML_TYPE_EXEC_1A_1T_1R,
599 AML_FLAGS_EXEC_1A_1T_1R | AML_CONSTANT),
600/* 74 */ ACPI_OP("ToDecimalString", ARGP_TO_DEC_STR_OP,
601 ARGI_TO_DEC_STR_OP, ACPI_TYPE_ANY,
602 AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_1T_1R,
603 AML_FLAGS_EXEC_1A_1T_1R | AML_CONSTANT),
604/* 75 */ ACPI_OP("ToHexString", ARGP_TO_HEX_STR_OP, ARGI_TO_HEX_STR_OP,
605 ACPI_TYPE_ANY, AML_CLASS_EXECUTE,
606 AML_TYPE_EXEC_1A_1T_1R,
607 AML_FLAGS_EXEC_1A_1T_1R | AML_CONSTANT),
608/* 76 */ ACPI_OP("ToInteger", ARGP_TO_INTEGER_OP, ARGI_TO_INTEGER_OP,
609 ACPI_TYPE_ANY, AML_CLASS_EXECUTE,
610 AML_TYPE_EXEC_1A_1T_1R,
611 AML_FLAGS_EXEC_1A_1T_1R | AML_CONSTANT),
612/* 77 */ ACPI_OP("ToString", ARGP_TO_STRING_OP, ARGI_TO_STRING_OP,
613 ACPI_TYPE_ANY, AML_CLASS_EXECUTE,
614 AML_TYPE_EXEC_2A_1T_1R,
615 AML_FLAGS_EXEC_2A_1T_1R | AML_CONSTANT),
616/* 78 */ ACPI_OP("CopyObject", ARGP_COPY_OP, ARGI_COPY_OP,
617 ACPI_TYPE_ANY, AML_CLASS_EXECUTE,
618 AML_TYPE_EXEC_1A_1T_1R, AML_FLAGS_EXEC_1A_1T_1R),
619/* 79 */ ACPI_OP("Mid", ARGP_MID_OP, ARGI_MID_OP, ACPI_TYPE_ANY,
620 AML_CLASS_EXECUTE, AML_TYPE_EXEC_3A_1T_1R,
621 AML_FLAGS_EXEC_3A_1T_1R | AML_CONSTANT),
622/* 7A */ ACPI_OP("Continue", ARGP_CONTINUE_OP, ARGI_CONTINUE_OP,
623 ACPI_TYPE_ANY, AML_CLASS_CONTROL, AML_TYPE_CONTROL, 0),
624/* 7B */ ACPI_OP("LoadTable", ARGP_LOAD_TABLE_OP, ARGI_LOAD_TABLE_OP,
625 ACPI_TYPE_ANY, AML_CLASS_EXECUTE,
626 AML_TYPE_EXEC_6A_0T_1R, AML_FLAGS_EXEC_6A_0T_1R),
627/* 7C */ ACPI_OP("DataTableRegion", ARGP_DATA_REGION_OP,
628 ARGI_DATA_REGION_OP, ACPI_TYPE_REGION,
629 AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_COMPLEX,
630 AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE |
631 AML_NSNODE | AML_NAMED | AML_DEFER),
632/* 7D */ ACPI_OP("[EvalSubTree]", ARGP_SCOPE_OP, ARGI_SCOPE_OP,
633 ACPI_TYPE_ANY, AML_CLASS_NAMED_OBJECT,
634 AML_TYPE_NAMED_NO_OBJ,
635 AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE),
636
637/* ACPI 3.0 opcodes */
638
639/* 7E */ ACPI_OP("Timer", ARGP_TIMER_OP, ARGI_TIMER_OP, ACPI_TYPE_ANY,
640 AML_CLASS_EXECUTE, AML_TYPE_EXEC_0A_0T_1R,
641 AML_FLAGS_EXEC_0A_0T_1R)
642
643/*! [End] no source code translation !*/
644};
645
646/*
647 * This table is directly indexed by the opcodes, and returns an
648 * index into the table above
649 */
650static const u8 acpi_gbl_short_op_index[256] = {
651/* 0 1 2 3 4 5 6 7 */
652/* 8 9 A B C D E F */
653/* 0x00 */ 0x00, 0x01, _UNK, _UNK, _UNK, _UNK, 0x02, _UNK,
654/* 0x08 */ 0x03, _UNK, 0x04, 0x05, 0x06, 0x07, 0x6E, _UNK,
655/* 0x10 */ 0x08, 0x09, 0x0a, 0x6F, 0x0b, _UNK, _UNK, _UNK,
656/* 0x18 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
657/* 0x20 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
658/* 0x28 */ _UNK, _UNK, _UNK, _UNK, _UNK, 0x63, _PFX, _PFX,
659/* 0x30 */ 0x67, 0x66, 0x68, 0x65, 0x69, 0x64, 0x6A, 0x7D,
660/* 0x38 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
661/* 0x40 */ _UNK, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC,
662/* 0x48 */ _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC,
663/* 0x50 */ _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC,
664/* 0x58 */ _ASC, _ASC, _ASC, _UNK, _PFX, _UNK, _PFX, _ASC,
665/* 0x60 */ 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13,
666/* 0x68 */ 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, _UNK,
667/* 0x70 */ 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22,
668/* 0x78 */ 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a,
669/* 0x80 */ 0x2b, 0x2c, 0x2d, 0x2e, 0x70, 0x71, 0x2f, 0x30,
670/* 0x88 */ 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x72,
671/* 0x90 */ 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x73, 0x74,
672/* 0x98 */ 0x75, 0x76, _UNK, _UNK, 0x77, 0x78, 0x79, 0x7A,
673/* 0xA0 */ 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x60, 0x61,
674/* 0xA8 */ 0x62, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
675/* 0xB0 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
676/* 0xB8 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
677/* 0xC0 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
678/* 0xC8 */ _UNK, _UNK, _UNK, _UNK, 0x44, _UNK, _UNK, _UNK,
679/* 0xD0 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
680/* 0xD8 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
681/* 0xE0 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
682/* 0xE8 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
683/* 0xF0 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
684/* 0xF8 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, 0x45,
685};
686
687/*
688 * This table is indexed by the second opcode of the extended opcode
689 * pair. It returns an index into the opcode table (acpi_gbl_aml_op_info)
690 */
691static const u8 acpi_gbl_long_op_index[NUM_EXTENDED_OPCODE] = {
692/* 0 1 2 3 4 5 6 7 */
693/* 8 9 A B C D E F */
694/* 0x00 */ _UNK, 0x46, 0x47, _UNK, _UNK, _UNK, _UNK, _UNK,
695/* 0x08 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
696/* 0x10 */ _UNK, _UNK, 0x48, 0x49, _UNK, _UNK, _UNK, _UNK,
697/* 0x18 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, 0x7B,
698/* 0x20 */ 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51,
699/* 0x28 */ 0x52, 0x53, 0x54, _UNK, _UNK, _UNK, _UNK, _UNK,
700/* 0x30 */ 0x55, 0x56, 0x57, 0x7e, _UNK, _UNK, _UNK, _UNK,
701/* 0x38 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
702/* 0x40 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
703/* 0x48 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
704/* 0x50 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
705/* 0x58 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
706/* 0x60 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
707/* 0x68 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
708/* 0x70 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
709/* 0x78 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
710/* 0x80 */ 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
711/* 0x88 */ 0x7C,
712};
713
714/*******************************************************************************
715 *
716 * FUNCTION: acpi_ps_get_opcode_info
717 *
718 * PARAMETERS: Opcode - The AML opcode
719 *
720 * RETURN: A pointer to the info about the opcode.
721 *
722 * DESCRIPTION: Find AML opcode description based on the opcode.
723 * NOTE: This procedure must ALWAYS return a valid pointer!
724 *
725 ******************************************************************************/
726
727const struct acpi_opcode_info *acpi_ps_get_opcode_info(u16 opcode)
728{
729 ACPI_FUNCTION_NAME(ps_get_opcode_info);
730
731 /*
732 * Detect normal 8-bit opcode or extended 16-bit opcode
733 */
734 if (!(opcode & 0xFF00)) {
735
736 /* Simple (8-bit) opcode: 0-255, can't index beyond table */
737
738 return (&acpi_gbl_aml_op_info
739 [acpi_gbl_short_op_index[(u8) opcode]]);
740 }
741
742 if (((opcode & 0xFF00) == AML_EXTENDED_OPCODE) &&
743 (((u8) opcode) <= MAX_EXTENDED_OPCODE)) {
744
745 /* Valid extended (16-bit) opcode */
746
747 return (&acpi_gbl_aml_op_info
748 [acpi_gbl_long_op_index[(u8) opcode]]);
749 }
750
751 /* Unknown AML opcode */
752
753 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
754 "Unknown AML opcode [%4.4X]\n", opcode));
755
756 return (&acpi_gbl_aml_op_info[_UNK]);
757}
758
759/*******************************************************************************
760 *
761 * FUNCTION: acpi_ps_get_opcode_name
762 *
763 * PARAMETERS: Opcode - The AML opcode
764 *
765 * RETURN: A pointer to the name of the opcode (ASCII String)
766 * Note: Never returns NULL.
767 *
768 * DESCRIPTION: Translate an opcode into a human-readable string
769 *
770 ******************************************************************************/
771
772char *acpi_ps_get_opcode_name(u16 opcode)
773{
774#if defined(ACPI_DISASSEMBLER) || defined (ACPI_DEBUG_OUTPUT)
775
776 const struct acpi_opcode_info *op;
777
778 op = acpi_ps_get_opcode_info(opcode);
779
780 /* Always guaranteed to return a valid pointer */
781
782 return (op->name);
783
784#else
785 return ("OpcodeName unavailable");
786
787#endif
788}
789
790/*******************************************************************************
791 *
792 * FUNCTION: acpi_ps_get_argument_count
793 *
794 * PARAMETERS: op_type - Type associated with the AML opcode
795 *
796 * RETURN: Argument count
797 *
798 * DESCRIPTION: Obtain the number of expected arguments for an AML opcode
799 *
800 ******************************************************************************/
801
802u8 acpi_ps_get_argument_count(u32 op_type)
803{
804
805 if (op_type <= AML_TYPE_EXEC_6A_0T_1R) {
806 return (acpi_gbl_argument_count[op_type]);
807 }
808
809 return (0);
810}
diff --git a/drivers/acpi/acpica/psparse.c b/drivers/acpi/acpica/psparse.c
new file mode 100644
index 00000000000..9da48fdb811
--- /dev/null
+++ b/drivers/acpi/acpica/psparse.c
@@ -0,0 +1,701 @@
1/******************************************************************************
2 *
3 * Module Name: psparse - Parser top level AML parse routines
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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 * Parse the AML and build an operation tree as most interpreters,
46 * like Perl, do. Parsing is done by hand rather than with a YACC
47 * generated parser to tightly constrain stack and dynamic memory
48 * usage. At the same time, parsing is kept flexible and the code
49 * fairly compact by parsing based on a list of AML opcode
50 * templates in aml_op_info[]
51 */
52
53#include <acpi/acpi.h>
54#include <acpi/accommon.h>
55#include <acpi/acparser.h>
56#include <acpi/acdispat.h>
57#include <acpi/amlcode.h>
58#include <acpi/acnamesp.h>
59#include <acpi/acinterp.h>
60
61#define _COMPONENT ACPI_PARSER
62ACPI_MODULE_NAME("psparse")
63
64/*******************************************************************************
65 *
66 * FUNCTION: acpi_ps_get_opcode_size
67 *
68 * PARAMETERS: Opcode - An AML opcode
69 *
70 * RETURN: Size of the opcode, in bytes (1 or 2)
71 *
72 * DESCRIPTION: Get the size of the current opcode.
73 *
74 ******************************************************************************/
75u32 acpi_ps_get_opcode_size(u32 opcode)
76{
77
78 /* Extended (2-byte) opcode if > 255 */
79
80 if (opcode > 0x00FF) {
81 return (2);
82 }
83
84 /* Otherwise, just a single byte opcode */
85
86 return (1);
87}
88
89/*******************************************************************************
90 *
91 * FUNCTION: acpi_ps_peek_opcode
92 *
93 * PARAMETERS: parser_state - A parser state object
94 *
95 * RETURN: Next AML opcode
96 *
97 * DESCRIPTION: Get next AML opcode (without incrementing AML pointer)
98 *
99 ******************************************************************************/
100
101u16 acpi_ps_peek_opcode(struct acpi_parse_state * parser_state)
102{
103 u8 *aml;
104 u16 opcode;
105
106 aml = parser_state->aml;
107 opcode = (u16) ACPI_GET8(aml);
108
109 if (opcode == AML_EXTENDED_OP_PREFIX) {
110
111 /* Extended opcode, get the second opcode byte */
112
113 aml++;
114 opcode = (u16) ((opcode << 8) | ACPI_GET8(aml));
115 }
116
117 return (opcode);
118}
119
120/*******************************************************************************
121 *
122 * FUNCTION: acpi_ps_complete_this_op
123 *
124 * PARAMETERS: walk_state - Current State
125 * Op - Op to complete
126 *
127 * RETURN: Status
128 *
129 * DESCRIPTION: Perform any cleanup at the completion of an Op.
130 *
131 ******************************************************************************/
132
133acpi_status
134acpi_ps_complete_this_op(struct acpi_walk_state * walk_state,
135 union acpi_parse_object * op)
136{
137 union acpi_parse_object *prev;
138 union acpi_parse_object *next;
139 const struct acpi_opcode_info *parent_info;
140 union acpi_parse_object *replacement_op = NULL;
141 acpi_status status = AE_OK;
142
143 ACPI_FUNCTION_TRACE_PTR(ps_complete_this_op, op);
144
145 /* Check for null Op, can happen if AML code is corrupt */
146
147 if (!op) {
148 return_ACPI_STATUS(AE_OK); /* OK for now */
149 }
150
151 /* Delete this op and the subtree below it if asked to */
152
153 if (((walk_state->parse_flags & ACPI_PARSE_TREE_MASK) !=
154 ACPI_PARSE_DELETE_TREE)
155 || (walk_state->op_info->class == AML_CLASS_ARGUMENT)) {
156 return_ACPI_STATUS(AE_OK);
157 }
158
159 /* Make sure that we only delete this subtree */
160
161 if (op->common.parent) {
162 prev = op->common.parent->common.value.arg;
163 if (!prev) {
164
165 /* Nothing more to do */
166
167 goto cleanup;
168 }
169
170 /*
171 * Check if we need to replace the operator and its subtree
172 * with a return value op (placeholder op)
173 */
174 parent_info =
175 acpi_ps_get_opcode_info(op->common.parent->common.
176 aml_opcode);
177
178 switch (parent_info->class) {
179 case AML_CLASS_CONTROL:
180 break;
181
182 case AML_CLASS_CREATE:
183
184 /*
185 * These opcodes contain term_arg operands. The current
186 * op must be replaced by a placeholder return op
187 */
188 replacement_op =
189 acpi_ps_alloc_op(AML_INT_RETURN_VALUE_OP);
190 if (!replacement_op) {
191 status = AE_NO_MEMORY;
192 }
193 break;
194
195 case AML_CLASS_NAMED_OBJECT:
196
197 /*
198 * These opcodes contain term_arg operands. The current
199 * op must be replaced by a placeholder return op
200 */
201 if ((op->common.parent->common.aml_opcode ==
202 AML_REGION_OP)
203 || (op->common.parent->common.aml_opcode ==
204 AML_DATA_REGION_OP)
205 || (op->common.parent->common.aml_opcode ==
206 AML_BUFFER_OP)
207 || (op->common.parent->common.aml_opcode ==
208 AML_PACKAGE_OP)
209 || (op->common.parent->common.aml_opcode ==
210 AML_BANK_FIELD_OP)
211 || (op->common.parent->common.aml_opcode ==
212 AML_VAR_PACKAGE_OP)) {
213 replacement_op =
214 acpi_ps_alloc_op(AML_INT_RETURN_VALUE_OP);
215 if (!replacement_op) {
216 status = AE_NO_MEMORY;
217 }
218 } else
219 if ((op->common.parent->common.aml_opcode ==
220 AML_NAME_OP)
221 && (walk_state->pass_number <=
222 ACPI_IMODE_LOAD_PASS2)) {
223 if ((op->common.aml_opcode == AML_BUFFER_OP)
224 || (op->common.aml_opcode == AML_PACKAGE_OP)
225 || (op->common.aml_opcode ==
226 AML_VAR_PACKAGE_OP)) {
227 replacement_op =
228 acpi_ps_alloc_op(op->common.
229 aml_opcode);
230 if (!replacement_op) {
231 status = AE_NO_MEMORY;
232 } else {
233 replacement_op->named.data =
234 op->named.data;
235 replacement_op->named.length =
236 op->named.length;
237 }
238 }
239 }
240 break;
241
242 default:
243
244 replacement_op =
245 acpi_ps_alloc_op(AML_INT_RETURN_VALUE_OP);
246 if (!replacement_op) {
247 status = AE_NO_MEMORY;
248 }
249 }
250
251 /* We must unlink this op from the parent tree */
252
253 if (prev == op) {
254
255 /* This op is the first in the list */
256
257 if (replacement_op) {
258 replacement_op->common.parent =
259 op->common.parent;
260 replacement_op->common.value.arg = NULL;
261 replacement_op->common.node = op->common.node;
262 op->common.parent->common.value.arg =
263 replacement_op;
264 replacement_op->common.next = op->common.next;
265 } else {
266 op->common.parent->common.value.arg =
267 op->common.next;
268 }
269 }
270
271 /* Search the parent list */
272
273 else
274 while (prev) {
275
276 /* Traverse all siblings in the parent's argument list */
277
278 next = prev->common.next;
279 if (next == op) {
280 if (replacement_op) {
281 replacement_op->common.parent =
282 op->common.parent;
283 replacement_op->common.value.
284 arg = NULL;
285 replacement_op->common.node =
286 op->common.node;
287 prev->common.next =
288 replacement_op;
289 replacement_op->common.next =
290 op->common.next;
291 next = NULL;
292 } else {
293 prev->common.next =
294 op->common.next;
295 next = NULL;
296 }
297 }
298 prev = next;
299 }
300 }
301
302 cleanup:
303
304 /* Now we can actually delete the subtree rooted at Op */
305
306 acpi_ps_delete_parse_tree(op);
307 return_ACPI_STATUS(status);
308}
309
310/*******************************************************************************
311 *
312 * FUNCTION: acpi_ps_next_parse_state
313 *
314 * PARAMETERS: walk_state - Current state
315 * Op - Current parse op
316 * callback_status - Status from previous operation
317 *
318 * RETURN: Status
319 *
320 * DESCRIPTION: Update the parser state based upon the return exception from
321 * the parser callback.
322 *
323 ******************************************************************************/
324
325acpi_status
326acpi_ps_next_parse_state(struct acpi_walk_state *walk_state,
327 union acpi_parse_object *op,
328 acpi_status callback_status)
329{
330 struct acpi_parse_state *parser_state = &walk_state->parser_state;
331 acpi_status status = AE_CTRL_PENDING;
332
333 ACPI_FUNCTION_TRACE_PTR(ps_next_parse_state, op);
334
335 switch (callback_status) {
336 case AE_CTRL_TERMINATE:
337 /*
338 * A control method was terminated via a RETURN statement.
339 * The walk of this method is complete.
340 */
341 parser_state->aml = parser_state->aml_end;
342 status = AE_CTRL_TERMINATE;
343 break;
344
345 case AE_CTRL_BREAK:
346
347 parser_state->aml = walk_state->aml_last_while;
348 walk_state->control_state->common.value = FALSE;
349 status = AE_CTRL_BREAK;
350 break;
351
352 case AE_CTRL_CONTINUE:
353
354 parser_state->aml = walk_state->aml_last_while;
355 status = AE_CTRL_CONTINUE;
356 break;
357
358 case AE_CTRL_PENDING:
359
360 parser_state->aml = walk_state->aml_last_while;
361 break;
362
363#if 0
364 case AE_CTRL_SKIP:
365
366 parser_state->aml = parser_state->scope->parse_scope.pkg_end;
367 status = AE_OK;
368 break;
369#endif
370
371 case AE_CTRL_TRUE:
372 /*
373 * Predicate of an IF was true, and we are at the matching ELSE.
374 * Just close out this package
375 */
376 parser_state->aml = acpi_ps_get_next_package_end(parser_state);
377 status = AE_CTRL_PENDING;
378 break;
379
380 case AE_CTRL_FALSE:
381 /*
382 * Either an IF/WHILE Predicate was false or we encountered a BREAK
383 * opcode. In both cases, we do not execute the rest of the
384 * package; We simply close out the parent (finishing the walk of
385 * this branch of the tree) and continue execution at the parent
386 * level.
387 */
388 parser_state->aml = parser_state->scope->parse_scope.pkg_end;
389
390 /* In the case of a BREAK, just force a predicate (if any) to FALSE */
391
392 walk_state->control_state->common.value = FALSE;
393 status = AE_CTRL_END;
394 break;
395
396 case AE_CTRL_TRANSFER:
397
398 /* A method call (invocation) -- transfer control */
399
400 status = AE_CTRL_TRANSFER;
401 walk_state->prev_op = op;
402 walk_state->method_call_op = op;
403 walk_state->method_call_node =
404 (op->common.value.arg)->common.node;
405
406 /* Will return value (if any) be used by the caller? */
407
408 walk_state->return_used =
409 acpi_ds_is_result_used(op, walk_state);
410 break;
411
412 default:
413
414 status = callback_status;
415 if ((callback_status & AE_CODE_MASK) == AE_CODE_CONTROL) {
416 status = AE_OK;
417 }
418 break;
419 }
420
421 return_ACPI_STATUS(status);
422}
423
424/*******************************************************************************
425 *
426 * FUNCTION: acpi_ps_parse_aml
427 *
428 * PARAMETERS: walk_state - Current state
429 *
430 *
431 * RETURN: Status
432 *
433 * DESCRIPTION: Parse raw AML and return a tree of ops
434 *
435 ******************************************************************************/
436
437acpi_status acpi_ps_parse_aml(struct acpi_walk_state *walk_state)
438{
439 acpi_status status;
440 struct acpi_thread_state *thread;
441 struct acpi_thread_state *prev_walk_list = acpi_gbl_current_walk_list;
442 struct acpi_walk_state *previous_walk_state;
443
444 ACPI_FUNCTION_TRACE(ps_parse_aml);
445
446 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
447 "Entered with WalkState=%p Aml=%p size=%X\n",
448 walk_state, walk_state->parser_state.aml,
449 walk_state->parser_state.aml_size));
450
451 if (!walk_state->parser_state.aml) {
452 return_ACPI_STATUS(AE_NULL_OBJECT);
453 }
454
455 /* Create and initialize a new thread state */
456
457 thread = acpi_ut_create_thread_state();
458 if (!thread) {
459 if (walk_state->method_desc) {
460
461 /* Executing a control method - additional cleanup */
462
463 acpi_ds_terminate_control_method(
464 walk_state->method_desc, walk_state);
465 }
466
467 acpi_ds_delete_walk_state(walk_state);
468 return_ACPI_STATUS(AE_NO_MEMORY);
469 }
470
471 walk_state->thread = thread;
472
473 /*
474 * If executing a method, the starting sync_level is this method's
475 * sync_level
476 */
477 if (walk_state->method_desc) {
478 walk_state->thread->current_sync_level =
479 walk_state->method_desc->method.sync_level;
480 }
481
482 acpi_ds_push_walk_state(walk_state, thread);
483
484 /*
485 * This global allows the AML debugger to get a handle to the currently
486 * executing control method.
487 */
488 acpi_gbl_current_walk_list = thread;
489
490 /*
491 * Execute the walk loop as long as there is a valid Walk State. This
492 * handles nested control method invocations without recursion.
493 */
494 ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "State=%p\n", walk_state));
495
496 status = AE_OK;
497 while (walk_state) {
498 if (ACPI_SUCCESS(status)) {
499 /*
500 * The parse_loop executes AML until the method terminates
501 * or calls another method.
502 */
503 status = acpi_ps_parse_loop(walk_state);
504 }
505
506 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
507 "Completed one call to walk loop, %s State=%p\n",
508 acpi_format_exception(status), walk_state));
509
510 if (status == AE_CTRL_TRANSFER) {
511 /*
512 * A method call was detected.
513 * Transfer control to the called control method
514 */
515 status =
516 acpi_ds_call_control_method(thread, walk_state,
517 NULL);
518 if (ACPI_FAILURE(status)) {
519 status =
520 acpi_ds_method_error(status, walk_state);
521 }
522
523 /*
524 * If the transfer to the new method method call worked, a new walk
525 * state was created -- get it
526 */
527 walk_state = acpi_ds_get_current_walk_state(thread);
528 continue;
529 } else if (status == AE_CTRL_TERMINATE) {
530 status = AE_OK;
531 } else if ((status != AE_OK) && (walk_state->method_desc)) {
532
533 /* Either the method parse or actual execution failed */
534
535 ACPI_ERROR_METHOD("Method parse/execution failed",
536 walk_state->method_node, NULL,
537 status);
538
539 /* Check for possible multi-thread reentrancy problem */
540
541 if ((status == AE_ALREADY_EXISTS) &&
542 (!walk_state->method_desc->method.mutex)) {
543 ACPI_INFO((AE_INFO,
544 "Marking method %4.4s as Serialized because of AE_ALREADY_EXISTS error",
545 walk_state->method_node->name.
546 ascii));
547
548 /*
549 * Method tried to create an object twice. The probable cause is
550 * that the method cannot handle reentrancy.
551 *
552 * The method is marked not_serialized, but it tried to create
553 * a named object, causing the second thread entrance to fail.
554 * Workaround this problem by marking the method permanently
555 * as Serialized.
556 */
557 walk_state->method_desc->method.method_flags |=
558 AML_METHOD_SERIALIZED;
559 walk_state->method_desc->method.sync_level = 0;
560 }
561 }
562
563 /* We are done with this walk, move on to the parent if any */
564
565 walk_state = acpi_ds_pop_walk_state(thread);
566
567 /* Reset the current scope to the beginning of scope stack */
568
569 acpi_ds_scope_stack_clear(walk_state);
570
571 /*
572 * If we just returned from the execution of a control method or if we
573 * encountered an error during the method parse phase, there's lots of
574 * cleanup to do
575 */
576 if (((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) ==
577 ACPI_PARSE_EXECUTE) || (ACPI_FAILURE(status))) {
578 acpi_ds_terminate_control_method(walk_state->
579 method_desc,
580 walk_state);
581 }
582
583 /* Delete this walk state and all linked control states */
584
585 acpi_ps_cleanup_scope(&walk_state->parser_state);
586 previous_walk_state = walk_state;
587
588 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
589 "ReturnValue=%p, ImplicitValue=%p State=%p\n",
590 walk_state->return_desc,
591 walk_state->implicit_return_obj, walk_state));
592
593 /* Check if we have restarted a preempted walk */
594
595 walk_state = acpi_ds_get_current_walk_state(thread);
596 if (walk_state) {
597 if (ACPI_SUCCESS(status)) {
598 /*
599 * There is another walk state, restart it.
600 * If the method return value is not used by the parent,
601 * The object is deleted
602 */
603 if (!previous_walk_state->return_desc) {
604 /*
605 * In slack mode execution, if there is no return value
606 * we should implicitly return zero (0) as a default value.
607 */
608 if (acpi_gbl_enable_interpreter_slack &&
609 !previous_walk_state->
610 implicit_return_obj) {
611 previous_walk_state->
612 implicit_return_obj =
613 acpi_ut_create_internal_object
614 (ACPI_TYPE_INTEGER);
615 if (!previous_walk_state->
616 implicit_return_obj) {
617 return_ACPI_STATUS
618 (AE_NO_MEMORY);
619 }
620
621 previous_walk_state->
622 implicit_return_obj->
623 integer.value = 0;
624 }
625
626 /* Restart the calling control method */
627
628 status =
629 acpi_ds_restart_control_method
630 (walk_state,
631 previous_walk_state->
632 implicit_return_obj);
633 } else {
634 /*
635 * We have a valid return value, delete any implicit
636 * return value.
637 */
638 acpi_ds_clear_implicit_return
639 (previous_walk_state);
640
641 status =
642 acpi_ds_restart_control_method
643 (walk_state,
644 previous_walk_state->return_desc);
645 }
646 if (ACPI_SUCCESS(status)) {
647 walk_state->walk_type |=
648 ACPI_WALK_METHOD_RESTART;
649 }
650 } else {
651 /* On error, delete any return object or implicit return */
652
653 acpi_ut_remove_reference(previous_walk_state->
654 return_desc);
655 acpi_ds_clear_implicit_return
656 (previous_walk_state);
657 }
658 }
659
660 /*
661 * Just completed a 1st-level method, save the final internal return
662 * value (if any)
663 */
664 else if (previous_walk_state->caller_return_desc) {
665 if (previous_walk_state->implicit_return_obj) {
666 *(previous_walk_state->caller_return_desc) =
667 previous_walk_state->implicit_return_obj;
668 } else {
669 /* NULL if no return value */
670
671 *(previous_walk_state->caller_return_desc) =
672 previous_walk_state->return_desc;
673 }
674 } else {
675 if (previous_walk_state->return_desc) {
676
677 /* Caller doesn't want it, must delete it */
678
679 acpi_ut_remove_reference(previous_walk_state->
680 return_desc);
681 }
682 if (previous_walk_state->implicit_return_obj) {
683
684 /* Caller doesn't want it, must delete it */
685
686 acpi_ut_remove_reference(previous_walk_state->
687 implicit_return_obj);
688 }
689 }
690
691 acpi_ds_delete_walk_state(previous_walk_state);
692 }
693
694 /* Normal exit */
695
696 acpi_ex_release_all_mutexes(thread);
697 acpi_ut_delete_generic_state(ACPI_CAST_PTR
698 (union acpi_generic_state, thread));
699 acpi_gbl_current_walk_list = prev_walk_list;
700 return_ACPI_STATUS(status);
701}
diff --git a/drivers/acpi/acpica/psscope.c b/drivers/acpi/acpica/psscope.c
new file mode 100644
index 00000000000..22929ca1ffe
--- /dev/null
+++ b/drivers/acpi/acpica/psscope.c
@@ -0,0 +1,265 @@
1/******************************************************************************
2 *
3 * Module Name: psscope - Parser scope stack management routines
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46#include <acpi/acparser.h>
47
48#define _COMPONENT ACPI_PARSER
49ACPI_MODULE_NAME("psscope")
50
51/*******************************************************************************
52 *
53 * FUNCTION: acpi_ps_get_parent_scope
54 *
55 * PARAMETERS: parser_state - Current parser state object
56 *
57 * RETURN: Pointer to an Op object
58 *
59 * DESCRIPTION: Get parent of current op being parsed
60 *
61 ******************************************************************************/
62union acpi_parse_object *acpi_ps_get_parent_scope(struct acpi_parse_state
63 *parser_state)
64{
65
66 return (parser_state->scope->parse_scope.op);
67}
68
69/*******************************************************************************
70 *
71 * FUNCTION: acpi_ps_has_completed_scope
72 *
73 * PARAMETERS: parser_state - Current parser state object
74 *
75 * RETURN: Boolean, TRUE = scope completed.
76 *
77 * DESCRIPTION: Is parsing of current argument complete? Determined by
78 * 1) AML pointer is at or beyond the end of the scope
79 * 2) The scope argument count has reached zero.
80 *
81 ******************************************************************************/
82
83u8 acpi_ps_has_completed_scope(struct acpi_parse_state * parser_state)
84{
85
86 return ((u8)
87 ((parser_state->aml >= parser_state->scope->parse_scope.arg_end
88 || !parser_state->scope->parse_scope.arg_count)));
89}
90
91/*******************************************************************************
92 *
93 * FUNCTION: acpi_ps_init_scope
94 *
95 * PARAMETERS: parser_state - Current parser state object
96 * Root - the Root Node of this new scope
97 *
98 * RETURN: Status
99 *
100 * DESCRIPTION: Allocate and init a new scope object
101 *
102 ******************************************************************************/
103
104acpi_status
105acpi_ps_init_scope(struct acpi_parse_state * parser_state,
106 union acpi_parse_object * root_op)
107{
108 union acpi_generic_state *scope;
109
110 ACPI_FUNCTION_TRACE_PTR(ps_init_scope, root_op);
111
112 scope = acpi_ut_create_generic_state();
113 if (!scope) {
114 return_ACPI_STATUS(AE_NO_MEMORY);
115 }
116
117 scope->common.descriptor_type = ACPI_DESC_TYPE_STATE_RPSCOPE;
118 scope->parse_scope.op = root_op;
119 scope->parse_scope.arg_count = ACPI_VAR_ARGS;
120 scope->parse_scope.arg_end = parser_state->aml_end;
121 scope->parse_scope.pkg_end = parser_state->aml_end;
122
123 parser_state->scope = scope;
124 parser_state->start_op = root_op;
125
126 return_ACPI_STATUS(AE_OK);
127}
128
129/*******************************************************************************
130 *
131 * FUNCTION: acpi_ps_push_scope
132 *
133 * PARAMETERS: parser_state - Current parser state object
134 * Op - Current op to be pushed
135 * remaining_args - List of args remaining
136 * arg_count - Fixed or variable number of args
137 *
138 * RETURN: Status
139 *
140 * DESCRIPTION: Push current op to begin parsing its argument
141 *
142 ******************************************************************************/
143
144acpi_status
145acpi_ps_push_scope(struct acpi_parse_state *parser_state,
146 union acpi_parse_object *op,
147 u32 remaining_args, u32 arg_count)
148{
149 union acpi_generic_state *scope;
150
151 ACPI_FUNCTION_TRACE_PTR(ps_push_scope, op);
152
153 scope = acpi_ut_create_generic_state();
154 if (!scope) {
155 return_ACPI_STATUS(AE_NO_MEMORY);
156 }
157
158 scope->common.descriptor_type = ACPI_DESC_TYPE_STATE_PSCOPE;
159 scope->parse_scope.op = op;
160 scope->parse_scope.arg_list = remaining_args;
161 scope->parse_scope.arg_count = arg_count;
162 scope->parse_scope.pkg_end = parser_state->pkg_end;
163
164 /* Push onto scope stack */
165
166 acpi_ut_push_generic_state(&parser_state->scope, scope);
167
168 if (arg_count == ACPI_VAR_ARGS) {
169
170 /* Multiple arguments */
171
172 scope->parse_scope.arg_end = parser_state->pkg_end;
173 } else {
174 /* Single argument */
175
176 scope->parse_scope.arg_end = ACPI_TO_POINTER(ACPI_MAX_PTR);
177 }
178
179 return_ACPI_STATUS(AE_OK);
180}
181
182/*******************************************************************************
183 *
184 * FUNCTION: acpi_ps_pop_scope
185 *
186 * PARAMETERS: parser_state - Current parser state object
187 * Op - Where the popped op is returned
188 * arg_list - Where the popped "next argument" is
189 * returned
190 * arg_count - Count of objects in arg_list
191 *
192 * RETURN: Status
193 *
194 * DESCRIPTION: Return to parsing a previous op
195 *
196 ******************************************************************************/
197
198void
199acpi_ps_pop_scope(struct acpi_parse_state *parser_state,
200 union acpi_parse_object **op, u32 * arg_list, u32 * arg_count)
201{
202 union acpi_generic_state *scope = parser_state->scope;
203
204 ACPI_FUNCTION_TRACE(ps_pop_scope);
205
206 /* Only pop the scope if there is in fact a next scope */
207
208 if (scope->common.next) {
209 scope = acpi_ut_pop_generic_state(&parser_state->scope);
210
211 /* Return to parsing previous op */
212
213 *op = scope->parse_scope.op;
214 *arg_list = scope->parse_scope.arg_list;
215 *arg_count = scope->parse_scope.arg_count;
216 parser_state->pkg_end = scope->parse_scope.pkg_end;
217
218 /* All done with this scope state structure */
219
220 acpi_ut_delete_generic_state(scope);
221 } else {
222 /* Empty parse stack, prepare to fetch next opcode */
223
224 *op = NULL;
225 *arg_list = 0;
226 *arg_count = 0;
227 }
228
229 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
230 "Popped Op %p Args %X\n", *op, *arg_count));
231 return_VOID;
232}
233
234/*******************************************************************************
235 *
236 * FUNCTION: acpi_ps_cleanup_scope
237 *
238 * PARAMETERS: parser_state - Current parser state object
239 *
240 * RETURN: None
241 *
242 * DESCRIPTION: Destroy available list, remaining stack levels, and return
243 * root scope
244 *
245 ******************************************************************************/
246
247void acpi_ps_cleanup_scope(struct acpi_parse_state *parser_state)
248{
249 union acpi_generic_state *scope;
250
251 ACPI_FUNCTION_TRACE_PTR(ps_cleanup_scope, parser_state);
252
253 if (!parser_state) {
254 return_VOID;
255 }
256
257 /* Delete anything on the scope stack */
258
259 while (parser_state->scope) {
260 scope = acpi_ut_pop_generic_state(&parser_state->scope);
261 acpi_ut_delete_generic_state(scope);
262 }
263
264 return_VOID;
265}
diff --git a/drivers/acpi/acpica/pstree.c b/drivers/acpi/acpica/pstree.c
new file mode 100644
index 00000000000..8e73fbf0097
--- /dev/null
+++ b/drivers/acpi/acpica/pstree.c
@@ -0,0 +1,312 @@
1/******************************************************************************
2 *
3 * Module Name: pstree - Parser op tree manipulation/traversal/search
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46#include <acpi/acparser.h>
47#include <acpi/amlcode.h>
48
49#define _COMPONENT ACPI_PARSER
50ACPI_MODULE_NAME("pstree")
51
52/* Local prototypes */
53#ifdef ACPI_OBSOLETE_FUNCTIONS
54union acpi_parse_object *acpi_ps_get_child(union acpi_parse_object *op);
55#endif
56
57/*******************************************************************************
58 *
59 * FUNCTION: acpi_ps_get_arg
60 *
61 * PARAMETERS: Op - Get an argument for this op
62 * Argn - Nth argument to get
63 *
64 * RETURN: The argument (as an Op object). NULL if argument does not exist
65 *
66 * DESCRIPTION: Get the specified op's argument.
67 *
68 ******************************************************************************/
69
70union acpi_parse_object *acpi_ps_get_arg(union acpi_parse_object *op, u32 argn)
71{
72 union acpi_parse_object *arg = NULL;
73 const struct acpi_opcode_info *op_info;
74
75 ACPI_FUNCTION_ENTRY();
76
77 /* Get the info structure for this opcode */
78
79 op_info = acpi_ps_get_opcode_info(op->common.aml_opcode);
80 if (op_info->class == AML_CLASS_UNKNOWN) {
81
82 /* Invalid opcode or ASCII character */
83
84 return (NULL);
85 }
86
87 /* Check if this opcode requires argument sub-objects */
88
89 if (!(op_info->flags & AML_HAS_ARGS)) {
90
91 /* Has no linked argument objects */
92
93 return (NULL);
94 }
95
96 /* Get the requested argument object */
97
98 arg = op->common.value.arg;
99 while (arg && argn) {
100 argn--;
101 arg = arg->common.next;
102 }
103
104 return (arg);
105}
106
107/*******************************************************************************
108 *
109 * FUNCTION: acpi_ps_append_arg
110 *
111 * PARAMETERS: Op - Append an argument to this Op.
112 * Arg - Argument Op to append
113 *
114 * RETURN: None.
115 *
116 * DESCRIPTION: Append an argument to an op's argument list (a NULL arg is OK)
117 *
118 ******************************************************************************/
119
120void
121acpi_ps_append_arg(union acpi_parse_object *op, union acpi_parse_object *arg)
122{
123 union acpi_parse_object *prev_arg;
124 const struct acpi_opcode_info *op_info;
125
126 ACPI_FUNCTION_ENTRY();
127
128 if (!op) {
129 return;
130 }
131
132 /* Get the info structure for this opcode */
133
134 op_info = acpi_ps_get_opcode_info(op->common.aml_opcode);
135 if (op_info->class == AML_CLASS_UNKNOWN) {
136
137 /* Invalid opcode */
138
139 ACPI_ERROR((AE_INFO, "Invalid AML Opcode: 0x%2.2X",
140 op->common.aml_opcode));
141 return;
142 }
143
144 /* Check if this opcode requires argument sub-objects */
145
146 if (!(op_info->flags & AML_HAS_ARGS)) {
147
148 /* Has no linked argument objects */
149
150 return;
151 }
152
153 /* Append the argument to the linked argument list */
154
155 if (op->common.value.arg) {
156
157 /* Append to existing argument list */
158
159 prev_arg = op->common.value.arg;
160 while (prev_arg->common.next) {
161 prev_arg = prev_arg->common.next;
162 }
163 prev_arg->common.next = arg;
164 } else {
165 /* No argument list, this will be the first argument */
166
167 op->common.value.arg = arg;
168 }
169
170 /* Set the parent in this arg and any args linked after it */
171
172 while (arg) {
173 arg->common.parent = op;
174 arg = arg->common.next;
175
176 op->common.arg_list_length++;
177 }
178}
179
180#ifdef ACPI_FUTURE_USAGE
181/*******************************************************************************
182 *
183 * FUNCTION: acpi_ps_get_depth_next
184 *
185 * PARAMETERS: Origin - Root of subtree to search
186 * Op - Last (previous) Op that was found
187 *
188 * RETURN: Next Op found in the search.
189 *
190 * DESCRIPTION: Get next op in tree (walking the tree in depth-first order)
191 * Return NULL when reaching "origin" or when walking up from root
192 *
193 ******************************************************************************/
194
195union acpi_parse_object *acpi_ps_get_depth_next(union acpi_parse_object *origin,
196 union acpi_parse_object *op)
197{
198 union acpi_parse_object *next = NULL;
199 union acpi_parse_object *parent;
200 union acpi_parse_object *arg;
201
202 ACPI_FUNCTION_ENTRY();
203
204 if (!op) {
205 return (NULL);
206 }
207
208 /* Look for an argument or child */
209
210 next = acpi_ps_get_arg(op, 0);
211 if (next) {
212 return (next);
213 }
214
215 /* Look for a sibling */
216
217 next = op->common.next;
218 if (next) {
219 return (next);
220 }
221
222 /* Look for a sibling of parent */
223
224 parent = op->common.parent;
225
226 while (parent) {
227 arg = acpi_ps_get_arg(parent, 0);
228 while (arg && (arg != origin) && (arg != op)) {
229 arg = arg->common.next;
230 }
231
232 if (arg == origin) {
233
234 /* Reached parent of origin, end search */
235
236 return (NULL);
237 }
238
239 if (parent->common.next) {
240
241 /* Found sibling of parent */
242
243 return (parent->common.next);
244 }
245
246 op = parent;
247 parent = parent->common.parent;
248 }
249
250 return (next);
251}
252
253#ifdef ACPI_OBSOLETE_FUNCTIONS
254/*******************************************************************************
255 *
256 * FUNCTION: acpi_ps_get_child
257 *
258 * PARAMETERS: Op - Get the child of this Op
259 *
260 * RETURN: Child Op, Null if none is found.
261 *
262 * DESCRIPTION: Get op's children or NULL if none
263 *
264 ******************************************************************************/
265
266union acpi_parse_object *acpi_ps_get_child(union acpi_parse_object *op)
267{
268 union acpi_parse_object *child = NULL;
269
270 ACPI_FUNCTION_ENTRY();
271
272 switch (op->common.aml_opcode) {
273 case AML_SCOPE_OP:
274 case AML_ELSE_OP:
275 case AML_DEVICE_OP:
276 case AML_THERMAL_ZONE_OP:
277 case AML_INT_METHODCALL_OP:
278
279 child = acpi_ps_get_arg(op, 0);
280 break;
281
282 case AML_BUFFER_OP:
283 case AML_PACKAGE_OP:
284 case AML_METHOD_OP:
285 case AML_IF_OP:
286 case AML_WHILE_OP:
287 case AML_FIELD_OP:
288
289 child = acpi_ps_get_arg(op, 1);
290 break;
291
292 case AML_POWER_RES_OP:
293 case AML_INDEX_FIELD_OP:
294
295 child = acpi_ps_get_arg(op, 2);
296 break;
297
298 case AML_PROCESSOR_OP:
299 case AML_BANK_FIELD_OP:
300
301 child = acpi_ps_get_arg(op, 3);
302 break;
303
304 default:
305 /* All others have no children */
306 break;
307 }
308
309 return (child);
310}
311#endif
312#endif /* ACPI_FUTURE_USAGE */
diff --git a/drivers/acpi/acpica/psutils.c b/drivers/acpi/acpica/psutils.c
new file mode 100644
index 00000000000..eec7d624db8
--- /dev/null
+++ b/drivers/acpi/acpica/psutils.c
@@ -0,0 +1,244 @@
1/******************************************************************************
2 *
3 * Module Name: psutils - Parser miscellaneous utilities (Parser only)
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46#include <acpi/acparser.h>
47#include <acpi/amlcode.h>
48
49#define _COMPONENT ACPI_PARSER
50ACPI_MODULE_NAME("psutils")
51
52/*******************************************************************************
53 *
54 * FUNCTION: acpi_ps_create_scope_op
55 *
56 * PARAMETERS: None
57 *
58 * RETURN: A new Scope object, null on failure
59 *
60 * DESCRIPTION: Create a Scope and associated namepath op with the root name
61 *
62 ******************************************************************************/
63union acpi_parse_object *acpi_ps_create_scope_op(void)
64{
65 union acpi_parse_object *scope_op;
66
67 scope_op = acpi_ps_alloc_op(AML_SCOPE_OP);
68 if (!scope_op) {
69 return (NULL);
70 }
71
72 scope_op->named.name = ACPI_ROOT_NAME;
73 return (scope_op);
74}
75
76/*******************************************************************************
77 *
78 * FUNCTION: acpi_ps_init_op
79 *
80 * PARAMETERS: Op - A newly allocated Op object
81 * Opcode - Opcode to store in the Op
82 *
83 * RETURN: None
84 *
85 * DESCRIPTION: Initialize a parse (Op) object
86 *
87 ******************************************************************************/
88
89void acpi_ps_init_op(union acpi_parse_object *op, u16 opcode)
90{
91 ACPI_FUNCTION_ENTRY();
92
93 op->common.descriptor_type = ACPI_DESC_TYPE_PARSER;
94 op->common.aml_opcode = opcode;
95
96 ACPI_DISASM_ONLY_MEMBERS(ACPI_STRNCPY(op->common.aml_op_name,
97 (acpi_ps_get_opcode_info
98 (opcode))->name,
99 sizeof(op->common.aml_op_name)));
100}
101
102/*******************************************************************************
103 *
104 * FUNCTION: acpi_ps_alloc_op
105 *
106 * PARAMETERS: Opcode - Opcode that will be stored in the new Op
107 *
108 * RETURN: Pointer to the new Op, null on failure
109 *
110 * DESCRIPTION: Allocate an acpi_op, choose op type (and thus size) based on
111 * opcode. A cache of opcodes is available for the pure
112 * GENERIC_OP, since this is by far the most commonly used.
113 *
114 ******************************************************************************/
115
116union acpi_parse_object *acpi_ps_alloc_op(u16 opcode)
117{
118 union acpi_parse_object *op;
119 const struct acpi_opcode_info *op_info;
120 u8 flags = ACPI_PARSEOP_GENERIC;
121
122 ACPI_FUNCTION_ENTRY();
123
124 op_info = acpi_ps_get_opcode_info(opcode);
125
126 /* Determine type of parse_op required */
127
128 if (op_info->flags & AML_DEFER) {
129 flags = ACPI_PARSEOP_DEFERRED;
130 } else if (op_info->flags & AML_NAMED) {
131 flags = ACPI_PARSEOP_NAMED;
132 } else if (opcode == AML_INT_BYTELIST_OP) {
133 flags = ACPI_PARSEOP_BYTELIST;
134 }
135
136 /* Allocate the minimum required size object */
137
138 if (flags == ACPI_PARSEOP_GENERIC) {
139
140 /* The generic op (default) is by far the most common (16 to 1) */
141
142 op = acpi_os_acquire_object(acpi_gbl_ps_node_cache);
143 } else {
144 /* Extended parseop */
145
146 op = acpi_os_acquire_object(acpi_gbl_ps_node_ext_cache);
147 }
148
149 /* Initialize the Op */
150
151 if (op) {
152 acpi_ps_init_op(op, opcode);
153 op->common.flags = flags;
154 }
155
156 return (op);
157}
158
159/*******************************************************************************
160 *
161 * FUNCTION: acpi_ps_free_op
162 *
163 * PARAMETERS: Op - Op to be freed
164 *
165 * RETURN: None.
166 *
167 * DESCRIPTION: Free an Op object. Either put it on the GENERIC_OP cache list
168 * or actually free it.
169 *
170 ******************************************************************************/
171
172void acpi_ps_free_op(union acpi_parse_object *op)
173{
174 ACPI_FUNCTION_NAME(ps_free_op);
175
176 if (op->common.aml_opcode == AML_INT_RETURN_VALUE_OP) {
177 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, "Free retval op: %p\n",
178 op));
179 }
180
181 if (op->common.flags & ACPI_PARSEOP_GENERIC) {
182 (void)acpi_os_release_object(acpi_gbl_ps_node_cache, op);
183 } else {
184 (void)acpi_os_release_object(acpi_gbl_ps_node_ext_cache, op);
185 }
186}
187
188/*******************************************************************************
189 *
190 * FUNCTION: Utility functions
191 *
192 * DESCRIPTION: Low level character and object functions
193 *
194 ******************************************************************************/
195
196/*
197 * Is "c" a namestring lead character?
198 */
199u8 acpi_ps_is_leading_char(u32 c)
200{
201 return ((u8) (c == '_' || (c >= 'A' && c <= 'Z')));
202}
203
204/*
205 * Is "c" a namestring prefix character?
206 */
207u8 acpi_ps_is_prefix_char(u32 c)
208{
209 return ((u8) (c == '\\' || c == '^'));
210}
211
212/*
213 * Get op's name (4-byte name segment) or 0 if unnamed
214 */
215#ifdef ACPI_FUTURE_USAGE
216u32 acpi_ps_get_name(union acpi_parse_object * op)
217{
218
219 /* The "generic" object has no name associated with it */
220
221 if (op->common.flags & ACPI_PARSEOP_GENERIC) {
222 return (0);
223 }
224
225 /* Only the "Extended" parse objects have a name */
226
227 return (op->named.name);
228}
229#endif /* ACPI_FUTURE_USAGE */
230
231/*
232 * Set op's name
233 */
234void acpi_ps_set_name(union acpi_parse_object *op, u32 name)
235{
236
237 /* The "generic" object has no name associated with it */
238
239 if (op->common.flags & ACPI_PARSEOP_GENERIC) {
240 return;
241 }
242
243 op->named.name = name;
244}
diff --git a/drivers/acpi/acpica/pswalk.c b/drivers/acpi/acpica/pswalk.c
new file mode 100644
index 00000000000..dacc4228ba1
--- /dev/null
+++ b/drivers/acpi/acpica/pswalk.c
@@ -0,0 +1,110 @@
1/******************************************************************************
2 *
3 * Module Name: pswalk - Parser routines to walk parsed op tree(s)
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46#include <acpi/acparser.h>
47
48#define _COMPONENT ACPI_PARSER
49ACPI_MODULE_NAME("pswalk")
50
51/*******************************************************************************
52 *
53 * FUNCTION: acpi_ps_delete_parse_tree
54 *
55 * PARAMETERS: subtree_root - Root of tree (or subtree) to delete
56 *
57 * RETURN: None
58 *
59 * DESCRIPTION: Delete a portion of or an entire parse tree.
60 *
61 ******************************************************************************/
62void acpi_ps_delete_parse_tree(union acpi_parse_object *subtree_root)
63{
64 union acpi_parse_object *op = subtree_root;
65 union acpi_parse_object *next = NULL;
66 union acpi_parse_object *parent = NULL;
67
68 ACPI_FUNCTION_TRACE_PTR(ps_delete_parse_tree, subtree_root);
69
70 /* Visit all nodes in the subtree */
71
72 while (op) {
73
74 /* Check if we are not ascending */
75
76 if (op != parent) {
77
78 /* Look for an argument or child of the current op */
79
80 next = acpi_ps_get_arg(op, 0);
81 if (next) {
82
83 /* Still going downward in tree (Op is not completed yet) */
84
85 op = next;
86 continue;
87 }
88 }
89
90 /* No more children, this Op is complete. */
91
92 next = op->common.next;
93 parent = op->common.parent;
94
95 acpi_ps_free_op(op);
96
97 /* If we are back to the starting point, the walk is complete. */
98
99 if (op == subtree_root) {
100 return_VOID;
101 }
102 if (next) {
103 op = next;
104 } else {
105 op = parent;
106 }
107 }
108
109 return_VOID;
110}
diff --git a/drivers/acpi/acpica/psxface.c b/drivers/acpi/acpica/psxface.c
new file mode 100644
index 00000000000..98c31a89370
--- /dev/null
+++ b/drivers/acpi/acpica/psxface.c
@@ -0,0 +1,385 @@
1/******************************************************************************
2 *
3 * Module Name: psxface - Parser external interfaces
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46#include <acpi/acparser.h>
47#include <acpi/acdispat.h>
48#include <acpi/acinterp.h>
49#include <acpi/amlcode.h>
50
51#define _COMPONENT ACPI_PARSER
52ACPI_MODULE_NAME("psxface")
53
54/* Local Prototypes */
55static void acpi_ps_start_trace(struct acpi_evaluate_info *info);
56
57static void acpi_ps_stop_trace(struct acpi_evaluate_info *info);
58
59static void
60acpi_ps_update_parameter_list(struct acpi_evaluate_info *info, u16 action);
61
62/*******************************************************************************
63 *
64 * FUNCTION: acpi_debug_trace
65 *
66 * PARAMETERS: method_name - Valid ACPI name string
67 * debug_level - Optional level mask. 0 to use default
68 * debug_layer - Optional layer mask. 0 to use default
69 * Flags - bit 1: one shot(1) or persistent(0)
70 *
71 * RETURN: Status
72 *
73 * DESCRIPTION: External interface to enable debug tracing during control
74 * method execution
75 *
76 ******************************************************************************/
77
78acpi_status
79acpi_debug_trace(char *name, u32 debug_level, u32 debug_layer, u32 flags)
80{
81 acpi_status status;
82
83 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
84 if (ACPI_FAILURE(status)) {
85 return (status);
86 }
87
88 /* TBDs: Validate name, allow full path or just nameseg */
89
90 acpi_gbl_trace_method_name = *ACPI_CAST_PTR(u32, name);
91 acpi_gbl_trace_flags = flags;
92
93 if (debug_level) {
94 acpi_gbl_trace_dbg_level = debug_level;
95 }
96 if (debug_layer) {
97 acpi_gbl_trace_dbg_layer = debug_layer;
98 }
99
100 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
101 return (AE_OK);
102}
103
104/*******************************************************************************
105 *
106 * FUNCTION: acpi_ps_start_trace
107 *
108 * PARAMETERS: Info - Method info struct
109 *
110 * RETURN: None
111 *
112 * DESCRIPTION: Start control method execution trace
113 *
114 ******************************************************************************/
115
116static void acpi_ps_start_trace(struct acpi_evaluate_info *info)
117{
118 acpi_status status;
119
120 ACPI_FUNCTION_ENTRY();
121
122 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
123 if (ACPI_FAILURE(status)) {
124 return;
125 }
126
127 if ((!acpi_gbl_trace_method_name) ||
128 (acpi_gbl_trace_method_name != info->resolved_node->name.integer)) {
129 goto exit;
130 }
131
132 acpi_gbl_original_dbg_level = acpi_dbg_level;
133 acpi_gbl_original_dbg_layer = acpi_dbg_layer;
134
135 acpi_dbg_level = 0x00FFFFFF;
136 acpi_dbg_layer = ACPI_UINT32_MAX;
137
138 if (acpi_gbl_trace_dbg_level) {
139 acpi_dbg_level = acpi_gbl_trace_dbg_level;
140 }
141 if (acpi_gbl_trace_dbg_layer) {
142 acpi_dbg_layer = acpi_gbl_trace_dbg_layer;
143 }
144
145 exit:
146 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
147}
148
149/*******************************************************************************
150 *
151 * FUNCTION: acpi_ps_stop_trace
152 *
153 * PARAMETERS: Info - Method info struct
154 *
155 * RETURN: None
156 *
157 * DESCRIPTION: Stop control method execution trace
158 *
159 ******************************************************************************/
160
161static void acpi_ps_stop_trace(struct acpi_evaluate_info *info)
162{
163 acpi_status status;
164
165 ACPI_FUNCTION_ENTRY();
166
167 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
168 if (ACPI_FAILURE(status)) {
169 return;
170 }
171
172 if ((!acpi_gbl_trace_method_name) ||
173 (acpi_gbl_trace_method_name != info->resolved_node->name.integer)) {
174 goto exit;
175 }
176
177 /* Disable further tracing if type is one-shot */
178
179 if (acpi_gbl_trace_flags & 1) {
180 acpi_gbl_trace_method_name = 0;
181 acpi_gbl_trace_dbg_level = 0;
182 acpi_gbl_trace_dbg_layer = 0;
183 }
184
185 acpi_dbg_level = acpi_gbl_original_dbg_level;
186 acpi_dbg_layer = acpi_gbl_original_dbg_layer;
187
188 exit:
189 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
190}
191
192/*******************************************************************************
193 *
194 * FUNCTION: acpi_ps_execute_method
195 *
196 * PARAMETERS: Info - Method info block, contains:
197 * Node - Method Node to execute
198 * obj_desc - Method object
199 * Parameters - List of parameters to pass to the method,
200 * terminated by NULL. Params itself may be
201 * NULL if no parameters are being passed.
202 * return_object - Where to put method's return value (if
203 * any). If NULL, no value is returned.
204 * parameter_type - Type of Parameter list
205 * return_object - Where to put method's return value (if
206 * any). If NULL, no value is returned.
207 * pass_number - Parse or execute pass
208 *
209 * RETURN: Status
210 *
211 * DESCRIPTION: Execute a control method
212 *
213 ******************************************************************************/
214
215acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info)
216{
217 acpi_status status;
218 union acpi_parse_object *op;
219 struct acpi_walk_state *walk_state;
220
221 ACPI_FUNCTION_TRACE(ps_execute_method);
222
223 /* Validate the Info and method Node */
224
225 if (!info || !info->resolved_node) {
226 return_ACPI_STATUS(AE_NULL_ENTRY);
227 }
228
229 /* Init for new method, wait on concurrency semaphore */
230
231 status =
232 acpi_ds_begin_method_execution(info->resolved_node, info->obj_desc,
233 NULL);
234 if (ACPI_FAILURE(status)) {
235 return_ACPI_STATUS(status);
236 }
237
238 /*
239 * The caller "owns" the parameters, so give each one an extra reference
240 */
241 acpi_ps_update_parameter_list(info, REF_INCREMENT);
242
243 /* Begin tracing if requested */
244
245 acpi_ps_start_trace(info);
246
247 /*
248 * Execute the method. Performs parse simultaneously
249 */
250 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
251 "**** Begin Method Parse/Execute [%4.4s] **** Node=%p Obj=%p\n",
252 info->resolved_node->name.ascii, info->resolved_node,
253 info->obj_desc));
254
255 /* Create and init a Root Node */
256
257 op = acpi_ps_create_scope_op();
258 if (!op) {
259 status = AE_NO_MEMORY;
260 goto cleanup;
261 }
262
263 /* Create and initialize a new walk state */
264
265 info->pass_number = ACPI_IMODE_EXECUTE;
266 walk_state =
267 acpi_ds_create_walk_state(info->obj_desc->method.owner_id, NULL,
268 NULL, NULL);
269 if (!walk_state) {
270 status = AE_NO_MEMORY;
271 goto cleanup;
272 }
273
274 status = acpi_ds_init_aml_walk(walk_state, op, info->resolved_node,
275 info->obj_desc->method.aml_start,
276 info->obj_desc->method.aml_length, info,
277 info->pass_number);
278 if (ACPI_FAILURE(status)) {
279 acpi_ds_delete_walk_state(walk_state);
280 goto cleanup;
281 }
282
283 /* Invoke an internal method if necessary */
284
285 if (info->obj_desc->method.method_flags & AML_METHOD_INTERNAL_ONLY) {
286 status = info->obj_desc->method.implementation(walk_state);
287 info->return_object = walk_state->return_desc;
288
289 /* Cleanup states */
290
291 acpi_ds_scope_stack_clear(walk_state);
292 acpi_ps_cleanup_scope(&walk_state->parser_state);
293 acpi_ds_terminate_control_method(walk_state->method_desc,
294 walk_state);
295 acpi_ds_delete_walk_state(walk_state);
296 goto cleanup;
297 }
298
299 /*
300 * Start method evaluation with an implicit return of zero.
301 * This is done for Windows compatibility.
302 */
303 if (acpi_gbl_enable_interpreter_slack) {
304 walk_state->implicit_return_obj =
305 acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
306 if (!walk_state->implicit_return_obj) {
307 status = AE_NO_MEMORY;
308 acpi_ds_delete_walk_state(walk_state);
309 goto cleanup;
310 }
311
312 walk_state->implicit_return_obj->integer.value = 0;
313 }
314
315 /* Parse the AML */
316
317 status = acpi_ps_parse_aml(walk_state);
318
319 /* walk_state was deleted by parse_aml */
320
321 cleanup:
322 acpi_ps_delete_parse_tree(op);
323
324 /* End optional tracing */
325
326 acpi_ps_stop_trace(info);
327
328 /* Take away the extra reference that we gave the parameters above */
329
330 acpi_ps_update_parameter_list(info, REF_DECREMENT);
331
332 /* Exit now if error above */
333
334 if (ACPI_FAILURE(status)) {
335 return_ACPI_STATUS(status);
336 }
337
338 /*
339 * If the method has returned an object, signal this to the caller with
340 * a control exception code
341 */
342 if (info->return_object) {
343 ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "Method returned ObjDesc=%p\n",
344 info->return_object));
345 ACPI_DUMP_STACK_ENTRY(info->return_object);
346
347 status = AE_CTRL_RETURN_VALUE;
348 }
349
350 return_ACPI_STATUS(status);
351}
352
353/*******************************************************************************
354 *
355 * FUNCTION: acpi_ps_update_parameter_list
356 *
357 * PARAMETERS: Info - See struct acpi_evaluate_info
358 * (Used: parameter_type and Parameters)
359 * Action - Add or Remove reference
360 *
361 * RETURN: Status
362 *
363 * DESCRIPTION: Update reference count on all method parameter objects
364 *
365 ******************************************************************************/
366
367static void
368acpi_ps_update_parameter_list(struct acpi_evaluate_info *info, u16 action)
369{
370 u32 i;
371
372 if (info->parameters) {
373
374 /* Update reference count for each parameter */
375
376 for (i = 0; info->parameters[i]; i++) {
377
378 /* Ignore errors, just do them all */
379
380 (void)acpi_ut_update_object_reference(info->
381 parameters[i],
382 action);
383 }
384 }
385}
diff --git a/drivers/acpi/acpica/rsaddr.c b/drivers/acpi/acpica/rsaddr.c
new file mode 100644
index 00000000000..b4aba3aebcb
--- /dev/null
+++ b/drivers/acpi/acpica/rsaddr.c
@@ -0,0 +1,381 @@
1/*******************************************************************************
2 *
3 * Module Name: rsaddr - Address resource descriptors (16/32/64)
4 *
5 ******************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46#include <acpi/acresrc.h>
47
48#define _COMPONENT ACPI_RESOURCES
49ACPI_MODULE_NAME("rsaddr")
50
51/*******************************************************************************
52 *
53 * acpi_rs_convert_address16 - All WORD (16-bit) address resources
54 *
55 ******************************************************************************/
56struct acpi_rsconvert_info acpi_rs_convert_address16[5] = {
57 {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_ADDRESS16,
58 ACPI_RS_SIZE(struct acpi_resource_address16),
59 ACPI_RSC_TABLE_SIZE(acpi_rs_convert_address16)},
60
61 {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_ADDRESS16,
62 sizeof(struct aml_resource_address16),
63 0},
64
65 /* Resource Type, General Flags, and Type-Specific Flags */
66
67 {ACPI_RSC_ADDRESS, 0, 0, 0},
68
69 /*
70 * These fields are contiguous in both the source and destination:
71 * Address Granularity
72 * Address Range Minimum
73 * Address Range Maximum
74 * Address Translation Offset
75 * Address Length
76 */
77 {ACPI_RSC_MOVE16, ACPI_RS_OFFSET(data.address16.granularity),
78 AML_OFFSET(address16.granularity),
79 5},
80
81 /* Optional resource_source (Index and String) */
82
83 {ACPI_RSC_SOURCE, ACPI_RS_OFFSET(data.address16.resource_source),
84 0,
85 sizeof(struct aml_resource_address16)}
86};
87
88/*******************************************************************************
89 *
90 * acpi_rs_convert_address32 - All DWORD (32-bit) address resources
91 *
92 ******************************************************************************/
93
94struct acpi_rsconvert_info acpi_rs_convert_address32[5] = {
95 {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_ADDRESS32,
96 ACPI_RS_SIZE(struct acpi_resource_address32),
97 ACPI_RSC_TABLE_SIZE(acpi_rs_convert_address32)},
98
99 {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_ADDRESS32,
100 sizeof(struct aml_resource_address32),
101 0},
102
103 /* Resource Type, General Flags, and Type-Specific Flags */
104
105 {ACPI_RSC_ADDRESS, 0, 0, 0},
106
107 /*
108 * These fields are contiguous in both the source and destination:
109 * Address Granularity
110 * Address Range Minimum
111 * Address Range Maximum
112 * Address Translation Offset
113 * Address Length
114 */
115 {ACPI_RSC_MOVE32, ACPI_RS_OFFSET(data.address32.granularity),
116 AML_OFFSET(address32.granularity),
117 5},
118
119 /* Optional resource_source (Index and String) */
120
121 {ACPI_RSC_SOURCE, ACPI_RS_OFFSET(data.address32.resource_source),
122 0,
123 sizeof(struct aml_resource_address32)}
124};
125
126/*******************************************************************************
127 *
128 * acpi_rs_convert_address64 - All QWORD (64-bit) address resources
129 *
130 ******************************************************************************/
131
132struct acpi_rsconvert_info acpi_rs_convert_address64[5] = {
133 {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_ADDRESS64,
134 ACPI_RS_SIZE(struct acpi_resource_address64),
135 ACPI_RSC_TABLE_SIZE(acpi_rs_convert_address64)},
136
137 {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_ADDRESS64,
138 sizeof(struct aml_resource_address64),
139 0},
140
141 /* Resource Type, General Flags, and Type-Specific Flags */
142
143 {ACPI_RSC_ADDRESS, 0, 0, 0},
144
145 /*
146 * These fields are contiguous in both the source and destination:
147 * Address Granularity
148 * Address Range Minimum
149 * Address Range Maximum
150 * Address Translation Offset
151 * Address Length
152 */
153 {ACPI_RSC_MOVE64, ACPI_RS_OFFSET(data.address64.granularity),
154 AML_OFFSET(address64.granularity),
155 5},
156
157 /* Optional resource_source (Index and String) */
158
159 {ACPI_RSC_SOURCE, ACPI_RS_OFFSET(data.address64.resource_source),
160 0,
161 sizeof(struct aml_resource_address64)}
162};
163
164/*******************************************************************************
165 *
166 * acpi_rs_convert_ext_address64 - All Extended (64-bit) address resources
167 *
168 ******************************************************************************/
169
170struct acpi_rsconvert_info acpi_rs_convert_ext_address64[5] = {
171 {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64,
172 ACPI_RS_SIZE(struct acpi_resource_extended_address64),
173 ACPI_RSC_TABLE_SIZE(acpi_rs_convert_ext_address64)},
174
175 {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_EXTENDED_ADDRESS64,
176 sizeof(struct aml_resource_extended_address64),
177 0},
178
179 /* Resource Type, General Flags, and Type-Specific Flags */
180
181 {ACPI_RSC_ADDRESS, 0, 0, 0},
182
183 /* Revision ID */
184
185 {ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.ext_address64.revision_iD),
186 AML_OFFSET(ext_address64.revision_iD),
187 1},
188 /*
189 * These fields are contiguous in both the source and destination:
190 * Address Granularity
191 * Address Range Minimum
192 * Address Range Maximum
193 * Address Translation Offset
194 * Address Length
195 * Type-Specific Attribute
196 */
197 {ACPI_RSC_MOVE64, ACPI_RS_OFFSET(data.ext_address64.granularity),
198 AML_OFFSET(ext_address64.granularity),
199 6}
200};
201
202/*******************************************************************************
203 *
204 * acpi_rs_convert_general_flags - Flags common to all address descriptors
205 *
206 ******************************************************************************/
207
208static struct acpi_rsconvert_info acpi_rs_convert_general_flags[6] = {
209 {ACPI_RSC_FLAGINIT, 0, AML_OFFSET(address.flags),
210 ACPI_RSC_TABLE_SIZE(acpi_rs_convert_general_flags)},
211
212 /* Resource Type (Memory, Io, bus_number, etc.) */
213
214 {ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.address.resource_type),
215 AML_OFFSET(address.resource_type),
216 1},
217
218 /* General Flags - Consume, Decode, min_fixed, max_fixed */
219
220 {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.producer_consumer),
221 AML_OFFSET(address.flags),
222 0},
223
224 {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.decode),
225 AML_OFFSET(address.flags),
226 1},
227
228 {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.min_address_fixed),
229 AML_OFFSET(address.flags),
230 2},
231
232 {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.max_address_fixed),
233 AML_OFFSET(address.flags),
234 3}
235};
236
237/*******************************************************************************
238 *
239 * acpi_rs_convert_mem_flags - Flags common to Memory address descriptors
240 *
241 ******************************************************************************/
242
243static struct acpi_rsconvert_info acpi_rs_convert_mem_flags[5] = {
244 {ACPI_RSC_FLAGINIT, 0, AML_OFFSET(address.specific_flags),
245 ACPI_RSC_TABLE_SIZE(acpi_rs_convert_mem_flags)},
246
247 /* Memory-specific flags */
248
249 {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.info.mem.write_protect),
250 AML_OFFSET(address.specific_flags),
251 0},
252
253 {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET(data.address.info.mem.caching),
254 AML_OFFSET(address.specific_flags),
255 1},
256
257 {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET(data.address.info.mem.range_type),
258 AML_OFFSET(address.specific_flags),
259 3},
260
261 {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.info.mem.translation),
262 AML_OFFSET(address.specific_flags),
263 5}
264};
265
266/*******************************************************************************
267 *
268 * acpi_rs_convert_io_flags - Flags common to I/O address descriptors
269 *
270 ******************************************************************************/
271
272static struct acpi_rsconvert_info acpi_rs_convert_io_flags[4] = {
273 {ACPI_RSC_FLAGINIT, 0, AML_OFFSET(address.specific_flags),
274 ACPI_RSC_TABLE_SIZE(acpi_rs_convert_io_flags)},
275
276 /* I/O-specific flags */
277
278 {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET(data.address.info.io.range_type),
279 AML_OFFSET(address.specific_flags),
280 0},
281
282 {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.address.info.io.translation),
283 AML_OFFSET(address.specific_flags),
284 4},
285
286 {ACPI_RSC_1BITFLAG,
287 ACPI_RS_OFFSET(data.address.info.io.translation_type),
288 AML_OFFSET(address.specific_flags),
289 5}
290};
291
292/*******************************************************************************
293 *
294 * FUNCTION: acpi_rs_get_address_common
295 *
296 * PARAMETERS: Resource - Pointer to the internal resource struct
297 * Aml - Pointer to the AML resource descriptor
298 *
299 * RETURN: TRUE if the resource_type field is OK, FALSE otherwise
300 *
301 * DESCRIPTION: Convert common flag fields from a raw AML resource descriptor
302 * to an internal resource descriptor
303 *
304 ******************************************************************************/
305
306u8
307acpi_rs_get_address_common(struct acpi_resource *resource,
308 union aml_resource *aml)
309{
310 ACPI_FUNCTION_ENTRY();
311
312 /* Validate the Resource Type */
313
314 if ((aml->address.resource_type > 2)
315 && (aml->address.resource_type < 0xC0)) {
316 return (FALSE);
317 }
318
319 /* Get the Resource Type and General Flags */
320
321 (void)acpi_rs_convert_aml_to_resource(resource, aml,
322 acpi_rs_convert_general_flags);
323
324 /* Get the Type-Specific Flags (Memory and I/O descriptors only) */
325
326 if (resource->data.address.resource_type == ACPI_MEMORY_RANGE) {
327 (void)acpi_rs_convert_aml_to_resource(resource, aml,
328 acpi_rs_convert_mem_flags);
329 } else if (resource->data.address.resource_type == ACPI_IO_RANGE) {
330 (void)acpi_rs_convert_aml_to_resource(resource, aml,
331 acpi_rs_convert_io_flags);
332 } else {
333 /* Generic resource type, just grab the type_specific byte */
334
335 resource->data.address.info.type_specific =
336 aml->address.specific_flags;
337 }
338
339 return (TRUE);
340}
341
342/*******************************************************************************
343 *
344 * FUNCTION: acpi_rs_set_address_common
345 *
346 * PARAMETERS: Aml - Pointer to the AML resource descriptor
347 * Resource - Pointer to the internal resource struct
348 *
349 * RETURN: None
350 *
351 * DESCRIPTION: Convert common flag fields from a resource descriptor to an
352 * AML descriptor
353 *
354 ******************************************************************************/
355
356void
357acpi_rs_set_address_common(union aml_resource *aml,
358 struct acpi_resource *resource)
359{
360 ACPI_FUNCTION_ENTRY();
361
362 /* Set the Resource Type and General Flags */
363
364 (void)acpi_rs_convert_resource_to_aml(resource, aml,
365 acpi_rs_convert_general_flags);
366
367 /* Set the Type-Specific Flags (Memory and I/O descriptors only) */
368
369 if (resource->data.address.resource_type == ACPI_MEMORY_RANGE) {
370 (void)acpi_rs_convert_resource_to_aml(resource, aml,
371 acpi_rs_convert_mem_flags);
372 } else if (resource->data.address.resource_type == ACPI_IO_RANGE) {
373 (void)acpi_rs_convert_resource_to_aml(resource, aml,
374 acpi_rs_convert_io_flags);
375 } else {
376 /* Generic resource type, just copy the type_specific byte */
377
378 aml->address.specific_flags =
379 resource->data.address.info.type_specific;
380 }
381}
diff --git a/drivers/acpi/acpica/rscalc.c b/drivers/acpi/acpica/rscalc.c
new file mode 100644
index 00000000000..4f2b186fe30
--- /dev/null
+++ b/drivers/acpi/acpica/rscalc.c
@@ -0,0 +1,618 @@
1/*******************************************************************************
2 *
3 * Module Name: rscalc - Calculate stream and list lengths
4 *
5 ******************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46#include <acpi/acresrc.h>
47#include <acpi/acnamesp.h>
48
49#define _COMPONENT ACPI_RESOURCES
50ACPI_MODULE_NAME("rscalc")
51
52/* Local prototypes */
53static u8 acpi_rs_count_set_bits(u16 bit_field);
54
55static acpi_rs_length
56acpi_rs_struct_option_length(struct acpi_resource_source *resource_source);
57
58static u32
59acpi_rs_stream_option_length(u32 resource_length, u32 minimum_total_length);
60
61/*******************************************************************************
62 *
63 * FUNCTION: acpi_rs_count_set_bits
64 *
65 * PARAMETERS: bit_field - Field in which to count bits
66 *
67 * RETURN: Number of bits set within the field
68 *
69 * DESCRIPTION: Count the number of bits set in a resource field. Used for
70 * (Short descriptor) interrupt and DMA lists.
71 *
72 ******************************************************************************/
73
74static u8 acpi_rs_count_set_bits(u16 bit_field)
75{
76 u8 bits_set;
77
78 ACPI_FUNCTION_ENTRY();
79
80 for (bits_set = 0; bit_field; bits_set++) {
81
82 /* Zero the least significant bit that is set */
83
84 bit_field &= (u16) (bit_field - 1);
85 }
86
87 return bits_set;
88}
89
90/*******************************************************************************
91 *
92 * FUNCTION: acpi_rs_struct_option_length
93 *
94 * PARAMETERS: resource_source - Pointer to optional descriptor field
95 *
96 * RETURN: Status
97 *
98 * DESCRIPTION: Common code to handle optional resource_source_index and
99 * resource_source fields in some Large descriptors. Used during
100 * list-to-stream conversion
101 *
102 ******************************************************************************/
103
104static acpi_rs_length
105acpi_rs_struct_option_length(struct acpi_resource_source *resource_source)
106{
107 ACPI_FUNCTION_ENTRY();
108
109 /*
110 * If the resource_source string is valid, return the size of the string
111 * (string_length includes the NULL terminator) plus the size of the
112 * resource_source_index (1).
113 */
114 if (resource_source->string_ptr) {
115 return ((acpi_rs_length) (resource_source->string_length + 1));
116 }
117
118 return (0);
119}
120
121/*******************************************************************************
122 *
123 * FUNCTION: acpi_rs_stream_option_length
124 *
125 * PARAMETERS: resource_length - Length from the resource header
126 * minimum_total_length - Minimum length of this resource, before
127 * any optional fields. Includes header size
128 *
129 * RETURN: Length of optional string (0 if no string present)
130 *
131 * DESCRIPTION: Common code to handle optional resource_source_index and
132 * resource_source fields in some Large descriptors. Used during
133 * stream-to-list conversion
134 *
135 ******************************************************************************/
136
137static u32
138acpi_rs_stream_option_length(u32 resource_length,
139 u32 minimum_aml_resource_length)
140{
141 u32 string_length = 0;
142
143 ACPI_FUNCTION_ENTRY();
144
145 /*
146 * The resource_source_index and resource_source are optional elements of some
147 * Large-type resource descriptors.
148 */
149
150 /*
151 * If the length of the actual resource descriptor is greater than the ACPI
152 * spec-defined minimum length, it means that a resource_source_index exists
153 * and is followed by a (required) null terminated string. The string length
154 * (including the null terminator) is the resource length minus the minimum
155 * length, minus one byte for the resource_source_index itself.
156 */
157 if (resource_length > minimum_aml_resource_length) {
158
159 /* Compute the length of the optional string */
160
161 string_length =
162 resource_length - minimum_aml_resource_length - 1;
163 }
164
165 /*
166 * Round the length up to a multiple of the native word in order to
167 * guarantee that the entire resource descriptor is native word aligned
168 */
169 return ((u32) ACPI_ROUND_UP_TO_NATIVE_WORD(string_length));
170}
171
172/*******************************************************************************
173 *
174 * FUNCTION: acpi_rs_get_aml_length
175 *
176 * PARAMETERS: Resource - Pointer to the resource linked list
177 * size_needed - Where the required size is returned
178 *
179 * RETURN: Status
180 *
181 * DESCRIPTION: Takes a linked list of internal resource descriptors and
182 * calculates the size buffer needed to hold the corresponding
183 * external resource byte stream.
184 *
185 ******************************************************************************/
186
187acpi_status
188acpi_rs_get_aml_length(struct acpi_resource * resource, acpi_size * size_needed)
189{
190 acpi_size aml_size_needed = 0;
191 acpi_rs_length total_size;
192
193 ACPI_FUNCTION_TRACE(rs_get_aml_length);
194
195 /* Traverse entire list of internal resource descriptors */
196
197 while (resource) {
198
199 /* Validate the descriptor type */
200
201 if (resource->type > ACPI_RESOURCE_TYPE_MAX) {
202 return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE);
203 }
204
205 /* Get the base size of the (external stream) resource descriptor */
206
207 total_size = acpi_gbl_aml_resource_sizes[resource->type];
208
209 /*
210 * Augment the base size for descriptors with optional and/or
211 * variable-length fields
212 */
213 switch (resource->type) {
214 case ACPI_RESOURCE_TYPE_IRQ:
215
216 /* Length can be 3 or 2 */
217
218 if (resource->data.irq.descriptor_length == 2) {
219 total_size--;
220 }
221 break;
222
223 case ACPI_RESOURCE_TYPE_START_DEPENDENT:
224
225 /* Length can be 1 or 0 */
226
227 if (resource->data.irq.descriptor_length == 0) {
228 total_size--;
229 }
230 break;
231
232 case ACPI_RESOURCE_TYPE_VENDOR:
233 /*
234 * Vendor Defined Resource:
235 * For a Vendor Specific resource, if the Length is between 1 and 7
236 * it will be created as a Small Resource data type, otherwise it
237 * is a Large Resource data type.
238 */
239 if (resource->data.vendor.byte_length > 7) {
240
241 /* Base size of a Large resource descriptor */
242
243 total_size =
244 sizeof(struct aml_resource_large_header);
245 }
246
247 /* Add the size of the vendor-specific data */
248
249 total_size = (acpi_rs_length)
250 (total_size + resource->data.vendor.byte_length);
251 break;
252
253 case ACPI_RESOURCE_TYPE_END_TAG:
254 /*
255 * End Tag:
256 * We are done -- return the accumulated total size.
257 */
258 *size_needed = aml_size_needed + total_size;
259
260 /* Normal exit */
261
262 return_ACPI_STATUS(AE_OK);
263
264 case ACPI_RESOURCE_TYPE_ADDRESS16:
265 /*
266 * 16-Bit Address Resource:
267 * Add the size of the optional resource_source info
268 */
269 total_size = (acpi_rs_length)
270 (total_size +
271 acpi_rs_struct_option_length(&resource->data.
272 address16.
273 resource_source));
274 break;
275
276 case ACPI_RESOURCE_TYPE_ADDRESS32:
277 /*
278 * 32-Bit Address Resource:
279 * Add the size of the optional resource_source info
280 */
281 total_size = (acpi_rs_length)
282 (total_size +
283 acpi_rs_struct_option_length(&resource->data.
284 address32.
285 resource_source));
286 break;
287
288 case ACPI_RESOURCE_TYPE_ADDRESS64:
289 /*
290 * 64-Bit Address Resource:
291 * Add the size of the optional resource_source info
292 */
293 total_size = (acpi_rs_length)
294 (total_size +
295 acpi_rs_struct_option_length(&resource->data.
296 address64.
297 resource_source));
298 break;
299
300 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
301 /*
302 * Extended IRQ Resource:
303 * Add the size of each additional optional interrupt beyond the
304 * required 1 (4 bytes for each u32 interrupt number)
305 */
306 total_size = (acpi_rs_length)
307 (total_size +
308 ((resource->data.extended_irq.interrupt_count -
309 1) * 4) +
310 /* Add the size of the optional resource_source info */
311 acpi_rs_struct_option_length(&resource->data.
312 extended_irq.
313 resource_source));
314 break;
315
316 default:
317 break;
318 }
319
320 /* Update the total */
321
322 aml_size_needed += total_size;
323
324 /* Point to the next object */
325
326 resource =
327 ACPI_ADD_PTR(struct acpi_resource, resource,
328 resource->length);
329 }
330
331 /* Did not find an end_tag resource descriptor */
332
333 return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG);
334}
335
336/*******************************************************************************
337 *
338 * FUNCTION: acpi_rs_get_list_length
339 *
340 * PARAMETERS: aml_buffer - Pointer to the resource byte stream
341 * aml_buffer_length - Size of aml_buffer
342 * size_needed - Where the size needed is returned
343 *
344 * RETURN: Status
345 *
346 * DESCRIPTION: Takes an external resource byte stream and calculates the size
347 * buffer needed to hold the corresponding internal resource
348 * descriptor linked list.
349 *
350 ******************************************************************************/
351
352acpi_status
353acpi_rs_get_list_length(u8 * aml_buffer,
354 u32 aml_buffer_length, acpi_size * size_needed)
355{
356 acpi_status status;
357 u8 *end_aml;
358 u8 *buffer;
359 u32 buffer_size;
360 u16 temp16;
361 u16 resource_length;
362 u32 extra_struct_bytes;
363 u8 resource_index;
364 u8 minimum_aml_resource_length;
365
366 ACPI_FUNCTION_TRACE(rs_get_list_length);
367
368 *size_needed = 0;
369 end_aml = aml_buffer + aml_buffer_length;
370
371 /* Walk the list of AML resource descriptors */
372
373 while (aml_buffer < end_aml) {
374
375 /* Validate the Resource Type and Resource Length */
376
377 status = acpi_ut_validate_resource(aml_buffer, &resource_index);
378 if (ACPI_FAILURE(status)) {
379 return_ACPI_STATUS(status);
380 }
381
382 /* Get the resource length and base (minimum) AML size */
383
384 resource_length = acpi_ut_get_resource_length(aml_buffer);
385 minimum_aml_resource_length =
386 acpi_gbl_resource_aml_sizes[resource_index];
387
388 /*
389 * Augment the size for descriptors with optional
390 * and/or variable length fields
391 */
392 extra_struct_bytes = 0;
393 buffer =
394 aml_buffer + acpi_ut_get_resource_header_length(aml_buffer);
395
396 switch (acpi_ut_get_resource_type(aml_buffer)) {
397 case ACPI_RESOURCE_NAME_IRQ:
398 /*
399 * IRQ Resource:
400 * Get the number of bits set in the 16-bit IRQ mask
401 */
402 ACPI_MOVE_16_TO_16(&temp16, buffer);
403 extra_struct_bytes = acpi_rs_count_set_bits(temp16);
404 break;
405
406 case ACPI_RESOURCE_NAME_DMA:
407 /*
408 * DMA Resource:
409 * Get the number of bits set in the 8-bit DMA mask
410 */
411 extra_struct_bytes = acpi_rs_count_set_bits(*buffer);
412 break;
413
414 case ACPI_RESOURCE_NAME_VENDOR_SMALL:
415 case ACPI_RESOURCE_NAME_VENDOR_LARGE:
416 /*
417 * Vendor Resource:
418 * Get the number of vendor data bytes
419 */
420 extra_struct_bytes = resource_length;
421 break;
422
423 case ACPI_RESOURCE_NAME_END_TAG:
424 /*
425 * End Tag:
426 * This is the normal exit, add size of end_tag
427 */
428 *size_needed += ACPI_RS_SIZE_MIN;
429 return_ACPI_STATUS(AE_OK);
430
431 case ACPI_RESOURCE_NAME_ADDRESS32:
432 case ACPI_RESOURCE_NAME_ADDRESS16:
433 case ACPI_RESOURCE_NAME_ADDRESS64:
434 /*
435 * Address Resource:
436 * Add the size of the optional resource_source
437 */
438 extra_struct_bytes =
439 acpi_rs_stream_option_length(resource_length,
440 minimum_aml_resource_length);
441 break;
442
443 case ACPI_RESOURCE_NAME_EXTENDED_IRQ:
444 /*
445 * Extended IRQ Resource:
446 * Using the interrupt_table_length, add 4 bytes for each additional
447 * interrupt. Note: at least one interrupt is required and is
448 * included in the minimum descriptor size (reason for the -1)
449 */
450 extra_struct_bytes = (buffer[1] - 1) * sizeof(u32);
451
452 /* Add the size of the optional resource_source */
453
454 extra_struct_bytes +=
455 acpi_rs_stream_option_length(resource_length -
456 extra_struct_bytes,
457 minimum_aml_resource_length);
458 break;
459
460 default:
461 break;
462 }
463
464 /*
465 * Update the required buffer size for the internal descriptor structs
466 *
467 * Important: Round the size up for the appropriate alignment. This
468 * is a requirement on IA64.
469 */
470 buffer_size = acpi_gbl_resource_struct_sizes[resource_index] +
471 extra_struct_bytes;
472 buffer_size = (u32) ACPI_ROUND_UP_TO_NATIVE_WORD(buffer_size);
473
474 *size_needed += buffer_size;
475
476 ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
477 "Type %.2X, AmlLength %.2X InternalLength %.2X\n",
478 acpi_ut_get_resource_type(aml_buffer),
479 acpi_ut_get_descriptor_length(aml_buffer),
480 buffer_size));
481
482 /*
483 * Point to the next resource within the AML stream using the length
484 * contained in the resource descriptor header
485 */
486 aml_buffer += acpi_ut_get_descriptor_length(aml_buffer);
487 }
488
489 /* Did not find an end_tag resource descriptor */
490
491 return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG);
492}
493
494/*******************************************************************************
495 *
496 * FUNCTION: acpi_rs_get_pci_routing_table_length
497 *
498 * PARAMETERS: package_object - Pointer to the package object
499 * buffer_size_needed - u32 pointer of the size buffer
500 * needed to properly return the
501 * parsed data
502 *
503 * RETURN: Status
504 *
505 * DESCRIPTION: Given a package representing a PCI routing table, this
506 * calculates the size of the corresponding linked list of
507 * descriptions.
508 *
509 ******************************************************************************/
510
511acpi_status
512acpi_rs_get_pci_routing_table_length(union acpi_operand_object *package_object,
513 acpi_size * buffer_size_needed)
514{
515 u32 number_of_elements;
516 acpi_size temp_size_needed = 0;
517 union acpi_operand_object **top_object_list;
518 u32 index;
519 union acpi_operand_object *package_element;
520 union acpi_operand_object **sub_object_list;
521 u8 name_found;
522 u32 table_index;
523
524 ACPI_FUNCTION_TRACE(rs_get_pci_routing_table_length);
525
526 number_of_elements = package_object->package.count;
527
528 /*
529 * Calculate the size of the return buffer.
530 * The base size is the number of elements * the sizes of the
531 * structures. Additional space for the strings is added below.
532 * The minus one is to subtract the size of the u8 Source[1]
533 * member because it is added below.
534 *
535 * But each PRT_ENTRY structure has a pointer to a string and
536 * the size of that string must be found.
537 */
538 top_object_list = package_object->package.elements;
539
540 for (index = 0; index < number_of_elements; index++) {
541
542 /* Dereference the sub-package */
543
544 package_element = *top_object_list;
545
546 /*
547 * The sub_object_list will now point to an array of the
548 * four IRQ elements: Address, Pin, Source and source_index
549 */
550 sub_object_list = package_element->package.elements;
551
552 /* Scan the irq_table_elements for the Source Name String */
553
554 name_found = FALSE;
555
556 for (table_index = 0; table_index < 4 && !name_found;
557 table_index++) {
558 if (*sub_object_list && /* Null object allowed */
559 ((ACPI_TYPE_STRING ==
560 ACPI_GET_OBJECT_TYPE(*sub_object_list)) ||
561 ((ACPI_TYPE_LOCAL_REFERENCE ==
562 ACPI_GET_OBJECT_TYPE(*sub_object_list)) &&
563 ((*sub_object_list)->reference.class ==
564 ACPI_REFCLASS_NAME)))) {
565 name_found = TRUE;
566 } else {
567 /* Look at the next element */
568
569 sub_object_list++;
570 }
571 }
572
573 temp_size_needed += (sizeof(struct acpi_pci_routing_table) - 4);
574
575 /* Was a String type found? */
576
577 if (name_found) {
578 if (ACPI_GET_OBJECT_TYPE(*sub_object_list) ==
579 ACPI_TYPE_STRING) {
580 /*
581 * The length String.Length field does not include the
582 * terminating NULL, add 1
583 */
584 temp_size_needed += ((acpi_size)
585 (*sub_object_list)->string.
586 length + 1);
587 } else {
588 temp_size_needed +=
589 acpi_ns_get_pathname_length((*sub_object_list)->reference.node);
590 if (!temp_size_needed) {
591 return_ACPI_STATUS(AE_BAD_PARAMETER);
592 }
593 }
594 } else {
595 /*
596 * If no name was found, then this is a NULL, which is
597 * translated as a u32 zero.
598 */
599 temp_size_needed += sizeof(u32);
600 }
601
602 /* Round up the size since each element must be aligned */
603
604 temp_size_needed = ACPI_ROUND_UP_TO_64BIT(temp_size_needed);
605
606 /* Point to the next union acpi_operand_object */
607
608 top_object_list++;
609 }
610
611 /*
612 * Add an extra element to the end of the list, essentially a
613 * NULL terminator
614 */
615 *buffer_size_needed =
616 temp_size_needed + sizeof(struct acpi_pci_routing_table);
617 return_ACPI_STATUS(AE_OK);
618}
diff --git a/drivers/acpi/acpica/rscreate.c b/drivers/acpi/acpica/rscreate.c
new file mode 100644
index 00000000000..3ca606974d5
--- /dev/null
+++ b/drivers/acpi/acpica/rscreate.c
@@ -0,0 +1,468 @@
1/*******************************************************************************
2 *
3 * Module Name: rscreate - Create resource lists/tables
4 *
5 ******************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46#include <acpi/acresrc.h>
47#include <acpi/acnamesp.h>
48
49#define _COMPONENT ACPI_RESOURCES
50ACPI_MODULE_NAME("rscreate")
51
52/*******************************************************************************
53 *
54 * FUNCTION: acpi_rs_create_resource_list
55 *
56 * PARAMETERS: aml_buffer - Pointer to the resource byte stream
57 * output_buffer - Pointer to the user's buffer
58 *
59 * RETURN: Status: AE_OK if okay, else a valid acpi_status code
60 * If output_buffer is not large enough, output_buffer_length
61 * indicates how large output_buffer should be, else it
62 * indicates how may u8 elements of output_buffer are valid.
63 *
64 * DESCRIPTION: Takes the byte stream returned from a _CRS, _PRS control method
65 * execution and parses the stream to create a linked list
66 * of device resources.
67 *
68 ******************************************************************************/
69acpi_status
70acpi_rs_create_resource_list(union acpi_operand_object *aml_buffer,
71 struct acpi_buffer *output_buffer)
72{
73
74 acpi_status status;
75 u8 *aml_start;
76 acpi_size list_size_needed = 0;
77 u32 aml_buffer_length;
78 void *resource;
79
80 ACPI_FUNCTION_TRACE(rs_create_resource_list);
81
82 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "AmlBuffer = %p\n", aml_buffer));
83
84 /* Params already validated, so we don't re-validate here */
85
86 aml_buffer_length = aml_buffer->buffer.length;
87 aml_start = aml_buffer->buffer.pointer;
88
89 /*
90 * Pass the aml_buffer into a module that can calculate
91 * the buffer size needed for the linked list
92 */
93 status = acpi_rs_get_list_length(aml_start, aml_buffer_length,
94 &list_size_needed);
95
96 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Status=%X ListSizeNeeded=%X\n",
97 status, (u32) list_size_needed));
98 if (ACPI_FAILURE(status)) {
99 return_ACPI_STATUS(status);
100 }
101
102 /* Validate/Allocate/Clear caller buffer */
103
104 status = acpi_ut_initialize_buffer(output_buffer, list_size_needed);
105 if (ACPI_FAILURE(status)) {
106 return_ACPI_STATUS(status);
107 }
108
109 /* Do the conversion */
110
111 resource = output_buffer->pointer;
112 status = acpi_ut_walk_aml_resources(aml_start, aml_buffer_length,
113 acpi_rs_convert_aml_to_resources,
114 &resource);
115 if (ACPI_FAILURE(status)) {
116 return_ACPI_STATUS(status);
117 }
118
119 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "OutputBuffer %p Length %X\n",
120 output_buffer->pointer, (u32) output_buffer->length));
121 return_ACPI_STATUS(AE_OK);
122}
123
124/*******************************************************************************
125 *
126 * FUNCTION: acpi_rs_create_pci_routing_table
127 *
128 * PARAMETERS: package_object - Pointer to an union acpi_operand_object
129 * package
130 * output_buffer - Pointer to the user's buffer
131 *
132 * RETURN: Status AE_OK if okay, else a valid acpi_status code.
133 * If the output_buffer is too small, the error will be
134 * AE_BUFFER_OVERFLOW and output_buffer->Length will point
135 * to the size buffer needed.
136 *
137 * DESCRIPTION: Takes the union acpi_operand_object package and creates a
138 * linked list of PCI interrupt descriptions
139 *
140 * NOTE: It is the caller's responsibility to ensure that the start of the
141 * output buffer is aligned properly (if necessary).
142 *
143 ******************************************************************************/
144
145acpi_status
146acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
147 struct acpi_buffer *output_buffer)
148{
149 u8 *buffer;
150 union acpi_operand_object **top_object_list;
151 union acpi_operand_object **sub_object_list;
152 union acpi_operand_object *obj_desc;
153 acpi_size buffer_size_needed = 0;
154 u32 number_of_elements;
155 u32 index;
156 struct acpi_pci_routing_table *user_prt;
157 struct acpi_namespace_node *node;
158 acpi_status status;
159 struct acpi_buffer path_buffer;
160
161 ACPI_FUNCTION_TRACE(rs_create_pci_routing_table);
162
163 /* Params already validated, so we don't re-validate here */
164
165 /* Get the required buffer length */
166
167 status = acpi_rs_get_pci_routing_table_length(package_object,
168 &buffer_size_needed);
169 if (ACPI_FAILURE(status)) {
170 return_ACPI_STATUS(status);
171 }
172
173 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "BufferSizeNeeded = %X\n",
174 (u32) buffer_size_needed));
175
176 /* Validate/Allocate/Clear caller buffer */
177
178 status = acpi_ut_initialize_buffer(output_buffer, buffer_size_needed);
179 if (ACPI_FAILURE(status)) {
180 return_ACPI_STATUS(status);
181 }
182
183 /*
184 * Loop through the ACPI_INTERNAL_OBJECTS - Each object should be a
185 * package that in turn contains an acpi_integer Address, a u8 Pin,
186 * a Name, and a u8 source_index.
187 */
188 top_object_list = package_object->package.elements;
189 number_of_elements = package_object->package.count;
190 buffer = output_buffer->pointer;
191 user_prt = ACPI_CAST_PTR(struct acpi_pci_routing_table, buffer);
192
193 for (index = 0; index < number_of_elements; index++) {
194 int source_name_index = 2;
195 int source_index_index = 3;
196
197 /*
198 * Point user_prt past this current structure
199 *
200 * NOTE: On the first iteration, user_prt->Length will
201 * be zero because we cleared the return buffer earlier
202 */
203 buffer += user_prt->length;
204 user_prt = ACPI_CAST_PTR(struct acpi_pci_routing_table, buffer);
205
206 /*
207 * Fill in the Length field with the information we have at this point.
208 * The minus four is to subtract the size of the u8 Source[4] member
209 * because it is added below.
210 */
211 user_prt->length = (sizeof(struct acpi_pci_routing_table) - 4);
212
213 /* Each element of the top-level package must also be a package */
214
215 if (ACPI_GET_OBJECT_TYPE(*top_object_list) != ACPI_TYPE_PACKAGE) {
216 ACPI_ERROR((AE_INFO,
217 "(PRT[%X]) Need sub-package, found %s",
218 index,
219 acpi_ut_get_object_type_name
220 (*top_object_list)));
221 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
222 }
223
224 /* Each sub-package must be of length 4 */
225
226 if ((*top_object_list)->package.count != 4) {
227 ACPI_ERROR((AE_INFO,
228 "(PRT[%X]) Need package of length 4, found length %d",
229 index, (*top_object_list)->package.count));
230 return_ACPI_STATUS(AE_AML_PACKAGE_LIMIT);
231 }
232
233 /*
234 * Dereference the sub-package.
235 * The sub_object_list will now point to an array of the four IRQ
236 * elements: [Address, Pin, Source, source_index]
237 */
238 sub_object_list = (*top_object_list)->package.elements;
239
240 /* 1) First subobject: Dereference the PRT.Address */
241
242 obj_desc = sub_object_list[0];
243 if (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_INTEGER) {
244 ACPI_ERROR((AE_INFO,
245 "(PRT[%X].Address) Need Integer, found %s",
246 index,
247 acpi_ut_get_object_type_name(obj_desc)));
248 return_ACPI_STATUS(AE_BAD_DATA);
249 }
250
251 user_prt->address = obj_desc->integer.value;
252
253 /* 2) Second subobject: Dereference the PRT.Pin */
254
255 obj_desc = sub_object_list[1];
256 if (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_INTEGER) {
257 ACPI_ERROR((AE_INFO,
258 "(PRT[%X].Pin) Need Integer, found %s",
259 index,
260 acpi_ut_get_object_type_name(obj_desc)));
261 return_ACPI_STATUS(AE_BAD_DATA);
262 }
263
264 /*
265 * If BIOS erroneously reversed the _PRT source_name and source_index,
266 * then reverse them back.
267 */
268 if (ACPI_GET_OBJECT_TYPE(sub_object_list[3]) !=
269 ACPI_TYPE_INTEGER) {
270 if (acpi_gbl_enable_interpreter_slack) {
271 source_name_index = 3;
272 source_index_index = 2;
273 printk(KERN_WARNING
274 "ACPI: Handling Garbled _PRT entry\n");
275 } else {
276 ACPI_ERROR((AE_INFO,
277 "(PRT[%X].source_index) Need Integer, found %s",
278 index,
279 acpi_ut_get_object_type_name
280 (sub_object_list[3])));
281 return_ACPI_STATUS(AE_BAD_DATA);
282 }
283 }
284
285 user_prt->pin = (u32) obj_desc->integer.value;
286
287 /*
288 * If the BIOS has erroneously reversed the _PRT source_name (index 2)
289 * and the source_index (index 3), fix it. _PRT is important enough to
290 * workaround this BIOS error. This also provides compatibility with
291 * other ACPI implementations.
292 */
293 obj_desc = sub_object_list[3];
294 if (!obj_desc
295 || (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_INTEGER)) {
296 sub_object_list[3] = sub_object_list[2];
297 sub_object_list[2] = obj_desc;
298
299 ACPI_WARNING((AE_INFO,
300 "(PRT[%X].Source) SourceName and SourceIndex are reversed, fixed",
301 index));
302 }
303
304 /*
305 * 3) Third subobject: Dereference the PRT.source_name
306 * The name may be unresolved (slack mode), so allow a null object
307 */
308 obj_desc = sub_object_list[source_name_index];
309 if (obj_desc) {
310 switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
311 case ACPI_TYPE_LOCAL_REFERENCE:
312
313 if (obj_desc->reference.class !=
314 ACPI_REFCLASS_NAME) {
315 ACPI_ERROR((AE_INFO,
316 "(PRT[%X].Source) Need name, found Reference Class %X",
317 index,
318 obj_desc->reference.class));
319 return_ACPI_STATUS(AE_BAD_DATA);
320 }
321
322 node = obj_desc->reference.node;
323
324 /* Use *remaining* length of the buffer as max for pathname */
325
326 path_buffer.length = output_buffer->length -
327 (u32) ((u8 *) user_prt->source -
328 (u8 *) output_buffer->pointer);
329 path_buffer.pointer = user_prt->source;
330
331 status =
332 acpi_ns_handle_to_pathname((acpi_handle)
333 node,
334 &path_buffer);
335
336 /* +1 to include null terminator */
337
338 user_prt->length +=
339 (u32) ACPI_STRLEN(user_prt->source) + 1;
340 break;
341
342 case ACPI_TYPE_STRING:
343
344 ACPI_STRCPY(user_prt->source,
345 obj_desc->string.pointer);
346
347 /*
348 * Add to the Length field the length of the string
349 * (add 1 for terminator)
350 */
351 user_prt->length += obj_desc->string.length + 1;
352 break;
353
354 case ACPI_TYPE_INTEGER:
355 /*
356 * If this is a number, then the Source Name is NULL, since the
357 * entire buffer was zeroed out, we can leave this alone.
358 *
359 * Add to the Length field the length of the u32 NULL
360 */
361 user_prt->length += sizeof(u32);
362 break;
363
364 default:
365
366 ACPI_ERROR((AE_INFO,
367 "(PRT[%X].Source) Need Ref/String/Integer, found %s",
368 index,
369 acpi_ut_get_object_type_name
370 (obj_desc)));
371 return_ACPI_STATUS(AE_BAD_DATA);
372 }
373 }
374
375 /* Now align the current length */
376
377 user_prt->length =
378 (u32) ACPI_ROUND_UP_TO_64BIT(user_prt->length);
379
380 /* 4) Fourth subobject: Dereference the PRT.source_index */
381
382 obj_desc = sub_object_list[source_index_index];
383 if (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_INTEGER) {
384 ACPI_ERROR((AE_INFO,
385 "(PRT[%X].SourceIndex) Need Integer, found %s",
386 index,
387 acpi_ut_get_object_type_name(obj_desc)));
388 return_ACPI_STATUS(AE_BAD_DATA);
389 }
390
391 user_prt->source_index = (u32) obj_desc->integer.value;
392
393 /* Point to the next union acpi_operand_object in the top level package */
394
395 top_object_list++;
396 }
397
398 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "OutputBuffer %p Length %X\n",
399 output_buffer->pointer, (u32) output_buffer->length));
400 return_ACPI_STATUS(AE_OK);
401}
402
403/*******************************************************************************
404 *
405 * FUNCTION: acpi_rs_create_aml_resources
406 *
407 * PARAMETERS: linked_list_buffer - Pointer to the resource linked list
408 * output_buffer - Pointer to the user's buffer
409 *
410 * RETURN: Status AE_OK if okay, else a valid acpi_status code.
411 * If the output_buffer is too small, the error will be
412 * AE_BUFFER_OVERFLOW and output_buffer->Length will point
413 * to the size buffer needed.
414 *
415 * DESCRIPTION: Takes the linked list of device resources and
416 * creates a bytestream to be used as input for the
417 * _SRS control method.
418 *
419 ******************************************************************************/
420
421acpi_status
422acpi_rs_create_aml_resources(struct acpi_resource *linked_list_buffer,
423 struct acpi_buffer *output_buffer)
424{
425 acpi_status status;
426 acpi_size aml_size_needed = 0;
427
428 ACPI_FUNCTION_TRACE(rs_create_aml_resources);
429
430 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "LinkedListBuffer = %p\n",
431 linked_list_buffer));
432
433 /*
434 * Params already validated, so we don't re-validate here
435 *
436 * Pass the linked_list_buffer into a module that calculates
437 * the buffer size needed for the byte stream.
438 */
439 status = acpi_rs_get_aml_length(linked_list_buffer, &aml_size_needed);
440
441 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "AmlSizeNeeded=%X, %s\n",
442 (u32) aml_size_needed,
443 acpi_format_exception(status)));
444 if (ACPI_FAILURE(status)) {
445 return_ACPI_STATUS(status);
446 }
447
448 /* Validate/Allocate/Clear caller buffer */
449
450 status = acpi_ut_initialize_buffer(output_buffer, aml_size_needed);
451 if (ACPI_FAILURE(status)) {
452 return_ACPI_STATUS(status);
453 }
454
455 /* Do the conversion */
456
457 status =
458 acpi_rs_convert_resources_to_aml(linked_list_buffer,
459 aml_size_needed,
460 output_buffer->pointer);
461 if (ACPI_FAILURE(status)) {
462 return_ACPI_STATUS(status);
463 }
464
465 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "OutputBuffer %p Length %X\n",
466 output_buffer->pointer, (u32) output_buffer->length));
467 return_ACPI_STATUS(AE_OK);
468}
diff --git a/drivers/acpi/acpica/rsdump.c b/drivers/acpi/acpica/rsdump.c
new file mode 100644
index 00000000000..936a59be39f
--- /dev/null
+++ b/drivers/acpi/acpica/rsdump.c
@@ -0,0 +1,771 @@
1/*******************************************************************************
2 *
3 * Module Name: rsdump - Functions to display the resource structures.
4 *
5 ******************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46#include <acpi/acresrc.h>
47
48#define _COMPONENT ACPI_RESOURCES
49ACPI_MODULE_NAME("rsdump")
50#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
51/* Local prototypes */
52static void acpi_rs_out_string(char *title, char *value);
53
54static void acpi_rs_out_integer8(char *title, u8 value);
55
56static void acpi_rs_out_integer16(char *title, u16 value);
57
58static void acpi_rs_out_integer32(char *title, u32 value);
59
60static void acpi_rs_out_integer64(char *title, u64 value);
61
62static void acpi_rs_out_title(char *title);
63
64static void acpi_rs_dump_byte_list(u16 length, u8 * data);
65
66static void acpi_rs_dump_dword_list(u8 length, u32 * data);
67
68static void acpi_rs_dump_short_byte_list(u8 length, u8 * data);
69
70static void
71acpi_rs_dump_resource_source(struct acpi_resource_source *resource_source);
72
73static void acpi_rs_dump_address_common(union acpi_resource_data *resource);
74
75static void
76acpi_rs_dump_descriptor(void *resource, struct acpi_rsdump_info *table);
77
78#define ACPI_RSD_OFFSET(f) (u8) ACPI_OFFSET (union acpi_resource_data,f)
79#define ACPI_PRT_OFFSET(f) (u8) ACPI_OFFSET (struct acpi_pci_routing_table,f)
80#define ACPI_RSD_TABLE_SIZE(name) (sizeof(name) / sizeof (struct acpi_rsdump_info))
81
82/*******************************************************************************
83 *
84 * Resource Descriptor info tables
85 *
86 * Note: The first table entry must be a Title or Literal and must contain
87 * the table length (number of table entries)
88 *
89 ******************************************************************************/
90
91struct acpi_rsdump_info acpi_rs_dump_irq[7] = {
92 {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_irq), "IRQ", NULL},
93 {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(irq.descriptor_length),
94 "Descriptor Length", NULL},
95 {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(irq.triggering), "Triggering",
96 acpi_gbl_he_decode},
97 {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(irq.polarity), "Polarity",
98 acpi_gbl_ll_decode},
99 {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(irq.sharable), "Sharing",
100 acpi_gbl_shr_decode},
101 {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(irq.interrupt_count),
102 "Interrupt Count", NULL},
103 {ACPI_RSD_SHORTLIST, ACPI_RSD_OFFSET(irq.interrupts[0]),
104 "Interrupt List", NULL}
105};
106
107struct acpi_rsdump_info acpi_rs_dump_dma[6] = {
108 {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_dma), "DMA", NULL},
109 {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(dma.type), "Speed",
110 acpi_gbl_typ_decode},
111 {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(dma.bus_master), "Mastering",
112 acpi_gbl_bm_decode},
113 {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(dma.transfer), "Transfer Type",
114 acpi_gbl_siz_decode},
115 {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(dma.channel_count), "Channel Count",
116 NULL},
117 {ACPI_RSD_SHORTLIST, ACPI_RSD_OFFSET(dma.channels[0]), "Channel List",
118 NULL}
119};
120
121struct acpi_rsdump_info acpi_rs_dump_start_dpf[4] = {
122 {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_start_dpf),
123 "Start-Dependent-Functions", NULL},
124 {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(start_dpf.descriptor_length),
125 "Descriptor Length", NULL},
126 {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(start_dpf.compatibility_priority),
127 "Compatibility Priority", acpi_gbl_config_decode},
128 {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(start_dpf.performance_robustness),
129 "Performance/Robustness", acpi_gbl_config_decode}
130};
131
132struct acpi_rsdump_info acpi_rs_dump_end_dpf[1] = {
133 {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_end_dpf),
134 "End-Dependent-Functions", NULL}
135};
136
137struct acpi_rsdump_info acpi_rs_dump_io[6] = {
138 {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_io), "I/O", NULL},
139 {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(io.io_decode), "Address Decoding",
140 acpi_gbl_io_decode},
141 {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(io.minimum), "Address Minimum", NULL},
142 {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(io.maximum), "Address Maximum", NULL},
143 {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(io.alignment), "Alignment", NULL},
144 {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(io.address_length), "Address Length",
145 NULL}
146};
147
148struct acpi_rsdump_info acpi_rs_dump_fixed_io[3] = {
149 {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_fixed_io),
150 "Fixed I/O", NULL},
151 {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(fixed_io.address), "Address", NULL},
152 {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(fixed_io.address_length),
153 "Address Length", NULL}
154};
155
156struct acpi_rsdump_info acpi_rs_dump_vendor[3] = {
157 {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_vendor),
158 "Vendor Specific", NULL},
159 {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(vendor.byte_length), "Length", NULL},
160 {ACPI_RSD_LONGLIST, ACPI_RSD_OFFSET(vendor.byte_data[0]), "Vendor Data",
161 NULL}
162};
163
164struct acpi_rsdump_info acpi_rs_dump_end_tag[1] = {
165 {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_end_tag), "EndTag",
166 NULL}
167};
168
169struct acpi_rsdump_info acpi_rs_dump_memory24[6] = {
170 {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_memory24),
171 "24-Bit Memory Range", NULL},
172 {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(memory24.write_protect),
173 "Write Protect", acpi_gbl_rw_decode},
174 {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(memory24.minimum), "Address Minimum",
175 NULL},
176 {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(memory24.maximum), "Address Maximum",
177 NULL},
178 {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(memory24.alignment), "Alignment",
179 NULL},
180 {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(memory24.address_length),
181 "Address Length", NULL}
182};
183
184struct acpi_rsdump_info acpi_rs_dump_memory32[6] = {
185 {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_memory32),
186 "32-Bit Memory Range", NULL},
187 {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(memory32.write_protect),
188 "Write Protect", acpi_gbl_rw_decode},
189 {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(memory32.minimum), "Address Minimum",
190 NULL},
191 {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(memory32.maximum), "Address Maximum",
192 NULL},
193 {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(memory32.alignment), "Alignment",
194 NULL},
195 {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(memory32.address_length),
196 "Address Length", NULL}
197};
198
199struct acpi_rsdump_info acpi_rs_dump_fixed_memory32[4] = {
200 {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_fixed_memory32),
201 "32-Bit Fixed Memory Range", NULL},
202 {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(fixed_memory32.write_protect),
203 "Write Protect", acpi_gbl_rw_decode},
204 {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(fixed_memory32.address), "Address",
205 NULL},
206 {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(fixed_memory32.address_length),
207 "Address Length", NULL}
208};
209
210struct acpi_rsdump_info acpi_rs_dump_address16[8] = {
211 {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_address16),
212 "16-Bit WORD Address Space", NULL},
213 {ACPI_RSD_ADDRESS, 0, NULL, NULL},
214 {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(address16.granularity), "Granularity",
215 NULL},
216 {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(address16.minimum), "Address Minimum",
217 NULL},
218 {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(address16.maximum), "Address Maximum",
219 NULL},
220 {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(address16.translation_offset),
221 "Translation Offset", NULL},
222 {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(address16.address_length),
223 "Address Length", NULL},
224 {ACPI_RSD_SOURCE, ACPI_RSD_OFFSET(address16.resource_source), NULL, NULL}
225};
226
227struct acpi_rsdump_info acpi_rs_dump_address32[8] = {
228 {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_address32),
229 "32-Bit DWORD Address Space", NULL},
230 {ACPI_RSD_ADDRESS, 0, NULL, NULL},
231 {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(address32.granularity), "Granularity",
232 NULL},
233 {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(address32.minimum), "Address Minimum",
234 NULL},
235 {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(address32.maximum), "Address Maximum",
236 NULL},
237 {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(address32.translation_offset),
238 "Translation Offset", NULL},
239 {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(address32.address_length),
240 "Address Length", NULL},
241 {ACPI_RSD_SOURCE, ACPI_RSD_OFFSET(address32.resource_source), NULL, NULL}
242};
243
244struct acpi_rsdump_info acpi_rs_dump_address64[8] = {
245 {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_address64),
246 "64-Bit QWORD Address Space", NULL},
247 {ACPI_RSD_ADDRESS, 0, NULL, NULL},
248 {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(address64.granularity), "Granularity",
249 NULL},
250 {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(address64.minimum), "Address Minimum",
251 NULL},
252 {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(address64.maximum), "Address Maximum",
253 NULL},
254 {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(address64.translation_offset),
255 "Translation Offset", NULL},
256 {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(address64.address_length),
257 "Address Length", NULL},
258 {ACPI_RSD_SOURCE, ACPI_RSD_OFFSET(address64.resource_source), NULL, NULL}
259};
260
261struct acpi_rsdump_info acpi_rs_dump_ext_address64[8] = {
262 {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_ext_address64),
263 "64-Bit Extended Address Space", NULL},
264 {ACPI_RSD_ADDRESS, 0, NULL, NULL},
265 {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(ext_address64.granularity),
266 "Granularity", NULL},
267 {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(ext_address64.minimum),
268 "Address Minimum", NULL},
269 {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(ext_address64.maximum),
270 "Address Maximum", NULL},
271 {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(ext_address64.translation_offset),
272 "Translation Offset", NULL},
273 {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(ext_address64.address_length),
274 "Address Length", NULL},
275 {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(ext_address64.type_specific),
276 "Type-Specific Attribute", NULL}
277};
278
279struct acpi_rsdump_info acpi_rs_dump_ext_irq[8] = {
280 {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_ext_irq),
281 "Extended IRQ", NULL},
282 {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(extended_irq.producer_consumer),
283 "Type", acpi_gbl_consume_decode},
284 {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(extended_irq.triggering),
285 "Triggering", acpi_gbl_he_decode},
286 {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(extended_irq.polarity), "Polarity",
287 acpi_gbl_ll_decode},
288 {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(extended_irq.sharable), "Sharing",
289 acpi_gbl_shr_decode},
290 {ACPI_RSD_SOURCE, ACPI_RSD_OFFSET(extended_irq.resource_source), NULL,
291 NULL},
292 {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(extended_irq.interrupt_count),
293 "Interrupt Count", NULL},
294 {ACPI_RSD_DWORDLIST, ACPI_RSD_OFFSET(extended_irq.interrupts[0]),
295 "Interrupt List", NULL}
296};
297
298struct acpi_rsdump_info acpi_rs_dump_generic_reg[6] = {
299 {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_generic_reg),
300 "Generic Register", NULL},
301 {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(generic_reg.space_id), "Space ID",
302 NULL},
303 {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(generic_reg.bit_width), "Bit Width",
304 NULL},
305 {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(generic_reg.bit_offset), "Bit Offset",
306 NULL},
307 {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(generic_reg.access_size),
308 "Access Size", NULL},
309 {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(generic_reg.address), "Address", NULL}
310};
311
312/*
313 * Tables used for common address descriptor flag fields
314 */
315static struct acpi_rsdump_info acpi_rs_dump_general_flags[5] = {
316 {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_general_flags), NULL,
317 NULL},
318 {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.producer_consumer),
319 "Consumer/Producer", acpi_gbl_consume_decode},
320 {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.decode), "Address Decode",
321 acpi_gbl_dec_decode},
322 {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.min_address_fixed),
323 "Min Relocatability", acpi_gbl_min_decode},
324 {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.max_address_fixed),
325 "Max Relocatability", acpi_gbl_max_decode}
326};
327
328static struct acpi_rsdump_info acpi_rs_dump_memory_flags[5] = {
329 {ACPI_RSD_LITERAL, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_memory_flags),
330 "Resource Type", (void *)"Memory Range"},
331 {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.info.mem.write_protect),
332 "Write Protect", acpi_gbl_rw_decode},
333 {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(address.info.mem.caching),
334 "Caching", acpi_gbl_mem_decode},
335 {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(address.info.mem.range_type),
336 "Range Type", acpi_gbl_mtp_decode},
337 {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.info.mem.translation),
338 "Translation", acpi_gbl_ttp_decode}
339};
340
341static struct acpi_rsdump_info acpi_rs_dump_io_flags[4] = {
342 {ACPI_RSD_LITERAL, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_io_flags),
343 "Resource Type", (void *)"I/O Range"},
344 {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(address.info.io.range_type),
345 "Range Type", acpi_gbl_rng_decode},
346 {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.info.io.translation),
347 "Translation", acpi_gbl_ttp_decode},
348 {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(address.info.io.translation_type),
349 "Translation Type", acpi_gbl_trs_decode}
350};
351
352/*
353 * Table used to dump _PRT contents
354 */
355static struct acpi_rsdump_info acpi_rs_dump_prt[5] = {
356 {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_prt), NULL, NULL},
357 {ACPI_RSD_UINT64, ACPI_PRT_OFFSET(address), "Address", NULL},
358 {ACPI_RSD_UINT32, ACPI_PRT_OFFSET(pin), "Pin", NULL},
359 {ACPI_RSD_STRING, ACPI_PRT_OFFSET(source[0]), "Source", NULL},
360 {ACPI_RSD_UINT32, ACPI_PRT_OFFSET(source_index), "Source Index", NULL}
361};
362
363/*******************************************************************************
364 *
365 * FUNCTION: acpi_rs_dump_descriptor
366 *
367 * PARAMETERS: Resource
368 *
369 * RETURN: None
370 *
371 * DESCRIPTION:
372 *
373 ******************************************************************************/
374
375static void
376acpi_rs_dump_descriptor(void *resource, struct acpi_rsdump_info *table)
377{
378 u8 *target = NULL;
379 u8 *previous_target;
380 char *name;
381 u8 count;
382
383 /* First table entry must contain the table length (# of table entries) */
384
385 count = table->offset;
386
387 while (count) {
388 previous_target = target;
389 target = ACPI_ADD_PTR(u8, resource, table->offset);
390 name = table->name;
391
392 switch (table->opcode) {
393 case ACPI_RSD_TITLE:
394 /*
395 * Optional resource title
396 */
397 if (table->name) {
398 acpi_os_printf("%s Resource\n", name);
399 }
400 break;
401
402 /* Strings */
403
404 case ACPI_RSD_LITERAL:
405 acpi_rs_out_string(name,
406 ACPI_CAST_PTR(char, table->pointer));
407 break;
408
409 case ACPI_RSD_STRING:
410 acpi_rs_out_string(name, ACPI_CAST_PTR(char, target));
411 break;
412
413 /* Data items, 8/16/32/64 bit */
414
415 case ACPI_RSD_UINT8:
416 acpi_rs_out_integer8(name, ACPI_GET8(target));
417 break;
418
419 case ACPI_RSD_UINT16:
420 acpi_rs_out_integer16(name, ACPI_GET16(target));
421 break;
422
423 case ACPI_RSD_UINT32:
424 acpi_rs_out_integer32(name, ACPI_GET32(target));
425 break;
426
427 case ACPI_RSD_UINT64:
428 acpi_rs_out_integer64(name, ACPI_GET64(target));
429 break;
430
431 /* Flags: 1-bit and 2-bit flags supported */
432
433 case ACPI_RSD_1BITFLAG:
434 acpi_rs_out_string(name, ACPI_CAST_PTR(char,
435 table->
436 pointer[*target &
437 0x01]));
438 break;
439
440 case ACPI_RSD_2BITFLAG:
441 acpi_rs_out_string(name, ACPI_CAST_PTR(char,
442 table->
443 pointer[*target &
444 0x03]));
445 break;
446
447 case ACPI_RSD_SHORTLIST:
448 /*
449 * Short byte list (single line output) for DMA and IRQ resources
450 * Note: The list length is obtained from the previous table entry
451 */
452 if (previous_target) {
453 acpi_rs_out_title(name);
454 acpi_rs_dump_short_byte_list(*previous_target,
455 target);
456 }
457 break;
458
459 case ACPI_RSD_LONGLIST:
460 /*
461 * Long byte list for Vendor resource data
462 * Note: The list length is obtained from the previous table entry
463 */
464 if (previous_target) {
465 acpi_rs_dump_byte_list(ACPI_GET16
466 (previous_target),
467 target);
468 }
469 break;
470
471 case ACPI_RSD_DWORDLIST:
472 /*
473 * Dword list for Extended Interrupt resources
474 * Note: The list length is obtained from the previous table entry
475 */
476 if (previous_target) {
477 acpi_rs_dump_dword_list(*previous_target,
478 ACPI_CAST_PTR(u32,
479 target));
480 }
481 break;
482
483 case ACPI_RSD_ADDRESS:
484 /*
485 * Common flags for all Address resources
486 */
487 acpi_rs_dump_address_common(ACPI_CAST_PTR
488 (union acpi_resource_data,
489 target));
490 break;
491
492 case ACPI_RSD_SOURCE:
493 /*
494 * Optional resource_source for Address resources
495 */
496 acpi_rs_dump_resource_source(ACPI_CAST_PTR(struct
497 acpi_resource_source,
498 target));
499 break;
500
501 default:
502 acpi_os_printf("**** Invalid table opcode [%X] ****\n",
503 table->opcode);
504 return;
505 }
506
507 table++;
508 count--;
509 }
510}
511
512/*******************************************************************************
513 *
514 * FUNCTION: acpi_rs_dump_resource_source
515 *
516 * PARAMETERS: resource_source - Pointer to a Resource Source struct
517 *
518 * RETURN: None
519 *
520 * DESCRIPTION: Common routine for dumping the optional resource_source and the
521 * corresponding resource_source_index.
522 *
523 ******************************************************************************/
524
525static void
526acpi_rs_dump_resource_source(struct acpi_resource_source *resource_source)
527{
528 ACPI_FUNCTION_ENTRY();
529
530 if (resource_source->index == 0xFF) {
531 return;
532 }
533
534 acpi_rs_out_integer8("Resource Source Index", resource_source->index);
535
536 acpi_rs_out_string("Resource Source",
537 resource_source->string_ptr ?
538 resource_source->string_ptr : "[Not Specified]");
539}
540
541/*******************************************************************************
542 *
543 * FUNCTION: acpi_rs_dump_address_common
544 *
545 * PARAMETERS: Resource - Pointer to an internal resource descriptor
546 *
547 * RETURN: None
548 *
549 * DESCRIPTION: Dump the fields that are common to all Address resource
550 * descriptors
551 *
552 ******************************************************************************/
553
554static void acpi_rs_dump_address_common(union acpi_resource_data *resource)
555{
556 ACPI_FUNCTION_ENTRY();
557
558 /* Decode the type-specific flags */
559
560 switch (resource->address.resource_type) {
561 case ACPI_MEMORY_RANGE:
562
563 acpi_rs_dump_descriptor(resource, acpi_rs_dump_memory_flags);
564 break;
565
566 case ACPI_IO_RANGE:
567
568 acpi_rs_dump_descriptor(resource, acpi_rs_dump_io_flags);
569 break;
570
571 case ACPI_BUS_NUMBER_RANGE:
572
573 acpi_rs_out_string("Resource Type", "Bus Number Range");
574 break;
575
576 default:
577
578 acpi_rs_out_integer8("Resource Type",
579 (u8) resource->address.resource_type);
580 break;
581 }
582
583 /* Decode the general flags */
584
585 acpi_rs_dump_descriptor(resource, acpi_rs_dump_general_flags);
586}
587
588/*******************************************************************************
589 *
590 * FUNCTION: acpi_rs_dump_resource_list
591 *
592 * PARAMETERS: resource_list - Pointer to a resource descriptor list
593 *
594 * RETURN: None
595 *
596 * DESCRIPTION: Dispatches the structure to the correct dump routine.
597 *
598 ******************************************************************************/
599
600void acpi_rs_dump_resource_list(struct acpi_resource *resource_list)
601{
602 u32 count = 0;
603 u32 type;
604
605 ACPI_FUNCTION_ENTRY();
606
607 if (!(acpi_dbg_level & ACPI_LV_RESOURCES)
608 || !(_COMPONENT & acpi_dbg_layer)) {
609 return;
610 }
611
612 /* Walk list and dump all resource descriptors (END_TAG terminates) */
613
614 do {
615 acpi_os_printf("\n[%02X] ", count);
616 count++;
617
618 /* Validate Type before dispatch */
619
620 type = resource_list->type;
621 if (type > ACPI_RESOURCE_TYPE_MAX) {
622 acpi_os_printf
623 ("Invalid descriptor type (%X) in resource list\n",
624 resource_list->type);
625 return;
626 }
627
628 /* Dump the resource descriptor */
629
630 acpi_rs_dump_descriptor(&resource_list->data,
631 acpi_gbl_dump_resource_dispatch[type]);
632
633 /* Point to the next resource structure */
634
635 resource_list =
636 ACPI_ADD_PTR(struct acpi_resource, resource_list,
637 resource_list->length);
638
639 /* Exit when END_TAG descriptor is reached */
640
641 } while (type != ACPI_RESOURCE_TYPE_END_TAG);
642}
643
644/*******************************************************************************
645 *
646 * FUNCTION: acpi_rs_dump_irq_list
647 *
648 * PARAMETERS: route_table - Pointer to the routing table to dump.
649 *
650 * RETURN: None
651 *
652 * DESCRIPTION: Print IRQ routing table
653 *
654 ******************************************************************************/
655
656void acpi_rs_dump_irq_list(u8 * route_table)
657{
658 struct acpi_pci_routing_table *prt_element;
659 u8 count;
660
661 ACPI_FUNCTION_ENTRY();
662
663 if (!(acpi_dbg_level & ACPI_LV_RESOURCES)
664 || !(_COMPONENT & acpi_dbg_layer)) {
665 return;
666 }
667
668 prt_element = ACPI_CAST_PTR(struct acpi_pci_routing_table, route_table);
669
670 /* Dump all table elements, Exit on zero length element */
671
672 for (count = 0; prt_element->length; count++) {
673 acpi_os_printf("\n[%02X] PCI IRQ Routing Table Package\n",
674 count);
675 acpi_rs_dump_descriptor(prt_element, acpi_rs_dump_prt);
676
677 prt_element = ACPI_ADD_PTR(struct acpi_pci_routing_table,
678 prt_element, prt_element->length);
679 }
680}
681
682/*******************************************************************************
683 *
684 * FUNCTION: acpi_rs_out*
685 *
686 * PARAMETERS: Title - Name of the resource field
687 * Value - Value of the resource field
688 *
689 * RETURN: None
690 *
691 * DESCRIPTION: Miscellaneous helper functions to consistently format the
692 * output of the resource dump routines
693 *
694 ******************************************************************************/
695
696static void acpi_rs_out_string(char *title, char *value)
697{
698 acpi_os_printf("%27s : %s", title, value);
699 if (!*value) {
700 acpi_os_printf("[NULL NAMESTRING]");
701 }
702 acpi_os_printf("\n");
703}
704
705static void acpi_rs_out_integer8(char *title, u8 value)
706{
707 acpi_os_printf("%27s : %2.2X\n", title, value);
708}
709
710static void acpi_rs_out_integer16(char *title, u16 value)
711{
712 acpi_os_printf("%27s : %4.4X\n", title, value);
713}
714
715static void acpi_rs_out_integer32(char *title, u32 value)
716{
717 acpi_os_printf("%27s : %8.8X\n", title, value);
718}
719
720static void acpi_rs_out_integer64(char *title, u64 value)
721{
722 acpi_os_printf("%27s : %8.8X%8.8X\n", title, ACPI_FORMAT_UINT64(value));
723}
724
725static void acpi_rs_out_title(char *title)
726{
727 acpi_os_printf("%27s : ", title);
728}
729
730/*******************************************************************************
731 *
732 * FUNCTION: acpi_rs_dump*List
733 *
734 * PARAMETERS: Length - Number of elements in the list
735 * Data - Start of the list
736 *
737 * RETURN: None
738 *
739 * DESCRIPTION: Miscellaneous functions to dump lists of raw data
740 *
741 ******************************************************************************/
742
743static void acpi_rs_dump_byte_list(u16 length, u8 * data)
744{
745 u8 i;
746
747 for (i = 0; i < length; i++) {
748 acpi_os_printf("%25s%2.2X : %2.2X\n", "Byte", i, data[i]);
749 }
750}
751
752static void acpi_rs_dump_short_byte_list(u8 length, u8 * data)
753{
754 u8 i;
755
756 for (i = 0; i < length; i++) {
757 acpi_os_printf("%X ", data[i]);
758 }
759 acpi_os_printf("\n");
760}
761
762static void acpi_rs_dump_dword_list(u8 length, u32 * data)
763{
764 u8 i;
765
766 for (i = 0; i < length; i++) {
767 acpi_os_printf("%25s%2.2X : %8.8X\n", "Dword", i, data[i]);
768 }
769}
770
771#endif
diff --git a/drivers/acpi/acpica/rsinfo.c b/drivers/acpi/acpica/rsinfo.c
new file mode 100644
index 00000000000..aac41cc2134
--- /dev/null
+++ b/drivers/acpi/acpica/rsinfo.c
@@ -0,0 +1,206 @@
1/*******************************************************************************
2 *
3 * Module Name: rsinfo - Dispatch and Info tables
4 *
5 ******************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46#include <acpi/acresrc.h>
47
48#define _COMPONENT ACPI_RESOURCES
49ACPI_MODULE_NAME("rsinfo")
50
51/*
52 * Resource dispatch and information tables. Any new resource types (either
53 * Large or Small) must be reflected in each of these tables, so they are here
54 * in one place.
55 *
56 * The tables for Large descriptors are indexed by bits 6:0 of the AML
57 * descriptor type byte. The tables for Small descriptors are indexed by
58 * bits 6:3 of the descriptor byte. The tables for internal resource
59 * descriptors are indexed by the acpi_resource_type field.
60 */
61/* Dispatch table for resource-to-AML (Set Resource) conversion functions */
62struct acpi_rsconvert_info *acpi_gbl_set_resource_dispatch[] = {
63 acpi_rs_set_irq, /* 0x00, ACPI_RESOURCE_TYPE_IRQ */
64 acpi_rs_convert_dma, /* 0x01, ACPI_RESOURCE_TYPE_DMA */
65 acpi_rs_set_start_dpf, /* 0x02, ACPI_RESOURCE_TYPE_START_DEPENDENT */
66 acpi_rs_convert_end_dpf, /* 0x03, ACPI_RESOURCE_TYPE_END_DEPENDENT */
67 acpi_rs_convert_io, /* 0x04, ACPI_RESOURCE_TYPE_IO */
68 acpi_rs_convert_fixed_io, /* 0x05, ACPI_RESOURCE_TYPE_FIXED_IO */
69 acpi_rs_set_vendor, /* 0x06, ACPI_RESOURCE_TYPE_VENDOR */
70 acpi_rs_convert_end_tag, /* 0x07, ACPI_RESOURCE_TYPE_END_TAG */
71 acpi_rs_convert_memory24, /* 0x08, ACPI_RESOURCE_TYPE_MEMORY24 */
72 acpi_rs_convert_memory32, /* 0x09, ACPI_RESOURCE_TYPE_MEMORY32 */
73 acpi_rs_convert_fixed_memory32, /* 0x0A, ACPI_RESOURCE_TYPE_FIXED_MEMORY32 */
74 acpi_rs_convert_address16, /* 0x0B, ACPI_RESOURCE_TYPE_ADDRESS16 */
75 acpi_rs_convert_address32, /* 0x0C, ACPI_RESOURCE_TYPE_ADDRESS32 */
76 acpi_rs_convert_address64, /* 0x0D, ACPI_RESOURCE_TYPE_ADDRESS64 */
77 acpi_rs_convert_ext_address64, /* 0x0E, ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64 */
78 acpi_rs_convert_ext_irq, /* 0x0F, ACPI_RESOURCE_TYPE_EXTENDED_IRQ */
79 acpi_rs_convert_generic_reg /* 0x10, ACPI_RESOURCE_TYPE_GENERIC_REGISTER */
80};
81
82/* Dispatch tables for AML-to-resource (Get Resource) conversion functions */
83
84struct acpi_rsconvert_info *acpi_gbl_get_resource_dispatch[] = {
85 /* Small descriptors */
86
87 NULL, /* 0x00, Reserved */
88 NULL, /* 0x01, Reserved */
89 NULL, /* 0x02, Reserved */
90 NULL, /* 0x03, Reserved */
91 acpi_rs_get_irq, /* 0x04, ACPI_RESOURCE_NAME_IRQ */
92 acpi_rs_convert_dma, /* 0x05, ACPI_RESOURCE_NAME_DMA */
93 acpi_rs_get_start_dpf, /* 0x06, ACPI_RESOURCE_NAME_START_DEPENDENT */
94 acpi_rs_convert_end_dpf, /* 0x07, ACPI_RESOURCE_NAME_END_DEPENDENT */
95 acpi_rs_convert_io, /* 0x08, ACPI_RESOURCE_NAME_IO */
96 acpi_rs_convert_fixed_io, /* 0x09, ACPI_RESOURCE_NAME_FIXED_IO */
97 NULL, /* 0x0A, Reserved */
98 NULL, /* 0x0B, Reserved */
99 NULL, /* 0x0C, Reserved */
100 NULL, /* 0x0D, Reserved */
101 acpi_rs_get_vendor_small, /* 0x0E, ACPI_RESOURCE_NAME_VENDOR_SMALL */
102 acpi_rs_convert_end_tag, /* 0x0F, ACPI_RESOURCE_NAME_END_TAG */
103
104 /* Large descriptors */
105
106 NULL, /* 0x00, Reserved */
107 acpi_rs_convert_memory24, /* 0x01, ACPI_RESOURCE_NAME_MEMORY24 */
108 acpi_rs_convert_generic_reg, /* 0x02, ACPI_RESOURCE_NAME_GENERIC_REGISTER */
109 NULL, /* 0x03, Reserved */
110 acpi_rs_get_vendor_large, /* 0x04, ACPI_RESOURCE_NAME_VENDOR_LARGE */
111 acpi_rs_convert_memory32, /* 0x05, ACPI_RESOURCE_NAME_MEMORY32 */
112 acpi_rs_convert_fixed_memory32, /* 0x06, ACPI_RESOURCE_NAME_FIXED_MEMORY32 */
113 acpi_rs_convert_address32, /* 0x07, ACPI_RESOURCE_NAME_ADDRESS32 */
114 acpi_rs_convert_address16, /* 0x08, ACPI_RESOURCE_NAME_ADDRESS16 */
115 acpi_rs_convert_ext_irq, /* 0x09, ACPI_RESOURCE_NAME_EXTENDED_IRQ */
116 acpi_rs_convert_address64, /* 0x0A, ACPI_RESOURCE_NAME_ADDRESS64 */
117 acpi_rs_convert_ext_address64 /* 0x0B, ACPI_RESOURCE_NAME_EXTENDED_ADDRESS64 */
118};
119
120#ifdef ACPI_FUTURE_USAGE
121#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
122
123/* Dispatch table for resource dump functions */
124
125struct acpi_rsdump_info *acpi_gbl_dump_resource_dispatch[] = {
126 acpi_rs_dump_irq, /* ACPI_RESOURCE_TYPE_IRQ */
127 acpi_rs_dump_dma, /* ACPI_RESOURCE_TYPE_DMA */
128 acpi_rs_dump_start_dpf, /* ACPI_RESOURCE_TYPE_START_DEPENDENT */
129 acpi_rs_dump_end_dpf, /* ACPI_RESOURCE_TYPE_END_DEPENDENT */
130 acpi_rs_dump_io, /* ACPI_RESOURCE_TYPE_IO */
131 acpi_rs_dump_fixed_io, /* ACPI_RESOURCE_TYPE_FIXED_IO */
132 acpi_rs_dump_vendor, /* ACPI_RESOURCE_TYPE_VENDOR */
133 acpi_rs_dump_end_tag, /* ACPI_RESOURCE_TYPE_END_TAG */
134 acpi_rs_dump_memory24, /* ACPI_RESOURCE_TYPE_MEMORY24 */
135 acpi_rs_dump_memory32, /* ACPI_RESOURCE_TYPE_MEMORY32 */
136 acpi_rs_dump_fixed_memory32, /* ACPI_RESOURCE_TYPE_FIXED_MEMORY32 */
137 acpi_rs_dump_address16, /* ACPI_RESOURCE_TYPE_ADDRESS16 */
138 acpi_rs_dump_address32, /* ACPI_RESOURCE_TYPE_ADDRESS32 */
139 acpi_rs_dump_address64, /* ACPI_RESOURCE_TYPE_ADDRESS64 */
140 acpi_rs_dump_ext_address64, /* ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64 */
141 acpi_rs_dump_ext_irq, /* ACPI_RESOURCE_TYPE_EXTENDED_IRQ */
142 acpi_rs_dump_generic_reg, /* ACPI_RESOURCE_TYPE_GENERIC_REGISTER */
143};
144#endif
145
146#endif /* ACPI_FUTURE_USAGE */
147/*
148 * Base sizes for external AML resource descriptors, indexed by internal type.
149 * Includes size of the descriptor header (1 byte for small descriptors,
150 * 3 bytes for large descriptors)
151 */
152const u8 acpi_gbl_aml_resource_sizes[] = {
153 sizeof(struct aml_resource_irq), /* ACPI_RESOURCE_TYPE_IRQ (optional Byte 3 always created) */
154 sizeof(struct aml_resource_dma), /* ACPI_RESOURCE_TYPE_DMA */
155 sizeof(struct aml_resource_start_dependent), /* ACPI_RESOURCE_TYPE_START_DEPENDENT (optional Byte 1 always created) */
156 sizeof(struct aml_resource_end_dependent), /* ACPI_RESOURCE_TYPE_END_DEPENDENT */
157 sizeof(struct aml_resource_io), /* ACPI_RESOURCE_TYPE_IO */
158 sizeof(struct aml_resource_fixed_io), /* ACPI_RESOURCE_TYPE_FIXED_IO */
159 sizeof(struct aml_resource_vendor_small), /* ACPI_RESOURCE_TYPE_VENDOR */
160 sizeof(struct aml_resource_end_tag), /* ACPI_RESOURCE_TYPE_END_TAG */
161 sizeof(struct aml_resource_memory24), /* ACPI_RESOURCE_TYPE_MEMORY24 */
162 sizeof(struct aml_resource_memory32), /* ACPI_RESOURCE_TYPE_MEMORY32 */
163 sizeof(struct aml_resource_fixed_memory32), /* ACPI_RESOURCE_TYPE_FIXED_MEMORY32 */
164 sizeof(struct aml_resource_address16), /* ACPI_RESOURCE_TYPE_ADDRESS16 */
165 sizeof(struct aml_resource_address32), /* ACPI_RESOURCE_TYPE_ADDRESS32 */
166 sizeof(struct aml_resource_address64), /* ACPI_RESOURCE_TYPE_ADDRESS64 */
167 sizeof(struct aml_resource_extended_address64), /*ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64 */
168 sizeof(struct aml_resource_extended_irq), /* ACPI_RESOURCE_TYPE_EXTENDED_IRQ */
169 sizeof(struct aml_resource_generic_register) /* ACPI_RESOURCE_TYPE_GENERIC_REGISTER */
170};
171
172const u8 acpi_gbl_resource_struct_sizes[] = {
173 /* Small descriptors */
174
175 0,
176 0,
177 0,
178 0,
179 ACPI_RS_SIZE(struct acpi_resource_irq),
180 ACPI_RS_SIZE(struct acpi_resource_dma),
181 ACPI_RS_SIZE(struct acpi_resource_start_dependent),
182 ACPI_RS_SIZE_MIN,
183 ACPI_RS_SIZE(struct acpi_resource_io),
184 ACPI_RS_SIZE(struct acpi_resource_fixed_io),
185 0,
186 0,
187 0,
188 0,
189 ACPI_RS_SIZE(struct acpi_resource_vendor),
190 ACPI_RS_SIZE_MIN,
191
192 /* Large descriptors */
193
194 0,
195 ACPI_RS_SIZE(struct acpi_resource_memory24),
196 ACPI_RS_SIZE(struct acpi_resource_generic_register),
197 0,
198 ACPI_RS_SIZE(struct acpi_resource_vendor),
199 ACPI_RS_SIZE(struct acpi_resource_memory32),
200 ACPI_RS_SIZE(struct acpi_resource_fixed_memory32),
201 ACPI_RS_SIZE(struct acpi_resource_address32),
202 ACPI_RS_SIZE(struct acpi_resource_address16),
203 ACPI_RS_SIZE(struct acpi_resource_extended_irq),
204 ACPI_RS_SIZE(struct acpi_resource_address64),
205 ACPI_RS_SIZE(struct acpi_resource_extended_address64)
206};
diff --git a/drivers/acpi/acpica/rsio.c b/drivers/acpi/acpica/rsio.c
new file mode 100644
index 00000000000..d31129aca40
--- /dev/null
+++ b/drivers/acpi/acpica/rsio.c
@@ -0,0 +1,290 @@
1/*******************************************************************************
2 *
3 * Module Name: rsio - IO and DMA resource descriptors
4 *
5 ******************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46#include <acpi/acresrc.h>
47
48#define _COMPONENT ACPI_RESOURCES
49ACPI_MODULE_NAME("rsio")
50
51/*******************************************************************************
52 *
53 * acpi_rs_convert_io
54 *
55 ******************************************************************************/
56struct acpi_rsconvert_info acpi_rs_convert_io[5] = {
57 {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_IO,
58 ACPI_RS_SIZE(struct acpi_resource_io),
59 ACPI_RSC_TABLE_SIZE(acpi_rs_convert_io)},
60
61 {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_IO,
62 sizeof(struct aml_resource_io),
63 0},
64
65 /* Decode flag */
66
67 {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.io.io_decode),
68 AML_OFFSET(io.flags),
69 0},
70 /*
71 * These fields are contiguous in both the source and destination:
72 * Address Alignment
73 * Length
74 * Minimum Base Address
75 * Maximum Base Address
76 */
77 {ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.io.alignment),
78 AML_OFFSET(io.alignment),
79 2},
80
81 {ACPI_RSC_MOVE16, ACPI_RS_OFFSET(data.io.minimum),
82 AML_OFFSET(io.minimum),
83 2}
84};
85
86/*******************************************************************************
87 *
88 * acpi_rs_convert_fixed_io
89 *
90 ******************************************************************************/
91
92struct acpi_rsconvert_info acpi_rs_convert_fixed_io[4] = {
93 {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_FIXED_IO,
94 ACPI_RS_SIZE(struct acpi_resource_fixed_io),
95 ACPI_RSC_TABLE_SIZE(acpi_rs_convert_fixed_io)},
96
97 {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_FIXED_IO,
98 sizeof(struct aml_resource_fixed_io),
99 0},
100 /*
101 * These fields are contiguous in both the source and destination:
102 * Base Address
103 * Length
104 */
105 {ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.fixed_io.address_length),
106 AML_OFFSET(fixed_io.address_length),
107 1},
108
109 {ACPI_RSC_MOVE16, ACPI_RS_OFFSET(data.fixed_io.address),
110 AML_OFFSET(fixed_io.address),
111 1}
112};
113
114/*******************************************************************************
115 *
116 * acpi_rs_convert_generic_reg
117 *
118 ******************************************************************************/
119
120struct acpi_rsconvert_info acpi_rs_convert_generic_reg[4] = {
121 {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_GENERIC_REGISTER,
122 ACPI_RS_SIZE(struct acpi_resource_generic_register),
123 ACPI_RSC_TABLE_SIZE(acpi_rs_convert_generic_reg)},
124
125 {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_GENERIC_REGISTER,
126 sizeof(struct aml_resource_generic_register),
127 0},
128 /*
129 * These fields are contiguous in both the source and destination:
130 * Address Space ID
131 * Register Bit Width
132 * Register Bit Offset
133 * Access Size
134 */
135 {ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.generic_reg.space_id),
136 AML_OFFSET(generic_reg.address_space_id),
137 4},
138
139 /* Get the Register Address */
140
141 {ACPI_RSC_MOVE64, ACPI_RS_OFFSET(data.generic_reg.address),
142 AML_OFFSET(generic_reg.address),
143 1}
144};
145
146/*******************************************************************************
147 *
148 * acpi_rs_convert_end_dpf
149 *
150 ******************************************************************************/
151
152struct acpi_rsconvert_info acpi_rs_convert_end_dpf[2] = {
153 {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_END_DEPENDENT,
154 ACPI_RS_SIZE_MIN,
155 ACPI_RSC_TABLE_SIZE(acpi_rs_convert_end_dpf)},
156
157 {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_END_DEPENDENT,
158 sizeof(struct aml_resource_end_dependent),
159 0}
160};
161
162/*******************************************************************************
163 *
164 * acpi_rs_convert_end_tag
165 *
166 ******************************************************************************/
167
168struct acpi_rsconvert_info acpi_rs_convert_end_tag[2] = {
169 {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_END_TAG,
170 ACPI_RS_SIZE_MIN,
171 ACPI_RSC_TABLE_SIZE(acpi_rs_convert_end_tag)},
172
173 /*
174 * Note: The checksum field is set to zero, meaning that the resource
175 * data is treated as if the checksum operation succeeded.
176 * (ACPI Spec 1.0b Section 6.4.2.8)
177 */
178 {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_END_TAG,
179 sizeof(struct aml_resource_end_tag),
180 0}
181};
182
183/*******************************************************************************
184 *
185 * acpi_rs_get_start_dpf
186 *
187 ******************************************************************************/
188
189struct acpi_rsconvert_info acpi_rs_get_start_dpf[6] = {
190 {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_START_DEPENDENT,
191 ACPI_RS_SIZE(struct acpi_resource_start_dependent),
192 ACPI_RSC_TABLE_SIZE(acpi_rs_get_start_dpf)},
193
194 /* Defaults for Compatibility and Performance priorities */
195
196 {ACPI_RSC_SET8, ACPI_RS_OFFSET(data.start_dpf.compatibility_priority),
197 ACPI_ACCEPTABLE_CONFIGURATION,
198 2},
199
200 /* Get the descriptor length (0 or 1 for Start Dpf descriptor) */
201
202 {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.start_dpf.descriptor_length),
203 AML_OFFSET(start_dpf.descriptor_type),
204 0},
205
206 /* All done if there is no flag byte present in the descriptor */
207
208 {ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_AML_LENGTH, 0, 1},
209
210 /* Flag byte is present, get the flags */
211
212 {ACPI_RSC_2BITFLAG,
213 ACPI_RS_OFFSET(data.start_dpf.compatibility_priority),
214 AML_OFFSET(start_dpf.flags),
215 0},
216
217 {ACPI_RSC_2BITFLAG,
218 ACPI_RS_OFFSET(data.start_dpf.performance_robustness),
219 AML_OFFSET(start_dpf.flags),
220 2}
221};
222
223/*******************************************************************************
224 *
225 * acpi_rs_set_start_dpf
226 *
227 ******************************************************************************/
228
229struct acpi_rsconvert_info acpi_rs_set_start_dpf[10] = {
230 /* Start with a default descriptor of length 1 */
231
232 {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_START_DEPENDENT,
233 sizeof(struct aml_resource_start_dependent),
234 ACPI_RSC_TABLE_SIZE(acpi_rs_set_start_dpf)},
235
236 /* Set the default flag values */
237
238 {ACPI_RSC_2BITFLAG,
239 ACPI_RS_OFFSET(data.start_dpf.compatibility_priority),
240 AML_OFFSET(start_dpf.flags),
241 0},
242
243 {ACPI_RSC_2BITFLAG,
244 ACPI_RS_OFFSET(data.start_dpf.performance_robustness),
245 AML_OFFSET(start_dpf.flags),
246 2},
247 /*
248 * All done if the output descriptor length is required to be 1
249 * (i.e., optimization to 0 bytes cannot be attempted)
250 */
251 {ACPI_RSC_EXIT_EQ, ACPI_RSC_COMPARE_VALUE,
252 ACPI_RS_OFFSET(data.start_dpf.descriptor_length),
253 1},
254
255 /* Set length to 0 bytes (no flags byte) */
256
257 {ACPI_RSC_LENGTH, 0, 0,
258 sizeof(struct aml_resource_start_dependent_noprio)},
259
260 /*
261 * All done if the output descriptor length is required to be 0.
262 *
263 * TBD: Perhaps we should check for error if input flags are not
264 * compatible with a 0-byte descriptor.
265 */
266 {ACPI_RSC_EXIT_EQ, ACPI_RSC_COMPARE_VALUE,
267 ACPI_RS_OFFSET(data.start_dpf.descriptor_length),
268 0},
269
270 /* Reset length to 1 byte (descriptor with flags byte) */
271
272 {ACPI_RSC_LENGTH, 0, 0, sizeof(struct aml_resource_start_dependent)},
273
274 /*
275 * All done if flags byte is necessary -- if either priority value
276 * is not ACPI_ACCEPTABLE_CONFIGURATION
277 */
278 {ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_VALUE,
279 ACPI_RS_OFFSET(data.start_dpf.compatibility_priority),
280 ACPI_ACCEPTABLE_CONFIGURATION},
281
282 {ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_VALUE,
283 ACPI_RS_OFFSET(data.start_dpf.performance_robustness),
284 ACPI_ACCEPTABLE_CONFIGURATION},
285
286 /* Flag byte is not necessary */
287
288 {ACPI_RSC_LENGTH, 0, 0,
289 sizeof(struct aml_resource_start_dependent_noprio)}
290};
diff --git a/drivers/acpi/acpica/rsirq.c b/drivers/acpi/acpica/rsirq.c
new file mode 100644
index 00000000000..9a5a08d6731
--- /dev/null
+++ b/drivers/acpi/acpica/rsirq.c
@@ -0,0 +1,266 @@
1/*******************************************************************************
2 *
3 * Module Name: rsirq - IRQ resource descriptors
4 *
5 ******************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46#include <acpi/acresrc.h>
47
48#define _COMPONENT ACPI_RESOURCES
49ACPI_MODULE_NAME("rsirq")
50
51/*******************************************************************************
52 *
53 * acpi_rs_get_irq
54 *
55 ******************************************************************************/
56struct acpi_rsconvert_info acpi_rs_get_irq[8] = {
57 {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_IRQ,
58 ACPI_RS_SIZE(struct acpi_resource_irq),
59 ACPI_RSC_TABLE_SIZE(acpi_rs_get_irq)},
60
61 /* Get the IRQ mask (bytes 1:2) */
62
63 {ACPI_RSC_BITMASK16, ACPI_RS_OFFSET(data.irq.interrupts[0]),
64 AML_OFFSET(irq.irq_mask),
65 ACPI_RS_OFFSET(data.irq.interrupt_count)},
66
67 /* Set default flags (others are zero) */
68
69 {ACPI_RSC_SET8, ACPI_RS_OFFSET(data.irq.triggering),
70 ACPI_EDGE_SENSITIVE,
71 1},
72
73 /* Get the descriptor length (2 or 3 for IRQ descriptor) */
74
75 {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET(data.irq.descriptor_length),
76 AML_OFFSET(irq.descriptor_type),
77 0},
78
79 /* All done if no flag byte present in descriptor */
80
81 {ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_AML_LENGTH, 0, 3},
82
83 /* Get flags: Triggering[0], Polarity[3], Sharing[4] */
84
85 {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.triggering),
86 AML_OFFSET(irq.flags),
87 0},
88
89 {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.polarity),
90 AML_OFFSET(irq.flags),
91 3},
92
93 {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.sharable),
94 AML_OFFSET(irq.flags),
95 4}
96};
97
98/*******************************************************************************
99 *
100 * acpi_rs_set_irq
101 *
102 ******************************************************************************/
103
104struct acpi_rsconvert_info acpi_rs_set_irq[13] = {
105 /* Start with a default descriptor of length 3 */
106
107 {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_IRQ,
108 sizeof(struct aml_resource_irq),
109 ACPI_RSC_TABLE_SIZE(acpi_rs_set_irq)},
110
111 /* Convert interrupt list to 16-bit IRQ bitmask */
112
113 {ACPI_RSC_BITMASK16, ACPI_RS_OFFSET(data.irq.interrupts[0]),
114 AML_OFFSET(irq.irq_mask),
115 ACPI_RS_OFFSET(data.irq.interrupt_count)},
116
117 /* Set the flags byte */
118
119 {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.triggering),
120 AML_OFFSET(irq.flags),
121 0},
122
123 {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.polarity),
124 AML_OFFSET(irq.flags),
125 3},
126
127 {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.sharable),
128 AML_OFFSET(irq.flags),
129 4},
130
131 /*
132 * All done if the output descriptor length is required to be 3
133 * (i.e., optimization to 2 bytes cannot be attempted)
134 */
135 {ACPI_RSC_EXIT_EQ, ACPI_RSC_COMPARE_VALUE,
136 ACPI_RS_OFFSET(data.irq.descriptor_length),
137 3},
138
139 /* Set length to 2 bytes (no flags byte) */
140
141 {ACPI_RSC_LENGTH, 0, 0, sizeof(struct aml_resource_irq_noflags)},
142
143 /*
144 * All done if the output descriptor length is required to be 2.
145 *
146 * TBD: Perhaps we should check for error if input flags are not
147 * compatible with a 2-byte descriptor.
148 */
149 {ACPI_RSC_EXIT_EQ, ACPI_RSC_COMPARE_VALUE,
150 ACPI_RS_OFFSET(data.irq.descriptor_length),
151 2},
152
153 /* Reset length to 3 bytes (descriptor with flags byte) */
154
155 {ACPI_RSC_LENGTH, 0, 0, sizeof(struct aml_resource_irq)},
156
157 /*
158 * Check if the flags byte is necessary. Not needed if the flags are:
159 * ACPI_EDGE_SENSITIVE, ACPI_ACTIVE_HIGH, ACPI_EXCLUSIVE
160 */
161 {ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_VALUE,
162 ACPI_RS_OFFSET(data.irq.triggering),
163 ACPI_EDGE_SENSITIVE},
164
165 {ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_VALUE,
166 ACPI_RS_OFFSET(data.irq.polarity),
167 ACPI_ACTIVE_HIGH},
168
169 {ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_VALUE,
170 ACPI_RS_OFFSET(data.irq.sharable),
171 ACPI_EXCLUSIVE},
172
173 /* We can optimize to a 2-byte irq_no_flags() descriptor */
174
175 {ACPI_RSC_LENGTH, 0, 0, sizeof(struct aml_resource_irq_noflags)}
176};
177
178/*******************************************************************************
179 *
180 * acpi_rs_convert_ext_irq
181 *
182 ******************************************************************************/
183
184struct acpi_rsconvert_info acpi_rs_convert_ext_irq[9] = {
185 {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_EXTENDED_IRQ,
186 ACPI_RS_SIZE(struct acpi_resource_extended_irq),
187 ACPI_RSC_TABLE_SIZE(acpi_rs_convert_ext_irq)},
188
189 {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_EXTENDED_IRQ,
190 sizeof(struct aml_resource_extended_irq),
191 0},
192
193 /* Flag bits */
194
195 {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.extended_irq.producer_consumer),
196 AML_OFFSET(extended_irq.flags),
197 0},
198
199 {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.extended_irq.triggering),
200 AML_OFFSET(extended_irq.flags),
201 1},
202
203 {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.extended_irq.polarity),
204 AML_OFFSET(extended_irq.flags),
205 2},
206
207 {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.extended_irq.sharable),
208 AML_OFFSET(extended_irq.flags),
209 3},
210
211 /* IRQ Table length (Byte4) */
212
213 {ACPI_RSC_COUNT, ACPI_RS_OFFSET(data.extended_irq.interrupt_count),
214 AML_OFFSET(extended_irq.interrupt_count),
215 sizeof(u32)}
216 ,
217
218 /* Copy every IRQ in the table, each is 32 bits */
219
220 {ACPI_RSC_MOVE32, ACPI_RS_OFFSET(data.extended_irq.interrupts[0]),
221 AML_OFFSET(extended_irq.interrupts[0]),
222 0}
223 ,
224
225 /* Optional resource_source (Index and String) */
226
227 {ACPI_RSC_SOURCEX, ACPI_RS_OFFSET(data.extended_irq.resource_source),
228 ACPI_RS_OFFSET(data.extended_irq.interrupts[0]),
229 sizeof(struct aml_resource_extended_irq)}
230};
231
232/*******************************************************************************
233 *
234 * acpi_rs_convert_dma
235 *
236 ******************************************************************************/
237
238struct acpi_rsconvert_info acpi_rs_convert_dma[6] = {
239 {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_DMA,
240 ACPI_RS_SIZE(struct acpi_resource_dma),
241 ACPI_RSC_TABLE_SIZE(acpi_rs_convert_dma)},
242
243 {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_DMA,
244 sizeof(struct aml_resource_dma),
245 0},
246
247 /* Flags: transfer preference, bus mastering, channel speed */
248
249 {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET(data.dma.transfer),
250 AML_OFFSET(dma.flags),
251 0},
252
253 {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.dma.bus_master),
254 AML_OFFSET(dma.flags),
255 2},
256
257 {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET(data.dma.type),
258 AML_OFFSET(dma.flags),
259 5},
260
261 /* DMA channel mask bits */
262
263 {ACPI_RSC_BITMASK, ACPI_RS_OFFSET(data.dma.channels[0]),
264 AML_OFFSET(dma.dma_channel_mask),
265 ACPI_RS_OFFSET(data.dma.channel_count)}
266};
diff --git a/drivers/acpi/acpica/rslist.c b/drivers/acpi/acpica/rslist.c
new file mode 100644
index 00000000000..483389871a5
--- /dev/null
+++ b/drivers/acpi/acpica/rslist.c
@@ -0,0 +1,203 @@
1/*******************************************************************************
2 *
3 * Module Name: rslist - Linked list utilities
4 *
5 ******************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46#include <acpi/acresrc.h>
47
48#define _COMPONENT ACPI_RESOURCES
49ACPI_MODULE_NAME("rslist")
50
51/*******************************************************************************
52 *
53 * FUNCTION: acpi_rs_convert_aml_to_resources
54 *
55 * PARAMETERS: acpi_walk_aml_callback
56 * resource_ptr - Pointer to the buffer that will
57 * contain the output structures
58 *
59 * RETURN: Status
60 *
61 * DESCRIPTION: Convert an AML resource to an internal representation of the
62 * resource that is aligned and easier to access.
63 *
64 ******************************************************************************/
65acpi_status
66acpi_rs_convert_aml_to_resources(u8 * aml,
67 u32 length,
68 u32 offset, u8 resource_index, void **context)
69{
70 struct acpi_resource **resource_ptr =
71 ACPI_CAST_INDIRECT_PTR(struct acpi_resource, context);
72 struct acpi_resource *resource;
73 acpi_status status;
74
75 ACPI_FUNCTION_TRACE(rs_convert_aml_to_resources);
76
77 /*
78 * Check that the input buffer and all subsequent pointers into it
79 * are aligned on a native word boundary. Most important on IA64
80 */
81 resource = *resource_ptr;
82 if (ACPI_IS_MISALIGNED(resource)) {
83 ACPI_WARNING((AE_INFO,
84 "Misaligned resource pointer %p", resource));
85 }
86
87 /* Convert the AML byte stream resource to a local resource struct */
88
89 status =
90 acpi_rs_convert_aml_to_resource(resource,
91 ACPI_CAST_PTR(union aml_resource,
92 aml),
93 acpi_gbl_get_resource_dispatch
94 [resource_index]);
95 if (ACPI_FAILURE(status)) {
96 ACPI_EXCEPTION((AE_INFO, status,
97 "Could not convert AML resource (Type %X)",
98 *aml));
99 return_ACPI_STATUS(status);
100 }
101
102 ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
103 "Type %.2X, AmlLength %.2X InternalLength %.2X\n",
104 acpi_ut_get_resource_type(aml), length,
105 resource->length));
106
107 /* Point to the next structure in the output buffer */
108
109 *resource_ptr = ACPI_ADD_PTR(void, resource, resource->length);
110 return_ACPI_STATUS(AE_OK);
111}
112
113/*******************************************************************************
114 *
115 * FUNCTION: acpi_rs_convert_resources_to_aml
116 *
117 * PARAMETERS: Resource - Pointer to the resource linked list
118 * aml_size_needed - Calculated size of the byte stream
119 * needed from calling acpi_rs_get_aml_length()
120 * The size of the output_buffer is
121 * guaranteed to be >= aml_size_needed
122 * output_buffer - Pointer to the buffer that will
123 * contain the byte stream
124 *
125 * RETURN: Status
126 *
127 * DESCRIPTION: Takes the resource linked list and parses it, creating a
128 * byte stream of resources in the caller's output buffer
129 *
130 ******************************************************************************/
131
132acpi_status
133acpi_rs_convert_resources_to_aml(struct acpi_resource *resource,
134 acpi_size aml_size_needed, u8 * output_buffer)
135{
136 u8 *aml = output_buffer;
137 u8 *end_aml = output_buffer + aml_size_needed;
138 acpi_status status;
139
140 ACPI_FUNCTION_TRACE(rs_convert_resources_to_aml);
141
142 /* Walk the resource descriptor list, convert each descriptor */
143
144 while (aml < end_aml) {
145
146 /* Validate the (internal) Resource Type */
147
148 if (resource->type > ACPI_RESOURCE_TYPE_MAX) {
149 ACPI_ERROR((AE_INFO,
150 "Invalid descriptor type (%X) in resource list",
151 resource->type));
152 return_ACPI_STATUS(AE_BAD_DATA);
153 }
154
155 /* Perform the conversion */
156
157 status = acpi_rs_convert_resource_to_aml(resource, ACPI_CAST_PTR(union
158 aml_resource,
159 aml),
160 acpi_gbl_set_resource_dispatch
161 [resource->type]);
162 if (ACPI_FAILURE(status)) {
163 ACPI_EXCEPTION((AE_INFO, status,
164 "Could not convert resource (type %X) to AML",
165 resource->type));
166 return_ACPI_STATUS(status);
167 }
168
169 /* Perform final sanity check on the new AML resource descriptor */
170
171 status =
172 acpi_ut_validate_resource(ACPI_CAST_PTR
173 (union aml_resource, aml), NULL);
174 if (ACPI_FAILURE(status)) {
175 return_ACPI_STATUS(status);
176 }
177
178 /* Check for end-of-list, normal exit */
179
180 if (resource->type == ACPI_RESOURCE_TYPE_END_TAG) {
181
182 /* An End Tag indicates the end of the input Resource Template */
183
184 return_ACPI_STATUS(AE_OK);
185 }
186
187 /*
188 * Extract the total length of the new descriptor and set the
189 * Aml to point to the next (output) resource descriptor
190 */
191 aml += acpi_ut_get_descriptor_length(aml);
192
193 /* Point to the next input resource descriptor */
194
195 resource =
196 ACPI_ADD_PTR(struct acpi_resource, resource,
197 resource->length);
198 }
199
200 /* Completed buffer, but did not find an end_tag resource descriptor */
201
202 return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG);
203}
diff --git a/drivers/acpi/acpica/rsmemory.c b/drivers/acpi/acpica/rsmemory.c
new file mode 100644
index 00000000000..5fd3746cca5
--- /dev/null
+++ b/drivers/acpi/acpica/rsmemory.c
@@ -0,0 +1,236 @@
1/*******************************************************************************
2 *
3 * Module Name: rsmem24 - Memory resource descriptors
4 *
5 ******************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46#include <acpi/acresrc.h>
47
48#define _COMPONENT ACPI_RESOURCES
49ACPI_MODULE_NAME("rsmemory")
50
51/*******************************************************************************
52 *
53 * acpi_rs_convert_memory24
54 *
55 ******************************************************************************/
56struct acpi_rsconvert_info acpi_rs_convert_memory24[4] = {
57 {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_MEMORY24,
58 ACPI_RS_SIZE(struct acpi_resource_memory24),
59 ACPI_RSC_TABLE_SIZE(acpi_rs_convert_memory24)},
60
61 {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_MEMORY24,
62 sizeof(struct aml_resource_memory24),
63 0},
64
65 /* Read/Write bit */
66
67 {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.memory24.write_protect),
68 AML_OFFSET(memory24.flags),
69 0},
70 /*
71 * These fields are contiguous in both the source and destination:
72 * Minimum Base Address
73 * Maximum Base Address
74 * Address Base Alignment
75 * Range Length
76 */
77 {ACPI_RSC_MOVE16, ACPI_RS_OFFSET(data.memory24.minimum),
78 AML_OFFSET(memory24.minimum),
79 4}
80};
81
82/*******************************************************************************
83 *
84 * acpi_rs_convert_memory32
85 *
86 ******************************************************************************/
87
88struct acpi_rsconvert_info acpi_rs_convert_memory32[4] = {
89 {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_MEMORY32,
90 ACPI_RS_SIZE(struct acpi_resource_memory32),
91 ACPI_RSC_TABLE_SIZE(acpi_rs_convert_memory32)},
92
93 {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_MEMORY32,
94 sizeof(struct aml_resource_memory32),
95 0},
96
97 /* Read/Write bit */
98
99 {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.memory32.write_protect),
100 AML_OFFSET(memory32.flags),
101 0},
102 /*
103 * These fields are contiguous in both the source and destination:
104 * Minimum Base Address
105 * Maximum Base Address
106 * Address Base Alignment
107 * Range Length
108 */
109 {ACPI_RSC_MOVE32, ACPI_RS_OFFSET(data.memory32.minimum),
110 AML_OFFSET(memory32.minimum),
111 4}
112};
113
114/*******************************************************************************
115 *
116 * acpi_rs_convert_fixed_memory32
117 *
118 ******************************************************************************/
119
120struct acpi_rsconvert_info acpi_rs_convert_fixed_memory32[4] = {
121 {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_FIXED_MEMORY32,
122 ACPI_RS_SIZE(struct acpi_resource_fixed_memory32),
123 ACPI_RSC_TABLE_SIZE(acpi_rs_convert_fixed_memory32)},
124
125 {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_FIXED_MEMORY32,
126 sizeof(struct aml_resource_fixed_memory32),
127 0},
128
129 /* Read/Write bit */
130
131 {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.fixed_memory32.write_protect),
132 AML_OFFSET(fixed_memory32.flags),
133 0},
134 /*
135 * These fields are contiguous in both the source and destination:
136 * Base Address
137 * Range Length
138 */
139 {ACPI_RSC_MOVE32, ACPI_RS_OFFSET(data.fixed_memory32.address),
140 AML_OFFSET(fixed_memory32.address),
141 2}
142};
143
144/*******************************************************************************
145 *
146 * acpi_rs_get_vendor_small
147 *
148 ******************************************************************************/
149
150struct acpi_rsconvert_info acpi_rs_get_vendor_small[3] = {
151 {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_VENDOR,
152 ACPI_RS_SIZE(struct acpi_resource_vendor),
153 ACPI_RSC_TABLE_SIZE(acpi_rs_get_vendor_small)},
154
155 /* Length of the vendor data (byte count) */
156
157 {ACPI_RSC_COUNT16, ACPI_RS_OFFSET(data.vendor.byte_length),
158 0,
159 sizeof(u8)}
160 ,
161
162 /* Vendor data */
163
164 {ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.vendor.byte_data[0]),
165 sizeof(struct aml_resource_small_header),
166 0}
167};
168
169/*******************************************************************************
170 *
171 * acpi_rs_get_vendor_large
172 *
173 ******************************************************************************/
174
175struct acpi_rsconvert_info acpi_rs_get_vendor_large[3] = {
176 {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_VENDOR,
177 ACPI_RS_SIZE(struct acpi_resource_vendor),
178 ACPI_RSC_TABLE_SIZE(acpi_rs_get_vendor_large)},
179
180 /* Length of the vendor data (byte count) */
181
182 {ACPI_RSC_COUNT16, ACPI_RS_OFFSET(data.vendor.byte_length),
183 0,
184 sizeof(u8)}
185 ,
186
187 /* Vendor data */
188
189 {ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.vendor.byte_data[0]),
190 sizeof(struct aml_resource_large_header),
191 0}
192};
193
194/*******************************************************************************
195 *
196 * acpi_rs_set_vendor
197 *
198 ******************************************************************************/
199
200struct acpi_rsconvert_info acpi_rs_set_vendor[7] = {
201 /* Default is a small vendor descriptor */
202
203 {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_VENDOR_SMALL,
204 sizeof(struct aml_resource_small_header),
205 ACPI_RSC_TABLE_SIZE(acpi_rs_set_vendor)},
206
207 /* Get the length and copy the data */
208
209 {ACPI_RSC_COUNT16, ACPI_RS_OFFSET(data.vendor.byte_length),
210 0,
211 0},
212
213 {ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.vendor.byte_data[0]),
214 sizeof(struct aml_resource_small_header),
215 0},
216
217 /*
218 * All done if the Vendor byte length is 7 or less, meaning that it will
219 * fit within a small descriptor
220 */
221 {ACPI_RSC_EXIT_LE, 0, 0, 7},
222
223 /* Must create a large vendor descriptor */
224
225 {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_VENDOR_LARGE,
226 sizeof(struct aml_resource_large_header),
227 0},
228
229 {ACPI_RSC_COUNT16, ACPI_RS_OFFSET(data.vendor.byte_length),
230 0,
231 0},
232
233 {ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.vendor.byte_data[0]),
234 sizeof(struct aml_resource_large_header),
235 0}
236};
diff --git a/drivers/acpi/acpica/rsmisc.c b/drivers/acpi/acpica/rsmisc.c
new file mode 100644
index 00000000000..2cd6e8cfaba
--- /dev/null
+++ b/drivers/acpi/acpica/rsmisc.c
@@ -0,0 +1,561 @@
1/*******************************************************************************
2 *
3 * Module Name: rsmisc - Miscellaneous resource descriptors
4 *
5 ******************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46#include <acpi/acresrc.h>
47
48#define _COMPONENT ACPI_RESOURCES
49ACPI_MODULE_NAME("rsmisc")
50#define INIT_RESOURCE_TYPE(i) i->resource_offset
51#define INIT_RESOURCE_LENGTH(i) i->aml_offset
52#define INIT_TABLE_LENGTH(i) i->value
53#define COMPARE_OPCODE(i) i->resource_offset
54#define COMPARE_TARGET(i) i->aml_offset
55#define COMPARE_VALUE(i) i->value
56/*******************************************************************************
57 *
58 * FUNCTION: acpi_rs_convert_aml_to_resource
59 *
60 * PARAMETERS: Resource - Pointer to the resource descriptor
61 * Aml - Where the AML descriptor is returned
62 * Info - Pointer to appropriate conversion table
63 *
64 * RETURN: Status
65 *
66 * DESCRIPTION: Convert an external AML resource descriptor to the corresponding
67 * internal resource descriptor
68 *
69 ******************************************************************************/
70acpi_status
71acpi_rs_convert_aml_to_resource(struct acpi_resource *resource,
72 union aml_resource *aml,
73 struct acpi_rsconvert_info *info)
74{
75 acpi_rs_length aml_resource_length;
76 void *source;
77 void *destination;
78 char *target;
79 u8 count;
80 u8 flags_mode = FALSE;
81 u16 item_count = 0;
82 u16 temp16 = 0;
83
84 ACPI_FUNCTION_TRACE(rs_convert_aml_to_resource);
85
86 if (((acpi_size) resource) & 0x3) {
87
88 /* Each internal resource struct is expected to be 32-bit aligned */
89
90 ACPI_WARNING((AE_INFO,
91 "Misaligned resource pointer (get): %p Type %2.2X Len %X",
92 resource, resource->type, resource->length));
93 }
94
95 /* Extract the resource Length field (does not include header length) */
96
97 aml_resource_length = acpi_ut_get_resource_length(aml);
98
99 /*
100 * First table entry must be ACPI_RSC_INITxxx and must contain the
101 * table length (# of table entries)
102 */
103 count = INIT_TABLE_LENGTH(info);
104
105 while (count) {
106 /*
107 * Source is the external AML byte stream buffer,
108 * destination is the internal resource descriptor
109 */
110 source = ACPI_ADD_PTR(void, aml, info->aml_offset);
111 destination =
112 ACPI_ADD_PTR(void, resource, info->resource_offset);
113
114 switch (info->opcode) {
115 case ACPI_RSC_INITGET:
116 /*
117 * Get the resource type and the initial (minimum) length
118 */
119 ACPI_MEMSET(resource, 0, INIT_RESOURCE_LENGTH(info));
120 resource->type = INIT_RESOURCE_TYPE(info);
121 resource->length = INIT_RESOURCE_LENGTH(info);
122 break;
123
124 case ACPI_RSC_INITSET:
125 break;
126
127 case ACPI_RSC_FLAGINIT:
128
129 flags_mode = TRUE;
130 break;
131
132 case ACPI_RSC_1BITFLAG:
133 /*
134 * Mask and shift the flag bit
135 */
136 ACPI_SET8(destination) = (u8)
137 ((ACPI_GET8(source) >> info->value) & 0x01);
138 break;
139
140 case ACPI_RSC_2BITFLAG:
141 /*
142 * Mask and shift the flag bits
143 */
144 ACPI_SET8(destination) = (u8)
145 ((ACPI_GET8(source) >> info->value) & 0x03);
146 break;
147
148 case ACPI_RSC_COUNT:
149
150 item_count = ACPI_GET8(source);
151 ACPI_SET8(destination) = (u8) item_count;
152
153 resource->length = resource->length +
154 (info->value * (item_count - 1));
155 break;
156
157 case ACPI_RSC_COUNT16:
158
159 item_count = aml_resource_length;
160 ACPI_SET16(destination) = item_count;
161
162 resource->length = resource->length +
163 (info->value * (item_count - 1));
164 break;
165
166 case ACPI_RSC_LENGTH:
167
168 resource->length = resource->length + info->value;
169 break;
170
171 case ACPI_RSC_MOVE8:
172 case ACPI_RSC_MOVE16:
173 case ACPI_RSC_MOVE32:
174 case ACPI_RSC_MOVE64:
175 /*
176 * Raw data move. Use the Info value field unless item_count has
177 * been previously initialized via a COUNT opcode
178 */
179 if (info->value) {
180 item_count = info->value;
181 }
182 acpi_rs_move_data(destination, source, item_count,
183 info->opcode);
184 break;
185
186 case ACPI_RSC_SET8:
187
188 ACPI_MEMSET(destination, info->aml_offset, info->value);
189 break;
190
191 case ACPI_RSC_DATA8:
192
193 target = ACPI_ADD_PTR(char, resource, info->value);
194 ACPI_MEMCPY(destination, source, ACPI_GET16(target));
195 break;
196
197 case ACPI_RSC_ADDRESS:
198 /*
199 * Common handler for address descriptor flags
200 */
201 if (!acpi_rs_get_address_common(resource, aml)) {
202 return_ACPI_STATUS
203 (AE_AML_INVALID_RESOURCE_TYPE);
204 }
205 break;
206
207 case ACPI_RSC_SOURCE:
208 /*
209 * Optional resource_source (Index and String)
210 */
211 resource->length +=
212 acpi_rs_get_resource_source(aml_resource_length,
213 info->value,
214 destination, aml, NULL);
215 break;
216
217 case ACPI_RSC_SOURCEX:
218 /*
219 * Optional resource_source (Index and String). This is the more
220 * complicated case used by the Interrupt() macro
221 */
222 target =
223 ACPI_ADD_PTR(char, resource,
224 info->aml_offset + (item_count * 4));
225
226 resource->length +=
227 acpi_rs_get_resource_source(aml_resource_length,
228 (acpi_rs_length) (((item_count - 1) * sizeof(u32)) + info->value), destination, aml, target);
229 break;
230
231 case ACPI_RSC_BITMASK:
232 /*
233 * 8-bit encoded bitmask (DMA macro)
234 */
235 item_count =
236 acpi_rs_decode_bitmask(ACPI_GET8(source),
237 destination);
238 if (item_count) {
239 resource->length += (item_count - 1);
240 }
241
242 target = ACPI_ADD_PTR(char, resource, info->value);
243 ACPI_SET8(target) = (u8) item_count;
244 break;
245
246 case ACPI_RSC_BITMASK16:
247 /*
248 * 16-bit encoded bitmask (IRQ macro)
249 */
250 ACPI_MOVE_16_TO_16(&temp16, source);
251
252 item_count =
253 acpi_rs_decode_bitmask(temp16, destination);
254 if (item_count) {
255 resource->length += (item_count - 1);
256 }
257
258 target = ACPI_ADD_PTR(char, resource, info->value);
259 ACPI_SET8(target) = (u8) item_count;
260 break;
261
262 case ACPI_RSC_EXIT_NE:
263 /*
264 * Control - Exit conversion if not equal
265 */
266 switch (info->resource_offset) {
267 case ACPI_RSC_COMPARE_AML_LENGTH:
268 if (aml_resource_length != info->value) {
269 goto exit;
270 }
271 break;
272
273 case ACPI_RSC_COMPARE_VALUE:
274 if (ACPI_GET8(source) != info->value) {
275 goto exit;
276 }
277 break;
278
279 default:
280
281 ACPI_ERROR((AE_INFO,
282 "Invalid conversion sub-opcode"));
283 return_ACPI_STATUS(AE_BAD_PARAMETER);
284 }
285 break;
286
287 default:
288
289 ACPI_ERROR((AE_INFO, "Invalid conversion opcode"));
290 return_ACPI_STATUS(AE_BAD_PARAMETER);
291 }
292
293 count--;
294 info++;
295 }
296
297 exit:
298 if (!flags_mode) {
299
300 /* Round the resource struct length up to the next boundary (32 or 64) */
301
302 resource->length =
303 (u32) ACPI_ROUND_UP_TO_NATIVE_WORD(resource->length);
304 }
305 return_ACPI_STATUS(AE_OK);
306}
307
308/*******************************************************************************
309 *
310 * FUNCTION: acpi_rs_convert_resource_to_aml
311 *
312 * PARAMETERS: Resource - Pointer to the resource descriptor
313 * Aml - Where the AML descriptor is returned
314 * Info - Pointer to appropriate conversion table
315 *
316 * RETURN: Status
317 *
318 * DESCRIPTION: Convert an internal resource descriptor to the corresponding
319 * external AML resource descriptor.
320 *
321 ******************************************************************************/
322
323acpi_status
324acpi_rs_convert_resource_to_aml(struct acpi_resource *resource,
325 union aml_resource *aml,
326 struct acpi_rsconvert_info *info)
327{
328 void *source = NULL;
329 void *destination;
330 acpi_rsdesc_size aml_length = 0;
331 u8 count;
332 u16 temp16 = 0;
333 u16 item_count = 0;
334
335 ACPI_FUNCTION_TRACE(rs_convert_resource_to_aml);
336
337 /*
338 * First table entry must be ACPI_RSC_INITxxx and must contain the
339 * table length (# of table entries)
340 */
341 count = INIT_TABLE_LENGTH(info);
342
343 while (count) {
344 /*
345 * Source is the internal resource descriptor,
346 * destination is the external AML byte stream buffer
347 */
348 source = ACPI_ADD_PTR(void, resource, info->resource_offset);
349 destination = ACPI_ADD_PTR(void, aml, info->aml_offset);
350
351 switch (info->opcode) {
352 case ACPI_RSC_INITSET:
353
354 ACPI_MEMSET(aml, 0, INIT_RESOURCE_LENGTH(info));
355 aml_length = INIT_RESOURCE_LENGTH(info);
356 acpi_rs_set_resource_header(INIT_RESOURCE_TYPE(info),
357 aml_length, aml);
358 break;
359
360 case ACPI_RSC_INITGET:
361 break;
362
363 case ACPI_RSC_FLAGINIT:
364 /*
365 * Clear the flag byte
366 */
367 ACPI_SET8(destination) = 0;
368 break;
369
370 case ACPI_RSC_1BITFLAG:
371 /*
372 * Mask and shift the flag bit
373 */
374 ACPI_SET8(destination) |= (u8)
375 ((ACPI_GET8(source) & 0x01) << info->value);
376 break;
377
378 case ACPI_RSC_2BITFLAG:
379 /*
380 * Mask and shift the flag bits
381 */
382 ACPI_SET8(destination) |= (u8)
383 ((ACPI_GET8(source) & 0x03) << info->value);
384 break;
385
386 case ACPI_RSC_COUNT:
387
388 item_count = ACPI_GET8(source);
389 ACPI_SET8(destination) = (u8) item_count;
390
391 aml_length =
392 (u16) (aml_length +
393 (info->value * (item_count - 1)));
394 break;
395
396 case ACPI_RSC_COUNT16:
397
398 item_count = ACPI_GET16(source);
399 aml_length = (u16) (aml_length + item_count);
400 acpi_rs_set_resource_length(aml_length, aml);
401 break;
402
403 case ACPI_RSC_LENGTH:
404
405 acpi_rs_set_resource_length(info->value, aml);
406 break;
407
408 case ACPI_RSC_MOVE8:
409 case ACPI_RSC_MOVE16:
410 case ACPI_RSC_MOVE32:
411 case ACPI_RSC_MOVE64:
412
413 if (info->value) {
414 item_count = info->value;
415 }
416 acpi_rs_move_data(destination, source, item_count,
417 info->opcode);
418 break;
419
420 case ACPI_RSC_ADDRESS:
421
422 /* Set the Resource Type, General Flags, and Type-Specific Flags */
423
424 acpi_rs_set_address_common(aml, resource);
425 break;
426
427 case ACPI_RSC_SOURCEX:
428 /*
429 * Optional resource_source (Index and String)
430 */
431 aml_length =
432 acpi_rs_set_resource_source(aml, (acpi_rs_length)
433 aml_length, source);
434 acpi_rs_set_resource_length(aml_length, aml);
435 break;
436
437 case ACPI_RSC_SOURCE:
438 /*
439 * Optional resource_source (Index and String). This is the more
440 * complicated case used by the Interrupt() macro
441 */
442 aml_length =
443 acpi_rs_set_resource_source(aml, info->value,
444 source);
445 acpi_rs_set_resource_length(aml_length, aml);
446 break;
447
448 case ACPI_RSC_BITMASK:
449 /*
450 * 8-bit encoded bitmask (DMA macro)
451 */
452 ACPI_SET8(destination) = (u8)
453 acpi_rs_encode_bitmask(source,
454 *ACPI_ADD_PTR(u8, resource,
455 info->value));
456 break;
457
458 case ACPI_RSC_BITMASK16:
459 /*
460 * 16-bit encoded bitmask (IRQ macro)
461 */
462 temp16 = acpi_rs_encode_bitmask(source,
463 *ACPI_ADD_PTR(u8,
464 resource,
465 info->
466 value));
467 ACPI_MOVE_16_TO_16(destination, &temp16);
468 break;
469
470 case ACPI_RSC_EXIT_LE:
471 /*
472 * Control - Exit conversion if less than or equal
473 */
474 if (item_count <= info->value) {
475 goto exit;
476 }
477 break;
478
479 case ACPI_RSC_EXIT_NE:
480 /*
481 * Control - Exit conversion if not equal
482 */
483 switch (COMPARE_OPCODE(info)) {
484 case ACPI_RSC_COMPARE_VALUE:
485
486 if (*ACPI_ADD_PTR(u8, resource,
487 COMPARE_TARGET(info)) !=
488 COMPARE_VALUE(info)) {
489 goto exit;
490 }
491 break;
492
493 default:
494
495 ACPI_ERROR((AE_INFO,
496 "Invalid conversion sub-opcode"));
497 return_ACPI_STATUS(AE_BAD_PARAMETER);
498 }
499 break;
500
501 case ACPI_RSC_EXIT_EQ:
502 /*
503 * Control - Exit conversion if equal
504 */
505 if (*ACPI_ADD_PTR(u8, resource,
506 COMPARE_TARGET(info)) ==
507 COMPARE_VALUE(info)) {
508 goto exit;
509 }
510 break;
511
512 default:
513
514 ACPI_ERROR((AE_INFO, "Invalid conversion opcode"));
515 return_ACPI_STATUS(AE_BAD_PARAMETER);
516 }
517
518 count--;
519 info++;
520 }
521
522 exit:
523 return_ACPI_STATUS(AE_OK);
524}
525
526#if 0
527/* Previous resource validations */
528
529if (aml->ext_address64.revision_iD != AML_RESOURCE_EXTENDED_ADDRESS_REVISION) {
530 return_ACPI_STATUS(AE_SUPPORT);
531}
532
533if (resource->data.start_dpf.performance_robustness >= 3) {
534 return_ACPI_STATUS(AE_AML_BAD_RESOURCE_VALUE);
535}
536
537if (((aml->irq.flags & 0x09) == 0x00) || ((aml->irq.flags & 0x09) == 0x09)) {
538 /*
539 * Only [active_high, edge_sensitive] or [active_low, level_sensitive]
540 * polarity/trigger interrupts are allowed (ACPI spec, section
541 * "IRQ Format"), so 0x00 and 0x09 are illegal.
542 */
543 ACPI_ERROR((AE_INFO,
544 "Invalid interrupt polarity/trigger in resource list, %X",
545 aml->irq.flags));
546 return_ACPI_STATUS(AE_BAD_DATA);
547}
548
549resource->data.extended_irq.interrupt_count = temp8;
550if (temp8 < 1) {
551
552 /* Must have at least one IRQ */
553
554 return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH);
555}
556
557if (resource->data.dma.transfer == 0x03) {
558 ACPI_ERROR((AE_INFO, "Invalid DMA.Transfer preference (3)"));
559 return_ACPI_STATUS(AE_BAD_DATA);
560}
561#endif
diff --git a/drivers/acpi/acpica/rsutils.c b/drivers/acpi/acpica/rsutils.c
new file mode 100644
index 00000000000..7450105f854
--- /dev/null
+++ b/drivers/acpi/acpica/rsutils.c
@@ -0,0 +1,727 @@
1/*******************************************************************************
2 *
3 * Module Name: rsutils - Utilities for the resource manager
4 *
5 ******************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46#include <acpi/acnamesp.h>
47#include <acpi/acresrc.h>
48
49#define _COMPONENT ACPI_RESOURCES
50ACPI_MODULE_NAME("rsutils")
51
52/*******************************************************************************
53 *
54 * FUNCTION: acpi_rs_decode_bitmask
55 *
56 * PARAMETERS: Mask - Bitmask to decode
57 * List - Where the converted list is returned
58 *
59 * RETURN: Count of bits set (length of list)
60 *
61 * DESCRIPTION: Convert a bit mask into a list of values
62 *
63 ******************************************************************************/
64u8 acpi_rs_decode_bitmask(u16 mask, u8 * list)
65{
66 u8 i;
67 u8 bit_count;
68
69 ACPI_FUNCTION_ENTRY();
70
71 /* Decode the mask bits */
72
73 for (i = 0, bit_count = 0; mask; i++) {
74 if (mask & 0x0001) {
75 list[bit_count] = i;
76 bit_count++;
77 }
78
79 mask >>= 1;
80 }
81
82 return (bit_count);
83}
84
85/*******************************************************************************
86 *
87 * FUNCTION: acpi_rs_encode_bitmask
88 *
89 * PARAMETERS: List - List of values to encode
90 * Count - Length of list
91 *
92 * RETURN: Encoded bitmask
93 *
94 * DESCRIPTION: Convert a list of values to an encoded bitmask
95 *
96 ******************************************************************************/
97
98u16 acpi_rs_encode_bitmask(u8 * list, u8 count)
99{
100 u32 i;
101 u16 mask;
102
103 ACPI_FUNCTION_ENTRY();
104
105 /* Encode the list into a single bitmask */
106
107 for (i = 0, mask = 0; i < count; i++) {
108 mask |= (0x1 << list[i]);
109 }
110
111 return mask;
112}
113
114/*******************************************************************************
115 *
116 * FUNCTION: acpi_rs_move_data
117 *
118 * PARAMETERS: Destination - Pointer to the destination descriptor
119 * Source - Pointer to the source descriptor
120 * item_count - How many items to move
121 * move_type - Byte width
122 *
123 * RETURN: None
124 *
125 * DESCRIPTION: Move multiple data items from one descriptor to another. Handles
126 * alignment issues and endian issues if necessary, as configured
127 * via the ACPI_MOVE_* macros. (This is why a memcpy is not used)
128 *
129 ******************************************************************************/
130
131void
132acpi_rs_move_data(void *destination, void *source, u16 item_count, u8 move_type)
133{
134 u32 i;
135
136 ACPI_FUNCTION_ENTRY();
137
138 /* One move per item */
139
140 for (i = 0; i < item_count; i++) {
141 switch (move_type) {
142 /*
143 * For the 8-bit case, we can perform the move all at once
144 * since there are no alignment or endian issues
145 */
146 case ACPI_RSC_MOVE8:
147 ACPI_MEMCPY(destination, source, item_count);
148 return;
149
150 /*
151 * 16-, 32-, and 64-bit cases must use the move macros that perform
152 * endian conversion and/or accomodate hardware that cannot perform
153 * misaligned memory transfers
154 */
155 case ACPI_RSC_MOVE16:
156 ACPI_MOVE_16_TO_16(&ACPI_CAST_PTR(u16, destination)[i],
157 &ACPI_CAST_PTR(u16, source)[i]);
158 break;
159
160 case ACPI_RSC_MOVE32:
161 ACPI_MOVE_32_TO_32(&ACPI_CAST_PTR(u32, destination)[i],
162 &ACPI_CAST_PTR(u32, source)[i]);
163 break;
164
165 case ACPI_RSC_MOVE64:
166 ACPI_MOVE_64_TO_64(&ACPI_CAST_PTR(u64, destination)[i],
167 &ACPI_CAST_PTR(u64, source)[i]);
168 break;
169
170 default:
171 return;
172 }
173 }
174}
175
176/*******************************************************************************
177 *
178 * FUNCTION: acpi_rs_set_resource_length
179 *
180 * PARAMETERS: total_length - Length of the AML descriptor, including
181 * the header and length fields.
182 * Aml - Pointer to the raw AML descriptor
183 *
184 * RETURN: None
185 *
186 * DESCRIPTION: Set the resource_length field of an AML
187 * resource descriptor, both Large and Small descriptors are
188 * supported automatically. Note: Descriptor Type field must
189 * be valid.
190 *
191 ******************************************************************************/
192
193void
194acpi_rs_set_resource_length(acpi_rsdesc_size total_length,
195 union aml_resource *aml)
196{
197 acpi_rs_length resource_length;
198
199 ACPI_FUNCTION_ENTRY();
200
201 /* Length is the total descriptor length minus the header length */
202
203 resource_length = (acpi_rs_length)
204 (total_length - acpi_ut_get_resource_header_length(aml));
205
206 /* Length is stored differently for large and small descriptors */
207
208 if (aml->small_header.descriptor_type & ACPI_RESOURCE_NAME_LARGE) {
209
210 /* Large descriptor -- bytes 1-2 contain the 16-bit length */
211
212 ACPI_MOVE_16_TO_16(&aml->large_header.resource_length,
213 &resource_length);
214 } else {
215 /* Small descriptor -- bits 2:0 of byte 0 contain the length */
216
217 aml->small_header.descriptor_type = (u8)
218
219 /* Clear any existing length, preserving descriptor type bits */
220 ((aml->small_header.
221 descriptor_type & ~ACPI_RESOURCE_NAME_SMALL_LENGTH_MASK)
222
223 | resource_length);
224 }
225}
226
227/*******************************************************************************
228 *
229 * FUNCTION: acpi_rs_set_resource_header
230 *
231 * PARAMETERS: descriptor_type - Byte to be inserted as the type
232 * total_length - Length of the AML descriptor, including
233 * the header and length fields.
234 * Aml - Pointer to the raw AML descriptor
235 *
236 * RETURN: None
237 *
238 * DESCRIPTION: Set the descriptor_type and resource_length fields of an AML
239 * resource descriptor, both Large and Small descriptors are
240 * supported automatically
241 *
242 ******************************************************************************/
243
244void
245acpi_rs_set_resource_header(u8 descriptor_type,
246 acpi_rsdesc_size total_length,
247 union aml_resource *aml)
248{
249 ACPI_FUNCTION_ENTRY();
250
251 /* Set the Resource Type */
252
253 aml->small_header.descriptor_type = descriptor_type;
254
255 /* Set the Resource Length */
256
257 acpi_rs_set_resource_length(total_length, aml);
258}
259
260/*******************************************************************************
261 *
262 * FUNCTION: acpi_rs_strcpy
263 *
264 * PARAMETERS: Destination - Pointer to the destination string
265 * Source - Pointer to the source string
266 *
267 * RETURN: String length, including NULL terminator
268 *
269 * DESCRIPTION: Local string copy that returns the string length, saving a
270 * strcpy followed by a strlen.
271 *
272 ******************************************************************************/
273
274static u16 acpi_rs_strcpy(char *destination, char *source)
275{
276 u16 i;
277
278 ACPI_FUNCTION_ENTRY();
279
280 for (i = 0; source[i]; i++) {
281 destination[i] = source[i];
282 }
283
284 destination[i] = 0;
285
286 /* Return string length including the NULL terminator */
287
288 return ((u16) (i + 1));
289}
290
291/*******************************************************************************
292 *
293 * FUNCTION: acpi_rs_get_resource_source
294 *
295 * PARAMETERS: resource_length - Length field of the descriptor
296 * minimum_length - Minimum length of the descriptor (minus
297 * any optional fields)
298 * resource_source - Where the resource_source is returned
299 * Aml - Pointer to the raw AML descriptor
300 * string_ptr - (optional) where to store the actual
301 * resource_source string
302 *
303 * RETURN: Length of the string plus NULL terminator, rounded up to native
304 * word boundary
305 *
306 * DESCRIPTION: Copy the optional resource_source data from a raw AML descriptor
307 * to an internal resource descriptor
308 *
309 ******************************************************************************/
310
311acpi_rs_length
312acpi_rs_get_resource_source(acpi_rs_length resource_length,
313 acpi_rs_length minimum_length,
314 struct acpi_resource_source * resource_source,
315 union aml_resource * aml, char *string_ptr)
316{
317 acpi_rsdesc_size total_length;
318 u8 *aml_resource_source;
319
320 ACPI_FUNCTION_ENTRY();
321
322 total_length =
323 resource_length + sizeof(struct aml_resource_large_header);
324 aml_resource_source = ACPI_ADD_PTR(u8, aml, minimum_length);
325
326 /*
327 * resource_source is present if the length of the descriptor is longer than
328 * the minimum length.
329 *
330 * Note: Some resource descriptors will have an additional null, so
331 * we add 1 to the minimum length.
332 */
333 if (total_length > (acpi_rsdesc_size) (minimum_length + 1)) {
334
335 /* Get the resource_source_index */
336
337 resource_source->index = aml_resource_source[0];
338
339 resource_source->string_ptr = string_ptr;
340 if (!string_ptr) {
341 /*
342 * String destination pointer is not specified; Set the String
343 * pointer to the end of the current resource_source structure.
344 */
345 resource_source->string_ptr =
346 ACPI_ADD_PTR(char, resource_source,
347 sizeof(struct acpi_resource_source));
348 }
349
350 /*
351 * In order for the Resource length to be a multiple of the native
352 * word, calculate the length of the string (+1 for NULL terminator)
353 * and expand to the next word multiple.
354 *
355 * Zero the entire area of the buffer.
356 */
357 total_length = (u32)
358 ACPI_STRLEN(ACPI_CAST_PTR(char, &aml_resource_source[1])) + 1;
359 total_length = (u32) ACPI_ROUND_UP_TO_NATIVE_WORD(total_length);
360
361 ACPI_MEMSET(resource_source->string_ptr, 0, total_length);
362
363 /* Copy the resource_source string to the destination */
364
365 resource_source->string_length =
366 acpi_rs_strcpy(resource_source->string_ptr,
367 ACPI_CAST_PTR(char,
368 &aml_resource_source[1]));
369
370 return ((acpi_rs_length) total_length);
371 }
372
373 /* resource_source is not present */
374
375 resource_source->index = 0;
376 resource_source->string_length = 0;
377 resource_source->string_ptr = NULL;
378 return (0);
379}
380
381/*******************************************************************************
382 *
383 * FUNCTION: acpi_rs_set_resource_source
384 *
385 * PARAMETERS: Aml - Pointer to the raw AML descriptor
386 * minimum_length - Minimum length of the descriptor (minus
387 * any optional fields)
388 * resource_source - Internal resource_source
389
390 *
391 * RETURN: Total length of the AML descriptor
392 *
393 * DESCRIPTION: Convert an optional resource_source from internal format to a
394 * raw AML resource descriptor
395 *
396 ******************************************************************************/
397
398acpi_rsdesc_size
399acpi_rs_set_resource_source(union aml_resource * aml,
400 acpi_rs_length minimum_length,
401 struct acpi_resource_source * resource_source)
402{
403 u8 *aml_resource_source;
404 acpi_rsdesc_size descriptor_length;
405
406 ACPI_FUNCTION_ENTRY();
407
408 descriptor_length = minimum_length;
409
410 /* Non-zero string length indicates presence of a resource_source */
411
412 if (resource_source->string_length) {
413
414 /* Point to the end of the AML descriptor */
415
416 aml_resource_source = ACPI_ADD_PTR(u8, aml, minimum_length);
417
418 /* Copy the resource_source_index */
419
420 aml_resource_source[0] = (u8) resource_source->index;
421
422 /* Copy the resource_source string */
423
424 ACPI_STRCPY(ACPI_CAST_PTR(char, &aml_resource_source[1]),
425 resource_source->string_ptr);
426
427 /*
428 * Add the length of the string (+ 1 for null terminator) to the
429 * final descriptor length
430 */
431 descriptor_length +=
432 ((acpi_rsdesc_size) resource_source->string_length + 1);
433 }
434
435 /* Return the new total length of the AML descriptor */
436
437 return (descriptor_length);
438}
439
440/*******************************************************************************
441 *
442 * FUNCTION: acpi_rs_get_prt_method_data
443 *
444 * PARAMETERS: Node - Device node
445 * ret_buffer - Pointer to a buffer structure for the
446 * results
447 *
448 * RETURN: Status
449 *
450 * DESCRIPTION: This function is called to get the _PRT value of an object
451 * contained in an object specified by the handle passed in
452 *
453 * If the function fails an appropriate status will be returned
454 * and the contents of the callers buffer is undefined.
455 *
456 ******************************************************************************/
457
458acpi_status
459acpi_rs_get_prt_method_data(struct acpi_namespace_node * node,
460 struct acpi_buffer * ret_buffer)
461{
462 union acpi_operand_object *obj_desc;
463 acpi_status status;
464
465 ACPI_FUNCTION_TRACE(rs_get_prt_method_data);
466
467 /* Parameters guaranteed valid by caller */
468
469 /* Execute the method, no parameters */
470
471 status = acpi_ut_evaluate_object(node, METHOD_NAME__PRT,
472 ACPI_BTYPE_PACKAGE, &obj_desc);
473 if (ACPI_FAILURE(status)) {
474 return_ACPI_STATUS(status);
475 }
476
477 /*
478 * Create a resource linked list from the byte stream buffer that comes
479 * back from the _CRS method execution.
480 */
481 status = acpi_rs_create_pci_routing_table(obj_desc, ret_buffer);
482
483 /* On exit, we must delete the object returned by evaluate_object */
484
485 acpi_ut_remove_reference(obj_desc);
486 return_ACPI_STATUS(status);
487}
488
489/*******************************************************************************
490 *
491 * FUNCTION: acpi_rs_get_crs_method_data
492 *
493 * PARAMETERS: Node - Device node
494 * ret_buffer - Pointer to a buffer structure for the
495 * results
496 *
497 * RETURN: Status
498 *
499 * DESCRIPTION: This function is called to get the _CRS value of an object
500 * contained in an object specified by the handle passed in
501 *
502 * If the function fails an appropriate status will be returned
503 * and the contents of the callers buffer is undefined.
504 *
505 ******************************************************************************/
506
507acpi_status
508acpi_rs_get_crs_method_data(struct acpi_namespace_node *node,
509 struct acpi_buffer *ret_buffer)
510{
511 union acpi_operand_object *obj_desc;
512 acpi_status status;
513
514 ACPI_FUNCTION_TRACE(rs_get_crs_method_data);
515
516 /* Parameters guaranteed valid by caller */
517
518 /* Execute the method, no parameters */
519
520 status = acpi_ut_evaluate_object(node, METHOD_NAME__CRS,
521 ACPI_BTYPE_BUFFER, &obj_desc);
522 if (ACPI_FAILURE(status)) {
523 return_ACPI_STATUS(status);
524 }
525
526 /*
527 * Make the call to create a resource linked list from the
528 * byte stream buffer that comes back from the _CRS method
529 * execution.
530 */
531 status = acpi_rs_create_resource_list(obj_desc, ret_buffer);
532
533 /* On exit, we must delete the object returned by evaluate_object */
534
535 acpi_ut_remove_reference(obj_desc);
536 return_ACPI_STATUS(status);
537}
538
539/*******************************************************************************
540 *
541 * FUNCTION: acpi_rs_get_prs_method_data
542 *
543 * PARAMETERS: Node - Device node
544 * ret_buffer - Pointer to a buffer structure for the
545 * results
546 *
547 * RETURN: Status
548 *
549 * DESCRIPTION: This function is called to get the _PRS value of an object
550 * contained in an object specified by the handle passed in
551 *
552 * If the function fails an appropriate status will be returned
553 * and the contents of the callers buffer is undefined.
554 *
555 ******************************************************************************/
556
557#ifdef ACPI_FUTURE_USAGE
558acpi_status
559acpi_rs_get_prs_method_data(struct acpi_namespace_node *node,
560 struct acpi_buffer *ret_buffer)
561{
562 union acpi_operand_object *obj_desc;
563 acpi_status status;
564
565 ACPI_FUNCTION_TRACE(rs_get_prs_method_data);
566
567 /* Parameters guaranteed valid by caller */
568
569 /* Execute the method, no parameters */
570
571 status = acpi_ut_evaluate_object(node, METHOD_NAME__PRS,
572 ACPI_BTYPE_BUFFER, &obj_desc);
573 if (ACPI_FAILURE(status)) {
574 return_ACPI_STATUS(status);
575 }
576
577 /*
578 * Make the call to create a resource linked list from the
579 * byte stream buffer that comes back from the _CRS method
580 * execution.
581 */
582 status = acpi_rs_create_resource_list(obj_desc, ret_buffer);
583
584 /* On exit, we must delete the object returned by evaluate_object */
585
586 acpi_ut_remove_reference(obj_desc);
587 return_ACPI_STATUS(status);
588}
589#endif /* ACPI_FUTURE_USAGE */
590
591/*******************************************************************************
592 *
593 * FUNCTION: acpi_rs_get_method_data
594 *
595 * PARAMETERS: Handle - Handle to the containing object
596 * Path - Path to method, relative to Handle
597 * ret_buffer - Pointer to a buffer structure for the
598 * results
599 *
600 * RETURN: Status
601 *
602 * DESCRIPTION: This function is called to get the _CRS or _PRS value of an
603 * object contained in an object specified by the handle passed in
604 *
605 * If the function fails an appropriate status will be returned
606 * and the contents of the callers buffer is undefined.
607 *
608 ******************************************************************************/
609
610acpi_status
611acpi_rs_get_method_data(acpi_handle handle,
612 char *path, struct acpi_buffer *ret_buffer)
613{
614 union acpi_operand_object *obj_desc;
615 acpi_status status;
616
617 ACPI_FUNCTION_TRACE(rs_get_method_data);
618
619 /* Parameters guaranteed valid by caller */
620
621 /* Execute the method, no parameters */
622
623 status =
624 acpi_ut_evaluate_object(handle, path, ACPI_BTYPE_BUFFER, &obj_desc);
625 if (ACPI_FAILURE(status)) {
626 return_ACPI_STATUS(status);
627 }
628
629 /*
630 * Make the call to create a resource linked list from the
631 * byte stream buffer that comes back from the method
632 * execution.
633 */
634 status = acpi_rs_create_resource_list(obj_desc, ret_buffer);
635
636 /* On exit, we must delete the object returned by evaluate_object */
637
638 acpi_ut_remove_reference(obj_desc);
639 return_ACPI_STATUS(status);
640}
641
642/*******************************************************************************
643 *
644 * FUNCTION: acpi_rs_set_srs_method_data
645 *
646 * PARAMETERS: Node - Device node
647 * in_buffer - Pointer to a buffer structure of the
648 * parameter
649 *
650 * RETURN: Status
651 *
652 * DESCRIPTION: This function is called to set the _SRS of an object contained
653 * in an object specified by the handle passed in
654 *
655 * If the function fails an appropriate status will be returned
656 * and the contents of the callers buffer is undefined.
657 *
658 * Note: Parameters guaranteed valid by caller
659 *
660 ******************************************************************************/
661
662acpi_status
663acpi_rs_set_srs_method_data(struct acpi_namespace_node *node,
664 struct acpi_buffer *in_buffer)
665{
666 struct acpi_evaluate_info *info;
667 union acpi_operand_object *args[2];
668 acpi_status status;
669 struct acpi_buffer buffer;
670
671 ACPI_FUNCTION_TRACE(rs_set_srs_method_data);
672
673 /* Allocate and initialize the evaluation information block */
674
675 info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
676 if (!info) {
677 return_ACPI_STATUS(AE_NO_MEMORY);
678 }
679
680 info->prefix_node = node;
681 info->pathname = METHOD_NAME__SRS;
682 info->parameters = args;
683 info->flags = ACPI_IGNORE_RETURN_VALUE;
684
685 /*
686 * The in_buffer parameter will point to a linked list of
687 * resource parameters. It needs to be formatted into a
688 * byte stream to be sent in as an input parameter to _SRS
689 *
690 * Convert the linked list into a byte stream
691 */
692 buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
693 status = acpi_rs_create_aml_resources(in_buffer->pointer, &buffer);
694 if (ACPI_FAILURE(status)) {
695 goto cleanup;
696 }
697
698 /* Create and initialize the method parameter object */
699
700 args[0] = acpi_ut_create_internal_object(ACPI_TYPE_BUFFER);
701 if (!args[0]) {
702 /*
703 * Must free the buffer allocated above (otherwise it is freed
704 * later)
705 */
706 ACPI_FREE(buffer.pointer);
707 status = AE_NO_MEMORY;
708 goto cleanup;
709 }
710
711 args[0]->buffer.length = (u32) buffer.length;
712 args[0]->buffer.pointer = buffer.pointer;
713 args[0]->common.flags = AOPOBJ_DATA_VALID;
714 args[1] = NULL;
715
716 /* Execute the method, no return value is expected */
717
718 status = acpi_ns_evaluate(info);
719
720 /* Clean up and return the status from acpi_ns_evaluate */
721
722 acpi_ut_remove_reference(args[0]);
723
724 cleanup:
725 ACPI_FREE(info);
726 return_ACPI_STATUS(status);
727}
diff --git a/drivers/acpi/acpica/rsxface.c b/drivers/acpi/acpica/rsxface.c
new file mode 100644
index 00000000000..0a274356b23
--- /dev/null
+++ b/drivers/acpi/acpica/rsxface.c
@@ -0,0 +1,571 @@
1/*******************************************************************************
2 *
3 * Module Name: rsxface - Public interfaces to the resource manager
4 *
5 ******************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46#include <acpi/acresrc.h>
47#include <acpi/acnamesp.h>
48
49#define _COMPONENT ACPI_RESOURCES
50ACPI_MODULE_NAME("rsxface")
51
52/* Local macros for 16,32-bit to 64-bit conversion */
53#define ACPI_COPY_FIELD(out, in, field) ((out)->field = (in)->field)
54#define ACPI_COPY_ADDRESS(out, in) \
55 ACPI_COPY_FIELD(out, in, resource_type); \
56 ACPI_COPY_FIELD(out, in, producer_consumer); \
57 ACPI_COPY_FIELD(out, in, decode); \
58 ACPI_COPY_FIELD(out, in, min_address_fixed); \
59 ACPI_COPY_FIELD(out, in, max_address_fixed); \
60 ACPI_COPY_FIELD(out, in, info); \
61 ACPI_COPY_FIELD(out, in, granularity); \
62 ACPI_COPY_FIELD(out, in, minimum); \
63 ACPI_COPY_FIELD(out, in, maximum); \
64 ACPI_COPY_FIELD(out, in, translation_offset); \
65 ACPI_COPY_FIELD(out, in, address_length); \
66 ACPI_COPY_FIELD(out, in, resource_source);
67/* Local prototypes */
68static acpi_status
69acpi_rs_match_vendor_resource(struct acpi_resource *resource, void *context);
70
71static acpi_status
72acpi_rs_validate_parameters(acpi_handle device_handle,
73 struct acpi_buffer *buffer,
74 struct acpi_namespace_node **return_node);
75
76/*******************************************************************************
77 *
78 * FUNCTION: acpi_rs_validate_parameters
79 *
80 * PARAMETERS: device_handle - Handle to a device
81 * Buffer - Pointer to a data buffer
82 * return_node - Pointer to where the device node is returned
83 *
84 * RETURN: Status
85 *
86 * DESCRIPTION: Common parameter validation for resource interfaces
87 *
88 ******************************************************************************/
89
90static acpi_status
91acpi_rs_validate_parameters(acpi_handle device_handle,
92 struct acpi_buffer *buffer,
93 struct acpi_namespace_node **return_node)
94{
95 acpi_status status;
96 struct acpi_namespace_node *node;
97
98 ACPI_FUNCTION_TRACE(rs_validate_parameters);
99
100 /*
101 * Must have a valid handle to an ACPI device
102 */
103 if (!device_handle) {
104 return_ACPI_STATUS(AE_BAD_PARAMETER);
105 }
106
107 node = acpi_ns_map_handle_to_node(device_handle);
108 if (!node) {
109 return_ACPI_STATUS(AE_BAD_PARAMETER);
110 }
111
112 if (node->type != ACPI_TYPE_DEVICE) {
113 return_ACPI_STATUS(AE_TYPE);
114 }
115
116 /*
117 * Validate the user buffer object
118 *
119 * if there is a non-zero buffer length we also need a valid pointer in
120 * the buffer. If it's a zero buffer length, we'll be returning the
121 * needed buffer size (later), so keep going.
122 */
123 status = acpi_ut_validate_buffer(buffer);
124 if (ACPI_FAILURE(status)) {
125 return_ACPI_STATUS(status);
126 }
127
128 *return_node = node;
129 return_ACPI_STATUS(AE_OK);
130}
131
132/*******************************************************************************
133 *
134 * FUNCTION: acpi_get_irq_routing_table
135 *
136 * PARAMETERS: device_handle - Handle to the Bus device we are querying
137 * ret_buffer - Pointer to a buffer to receive the
138 * current resources for the device
139 *
140 * RETURN: Status
141 *
142 * DESCRIPTION: This function is called to get the IRQ routing table for a
143 * specific bus. The caller must first acquire a handle for the
144 * desired bus. The routine table is placed in the buffer pointed
145 * to by the ret_buffer variable parameter.
146 *
147 * If the function fails an appropriate status will be returned
148 * and the value of ret_buffer is undefined.
149 *
150 * This function attempts to execute the _PRT method contained in
151 * the object indicated by the passed device_handle.
152 *
153 ******************************************************************************/
154
155acpi_status
156acpi_get_irq_routing_table(acpi_handle device_handle,
157 struct acpi_buffer *ret_buffer)
158{
159 acpi_status status;
160 struct acpi_namespace_node *node;
161
162 ACPI_FUNCTION_TRACE(acpi_get_irq_routing_table);
163
164 /* Validate parameters then dispatch to internal routine */
165
166 status = acpi_rs_validate_parameters(device_handle, ret_buffer, &node);
167 if (ACPI_FAILURE(status)) {
168 return_ACPI_STATUS(status);
169 }
170
171 status = acpi_rs_get_prt_method_data(node, ret_buffer);
172 return_ACPI_STATUS(status);
173}
174
175ACPI_EXPORT_SYMBOL(acpi_get_irq_routing_table)
176
177/*******************************************************************************
178 *
179 * FUNCTION: acpi_get_current_resources
180 *
181 * PARAMETERS: device_handle - Handle to the device object for the
182 * device we are querying
183 * ret_buffer - Pointer to a buffer to receive the
184 * current resources for the device
185 *
186 * RETURN: Status
187 *
188 * DESCRIPTION: This function is called to get the current resources for a
189 * specific device. The caller must first acquire a handle for
190 * the desired device. The resource data is placed in the buffer
191 * pointed to by the ret_buffer variable parameter.
192 *
193 * If the function fails an appropriate status will be returned
194 * and the value of ret_buffer is undefined.
195 *
196 * This function attempts to execute the _CRS method contained in
197 * the object indicated by the passed device_handle.
198 *
199 ******************************************************************************/
200acpi_status
201acpi_get_current_resources(acpi_handle device_handle,
202 struct acpi_buffer *ret_buffer)
203{
204 acpi_status status;
205 struct acpi_namespace_node *node;
206
207 ACPI_FUNCTION_TRACE(acpi_get_current_resources);
208
209 /* Validate parameters then dispatch to internal routine */
210
211 status = acpi_rs_validate_parameters(device_handle, ret_buffer, &node);
212 if (ACPI_FAILURE(status)) {
213 return_ACPI_STATUS(status);
214 }
215
216 status = acpi_rs_get_crs_method_data(node, ret_buffer);
217 return_ACPI_STATUS(status);
218}
219
220ACPI_EXPORT_SYMBOL(acpi_get_current_resources)
221#ifdef ACPI_FUTURE_USAGE
222/*******************************************************************************
223 *
224 * FUNCTION: acpi_get_possible_resources
225 *
226 * PARAMETERS: device_handle - Handle to the device object for the
227 * device we are querying
228 * ret_buffer - Pointer to a buffer to receive the
229 * resources for the device
230 *
231 * RETURN: Status
232 *
233 * DESCRIPTION: This function is called to get a list of the possible resources
234 * for a specific device. The caller must first acquire a handle
235 * for the desired device. The resource data is placed in the
236 * buffer pointed to by the ret_buffer variable.
237 *
238 * If the function fails an appropriate status will be returned
239 * and the value of ret_buffer is undefined.
240 *
241 ******************************************************************************/
242acpi_status
243acpi_get_possible_resources(acpi_handle device_handle,
244 struct acpi_buffer *ret_buffer)
245{
246 acpi_status status;
247 struct acpi_namespace_node *node;
248
249 ACPI_FUNCTION_TRACE(acpi_get_possible_resources);
250
251 /* Validate parameters then dispatch to internal routine */
252
253 status = acpi_rs_validate_parameters(device_handle, ret_buffer, &node);
254 if (ACPI_FAILURE(status)) {
255 return_ACPI_STATUS(status);
256 }
257
258 status = acpi_rs_get_prs_method_data(node, ret_buffer);
259 return_ACPI_STATUS(status);
260}
261
262ACPI_EXPORT_SYMBOL(acpi_get_possible_resources)
263#endif /* ACPI_FUTURE_USAGE */
264/*******************************************************************************
265 *
266 * FUNCTION: acpi_set_current_resources
267 *
268 * PARAMETERS: device_handle - Handle to the device object for the
269 * device we are setting resources
270 * in_buffer - Pointer to a buffer containing the
271 * resources to be set for the device
272 *
273 * RETURN: Status
274 *
275 * DESCRIPTION: This function is called to set the current resources for a
276 * specific device. The caller must first acquire a handle for
277 * the desired device. The resource data is passed to the routine
278 * the buffer pointed to by the in_buffer variable.
279 *
280 ******************************************************************************/
281acpi_status
282acpi_set_current_resources(acpi_handle device_handle,
283 struct acpi_buffer *in_buffer)
284{
285 acpi_status status;
286 struct acpi_namespace_node *node;
287
288 ACPI_FUNCTION_TRACE(acpi_set_current_resources);
289
290 /* Validate the buffer, don't allow zero length */
291
292 if ((!in_buffer) || (!in_buffer->pointer) || (!in_buffer->length)) {
293 return_ACPI_STATUS(AE_BAD_PARAMETER);
294 }
295
296 /* Validate parameters then dispatch to internal routine */
297
298 status = acpi_rs_validate_parameters(device_handle, in_buffer, &node);
299 if (ACPI_FAILURE(status)) {
300 return_ACPI_STATUS(status);
301 }
302
303 status = acpi_rs_set_srs_method_data(node, in_buffer);
304 return_ACPI_STATUS(status);
305}
306
307ACPI_EXPORT_SYMBOL(acpi_set_current_resources)
308
309/******************************************************************************
310 *
311 * FUNCTION: acpi_resource_to_address64
312 *
313 * PARAMETERS: Resource - Pointer to a resource
314 * Out - Pointer to the users's return buffer
315 * (a struct acpi_resource_address64)
316 *
317 * RETURN: Status
318 *
319 * DESCRIPTION: If the resource is an address16, address32, or address64,
320 * copy it to the address64 return buffer. This saves the
321 * caller from having to duplicate code for different-sized
322 * addresses.
323 *
324 ******************************************************************************/
325acpi_status
326acpi_resource_to_address64(struct acpi_resource *resource,
327 struct acpi_resource_address64 *out)
328{
329 struct acpi_resource_address16 *address16;
330 struct acpi_resource_address32 *address32;
331
332 if (!resource || !out) {
333 return (AE_BAD_PARAMETER);
334 }
335
336 /* Convert 16 or 32 address descriptor to 64 */
337
338 switch (resource->type) {
339 case ACPI_RESOURCE_TYPE_ADDRESS16:
340
341 address16 = (struct acpi_resource_address16 *)&resource->data;
342 ACPI_COPY_ADDRESS(out, address16);
343 break;
344
345 case ACPI_RESOURCE_TYPE_ADDRESS32:
346
347 address32 = (struct acpi_resource_address32 *)&resource->data;
348 ACPI_COPY_ADDRESS(out, address32);
349 break;
350
351 case ACPI_RESOURCE_TYPE_ADDRESS64:
352
353 /* Simple copy for 64 bit source */
354
355 ACPI_MEMCPY(out, &resource->data,
356 sizeof(struct acpi_resource_address64));
357 break;
358
359 default:
360 return (AE_BAD_PARAMETER);
361 }
362
363 return (AE_OK);
364}
365
366ACPI_EXPORT_SYMBOL(acpi_resource_to_address64)
367
368/*******************************************************************************
369 *
370 * FUNCTION: acpi_get_vendor_resource
371 *
372 * PARAMETERS: device_handle - Handle for the parent device object
373 * Name - Method name for the parent resource
374 * (METHOD_NAME__CRS or METHOD_NAME__PRS)
375 * Uuid - Pointer to the UUID to be matched.
376 * includes both subtype and 16-byte UUID
377 * ret_buffer - Where the vendor resource is returned
378 *
379 * RETURN: Status
380 *
381 * DESCRIPTION: Walk a resource template for the specified evice to find a
382 * vendor-defined resource that matches the supplied UUID and
383 * UUID subtype. Returns a struct acpi_resource of type Vendor.
384 *
385 ******************************************************************************/
386acpi_status
387acpi_get_vendor_resource(acpi_handle device_handle,
388 char *name,
389 struct acpi_vendor_uuid * uuid,
390 struct acpi_buffer * ret_buffer)
391{
392 struct acpi_vendor_walk_info info;
393 acpi_status status;
394
395 /* Other parameters are validated by acpi_walk_resources */
396
397 if (!uuid || !ret_buffer) {
398 return (AE_BAD_PARAMETER);
399 }
400
401 info.uuid = uuid;
402 info.buffer = ret_buffer;
403 info.status = AE_NOT_EXIST;
404
405 /* Walk the _CRS or _PRS resource list for this device */
406
407 status =
408 acpi_walk_resources(device_handle, name,
409 acpi_rs_match_vendor_resource, &info);
410 if (ACPI_FAILURE(status)) {
411 return (status);
412 }
413
414 return (info.status);
415}
416
417ACPI_EXPORT_SYMBOL(acpi_get_vendor_resource)
418
419/*******************************************************************************
420 *
421 * FUNCTION: acpi_rs_match_vendor_resource
422 *
423 * PARAMETERS: acpi_walk_resource_callback
424 *
425 * RETURN: Status
426 *
427 * DESCRIPTION: Match a vendor resource via the ACPI 3.0 UUID
428 *
429 ******************************************************************************/
430static acpi_status
431acpi_rs_match_vendor_resource(struct acpi_resource *resource, void *context)
432{
433 struct acpi_vendor_walk_info *info = context;
434 struct acpi_resource_vendor_typed *vendor;
435 struct acpi_buffer *buffer;
436 acpi_status status;
437
438 /* Ignore all descriptors except Vendor */
439
440 if (resource->type != ACPI_RESOURCE_TYPE_VENDOR) {
441 return (AE_OK);
442 }
443
444 vendor = &resource->data.vendor_typed;
445
446 /*
447 * For a valid match, these conditions must hold:
448 *
449 * 1) Length of descriptor data must be at least as long as a UUID struct
450 * 2) The UUID subtypes must match
451 * 3) The UUID data must match
452 */
453 if ((vendor->byte_length < (ACPI_UUID_LENGTH + 1)) ||
454 (vendor->uuid_subtype != info->uuid->subtype) ||
455 (ACPI_MEMCMP(vendor->uuid, info->uuid->data, ACPI_UUID_LENGTH))) {
456 return (AE_OK);
457 }
458
459 /* Validate/Allocate/Clear caller buffer */
460
461 buffer = info->buffer;
462 status = acpi_ut_initialize_buffer(buffer, resource->length);
463 if (ACPI_FAILURE(status)) {
464 return (status);
465 }
466
467 /* Found the correct resource, copy and return it */
468
469 ACPI_MEMCPY(buffer->pointer, resource, resource->length);
470 buffer->length = resource->length;
471
472 /* Found the desired descriptor, terminate resource walk */
473
474 info->status = AE_OK;
475 return (AE_CTRL_TERMINATE);
476}
477
478/*******************************************************************************
479 *
480 * FUNCTION: acpi_walk_resources
481 *
482 * PARAMETERS: device_handle - Handle to the device object for the
483 * device we are querying
484 * Name - Method name of the resources we want
485 * (METHOD_NAME__CRS or METHOD_NAME__PRS)
486 * user_function - Called for each resource
487 * Context - Passed to user_function
488 *
489 * RETURN: Status
490 *
491 * DESCRIPTION: Retrieves the current or possible resource list for the
492 * specified device. The user_function is called once for
493 * each resource in the list.
494 *
495 ******************************************************************************/
496acpi_status
497acpi_walk_resources(acpi_handle device_handle,
498 char *name,
499 acpi_walk_resource_callback user_function, void *context)
500{
501 acpi_status status;
502 struct acpi_buffer buffer;
503 struct acpi_resource *resource;
504 struct acpi_resource *resource_end;
505
506 ACPI_FUNCTION_TRACE(acpi_walk_resources);
507
508 /* Parameter validation */
509
510 if (!device_handle || !user_function || !name ||
511 (!ACPI_COMPARE_NAME(name, METHOD_NAME__CRS) &&
512 !ACPI_COMPARE_NAME(name, METHOD_NAME__PRS))) {
513 return_ACPI_STATUS(AE_BAD_PARAMETER);
514 }
515
516 /* Get the _CRS or _PRS resource list */
517
518 buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
519 status = acpi_rs_get_method_data(device_handle, name, &buffer);
520 if (ACPI_FAILURE(status)) {
521 return_ACPI_STATUS(status);
522 }
523
524 /* Buffer now contains the resource list */
525
526 resource = ACPI_CAST_PTR(struct acpi_resource, buffer.pointer);
527 resource_end =
528 ACPI_ADD_PTR(struct acpi_resource, buffer.pointer, buffer.length);
529
530 /* Walk the resource list until the end_tag is found (or buffer end) */
531
532 while (resource < resource_end) {
533
534 /* Sanity check the resource */
535
536 if (resource->type > ACPI_RESOURCE_TYPE_MAX) {
537 status = AE_AML_INVALID_RESOURCE_TYPE;
538 break;
539 }
540
541 /* Invoke the user function, abort on any error returned */
542
543 status = user_function(resource, context);
544 if (ACPI_FAILURE(status)) {
545 if (status == AE_CTRL_TERMINATE) {
546
547 /* This is an OK termination by the user function */
548
549 status = AE_OK;
550 }
551 break;
552 }
553
554 /* end_tag indicates end-of-list */
555
556 if (resource->type == ACPI_RESOURCE_TYPE_END_TAG) {
557 break;
558 }
559
560 /* Get the next resource descriptor */
561
562 resource =
563 ACPI_ADD_PTR(struct acpi_resource, resource,
564 resource->length);
565 }
566
567 ACPI_FREE(buffer.pointer);
568 return_ACPI_STATUS(status);
569}
570
571ACPI_EXPORT_SYMBOL(acpi_walk_resources)
diff --git a/drivers/acpi/acpica/tbfadt.c b/drivers/acpi/acpica/tbfadt.c
new file mode 100644
index 00000000000..87f22e68c6d
--- /dev/null
+++ b/drivers/acpi/acpica/tbfadt.c
@@ -0,0 +1,610 @@
1/******************************************************************************
2 *
3 * Module Name: tbfadt - FADT table utilities
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46#include <acpi/actables.h>
47
48#define _COMPONENT ACPI_TABLES
49ACPI_MODULE_NAME("tbfadt")
50
51/* Local prototypes */
52static inline void
53acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
54 u8 space_id, u8 byte_width, u64 address);
55
56static void acpi_tb_convert_fadt(void);
57
58static void acpi_tb_validate_fadt(void);
59
60/* Table for conversion of FADT to common internal format and FADT validation */
61
62typedef struct acpi_fadt_info {
63 char *name;
64 u8 address64;
65 u8 address32;
66 u8 length;
67 u8 default_length;
68 u8 type;
69
70} acpi_fadt_info;
71
72#define ACPI_FADT_REQUIRED 1
73#define ACPI_FADT_SEPARATE_LENGTH 2
74
75static struct acpi_fadt_info fadt_info_table[] = {
76 {"Pm1aEventBlock",
77 ACPI_FADT_OFFSET(xpm1a_event_block),
78 ACPI_FADT_OFFSET(pm1a_event_block),
79 ACPI_FADT_OFFSET(pm1_event_length),
80 ACPI_PM1_REGISTER_WIDTH * 2, /* Enable + Status register */
81 ACPI_FADT_REQUIRED},
82
83 {"Pm1bEventBlock",
84 ACPI_FADT_OFFSET(xpm1b_event_block),
85 ACPI_FADT_OFFSET(pm1b_event_block),
86 ACPI_FADT_OFFSET(pm1_event_length),
87 ACPI_PM1_REGISTER_WIDTH * 2, /* Enable + Status register */
88 0},
89
90 {"Pm1aControlBlock",
91 ACPI_FADT_OFFSET(xpm1a_control_block),
92 ACPI_FADT_OFFSET(pm1a_control_block),
93 ACPI_FADT_OFFSET(pm1_control_length),
94 ACPI_PM1_REGISTER_WIDTH,
95 ACPI_FADT_REQUIRED},
96
97 {"Pm1bControlBlock",
98 ACPI_FADT_OFFSET(xpm1b_control_block),
99 ACPI_FADT_OFFSET(pm1b_control_block),
100 ACPI_FADT_OFFSET(pm1_control_length),
101 ACPI_PM1_REGISTER_WIDTH,
102 0},
103
104 {"Pm2ControlBlock",
105 ACPI_FADT_OFFSET(xpm2_control_block),
106 ACPI_FADT_OFFSET(pm2_control_block),
107 ACPI_FADT_OFFSET(pm2_control_length),
108 ACPI_PM2_REGISTER_WIDTH,
109 ACPI_FADT_SEPARATE_LENGTH},
110
111 {"PmTimerBlock",
112 ACPI_FADT_OFFSET(xpm_timer_block),
113 ACPI_FADT_OFFSET(pm_timer_block),
114 ACPI_FADT_OFFSET(pm_timer_length),
115 ACPI_PM_TIMER_WIDTH,
116 ACPI_FADT_REQUIRED},
117
118 {"Gpe0Block",
119 ACPI_FADT_OFFSET(xgpe0_block),
120 ACPI_FADT_OFFSET(gpe0_block),
121 ACPI_FADT_OFFSET(gpe0_block_length),
122 0,
123 ACPI_FADT_SEPARATE_LENGTH},
124
125 {"Gpe1Block",
126 ACPI_FADT_OFFSET(xgpe1_block),
127 ACPI_FADT_OFFSET(gpe1_block),
128 ACPI_FADT_OFFSET(gpe1_block_length),
129 0,
130 ACPI_FADT_SEPARATE_LENGTH}
131};
132
133#define ACPI_FADT_INFO_ENTRIES (sizeof (fadt_info_table) / sizeof (struct acpi_fadt_info))
134
135/*******************************************************************************
136 *
137 * FUNCTION: acpi_tb_init_generic_address
138 *
139 * PARAMETERS: generic_address - GAS struct to be initialized
140 * byte_width - Width of this register
141 * Address - Address of the register
142 *
143 * RETURN: None
144 *
145 * DESCRIPTION: Initialize a Generic Address Structure (GAS)
146 * See the ACPI specification for a full description and
147 * definition of this structure.
148 *
149 ******************************************************************************/
150
151static inline void
152acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
153 u8 space_id, u8 byte_width, u64 address)
154{
155
156 /*
157 * The 64-bit Address field is non-aligned in the byte packed
158 * GAS struct.
159 */
160 ACPI_MOVE_64_TO_64(&generic_address->address, &address);
161
162 /* All other fields are byte-wide */
163
164 generic_address->space_id = space_id;
165 generic_address->bit_width = (u8)ACPI_MUL_8(byte_width);
166 generic_address->bit_offset = 0;
167 generic_address->access_width = 0; /* Access width ANY */
168}
169
170/*******************************************************************************
171 *
172 * FUNCTION: acpi_tb_parse_fadt
173 *
174 * PARAMETERS: table_index - Index for the FADT
175 * Flags - Flags
176 *
177 * RETURN: None
178 *
179 * DESCRIPTION: Initialize the FADT, DSDT and FACS tables
180 * (FADT contains the addresses of the DSDT and FACS)
181 *
182 ******************************************************************************/
183
184void acpi_tb_parse_fadt(u32 table_index, u8 flags)
185{
186 u32 length;
187 struct acpi_table_header *table;
188
189 /*
190 * The FADT has multiple versions with different lengths,
191 * and it contains pointers to both the DSDT and FACS tables.
192 *
193 * Get a local copy of the FADT and convert it to a common format
194 * Map entire FADT, assumed to be smaller than one page.
195 */
196 length = acpi_gbl_root_table_list.tables[table_index].length;
197
198 table =
199 acpi_os_map_memory(acpi_gbl_root_table_list.tables[table_index].
200 address, length);
201 if (!table) {
202 return;
203 }
204
205 /*
206 * Validate the FADT checksum before we copy the table. Ignore
207 * checksum error as we want to try to get the DSDT and FACS.
208 */
209 (void)acpi_tb_verify_checksum(table, length);
210
211 /* Obtain a local copy of the FADT in common ACPI 2.0+ format */
212
213 acpi_tb_create_local_fadt(table, length);
214
215 /* All done with the real FADT, unmap it */
216
217 acpi_os_unmap_memory(table, length);
218
219 /* Obtain the DSDT and FACS tables via their addresses within the FADT */
220
221 acpi_tb_install_table((acpi_physical_address) acpi_gbl_FADT.Xdsdt,
222 flags, ACPI_SIG_DSDT, ACPI_TABLE_INDEX_DSDT);
223
224 acpi_tb_install_table((acpi_physical_address) acpi_gbl_FADT.Xfacs,
225 flags, ACPI_SIG_FACS, ACPI_TABLE_INDEX_FACS);
226}
227
228/*******************************************************************************
229 *
230 * FUNCTION: acpi_tb_create_local_fadt
231 *
232 * PARAMETERS: Table - Pointer to BIOS FADT
233 * Length - Length of the table
234 *
235 * RETURN: None
236 *
237 * DESCRIPTION: Get a local copy of the FADT and convert it to a common format.
238 * Performs validation on some important FADT fields.
239 *
240 * NOTE: We create a local copy of the FADT regardless of the version.
241 *
242 ******************************************************************************/
243
244void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length)
245{
246
247 /*
248 * Check if the FADT is larger than the largest table that we expect
249 * (the ACPI 2.0/3.0 version). If so, truncate the table, and issue
250 * a warning.
251 */
252 if (length > sizeof(struct acpi_table_fadt)) {
253 ACPI_WARNING((AE_INFO,
254 "FADT (revision %u) is longer than ACPI 2.0 version, "
255 "truncating length 0x%X to 0x%zX",
256 table->revision, (unsigned)length,
257 sizeof(struct acpi_table_fadt)));
258 }
259
260 /* Clear the entire local FADT */
261
262 ACPI_MEMSET(&acpi_gbl_FADT, 0, sizeof(struct acpi_table_fadt));
263
264 /* Copy the original FADT, up to sizeof (struct acpi_table_fadt) */
265
266 ACPI_MEMCPY(&acpi_gbl_FADT, table,
267 ACPI_MIN(length, sizeof(struct acpi_table_fadt)));
268
269 /*
270 * 1) Convert the local copy of the FADT to the common internal format
271 * 2) Validate some of the important values within the FADT
272 */
273 acpi_tb_convert_fadt();
274}
275
276/*******************************************************************************
277 *
278 * FUNCTION: acpi_tb_convert_fadt
279 *
280 * PARAMETERS: None, uses acpi_gbl_FADT
281 *
282 * RETURN: None
283 *
284 * DESCRIPTION: Converts all versions of the FADT to a common internal format.
285 * Expand all 32-bit addresses to 64-bit.
286 *
287 * NOTE: acpi_gbl_FADT must be of size (struct acpi_table_fadt),
288 * and must contain a copy of the actual FADT.
289 *
290 * ACPICA will use the "X" fields of the FADT for all addresses.
291 *
292 * "X" fields are optional extensions to the original V1.0 fields. Even if
293 * they are present in the structure, they can be optionally not used by
294 * setting them to zero. Therefore, we must selectively expand V1.0 fields
295 * if the corresponding X field is zero.
296 *
297 * For ACPI 1.0 FADTs, all address fields are expanded to the corresponding
298 * "X" fields.
299 *
300 * For ACPI 2.0 FADTs, any "X" fields that are NULL are filled in by
301 * expanding the corresponding ACPI 1.0 field.
302 *
303 ******************************************************************************/
304
305static void acpi_tb_convert_fadt(void)
306{
307 u8 pm1_register_bit_width;
308 u8 pm1_register_byte_width;
309 struct acpi_generic_address *target64;
310 u32 i;
311
312 /* Update the local FADT table header length */
313
314 acpi_gbl_FADT.header.length = sizeof(struct acpi_table_fadt);
315
316 /*
317 * Expand the 32-bit FACS and DSDT addresses to 64-bit as necessary.
318 * Later code will always use the X 64-bit field. Also, check for an
319 * address mismatch between the 32-bit and 64-bit address fields
320 * (FIRMWARE_CTRL/X_FIRMWARE_CTRL, DSDT/X_DSDT) which would indicate
321 * the presence of two FACS or two DSDT tables.
322 */
323 if (!acpi_gbl_FADT.Xfacs) {
324 acpi_gbl_FADT.Xfacs = (u64) acpi_gbl_FADT.facs;
325 } else if (acpi_gbl_FADT.facs &&
326 (acpi_gbl_FADT.Xfacs != (u64) acpi_gbl_FADT.facs)) {
327 ACPI_WARNING((AE_INFO,
328 "32/64 FACS address mismatch in FADT - two FACS tables!"));
329 }
330
331 if (!acpi_gbl_FADT.Xdsdt) {
332 acpi_gbl_FADT.Xdsdt = (u64) acpi_gbl_FADT.dsdt;
333 } else if (acpi_gbl_FADT.dsdt &&
334 (acpi_gbl_FADT.Xdsdt != (u64) acpi_gbl_FADT.dsdt)) {
335 ACPI_WARNING((AE_INFO,
336 "32/64 DSDT address mismatch in FADT - two DSDT tables!"));
337 }
338
339 /*
340 * For ACPI 1.0 FADTs (revision 1 or 2), ensure that reserved fields which
341 * should be zero are indeed zero. This will workaround BIOSs that
342 * inadvertently place values in these fields.
343 *
344 * The ACPI 1.0 reserved fields that will be zeroed are the bytes located at
345 * offset 45, 55, 95, and the word located at offset 109, 110.
346 */
347 if (acpi_gbl_FADT.header.revision < FADT2_REVISION_ID) {
348 acpi_gbl_FADT.preferred_profile = 0;
349 acpi_gbl_FADT.pstate_control = 0;
350 acpi_gbl_FADT.cst_control = 0;
351 acpi_gbl_FADT.boot_flags = 0;
352 }
353
354 /*
355 * Expand the ACPI 1.0 32-bit addresses to the ACPI 2.0 64-bit "X"
356 * generic address structures as necessary. Later code will always use
357 * the 64-bit address structures.
358 */
359 for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) {
360 target64 =
361 ACPI_ADD_PTR(struct acpi_generic_address, &acpi_gbl_FADT,
362 fadt_info_table[i].address64);
363
364 /* Expand only if the 64-bit X target is null */
365
366 if (!target64->address) {
367
368 /* The space_id is always I/O for the 32-bit legacy address fields */
369
370 acpi_tb_init_generic_address(target64,
371 ACPI_ADR_SPACE_SYSTEM_IO,
372 *ACPI_ADD_PTR(u8,
373 &acpi_gbl_FADT,
374 fadt_info_table
375 [i].length),
376 (u64) * ACPI_ADD_PTR(u32,
377 &acpi_gbl_FADT,
378 fadt_info_table
379 [i].
380 address32));
381 }
382 }
383
384 /* Validate FADT values now, before we make any changes */
385
386 acpi_tb_validate_fadt();
387
388 /*
389 * Optionally check all register lengths against the default values and
390 * update them if they are incorrect.
391 */
392 if (acpi_gbl_use_default_register_widths) {
393 for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) {
394 target64 =
395 ACPI_ADD_PTR(struct acpi_generic_address,
396 &acpi_gbl_FADT,
397 fadt_info_table[i].address64);
398
399 /*
400 * If a valid register (Address != 0) and the (default_length > 0)
401 * (Not a GPE register), then check the width against the default.
402 */
403 if ((target64->address) &&
404 (fadt_info_table[i].default_length > 0) &&
405 (fadt_info_table[i].default_length !=
406 target64->bit_width)) {
407 ACPI_WARNING((AE_INFO,
408 "Invalid length for %s: %d, using default %d",
409 fadt_info_table[i].name,
410 target64->bit_width,
411 fadt_info_table[i].
412 default_length));
413
414 /* Incorrect size, set width to the default */
415
416 target64->bit_width =
417 fadt_info_table[i].default_length;
418 }
419 }
420 }
421
422 /*
423 * Get the length of the individual PM1 registers (enable and status).
424 * Each register is defined to be (event block length / 2).
425 */
426 pm1_register_bit_width =
427 (u8)ACPI_DIV_2(acpi_gbl_FADT.xpm1a_event_block.bit_width);
428 pm1_register_byte_width = (u8)ACPI_DIV_8(pm1_register_bit_width);
429
430 /*
431 * Adjust the lengths of the PM1 Event Blocks so that they can be used to
432 * access the PM1 status register(s). Use (width / 2)
433 */
434 acpi_gbl_FADT.xpm1a_event_block.bit_width = pm1_register_bit_width;
435 acpi_gbl_FADT.xpm1b_event_block.bit_width = pm1_register_bit_width;
436
437 /*
438 * Calculate separate GAS structs for the PM1 Enable registers.
439 * These addresses do not appear (directly) in the FADT, so it is
440 * useful to calculate them once, here.
441 *
442 * The PM event blocks are split into two register blocks, first is the
443 * PM Status Register block, followed immediately by the PM Enable
444 * Register block. Each is of length (xpm1x_event_block.bit_width/2).
445 *
446 * On various systems the v2 fields (and particularly the bit widths)
447 * cannot be relied upon, though. Hence resort to using the v1 length
448 * here (and warn about the inconsistency).
449 */
450 if (acpi_gbl_FADT.xpm1a_event_block.bit_width
451 != acpi_gbl_FADT.pm1_event_length * 8)
452 printk(KERN_WARNING "FADT: "
453 "X_PM1a_EVT_BLK.bit_width (%u) does not match"
454 " PM1_EVT_LEN (%u)\n",
455 acpi_gbl_FADT.xpm1a_event_block.bit_width,
456 acpi_gbl_FADT.pm1_event_length);
457
458 /* The PM1A register block is required */
459
460 acpi_tb_init_generic_address(&acpi_gbl_xpm1a_enable,
461 acpi_gbl_FADT.xpm1a_event_block.space_id,
462 pm1_register_byte_width,
463 (acpi_gbl_FADT.xpm1a_event_block.address +
464 pm1_register_byte_width));
465 /* Don't forget to copy space_id of the GAS */
466 acpi_gbl_xpm1a_enable.space_id =
467 acpi_gbl_FADT.xpm1a_event_block.space_id;
468
469 /* The PM1B register block is optional, ignore if not present */
470
471 if (acpi_gbl_FADT.xpm1b_event_block.address) {
472 if (acpi_gbl_FADT.xpm1b_event_block.bit_width
473 != acpi_gbl_FADT.pm1_event_length * 8)
474 printk(KERN_WARNING "FADT: "
475 "X_PM1b_EVT_BLK.bit_width (%u) does not match"
476 " PM1_EVT_LEN (%u)\n",
477 acpi_gbl_FADT.xpm1b_event_block.bit_width,
478 acpi_gbl_FADT.pm1_event_length);
479 acpi_tb_init_generic_address(&acpi_gbl_xpm1b_enable,
480 acpi_gbl_FADT.xpm1b_event_block.space_id,
481 pm1_register_byte_width,
482 (acpi_gbl_FADT.xpm1b_event_block.
483 address + pm1_register_byte_width));
484 /* Don't forget to copy space_id of the GAS */
485 acpi_gbl_xpm1b_enable.space_id =
486 acpi_gbl_FADT.xpm1b_event_block.space_id;
487
488 }
489}
490
491/******************************************************************************
492 *
493 * FUNCTION: acpi_tb_validate_fadt
494 *
495 * PARAMETERS: Table - Pointer to the FADT to be validated
496 *
497 * RETURN: None
498 *
499 * DESCRIPTION: Validate various important fields within the FADT. If a problem
500 * is found, issue a message, but no status is returned.
501 * Used by both the table manager and the disassembler.
502 *
503 * Possible additional checks:
504 * (acpi_gbl_FADT.pm1_event_length >= 4)
505 * (acpi_gbl_FADT.pm1_control_length >= 2)
506 * (acpi_gbl_FADT.pm_timer_length >= 4)
507 * Gpe block lengths must be multiple of 2
508 *
509 ******************************************************************************/
510
511static void acpi_tb_validate_fadt(void)
512{
513 char *name;
514 u32 *address32;
515 struct acpi_generic_address *address64;
516 u8 length;
517 u32 i;
518
519 /*
520 * Check for FACS and DSDT address mismatches. An address mismatch between
521 * the 32-bit and 64-bit address fields (FIRMWARE_CTRL/X_FIRMWARE_CTRL and
522 * DSDT/X_DSDT) would indicate the presence of two FACS or two DSDT tables.
523 */
524 if (acpi_gbl_FADT.facs &&
525 (acpi_gbl_FADT.Xfacs != (u64) acpi_gbl_FADT.facs)) {
526 ACPI_WARNING((AE_INFO,
527 "32/64X FACS address mismatch in FADT - "
528 "two FACS tables! %8.8X/%8.8X%8.8X",
529 acpi_gbl_FADT.facs,
530 ACPI_FORMAT_UINT64(acpi_gbl_FADT.Xfacs)));
531 }
532
533 if (acpi_gbl_FADT.dsdt &&
534 (acpi_gbl_FADT.Xdsdt != (u64) acpi_gbl_FADT.dsdt)) {
535 ACPI_WARNING((AE_INFO,
536 "32/64X DSDT address mismatch in FADT - "
537 "two DSDT tables! %8.8X/%8.8X%8.8X",
538 acpi_gbl_FADT.dsdt,
539 ACPI_FORMAT_UINT64(acpi_gbl_FADT.Xdsdt)));
540 }
541
542 /* Examine all of the 64-bit extended address fields (X fields) */
543
544 for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) {
545 /*
546 * Generate pointers to the 32-bit and 64-bit addresses, get the
547 * register length (width), and the register name
548 */
549 address64 = ACPI_ADD_PTR(struct acpi_generic_address,
550 &acpi_gbl_FADT,
551 fadt_info_table[i].address64);
552 address32 =
553 ACPI_ADD_PTR(u32, &acpi_gbl_FADT,
554 fadt_info_table[i].address32);
555 length =
556 *ACPI_ADD_PTR(u8, &acpi_gbl_FADT,
557 fadt_info_table[i].length);
558 name = fadt_info_table[i].name;
559
560 /*
561 * For each extended field, check for length mismatch between the
562 * legacy length field and the corresponding 64-bit X length field.
563 */
564 if (address64 && (address64->bit_width != ACPI_MUL_8(length))) {
565 ACPI_WARNING((AE_INFO,
566 "32/64X length mismatch in %s: %d/%d",
567 name, ACPI_MUL_8(length),
568 address64->bit_width));
569 }
570
571 if (fadt_info_table[i].type & ACPI_FADT_REQUIRED) {
572 /*
573 * Field is required (Pm1a_event, Pm1a_control, pm_timer).
574 * Both the address and length must be non-zero.
575 */
576 if (!address64->address || !length) {
577 ACPI_ERROR((AE_INFO,
578 "Required field %s has zero address and/or length: %8.8X%8.8X/%X",
579 name,
580 ACPI_FORMAT_UINT64(address64->
581 address),
582 length));
583 }
584 } else if (fadt_info_table[i].type & ACPI_FADT_SEPARATE_LENGTH) {
585 /*
586 * Field is optional (PM2Control, GPE0, GPE1) AND has its own
587 * length field. If present, both the address and length must be valid.
588 */
589 if ((address64->address && !length)
590 || (!address64->address && length)) {
591 ACPI_WARNING((AE_INFO,
592 "Optional field %s has zero address or length: %8.8X%8.8X/%X",
593 name,
594 ACPI_FORMAT_UINT64(address64->
595 address),
596 length));
597 }
598 }
599
600 /* If both 32- and 64-bit addresses are valid (non-zero), they must match */
601
602 if (address64->address && *address32 &&
603 (address64->address != (u64) * address32)) {
604 ACPI_ERROR((AE_INFO,
605 "32/64X address mismatch in %s: %8.8X/%8.8X%8.8X, using 64X",
606 name, *address32,
607 ACPI_FORMAT_UINT64(address64->address)));
608 }
609 }
610}
diff --git a/drivers/acpi/acpica/tbfind.c b/drivers/acpi/acpica/tbfind.c
new file mode 100644
index 00000000000..9d20cb6db89
--- /dev/null
+++ b/drivers/acpi/acpica/tbfind.c
@@ -0,0 +1,140 @@
1/******************************************************************************
2 *
3 * Module Name: tbfind - find table
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46#include <acpi/actables.h>
47
48#define _COMPONENT ACPI_TABLES
49ACPI_MODULE_NAME("tbfind")
50
51/*******************************************************************************
52 *
53 * FUNCTION: acpi_tb_find_table
54 *
55 * PARAMETERS: Signature - String with ACPI table signature
56 * oem_id - String with the table OEM ID
57 * oem_table_id - String with the OEM Table ID
58 * table_index - Where the table index is returned
59 *
60 * RETURN: Status and table index
61 *
62 * DESCRIPTION: Find an ACPI table (in the RSDT/XSDT) that matches the
63 * Signature, OEM ID and OEM Table ID. Returns an index that can
64 * be used to get the table header or entire table.
65 *
66 ******************************************************************************/
67acpi_status
68acpi_tb_find_table(char *signature,
69 char *oem_id, char *oem_table_id, u32 *table_index)
70{
71 u32 i;
72 acpi_status status;
73 struct acpi_table_header header;
74
75 ACPI_FUNCTION_TRACE(tb_find_table);
76
77 /* Normalize the input strings */
78
79 ACPI_MEMSET(&header, 0, sizeof(struct acpi_table_header));
80 ACPI_STRNCPY(header.signature, signature, ACPI_NAME_SIZE);
81 ACPI_STRNCPY(header.oem_id, oem_id, ACPI_OEM_ID_SIZE);
82 ACPI_STRNCPY(header.oem_table_id, oem_table_id, ACPI_OEM_TABLE_ID_SIZE);
83
84 /* Search for the table */
85
86 for (i = 0; i < acpi_gbl_root_table_list.count; ++i) {
87 if (ACPI_MEMCMP(&(acpi_gbl_root_table_list.tables[i].signature),
88 header.signature, ACPI_NAME_SIZE)) {
89
90 /* Not the requested table */
91
92 continue;
93 }
94
95 /* Table with matching signature has been found */
96
97 if (!acpi_gbl_root_table_list.tables[i].pointer) {
98
99 /* Table is not currently mapped, map it */
100
101 status =
102 acpi_tb_verify_table(&acpi_gbl_root_table_list.
103 tables[i]);
104 if (ACPI_FAILURE(status)) {
105 return_ACPI_STATUS(status);
106 }
107
108 if (!acpi_gbl_root_table_list.tables[i].pointer) {
109 continue;
110 }
111 }
112
113 /* Check for table match on all IDs */
114
115 if (!ACPI_MEMCMP
116 (acpi_gbl_root_table_list.tables[i].pointer->signature,
117 header.signature, ACPI_NAME_SIZE) && (!oem_id[0]
118 ||
119 !ACPI_MEMCMP
120 (acpi_gbl_root_table_list.
121 tables[i].pointer->
122 oem_id,
123 header.oem_id,
124 ACPI_OEM_ID_SIZE))
125 && (!oem_table_id[0]
126 || !ACPI_MEMCMP(acpi_gbl_root_table_list.tables[i].
127 pointer->oem_table_id,
128 header.oem_table_id,
129 ACPI_OEM_TABLE_ID_SIZE))) {
130 *table_index = i;
131
132 ACPI_DEBUG_PRINT((ACPI_DB_TABLES,
133 "Found table [%4.4s]\n",
134 header.signature));
135 return_ACPI_STATUS(AE_OK);
136 }
137 }
138
139 return_ACPI_STATUS(AE_NOT_FOUND);
140}
diff --git a/drivers/acpi/acpica/tbinstal.c b/drivers/acpi/acpica/tbinstal.c
new file mode 100644
index 00000000000..019b0d84cbe
--- /dev/null
+++ b/drivers/acpi/acpica/tbinstal.c
@@ -0,0 +1,574 @@
1/******************************************************************************
2 *
3 * Module Name: tbinstal - ACPI table installation and removal
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46#include <acpi/acnamesp.h>
47#include <acpi/actables.h>
48
49#define _COMPONENT ACPI_TABLES
50ACPI_MODULE_NAME("tbinstal")
51
52/******************************************************************************
53 *
54 * FUNCTION: acpi_tb_verify_table
55 *
56 * PARAMETERS: table_desc - table
57 *
58 * RETURN: Status
59 *
60 * DESCRIPTION: this function is called to verify and map table
61 *
62 *****************************************************************************/
63acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc)
64{
65 acpi_status status = AE_OK;
66
67 ACPI_FUNCTION_TRACE(tb_verify_table);
68
69 /* Map the table if necessary */
70
71 if (!table_desc->pointer) {
72 if ((table_desc->flags & ACPI_TABLE_ORIGIN_MASK) ==
73 ACPI_TABLE_ORIGIN_MAPPED) {
74 table_desc->pointer =
75 acpi_os_map_memory(table_desc->address,
76 table_desc->length);
77 }
78 if (!table_desc->pointer) {
79 return_ACPI_STATUS(AE_NO_MEMORY);
80 }
81 }
82
83 /* FACS is the odd table, has no standard ACPI header and no checksum */
84
85 if (!ACPI_COMPARE_NAME(&table_desc->signature, ACPI_SIG_FACS)) {
86
87 /* Always calculate checksum, ignore bad checksum if requested */
88
89 status =
90 acpi_tb_verify_checksum(table_desc->pointer,
91 table_desc->length);
92 }
93
94 return_ACPI_STATUS(status);
95}
96
97/*******************************************************************************
98 *
99 * FUNCTION: acpi_tb_add_table
100 *
101 * PARAMETERS: table_desc - Table descriptor
102 * table_index - Where the table index is returned
103 *
104 * RETURN: Status
105 *
106 * DESCRIPTION: This function is called to add the ACPI table
107 *
108 ******************************************************************************/
109
110acpi_status
111acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index)
112{
113 u32 i;
114 acpi_status status = AE_OK;
115
116 ACPI_FUNCTION_TRACE(tb_add_table);
117
118 if (!table_desc->pointer) {
119 status = acpi_tb_verify_table(table_desc);
120 if (ACPI_FAILURE(status) || !table_desc->pointer) {
121 return_ACPI_STATUS(status);
122 }
123 }
124
125 /*
126 * Originally, we checked the table signature for "SSDT" or "PSDT" here.
127 * Next, we added support for OEMx tables, signature "OEM".
128 * Valid tables were encountered with a null signature, so we've just
129 * given up on validating the signature, since it seems to be a waste
130 * of code. The original code was removed (05/2008).
131 */
132
133 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
134
135 /* Check if table is already registered */
136
137 for (i = 0; i < acpi_gbl_root_table_list.count; ++i) {
138 if (!acpi_gbl_root_table_list.tables[i].pointer) {
139 status =
140 acpi_tb_verify_table(&acpi_gbl_root_table_list.
141 tables[i]);
142 if (ACPI_FAILURE(status)
143 || !acpi_gbl_root_table_list.tables[i].pointer) {
144 continue;
145 }
146 }
147
148 /*
149 * Check for a table match on the entire table length,
150 * not just the header.
151 */
152 if (table_desc->length !=
153 acpi_gbl_root_table_list.tables[i].length) {
154 continue;
155 }
156
157 if (ACPI_MEMCMP(table_desc->pointer,
158 acpi_gbl_root_table_list.tables[i].pointer,
159 acpi_gbl_root_table_list.tables[i].length)) {
160 continue;
161 }
162
163 /*
164 * Note: the current mechanism does not unregister a table if it is
165 * dynamically unloaded. The related namespace entries are deleted,
166 * but the table remains in the root table list.
167 *
168 * The assumption here is that the number of different tables that
169 * will be loaded is actually small, and there is minimal overhead
170 * in just keeping the table in case it is needed again.
171 *
172 * If this assumption changes in the future (perhaps on large
173 * machines with many table load/unload operations), tables will
174 * need to be unregistered when they are unloaded, and slots in the
175 * root table list should be reused when empty.
176 */
177
178 /*
179 * Table is already registered.
180 * We can delete the table that was passed as a parameter.
181 */
182 acpi_tb_delete_table(table_desc);
183 *table_index = i;
184
185 if (acpi_gbl_root_table_list.tables[i].
186 flags & ACPI_TABLE_IS_LOADED) {
187
188 /* Table is still loaded, this is an error */
189
190 status = AE_ALREADY_EXISTS;
191 goto release;
192 } else {
193 /* Table was unloaded, allow it to be reloaded */
194
195 table_desc->pointer =
196 acpi_gbl_root_table_list.tables[i].pointer;
197 table_desc->address =
198 acpi_gbl_root_table_list.tables[i].address;
199 status = AE_OK;
200 goto print_header;
201 }
202 }
203
204 /* Add the table to the global root table list */
205
206 status = acpi_tb_store_table(table_desc->address, table_desc->pointer,
207 table_desc->length, table_desc->flags,
208 table_index);
209 if (ACPI_FAILURE(status)) {
210 goto release;
211 }
212
213 print_header:
214 acpi_tb_print_table_header(table_desc->address, table_desc->pointer);
215
216 release:
217 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
218 return_ACPI_STATUS(status);
219}
220
221/*******************************************************************************
222 *
223 * FUNCTION: acpi_tb_resize_root_table_list
224 *
225 * PARAMETERS: None
226 *
227 * RETURN: Status
228 *
229 * DESCRIPTION: Expand the size of global table array
230 *
231 ******************************************************************************/
232
233acpi_status acpi_tb_resize_root_table_list(void)
234{
235 struct acpi_table_desc *tables;
236
237 ACPI_FUNCTION_TRACE(tb_resize_root_table_list);
238
239 /* allow_resize flag is a parameter to acpi_initialize_tables */
240
241 if (!(acpi_gbl_root_table_list.flags & ACPI_ROOT_ALLOW_RESIZE)) {
242 ACPI_ERROR((AE_INFO,
243 "Resize of Root Table Array is not allowed"));
244 return_ACPI_STATUS(AE_SUPPORT);
245 }
246
247 /* Increase the Table Array size */
248
249 tables = ACPI_ALLOCATE_ZEROED(((acpi_size) acpi_gbl_root_table_list.
250 size + ACPI_ROOT_TABLE_SIZE_INCREMENT)
251 * sizeof(struct acpi_table_desc));
252 if (!tables) {
253 ACPI_ERROR((AE_INFO,
254 "Could not allocate new root table array"));
255 return_ACPI_STATUS(AE_NO_MEMORY);
256 }
257
258 /* Copy and free the previous table array */
259
260 if (acpi_gbl_root_table_list.tables) {
261 ACPI_MEMCPY(tables, acpi_gbl_root_table_list.tables,
262 (acpi_size) acpi_gbl_root_table_list.size *
263 sizeof(struct acpi_table_desc));
264
265 if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) {
266 ACPI_FREE(acpi_gbl_root_table_list.tables);
267 }
268 }
269
270 acpi_gbl_root_table_list.tables = tables;
271 acpi_gbl_root_table_list.size += ACPI_ROOT_TABLE_SIZE_INCREMENT;
272 acpi_gbl_root_table_list.flags |= (u8) ACPI_ROOT_ORIGIN_ALLOCATED;
273
274 return_ACPI_STATUS(AE_OK);
275}
276
277/*******************************************************************************
278 *
279 * FUNCTION: acpi_tb_store_table
280 *
281 * PARAMETERS: Address - Table address
282 * Table - Table header
283 * Length - Table length
284 * Flags - flags
285 *
286 * RETURN: Status and table index.
287 *
288 * DESCRIPTION: Add an ACPI table to the global table list
289 *
290 ******************************************************************************/
291
292acpi_status
293acpi_tb_store_table(acpi_physical_address address,
294 struct acpi_table_header *table,
295 u32 length, u8 flags, u32 *table_index)
296{
297 acpi_status status = AE_OK;
298
299 /* Ensure that there is room for the table in the Root Table List */
300
301 if (acpi_gbl_root_table_list.count >= acpi_gbl_root_table_list.size) {
302 status = acpi_tb_resize_root_table_list();
303 if (ACPI_FAILURE(status)) {
304 return (status);
305 }
306 }
307
308 /* Initialize added table */
309
310 acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count].
311 address = address;
312 acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count].
313 pointer = table;
314 acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count].length =
315 length;
316 acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count].
317 owner_id = 0;
318 acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count].flags =
319 flags;
320
321 ACPI_MOVE_32_TO_32(&
322 (acpi_gbl_root_table_list.
323 tables[acpi_gbl_root_table_list.count].signature),
324 table->signature);
325
326 *table_index = acpi_gbl_root_table_list.count;
327 acpi_gbl_root_table_list.count++;
328 return (status);
329}
330
331/*******************************************************************************
332 *
333 * FUNCTION: acpi_tb_delete_table
334 *
335 * PARAMETERS: table_index - Table index
336 *
337 * RETURN: None
338 *
339 * DESCRIPTION: Delete one internal ACPI table
340 *
341 ******************************************************************************/
342
343void acpi_tb_delete_table(struct acpi_table_desc *table_desc)
344{
345 /* Table must be mapped or allocated */
346 if (!table_desc->pointer) {
347 return;
348 }
349 switch (table_desc->flags & ACPI_TABLE_ORIGIN_MASK) {
350 case ACPI_TABLE_ORIGIN_MAPPED:
351 acpi_os_unmap_memory(table_desc->pointer, table_desc->length);
352 break;
353 case ACPI_TABLE_ORIGIN_ALLOCATED:
354 ACPI_FREE(table_desc->pointer);
355 break;
356 default:;
357 }
358
359 table_desc->pointer = NULL;
360}
361
362/*******************************************************************************
363 *
364 * FUNCTION: acpi_tb_terminate
365 *
366 * PARAMETERS: None
367 *
368 * RETURN: None
369 *
370 * DESCRIPTION: Delete all internal ACPI tables
371 *
372 ******************************************************************************/
373
374void acpi_tb_terminate(void)
375{
376 u32 i;
377
378 ACPI_FUNCTION_TRACE(tb_terminate);
379
380 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
381
382 /* Delete the individual tables */
383
384 for (i = 0; i < acpi_gbl_root_table_list.count; ++i) {
385 acpi_tb_delete_table(&acpi_gbl_root_table_list.tables[i]);
386 }
387
388 /*
389 * Delete the root table array if allocated locally. Array cannot be
390 * mapped, so we don't need to check for that flag.
391 */
392 if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) {
393 ACPI_FREE(acpi_gbl_root_table_list.tables);
394 }
395
396 acpi_gbl_root_table_list.tables = NULL;
397 acpi_gbl_root_table_list.flags = 0;
398 acpi_gbl_root_table_list.count = 0;
399
400 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "ACPI Tables freed\n"));
401 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
402}
403
404/*******************************************************************************
405 *
406 * FUNCTION: acpi_tb_delete_namespace_by_owner
407 *
408 * PARAMETERS: table_index - Table index
409 *
410 * RETURN: None
411 *
412 * DESCRIPTION: Delete all namespace objects created when this table was loaded.
413 *
414 ******************************************************************************/
415
416void acpi_tb_delete_namespace_by_owner(u32 table_index)
417{
418 acpi_owner_id owner_id;
419
420 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
421 if (table_index < acpi_gbl_root_table_list.count) {
422 owner_id =
423 acpi_gbl_root_table_list.tables[table_index].owner_id;
424 } else {
425 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
426 return;
427 }
428
429 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
430 acpi_ns_delete_namespace_by_owner(owner_id);
431}
432
433/*******************************************************************************
434 *
435 * FUNCTION: acpi_tb_allocate_owner_id
436 *
437 * PARAMETERS: table_index - Table index
438 *
439 * RETURN: Status
440 *
441 * DESCRIPTION: Allocates owner_id in table_desc
442 *
443 ******************************************************************************/
444
445acpi_status acpi_tb_allocate_owner_id(u32 table_index)
446{
447 acpi_status status = AE_BAD_PARAMETER;
448
449 ACPI_FUNCTION_TRACE(tb_allocate_owner_id);
450
451 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
452 if (table_index < acpi_gbl_root_table_list.count) {
453 status = acpi_ut_allocate_owner_id
454 (&(acpi_gbl_root_table_list.tables[table_index].owner_id));
455 }
456
457 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
458 return_ACPI_STATUS(status);
459}
460
461/*******************************************************************************
462 *
463 * FUNCTION: acpi_tb_release_owner_id
464 *
465 * PARAMETERS: table_index - Table index
466 *
467 * RETURN: Status
468 *
469 * DESCRIPTION: Releases owner_id in table_desc
470 *
471 ******************************************************************************/
472
473acpi_status acpi_tb_release_owner_id(u32 table_index)
474{
475 acpi_status status = AE_BAD_PARAMETER;
476
477 ACPI_FUNCTION_TRACE(tb_release_owner_id);
478
479 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
480 if (table_index < acpi_gbl_root_table_list.count) {
481 acpi_ut_release_owner_id(&
482 (acpi_gbl_root_table_list.
483 tables[table_index].owner_id));
484 status = AE_OK;
485 }
486
487 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
488 return_ACPI_STATUS(status);
489}
490
491/*******************************************************************************
492 *
493 * FUNCTION: acpi_tb_get_owner_id
494 *
495 * PARAMETERS: table_index - Table index
496 * owner_id - Where the table owner_id is returned
497 *
498 * RETURN: Status
499 *
500 * DESCRIPTION: returns owner_id for the ACPI table
501 *
502 ******************************************************************************/
503
504acpi_status acpi_tb_get_owner_id(u32 table_index, acpi_owner_id *owner_id)
505{
506 acpi_status status = AE_BAD_PARAMETER;
507
508 ACPI_FUNCTION_TRACE(tb_get_owner_id);
509
510 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
511 if (table_index < acpi_gbl_root_table_list.count) {
512 *owner_id =
513 acpi_gbl_root_table_list.tables[table_index].owner_id;
514 status = AE_OK;
515 }
516
517 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
518 return_ACPI_STATUS(status);
519}
520
521/*******************************************************************************
522 *
523 * FUNCTION: acpi_tb_is_table_loaded
524 *
525 * PARAMETERS: table_index - Table index
526 *
527 * RETURN: Table Loaded Flag
528 *
529 ******************************************************************************/
530
531u8 acpi_tb_is_table_loaded(u32 table_index)
532{
533 u8 is_loaded = FALSE;
534
535 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
536 if (table_index < acpi_gbl_root_table_list.count) {
537 is_loaded = (u8)
538 (acpi_gbl_root_table_list.tables[table_index].
539 flags & ACPI_TABLE_IS_LOADED);
540 }
541
542 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
543 return (is_loaded);
544}
545
546/*******************************************************************************
547 *
548 * FUNCTION: acpi_tb_set_table_loaded_flag
549 *
550 * PARAMETERS: table_index - Table index
551 * is_loaded - TRUE if table is loaded, FALSE otherwise
552 *
553 * RETURN: None
554 *
555 * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE.
556 *
557 ******************************************************************************/
558
559void acpi_tb_set_table_loaded_flag(u32 table_index, u8 is_loaded)
560{
561
562 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
563 if (table_index < acpi_gbl_root_table_list.count) {
564 if (is_loaded) {
565 acpi_gbl_root_table_list.tables[table_index].flags |=
566 ACPI_TABLE_IS_LOADED;
567 } else {
568 acpi_gbl_root_table_list.tables[table_index].flags &=
569 ~ACPI_TABLE_IS_LOADED;
570 }
571 }
572
573 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
574}
diff --git a/drivers/acpi/acpica/tbutils.c b/drivers/acpi/acpica/tbutils.c
new file mode 100644
index 00000000000..4eb7189974c
--- /dev/null
+++ b/drivers/acpi/acpica/tbutils.c
@@ -0,0 +1,582 @@
1/******************************************************************************
2 *
3 * Module Name: tbutils - table utilities
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46#include <acpi/actables.h>
47
48#define _COMPONENT ACPI_TABLES
49ACPI_MODULE_NAME("tbutils")
50
51/* Local prototypes */
52static acpi_physical_address
53acpi_tb_get_root_table_entry(u8 *table_entry, u32 table_entry_size);
54
55/*******************************************************************************
56 *
57 * FUNCTION: acpi_tb_check_xsdt
58 *
59 * PARAMETERS: address - Pointer to the XSDT
60 *
61 * RETURN: status
62 * AE_OK - XSDT is okay
63 * AE_NO_MEMORY - can't map XSDT
64 * AE_INVALID_TABLE_LENGTH - invalid table length
65 * AE_NULL_ENTRY - XSDT has NULL entry
66 *
67 * DESCRIPTION: validate XSDT
68******************************************************************************/
69
70static acpi_status
71acpi_tb_check_xsdt(acpi_physical_address address)
72{
73 struct acpi_table_header *table;
74 u32 length;
75 u64 xsdt_entry_address;
76 u8 *table_entry;
77 u32 table_count;
78 int i;
79
80 table = acpi_os_map_memory(address, sizeof(struct acpi_table_header));
81 if (!table)
82 return AE_NO_MEMORY;
83
84 length = table->length;
85 acpi_os_unmap_memory(table, sizeof(struct acpi_table_header));
86 if (length < sizeof(struct acpi_table_header))
87 return AE_INVALID_TABLE_LENGTH;
88
89 table = acpi_os_map_memory(address, length);
90 if (!table)
91 return AE_NO_MEMORY;
92
93 /* Calculate the number of tables described in XSDT */
94 table_count =
95 (u32) ((table->length -
96 sizeof(struct acpi_table_header)) / sizeof(u64));
97 table_entry =
98 ACPI_CAST_PTR(u8, table) + sizeof(struct acpi_table_header);
99 for (i = 0; i < table_count; i++) {
100 ACPI_MOVE_64_TO_64(&xsdt_entry_address, table_entry);
101 if (!xsdt_entry_address) {
102 /* XSDT has NULL entry */
103 break;
104 }
105 table_entry += sizeof(u64);
106 }
107 acpi_os_unmap_memory(table, length);
108
109 if (i < table_count)
110 return AE_NULL_ENTRY;
111 else
112 return AE_OK;
113}
114
115/*******************************************************************************
116 *
117 * FUNCTION: acpi_tb_initialize_facs
118 *
119 * PARAMETERS: None
120 *
121 * RETURN: Status
122 *
123 * DESCRIPTION: Create a permanent mapping for the FADT and save it in a global
124 * for accessing the Global Lock and Firmware Waking Vector
125 *
126 ******************************************************************************/
127
128acpi_status acpi_tb_initialize_facs(void)
129{
130 acpi_status status;
131
132 status = acpi_get_table_by_index(ACPI_TABLE_INDEX_FACS,
133 ACPI_CAST_INDIRECT_PTR(struct
134 acpi_table_header,
135 &acpi_gbl_FACS));
136 return status;
137}
138
139/*******************************************************************************
140 *
141 * FUNCTION: acpi_tb_tables_loaded
142 *
143 * PARAMETERS: None
144 *
145 * RETURN: TRUE if required ACPI tables are loaded
146 *
147 * DESCRIPTION: Determine if the minimum required ACPI tables are present
148 * (FADT, FACS, DSDT)
149 *
150 ******************************************************************************/
151
152u8 acpi_tb_tables_loaded(void)
153{
154
155 if (acpi_gbl_root_table_list.count >= 3) {
156 return (TRUE);
157 }
158
159 return (FALSE);
160}
161
162/*******************************************************************************
163 *
164 * FUNCTION: acpi_tb_print_table_header
165 *
166 * PARAMETERS: Address - Table physical address
167 * Header - Table header
168 *
169 * RETURN: None
170 *
171 * DESCRIPTION: Print an ACPI table header. Special cases for FACS and RSDP.
172 *
173 ******************************************************************************/
174
175void
176acpi_tb_print_table_header(acpi_physical_address address,
177 struct acpi_table_header *header)
178{
179
180 if (ACPI_COMPARE_NAME(header->signature, ACPI_SIG_FACS)) {
181
182 /* FACS only has signature and length fields of common table header */
183
184 ACPI_INFO((AE_INFO, "%4.4s %08lX, %04X",
185 header->signature, (unsigned long)address,
186 header->length));
187 } else if (ACPI_COMPARE_NAME(header->signature, ACPI_SIG_RSDP)) {
188
189 /* RSDP has no common fields */
190
191 ACPI_INFO((AE_INFO, "RSDP %08lX, %04X (r%d %6.6s)",
192 (unsigned long)address,
193 (ACPI_CAST_PTR(struct acpi_table_rsdp, header)->
194 revision >
195 0) ? ACPI_CAST_PTR(struct acpi_table_rsdp,
196 header)->length : 20,
197 ACPI_CAST_PTR(struct acpi_table_rsdp,
198 header)->revision,
199 ACPI_CAST_PTR(struct acpi_table_rsdp,
200 header)->oem_id));
201 } else {
202 /* Standard ACPI table with full common header */
203
204 ACPI_INFO((AE_INFO,
205 "%4.4s %08lX, %04X (r%d %6.6s %8.8s %8X %4.4s %8X)",
206 header->signature, (unsigned long)address,
207 header->length, header->revision, header->oem_id,
208 header->oem_table_id, header->oem_revision,
209 header->asl_compiler_id,
210 header->asl_compiler_revision));
211 }
212}
213
214/*******************************************************************************
215 *
216 * FUNCTION: acpi_tb_validate_checksum
217 *
218 * PARAMETERS: Table - ACPI table to verify
219 * Length - Length of entire table
220 *
221 * RETURN: Status
222 *
223 * DESCRIPTION: Verifies that the table checksums to zero. Optionally returns
224 * exception on bad checksum.
225 *
226 ******************************************************************************/
227
228acpi_status acpi_tb_verify_checksum(struct acpi_table_header *table, u32 length)
229{
230 u8 checksum;
231
232 /* Compute the checksum on the table */
233
234 checksum = acpi_tb_checksum(ACPI_CAST_PTR(u8, table), length);
235
236 /* Checksum ok? (should be zero) */
237
238 if (checksum) {
239 ACPI_WARNING((AE_INFO,
240 "Incorrect checksum in table [%4.4s] - %2.2X, should be %2.2X",
241 table->signature, table->checksum,
242 (u8) (table->checksum - checksum)));
243
244#if (ACPI_CHECKSUM_ABORT)
245
246 return (AE_BAD_CHECKSUM);
247#endif
248 }
249
250 return (AE_OK);
251}
252
253/*******************************************************************************
254 *
255 * FUNCTION: acpi_tb_checksum
256 *
257 * PARAMETERS: Buffer - Pointer to memory region to be checked
258 * Length - Length of this memory region
259 *
260 * RETURN: Checksum (u8)
261 *
262 * DESCRIPTION: Calculates circular checksum of memory region.
263 *
264 ******************************************************************************/
265
266u8 acpi_tb_checksum(u8 *buffer, u32 length)
267{
268 u8 sum = 0;
269 u8 *end = buffer + length;
270
271 while (buffer < end) {
272 sum = (u8) (sum + *(buffer++));
273 }
274
275 return sum;
276}
277
278/*******************************************************************************
279 *
280 * FUNCTION: acpi_tb_install_table
281 *
282 * PARAMETERS: Address - Physical address of DSDT or FACS
283 * Flags - Flags
284 * Signature - Table signature, NULL if no need to
285 * match
286 * table_index - Index into root table array
287 *
288 * RETURN: None
289 *
290 * DESCRIPTION: Install an ACPI table into the global data structure.
291 *
292 ******************************************************************************/
293
294void
295acpi_tb_install_table(acpi_physical_address address,
296 u8 flags, char *signature, u32 table_index)
297{
298 struct acpi_table_header *table;
299
300 if (!address) {
301 ACPI_ERROR((AE_INFO,
302 "Null physical address for ACPI table [%s]",
303 signature));
304 return;
305 }
306
307 /* Map just the table header */
308
309 table = acpi_os_map_memory(address, sizeof(struct acpi_table_header));
310 if (!table) {
311 return;
312 }
313
314 /* If a particular signature is expected, signature must match */
315
316 if (signature && !ACPI_COMPARE_NAME(table->signature, signature)) {
317 ACPI_ERROR((AE_INFO,
318 "Invalid signature 0x%X for ACPI table [%s]",
319 *ACPI_CAST_PTR(u32, table->signature), signature));
320 goto unmap_and_exit;
321 }
322
323 /* Initialize the table entry */
324
325 acpi_gbl_root_table_list.tables[table_index].address = address;
326 acpi_gbl_root_table_list.tables[table_index].length = table->length;
327 acpi_gbl_root_table_list.tables[table_index].flags = flags;
328
329 ACPI_MOVE_32_TO_32(&
330 (acpi_gbl_root_table_list.tables[table_index].
331 signature), table->signature);
332
333 acpi_tb_print_table_header(address, table);
334
335 if (table_index == ACPI_TABLE_INDEX_DSDT) {
336
337 /* Global integer width is based upon revision of the DSDT */
338
339 acpi_ut_set_integer_width(table->revision);
340 }
341
342 unmap_and_exit:
343 acpi_os_unmap_memory(table, sizeof(struct acpi_table_header));
344}
345
346/*******************************************************************************
347 *
348 * FUNCTION: acpi_tb_get_root_table_entry
349 *
350 * PARAMETERS: table_entry - Pointer to the RSDT/XSDT table entry
351 * table_entry_size - sizeof 32 or 64 (RSDT or XSDT)
352 *
353 * RETURN: Physical address extracted from the root table
354 *
355 * DESCRIPTION: Get one root table entry. Handles 32-bit and 64-bit cases on
356 * both 32-bit and 64-bit platforms
357 *
358 * NOTE: acpi_physical_address is 32-bit on 32-bit platforms, 64-bit on
359 * 64-bit platforms.
360 *
361 ******************************************************************************/
362
363static acpi_physical_address
364acpi_tb_get_root_table_entry(u8 *table_entry, u32 table_entry_size)
365{
366 u64 address64;
367
368 /*
369 * Get the table physical address (32-bit for RSDT, 64-bit for XSDT):
370 * Note: Addresses are 32-bit aligned (not 64) in both RSDT and XSDT
371 */
372 if (table_entry_size == sizeof(u32)) {
373 /*
374 * 32-bit platform, RSDT: Return 32-bit table entry
375 * 64-bit platform, RSDT: Expand 32-bit to 64-bit and return
376 */
377 return ((acpi_physical_address)
378 (*ACPI_CAST_PTR(u32, table_entry)));
379 } else {
380 /*
381 * 32-bit platform, XSDT: Truncate 64-bit to 32-bit and return
382 * 64-bit platform, XSDT: Move (unaligned) 64-bit to local, return 64-bit
383 */
384 ACPI_MOVE_64_TO_64(&address64, table_entry);
385
386#if ACPI_MACHINE_WIDTH == 32
387 if (address64 > ACPI_UINT32_MAX) {
388
389 /* Will truncate 64-bit address to 32 bits, issue warning */
390
391 ACPI_WARNING((AE_INFO,
392 "64-bit Physical Address in XSDT is too large (%8.8X%8.8X), truncating",
393 ACPI_FORMAT_UINT64(address64)));
394 }
395#endif
396 return ((acpi_physical_address) (address64));
397 }
398}
399
400/*******************************************************************************
401 *
402 * FUNCTION: acpi_tb_parse_root_table
403 *
404 * PARAMETERS: Rsdp - Pointer to the RSDP
405 * Flags - Flags
406 *
407 * RETURN: Status
408 *
409 * DESCRIPTION: This function is called to parse the Root System Description
410 * Table (RSDT or XSDT)
411 *
412 * NOTE: Tables are mapped (not copied) for efficiency. The FACS must
413 * be mapped and cannot be copied because it contains the actual
414 * memory location of the ACPI Global Lock.
415 *
416 ******************************************************************************/
417
418acpi_status __init
419acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags)
420{
421 struct acpi_table_rsdp *rsdp;
422 u32 table_entry_size;
423 u32 i;
424 u32 table_count;
425 struct acpi_table_header *table;
426 acpi_physical_address address;
427 acpi_physical_address uninitialized_var(rsdt_address);
428 u32 length;
429 u8 *table_entry;
430 acpi_status status;
431
432 ACPI_FUNCTION_TRACE(tb_parse_root_table);
433
434 /*
435 * Map the entire RSDP and extract the address of the RSDT or XSDT
436 */
437 rsdp = acpi_os_map_memory(rsdp_address, sizeof(struct acpi_table_rsdp));
438 if (!rsdp) {
439 return_ACPI_STATUS(AE_NO_MEMORY);
440 }
441
442 acpi_tb_print_table_header(rsdp_address,
443 ACPI_CAST_PTR(struct acpi_table_header,
444 rsdp));
445
446 /* Differentiate between RSDT and XSDT root tables */
447
448 if (rsdp->revision > 1 && rsdp->xsdt_physical_address) {
449 /*
450 * Root table is an XSDT (64-bit physical addresses). We must use the
451 * XSDT if the revision is > 1 and the XSDT pointer is present, as per
452 * the ACPI specification.
453 */
454 address = (acpi_physical_address) rsdp->xsdt_physical_address;
455 table_entry_size = sizeof(u64);
456 rsdt_address = (acpi_physical_address)
457 rsdp->rsdt_physical_address;
458 } else {
459 /* Root table is an RSDT (32-bit physical addresses) */
460
461 address = (acpi_physical_address) rsdp->rsdt_physical_address;
462 table_entry_size = sizeof(u32);
463 }
464
465 /*
466 * It is not possible to map more than one entry in some environments,
467 * so unmap the RSDP here before mapping other tables
468 */
469 acpi_os_unmap_memory(rsdp, sizeof(struct acpi_table_rsdp));
470
471 if (table_entry_size == sizeof(u64)) {
472 if (acpi_tb_check_xsdt(address) == AE_NULL_ENTRY) {
473 /* XSDT has NULL entry, RSDT is used */
474 address = rsdt_address;
475 table_entry_size = sizeof(u32);
476 ACPI_WARNING((AE_INFO, "BIOS XSDT has NULL entry, "
477 "using RSDT"));
478 }
479 }
480 /* Map the RSDT/XSDT table header to get the full table length */
481
482 table = acpi_os_map_memory(address, sizeof(struct acpi_table_header));
483 if (!table) {
484 return_ACPI_STATUS(AE_NO_MEMORY);
485 }
486
487 acpi_tb_print_table_header(address, table);
488
489 /* Get the length of the full table, verify length and map entire table */
490
491 length = table->length;
492 acpi_os_unmap_memory(table, sizeof(struct acpi_table_header));
493
494 if (length < sizeof(struct acpi_table_header)) {
495 ACPI_ERROR((AE_INFO, "Invalid length 0x%X in RSDT/XSDT",
496 length));
497 return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH);
498 }
499
500 table = acpi_os_map_memory(address, length);
501 if (!table) {
502 return_ACPI_STATUS(AE_NO_MEMORY);
503 }
504
505 /* Validate the root table checksum */
506
507 status = acpi_tb_verify_checksum(table, length);
508 if (ACPI_FAILURE(status)) {
509 acpi_os_unmap_memory(table, length);
510 return_ACPI_STATUS(status);
511 }
512
513 /* Calculate the number of tables described in the root table */
514
515 table_count =
516 (u32) ((table->length -
517 sizeof(struct acpi_table_header)) / table_entry_size);
518
519 /*
520 * First two entries in the table array are reserved for the DSDT and FACS,
521 * which are not actually present in the RSDT/XSDT - they come from the FADT
522 */
523 table_entry =
524 ACPI_CAST_PTR(u8, table) + sizeof(struct acpi_table_header);
525 acpi_gbl_root_table_list.count = 2;
526
527 /*
528 * Initialize the root table array from the RSDT/XSDT
529 */
530 for (i = 0; i < table_count; i++) {
531 if (acpi_gbl_root_table_list.count >=
532 acpi_gbl_root_table_list.size) {
533
534 /* There is no more room in the root table array, attempt resize */
535
536 status = acpi_tb_resize_root_table_list();
537 if (ACPI_FAILURE(status)) {
538 ACPI_WARNING((AE_INFO,
539 "Truncating %u table entries!",
540 (unsigned)
541 (acpi_gbl_root_table_list.size -
542 acpi_gbl_root_table_list.
543 count)));
544 break;
545 }
546 }
547
548 /* Get the table physical address (32-bit for RSDT, 64-bit for XSDT) */
549
550 acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count].
551 address =
552 acpi_tb_get_root_table_entry(table_entry, table_entry_size);
553
554 table_entry += table_entry_size;
555 acpi_gbl_root_table_list.count++;
556 }
557
558 /*
559 * It is not possible to map more than one entry in some environments,
560 * so unmap the root table here before mapping other tables
561 */
562 acpi_os_unmap_memory(table, length);
563
564 /*
565 * Complete the initialization of the root table array by examining
566 * the header of each table
567 */
568 for (i = 2; i < acpi_gbl_root_table_list.count; i++) {
569 acpi_tb_install_table(acpi_gbl_root_table_list.tables[i].
570 address, flags, NULL, i);
571
572 /* Special case for FADT - get the DSDT and FACS */
573
574 if (ACPI_COMPARE_NAME
575 (&acpi_gbl_root_table_list.tables[i].signature,
576 ACPI_SIG_FADT)) {
577 acpi_tb_parse_fadt(i, flags);
578 }
579 }
580
581 return_ACPI_STATUS(AE_OK);
582}
diff --git a/drivers/acpi/acpica/tbxface.c b/drivers/acpi/acpica/tbxface.c
new file mode 100644
index 00000000000..115796694a2
--- /dev/null
+++ b/drivers/acpi/acpica/tbxface.c
@@ -0,0 +1,735 @@
1/******************************************************************************
2 *
3 * Module Name: tbxface - Public interfaces to the ACPI subsystem
4 * ACPI table oriented interfaces
5 *
6 *****************************************************************************/
7
8/*
9 * Copyright (C) 2000 - 2008, Intel Corp.
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions, and the following disclaimer,
17 * without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 * substantially similar to the "NO WARRANTY" disclaimer below
20 * ("Disclaimer") and any redistribution must be conditioned upon
21 * including a substantially similar Disclaimer requirement for further
22 * binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 * of any contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
30 *
31 * NO WARRANTY
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
43 */
44
45#include <acpi/acpi.h>
46#include <acpi/accommon.h>
47#include <acpi/acnamesp.h>
48#include <acpi/actables.h>
49
50#define _COMPONENT ACPI_TABLES
51ACPI_MODULE_NAME("tbxface")
52
53/* Local prototypes */
54static acpi_status acpi_tb_load_namespace(void);
55
56static int no_auto_ssdt;
57
58/*******************************************************************************
59 *
60 * FUNCTION: acpi_allocate_root_table
61 *
62 * PARAMETERS: initial_table_count - Size of initial_table_array, in number of
63 * struct acpi_table_desc structures
64 *
65 * RETURN: Status
66 *
67 * DESCRIPTION: Allocate a root table array. Used by i_aSL compiler and
68 * acpi_initialize_tables.
69 *
70 ******************************************************************************/
71
72acpi_status acpi_allocate_root_table(u32 initial_table_count)
73{
74
75 acpi_gbl_root_table_list.size = initial_table_count;
76 acpi_gbl_root_table_list.flags = ACPI_ROOT_ALLOW_RESIZE;
77
78 return (acpi_tb_resize_root_table_list());
79}
80
81/*******************************************************************************
82 *
83 * FUNCTION: acpi_initialize_tables
84 *
85 * PARAMETERS: initial_table_array - Pointer to an array of pre-allocated
86 * struct acpi_table_desc structures. If NULL, the
87 * array is dynamically allocated.
88 * initial_table_count - Size of initial_table_array, in number of
89 * struct acpi_table_desc structures
90 * allow_realloc - Flag to tell Table Manager if resize of
91 * pre-allocated array is allowed. Ignored
92 * if initial_table_array is NULL.
93 *
94 * RETURN: Status
95 *
96 * DESCRIPTION: Initialize the table manager, get the RSDP and RSDT/XSDT.
97 *
98 * NOTE: Allows static allocation of the initial table array in order
99 * to avoid the use of dynamic memory in confined environments
100 * such as the kernel boot sequence where it may not be available.
101 *
102 * If the host OS memory managers are initialized, use NULL for
103 * initial_table_array, and the table will be dynamically allocated.
104 *
105 ******************************************************************************/
106
107acpi_status __init
108acpi_initialize_tables(struct acpi_table_desc * initial_table_array,
109 u32 initial_table_count, u8 allow_resize)
110{
111 acpi_physical_address rsdp_address;
112 acpi_status status;
113
114 ACPI_FUNCTION_TRACE(acpi_initialize_tables);
115
116 /*
117 * Set up the Root Table Array
118 * Allocate the table array if requested
119 */
120 if (!initial_table_array) {
121 status = acpi_allocate_root_table(initial_table_count);
122 if (ACPI_FAILURE(status)) {
123 return_ACPI_STATUS(status);
124 }
125 } else {
126 /* Root Table Array has been statically allocated by the host */
127
128 ACPI_MEMSET(initial_table_array, 0,
129 (acpi_size) initial_table_count *
130 sizeof(struct acpi_table_desc));
131
132 acpi_gbl_root_table_list.tables = initial_table_array;
133 acpi_gbl_root_table_list.size = initial_table_count;
134 acpi_gbl_root_table_list.flags = ACPI_ROOT_ORIGIN_UNKNOWN;
135 if (allow_resize) {
136 acpi_gbl_root_table_list.flags |=
137 ACPI_ROOT_ALLOW_RESIZE;
138 }
139 }
140
141 /* Get the address of the RSDP */
142
143 rsdp_address = acpi_os_get_root_pointer();
144 if (!rsdp_address) {
145 return_ACPI_STATUS(AE_NOT_FOUND);
146 }
147
148 /*
149 * Get the root table (RSDT or XSDT) and extract all entries to the local
150 * Root Table Array. This array contains the information of the RSDT/XSDT
151 * in a common, more useable format.
152 */
153 status =
154 acpi_tb_parse_root_table(rsdp_address, ACPI_TABLE_ORIGIN_MAPPED);
155 return_ACPI_STATUS(status);
156}
157
158/*******************************************************************************
159 *
160 * FUNCTION: acpi_reallocate_root_table
161 *
162 * PARAMETERS: None
163 *
164 * RETURN: Status
165 *
166 * DESCRIPTION: Reallocate Root Table List into dynamic memory. Copies the
167 * root list from the previously provided scratch area. Should
168 * be called once dynamic memory allocation is available in the
169 * kernel
170 *
171 ******************************************************************************/
172acpi_status acpi_reallocate_root_table(void)
173{
174 struct acpi_table_desc *tables;
175 acpi_size new_size;
176
177 ACPI_FUNCTION_TRACE(acpi_reallocate_root_table);
178
179 /*
180 * Only reallocate the root table if the host provided a static buffer
181 * for the table array in the call to acpi_initialize_tables.
182 */
183 if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) {
184 return_ACPI_STATUS(AE_SUPPORT);
185 }
186
187 new_size = ((acpi_size) acpi_gbl_root_table_list.count +
188 ACPI_ROOT_TABLE_SIZE_INCREMENT) *
189 sizeof(struct acpi_table_desc);
190
191 /* Create new array and copy the old array */
192
193 tables = ACPI_ALLOCATE_ZEROED(new_size);
194 if (!tables) {
195 return_ACPI_STATUS(AE_NO_MEMORY);
196 }
197
198 ACPI_MEMCPY(tables, acpi_gbl_root_table_list.tables, new_size);
199
200 acpi_gbl_root_table_list.size = acpi_gbl_root_table_list.count;
201 acpi_gbl_root_table_list.tables = tables;
202 acpi_gbl_root_table_list.flags =
203 ACPI_ROOT_ORIGIN_ALLOCATED | ACPI_ROOT_ALLOW_RESIZE;
204
205 return_ACPI_STATUS(AE_OK);
206}
207
208/*******************************************************************************
209 *
210 * FUNCTION: acpi_load_table
211 *
212 * PARAMETERS: table_ptr - pointer to a buffer containing the entire
213 * table to be loaded
214 *
215 * RETURN: Status
216 *
217 * DESCRIPTION: This function is called to load a table from the caller's
218 * buffer. The buffer must contain an entire ACPI Table including
219 * a valid header. The header fields will be verified, and if it
220 * is determined that the table is invalid, the call will fail.
221 *
222 ******************************************************************************/
223acpi_status acpi_load_table(struct acpi_table_header *table_ptr)
224{
225 acpi_status status;
226 u32 table_index;
227 struct acpi_table_desc table_desc;
228
229 if (!table_ptr)
230 return AE_BAD_PARAMETER;
231
232 ACPI_MEMSET(&table_desc, 0, sizeof(struct acpi_table_desc));
233 table_desc.pointer = table_ptr;
234 table_desc.length = table_ptr->length;
235 table_desc.flags = ACPI_TABLE_ORIGIN_UNKNOWN;
236
237 /*
238 * Install the new table into the local data structures
239 */
240 status = acpi_tb_add_table(&table_desc, &table_index);
241 if (ACPI_FAILURE(status)) {
242 return status;
243 }
244 status = acpi_ns_load_table(table_index, acpi_gbl_root_node);
245 return status;
246}
247
248ACPI_EXPORT_SYMBOL(acpi_load_table)
249
250/******************************************************************************
251 *
252 * FUNCTION: acpi_get_table_header
253 *
254 * PARAMETERS: Signature - ACPI signature of needed table
255 * Instance - Which instance (for SSDTs)
256 * out_table_header - The pointer to the table header to fill
257 *
258 * RETURN: Status and pointer to mapped table header
259 *
260 * DESCRIPTION: Finds an ACPI table header.
261 *
262 * NOTE: Caller is responsible in unmapping the header with
263 * acpi_os_unmap_memory
264 *
265 *****************************************************************************/
266acpi_status
267acpi_get_table_header(char *signature,
268 u32 instance, struct acpi_table_header *out_table_header)
269{
270 u32 i;
271 u32 j;
272 struct acpi_table_header *header;
273
274 /* Parameter validation */
275
276 if (!signature || !out_table_header) {
277 return (AE_BAD_PARAMETER);
278 }
279
280 /*
281 * Walk the root table list
282 */
283 for (i = 0, j = 0; i < acpi_gbl_root_table_list.count; i++) {
284 if (!ACPI_COMPARE_NAME
285 (&(acpi_gbl_root_table_list.tables[i].signature),
286 signature)) {
287 continue;
288 }
289
290 if (++j < instance) {
291 continue;
292 }
293
294 if (!acpi_gbl_root_table_list.tables[i].pointer) {
295 if ((acpi_gbl_root_table_list.tables[i].
296 flags & ACPI_TABLE_ORIGIN_MASK) ==
297 ACPI_TABLE_ORIGIN_MAPPED) {
298 header =
299 acpi_os_map_memory(acpi_gbl_root_table_list.
300 tables[i].address,
301 sizeof(struct
302 acpi_table_header));
303 if (!header) {
304 return AE_NO_MEMORY;
305 }
306 ACPI_MEMCPY(out_table_header, header,
307 sizeof(struct acpi_table_header));
308 acpi_os_unmap_memory(header,
309 sizeof(struct
310 acpi_table_header));
311 } else {
312 return AE_NOT_FOUND;
313 }
314 } else {
315 ACPI_MEMCPY(out_table_header,
316 acpi_gbl_root_table_list.tables[i].pointer,
317 sizeof(struct acpi_table_header));
318 }
319 return (AE_OK);
320 }
321
322 return (AE_NOT_FOUND);
323}
324
325ACPI_EXPORT_SYMBOL(acpi_get_table_header)
326
327/******************************************************************************
328 *
329 * FUNCTION: acpi_unload_table_id
330 *
331 * PARAMETERS: id - Owner ID of the table to be removed.
332 *
333 * RETURN: Status
334 *
335 * DESCRIPTION: This routine is used to force the unload of a table (by id)
336 *
337 ******************************************************************************/
338acpi_status acpi_unload_table_id(acpi_owner_id id)
339{
340 int i;
341 acpi_status status = AE_NOT_EXIST;
342
343 ACPI_FUNCTION_TRACE(acpi_unload_table_id);
344
345 /* Find table in the global table list */
346 for (i = 0; i < acpi_gbl_root_table_list.count; ++i) {
347 if (id != acpi_gbl_root_table_list.tables[i].owner_id) {
348 continue;
349 }
350 /*
351 * Delete all namespace objects owned by this table. Note that these
352 * objects can appear anywhere in the namespace by virtue of the AML
353 * "Scope" operator. Thus, we need to track ownership by an ID, not
354 * simply a position within the hierarchy
355 */
356 acpi_tb_delete_namespace_by_owner(i);
357 status = acpi_tb_release_owner_id(i);
358 acpi_tb_set_table_loaded_flag(i, FALSE);
359 break;
360 }
361 return_ACPI_STATUS(status);
362}
363
364ACPI_EXPORT_SYMBOL(acpi_unload_table_id)
365
366/*******************************************************************************
367 *
368 * FUNCTION: acpi_get_table
369 *
370 * PARAMETERS: Signature - ACPI signature of needed table
371 * Instance - Which instance (for SSDTs)
372 * out_table - Where the pointer to the table is returned
373 *
374 * RETURN: Status and pointer to table
375 *
376 * DESCRIPTION: Finds and verifies an ACPI table.
377 *
378 *****************************************************************************/
379acpi_status
380acpi_get_table(char *signature,
381 u32 instance, struct acpi_table_header **out_table)
382{
383 u32 i;
384 u32 j;
385 acpi_status status;
386
387 /* Parameter validation */
388
389 if (!signature || !out_table) {
390 return (AE_BAD_PARAMETER);
391 }
392
393 /*
394 * Walk the root table list
395 */
396 for (i = 0, j = 0; i < acpi_gbl_root_table_list.count; i++) {
397 if (!ACPI_COMPARE_NAME
398 (&(acpi_gbl_root_table_list.tables[i].signature),
399 signature)) {
400 continue;
401 }
402
403 if (++j < instance) {
404 continue;
405 }
406
407 status =
408 acpi_tb_verify_table(&acpi_gbl_root_table_list.tables[i]);
409 if (ACPI_SUCCESS(status)) {
410 *out_table = acpi_gbl_root_table_list.tables[i].pointer;
411 }
412
413 if (!acpi_gbl_permanent_mmap) {
414 acpi_gbl_root_table_list.tables[i].pointer = NULL;
415 }
416
417 return (status);
418 }
419
420 return (AE_NOT_FOUND);
421}
422
423ACPI_EXPORT_SYMBOL(acpi_get_table)
424
425/*******************************************************************************
426 *
427 * FUNCTION: acpi_get_table_by_index
428 *
429 * PARAMETERS: table_index - Table index
430 * Table - Where the pointer to the table is returned
431 *
432 * RETURN: Status and pointer to the table
433 *
434 * DESCRIPTION: Obtain a table by an index into the global table list.
435 *
436 ******************************************************************************/
437acpi_status
438acpi_get_table_by_index(u32 table_index, struct acpi_table_header **table)
439{
440 acpi_status status;
441
442 ACPI_FUNCTION_TRACE(acpi_get_table_by_index);
443
444 /* Parameter validation */
445
446 if (!table) {
447 return_ACPI_STATUS(AE_BAD_PARAMETER);
448 }
449
450 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
451
452 /* Validate index */
453
454 if (table_index >= acpi_gbl_root_table_list.count) {
455 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
456 return_ACPI_STATUS(AE_BAD_PARAMETER);
457 }
458
459 if (!acpi_gbl_root_table_list.tables[table_index].pointer) {
460
461 /* Table is not mapped, map it */
462
463 status =
464 acpi_tb_verify_table(&acpi_gbl_root_table_list.
465 tables[table_index]);
466 if (ACPI_FAILURE(status)) {
467 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
468 return_ACPI_STATUS(status);
469 }
470 }
471
472 *table = acpi_gbl_root_table_list.tables[table_index].pointer;
473 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
474 return_ACPI_STATUS(AE_OK);
475}
476
477ACPI_EXPORT_SYMBOL(acpi_get_table_by_index)
478
479/*******************************************************************************
480 *
481 * FUNCTION: acpi_tb_load_namespace
482 *
483 * PARAMETERS: None
484 *
485 * RETURN: Status
486 *
487 * DESCRIPTION: Load the namespace from the DSDT and all SSDTs/PSDTs found in
488 * the RSDT/XSDT.
489 *
490 ******************************************************************************/
491static acpi_status acpi_tb_load_namespace(void)
492{
493 acpi_status status;
494 struct acpi_table_header *table;
495 u32 i;
496
497 ACPI_FUNCTION_TRACE(tb_load_namespace);
498
499 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
500
501 /*
502 * Load the namespace. The DSDT is required, but any SSDT and PSDT tables
503 * are optional.
504 */
505 if (!acpi_gbl_root_table_list.count ||
506 !ACPI_COMPARE_NAME(&
507 (acpi_gbl_root_table_list.
508 tables[ACPI_TABLE_INDEX_DSDT].signature),
509 ACPI_SIG_DSDT)
510 ||
511 ACPI_FAILURE(acpi_tb_verify_table
512 (&acpi_gbl_root_table_list.
513 tables[ACPI_TABLE_INDEX_DSDT]))) {
514 status = AE_NO_ACPI_TABLES;
515 goto unlock_and_exit;
516 }
517
518 /*
519 * Find DSDT table
520 */
521 status =
522 acpi_os_table_override(acpi_gbl_root_table_list.
523 tables[ACPI_TABLE_INDEX_DSDT].pointer,
524 &table);
525 if (ACPI_SUCCESS(status) && table) {
526 /*
527 * DSDT table has been found
528 */
529 acpi_tb_delete_table(&acpi_gbl_root_table_list.
530 tables[ACPI_TABLE_INDEX_DSDT]);
531 acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].pointer =
532 table;
533 acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].length =
534 table->length;
535 acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].flags =
536 ACPI_TABLE_ORIGIN_UNKNOWN;
537
538 ACPI_INFO((AE_INFO, "Table DSDT replaced by host OS"));
539 acpi_tb_print_table_header(0, table);
540
541 if (no_auto_ssdt == 0) {
542 printk(KERN_WARNING "ACPI: DSDT override uses original SSDTs unless \"acpi_no_auto_ssdt\"\n");
543 }
544 }
545
546 status =
547 acpi_tb_verify_table(&acpi_gbl_root_table_list.
548 tables[ACPI_TABLE_INDEX_DSDT]);
549 if (ACPI_FAILURE(status)) {
550
551 /* A valid DSDT is required */
552
553 status = AE_NO_ACPI_TABLES;
554 goto unlock_and_exit;
555 }
556
557 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
558
559 /*
560 * Load and parse tables.
561 */
562 status = acpi_ns_load_table(ACPI_TABLE_INDEX_DSDT, acpi_gbl_root_node);
563 if (ACPI_FAILURE(status)) {
564 return_ACPI_STATUS(status);
565 }
566
567 /*
568 * Load any SSDT or PSDT tables. Note: Loop leaves tables locked
569 */
570 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
571 for (i = 0; i < acpi_gbl_root_table_list.count; ++i) {
572 if ((!ACPI_COMPARE_NAME
573 (&(acpi_gbl_root_table_list.tables[i].signature),
574 ACPI_SIG_SSDT)
575 &&
576 !ACPI_COMPARE_NAME(&
577 (acpi_gbl_root_table_list.tables[i].
578 signature), ACPI_SIG_PSDT))
579 ||
580 ACPI_FAILURE(acpi_tb_verify_table
581 (&acpi_gbl_root_table_list.tables[i]))) {
582 continue;
583 }
584
585 if (no_auto_ssdt) {
586 printk(KERN_WARNING "ACPI: SSDT ignored due to \"acpi_no_auto_ssdt\"\n");
587 continue;
588 }
589
590 /* Ignore errors while loading tables, get as many as possible */
591
592 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
593 (void)acpi_ns_load_table(i, acpi_gbl_root_node);
594 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
595 }
596
597 ACPI_DEBUG_PRINT((ACPI_DB_INIT, "ACPI Tables successfully acquired\n"));
598
599 unlock_and_exit:
600 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
601 return_ACPI_STATUS(status);
602}
603
604/*******************************************************************************
605 *
606 * FUNCTION: acpi_load_tables
607 *
608 * PARAMETERS: None
609 *
610 * RETURN: Status
611 *
612 * DESCRIPTION: Load the ACPI tables from the RSDT/XSDT
613 *
614 ******************************************************************************/
615
616acpi_status acpi_load_tables(void)
617{
618 acpi_status status;
619
620 ACPI_FUNCTION_TRACE(acpi_load_tables);
621
622 /*
623 * Load the namespace from the tables
624 */
625 status = acpi_tb_load_namespace();
626 if (ACPI_FAILURE(status)) {
627 ACPI_EXCEPTION((AE_INFO, status,
628 "While loading namespace from ACPI tables"));
629 }
630
631 return_ACPI_STATUS(status);
632}
633
634ACPI_EXPORT_SYMBOL(acpi_load_tables)
635
636
637/*******************************************************************************
638 *
639 * FUNCTION: acpi_install_table_handler
640 *
641 * PARAMETERS: Handler - Table event handler
642 * Context - Value passed to the handler on each event
643 *
644 * RETURN: Status
645 *
646 * DESCRIPTION: Install table event handler
647 *
648 ******************************************************************************/
649acpi_status
650acpi_install_table_handler(acpi_tbl_handler handler, void *context)
651{
652 acpi_status status;
653
654 ACPI_FUNCTION_TRACE(acpi_install_table_handler);
655
656 if (!handler) {
657 return_ACPI_STATUS(AE_BAD_PARAMETER);
658 }
659
660 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
661 if (ACPI_FAILURE(status)) {
662 return_ACPI_STATUS(status);
663 }
664
665 /* Don't allow more than one handler */
666
667 if (acpi_gbl_table_handler) {
668 status = AE_ALREADY_EXISTS;
669 goto cleanup;
670 }
671
672 /* Install the handler */
673
674 acpi_gbl_table_handler = handler;
675 acpi_gbl_table_handler_context = context;
676
677 cleanup:
678 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
679 return_ACPI_STATUS(status);
680}
681
682ACPI_EXPORT_SYMBOL(acpi_install_table_handler)
683
684/*******************************************************************************
685 *
686 * FUNCTION: acpi_remove_table_handler
687 *
688 * PARAMETERS: Handler - Table event handler that was installed
689 * previously.
690 *
691 * RETURN: Status
692 *
693 * DESCRIPTION: Remove table event handler
694 *
695 ******************************************************************************/
696acpi_status acpi_remove_table_handler(acpi_tbl_handler handler)
697{
698 acpi_status status;
699
700 ACPI_FUNCTION_TRACE(acpi_remove_table_handler);
701
702 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
703 if (ACPI_FAILURE(status)) {
704 return_ACPI_STATUS(status);
705 }
706
707 /* Make sure that the installed handler is the same */
708
709 if (!handler || handler != acpi_gbl_table_handler) {
710 status = AE_BAD_PARAMETER;
711 goto cleanup;
712 }
713
714 /* Remove the handler */
715
716 acpi_gbl_table_handler = NULL;
717
718 cleanup:
719 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
720 return_ACPI_STATUS(status);
721}
722
723ACPI_EXPORT_SYMBOL(acpi_remove_table_handler)
724
725
726static int __init acpi_no_auto_ssdt_setup(char *s) {
727
728 printk(KERN_NOTICE "ACPI: SSDT auto-load disabled\n");
729
730 no_auto_ssdt = 1;
731
732 return 1;
733}
734
735__setup("acpi_no_auto_ssdt", acpi_no_auto_ssdt_setup);
diff --git a/drivers/acpi/acpica/tbxfroot.c b/drivers/acpi/acpica/tbxfroot.c
new file mode 100644
index 00000000000..3495dca4e86
--- /dev/null
+++ b/drivers/acpi/acpica/tbxfroot.c
@@ -0,0 +1,274 @@
1/******************************************************************************
2 *
3 * Module Name: tbxfroot - Find the root ACPI table (RSDT)
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46#include <acpi/actables.h>
47
48#define _COMPONENT ACPI_TABLES
49ACPI_MODULE_NAME("tbxfroot")
50
51/* Local prototypes */
52static u8 *acpi_tb_scan_memory_for_rsdp(u8 * start_address, u32 length);
53
54static acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp);
55
56/*******************************************************************************
57 *
58 * FUNCTION: acpi_tb_validate_rsdp
59 *
60 * PARAMETERS: Rsdp - Pointer to unvalidated RSDP
61 *
62 * RETURN: Status
63 *
64 * DESCRIPTION: Validate the RSDP (ptr)
65 *
66 ******************************************************************************/
67
68static acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp)
69{
70 ACPI_FUNCTION_ENTRY();
71
72 /*
73 * The signature and checksum must both be correct
74 *
75 * Note: Sometimes there exists more than one RSDP in memory; the valid
76 * RSDP has a valid checksum, all others have an invalid checksum.
77 */
78 if (ACPI_STRNCMP((char *)rsdp, ACPI_SIG_RSDP, sizeof(ACPI_SIG_RSDP) - 1)
79 != 0) {
80
81 /* Nope, BAD Signature */
82
83 return (AE_BAD_SIGNATURE);
84 }
85
86 /* Check the standard checksum */
87
88 if (acpi_tb_checksum((u8 *) rsdp, ACPI_RSDP_CHECKSUM_LENGTH) != 0) {
89 return (AE_BAD_CHECKSUM);
90 }
91
92 /* Check extended checksum if table version >= 2 */
93
94 if ((rsdp->revision >= 2) &&
95 (acpi_tb_checksum((u8 *) rsdp, ACPI_RSDP_XCHECKSUM_LENGTH) != 0)) {
96 return (AE_BAD_CHECKSUM);
97 }
98
99 return (AE_OK);
100}
101
102/*******************************************************************************
103 *
104 * FUNCTION: acpi_find_root_pointer
105 *
106 * PARAMETERS: table_address - Where the table pointer is returned
107 *
108 * RETURN: Status, RSDP physical address
109 *
110 * DESCRIPTION: Search lower 1_mbyte of memory for the root system descriptor
111 * pointer structure. If it is found, set *RSDP to point to it.
112 *
113 * NOTE1: The RSDP must be either in the first 1_k of the Extended
114 * BIOS Data Area or between E0000 and FFFFF (From ACPI Spec.)
115 * Only a 32-bit physical address is necessary.
116 *
117 * NOTE2: This function is always available, regardless of the
118 * initialization state of the rest of ACPI.
119 *
120 ******************************************************************************/
121
122acpi_status acpi_find_root_pointer(acpi_size *table_address)
123{
124 u8 *table_ptr;
125 u8 *mem_rover;
126 u32 physical_address;
127
128 ACPI_FUNCTION_TRACE(acpi_find_root_pointer);
129
130 /* 1a) Get the location of the Extended BIOS Data Area (EBDA) */
131
132 table_ptr = acpi_os_map_memory((acpi_physical_address)
133 ACPI_EBDA_PTR_LOCATION,
134 ACPI_EBDA_PTR_LENGTH);
135 if (!table_ptr) {
136 ACPI_ERROR((AE_INFO,
137 "Could not map memory at %8.8X for length %X",
138 ACPI_EBDA_PTR_LOCATION, ACPI_EBDA_PTR_LENGTH));
139
140 return_ACPI_STATUS(AE_NO_MEMORY);
141 }
142
143 ACPI_MOVE_16_TO_32(&physical_address, table_ptr);
144
145 /* Convert segment part to physical address */
146
147 physical_address <<= 4;
148 acpi_os_unmap_memory(table_ptr, ACPI_EBDA_PTR_LENGTH);
149
150 /* EBDA present? */
151
152 if (physical_address > 0x400) {
153 /*
154 * 1b) Search EBDA paragraphs (EBDA is required to be a
155 * minimum of 1_k length)
156 */
157 table_ptr = acpi_os_map_memory((acpi_physical_address)
158 physical_address,
159 ACPI_EBDA_WINDOW_SIZE);
160 if (!table_ptr) {
161 ACPI_ERROR((AE_INFO,
162 "Could not map memory at %8.8X for length %X",
163 physical_address, ACPI_EBDA_WINDOW_SIZE));
164
165 return_ACPI_STATUS(AE_NO_MEMORY);
166 }
167
168 mem_rover =
169 acpi_tb_scan_memory_for_rsdp(table_ptr,
170 ACPI_EBDA_WINDOW_SIZE);
171 acpi_os_unmap_memory(table_ptr, ACPI_EBDA_WINDOW_SIZE);
172
173 if (mem_rover) {
174
175 /* Return the physical address */
176
177 physical_address +=
178 (u32) ACPI_PTR_DIFF(mem_rover, table_ptr);
179
180 *table_address = physical_address;
181 return_ACPI_STATUS(AE_OK);
182 }
183 }
184
185 /*
186 * 2) Search upper memory: 16-byte boundaries in E0000h-FFFFFh
187 */
188 table_ptr = acpi_os_map_memory((acpi_physical_address)
189 ACPI_HI_RSDP_WINDOW_BASE,
190 ACPI_HI_RSDP_WINDOW_SIZE);
191
192 if (!table_ptr) {
193 ACPI_ERROR((AE_INFO,
194 "Could not map memory at %8.8X for length %X",
195 ACPI_HI_RSDP_WINDOW_BASE,
196 ACPI_HI_RSDP_WINDOW_SIZE));
197
198 return_ACPI_STATUS(AE_NO_MEMORY);
199 }
200
201 mem_rover =
202 acpi_tb_scan_memory_for_rsdp(table_ptr, ACPI_HI_RSDP_WINDOW_SIZE);
203 acpi_os_unmap_memory(table_ptr, ACPI_HI_RSDP_WINDOW_SIZE);
204
205 if (mem_rover) {
206
207 /* Return the physical address */
208
209 physical_address = (u32)
210 (ACPI_HI_RSDP_WINDOW_BASE +
211 ACPI_PTR_DIFF(mem_rover, table_ptr));
212
213 *table_address = physical_address;
214 return_ACPI_STATUS(AE_OK);
215 }
216
217 /* A valid RSDP was not found */
218
219 ACPI_ERROR((AE_INFO, "A valid RSDP was not found"));
220 return_ACPI_STATUS(AE_NOT_FOUND);
221}
222
223/*******************************************************************************
224 *
225 * FUNCTION: acpi_tb_scan_memory_for_rsdp
226 *
227 * PARAMETERS: start_address - Starting pointer for search
228 * Length - Maximum length to search
229 *
230 * RETURN: Pointer to the RSDP if found, otherwise NULL.
231 *
232 * DESCRIPTION: Search a block of memory for the RSDP signature
233 *
234 ******************************************************************************/
235static u8 *acpi_tb_scan_memory_for_rsdp(u8 * start_address, u32 length)
236{
237 acpi_status status;
238 u8 *mem_rover;
239 u8 *end_address;
240
241 ACPI_FUNCTION_TRACE(tb_scan_memory_for_rsdp);
242
243 end_address = start_address + length;
244
245 /* Search from given start address for the requested length */
246
247 for (mem_rover = start_address; mem_rover < end_address;
248 mem_rover += ACPI_RSDP_SCAN_STEP) {
249
250 /* The RSDP signature and checksum must both be correct */
251
252 status =
253 acpi_tb_validate_rsdp(ACPI_CAST_PTR
254 (struct acpi_table_rsdp, mem_rover));
255 if (ACPI_SUCCESS(status)) {
256
257 /* Sig and checksum valid, we have found a real RSDP */
258
259 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
260 "RSDP located at physical address %p\n",
261 mem_rover));
262 return_PTR(mem_rover);
263 }
264
265 /* No sig match or bad checksum, keep searching */
266 }
267
268 /* Searched entire block, no RSDP was found */
269
270 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
271 "Searched entire block from %p, valid RSDP was not found\n",
272 start_address));
273 return_PTR(NULL);
274}
diff --git a/drivers/acpi/acpica/utalloc.c b/drivers/acpi/acpica/utalloc.c
new file mode 100644
index 00000000000..2a017b29aa4
--- /dev/null
+++ b/drivers/acpi/acpica/utalloc.c
@@ -0,0 +1,383 @@
1/******************************************************************************
2 *
3 * Module Name: utalloc - local memory allocation routines
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46#include <acpi/acdebug.h>
47
48#define _COMPONENT ACPI_UTILITIES
49ACPI_MODULE_NAME("utalloc")
50
51/*******************************************************************************
52 *
53 * FUNCTION: acpi_ut_create_caches
54 *
55 * PARAMETERS: None
56 *
57 * RETURN: Status
58 *
59 * DESCRIPTION: Create all local caches
60 *
61 ******************************************************************************/
62acpi_status acpi_ut_create_caches(void)
63{
64 acpi_status status;
65
66 /* Object Caches, for frequently used objects */
67
68 status =
69 acpi_os_create_cache("Acpi-Namespace",
70 sizeof(struct acpi_namespace_node),
71 ACPI_MAX_NAMESPACE_CACHE_DEPTH,
72 &acpi_gbl_namespace_cache);
73 if (ACPI_FAILURE(status)) {
74 return (status);
75 }
76
77 status =
78 acpi_os_create_cache("Acpi-State", sizeof(union acpi_generic_state),
79 ACPI_MAX_STATE_CACHE_DEPTH,
80 &acpi_gbl_state_cache);
81 if (ACPI_FAILURE(status)) {
82 return (status);
83 }
84
85 status =
86 acpi_os_create_cache("Acpi-Parse",
87 sizeof(struct acpi_parse_obj_common),
88 ACPI_MAX_PARSE_CACHE_DEPTH,
89 &acpi_gbl_ps_node_cache);
90 if (ACPI_FAILURE(status)) {
91 return (status);
92 }
93
94 status =
95 acpi_os_create_cache("Acpi-ParseExt",
96 sizeof(struct acpi_parse_obj_named),
97 ACPI_MAX_EXTPARSE_CACHE_DEPTH,
98 &acpi_gbl_ps_node_ext_cache);
99 if (ACPI_FAILURE(status)) {
100 return (status);
101 }
102
103 status =
104 acpi_os_create_cache("Acpi-Operand",
105 sizeof(union acpi_operand_object),
106 ACPI_MAX_OBJECT_CACHE_DEPTH,
107 &acpi_gbl_operand_cache);
108 if (ACPI_FAILURE(status)) {
109 return (status);
110 }
111#ifdef ACPI_DBG_TRACK_ALLOCATIONS
112
113 /* Memory allocation lists */
114
115 status = acpi_ut_create_list("Acpi-Global", 0, &acpi_gbl_global_list);
116 if (ACPI_FAILURE(status)) {
117 return (status);
118 }
119
120 status =
121 acpi_ut_create_list("Acpi-Namespace",
122 sizeof(struct acpi_namespace_node),
123 &acpi_gbl_ns_node_list);
124 if (ACPI_FAILURE(status)) {
125 return (status);
126 }
127#endif
128
129 return (AE_OK);
130}
131
132/*******************************************************************************
133 *
134 * FUNCTION: acpi_ut_delete_caches
135 *
136 * PARAMETERS: None
137 *
138 * RETURN: Status
139 *
140 * DESCRIPTION: Purge and delete all local caches
141 *
142 ******************************************************************************/
143
144acpi_status acpi_ut_delete_caches(void)
145{
146#ifdef ACPI_DBG_TRACK_ALLOCATIONS
147 char buffer[7];
148
149 if (acpi_gbl_display_final_mem_stats) {
150 ACPI_STRCPY(buffer, "MEMORY");
151 (void)acpi_db_display_statistics(buffer);
152 }
153#endif
154
155 (void)acpi_os_delete_cache(acpi_gbl_namespace_cache);
156 acpi_gbl_namespace_cache = NULL;
157
158 (void)acpi_os_delete_cache(acpi_gbl_state_cache);
159 acpi_gbl_state_cache = NULL;
160
161 (void)acpi_os_delete_cache(acpi_gbl_operand_cache);
162 acpi_gbl_operand_cache = NULL;
163
164 (void)acpi_os_delete_cache(acpi_gbl_ps_node_cache);
165 acpi_gbl_ps_node_cache = NULL;
166
167 (void)acpi_os_delete_cache(acpi_gbl_ps_node_ext_cache);
168 acpi_gbl_ps_node_ext_cache = NULL;
169
170#ifdef ACPI_DBG_TRACK_ALLOCATIONS
171
172 /* Debug only - display leftover memory allocation, if any */
173
174 acpi_ut_dump_allocations(ACPI_UINT32_MAX, NULL);
175
176 /* Free memory lists */
177
178 ACPI_FREE(acpi_gbl_global_list);
179 acpi_gbl_global_list = NULL;
180
181 ACPI_FREE(acpi_gbl_ns_node_list);
182 acpi_gbl_ns_node_list = NULL;
183#endif
184
185 return (AE_OK);
186}
187
188/*******************************************************************************
189 *
190 * FUNCTION: acpi_ut_validate_buffer
191 *
192 * PARAMETERS: Buffer - Buffer descriptor to be validated
193 *
194 * RETURN: Status
195 *
196 * DESCRIPTION: Perform parameter validation checks on an struct acpi_buffer
197 *
198 ******************************************************************************/
199
200acpi_status acpi_ut_validate_buffer(struct acpi_buffer * buffer)
201{
202
203 /* Obviously, the structure pointer must be valid */
204
205 if (!buffer) {
206 return (AE_BAD_PARAMETER);
207 }
208
209 /* Special semantics for the length */
210
211 if ((buffer->length == ACPI_NO_BUFFER) ||
212 (buffer->length == ACPI_ALLOCATE_BUFFER) ||
213 (buffer->length == ACPI_ALLOCATE_LOCAL_BUFFER)) {
214 return (AE_OK);
215 }
216
217 /* Length is valid, the buffer pointer must be also */
218
219 if (!buffer->pointer) {
220 return (AE_BAD_PARAMETER);
221 }
222
223 return (AE_OK);
224}
225
226/*******************************************************************************
227 *
228 * FUNCTION: acpi_ut_initialize_buffer
229 *
230 * PARAMETERS: Buffer - Buffer to be validated
231 * required_length - Length needed
232 *
233 * RETURN: Status
234 *
235 * DESCRIPTION: Validate that the buffer is of the required length or
236 * allocate a new buffer. Returned buffer is always zeroed.
237 *
238 ******************************************************************************/
239
240acpi_status
241acpi_ut_initialize_buffer(struct acpi_buffer * buffer,
242 acpi_size required_length)
243{
244 acpi_size input_buffer_length;
245
246 /* Parameter validation */
247
248 if (!buffer || !required_length) {
249 return (AE_BAD_PARAMETER);
250 }
251
252 /*
253 * Buffer->Length is used as both an input and output parameter. Get the
254 * input actual length and set the output required buffer length.
255 */
256 input_buffer_length = buffer->length;
257 buffer->length = required_length;
258
259 /*
260 * The input buffer length contains the actual buffer length, or the type
261 * of buffer to be allocated by this routine.
262 */
263 switch (input_buffer_length) {
264 case ACPI_NO_BUFFER:
265
266 /* Return the exception (and the required buffer length) */
267
268 return (AE_BUFFER_OVERFLOW);
269
270 case ACPI_ALLOCATE_BUFFER:
271
272 /* Allocate a new buffer */
273
274 buffer->pointer = acpi_os_allocate(required_length);
275 break;
276
277 case ACPI_ALLOCATE_LOCAL_BUFFER:
278
279 /* Allocate a new buffer with local interface to allow tracking */
280
281 buffer->pointer = ACPI_ALLOCATE(required_length);
282 break;
283
284 default:
285
286 /* Existing buffer: Validate the size of the buffer */
287
288 if (input_buffer_length < required_length) {
289 return (AE_BUFFER_OVERFLOW);
290 }
291 break;
292 }
293
294 /* Validate allocation from above or input buffer pointer */
295
296 if (!buffer->pointer) {
297 return (AE_NO_MEMORY);
298 }
299
300 /* Have a valid buffer, clear it */
301
302 ACPI_MEMSET(buffer->pointer, 0, required_length);
303 return (AE_OK);
304}
305
306#ifdef NOT_USED_BY_LINUX
307/*******************************************************************************
308 *
309 * FUNCTION: acpi_ut_allocate
310 *
311 * PARAMETERS: Size - Size of the allocation
312 * Component - Component type of caller
313 * Module - Source file name of caller
314 * Line - Line number of caller
315 *
316 * RETURN: Address of the allocated memory on success, NULL on failure.
317 *
318 * DESCRIPTION: Subsystem equivalent of malloc.
319 *
320 ******************************************************************************/
321
322void *acpi_ut_allocate(acpi_size size,
323 u32 component, const char *module, u32 line)
324{
325 void *allocation;
326
327 ACPI_FUNCTION_TRACE_U32(ut_allocate, size);
328
329 /* Check for an inadvertent size of zero bytes */
330
331 if (!size) {
332 ACPI_WARNING((module, line,
333 "Attempt to allocate zero bytes, allocating 1 byte"));
334 size = 1;
335 }
336
337 allocation = acpi_os_allocate(size);
338 if (!allocation) {
339
340 /* Report allocation error */
341
342 ACPI_WARNING((module, line,
343 "Could not allocate size %X", (u32) size));
344
345 return_PTR(NULL);
346 }
347
348 return_PTR(allocation);
349}
350
351/*******************************************************************************
352 *
353 * FUNCTION: acpi_ut_allocate_zeroed
354 *
355 * PARAMETERS: Size - Size of the allocation
356 * Component - Component type of caller
357 * Module - Source file name of caller
358 * Line - Line number of caller
359 *
360 * RETURN: Address of the allocated memory on success, NULL on failure.
361 *
362 * DESCRIPTION: Subsystem equivalent of calloc. Allocate and zero memory.
363 *
364 ******************************************************************************/
365
366void *acpi_ut_allocate_zeroed(acpi_size size,
367 u32 component, const char *module, u32 line)
368{
369 void *allocation;
370
371 ACPI_FUNCTION_ENTRY();
372
373 allocation = acpi_ut_allocate(size, component, module, line);
374 if (allocation) {
375
376 /* Clear the memory block */
377
378 ACPI_MEMSET(allocation, 0, size);
379 }
380
381 return (allocation);
382}
383#endif
diff --git a/drivers/acpi/acpica/utcopy.c b/drivers/acpi/acpica/utcopy.c
new file mode 100644
index 00000000000..e6f3002312e
--- /dev/null
+++ b/drivers/acpi/acpica/utcopy.c
@@ -0,0 +1,970 @@
1/******************************************************************************
2 *
3 * Module Name: utcopy - Internal to external object translation utilities
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46#include <acpi/acnamesp.h>
47
48
49#define _COMPONENT ACPI_UTILITIES
50ACPI_MODULE_NAME("utcopy")
51
52/* Local prototypes */
53static acpi_status
54acpi_ut_copy_isimple_to_esimple(union acpi_operand_object *internal_object,
55 union acpi_object *external_object,
56 u8 * data_space, acpi_size * buffer_space_used);
57
58static acpi_status
59acpi_ut_copy_ielement_to_ielement(u8 object_type,
60 union acpi_operand_object *source_object,
61 union acpi_generic_state *state,
62 void *context);
63
64static acpi_status
65acpi_ut_copy_ipackage_to_epackage(union acpi_operand_object *internal_object,
66 u8 * buffer, acpi_size * space_used);
67
68static acpi_status
69acpi_ut_copy_esimple_to_isimple(union acpi_object *user_obj,
70 union acpi_operand_object **return_obj);
71
72static acpi_status
73acpi_ut_copy_epackage_to_ipackage(union acpi_object *external_object,
74 union acpi_operand_object **internal_object);
75
76static acpi_status
77acpi_ut_copy_simple_object(union acpi_operand_object *source_desc,
78 union acpi_operand_object *dest_desc);
79
80static acpi_status
81acpi_ut_copy_ielement_to_eelement(u8 object_type,
82 union acpi_operand_object *source_object,
83 union acpi_generic_state *state,
84 void *context);
85
86static acpi_status
87acpi_ut_copy_ipackage_to_ipackage(union acpi_operand_object *source_obj,
88 union acpi_operand_object *dest_obj,
89 struct acpi_walk_state *walk_state);
90
91/*******************************************************************************
92 *
93 * FUNCTION: acpi_ut_copy_isimple_to_esimple
94 *
95 * PARAMETERS: internal_object - Source object to be copied
96 * external_object - Where to return the copied object
97 * data_space - Where object data is returned (such as
98 * buffer and string data)
99 * buffer_space_used - Length of data_space that was used
100 *
101 * RETURN: Status
102 *
103 * DESCRIPTION: This function is called to copy a simple internal object to
104 * an external object.
105 *
106 * The data_space buffer is assumed to have sufficient space for
107 * the object.
108 *
109 ******************************************************************************/
110
111static acpi_status
112acpi_ut_copy_isimple_to_esimple(union acpi_operand_object *internal_object,
113 union acpi_object *external_object,
114 u8 * data_space, acpi_size * buffer_space_used)
115{
116 acpi_status status = AE_OK;
117
118 ACPI_FUNCTION_TRACE(ut_copy_isimple_to_esimple);
119
120 *buffer_space_used = 0;
121
122 /*
123 * Check for NULL object case (could be an uninitialized
124 * package element)
125 */
126 if (!internal_object) {
127 return_ACPI_STATUS(AE_OK);
128 }
129
130 /* Always clear the external object */
131
132 ACPI_MEMSET(external_object, 0, sizeof(union acpi_object));
133
134 /*
135 * In general, the external object will be the same type as
136 * the internal object
137 */
138 external_object->type = ACPI_GET_OBJECT_TYPE(internal_object);
139
140 /* However, only a limited number of external types are supported */
141
142 switch (ACPI_GET_OBJECT_TYPE(internal_object)) {
143 case ACPI_TYPE_STRING:
144
145 external_object->string.pointer = (char *)data_space;
146 external_object->string.length = internal_object->string.length;
147 *buffer_space_used = ACPI_ROUND_UP_TO_NATIVE_WORD((acpi_size)
148 internal_object->
149 string.
150 length + 1);
151
152 ACPI_MEMCPY((void *)data_space,
153 (void *)internal_object->string.pointer,
154 (acpi_size) internal_object->string.length + 1);
155 break;
156
157 case ACPI_TYPE_BUFFER:
158
159 external_object->buffer.pointer = data_space;
160 external_object->buffer.length = internal_object->buffer.length;
161 *buffer_space_used =
162 ACPI_ROUND_UP_TO_NATIVE_WORD(internal_object->string.
163 length);
164
165 ACPI_MEMCPY((void *)data_space,
166 (void *)internal_object->buffer.pointer,
167 internal_object->buffer.length);
168 break;
169
170 case ACPI_TYPE_INTEGER:
171
172 external_object->integer.value = internal_object->integer.value;
173 break;
174
175 case ACPI_TYPE_LOCAL_REFERENCE:
176
177 /* This is an object reference. */
178
179 switch (internal_object->reference.class) {
180 case ACPI_REFCLASS_NAME:
181
182 /*
183 * For namepath, return the object handle ("reference")
184 * We are referring to the namespace node
185 */
186 external_object->reference.handle =
187 internal_object->reference.node;
188 external_object->reference.actual_type =
189 acpi_ns_get_type(internal_object->reference.node);
190 break;
191
192 default:
193
194 /* All other reference types are unsupported */
195
196 return_ACPI_STATUS(AE_TYPE);
197 }
198 break;
199
200 case ACPI_TYPE_PROCESSOR:
201
202 external_object->processor.proc_id =
203 internal_object->processor.proc_id;
204 external_object->processor.pblk_address =
205 internal_object->processor.address;
206 external_object->processor.pblk_length =
207 internal_object->processor.length;
208 break;
209
210 case ACPI_TYPE_POWER:
211
212 external_object->power_resource.system_level =
213 internal_object->power_resource.system_level;
214
215 external_object->power_resource.resource_order =
216 internal_object->power_resource.resource_order;
217 break;
218
219 default:
220 /*
221 * There is no corresponding external object type
222 */
223 ACPI_ERROR((AE_INFO,
224 "Unsupported object type, cannot convert to external object: %s",
225 acpi_ut_get_type_name(ACPI_GET_OBJECT_TYPE
226 (internal_object))));
227
228 return_ACPI_STATUS(AE_SUPPORT);
229 }
230
231 return_ACPI_STATUS(status);
232}
233
234/*******************************************************************************
235 *
236 * FUNCTION: acpi_ut_copy_ielement_to_eelement
237 *
238 * PARAMETERS: acpi_pkg_callback
239 *
240 * RETURN: Status
241 *
242 * DESCRIPTION: Copy one package element to another package element
243 *
244 ******************************************************************************/
245
246static acpi_status
247acpi_ut_copy_ielement_to_eelement(u8 object_type,
248 union acpi_operand_object *source_object,
249 union acpi_generic_state *state,
250 void *context)
251{
252 acpi_status status = AE_OK;
253 struct acpi_pkg_info *info = (struct acpi_pkg_info *)context;
254 acpi_size object_space;
255 u32 this_index;
256 union acpi_object *target_object;
257
258 ACPI_FUNCTION_ENTRY();
259
260 this_index = state->pkg.index;
261 target_object = (union acpi_object *)
262 &((union acpi_object *)(state->pkg.dest_object))->package.
263 elements[this_index];
264
265 switch (object_type) {
266 case ACPI_COPY_TYPE_SIMPLE:
267
268 /*
269 * This is a simple or null object
270 */
271 status = acpi_ut_copy_isimple_to_esimple(source_object,
272 target_object,
273 info->free_space,
274 &object_space);
275 if (ACPI_FAILURE(status)) {
276 return (status);
277 }
278 break;
279
280 case ACPI_COPY_TYPE_PACKAGE:
281
282 /*
283 * Build the package object
284 */
285 target_object->type = ACPI_TYPE_PACKAGE;
286 target_object->package.count = source_object->package.count;
287 target_object->package.elements =
288 ACPI_CAST_PTR(union acpi_object, info->free_space);
289
290 /*
291 * Pass the new package object back to the package walk routine
292 */
293 state->pkg.this_target_obj = target_object;
294
295 /*
296 * Save space for the array of objects (Package elements)
297 * update the buffer length counter
298 */
299 object_space = ACPI_ROUND_UP_TO_NATIVE_WORD((acpi_size)
300 target_object->
301 package.count *
302 sizeof(union
303 acpi_object));
304 break;
305
306 default:
307 return (AE_BAD_PARAMETER);
308 }
309
310 info->free_space += object_space;
311 info->length += object_space;
312 return (status);
313}
314
315/*******************************************************************************
316 *
317 * FUNCTION: acpi_ut_copy_ipackage_to_epackage
318 *
319 * PARAMETERS: internal_object - Pointer to the object we are returning
320 * Buffer - Where the object is returned
321 * space_used - Where the object length is returned
322 *
323 * RETURN: Status
324 *
325 * DESCRIPTION: This function is called to place a package object in a user
326 * buffer. A package object by definition contains other objects.
327 *
328 * The buffer is assumed to have sufficient space for the object.
329 * The caller must have verified the buffer length needed using the
330 * acpi_ut_get_object_size function before calling this function.
331 *
332 ******************************************************************************/
333
334static acpi_status
335acpi_ut_copy_ipackage_to_epackage(union acpi_operand_object *internal_object,
336 u8 * buffer, acpi_size * space_used)
337{
338 union acpi_object *external_object;
339 acpi_status status;
340 struct acpi_pkg_info info;
341
342 ACPI_FUNCTION_TRACE(ut_copy_ipackage_to_epackage);
343
344 /*
345 * First package at head of the buffer
346 */
347 external_object = ACPI_CAST_PTR(union acpi_object, buffer);
348
349 /*
350 * Free space begins right after the first package
351 */
352 info.length = ACPI_ROUND_UP_TO_NATIVE_WORD(sizeof(union acpi_object));
353 info.free_space =
354 buffer + ACPI_ROUND_UP_TO_NATIVE_WORD(sizeof(union acpi_object));
355 info.object_space = 0;
356 info.num_packages = 1;
357
358 external_object->type = ACPI_GET_OBJECT_TYPE(internal_object);
359 external_object->package.count = internal_object->package.count;
360 external_object->package.elements = ACPI_CAST_PTR(union acpi_object,
361 info.free_space);
362
363 /*
364 * Leave room for an array of ACPI_OBJECTS in the buffer
365 * and move the free space past it
366 */
367 info.length += (acpi_size) external_object->package.count *
368 ACPI_ROUND_UP_TO_NATIVE_WORD(sizeof(union acpi_object));
369 info.free_space += external_object->package.count *
370 ACPI_ROUND_UP_TO_NATIVE_WORD(sizeof(union acpi_object));
371
372 status = acpi_ut_walk_package_tree(internal_object, external_object,
373 acpi_ut_copy_ielement_to_eelement,
374 &info);
375
376 *space_used = info.length;
377 return_ACPI_STATUS(status);
378}
379
380/*******************************************************************************
381 *
382 * FUNCTION: acpi_ut_copy_iobject_to_eobject
383 *
384 * PARAMETERS: internal_object - The internal object to be converted
385 * buffer_ptr - Where the object is returned
386 *
387 * RETURN: Status
388 *
389 * DESCRIPTION: This function is called to build an API object to be returned to
390 * the caller.
391 *
392 ******************************************************************************/
393
394acpi_status
395acpi_ut_copy_iobject_to_eobject(union acpi_operand_object *internal_object,
396 struct acpi_buffer *ret_buffer)
397{
398 acpi_status status;
399
400 ACPI_FUNCTION_TRACE(ut_copy_iobject_to_eobject);
401
402 if (ACPI_GET_OBJECT_TYPE(internal_object) == ACPI_TYPE_PACKAGE) {
403 /*
404 * Package object: Copy all subobjects (including
405 * nested packages)
406 */
407 status = acpi_ut_copy_ipackage_to_epackage(internal_object,
408 ret_buffer->pointer,
409 &ret_buffer->length);
410 } else {
411 /*
412 * Build a simple object (no nested objects)
413 */
414 status = acpi_ut_copy_isimple_to_esimple(internal_object,
415 ACPI_CAST_PTR(union
416 acpi_object,
417 ret_buffer->
418 pointer),
419 ACPI_ADD_PTR(u8,
420 ret_buffer->
421 pointer,
422 ACPI_ROUND_UP_TO_NATIVE_WORD
423 (sizeof
424 (union
425 acpi_object))),
426 &ret_buffer->length);
427 /*
428 * build simple does not include the object size in the length
429 * so we add it in here
430 */
431 ret_buffer->length += sizeof(union acpi_object);
432 }
433
434 return_ACPI_STATUS(status);
435}
436
437/*******************************************************************************
438 *
439 * FUNCTION: acpi_ut_copy_esimple_to_isimple
440 *
441 * PARAMETERS: external_object - The external object to be converted
442 * ret_internal_object - Where the internal object is returned
443 *
444 * RETURN: Status
445 *
446 * DESCRIPTION: This function copies an external object to an internal one.
447 * NOTE: Pointers can be copied, we don't need to copy data.
448 * (The pointers have to be valid in our address space no matter
449 * what we do with them!)
450 *
451 ******************************************************************************/
452
453static acpi_status
454acpi_ut_copy_esimple_to_isimple(union acpi_object *external_object,
455 union acpi_operand_object **ret_internal_object)
456{
457 union acpi_operand_object *internal_object;
458
459 ACPI_FUNCTION_TRACE(ut_copy_esimple_to_isimple);
460
461 /*
462 * Simple types supported are: String, Buffer, Integer
463 */
464 switch (external_object->type) {
465 case ACPI_TYPE_STRING:
466 case ACPI_TYPE_BUFFER:
467 case ACPI_TYPE_INTEGER:
468 case ACPI_TYPE_LOCAL_REFERENCE:
469
470 internal_object = acpi_ut_create_internal_object((u8)
471 external_object->
472 type);
473 if (!internal_object) {
474 return_ACPI_STATUS(AE_NO_MEMORY);
475 }
476 break;
477
478 case ACPI_TYPE_ANY: /* This is the case for a NULL object */
479
480 *ret_internal_object = NULL;
481 return_ACPI_STATUS(AE_OK);
482
483 default:
484 /* All other types are not supported */
485
486 ACPI_ERROR((AE_INFO,
487 "Unsupported object type, cannot convert to internal object: %s",
488 acpi_ut_get_type_name(external_object->type)));
489
490 return_ACPI_STATUS(AE_SUPPORT);
491 }
492
493 /* Must COPY string and buffer contents */
494
495 switch (external_object->type) {
496 case ACPI_TYPE_STRING:
497
498 internal_object->string.pointer =
499 ACPI_ALLOCATE_ZEROED((acpi_size) external_object->string.
500 length + 1);
501 if (!internal_object->string.pointer) {
502 goto error_exit;
503 }
504
505 ACPI_MEMCPY(internal_object->string.pointer,
506 external_object->string.pointer,
507 external_object->string.length);
508
509 internal_object->string.length = external_object->string.length;
510 break;
511
512 case ACPI_TYPE_BUFFER:
513
514 internal_object->buffer.pointer =
515 ACPI_ALLOCATE_ZEROED(external_object->buffer.length);
516 if (!internal_object->buffer.pointer) {
517 goto error_exit;
518 }
519
520 ACPI_MEMCPY(internal_object->buffer.pointer,
521 external_object->buffer.pointer,
522 external_object->buffer.length);
523
524 internal_object->buffer.length = external_object->buffer.length;
525
526 /* Mark buffer data valid */
527
528 internal_object->buffer.flags |= AOPOBJ_DATA_VALID;
529 break;
530
531 case ACPI_TYPE_INTEGER:
532
533 internal_object->integer.value = external_object->integer.value;
534 break;
535
536 case ACPI_TYPE_LOCAL_REFERENCE:
537
538 /* TBD: should validate incoming handle */
539
540 internal_object->reference.class = ACPI_REFCLASS_NAME;
541 internal_object->reference.node =
542 external_object->reference.handle;
543 break;
544
545 default:
546 /* Other types can't get here */
547 break;
548 }
549
550 *ret_internal_object = internal_object;
551 return_ACPI_STATUS(AE_OK);
552
553 error_exit:
554 acpi_ut_remove_reference(internal_object);
555 return_ACPI_STATUS(AE_NO_MEMORY);
556}
557
558/*******************************************************************************
559 *
560 * FUNCTION: acpi_ut_copy_epackage_to_ipackage
561 *
562 * PARAMETERS: external_object - The external object to be converted
563 * internal_object - Where the internal object is returned
564 *
565 * RETURN: Status
566 *
567 * DESCRIPTION: Copy an external package object to an internal package.
568 * Handles nested packages.
569 *
570 ******************************************************************************/
571
572static acpi_status
573acpi_ut_copy_epackage_to_ipackage(union acpi_object *external_object,
574 union acpi_operand_object **internal_object)
575{
576 acpi_status status = AE_OK;
577 union acpi_operand_object *package_object;
578 union acpi_operand_object **package_elements;
579 u32 i;
580
581 ACPI_FUNCTION_TRACE(ut_copy_epackage_to_ipackage);
582
583 /* Create the package object */
584
585 package_object =
586 acpi_ut_create_package_object(external_object->package.count);
587 if (!package_object) {
588 return_ACPI_STATUS(AE_NO_MEMORY);
589 }
590
591 package_elements = package_object->package.elements;
592
593 /*
594 * Recursive implementation. Probably ok, since nested external packages
595 * as parameters should be very rare.
596 */
597 for (i = 0; i < external_object->package.count; i++) {
598 status =
599 acpi_ut_copy_eobject_to_iobject(&external_object->package.
600 elements[i],
601 &package_elements[i]);
602 if (ACPI_FAILURE(status)) {
603
604 /* Truncate package and delete it */
605
606 package_object->package.count = i;
607 package_elements[i] = NULL;
608 acpi_ut_remove_reference(package_object);
609 return_ACPI_STATUS(status);
610 }
611 }
612
613 /* Mark package data valid */
614
615 package_object->package.flags |= AOPOBJ_DATA_VALID;
616
617 *internal_object = package_object;
618 return_ACPI_STATUS(status);
619}
620
621/*******************************************************************************
622 *
623 * FUNCTION: acpi_ut_copy_eobject_to_iobject
624 *
625 * PARAMETERS: external_object - The external object to be converted
626 * internal_object - Where the internal object is returned
627 *
628 * RETURN: Status - the status of the call
629 *
630 * DESCRIPTION: Converts an external object to an internal object.
631 *
632 ******************************************************************************/
633
634acpi_status
635acpi_ut_copy_eobject_to_iobject(union acpi_object *external_object,
636 union acpi_operand_object **internal_object)
637{
638 acpi_status status;
639
640 ACPI_FUNCTION_TRACE(ut_copy_eobject_to_iobject);
641
642 if (external_object->type == ACPI_TYPE_PACKAGE) {
643 status =
644 acpi_ut_copy_epackage_to_ipackage(external_object,
645 internal_object);
646 } else {
647 /*
648 * Build a simple object (no nested objects)
649 */
650 status =
651 acpi_ut_copy_esimple_to_isimple(external_object,
652 internal_object);
653 }
654
655 return_ACPI_STATUS(status);
656}
657
658/*******************************************************************************
659 *
660 * FUNCTION: acpi_ut_copy_simple_object
661 *
662 * PARAMETERS: source_desc - The internal object to be copied
663 * dest_desc - New target object
664 *
665 * RETURN: Status
666 *
667 * DESCRIPTION: Simple copy of one internal object to another. Reference count
668 * of the destination object is preserved.
669 *
670 ******************************************************************************/
671
672static acpi_status
673acpi_ut_copy_simple_object(union acpi_operand_object *source_desc,
674 union acpi_operand_object *dest_desc)
675{
676 u16 reference_count;
677 union acpi_operand_object *next_object;
678
679 /* Save fields from destination that we don't want to overwrite */
680
681 reference_count = dest_desc->common.reference_count;
682 next_object = dest_desc->common.next_object;
683
684 /* Copy the entire source object over the destination object */
685
686 ACPI_MEMCPY((char *)dest_desc, (char *)source_desc,
687 sizeof(union acpi_operand_object));
688
689 /* Restore the saved fields */
690
691 dest_desc->common.reference_count = reference_count;
692 dest_desc->common.next_object = next_object;
693
694 /* New object is not static, regardless of source */
695
696 dest_desc->common.flags &= ~AOPOBJ_STATIC_POINTER;
697
698 /* Handle the objects with extra data */
699
700 switch (ACPI_GET_OBJECT_TYPE(dest_desc)) {
701 case ACPI_TYPE_BUFFER:
702 /*
703 * Allocate and copy the actual buffer if and only if:
704 * 1) There is a valid buffer pointer
705 * 2) The buffer has a length > 0
706 */
707 if ((source_desc->buffer.pointer) &&
708 (source_desc->buffer.length)) {
709 dest_desc->buffer.pointer =
710 ACPI_ALLOCATE(source_desc->buffer.length);
711 if (!dest_desc->buffer.pointer) {
712 return (AE_NO_MEMORY);
713 }
714
715 /* Copy the actual buffer data */
716
717 ACPI_MEMCPY(dest_desc->buffer.pointer,
718 source_desc->buffer.pointer,
719 source_desc->buffer.length);
720 }
721 break;
722
723 case ACPI_TYPE_STRING:
724 /*
725 * Allocate and copy the actual string if and only if:
726 * 1) There is a valid string pointer
727 * (Pointer to a NULL string is allowed)
728 */
729 if (source_desc->string.pointer) {
730 dest_desc->string.pointer =
731 ACPI_ALLOCATE((acpi_size) source_desc->string.
732 length + 1);
733 if (!dest_desc->string.pointer) {
734 return (AE_NO_MEMORY);
735 }
736
737 /* Copy the actual string data */
738
739 ACPI_MEMCPY(dest_desc->string.pointer,
740 source_desc->string.pointer,
741 (acpi_size) source_desc->string.length + 1);
742 }
743 break;
744
745 case ACPI_TYPE_LOCAL_REFERENCE:
746 /*
747 * We copied the reference object, so we now must add a reference
748 * to the object pointed to by the reference
749 *
750 * DDBHandle reference (from Load/load_table) is a special reference,
751 * it does not have a Reference.Object, so does not need to
752 * increase the reference count
753 */
754 if (source_desc->reference.class == ACPI_REFCLASS_TABLE) {
755 break;
756 }
757
758 acpi_ut_add_reference(source_desc->reference.object);
759 break;
760
761 case ACPI_TYPE_REGION:
762 /*
763 * We copied the Region Handler, so we now must add a reference
764 */
765 if (dest_desc->region.handler) {
766 acpi_ut_add_reference(dest_desc->region.handler);
767 }
768 break;
769
770 default:
771 /* Nothing to do for other simple objects */
772 break;
773 }
774
775 return (AE_OK);
776}
777
778/*******************************************************************************
779 *
780 * FUNCTION: acpi_ut_copy_ielement_to_ielement
781 *
782 * PARAMETERS: acpi_pkg_callback
783 *
784 * RETURN: Status
785 *
786 * DESCRIPTION: Copy one package element to another package element
787 *
788 ******************************************************************************/
789
790static acpi_status
791acpi_ut_copy_ielement_to_ielement(u8 object_type,
792 union acpi_operand_object *source_object,
793 union acpi_generic_state *state,
794 void *context)
795{
796 acpi_status status = AE_OK;
797 u32 this_index;
798 union acpi_operand_object **this_target_ptr;
799 union acpi_operand_object *target_object;
800
801 ACPI_FUNCTION_ENTRY();
802
803 this_index = state->pkg.index;
804 this_target_ptr = (union acpi_operand_object **)
805 &state->pkg.dest_object->package.elements[this_index];
806
807 switch (object_type) {
808 case ACPI_COPY_TYPE_SIMPLE:
809
810 /* A null source object indicates a (legal) null package element */
811
812 if (source_object) {
813 /*
814 * This is a simple object, just copy it
815 */
816 target_object =
817 acpi_ut_create_internal_object(ACPI_GET_OBJECT_TYPE
818 (source_object));
819 if (!target_object) {
820 return (AE_NO_MEMORY);
821 }
822
823 status =
824 acpi_ut_copy_simple_object(source_object,
825 target_object);
826 if (ACPI_FAILURE(status)) {
827 goto error_exit;
828 }
829
830 *this_target_ptr = target_object;
831 } else {
832 /* Pass through a null element */
833
834 *this_target_ptr = NULL;
835 }
836 break;
837
838 case ACPI_COPY_TYPE_PACKAGE:
839
840 /*
841 * This object is a package - go down another nesting level
842 * Create and build the package object
843 */
844 target_object =
845 acpi_ut_create_package_object(source_object->package.count);
846 if (!target_object) {
847 return (AE_NO_MEMORY);
848 }
849
850 target_object->common.flags = source_object->common.flags;
851
852 /* Pass the new package object back to the package walk routine */
853
854 state->pkg.this_target_obj = target_object;
855
856 /* Store the object pointer in the parent package object */
857
858 *this_target_ptr = target_object;
859 break;
860
861 default:
862 return (AE_BAD_PARAMETER);
863 }
864
865 return (status);
866
867 error_exit:
868 acpi_ut_remove_reference(target_object);
869 return (status);
870}
871
872/*******************************************************************************
873 *
874 * FUNCTION: acpi_ut_copy_ipackage_to_ipackage
875 *
876 * PARAMETERS: *source_obj - Pointer to the source package object
877 * *dest_obj - Where the internal object is returned
878 *
879 * RETURN: Status - the status of the call
880 *
881 * DESCRIPTION: This function is called to copy an internal package object
882 * into another internal package object.
883 *
884 ******************************************************************************/
885
886static acpi_status
887acpi_ut_copy_ipackage_to_ipackage(union acpi_operand_object *source_obj,
888 union acpi_operand_object *dest_obj,
889 struct acpi_walk_state *walk_state)
890{
891 acpi_status status = AE_OK;
892
893 ACPI_FUNCTION_TRACE(ut_copy_ipackage_to_ipackage);
894
895 dest_obj->common.type = ACPI_GET_OBJECT_TYPE(source_obj);
896 dest_obj->common.flags = source_obj->common.flags;
897 dest_obj->package.count = source_obj->package.count;
898
899 /*
900 * Create the object array and walk the source package tree
901 */
902 dest_obj->package.elements = ACPI_ALLOCATE_ZEROED(((acpi_size)
903 source_obj->package.
904 count +
905 1) * sizeof(void *));
906 if (!dest_obj->package.elements) {
907 ACPI_ERROR((AE_INFO, "Package allocation failure"));
908 return_ACPI_STATUS(AE_NO_MEMORY);
909 }
910
911 /*
912 * Copy the package element-by-element by walking the package "tree".
913 * This handles nested packages of arbitrary depth.
914 */
915 status = acpi_ut_walk_package_tree(source_obj, dest_obj,
916 acpi_ut_copy_ielement_to_ielement,
917 walk_state);
918 if (ACPI_FAILURE(status)) {
919
920 /* On failure, delete the destination package object */
921
922 acpi_ut_remove_reference(dest_obj);
923 }
924
925 return_ACPI_STATUS(status);
926}
927
928/*******************************************************************************
929 *
930 * FUNCTION: acpi_ut_copy_iobject_to_iobject
931 *
932 * PARAMETERS: walk_state - Current walk state
933 * source_desc - The internal object to be copied
934 * dest_desc - Where the copied object is returned
935 *
936 * RETURN: Status
937 *
938 * DESCRIPTION: Copy an internal object to a new internal object
939 *
940 ******************************************************************************/
941
942acpi_status
943acpi_ut_copy_iobject_to_iobject(union acpi_operand_object *source_desc,
944 union acpi_operand_object **dest_desc,
945 struct acpi_walk_state *walk_state)
946{
947 acpi_status status = AE_OK;
948
949 ACPI_FUNCTION_TRACE(ut_copy_iobject_to_iobject);
950
951 /* Create the top level object */
952
953 *dest_desc =
954 acpi_ut_create_internal_object(ACPI_GET_OBJECT_TYPE(source_desc));
955 if (!*dest_desc) {
956 return_ACPI_STATUS(AE_NO_MEMORY);
957 }
958
959 /* Copy the object and possible subobjects */
960
961 if (ACPI_GET_OBJECT_TYPE(source_desc) == ACPI_TYPE_PACKAGE) {
962 status =
963 acpi_ut_copy_ipackage_to_ipackage(source_desc, *dest_desc,
964 walk_state);
965 } else {
966 status = acpi_ut_copy_simple_object(source_desc, *dest_desc);
967 }
968
969 return_ACPI_STATUS(status);
970}
diff --git a/drivers/acpi/acpica/utdebug.c b/drivers/acpi/acpica/utdebug.c
new file mode 100644
index 00000000000..9a3538c497d
--- /dev/null
+++ b/drivers/acpi/acpica/utdebug.c
@@ -0,0 +1,651 @@
1/******************************************************************************
2 *
3 * Module Name: utdebug - Debug print routines
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46
47#define _COMPONENT ACPI_UTILITIES
48ACPI_MODULE_NAME("utdebug")
49#ifdef ACPI_DEBUG_OUTPUT
50static acpi_thread_id acpi_gbl_prev_thread_id;
51static char *acpi_gbl_fn_entry_str = "----Entry";
52static char *acpi_gbl_fn_exit_str = "----Exit-";
53
54/* Local prototypes */
55
56static const char *acpi_ut_trim_function_name(const char *function_name);
57
58/*******************************************************************************
59 *
60 * FUNCTION: acpi_ut_init_stack_ptr_trace
61 *
62 * PARAMETERS: None
63 *
64 * RETURN: None
65 *
66 * DESCRIPTION: Save the current CPU stack pointer at subsystem startup
67 *
68 ******************************************************************************/
69
70void acpi_ut_init_stack_ptr_trace(void)
71{
72 acpi_size current_sp;
73
74 acpi_gbl_entry_stack_pointer = &current_sp;
75}
76
77/*******************************************************************************
78 *
79 * FUNCTION: acpi_ut_track_stack_ptr
80 *
81 * PARAMETERS: None
82 *
83 * RETURN: None
84 *
85 * DESCRIPTION: Save the current CPU stack pointer
86 *
87 ******************************************************************************/
88
89void acpi_ut_track_stack_ptr(void)
90{
91 acpi_size current_sp;
92
93 if (&current_sp < acpi_gbl_lowest_stack_pointer) {
94 acpi_gbl_lowest_stack_pointer = &current_sp;
95 }
96
97 if (acpi_gbl_nesting_level > acpi_gbl_deepest_nesting) {
98 acpi_gbl_deepest_nesting = acpi_gbl_nesting_level;
99 }
100}
101
102/*******************************************************************************
103 *
104 * FUNCTION: acpi_ut_trim_function_name
105 *
106 * PARAMETERS: function_name - Ascii string containing a procedure name
107 *
108 * RETURN: Updated pointer to the function name
109 *
110 * DESCRIPTION: Remove the "Acpi" prefix from the function name, if present.
111 * This allows compiler macros such as __func__ to be used
112 * with no change to the debug output.
113 *
114 ******************************************************************************/
115
116static const char *acpi_ut_trim_function_name(const char *function_name)
117{
118
119 /* All Function names are longer than 4 chars, check is safe */
120
121 if (*(ACPI_CAST_PTR(u32, function_name)) == ACPI_PREFIX_MIXED) {
122
123 /* This is the case where the original source has not been modified */
124
125 return (function_name + 4);
126 }
127
128 if (*(ACPI_CAST_PTR(u32, function_name)) == ACPI_PREFIX_LOWER) {
129
130 /* This is the case where the source has been 'linuxized' */
131
132 return (function_name + 5);
133 }
134
135 return (function_name);
136}
137
138/*******************************************************************************
139 *
140 * FUNCTION: acpi_debug_print
141 *
142 * PARAMETERS: requested_debug_level - Requested debug print level
143 * line_number - Caller's line number (for error output)
144 * function_name - Caller's procedure name
145 * module_name - Caller's module name
146 * component_id - Caller's component ID
147 * Format - Printf format field
148 * ... - Optional printf arguments
149 *
150 * RETURN: None
151 *
152 * DESCRIPTION: Print error message with prefix consisting of the module name,
153 * line number, and component ID.
154 *
155 ******************************************************************************/
156
157void ACPI_INTERNAL_VAR_XFACE
158acpi_debug_print(u32 requested_debug_level,
159 u32 line_number,
160 const char *function_name,
161 const char *module_name,
162 u32 component_id, const char *format, ...)
163{
164 acpi_thread_id thread_id;
165 va_list args;
166
167 /*
168 * Stay silent if the debug level or component ID is disabled
169 */
170 if (!(requested_debug_level & acpi_dbg_level) ||
171 !(component_id & acpi_dbg_layer)) {
172 return;
173 }
174
175 /*
176 * Thread tracking and context switch notification
177 */
178 thread_id = acpi_os_get_thread_id();
179 if (thread_id != acpi_gbl_prev_thread_id) {
180 if (ACPI_LV_THREADS & acpi_dbg_level) {
181 acpi_os_printf
182 ("\n**** Context Switch from TID %lX to TID %lX ****\n\n",
183 (unsigned long)acpi_gbl_prev_thread_id,
184 (unsigned long)thread_id);
185 }
186
187 acpi_gbl_prev_thread_id = thread_id;
188 }
189
190 /*
191 * Display the module name, current line number, thread ID (if requested),
192 * current procedure nesting level, and the current procedure name
193 */
194 acpi_os_printf("%8s-%04ld ", module_name, line_number);
195
196 if (ACPI_LV_THREADS & acpi_dbg_level) {
197 acpi_os_printf("[%04lX] ", (unsigned long)thread_id);
198 }
199
200 acpi_os_printf("[%02ld] %-22.22s: ",
201 acpi_gbl_nesting_level,
202 acpi_ut_trim_function_name(function_name));
203
204 va_start(args, format);
205 acpi_os_vprintf(format, args);
206 va_end(args);
207}
208
209ACPI_EXPORT_SYMBOL(acpi_debug_print)
210
211/*******************************************************************************
212 *
213 * FUNCTION: acpi_debug_print_raw
214 *
215 * PARAMETERS: requested_debug_level - Requested debug print level
216 * line_number - Caller's line number
217 * function_name - Caller's procedure name
218 * module_name - Caller's module name
219 * component_id - Caller's component ID
220 * Format - Printf format field
221 * ... - Optional printf arguments
222 *
223 * RETURN: None
224 *
225 * DESCRIPTION: Print message with no headers. Has same interface as
226 * debug_print so that the same macros can be used.
227 *
228 ******************************************************************************/
229void ACPI_INTERNAL_VAR_XFACE
230acpi_debug_print_raw(u32 requested_debug_level,
231 u32 line_number,
232 const char *function_name,
233 const char *module_name,
234 u32 component_id, const char *format, ...)
235{
236 va_list args;
237
238 if (!(requested_debug_level & acpi_dbg_level) ||
239 !(component_id & acpi_dbg_layer)) {
240 return;
241 }
242
243 va_start(args, format);
244 acpi_os_vprintf(format, args);
245 va_end(args);
246}
247
248ACPI_EXPORT_SYMBOL(acpi_debug_print_raw)
249
250/*******************************************************************************
251 *
252 * FUNCTION: acpi_ut_trace
253 *
254 * PARAMETERS: line_number - Caller's line number
255 * function_name - Caller's procedure name
256 * module_name - Caller's module name
257 * component_id - Caller's component ID
258 *
259 * RETURN: None
260 *
261 * DESCRIPTION: Function entry trace. Prints only if TRACE_FUNCTIONS bit is
262 * set in debug_level
263 *
264 ******************************************************************************/
265void
266acpi_ut_trace(u32 line_number,
267 const char *function_name,
268 const char *module_name, u32 component_id)
269{
270
271 acpi_gbl_nesting_level++;
272 acpi_ut_track_stack_ptr();
273
274 acpi_debug_print(ACPI_LV_FUNCTIONS,
275 line_number, function_name, module_name, component_id,
276 "%s\n", acpi_gbl_fn_entry_str);
277}
278
279ACPI_EXPORT_SYMBOL(acpi_ut_trace)
280
281/*******************************************************************************
282 *
283 * FUNCTION: acpi_ut_trace_ptr
284 *
285 * PARAMETERS: line_number - Caller's line number
286 * function_name - Caller's procedure name
287 * module_name - Caller's module name
288 * component_id - Caller's component ID
289 * Pointer - Pointer to display
290 *
291 * RETURN: None
292 *
293 * DESCRIPTION: Function entry trace. Prints only if TRACE_FUNCTIONS bit is
294 * set in debug_level
295 *
296 ******************************************************************************/
297void
298acpi_ut_trace_ptr(u32 line_number,
299 const char *function_name,
300 const char *module_name, u32 component_id, void *pointer)
301{
302 acpi_gbl_nesting_level++;
303 acpi_ut_track_stack_ptr();
304
305 acpi_debug_print(ACPI_LV_FUNCTIONS,
306 line_number, function_name, module_name, component_id,
307 "%s %p\n", acpi_gbl_fn_entry_str, pointer);
308}
309
310/*******************************************************************************
311 *
312 * FUNCTION: acpi_ut_trace_str
313 *
314 * PARAMETERS: line_number - Caller's line number
315 * function_name - Caller's procedure name
316 * module_name - Caller's module name
317 * component_id - Caller's component ID
318 * String - Additional string to display
319 *
320 * RETURN: None
321 *
322 * DESCRIPTION: Function entry trace. Prints only if TRACE_FUNCTIONS bit is
323 * set in debug_level
324 *
325 ******************************************************************************/
326
327void
328acpi_ut_trace_str(u32 line_number,
329 const char *function_name,
330 const char *module_name, u32 component_id, char *string)
331{
332
333 acpi_gbl_nesting_level++;
334 acpi_ut_track_stack_ptr();
335
336 acpi_debug_print(ACPI_LV_FUNCTIONS,
337 line_number, function_name, module_name, component_id,
338 "%s %s\n", acpi_gbl_fn_entry_str, string);
339}
340
341/*******************************************************************************
342 *
343 * FUNCTION: acpi_ut_trace_u32
344 *
345 * PARAMETERS: line_number - Caller's line number
346 * function_name - Caller's procedure name
347 * module_name - Caller's module name
348 * component_id - Caller's component ID
349 * Integer - Integer to display
350 *
351 * RETURN: None
352 *
353 * DESCRIPTION: Function entry trace. Prints only if TRACE_FUNCTIONS bit is
354 * set in debug_level
355 *
356 ******************************************************************************/
357
358void
359acpi_ut_trace_u32(u32 line_number,
360 const char *function_name,
361 const char *module_name, u32 component_id, u32 integer)
362{
363
364 acpi_gbl_nesting_level++;
365 acpi_ut_track_stack_ptr();
366
367 acpi_debug_print(ACPI_LV_FUNCTIONS,
368 line_number, function_name, module_name, component_id,
369 "%s %08X\n", acpi_gbl_fn_entry_str, integer);
370}
371
372/*******************************************************************************
373 *
374 * FUNCTION: acpi_ut_exit
375 *
376 * PARAMETERS: line_number - Caller's line number
377 * function_name - Caller's procedure name
378 * module_name - Caller's module name
379 * component_id - Caller's component ID
380 *
381 * RETURN: None
382 *
383 * DESCRIPTION: Function exit trace. Prints only if TRACE_FUNCTIONS bit is
384 * set in debug_level
385 *
386 ******************************************************************************/
387
388void
389acpi_ut_exit(u32 line_number,
390 const char *function_name,
391 const char *module_name, u32 component_id)
392{
393
394 acpi_debug_print(ACPI_LV_FUNCTIONS,
395 line_number, function_name, module_name, component_id,
396 "%s\n", acpi_gbl_fn_exit_str);
397
398 acpi_gbl_nesting_level--;
399}
400
401ACPI_EXPORT_SYMBOL(acpi_ut_exit)
402
403/*******************************************************************************
404 *
405 * FUNCTION: acpi_ut_status_exit
406 *
407 * PARAMETERS: line_number - Caller's line number
408 * function_name - Caller's procedure name
409 * module_name - Caller's module name
410 * component_id - Caller's component ID
411 * Status - Exit status code
412 *
413 * RETURN: None
414 *
415 * DESCRIPTION: Function exit trace. Prints only if TRACE_FUNCTIONS bit is
416 * set in debug_level. Prints exit status also.
417 *
418 ******************************************************************************/
419void
420acpi_ut_status_exit(u32 line_number,
421 const char *function_name,
422 const char *module_name,
423 u32 component_id, acpi_status status)
424{
425
426 if (ACPI_SUCCESS(status)) {
427 acpi_debug_print(ACPI_LV_FUNCTIONS,
428 line_number, function_name, module_name,
429 component_id, "%s %s\n", acpi_gbl_fn_exit_str,
430 acpi_format_exception(status));
431 } else {
432 acpi_debug_print(ACPI_LV_FUNCTIONS,
433 line_number, function_name, module_name,
434 component_id, "%s ****Exception****: %s\n",
435 acpi_gbl_fn_exit_str,
436 acpi_format_exception(status));
437 }
438
439 acpi_gbl_nesting_level--;
440}
441
442ACPI_EXPORT_SYMBOL(acpi_ut_status_exit)
443
444/*******************************************************************************
445 *
446 * FUNCTION: acpi_ut_value_exit
447 *
448 * PARAMETERS: line_number - Caller's line number
449 * function_name - Caller's procedure name
450 * module_name - Caller's module name
451 * component_id - Caller's component ID
452 * Value - Value to be printed with exit msg
453 *
454 * RETURN: None
455 *
456 * DESCRIPTION: Function exit trace. Prints only if TRACE_FUNCTIONS bit is
457 * set in debug_level. Prints exit value also.
458 *
459 ******************************************************************************/
460void
461acpi_ut_value_exit(u32 line_number,
462 const char *function_name,
463 const char *module_name,
464 u32 component_id, acpi_integer value)
465{
466
467 acpi_debug_print(ACPI_LV_FUNCTIONS,
468 line_number, function_name, module_name, component_id,
469 "%s %8.8X%8.8X\n", acpi_gbl_fn_exit_str,
470 ACPI_FORMAT_UINT64(value));
471
472 acpi_gbl_nesting_level--;
473}
474
475ACPI_EXPORT_SYMBOL(acpi_ut_value_exit)
476
477/*******************************************************************************
478 *
479 * FUNCTION: acpi_ut_ptr_exit
480 *
481 * PARAMETERS: line_number - Caller's line number
482 * function_name - Caller's procedure name
483 * module_name - Caller's module name
484 * component_id - Caller's component ID
485 * Ptr - Pointer to display
486 *
487 * RETURN: None
488 *
489 * DESCRIPTION: Function exit trace. Prints only if TRACE_FUNCTIONS bit is
490 * set in debug_level. Prints exit value also.
491 *
492 ******************************************************************************/
493void
494acpi_ut_ptr_exit(u32 line_number,
495 const char *function_name,
496 const char *module_name, u32 component_id, u8 *ptr)
497{
498
499 acpi_debug_print(ACPI_LV_FUNCTIONS,
500 line_number, function_name, module_name, component_id,
501 "%s %p\n", acpi_gbl_fn_exit_str, ptr);
502
503 acpi_gbl_nesting_level--;
504}
505
506#endif
507
508/*******************************************************************************
509 *
510 * FUNCTION: acpi_ut_dump_buffer
511 *
512 * PARAMETERS: Buffer - Buffer to dump
513 * Count - Amount to dump, in bytes
514 * Display - BYTE, WORD, DWORD, or QWORD display
515 * component_iD - Caller's component ID
516 *
517 * RETURN: None
518 *
519 * DESCRIPTION: Generic dump buffer in both hex and ascii.
520 *
521 ******************************************************************************/
522
523void acpi_ut_dump_buffer2(u8 * buffer, u32 count, u32 display)
524{
525 u32 i = 0;
526 u32 j;
527 u32 temp32;
528 u8 buf_char;
529
530 if (!buffer) {
531 acpi_os_printf("Null Buffer Pointer in DumpBuffer!\n");
532 return;
533 }
534
535 if ((count < 4) || (count & 0x01)) {
536 display = DB_BYTE_DISPLAY;
537 }
538
539 /* Nasty little dump buffer routine! */
540
541 while (i < count) {
542
543 /* Print current offset */
544
545 acpi_os_printf("%6.4X: ", i);
546
547 /* Print 16 hex chars */
548
549 for (j = 0; j < 16;) {
550 if (i + j >= count) {
551
552 /* Dump fill spaces */
553
554 acpi_os_printf("%*s", ((display * 2) + 1), " ");
555 j += display;
556 continue;
557 }
558
559 switch (display) {
560 case DB_BYTE_DISPLAY:
561 default: /* Default is BYTE display */
562
563 acpi_os_printf("%02X ",
564 buffer[(acpi_size) i + j]);
565 break;
566
567 case DB_WORD_DISPLAY:
568
569 ACPI_MOVE_16_TO_32(&temp32,
570 &buffer[(acpi_size) i + j]);
571 acpi_os_printf("%04X ", temp32);
572 break;
573
574 case DB_DWORD_DISPLAY:
575
576 ACPI_MOVE_32_TO_32(&temp32,
577 &buffer[(acpi_size) i + j]);
578 acpi_os_printf("%08X ", temp32);
579 break;
580
581 case DB_QWORD_DISPLAY:
582
583 ACPI_MOVE_32_TO_32(&temp32,
584 &buffer[(acpi_size) i + j]);
585 acpi_os_printf("%08X", temp32);
586
587 ACPI_MOVE_32_TO_32(&temp32,
588 &buffer[(acpi_size) i + j +
589 4]);
590 acpi_os_printf("%08X ", temp32);
591 break;
592 }
593
594 j += display;
595 }
596
597 /*
598 * Print the ASCII equivalent characters but watch out for the bad
599 * unprintable ones (printable chars are 0x20 through 0x7E)
600 */
601 acpi_os_printf(" ");
602 for (j = 0; j < 16; j++) {
603 if (i + j >= count) {
604 acpi_os_printf("\n");
605 return;
606 }
607
608 buf_char = buffer[(acpi_size) i + j];
609 if (ACPI_IS_PRINT(buf_char)) {
610 acpi_os_printf("%c", buf_char);
611 } else {
612 acpi_os_printf(".");
613 }
614 }
615
616 /* Done with that line. */
617
618 acpi_os_printf("\n");
619 i += 16;
620 }
621
622 return;
623}
624
625/*******************************************************************************
626 *
627 * FUNCTION: acpi_ut_dump_buffer
628 *
629 * PARAMETERS: Buffer - Buffer to dump
630 * Count - Amount to dump, in bytes
631 * Display - BYTE, WORD, DWORD, or QWORD display
632 * component_iD - Caller's component ID
633 *
634 * RETURN: None
635 *
636 * DESCRIPTION: Generic dump buffer in both hex and ascii.
637 *
638 ******************************************************************************/
639
640void acpi_ut_dump_buffer(u8 * buffer, u32 count, u32 display, u32 component_id)
641{
642
643 /* Only dump the buffer if tracing is enabled */
644
645 if (!((ACPI_LV_TABLES & acpi_dbg_level) &&
646 (component_id & acpi_dbg_layer))) {
647 return;
648 }
649
650 acpi_ut_dump_buffer2(buffer, count, display);
651}
diff --git a/drivers/acpi/acpica/utdelete.c b/drivers/acpi/acpica/utdelete.c
new file mode 100644
index 00000000000..5b4e3b1a752
--- /dev/null
+++ b/drivers/acpi/acpica/utdelete.c
@@ -0,0 +1,677 @@
1/*******************************************************************************
2 *
3 * Module Name: utdelete - object deletion and reference count utilities
4 *
5 ******************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46#include <acpi/acinterp.h>
47#include <acpi/acnamesp.h>
48#include <acpi/acevents.h>
49
50#define _COMPONENT ACPI_UTILITIES
51ACPI_MODULE_NAME("utdelete")
52
53/* Local prototypes */
54static void acpi_ut_delete_internal_obj(union acpi_operand_object *object);
55
56static void
57acpi_ut_update_ref_count(union acpi_operand_object *object, u32 action);
58
59/*******************************************************************************
60 *
61 * FUNCTION: acpi_ut_delete_internal_obj
62 *
63 * PARAMETERS: Object - Object to be deleted
64 *
65 * RETURN: None
66 *
67 * DESCRIPTION: Low level object deletion, after reference counts have been
68 * updated (All reference counts, including sub-objects!)
69 *
70 ******************************************************************************/
71
72static void acpi_ut_delete_internal_obj(union acpi_operand_object *object)
73{
74 void *obj_pointer = NULL;
75 union acpi_operand_object *handler_desc;
76 union acpi_operand_object *second_desc;
77 union acpi_operand_object *next_desc;
78
79 ACPI_FUNCTION_TRACE_PTR(ut_delete_internal_obj, object);
80
81 if (!object) {
82 return_VOID;
83 }
84
85 /*
86 * Must delete or free any pointers within the object that are not
87 * actual ACPI objects (for example, a raw buffer pointer).
88 */
89 switch (ACPI_GET_OBJECT_TYPE(object)) {
90 case ACPI_TYPE_STRING:
91
92 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
93 "**** String %p, ptr %p\n", object,
94 object->string.pointer));
95
96 /* Free the actual string buffer */
97
98 if (!(object->common.flags & AOPOBJ_STATIC_POINTER)) {
99
100 /* But only if it is NOT a pointer into an ACPI table */
101
102 obj_pointer = object->string.pointer;
103 }
104 break;
105
106 case ACPI_TYPE_BUFFER:
107
108 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
109 "**** Buffer %p, ptr %p\n", object,
110 object->buffer.pointer));
111
112 /* Free the actual buffer */
113
114 if (!(object->common.flags & AOPOBJ_STATIC_POINTER)) {
115
116 /* But only if it is NOT a pointer into an ACPI table */
117
118 obj_pointer = object->buffer.pointer;
119 }
120 break;
121
122 case ACPI_TYPE_PACKAGE:
123
124 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
125 " **** Package of count %X\n",
126 object->package.count));
127
128 /*
129 * Elements of the package are not handled here, they are deleted
130 * separately
131 */
132
133 /* Free the (variable length) element pointer array */
134
135 obj_pointer = object->package.elements;
136 break;
137
138 /*
139 * These objects have a possible list of notify handlers.
140 * Device object also may have a GPE block.
141 */
142 case ACPI_TYPE_DEVICE:
143
144 if (object->device.gpe_block) {
145 (void)acpi_ev_delete_gpe_block(object->device.
146 gpe_block);
147 }
148
149 /*lint -fallthrough */
150
151 case ACPI_TYPE_PROCESSOR:
152 case ACPI_TYPE_THERMAL:
153
154 /* Walk the notify handler list for this object */
155
156 handler_desc = object->common_notify.handler;
157 while (handler_desc) {
158 next_desc = handler_desc->address_space.next;
159 acpi_ut_remove_reference(handler_desc);
160 handler_desc = next_desc;
161 }
162 break;
163
164 case ACPI_TYPE_MUTEX:
165
166 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
167 "***** Mutex %p, OS Mutex %p\n",
168 object, object->mutex.os_mutex));
169
170 if (object == acpi_gbl_global_lock_mutex) {
171
172 /* Global Lock has extra semaphore */
173
174 (void)
175 acpi_os_delete_semaphore
176 (acpi_gbl_global_lock_semaphore);
177 acpi_gbl_global_lock_semaphore = NULL;
178
179 acpi_os_delete_mutex(object->mutex.os_mutex);
180 acpi_gbl_global_lock_mutex = NULL;
181 } else {
182 acpi_ex_unlink_mutex(object);
183 acpi_os_delete_mutex(object->mutex.os_mutex);
184 }
185 break;
186
187 case ACPI_TYPE_EVENT:
188
189 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
190 "***** Event %p, OS Semaphore %p\n",
191 object, object->event.os_semaphore));
192
193 (void)acpi_os_delete_semaphore(object->event.os_semaphore);
194 object->event.os_semaphore = NULL;
195 break;
196
197 case ACPI_TYPE_METHOD:
198
199 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
200 "***** Method %p\n", object));
201
202 /* Delete the method mutex if it exists */
203
204 if (object->method.mutex) {
205 acpi_os_delete_mutex(object->method.mutex->mutex.
206 os_mutex);
207 acpi_ut_delete_object_desc(object->method.mutex);
208 object->method.mutex = NULL;
209 }
210 break;
211
212 case ACPI_TYPE_REGION:
213
214 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
215 "***** Region %p\n", object));
216
217 second_desc = acpi_ns_get_secondary_object(object);
218 if (second_desc) {
219 /*
220 * Free the region_context if and only if the handler is one of the
221 * default handlers -- and therefore, we created the context object
222 * locally, it was not created by an external caller.
223 */
224 handler_desc = object->region.handler;
225 if (handler_desc) {
226 if (handler_desc->address_space.handler_flags &
227 ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) {
228
229 /* Deactivate region and free region context */
230
231 if (handler_desc->address_space.setup) {
232 (void)handler_desc->
233 address_space.setup(object,
234 ACPI_REGION_DEACTIVATE,
235 handler_desc->
236 address_space.
237 context,
238 &second_desc->
239 extra.
240 region_context);
241 }
242 }
243
244 acpi_ut_remove_reference(handler_desc);
245 }
246
247 /* Now we can free the Extra object */
248
249 acpi_ut_delete_object_desc(second_desc);
250 }
251 break;
252
253 case ACPI_TYPE_BUFFER_FIELD:
254
255 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
256 "***** Buffer Field %p\n", object));
257
258 second_desc = acpi_ns_get_secondary_object(object);
259 if (second_desc) {
260 acpi_ut_delete_object_desc(second_desc);
261 }
262 break;
263
264 case ACPI_TYPE_LOCAL_BANK_FIELD:
265
266 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
267 "***** Bank Field %p\n", object));
268
269 second_desc = acpi_ns_get_secondary_object(object);
270 if (second_desc) {
271 acpi_ut_delete_object_desc(second_desc);
272 }
273 break;
274
275 default:
276 break;
277 }
278
279 /* Free any allocated memory (pointer within the object) found above */
280
281 if (obj_pointer) {
282 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
283 "Deleting Object Subptr %p\n", obj_pointer));
284 ACPI_FREE(obj_pointer);
285 }
286
287 /* Now the object can be safely deleted */
288
289 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, "Deleting Object %p [%s]\n",
290 object, acpi_ut_get_object_type_name(object)));
291
292 acpi_ut_delete_object_desc(object);
293 return_VOID;
294}
295
296/*******************************************************************************
297 *
298 * FUNCTION: acpi_ut_delete_internal_object_list
299 *
300 * PARAMETERS: obj_list - Pointer to the list to be deleted
301 *
302 * RETURN: None
303 *
304 * DESCRIPTION: This function deletes an internal object list, including both
305 * simple objects and package objects
306 *
307 ******************************************************************************/
308
309void acpi_ut_delete_internal_object_list(union acpi_operand_object **obj_list)
310{
311 union acpi_operand_object **internal_obj;
312
313 ACPI_FUNCTION_TRACE(ut_delete_internal_object_list);
314
315 /* Walk the null-terminated internal list */
316
317 for (internal_obj = obj_list; *internal_obj; internal_obj++) {
318 acpi_ut_remove_reference(*internal_obj);
319 }
320
321 /* Free the combined parameter pointer list and object array */
322
323 ACPI_FREE(obj_list);
324 return_VOID;
325}
326
327/*******************************************************************************
328 *
329 * FUNCTION: acpi_ut_update_ref_count
330 *
331 * PARAMETERS: Object - Object whose ref count is to be updated
332 * Action - What to do
333 *
334 * RETURN: New ref count
335 *
336 * DESCRIPTION: Modify the ref count and return it.
337 *
338 ******************************************************************************/
339
340static void
341acpi_ut_update_ref_count(union acpi_operand_object *object, u32 action)
342{
343 u16 count;
344 u16 new_count;
345
346 ACPI_FUNCTION_NAME(ut_update_ref_count);
347
348 if (!object) {
349 return;
350 }
351
352 count = object->common.reference_count;
353 new_count = count;
354
355 /*
356 * Perform the reference count action (increment, decrement, force delete)
357 */
358 switch (action) {
359 case REF_INCREMENT:
360
361 new_count++;
362 object->common.reference_count = new_count;
363
364 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
365 "Obj %p Refs=%X, [Incremented]\n",
366 object, new_count));
367 break;
368
369 case REF_DECREMENT:
370
371 if (count < 1) {
372 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
373 "Obj %p Refs=%X, can't decrement! (Set to 0)\n",
374 object, new_count));
375
376 new_count = 0;
377 } else {
378 new_count--;
379
380 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
381 "Obj %p Refs=%X, [Decremented]\n",
382 object, new_count));
383 }
384
385 if (ACPI_GET_OBJECT_TYPE(object) == ACPI_TYPE_METHOD) {
386 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
387 "Method Obj %p Refs=%X, [Decremented]\n",
388 object, new_count));
389 }
390
391 object->common.reference_count = new_count;
392 if (new_count == 0) {
393 acpi_ut_delete_internal_obj(object);
394 }
395 break;
396
397 case REF_FORCE_DELETE:
398
399 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
400 "Obj %p Refs=%X, Force delete! (Set to 0)\n",
401 object, count));
402
403 new_count = 0;
404 object->common.reference_count = new_count;
405 acpi_ut_delete_internal_obj(object);
406 break;
407
408 default:
409
410 ACPI_ERROR((AE_INFO, "Unknown action (%X)", action));
411 break;
412 }
413
414 /*
415 * Sanity check the reference count, for debug purposes only.
416 * (A deleted object will have a huge reference count)
417 */
418 if (count > ACPI_MAX_REFERENCE_COUNT) {
419 ACPI_WARNING((AE_INFO,
420 "Large Reference Count (%X) in object %p", count,
421 object));
422 }
423}
424
425/*******************************************************************************
426 *
427 * FUNCTION: acpi_ut_update_object_reference
428 *
429 * PARAMETERS: Object - Increment ref count for this object
430 * and all sub-objects
431 * Action - Either REF_INCREMENT or REF_DECREMENT or
432 * REF_FORCE_DELETE
433 *
434 * RETURN: Status
435 *
436 * DESCRIPTION: Increment the object reference count
437 *
438 * Object references are incremented when:
439 * 1) An object is attached to a Node (namespace object)
440 * 2) An object is copied (all subobjects must be incremented)
441 *
442 * Object references are decremented when:
443 * 1) An object is detached from an Node
444 *
445 ******************************************************************************/
446
447acpi_status
448acpi_ut_update_object_reference(union acpi_operand_object *object, u16 action)
449{
450 acpi_status status = AE_OK;
451 union acpi_generic_state *state_list = NULL;
452 union acpi_operand_object *next_object = NULL;
453 union acpi_generic_state *state;
454 u32 i;
455
456 ACPI_FUNCTION_TRACE_PTR(ut_update_object_reference, object);
457
458 while (object) {
459
460 /* Make sure that this isn't a namespace handle */
461
462 if (ACPI_GET_DESCRIPTOR_TYPE(object) == ACPI_DESC_TYPE_NAMED) {
463 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
464 "Object %p is NS handle\n", object));
465 return_ACPI_STATUS(AE_OK);
466 }
467
468 /*
469 * All sub-objects must have their reference count incremented also.
470 * Different object types have different subobjects.
471 */
472 switch (ACPI_GET_OBJECT_TYPE(object)) {
473 case ACPI_TYPE_DEVICE:
474 case ACPI_TYPE_PROCESSOR:
475 case ACPI_TYPE_POWER:
476 case ACPI_TYPE_THERMAL:
477
478 /* Update the notify objects for these types (if present) */
479
480 acpi_ut_update_ref_count(object->common_notify.
481 system_notify, action);
482 acpi_ut_update_ref_count(object->common_notify.
483 device_notify, action);
484 break;
485
486 case ACPI_TYPE_PACKAGE:
487 /*
488 * We must update all the sub-objects of the package,
489 * each of whom may have their own sub-objects.
490 */
491 for (i = 0; i < object->package.count; i++) {
492 /*
493 * Push each element onto the stack for later processing.
494 * Note: There can be null elements within the package,
495 * these are simply ignored
496 */
497 status =
498 acpi_ut_create_update_state_and_push
499 (object->package.elements[i], action,
500 &state_list);
501 if (ACPI_FAILURE(status)) {
502 goto error_exit;
503 }
504 }
505 break;
506
507 case ACPI_TYPE_BUFFER_FIELD:
508
509 next_object = object->buffer_field.buffer_obj;
510 break;
511
512 case ACPI_TYPE_LOCAL_REGION_FIELD:
513
514 next_object = object->field.region_obj;
515 break;
516
517 case ACPI_TYPE_LOCAL_BANK_FIELD:
518
519 next_object = object->bank_field.bank_obj;
520 status =
521 acpi_ut_create_update_state_and_push(object->
522 bank_field.
523 region_obj,
524 action,
525 &state_list);
526 if (ACPI_FAILURE(status)) {
527 goto error_exit;
528 }
529 break;
530
531 case ACPI_TYPE_LOCAL_INDEX_FIELD:
532
533 next_object = object->index_field.index_obj;
534 status =
535 acpi_ut_create_update_state_and_push(object->
536 index_field.
537 data_obj,
538 action,
539 &state_list);
540 if (ACPI_FAILURE(status)) {
541 goto error_exit;
542 }
543 break;
544
545 case ACPI_TYPE_LOCAL_REFERENCE:
546 /*
547 * The target of an Index (a package, string, or buffer) or a named
548 * reference must track changes to the ref count of the index or
549 * target object.
550 */
551 if ((object->reference.class == ACPI_REFCLASS_INDEX) ||
552 (object->reference.class == ACPI_REFCLASS_NAME)) {
553 next_object = object->reference.object;
554 }
555 break;
556
557 case ACPI_TYPE_REGION:
558 default:
559 break; /* No subobjects for all other types */
560 }
561
562 /*
563 * Now we can update the count in the main object. This can only
564 * happen after we update the sub-objects in case this causes the
565 * main object to be deleted.
566 */
567 acpi_ut_update_ref_count(object, action);
568 object = NULL;
569
570 /* Move on to the next object to be updated */
571
572 if (next_object) {
573 object = next_object;
574 next_object = NULL;
575 } else if (state_list) {
576 state = acpi_ut_pop_generic_state(&state_list);
577 object = state->update.object;
578 acpi_ut_delete_generic_state(state);
579 }
580 }
581
582 return_ACPI_STATUS(AE_OK);
583
584 error_exit:
585
586 ACPI_EXCEPTION((AE_INFO, status,
587 "Could not update object reference count"));
588
589 /* Free any stacked Update State objects */
590
591 while (state_list) {
592 state = acpi_ut_pop_generic_state(&state_list);
593 acpi_ut_delete_generic_state(state);
594 }
595
596 return_ACPI_STATUS(status);
597}
598
599/*******************************************************************************
600 *
601 * FUNCTION: acpi_ut_add_reference
602 *
603 * PARAMETERS: Object - Object whose reference count is to be
604 * incremented
605 *
606 * RETURN: None
607 *
608 * DESCRIPTION: Add one reference to an ACPI object
609 *
610 ******************************************************************************/
611
612void acpi_ut_add_reference(union acpi_operand_object *object)
613{
614
615 ACPI_FUNCTION_TRACE_PTR(ut_add_reference, object);
616
617 /* Ensure that we have a valid object */
618
619 if (!acpi_ut_valid_internal_object(object)) {
620 return_VOID;
621 }
622
623 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
624 "Obj %p Current Refs=%X [To Be Incremented]\n",
625 object, object->common.reference_count));
626
627 /* Increment the reference count */
628
629 (void)acpi_ut_update_object_reference(object, REF_INCREMENT);
630 return_VOID;
631}
632
633/*******************************************************************************
634 *
635 * FUNCTION: acpi_ut_remove_reference
636 *
637 * PARAMETERS: Object - Object whose ref count will be decremented
638 *
639 * RETURN: None
640 *
641 * DESCRIPTION: Decrement the reference count of an ACPI internal object
642 *
643 ******************************************************************************/
644
645void acpi_ut_remove_reference(union acpi_operand_object *object)
646{
647
648 ACPI_FUNCTION_TRACE_PTR(ut_remove_reference, object);
649
650 /*
651 * Allow a NULL pointer to be passed in, just ignore it. This saves
652 * each caller from having to check. Also, ignore NS nodes.
653 *
654 */
655 if (!object ||
656 (ACPI_GET_DESCRIPTOR_TYPE(object) == ACPI_DESC_TYPE_NAMED)) {
657 return_VOID;
658 }
659
660 /* Ensure that we have a valid object */
661
662 if (!acpi_ut_valid_internal_object(object)) {
663 return_VOID;
664 }
665
666 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
667 "Obj %p Current Refs=%X [To Be Decremented]\n",
668 object, object->common.reference_count));
669
670 /*
671 * Decrement the reference count, and only actually delete the object
672 * if the reference count becomes 0. (Must also decrement the ref count
673 * of all subobjects!)
674 */
675 (void)acpi_ut_update_object_reference(object, REF_DECREMENT);
676 return_VOID;
677}
diff --git a/drivers/acpi/acpica/uteval.c b/drivers/acpi/acpica/uteval.c
new file mode 100644
index 00000000000..e1e438cd54a
--- /dev/null
+++ b/drivers/acpi/acpica/uteval.c
@@ -0,0 +1,752 @@
1/******************************************************************************
2 *
3 * Module Name: uteval - Object evaluation
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46#include <acpi/acnamesp.h>
47#include <acpi/acinterp.h>
48
49#define _COMPONENT ACPI_UTILITIES
50ACPI_MODULE_NAME("uteval")
51
52/* Local prototypes */
53static void
54acpi_ut_copy_id_string(char *destination, char *source, acpi_size max_length);
55
56static acpi_status
57acpi_ut_translate_one_cid(union acpi_operand_object *obj_desc,
58 struct acpi_compatible_id *one_cid);
59
60/*
61 * Strings supported by the _OSI predefined (internal) method.
62 */
63static char *acpi_interfaces_supported[] = {
64 /* Operating System Vendor Strings */
65
66 "Windows 2000", /* Windows 2000 */
67 "Windows 2001", /* Windows XP */
68 "Windows 2001 SP1", /* Windows XP SP1 */
69 "Windows 2001 SP2", /* Windows XP SP2 */
70 "Windows 2001.1", /* Windows Server 2003 */
71 "Windows 2001.1 SP1", /* Windows Server 2003 SP1 - Added 03/2006 */
72 "Windows 2006", /* Windows Vista - Added 03/2006 */
73
74 /* Feature Group Strings */
75
76 "Extended Address Space Descriptor"
77 /*
78 * All "optional" feature group strings (features that are implemented
79 * by the host) should be implemented in the host version of
80 * acpi_os_validate_interface and should not be added here.
81 */
82};
83
84/*******************************************************************************
85 *
86 * FUNCTION: acpi_ut_osi_implementation
87 *
88 * PARAMETERS: walk_state - Current walk state
89 *
90 * RETURN: Status
91 *
92 * DESCRIPTION: Implementation of the _OSI predefined control method
93 *
94 ******************************************************************************/
95
96acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state)
97{
98 acpi_status status;
99 union acpi_operand_object *string_desc;
100 union acpi_operand_object *return_desc;
101 u32 i;
102
103 ACPI_FUNCTION_TRACE(ut_osi_implementation);
104
105 /* Validate the string input argument */
106
107 string_desc = walk_state->arguments[0].object;
108 if (!string_desc || (string_desc->common.type != ACPI_TYPE_STRING)) {
109 return_ACPI_STATUS(AE_TYPE);
110 }
111
112 /* Create a return object */
113
114 return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
115 if (!return_desc) {
116 return_ACPI_STATUS(AE_NO_MEMORY);
117 }
118
119 /* Default return value is SUPPORTED */
120
121 return_desc->integer.value = ACPI_UINT32_MAX;
122 walk_state->return_desc = return_desc;
123
124 /* Compare input string to static table of supported interfaces */
125
126 for (i = 0; i < ACPI_ARRAY_LENGTH(acpi_interfaces_supported); i++) {
127 if (!ACPI_STRCMP
128 (string_desc->string.pointer,
129 acpi_interfaces_supported[i])) {
130
131 /* The interface is supported */
132
133 return_ACPI_STATUS(AE_OK);
134 }
135 }
136
137 /*
138 * Did not match the string in the static table, call the host OSL to
139 * check for a match with one of the optional strings (such as
140 * "Module Device", "3.0 Thermal Model", etc.)
141 */
142 status = acpi_os_validate_interface(string_desc->string.pointer);
143 if (ACPI_SUCCESS(status)) {
144
145 /* The interface is supported */
146
147 return_ACPI_STATUS(AE_OK);
148 }
149
150 /* The interface is not supported */
151
152 return_desc->integer.value = 0;
153 return_ACPI_STATUS(AE_OK);
154}
155
156/*******************************************************************************
157 *
158 * FUNCTION: acpi_osi_invalidate
159 *
160 * PARAMETERS: interface_string
161 *
162 * RETURN: Status
163 *
164 * DESCRIPTION: invalidate string in pre-defiend _OSI string list
165 *
166 ******************************************************************************/
167
168acpi_status acpi_osi_invalidate(char *interface)
169{
170 int i;
171
172 for (i = 0; i < ACPI_ARRAY_LENGTH(acpi_interfaces_supported); i++) {
173 if (!ACPI_STRCMP(interface, acpi_interfaces_supported[i])) {
174 *acpi_interfaces_supported[i] = '\0';
175 return AE_OK;
176 }
177 }
178 return AE_NOT_FOUND;
179}
180
181/*******************************************************************************
182 *
183 * FUNCTION: acpi_ut_evaluate_object
184 *
185 * PARAMETERS: prefix_node - Starting node
186 * Path - Path to object from starting node
187 * expected_return_types - Bitmap of allowed return types
188 * return_desc - Where a return value is stored
189 *
190 * RETURN: Status
191 *
192 * DESCRIPTION: Evaluates a namespace object and verifies the type of the
193 * return object. Common code that simplifies accessing objects
194 * that have required return objects of fixed types.
195 *
196 * NOTE: Internal function, no parameter validation
197 *
198 ******************************************************************************/
199
200acpi_status
201acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node,
202 char *path,
203 u32 expected_return_btypes,
204 union acpi_operand_object **return_desc)
205{
206 struct acpi_evaluate_info *info;
207 acpi_status status;
208 u32 return_btype;
209
210 ACPI_FUNCTION_TRACE(ut_evaluate_object);
211
212 /* Allocate the evaluation information block */
213
214 info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
215 if (!info) {
216 return_ACPI_STATUS(AE_NO_MEMORY);
217 }
218
219 info->prefix_node = prefix_node;
220 info->pathname = path;
221
222 /* Evaluate the object/method */
223
224 status = acpi_ns_evaluate(info);
225 if (ACPI_FAILURE(status)) {
226 if (status == AE_NOT_FOUND) {
227 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
228 "[%4.4s.%s] was not found\n",
229 acpi_ut_get_node_name(prefix_node),
230 path));
231 } else {
232 ACPI_ERROR_METHOD("Method execution failed",
233 prefix_node, path, status);
234 }
235
236 goto cleanup;
237 }
238
239 /* Did we get a return object? */
240
241 if (!info->return_object) {
242 if (expected_return_btypes) {
243 ACPI_ERROR_METHOD("No object was returned from",
244 prefix_node, path, AE_NOT_EXIST);
245
246 status = AE_NOT_EXIST;
247 }
248
249 goto cleanup;
250 }
251
252 /* Map the return object type to the bitmapped type */
253
254 switch (ACPI_GET_OBJECT_TYPE(info->return_object)) {
255 case ACPI_TYPE_INTEGER:
256 return_btype = ACPI_BTYPE_INTEGER;
257 break;
258
259 case ACPI_TYPE_BUFFER:
260 return_btype = ACPI_BTYPE_BUFFER;
261 break;
262
263 case ACPI_TYPE_STRING:
264 return_btype = ACPI_BTYPE_STRING;
265 break;
266
267 case ACPI_TYPE_PACKAGE:
268 return_btype = ACPI_BTYPE_PACKAGE;
269 break;
270
271 default:
272 return_btype = 0;
273 break;
274 }
275
276 if ((acpi_gbl_enable_interpreter_slack) && (!expected_return_btypes)) {
277 /*
278 * We received a return object, but one was not expected. This can
279 * happen frequently if the "implicit return" feature is enabled.
280 * Just delete the return object and return AE_OK.
281 */
282 acpi_ut_remove_reference(info->return_object);
283 goto cleanup;
284 }
285
286 /* Is the return object one of the expected types? */
287
288 if (!(expected_return_btypes & return_btype)) {
289 ACPI_ERROR_METHOD("Return object type is incorrect",
290 prefix_node, path, AE_TYPE);
291
292 ACPI_ERROR((AE_INFO,
293 "Type returned from %s was incorrect: %s, expected Btypes: %X",
294 path,
295 acpi_ut_get_object_type_name(info->return_object),
296 expected_return_btypes));
297
298 /* On error exit, we must delete the return object */
299
300 acpi_ut_remove_reference(info->return_object);
301 status = AE_TYPE;
302 goto cleanup;
303 }
304
305 /* Object type is OK, return it */
306
307 *return_desc = info->return_object;
308
309 cleanup:
310 ACPI_FREE(info);
311 return_ACPI_STATUS(status);
312}
313
314/*******************************************************************************
315 *
316 * FUNCTION: acpi_ut_evaluate_numeric_object
317 *
318 * PARAMETERS: object_name - Object name to be evaluated
319 * device_node - Node for the device
320 * Address - Where the value is returned
321 *
322 * RETURN: Status
323 *
324 * DESCRIPTION: Evaluates a numeric namespace object for a selected device
325 * and stores result in *Address.
326 *
327 * NOTE: Internal function, no parameter validation
328 *
329 ******************************************************************************/
330
331acpi_status
332acpi_ut_evaluate_numeric_object(char *object_name,
333 struct acpi_namespace_node *device_node,
334 acpi_integer * address)
335{
336 union acpi_operand_object *obj_desc;
337 acpi_status status;
338
339 ACPI_FUNCTION_TRACE(ut_evaluate_numeric_object);
340
341 status = acpi_ut_evaluate_object(device_node, object_name,
342 ACPI_BTYPE_INTEGER, &obj_desc);
343 if (ACPI_FAILURE(status)) {
344 return_ACPI_STATUS(status);
345 }
346
347 /* Get the returned Integer */
348
349 *address = obj_desc->integer.value;
350
351 /* On exit, we must delete the return object */
352
353 acpi_ut_remove_reference(obj_desc);
354 return_ACPI_STATUS(status);
355}
356
357/*******************************************************************************
358 *
359 * FUNCTION: acpi_ut_copy_id_string
360 *
361 * PARAMETERS: Destination - Where to copy the string
362 * Source - Source string
363 * max_length - Length of the destination buffer
364 *
365 * RETURN: None
366 *
367 * DESCRIPTION: Copies an ID string for the _HID, _CID, and _UID methods.
368 * Performs removal of a leading asterisk if present -- workaround
369 * for a known issue on a bunch of machines.
370 *
371 ******************************************************************************/
372
373static void
374acpi_ut_copy_id_string(char *destination, char *source, acpi_size max_length)
375{
376
377 /*
378 * Workaround for ID strings that have a leading asterisk. This construct
379 * is not allowed by the ACPI specification (ID strings must be
380 * alphanumeric), but enough existing machines have this embedded in their
381 * ID strings that the following code is useful.
382 */
383 if (*source == '*') {
384 source++;
385 }
386
387 /* Do the actual copy */
388
389 ACPI_STRNCPY(destination, source, max_length);
390}
391
392/*******************************************************************************
393 *
394 * FUNCTION: acpi_ut_execute_HID
395 *
396 * PARAMETERS: device_node - Node for the device
397 * Hid - Where the HID is returned
398 *
399 * RETURN: Status
400 *
401 * DESCRIPTION: Executes the _HID control method that returns the hardware
402 * ID of the device.
403 *
404 * NOTE: Internal function, no parameter validation
405 *
406 ******************************************************************************/
407
408acpi_status
409acpi_ut_execute_HID(struct acpi_namespace_node *device_node,
410 struct acpica_device_id *hid)
411{
412 union acpi_operand_object *obj_desc;
413 acpi_status status;
414
415 ACPI_FUNCTION_TRACE(ut_execute_HID);
416
417 status = acpi_ut_evaluate_object(device_node, METHOD_NAME__HID,
418 ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING,
419 &obj_desc);
420 if (ACPI_FAILURE(status)) {
421 return_ACPI_STATUS(status);
422 }
423
424 if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {
425
426 /* Convert the Numeric HID to string */
427
428 acpi_ex_eisa_id_to_string((u32) obj_desc->integer.value,
429 hid->value);
430 } else {
431 /* Copy the String HID from the returned object */
432
433 acpi_ut_copy_id_string(hid->value, obj_desc->string.pointer,
434 sizeof(hid->value));
435 }
436
437 /* On exit, we must delete the return object */
438
439 acpi_ut_remove_reference(obj_desc);
440 return_ACPI_STATUS(status);
441}
442
443/*******************************************************************************
444 *
445 * FUNCTION: acpi_ut_translate_one_cid
446 *
447 * PARAMETERS: obj_desc - _CID object, must be integer or string
448 * one_cid - Where the CID string is returned
449 *
450 * RETURN: Status
451 *
452 * DESCRIPTION: Return a numeric or string _CID value as a string.
453 * (Compatible ID)
454 *
455 * NOTE: Assumes a maximum _CID string length of
456 * ACPI_MAX_CID_LENGTH.
457 *
458 ******************************************************************************/
459
460static acpi_status
461acpi_ut_translate_one_cid(union acpi_operand_object *obj_desc,
462 struct acpi_compatible_id *one_cid)
463{
464
465 switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
466 case ACPI_TYPE_INTEGER:
467
468 /* Convert the Numeric CID to string */
469
470 acpi_ex_eisa_id_to_string((u32) obj_desc->integer.value,
471 one_cid->value);
472 return (AE_OK);
473
474 case ACPI_TYPE_STRING:
475
476 if (obj_desc->string.length > ACPI_MAX_CID_LENGTH) {
477 return (AE_AML_STRING_LIMIT);
478 }
479
480 /* Copy the String CID from the returned object */
481
482 acpi_ut_copy_id_string(one_cid->value, obj_desc->string.pointer,
483 ACPI_MAX_CID_LENGTH);
484 return (AE_OK);
485
486 default:
487
488 return (AE_TYPE);
489 }
490}
491
492/*******************************************************************************
493 *
494 * FUNCTION: acpi_ut_execute_CID
495 *
496 * PARAMETERS: device_node - Node for the device
497 * return_cid_list - Where the CID list is returned
498 *
499 * RETURN: Status
500 *
501 * DESCRIPTION: Executes the _CID control method that returns one or more
502 * compatible hardware IDs for the device.
503 *
504 * NOTE: Internal function, no parameter validation
505 *
506 ******************************************************************************/
507
508acpi_status
509acpi_ut_execute_CID(struct acpi_namespace_node * device_node,
510 struct acpi_compatible_id_list ** return_cid_list)
511{
512 union acpi_operand_object *obj_desc;
513 acpi_status status;
514 u32 count;
515 u32 size;
516 struct acpi_compatible_id_list *cid_list;
517 u32 i;
518
519 ACPI_FUNCTION_TRACE(ut_execute_CID);
520
521 /* Evaluate the _CID method for this device */
522
523 status = acpi_ut_evaluate_object(device_node, METHOD_NAME__CID,
524 ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING
525 | ACPI_BTYPE_PACKAGE, &obj_desc);
526 if (ACPI_FAILURE(status)) {
527 return_ACPI_STATUS(status);
528 }
529
530 /* Get the number of _CIDs returned */
531
532 count = 1;
533 if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_PACKAGE) {
534 count = obj_desc->package.count;
535 }
536
537 /* Allocate a worst-case buffer for the _CIDs */
538
539 size = (((count - 1) * sizeof(struct acpi_compatible_id)) +
540 sizeof(struct acpi_compatible_id_list));
541
542 cid_list = ACPI_ALLOCATE_ZEROED((acpi_size) size);
543 if (!cid_list) {
544 return_ACPI_STATUS(AE_NO_MEMORY);
545 }
546
547 /* Init CID list */
548
549 cid_list->count = count;
550 cid_list->size = size;
551
552 /*
553 * A _CID can return either a single compatible ID or a package of
554 * compatible IDs. Each compatible ID can be one of the following:
555 * 1) Integer (32 bit compressed EISA ID) or
556 * 2) String (PCI ID format, e.g. "PCI\VEN_vvvv&DEV_dddd&SUBSYS_ssssssss")
557 */
558
559 /* The _CID object can be either a single CID or a package (list) of CIDs */
560
561 if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_PACKAGE) {
562
563 /* Translate each package element */
564
565 for (i = 0; i < count; i++) {
566 status =
567 acpi_ut_translate_one_cid(obj_desc->package.
568 elements[i],
569 &cid_list->id[i]);
570 if (ACPI_FAILURE(status)) {
571 break;
572 }
573 }
574 } else {
575 /* Only one CID, translate to a string */
576
577 status = acpi_ut_translate_one_cid(obj_desc, cid_list->id);
578 }
579
580 /* Cleanup on error */
581
582 if (ACPI_FAILURE(status)) {
583 ACPI_FREE(cid_list);
584 } else {
585 *return_cid_list = cid_list;
586 }
587
588 /* On exit, we must delete the _CID return object */
589
590 acpi_ut_remove_reference(obj_desc);
591 return_ACPI_STATUS(status);
592}
593
594/*******************************************************************************
595 *
596 * FUNCTION: acpi_ut_execute_UID
597 *
598 * PARAMETERS: device_node - Node for the device
599 * Uid - Where the UID is returned
600 *
601 * RETURN: Status
602 *
603 * DESCRIPTION: Executes the _UID control method that returns the hardware
604 * ID of the device.
605 *
606 * NOTE: Internal function, no parameter validation
607 *
608 ******************************************************************************/
609
610acpi_status
611acpi_ut_execute_UID(struct acpi_namespace_node *device_node,
612 struct acpica_device_id *uid)
613{
614 union acpi_operand_object *obj_desc;
615 acpi_status status;
616
617 ACPI_FUNCTION_TRACE(ut_execute_UID);
618
619 status = acpi_ut_evaluate_object(device_node, METHOD_NAME__UID,
620 ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING,
621 &obj_desc);
622 if (ACPI_FAILURE(status)) {
623 return_ACPI_STATUS(status);
624 }
625
626 if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {
627
628 /* Convert the Numeric UID to string */
629
630 acpi_ex_unsigned_integer_to_string(obj_desc->integer.value,
631 uid->value);
632 } else {
633 /* Copy the String UID from the returned object */
634
635 acpi_ut_copy_id_string(uid->value, obj_desc->string.pointer,
636 sizeof(uid->value));
637 }
638
639 /* On exit, we must delete the return object */
640
641 acpi_ut_remove_reference(obj_desc);
642 return_ACPI_STATUS(status);
643}
644
645/*******************************************************************************
646 *
647 * FUNCTION: acpi_ut_execute_STA
648 *
649 * PARAMETERS: device_node - Node for the device
650 * Flags - Where the status flags are returned
651 *
652 * RETURN: Status
653 *
654 * DESCRIPTION: Executes _STA for selected device and stores results in
655 * *Flags.
656 *
657 * NOTE: Internal function, no parameter validation
658 *
659 ******************************************************************************/
660
661acpi_status
662acpi_ut_execute_STA(struct acpi_namespace_node *device_node, u32 * flags)
663{
664 union acpi_operand_object *obj_desc;
665 acpi_status status;
666
667 ACPI_FUNCTION_TRACE(ut_execute_STA);
668
669 status = acpi_ut_evaluate_object(device_node, METHOD_NAME__STA,
670 ACPI_BTYPE_INTEGER, &obj_desc);
671 if (ACPI_FAILURE(status)) {
672 if (AE_NOT_FOUND == status) {
673 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
674 "_STA on %4.4s was not found, assuming device is present\n",
675 acpi_ut_get_node_name(device_node)));
676
677 *flags = ACPI_UINT32_MAX;
678 status = AE_OK;
679 }
680
681 return_ACPI_STATUS(status);
682 }
683
684 /* Extract the status flags */
685
686 *flags = (u32) obj_desc->integer.value;
687
688 /* On exit, we must delete the return object */
689
690 acpi_ut_remove_reference(obj_desc);
691 return_ACPI_STATUS(status);
692}
693
694/*******************************************************************************
695 *
696 * FUNCTION: acpi_ut_execute_Sxds
697 *
698 * PARAMETERS: device_node - Node for the device
699 * Flags - Where the status flags are returned
700 *
701 * RETURN: Status
702 *
703 * DESCRIPTION: Executes _STA for selected device and stores results in
704 * *Flags.
705 *
706 * NOTE: Internal function, no parameter validation
707 *
708 ******************************************************************************/
709
710acpi_status
711acpi_ut_execute_sxds(struct acpi_namespace_node *device_node, u8 * highest)
712{
713 union acpi_operand_object *obj_desc;
714 acpi_status status;
715 u32 i;
716
717 ACPI_FUNCTION_TRACE(ut_execute_sxds);
718
719 for (i = 0; i < 4; i++) {
720 highest[i] = 0xFF;
721 status = acpi_ut_evaluate_object(device_node,
722 ACPI_CAST_PTR(char,
723 acpi_gbl_highest_dstate_names
724 [i]),
725 ACPI_BTYPE_INTEGER, &obj_desc);
726 if (ACPI_FAILURE(status)) {
727 if (status != AE_NOT_FOUND) {
728 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
729 "%s on Device %4.4s, %s\n",
730 ACPI_CAST_PTR(char,
731 acpi_gbl_highest_dstate_names
732 [i]),
733 acpi_ut_get_node_name
734 (device_node),
735 acpi_format_exception
736 (status)));
737
738 return_ACPI_STATUS(status);
739 }
740 } else {
741 /* Extract the Dstate value */
742
743 highest[i] = (u8) obj_desc->integer.value;
744
745 /* Delete the return object */
746
747 acpi_ut_remove_reference(obj_desc);
748 }
749 }
750
751 return_ACPI_STATUS(AE_OK);
752}
diff --git a/drivers/acpi/acpica/utglobal.c b/drivers/acpi/acpica/utglobal.c
new file mode 100644
index 00000000000..3e28d8c4045
--- /dev/null
+++ b/drivers/acpi/acpica/utglobal.c
@@ -0,0 +1,823 @@
1/******************************************************************************
2 *
3 * Module Name: utglobal - Global variables for the ACPI subsystem
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#define DEFINE_ACPI_GLOBALS
45
46#include <acpi/acpi.h>
47#include <acpi/accommon.h>
48#include <acpi/acnamesp.h>
49
50#define _COMPONENT ACPI_UTILITIES
51ACPI_MODULE_NAME("utglobal")
52
53/*******************************************************************************
54 *
55 * Static global variable initialization.
56 *
57 ******************************************************************************/
58/*
59 * We want the debug switches statically initialized so they
60 * are already set when the debugger is entered.
61 */
62/* Debug switch - level and trace mask */
63u32 acpi_dbg_level = ACPI_DEBUG_DEFAULT;
64
65/* Debug switch - layer (component) mask */
66
67u32 acpi_dbg_layer = 0;
68u32 acpi_gbl_nesting_level = 0;
69
70/* Debugger globals */
71
72u8 acpi_gbl_db_terminate_threads = FALSE;
73u8 acpi_gbl_abort_method = FALSE;
74u8 acpi_gbl_method_executing = FALSE;
75
76/* System flags */
77
78u32 acpi_gbl_startup_flags = 0;
79
80/* System starts uninitialized */
81
82u8 acpi_gbl_shutdown = TRUE;
83
84const char *acpi_gbl_sleep_state_names[ACPI_S_STATE_COUNT] = {
85 "\\_S0_",
86 "\\_S1_",
87 "\\_S2_",
88 "\\_S3_",
89 "\\_S4_",
90 "\\_S5_"
91};
92
93const char *acpi_gbl_highest_dstate_names[4] = {
94 "_S1D",
95 "_S2D",
96 "_S3D",
97 "_S4D"
98};
99
100/*******************************************************************************
101 *
102 * FUNCTION: acpi_format_exception
103 *
104 * PARAMETERS: Status - The acpi_status code to be formatted
105 *
106 * RETURN: A string containing the exception text. A valid pointer is
107 * always returned.
108 *
109 * DESCRIPTION: This function translates an ACPI exception into an ASCII string
110 * It is here instead of utxface.c so it is always present.
111 *
112 ******************************************************************************/
113
114const char *acpi_format_exception(acpi_status status)
115{
116 const char *exception = NULL;
117
118 ACPI_FUNCTION_ENTRY();
119
120 exception = acpi_ut_validate_exception(status);
121 if (!exception) {
122
123 /* Exception code was not recognized */
124
125 ACPI_ERROR((AE_INFO,
126 "Unknown exception code: 0x%8.8X", status));
127
128 exception = "UNKNOWN_STATUS_CODE";
129 dump_stack();
130 }
131
132 return (ACPI_CAST_PTR(const char, exception));
133}
134
135ACPI_EXPORT_SYMBOL(acpi_format_exception)
136
137/*******************************************************************************
138 *
139 * Namespace globals
140 *
141 ******************************************************************************/
142/*
143 * Predefined ACPI Names (Built-in to the Interpreter)
144 *
145 * NOTES:
146 * 1) _SB_ is defined to be a device to allow \_SB_._INI to be run
147 * during the initialization sequence.
148 * 2) _TZ_ is defined to be a thermal zone in order to allow ASL code to
149 * perform a Notify() operation on it.
150 */
151const struct acpi_predefined_names acpi_gbl_pre_defined_names[] = {
152 {"_GPE", ACPI_TYPE_LOCAL_SCOPE, NULL},
153 {"_PR_", ACPI_TYPE_LOCAL_SCOPE, NULL},
154 {"_SB_", ACPI_TYPE_DEVICE, NULL},
155 {"_SI_", ACPI_TYPE_LOCAL_SCOPE, NULL},
156 {"_TZ_", ACPI_TYPE_THERMAL, NULL},
157 {"_REV", ACPI_TYPE_INTEGER, (char *)ACPI_CA_SUPPORT_LEVEL},
158 {"_OS_", ACPI_TYPE_STRING, ACPI_OS_NAME},
159 {"_GL_", ACPI_TYPE_MUTEX, (char *)1},
160
161#if !defined (ACPI_NO_METHOD_EXECUTION) || defined (ACPI_CONSTANT_EVAL_ONLY)
162 {"_OSI", ACPI_TYPE_METHOD, (char *)1},
163#endif
164
165 /* Table terminator */
166
167 {NULL, ACPI_TYPE_ANY, NULL}
168};
169
170/*
171 * Properties of the ACPI Object Types, both internal and external.
172 * The table is indexed by values of acpi_object_type
173 */
174const u8 acpi_gbl_ns_properties[] = {
175 ACPI_NS_NORMAL, /* 00 Any */
176 ACPI_NS_NORMAL, /* 01 Number */
177 ACPI_NS_NORMAL, /* 02 String */
178 ACPI_NS_NORMAL, /* 03 Buffer */
179 ACPI_NS_NORMAL, /* 04 Package */
180 ACPI_NS_NORMAL, /* 05 field_unit */
181 ACPI_NS_NEWSCOPE, /* 06 Device */
182 ACPI_NS_NORMAL, /* 07 Event */
183 ACPI_NS_NEWSCOPE, /* 08 Method */
184 ACPI_NS_NORMAL, /* 09 Mutex */
185 ACPI_NS_NORMAL, /* 10 Region */
186 ACPI_NS_NEWSCOPE, /* 11 Power */
187 ACPI_NS_NEWSCOPE, /* 12 Processor */
188 ACPI_NS_NEWSCOPE, /* 13 Thermal */
189 ACPI_NS_NORMAL, /* 14 buffer_field */
190 ACPI_NS_NORMAL, /* 15 ddb_handle */
191 ACPI_NS_NORMAL, /* 16 Debug Object */
192 ACPI_NS_NORMAL, /* 17 def_field */
193 ACPI_NS_NORMAL, /* 18 bank_field */
194 ACPI_NS_NORMAL, /* 19 index_field */
195 ACPI_NS_NORMAL, /* 20 Reference */
196 ACPI_NS_NORMAL, /* 21 Alias */
197 ACPI_NS_NORMAL, /* 22 method_alias */
198 ACPI_NS_NORMAL, /* 23 Notify */
199 ACPI_NS_NORMAL, /* 24 Address Handler */
200 ACPI_NS_NEWSCOPE | ACPI_NS_LOCAL, /* 25 Resource Desc */
201 ACPI_NS_NEWSCOPE | ACPI_NS_LOCAL, /* 26 Resource Field */
202 ACPI_NS_NEWSCOPE, /* 27 Scope */
203 ACPI_NS_NORMAL, /* 28 Extra */
204 ACPI_NS_NORMAL, /* 29 Data */
205 ACPI_NS_NORMAL /* 30 Invalid */
206};
207
208/* Hex to ASCII conversion table */
209
210static const char acpi_gbl_hex_to_ascii[] = {
211 '0', '1', '2', '3', '4', '5', '6', '7',
212 '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
213};
214
215/*******************************************************************************
216 *
217 * FUNCTION: acpi_ut_hex_to_ascii_char
218 *
219 * PARAMETERS: Integer - Contains the hex digit
220 * Position - bit position of the digit within the
221 * integer (multiple of 4)
222 *
223 * RETURN: The converted Ascii character
224 *
225 * DESCRIPTION: Convert a hex digit to an Ascii character
226 *
227 ******************************************************************************/
228
229char acpi_ut_hex_to_ascii_char(acpi_integer integer, u32 position)
230{
231
232 return (acpi_gbl_hex_to_ascii[(integer >> position) & 0xF]);
233}
234
235/******************************************************************************
236 *
237 * Event and Hardware globals
238 *
239 ******************************************************************************/
240
241struct acpi_bit_register_info acpi_gbl_bit_register_info[ACPI_NUM_BITREG] = {
242 /* Name Parent Register Register Bit Position Register Bit Mask */
243
244 /* ACPI_BITREG_TIMER_STATUS */ {ACPI_REGISTER_PM1_STATUS,
245 ACPI_BITPOSITION_TIMER_STATUS,
246 ACPI_BITMASK_TIMER_STATUS},
247 /* ACPI_BITREG_BUS_MASTER_STATUS */ {ACPI_REGISTER_PM1_STATUS,
248 ACPI_BITPOSITION_BUS_MASTER_STATUS,
249 ACPI_BITMASK_BUS_MASTER_STATUS},
250 /* ACPI_BITREG_GLOBAL_LOCK_STATUS */ {ACPI_REGISTER_PM1_STATUS,
251 ACPI_BITPOSITION_GLOBAL_LOCK_STATUS,
252 ACPI_BITMASK_GLOBAL_LOCK_STATUS},
253 /* ACPI_BITREG_POWER_BUTTON_STATUS */ {ACPI_REGISTER_PM1_STATUS,
254 ACPI_BITPOSITION_POWER_BUTTON_STATUS,
255 ACPI_BITMASK_POWER_BUTTON_STATUS},
256 /* ACPI_BITREG_SLEEP_BUTTON_STATUS */ {ACPI_REGISTER_PM1_STATUS,
257 ACPI_BITPOSITION_SLEEP_BUTTON_STATUS,
258 ACPI_BITMASK_SLEEP_BUTTON_STATUS},
259 /* ACPI_BITREG_RT_CLOCK_STATUS */ {ACPI_REGISTER_PM1_STATUS,
260 ACPI_BITPOSITION_RT_CLOCK_STATUS,
261 ACPI_BITMASK_RT_CLOCK_STATUS},
262 /* ACPI_BITREG_WAKE_STATUS */ {ACPI_REGISTER_PM1_STATUS,
263 ACPI_BITPOSITION_WAKE_STATUS,
264 ACPI_BITMASK_WAKE_STATUS},
265 /* ACPI_BITREG_PCIEXP_WAKE_STATUS */ {ACPI_REGISTER_PM1_STATUS,
266 ACPI_BITPOSITION_PCIEXP_WAKE_STATUS,
267 ACPI_BITMASK_PCIEXP_WAKE_STATUS},
268
269 /* ACPI_BITREG_TIMER_ENABLE */ {ACPI_REGISTER_PM1_ENABLE,
270 ACPI_BITPOSITION_TIMER_ENABLE,
271 ACPI_BITMASK_TIMER_ENABLE},
272 /* ACPI_BITREG_GLOBAL_LOCK_ENABLE */ {ACPI_REGISTER_PM1_ENABLE,
273 ACPI_BITPOSITION_GLOBAL_LOCK_ENABLE,
274 ACPI_BITMASK_GLOBAL_LOCK_ENABLE},
275 /* ACPI_BITREG_POWER_BUTTON_ENABLE */ {ACPI_REGISTER_PM1_ENABLE,
276 ACPI_BITPOSITION_POWER_BUTTON_ENABLE,
277 ACPI_BITMASK_POWER_BUTTON_ENABLE},
278 /* ACPI_BITREG_SLEEP_BUTTON_ENABLE */ {ACPI_REGISTER_PM1_ENABLE,
279 ACPI_BITPOSITION_SLEEP_BUTTON_ENABLE,
280 ACPI_BITMASK_SLEEP_BUTTON_ENABLE},
281 /* ACPI_BITREG_RT_CLOCK_ENABLE */ {ACPI_REGISTER_PM1_ENABLE,
282 ACPI_BITPOSITION_RT_CLOCK_ENABLE,
283 ACPI_BITMASK_RT_CLOCK_ENABLE},
284 /* ACPI_BITREG_PCIEXP_WAKE_DISABLE */ {ACPI_REGISTER_PM1_ENABLE,
285 ACPI_BITPOSITION_PCIEXP_WAKE_DISABLE,
286 ACPI_BITMASK_PCIEXP_WAKE_DISABLE},
287
288 /* ACPI_BITREG_SCI_ENABLE */ {ACPI_REGISTER_PM1_CONTROL,
289 ACPI_BITPOSITION_SCI_ENABLE,
290 ACPI_BITMASK_SCI_ENABLE},
291 /* ACPI_BITREG_BUS_MASTER_RLD */ {ACPI_REGISTER_PM1_CONTROL,
292 ACPI_BITPOSITION_BUS_MASTER_RLD,
293 ACPI_BITMASK_BUS_MASTER_RLD},
294 /* ACPI_BITREG_GLOBAL_LOCK_RELEASE */ {ACPI_REGISTER_PM1_CONTROL,
295 ACPI_BITPOSITION_GLOBAL_LOCK_RELEASE,
296 ACPI_BITMASK_GLOBAL_LOCK_RELEASE},
297 /* ACPI_BITREG_SLEEP_TYPE_A */ {ACPI_REGISTER_PM1_CONTROL,
298 ACPI_BITPOSITION_SLEEP_TYPE_X,
299 ACPI_BITMASK_SLEEP_TYPE_X},
300 /* ACPI_BITREG_SLEEP_TYPE_B */ {ACPI_REGISTER_PM1_CONTROL,
301 ACPI_BITPOSITION_SLEEP_TYPE_X,
302 ACPI_BITMASK_SLEEP_TYPE_X},
303 /* ACPI_BITREG_SLEEP_ENABLE */ {ACPI_REGISTER_PM1_CONTROL,
304 ACPI_BITPOSITION_SLEEP_ENABLE,
305 ACPI_BITMASK_SLEEP_ENABLE},
306
307 /* ACPI_BITREG_ARB_DIS */ {ACPI_REGISTER_PM2_CONTROL,
308 ACPI_BITPOSITION_ARB_DISABLE,
309 ACPI_BITMASK_ARB_DISABLE}
310};
311
312struct acpi_fixed_event_info acpi_gbl_fixed_event_info[ACPI_NUM_FIXED_EVENTS] = {
313 /* ACPI_EVENT_PMTIMER */ {ACPI_BITREG_TIMER_STATUS,
314 ACPI_BITREG_TIMER_ENABLE,
315 ACPI_BITMASK_TIMER_STATUS,
316 ACPI_BITMASK_TIMER_ENABLE},
317 /* ACPI_EVENT_GLOBAL */ {ACPI_BITREG_GLOBAL_LOCK_STATUS,
318 ACPI_BITREG_GLOBAL_LOCK_ENABLE,
319 ACPI_BITMASK_GLOBAL_LOCK_STATUS,
320 ACPI_BITMASK_GLOBAL_LOCK_ENABLE},
321 /* ACPI_EVENT_POWER_BUTTON */ {ACPI_BITREG_POWER_BUTTON_STATUS,
322 ACPI_BITREG_POWER_BUTTON_ENABLE,
323 ACPI_BITMASK_POWER_BUTTON_STATUS,
324 ACPI_BITMASK_POWER_BUTTON_ENABLE},
325 /* ACPI_EVENT_SLEEP_BUTTON */ {ACPI_BITREG_SLEEP_BUTTON_STATUS,
326 ACPI_BITREG_SLEEP_BUTTON_ENABLE,
327 ACPI_BITMASK_SLEEP_BUTTON_STATUS,
328 ACPI_BITMASK_SLEEP_BUTTON_ENABLE},
329 /* ACPI_EVENT_RTC */ {ACPI_BITREG_RT_CLOCK_STATUS,
330 ACPI_BITREG_RT_CLOCK_ENABLE,
331 ACPI_BITMASK_RT_CLOCK_STATUS,
332 ACPI_BITMASK_RT_CLOCK_ENABLE},
333};
334
335/*******************************************************************************
336 *
337 * FUNCTION: acpi_ut_get_region_name
338 *
339 * PARAMETERS: None.
340 *
341 * RETURN: Status
342 *
343 * DESCRIPTION: Translate a Space ID into a name string (Debug only)
344 *
345 ******************************************************************************/
346
347/* Region type decoding */
348
349const char *acpi_gbl_region_types[ACPI_NUM_PREDEFINED_REGIONS] = {
350 "SystemMemory",
351 "SystemIO",
352 "PCI_Config",
353 "EmbeddedControl",
354 "SMBus",
355 "SystemCMOS",
356 "PCIBARTarget",
357 "DataTable"
358};
359
360char *acpi_ut_get_region_name(u8 space_id)
361{
362
363 if (space_id >= ACPI_USER_REGION_BEGIN) {
364 return ("UserDefinedRegion");
365 } else if (space_id >= ACPI_NUM_PREDEFINED_REGIONS) {
366 return ("InvalidSpaceId");
367 }
368
369 return (ACPI_CAST_PTR(char, acpi_gbl_region_types[space_id]));
370}
371
372/*******************************************************************************
373 *
374 * FUNCTION: acpi_ut_get_event_name
375 *
376 * PARAMETERS: None.
377 *
378 * RETURN: Status
379 *
380 * DESCRIPTION: Translate a Event ID into a name string (Debug only)
381 *
382 ******************************************************************************/
383
384/* Event type decoding */
385
386static const char *acpi_gbl_event_types[ACPI_NUM_FIXED_EVENTS] = {
387 "PM_Timer",
388 "GlobalLock",
389 "PowerButton",
390 "SleepButton",
391 "RealTimeClock",
392};
393
394char *acpi_ut_get_event_name(u32 event_id)
395{
396
397 if (event_id > ACPI_EVENT_MAX) {
398 return ("InvalidEventID");
399 }
400
401 return (ACPI_CAST_PTR(char, acpi_gbl_event_types[event_id]));
402}
403
404/*******************************************************************************
405 *
406 * FUNCTION: acpi_ut_get_type_name
407 *
408 * PARAMETERS: None.
409 *
410 * RETURN: Status
411 *
412 * DESCRIPTION: Translate a Type ID into a name string (Debug only)
413 *
414 ******************************************************************************/
415
416/*
417 * Elements of acpi_gbl_ns_type_names below must match
418 * one-to-one with values of acpi_object_type
419 *
420 * The type ACPI_TYPE_ANY (Untyped) is used as a "don't care" when searching;
421 * when stored in a table it really means that we have thus far seen no
422 * evidence to indicate what type is actually going to be stored for this entry.
423 */
424static const char acpi_gbl_bad_type[] = "UNDEFINED";
425
426/* Printable names of the ACPI object types */
427
428static const char *acpi_gbl_ns_type_names[] = {
429 /* 00 */ "Untyped",
430 /* 01 */ "Integer",
431 /* 02 */ "String",
432 /* 03 */ "Buffer",
433 /* 04 */ "Package",
434 /* 05 */ "FieldUnit",
435 /* 06 */ "Device",
436 /* 07 */ "Event",
437 /* 08 */ "Method",
438 /* 09 */ "Mutex",
439 /* 10 */ "Region",
440 /* 11 */ "Power",
441 /* 12 */ "Processor",
442 /* 13 */ "Thermal",
443 /* 14 */ "BufferField",
444 /* 15 */ "DdbHandle",
445 /* 16 */ "DebugObject",
446 /* 17 */ "RegionField",
447 /* 18 */ "BankField",
448 /* 19 */ "IndexField",
449 /* 20 */ "Reference",
450 /* 21 */ "Alias",
451 /* 22 */ "MethodAlias",
452 /* 23 */ "Notify",
453 /* 24 */ "AddrHandler",
454 /* 25 */ "ResourceDesc",
455 /* 26 */ "ResourceFld",
456 /* 27 */ "Scope",
457 /* 28 */ "Extra",
458 /* 29 */ "Data",
459 /* 30 */ "Invalid"
460};
461
462char *acpi_ut_get_type_name(acpi_object_type type)
463{
464
465 if (type > ACPI_TYPE_INVALID) {
466 return (ACPI_CAST_PTR(char, acpi_gbl_bad_type));
467 }
468
469 return (ACPI_CAST_PTR(char, acpi_gbl_ns_type_names[type]));
470}
471
472char *acpi_ut_get_object_type_name(union acpi_operand_object *obj_desc)
473{
474
475 if (!obj_desc) {
476 return ("[NULL Object Descriptor]");
477 }
478
479 return (acpi_ut_get_type_name(ACPI_GET_OBJECT_TYPE(obj_desc)));
480}
481
482/*******************************************************************************
483 *
484 * FUNCTION: acpi_ut_get_node_name
485 *
486 * PARAMETERS: Object - A namespace node
487 *
488 * RETURN: Pointer to a string
489 *
490 * DESCRIPTION: Validate the node and return the node's ACPI name.
491 *
492 ******************************************************************************/
493
494char *acpi_ut_get_node_name(void *object)
495{
496 struct acpi_namespace_node *node = (struct acpi_namespace_node *)object;
497
498 /* Must return a string of exactly 4 characters == ACPI_NAME_SIZE */
499
500 if (!object) {
501 return ("NULL");
502 }
503
504 /* Check for Root node */
505
506 if ((object == ACPI_ROOT_OBJECT) || (object == acpi_gbl_root_node)) {
507 return ("\"\\\" ");
508 }
509
510 /* Descriptor must be a namespace node */
511
512 if (ACPI_GET_DESCRIPTOR_TYPE(node) != ACPI_DESC_TYPE_NAMED) {
513 return ("####");
514 }
515
516 /* Name must be a valid ACPI name */
517
518 if (!acpi_ut_valid_acpi_name(node->name.integer)) {
519 node->name.integer = acpi_ut_repair_name(node->name.ascii);
520 }
521
522 /* Return the name */
523
524 return (node->name.ascii);
525}
526
527/*******************************************************************************
528 *
529 * FUNCTION: acpi_ut_get_descriptor_name
530 *
531 * PARAMETERS: Object - An ACPI object
532 *
533 * RETURN: Pointer to a string
534 *
535 * DESCRIPTION: Validate object and return the descriptor type
536 *
537 ******************************************************************************/
538
539/* Printable names of object descriptor types */
540
541static const char *acpi_gbl_desc_type_names[] = {
542 /* 00 */ "Invalid",
543 /* 01 */ "Cached",
544 /* 02 */ "State-Generic",
545 /* 03 */ "State-Update",
546 /* 04 */ "State-Package",
547 /* 05 */ "State-Control",
548 /* 06 */ "State-RootParseScope",
549 /* 07 */ "State-ParseScope",
550 /* 08 */ "State-WalkScope",
551 /* 09 */ "State-Result",
552 /* 10 */ "State-Notify",
553 /* 11 */ "State-Thread",
554 /* 12 */ "Walk",
555 /* 13 */ "Parser",
556 /* 14 */ "Operand",
557 /* 15 */ "Node"
558};
559
560char *acpi_ut_get_descriptor_name(void *object)
561{
562
563 if (!object) {
564 return ("NULL OBJECT");
565 }
566
567 if (ACPI_GET_DESCRIPTOR_TYPE(object) > ACPI_DESC_TYPE_MAX) {
568 return (ACPI_CAST_PTR(char, acpi_gbl_bad_type));
569 }
570
571 return (ACPI_CAST_PTR(char,
572 acpi_gbl_desc_type_names[ACPI_GET_DESCRIPTOR_TYPE
573 (object)]));
574
575}
576
577/*******************************************************************************
578 *
579 * FUNCTION: acpi_ut_get_reference_name
580 *
581 * PARAMETERS: Object - An ACPI reference object
582 *
583 * RETURN: Pointer to a string
584 *
585 * DESCRIPTION: Decode a reference object sub-type to a string.
586 *
587 ******************************************************************************/
588
589/* Printable names of reference object sub-types */
590
591static const char *acpi_gbl_ref_class_names[] = {
592 /* 00 */ "Local",
593 /* 01 */ "Argument",
594 /* 02 */ "RefOf",
595 /* 03 */ "Index",
596 /* 04 */ "DdbHandle",
597 /* 05 */ "Named Object",
598 /* 06 */ "Debug"
599};
600
601const char *acpi_ut_get_reference_name(union acpi_operand_object *object)
602{
603 if (!object)
604 return "NULL Object";
605
606 if (ACPI_GET_DESCRIPTOR_TYPE(object) != ACPI_DESC_TYPE_OPERAND)
607 return "Not an Operand object";
608
609 if (object->common.type != ACPI_TYPE_LOCAL_REFERENCE)
610 return "Not a Reference object";
611
612 if (object->reference.class > ACPI_REFCLASS_MAX)
613 return "Unknown Reference class";
614
615 return acpi_gbl_ref_class_names[object->reference.class];
616}
617
618#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
619/*
620 * Strings and procedures used for debug only
621 */
622
623/*******************************************************************************
624 *
625 * FUNCTION: acpi_ut_get_mutex_name
626 *
627 * PARAMETERS: mutex_id - The predefined ID for this mutex.
628 *
629 * RETURN: String containing the name of the mutex. Always returns a valid
630 * pointer.
631 *
632 * DESCRIPTION: Translate a mutex ID into a name string (Debug only)
633 *
634 ******************************************************************************/
635
636char *acpi_ut_get_mutex_name(u32 mutex_id)
637{
638
639 if (mutex_id > ACPI_MAX_MUTEX) {
640 return ("Invalid Mutex ID");
641 }
642
643 return (acpi_gbl_mutex_names[mutex_id]);
644}
645
646/*******************************************************************************
647 *
648 * FUNCTION: acpi_ut_get_notify_name
649 *
650 * PARAMETERS: notify_value - Value from the Notify() request
651 *
652 * RETURN: String corresponding to the Notify Value.
653 *
654 * DESCRIPTION: Translate a Notify Value to a notify namestring.
655 *
656 ******************************************************************************/
657
658/* Names for Notify() values, used for debug output */
659
660static const char *acpi_gbl_notify_value_names[] = {
661 "Bus Check",
662 "Device Check",
663 "Device Wake",
664 "Eject Request",
665 "Device Check Light",
666 "Frequency Mismatch",
667 "Bus Mode Mismatch",
668 "Power Fault",
669 "Capabilities Check",
670 "Device PLD Check",
671 "Reserved",
672 "System Locality Update"
673};
674
675const char *acpi_ut_get_notify_name(u32 notify_value)
676{
677
678 if (notify_value <= ACPI_NOTIFY_MAX) {
679 return (acpi_gbl_notify_value_names[notify_value]);
680 } else if (notify_value <= ACPI_MAX_SYS_NOTIFY) {
681 return ("Reserved");
682 } else { /* Greater or equal to 0x80 */
683
684 return ("**Device Specific**");
685 }
686}
687#endif
688
689/*******************************************************************************
690 *
691 * FUNCTION: acpi_ut_valid_object_type
692 *
693 * PARAMETERS: Type - Object type to be validated
694 *
695 * RETURN: TRUE if valid object type, FALSE otherwise
696 *
697 * DESCRIPTION: Validate an object type
698 *
699 ******************************************************************************/
700
701u8 acpi_ut_valid_object_type(acpi_object_type type)
702{
703
704 if (type > ACPI_TYPE_LOCAL_MAX) {
705
706 /* Note: Assumes all TYPEs are contiguous (external/local) */
707
708 return (FALSE);
709 }
710
711 return (TRUE);
712}
713
714/*******************************************************************************
715 *
716 * FUNCTION: acpi_ut_init_globals
717 *
718 * PARAMETERS: None
719 *
720 * RETURN: Status
721 *
722 * DESCRIPTION: Init library globals. All globals that require specific
723 * initialization should be initialized here!
724 *
725 ******************************************************************************/
726
727acpi_status acpi_ut_init_globals(void)
728{
729 acpi_status status;
730 u32 i;
731
732 ACPI_FUNCTION_TRACE(ut_init_globals);
733
734 /* Create all memory caches */
735
736 status = acpi_ut_create_caches();
737 if (ACPI_FAILURE(status)) {
738 return_ACPI_STATUS(status);
739 }
740
741 /* Mutex locked flags */
742
743 for (i = 0; i < ACPI_NUM_MUTEX; i++) {
744 acpi_gbl_mutex_info[i].mutex = NULL;
745 acpi_gbl_mutex_info[i].thread_id = ACPI_MUTEX_NOT_ACQUIRED;
746 acpi_gbl_mutex_info[i].use_count = 0;
747 }
748
749 for (i = 0; i < ACPI_NUM_OWNERID_MASKS; i++) {
750 acpi_gbl_owner_id_mask[i] = 0;
751 }
752 acpi_gbl_owner_id_mask[ACPI_NUM_OWNERID_MASKS - 1] = 0x80000000; /* Last ID is never valid */
753
754 /* GPE support */
755
756 acpi_gbl_gpe_xrupt_list_head = NULL;
757 acpi_gbl_gpe_fadt_blocks[0] = NULL;
758 acpi_gbl_gpe_fadt_blocks[1] = NULL;
759 acpi_current_gpe_count = 0;
760
761 /* Global handlers */
762
763 acpi_gbl_system_notify.handler = NULL;
764 acpi_gbl_device_notify.handler = NULL;
765 acpi_gbl_exception_handler = NULL;
766 acpi_gbl_init_handler = NULL;
767 acpi_gbl_table_handler = NULL;
768
769 /* Global Lock support */
770
771 acpi_gbl_global_lock_semaphore = NULL;
772 acpi_gbl_global_lock_mutex = NULL;
773 acpi_gbl_global_lock_acquired = FALSE;
774 acpi_gbl_global_lock_handle = 0;
775 acpi_gbl_global_lock_present = FALSE;
776
777 /* Miscellaneous variables */
778
779 acpi_gbl_cm_single_step = FALSE;
780 acpi_gbl_db_terminate_threads = FALSE;
781 acpi_gbl_shutdown = FALSE;
782 acpi_gbl_ns_lookup_count = 0;
783 acpi_gbl_ps_find_count = 0;
784 acpi_gbl_acpi_hardware_present = TRUE;
785 acpi_gbl_last_owner_id_index = 0;
786 acpi_gbl_next_owner_id_offset = 0;
787 acpi_gbl_trace_method_name = 0;
788 acpi_gbl_trace_dbg_level = 0;
789 acpi_gbl_trace_dbg_layer = 0;
790 acpi_gbl_debugger_configuration = DEBUGGER_THREADING;
791 acpi_gbl_db_output_flags = ACPI_DB_CONSOLE_OUTPUT;
792
793 /* Hardware oriented */
794
795 acpi_gbl_events_initialized = FALSE;
796 acpi_gbl_system_awake_and_running = TRUE;
797
798 /* Namespace */
799
800 acpi_gbl_root_node = NULL;
801 acpi_gbl_root_node_struct.name.integer = ACPI_ROOT_NAME;
802 acpi_gbl_root_node_struct.descriptor_type = ACPI_DESC_TYPE_NAMED;
803 acpi_gbl_root_node_struct.type = ACPI_TYPE_DEVICE;
804 acpi_gbl_root_node_struct.child = NULL;
805 acpi_gbl_root_node_struct.peer = NULL;
806 acpi_gbl_root_node_struct.object = NULL;
807 acpi_gbl_root_node_struct.flags = ANOBJ_END_OF_PEER_LIST;
808
809#ifdef ACPI_DEBUG_OUTPUT
810 acpi_gbl_lowest_stack_pointer = ACPI_CAST_PTR(acpi_size, ACPI_SIZE_MAX);
811#endif
812
813#ifdef ACPI_DBG_TRACK_ALLOCATIONS
814 acpi_gbl_display_final_mem_stats = FALSE;
815#endif
816
817 return_ACPI_STATUS(AE_OK);
818}
819
820ACPI_EXPORT_SYMBOL(acpi_gbl_FADT)
821ACPI_EXPORT_SYMBOL(acpi_dbg_level)
822ACPI_EXPORT_SYMBOL(acpi_dbg_layer)
823ACPI_EXPORT_SYMBOL(acpi_current_gpe_count)
diff --git a/drivers/acpi/acpica/utinit.c b/drivers/acpi/acpica/utinit.c
new file mode 100644
index 00000000000..9316ec36a83
--- /dev/null
+++ b/drivers/acpi/acpica/utinit.c
@@ -0,0 +1,152 @@
1/******************************************************************************
2 *
3 * Module Name: utinit - Common ACPI subsystem initialization
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46#include <acpi/acnamesp.h>
47#include <acpi/acevents.h>
48#include <acpi/actables.h>
49
50#define _COMPONENT ACPI_UTILITIES
51ACPI_MODULE_NAME("utinit")
52
53/* Local prototypes */
54static void acpi_ut_terminate(void);
55
56/******************************************************************************
57 *
58 * FUNCTION: acpi_ut_terminate
59 *
60 * PARAMETERS: none
61 *
62 * RETURN: none
63 *
64 * DESCRIPTION: Free global memory
65 *
66 ******************************************************************************/
67
68static void acpi_ut_terminate(void)
69{
70 struct acpi_gpe_block_info *gpe_block;
71 struct acpi_gpe_block_info *next_gpe_block;
72 struct acpi_gpe_xrupt_info *gpe_xrupt_info;
73 struct acpi_gpe_xrupt_info *next_gpe_xrupt_info;
74
75 ACPI_FUNCTION_TRACE(ut_terminate);
76
77 /* Free global GPE blocks and related info structures */
78
79 gpe_xrupt_info = acpi_gbl_gpe_xrupt_list_head;
80 while (gpe_xrupt_info) {
81 gpe_block = gpe_xrupt_info->gpe_block_list_head;
82 while (gpe_block) {
83 next_gpe_block = gpe_block->next;
84 ACPI_FREE(gpe_block->event_info);
85 ACPI_FREE(gpe_block->register_info);
86 ACPI_FREE(gpe_block);
87
88 gpe_block = next_gpe_block;
89 }
90 next_gpe_xrupt_info = gpe_xrupt_info->next;
91 ACPI_FREE(gpe_xrupt_info);
92 gpe_xrupt_info = next_gpe_xrupt_info;
93 }
94
95 return_VOID;
96}
97
98/*******************************************************************************
99 *
100 * FUNCTION: acpi_ut_subsystem_shutdown
101 *
102 * PARAMETERS: none
103 *
104 * RETURN: none
105 *
106 * DESCRIPTION: Shutdown the various subsystems. Don't delete the mutex
107 * objects here -- because the AML debugger may be still running.
108 *
109 ******************************************************************************/
110
111void acpi_ut_subsystem_shutdown(void)
112{
113
114 ACPI_FUNCTION_TRACE(ut_subsystem_shutdown);
115
116 /* Just exit if subsystem is already shutdown */
117
118 if (acpi_gbl_shutdown) {
119 ACPI_ERROR((AE_INFO, "ACPI Subsystem is already terminated"));
120 return_VOID;
121 }
122
123 /* Subsystem appears active, go ahead and shut it down */
124
125 acpi_gbl_shutdown = TRUE;
126 acpi_gbl_startup_flags = 0;
127 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Shutting down ACPI Subsystem\n"));
128
129#ifndef ACPI_ASL_COMPILER
130
131 /* Close the acpi_event Handling */
132
133 acpi_ev_terminate();
134#endif
135
136 /* Close the Namespace */
137
138 acpi_ns_terminate();
139
140 /* Delete the ACPI tables */
141
142 acpi_tb_terminate();
143
144 /* Close the globals */
145
146 acpi_ut_terminate();
147
148 /* Purge the local caches */
149
150 (void)acpi_ut_delete_caches();
151 return_VOID;
152}
diff --git a/drivers/acpi/acpica/utmath.c b/drivers/acpi/acpica/utmath.c
new file mode 100644
index 00000000000..616d7b271c9
--- /dev/null
+++ b/drivers/acpi/acpica/utmath.c
@@ -0,0 +1,312 @@
1/*******************************************************************************
2 *
3 * Module Name: utmath - Integer math support routines
4 *
5 ******************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46
47#define _COMPONENT ACPI_UTILITIES
48ACPI_MODULE_NAME("utmath")
49
50/*
51 * Support for double-precision integer divide. This code is included here
52 * in order to support kernel environments where the double-precision math
53 * library is not available.
54 */
55#ifndef ACPI_USE_NATIVE_DIVIDE
56/*******************************************************************************
57 *
58 * FUNCTION: acpi_ut_short_divide
59 *
60 * PARAMETERS: Dividend - 64-bit dividend
61 * Divisor - 32-bit divisor
62 * out_quotient - Pointer to where the quotient is returned
63 * out_remainder - Pointer to where the remainder is returned
64 *
65 * RETURN: Status (Checks for divide-by-zero)
66 *
67 * DESCRIPTION: Perform a short (maximum 64 bits divided by 32 bits)
68 * divide and modulo. The result is a 64-bit quotient and a
69 * 32-bit remainder.
70 *
71 ******************************************************************************/
72acpi_status
73acpi_ut_short_divide(acpi_integer dividend,
74 u32 divisor,
75 acpi_integer * out_quotient, u32 * out_remainder)
76{
77 union uint64_overlay dividend_ovl;
78 union uint64_overlay quotient;
79 u32 remainder32;
80
81 ACPI_FUNCTION_TRACE(ut_short_divide);
82
83 /* Always check for a zero divisor */
84
85 if (divisor == 0) {
86 ACPI_ERROR((AE_INFO, "Divide by zero"));
87 return_ACPI_STATUS(AE_AML_DIVIDE_BY_ZERO);
88 }
89
90 dividend_ovl.full = dividend;
91
92 /*
93 * The quotient is 64 bits, the remainder is always 32 bits,
94 * and is generated by the second divide.
95 */
96 ACPI_DIV_64_BY_32(0, dividend_ovl.part.hi, divisor,
97 quotient.part.hi, remainder32);
98 ACPI_DIV_64_BY_32(remainder32, dividend_ovl.part.lo, divisor,
99 quotient.part.lo, remainder32);
100
101 /* Return only what was requested */
102
103 if (out_quotient) {
104 *out_quotient = quotient.full;
105 }
106 if (out_remainder) {
107 *out_remainder = remainder32;
108 }
109
110 return_ACPI_STATUS(AE_OK);
111}
112
113/*******************************************************************************
114 *
115 * FUNCTION: acpi_ut_divide
116 *
117 * PARAMETERS: in_dividend - Dividend
118 * in_divisor - Divisor
119 * out_quotient - Pointer to where the quotient is returned
120 * out_remainder - Pointer to where the remainder is returned
121 *
122 * RETURN: Status (Checks for divide-by-zero)
123 *
124 * DESCRIPTION: Perform a divide and modulo.
125 *
126 ******************************************************************************/
127
128acpi_status
129acpi_ut_divide(acpi_integer in_dividend,
130 acpi_integer in_divisor,
131 acpi_integer * out_quotient, acpi_integer * out_remainder)
132{
133 union uint64_overlay dividend;
134 union uint64_overlay divisor;
135 union uint64_overlay quotient;
136 union uint64_overlay remainder;
137 union uint64_overlay normalized_dividend;
138 union uint64_overlay normalized_divisor;
139 u32 partial1;
140 union uint64_overlay partial2;
141 union uint64_overlay partial3;
142
143 ACPI_FUNCTION_TRACE(ut_divide);
144
145 /* Always check for a zero divisor */
146
147 if (in_divisor == 0) {
148 ACPI_ERROR((AE_INFO, "Divide by zero"));
149 return_ACPI_STATUS(AE_AML_DIVIDE_BY_ZERO);
150 }
151
152 divisor.full = in_divisor;
153 dividend.full = in_dividend;
154 if (divisor.part.hi == 0) {
155 /*
156 * 1) Simplest case is where the divisor is 32 bits, we can
157 * just do two divides
158 */
159 remainder.part.hi = 0;
160
161 /*
162 * The quotient is 64 bits, the remainder is always 32 bits,
163 * and is generated by the second divide.
164 */
165 ACPI_DIV_64_BY_32(0, dividend.part.hi, divisor.part.lo,
166 quotient.part.hi, partial1);
167 ACPI_DIV_64_BY_32(partial1, dividend.part.lo, divisor.part.lo,
168 quotient.part.lo, remainder.part.lo);
169 }
170
171 else {
172 /*
173 * 2) The general case where the divisor is a full 64 bits
174 * is more difficult
175 */
176 quotient.part.hi = 0;
177 normalized_dividend = dividend;
178 normalized_divisor = divisor;
179
180 /* Normalize the operands (shift until the divisor is < 32 bits) */
181
182 do {
183 ACPI_SHIFT_RIGHT_64(normalized_divisor.part.hi,
184 normalized_divisor.part.lo);
185 ACPI_SHIFT_RIGHT_64(normalized_dividend.part.hi,
186 normalized_dividend.part.lo);
187
188 } while (normalized_divisor.part.hi != 0);
189
190 /* Partial divide */
191
192 ACPI_DIV_64_BY_32(normalized_dividend.part.hi,
193 normalized_dividend.part.lo,
194 normalized_divisor.part.lo,
195 quotient.part.lo, partial1);
196
197 /*
198 * The quotient is always 32 bits, and simply requires adjustment.
199 * The 64-bit remainder must be generated.
200 */
201 partial1 = quotient.part.lo * divisor.part.hi;
202 partial2.full =
203 (acpi_integer) quotient.part.lo * divisor.part.lo;
204 partial3.full = (acpi_integer) partial2.part.hi + partial1;
205
206 remainder.part.hi = partial3.part.lo;
207 remainder.part.lo = partial2.part.lo;
208
209 if (partial3.part.hi == 0) {
210 if (partial3.part.lo >= dividend.part.hi) {
211 if (partial3.part.lo == dividend.part.hi) {
212 if (partial2.part.lo > dividend.part.lo) {
213 quotient.part.lo--;
214 remainder.full -= divisor.full;
215 }
216 } else {
217 quotient.part.lo--;
218 remainder.full -= divisor.full;
219 }
220 }
221
222 remainder.full = remainder.full - dividend.full;
223 remainder.part.hi = (u32) - ((s32) remainder.part.hi);
224 remainder.part.lo = (u32) - ((s32) remainder.part.lo);
225
226 if (remainder.part.lo) {
227 remainder.part.hi--;
228 }
229 }
230 }
231
232 /* Return only what was requested */
233
234 if (out_quotient) {
235 *out_quotient = quotient.full;
236 }
237 if (out_remainder) {
238 *out_remainder = remainder.full;
239 }
240
241 return_ACPI_STATUS(AE_OK);
242}
243
244#else
245/*******************************************************************************
246 *
247 * FUNCTION: acpi_ut_short_divide, acpi_ut_divide
248 *
249 * PARAMETERS: See function headers above
250 *
251 * DESCRIPTION: Native versions of the ut_divide functions. Use these if either
252 * 1) The target is a 64-bit platform and therefore 64-bit
253 * integer math is supported directly by the machine.
254 * 2) The target is a 32-bit or 16-bit platform, and the
255 * double-precision integer math library is available to
256 * perform the divide.
257 *
258 ******************************************************************************/
259acpi_status
260acpi_ut_short_divide(acpi_integer in_dividend,
261 u32 divisor,
262 acpi_integer * out_quotient, u32 * out_remainder)
263{
264
265 ACPI_FUNCTION_TRACE(ut_short_divide);
266
267 /* Always check for a zero divisor */
268
269 if (divisor == 0) {
270 ACPI_ERROR((AE_INFO, "Divide by zero"));
271 return_ACPI_STATUS(AE_AML_DIVIDE_BY_ZERO);
272 }
273
274 /* Return only what was requested */
275
276 if (out_quotient) {
277 *out_quotient = in_dividend / divisor;
278 }
279 if (out_remainder) {
280 *out_remainder = (u32) (in_dividend % divisor);
281 }
282
283 return_ACPI_STATUS(AE_OK);
284}
285
286acpi_status
287acpi_ut_divide(acpi_integer in_dividend,
288 acpi_integer in_divisor,
289 acpi_integer * out_quotient, acpi_integer * out_remainder)
290{
291 ACPI_FUNCTION_TRACE(ut_divide);
292
293 /* Always check for a zero divisor */
294
295 if (in_divisor == 0) {
296 ACPI_ERROR((AE_INFO, "Divide by zero"));
297 return_ACPI_STATUS(AE_AML_DIVIDE_BY_ZERO);
298 }
299
300 /* Return only what was requested */
301
302 if (out_quotient) {
303 *out_quotient = in_dividend / in_divisor;
304 }
305 if (out_remainder) {
306 *out_remainder = in_dividend % in_divisor;
307 }
308
309 return_ACPI_STATUS(AE_OK);
310}
311
312#endif
diff --git a/drivers/acpi/acpica/utmisc.c b/drivers/acpi/acpica/utmisc.c
new file mode 100644
index 00000000000..8f8b407142e
--- /dev/null
+++ b/drivers/acpi/acpica/utmisc.c
@@ -0,0 +1,1093 @@
1/*******************************************************************************
2 *
3 * Module Name: utmisc - common utility procedures
4 *
5 ******************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <linux/module.h>
45
46#include <acpi/acpi.h>
47#include <acpi/accommon.h>
48#include <acpi/acnamesp.h>
49
50#define _COMPONENT ACPI_UTILITIES
51ACPI_MODULE_NAME("utmisc")
52
53/*******************************************************************************
54 *
55 * FUNCTION: acpi_ut_validate_exception
56 *
57 * PARAMETERS: Status - The acpi_status code to be formatted
58 *
59 * RETURN: A string containing the exception text. NULL if exception is
60 * not valid.
61 *
62 * DESCRIPTION: This function validates and translates an ACPI exception into
63 * an ASCII string.
64 *
65 ******************************************************************************/
66const char *acpi_ut_validate_exception(acpi_status status)
67{
68 u32 sub_status;
69 const char *exception = NULL;
70
71 ACPI_FUNCTION_ENTRY();
72
73 /*
74 * Status is composed of two parts, a "type" and an actual code
75 */
76 sub_status = (status & ~AE_CODE_MASK);
77
78 switch (status & AE_CODE_MASK) {
79 case AE_CODE_ENVIRONMENTAL:
80
81 if (sub_status <= AE_CODE_ENV_MAX) {
82 exception = acpi_gbl_exception_names_env[sub_status];
83 }
84 break;
85
86 case AE_CODE_PROGRAMMER:
87
88 if (sub_status <= AE_CODE_PGM_MAX) {
89 exception = acpi_gbl_exception_names_pgm[sub_status];
90 }
91 break;
92
93 case AE_CODE_ACPI_TABLES:
94
95 if (sub_status <= AE_CODE_TBL_MAX) {
96 exception = acpi_gbl_exception_names_tbl[sub_status];
97 }
98 break;
99
100 case AE_CODE_AML:
101
102 if (sub_status <= AE_CODE_AML_MAX) {
103 exception = acpi_gbl_exception_names_aml[sub_status];
104 }
105 break;
106
107 case AE_CODE_CONTROL:
108
109 if (sub_status <= AE_CODE_CTRL_MAX) {
110 exception = acpi_gbl_exception_names_ctrl[sub_status];
111 }
112 break;
113
114 default:
115 break;
116 }
117
118 return (ACPI_CAST_PTR(const char, exception));
119}
120
121/*******************************************************************************
122 *
123 * FUNCTION: acpi_ut_is_aml_table
124 *
125 * PARAMETERS: Table - An ACPI table
126 *
127 * RETURN: TRUE if table contains executable AML; FALSE otherwise
128 *
129 * DESCRIPTION: Check ACPI Signature for a table that contains AML code.
130 * Currently, these are DSDT,SSDT,PSDT. All other table types are
131 * data tables that do not contain AML code.
132 *
133 ******************************************************************************/
134
135u8 acpi_ut_is_aml_table(struct acpi_table_header *table)
136{
137
138 /* These are the only tables that contain executable AML */
139
140 if (ACPI_COMPARE_NAME(table->signature, ACPI_SIG_DSDT) ||
141 ACPI_COMPARE_NAME(table->signature, ACPI_SIG_PSDT) ||
142 ACPI_COMPARE_NAME(table->signature, ACPI_SIG_SSDT)) {
143 return (TRUE);
144 }
145
146 return (FALSE);
147}
148
149/*******************************************************************************
150 *
151 * FUNCTION: acpi_ut_allocate_owner_id
152 *
153 * PARAMETERS: owner_id - Where the new owner ID is returned
154 *
155 * RETURN: Status
156 *
157 * DESCRIPTION: Allocate a table or method owner ID. The owner ID is used to
158 * track objects created by the table or method, to be deleted
159 * when the method exits or the table is unloaded.
160 *
161 ******************************************************************************/
162
163acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id)
164{
165 u32 i;
166 u32 j;
167 u32 k;
168 acpi_status status;
169
170 ACPI_FUNCTION_TRACE(ut_allocate_owner_id);
171
172 /* Guard against multiple allocations of ID to the same location */
173
174 if (*owner_id) {
175 ACPI_ERROR((AE_INFO, "Owner ID [%2.2X] already exists",
176 *owner_id));
177 return_ACPI_STATUS(AE_ALREADY_EXISTS);
178 }
179
180 /* Mutex for the global ID mask */
181
182 status = acpi_ut_acquire_mutex(ACPI_MTX_CACHES);
183 if (ACPI_FAILURE(status)) {
184 return_ACPI_STATUS(status);
185 }
186
187 /*
188 * Find a free owner ID, cycle through all possible IDs on repeated
189 * allocations. (ACPI_NUM_OWNERID_MASKS + 1) because first index may have
190 * to be scanned twice.
191 */
192 for (i = 0, j = acpi_gbl_last_owner_id_index;
193 i < (ACPI_NUM_OWNERID_MASKS + 1); i++, j++) {
194 if (j >= ACPI_NUM_OWNERID_MASKS) {
195 j = 0; /* Wraparound to start of mask array */
196 }
197
198 for (k = acpi_gbl_next_owner_id_offset; k < 32; k++) {
199 if (acpi_gbl_owner_id_mask[j] == ACPI_UINT32_MAX) {
200
201 /* There are no free IDs in this mask */
202
203 break;
204 }
205
206 if (!(acpi_gbl_owner_id_mask[j] & (1 << k))) {
207 /*
208 * Found a free ID. The actual ID is the bit index plus one,
209 * making zero an invalid Owner ID. Save this as the last ID
210 * allocated and update the global ID mask.
211 */
212 acpi_gbl_owner_id_mask[j] |= (1 << k);
213
214 acpi_gbl_last_owner_id_index = (u8) j;
215 acpi_gbl_next_owner_id_offset = (u8) (k + 1);
216
217 /*
218 * Construct encoded ID from the index and bit position
219 *
220 * Note: Last [j].k (bit 255) is never used and is marked
221 * permanently allocated (prevents +1 overflow)
222 */
223 *owner_id =
224 (acpi_owner_id) ((k + 1) + ACPI_MUL_32(j));
225
226 ACPI_DEBUG_PRINT((ACPI_DB_VALUES,
227 "Allocated OwnerId: %2.2X\n",
228 (unsigned int)*owner_id));
229 goto exit;
230 }
231 }
232
233 acpi_gbl_next_owner_id_offset = 0;
234 }
235
236 /*
237 * All owner_ids have been allocated. This typically should
238 * not happen since the IDs are reused after deallocation. The IDs are
239 * allocated upon table load (one per table) and method execution, and
240 * they are released when a table is unloaded or a method completes
241 * execution.
242 *
243 * If this error happens, there may be very deep nesting of invoked control
244 * methods, or there may be a bug where the IDs are not released.
245 */
246 status = AE_OWNER_ID_LIMIT;
247 ACPI_ERROR((AE_INFO,
248 "Could not allocate new OwnerId (255 max), AE_OWNER_ID_LIMIT"));
249
250 exit:
251 (void)acpi_ut_release_mutex(ACPI_MTX_CACHES);
252 return_ACPI_STATUS(status);
253}
254
255/*******************************************************************************
256 *
257 * FUNCTION: acpi_ut_release_owner_id
258 *
259 * PARAMETERS: owner_id_ptr - Pointer to a previously allocated owner_iD
260 *
261 * RETURN: None. No error is returned because we are either exiting a
262 * control method or unloading a table. Either way, we would
263 * ignore any error anyway.
264 *
265 * DESCRIPTION: Release a table or method owner ID. Valid IDs are 1 - 255
266 *
267 ******************************************************************************/
268
269void acpi_ut_release_owner_id(acpi_owner_id * owner_id_ptr)
270{
271 acpi_owner_id owner_id = *owner_id_ptr;
272 acpi_status status;
273 u32 index;
274 u32 bit;
275
276 ACPI_FUNCTION_TRACE_U32(ut_release_owner_id, owner_id);
277
278 /* Always clear the input owner_id (zero is an invalid ID) */
279
280 *owner_id_ptr = 0;
281
282 /* Zero is not a valid owner_iD */
283
284 if (owner_id == 0) {
285 ACPI_ERROR((AE_INFO, "Invalid OwnerId: %2.2X", owner_id));
286 return_VOID;
287 }
288
289 /* Mutex for the global ID mask */
290
291 status = acpi_ut_acquire_mutex(ACPI_MTX_CACHES);
292 if (ACPI_FAILURE(status)) {
293 return_VOID;
294 }
295
296 /* Normalize the ID to zero */
297
298 owner_id--;
299
300 /* Decode ID to index/offset pair */
301
302 index = ACPI_DIV_32(owner_id);
303 bit = 1 << ACPI_MOD_32(owner_id);
304
305 /* Free the owner ID only if it is valid */
306
307 if (acpi_gbl_owner_id_mask[index] & bit) {
308 acpi_gbl_owner_id_mask[index] ^= bit;
309 } else {
310 ACPI_ERROR((AE_INFO,
311 "Release of non-allocated OwnerId: %2.2X",
312 owner_id + 1));
313 }
314
315 (void)acpi_ut_release_mutex(ACPI_MTX_CACHES);
316 return_VOID;
317}
318
319/*******************************************************************************
320 *
321 * FUNCTION: acpi_ut_strupr (strupr)
322 *
323 * PARAMETERS: src_string - The source string to convert
324 *
325 * RETURN: None
326 *
327 * DESCRIPTION: Convert string to uppercase
328 *
329 * NOTE: This is not a POSIX function, so it appears here, not in utclib.c
330 *
331 ******************************************************************************/
332
333void acpi_ut_strupr(char *src_string)
334{
335 char *string;
336
337 ACPI_FUNCTION_ENTRY();
338
339 if (!src_string) {
340 return;
341 }
342
343 /* Walk entire string, uppercasing the letters */
344
345 for (string = src_string; *string; string++) {
346 *string = (char)ACPI_TOUPPER(*string);
347 }
348
349 return;
350}
351
352/*******************************************************************************
353 *
354 * FUNCTION: acpi_ut_print_string
355 *
356 * PARAMETERS: String - Null terminated ASCII string
357 * max_length - Maximum output length
358 *
359 * RETURN: None
360 *
361 * DESCRIPTION: Dump an ASCII string with support for ACPI-defined escape
362 * sequences.
363 *
364 ******************************************************************************/
365
366void acpi_ut_print_string(char *string, u8 max_length)
367{
368 u32 i;
369
370 if (!string) {
371 acpi_os_printf("<\"NULL STRING PTR\">");
372 return;
373 }
374
375 acpi_os_printf("\"");
376 for (i = 0; string[i] && (i < max_length); i++) {
377
378 /* Escape sequences */
379
380 switch (string[i]) {
381 case 0x07:
382 acpi_os_printf("\\a"); /* BELL */
383 break;
384
385 case 0x08:
386 acpi_os_printf("\\b"); /* BACKSPACE */
387 break;
388
389 case 0x0C:
390 acpi_os_printf("\\f"); /* FORMFEED */
391 break;
392
393 case 0x0A:
394 acpi_os_printf("\\n"); /* LINEFEED */
395 break;
396
397 case 0x0D:
398 acpi_os_printf("\\r"); /* CARRIAGE RETURN */
399 break;
400
401 case 0x09:
402 acpi_os_printf("\\t"); /* HORIZONTAL TAB */
403 break;
404
405 case 0x0B:
406 acpi_os_printf("\\v"); /* VERTICAL TAB */
407 break;
408
409 case '\'': /* Single Quote */
410 case '\"': /* Double Quote */
411 case '\\': /* Backslash */
412 acpi_os_printf("\\%c", (int)string[i]);
413 break;
414
415 default:
416
417 /* Check for printable character or hex escape */
418
419 if (ACPI_IS_PRINT(string[i])) {
420 /* This is a normal character */
421
422 acpi_os_printf("%c", (int)string[i]);
423 } else {
424 /* All others will be Hex escapes */
425
426 acpi_os_printf("\\x%2.2X", (s32) string[i]);
427 }
428 break;
429 }
430 }
431 acpi_os_printf("\"");
432
433 if (i == max_length && string[i]) {
434 acpi_os_printf("...");
435 }
436}
437
438/*******************************************************************************
439 *
440 * FUNCTION: acpi_ut_dword_byte_swap
441 *
442 * PARAMETERS: Value - Value to be converted
443 *
444 * RETURN: u32 integer with bytes swapped
445 *
446 * DESCRIPTION: Convert a 32-bit value to big-endian (swap the bytes)
447 *
448 ******************************************************************************/
449
450u32 acpi_ut_dword_byte_swap(u32 value)
451{
452 union {
453 u32 value;
454 u8 bytes[4];
455 } out;
456 union {
457 u32 value;
458 u8 bytes[4];
459 } in;
460
461 ACPI_FUNCTION_ENTRY();
462
463 in.value = value;
464
465 out.bytes[0] = in.bytes[3];
466 out.bytes[1] = in.bytes[2];
467 out.bytes[2] = in.bytes[1];
468 out.bytes[3] = in.bytes[0];
469
470 return (out.value);
471}
472
473/*******************************************************************************
474 *
475 * FUNCTION: acpi_ut_set_integer_width
476 *
477 * PARAMETERS: Revision From DSDT header
478 *
479 * RETURN: None
480 *
481 * DESCRIPTION: Set the global integer bit width based upon the revision
482 * of the DSDT. For Revision 1 and 0, Integers are 32 bits.
483 * For Revision 2 and above, Integers are 64 bits. Yes, this
484 * makes a difference.
485 *
486 ******************************************************************************/
487
488void acpi_ut_set_integer_width(u8 revision)
489{
490
491 if (revision < 2) {
492
493 /* 32-bit case */
494
495 acpi_gbl_integer_bit_width = 32;
496 acpi_gbl_integer_nybble_width = 8;
497 acpi_gbl_integer_byte_width = 4;
498 } else {
499 /* 64-bit case (ACPI 2.0+) */
500
501 acpi_gbl_integer_bit_width = 64;
502 acpi_gbl_integer_nybble_width = 16;
503 acpi_gbl_integer_byte_width = 8;
504 }
505}
506
507#ifdef ACPI_DEBUG_OUTPUT
508/*******************************************************************************
509 *
510 * FUNCTION: acpi_ut_display_init_pathname
511 *
512 * PARAMETERS: Type - Object type of the node
513 * obj_handle - Handle whose pathname will be displayed
514 * Path - Additional path string to be appended.
515 * (NULL if no extra path)
516 *
517 * RETURN: acpi_status
518 *
519 * DESCRIPTION: Display full pathname of an object, DEBUG ONLY
520 *
521 ******************************************************************************/
522
523void
524acpi_ut_display_init_pathname(u8 type,
525 struct acpi_namespace_node *obj_handle,
526 char *path)
527{
528 acpi_status status;
529 struct acpi_buffer buffer;
530
531 ACPI_FUNCTION_ENTRY();
532
533 /* Only print the path if the appropriate debug level is enabled */
534
535 if (!(acpi_dbg_level & ACPI_LV_INIT_NAMES)) {
536 return;
537 }
538
539 /* Get the full pathname to the node */
540
541 buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
542 status = acpi_ns_handle_to_pathname(obj_handle, &buffer);
543 if (ACPI_FAILURE(status)) {
544 return;
545 }
546
547 /* Print what we're doing */
548
549 switch (type) {
550 case ACPI_TYPE_METHOD:
551 acpi_os_printf("Executing ");
552 break;
553
554 default:
555 acpi_os_printf("Initializing ");
556 break;
557 }
558
559 /* Print the object type and pathname */
560
561 acpi_os_printf("%-12s %s",
562 acpi_ut_get_type_name(type), (char *)buffer.pointer);
563
564 /* Extra path is used to append names like _STA, _INI, etc. */
565
566 if (path) {
567 acpi_os_printf(".%s", path);
568 }
569 acpi_os_printf("\n");
570
571 ACPI_FREE(buffer.pointer);
572}
573#endif
574
575/*******************************************************************************
576 *
577 * FUNCTION: acpi_ut_valid_acpi_char
578 *
579 * PARAMETERS: Char - The character to be examined
580 * Position - Byte position (0-3)
581 *
582 * RETURN: TRUE if the character is valid, FALSE otherwise
583 *
584 * DESCRIPTION: Check for a valid ACPI character. Must be one of:
585 * 1) Upper case alpha
586 * 2) numeric
587 * 3) underscore
588 *
589 * We allow a '!' as the last character because of the ASF! table
590 *
591 ******************************************************************************/
592
593u8 acpi_ut_valid_acpi_char(char character, u32 position)
594{
595
596 if (!((character >= 'A' && character <= 'Z') ||
597 (character >= '0' && character <= '9') || (character == '_'))) {
598
599 /* Allow a '!' in the last position */
600
601 if (character == '!' && position == 3) {
602 return (TRUE);
603 }
604
605 return (FALSE);
606 }
607
608 return (TRUE);
609}
610
611/*******************************************************************************
612 *
613 * FUNCTION: acpi_ut_valid_acpi_name
614 *
615 * PARAMETERS: Name - The name to be examined
616 *
617 * RETURN: TRUE if the name is valid, FALSE otherwise
618 *
619 * DESCRIPTION: Check for a valid ACPI name. Each character must be one of:
620 * 1) Upper case alpha
621 * 2) numeric
622 * 3) underscore
623 *
624 ******************************************************************************/
625
626u8 acpi_ut_valid_acpi_name(u32 name)
627{
628 u32 i;
629
630 ACPI_FUNCTION_ENTRY();
631
632 for (i = 0; i < ACPI_NAME_SIZE; i++) {
633 if (!acpi_ut_valid_acpi_char
634 ((ACPI_CAST_PTR(char, &name))[i], i)) {
635 return (FALSE);
636 }
637 }
638
639 return (TRUE);
640}
641
642/*******************************************************************************
643 *
644 * FUNCTION: acpi_ut_repair_name
645 *
646 * PARAMETERS: Name - The ACPI name to be repaired
647 *
648 * RETURN: Repaired version of the name
649 *
650 * DESCRIPTION: Repair an ACPI name: Change invalid characters to '*' and
651 * return the new name.
652 *
653 ******************************************************************************/
654
655acpi_name acpi_ut_repair_name(char *name)
656{
657 u32 i;
658 char new_name[ACPI_NAME_SIZE];
659
660 for (i = 0; i < ACPI_NAME_SIZE; i++) {
661 new_name[i] = name[i];
662
663 /*
664 * Replace a bad character with something printable, yet technically
665 * still invalid. This prevents any collisions with existing "good"
666 * names in the namespace.
667 */
668 if (!acpi_ut_valid_acpi_char(name[i], i)) {
669 new_name[i] = '*';
670 }
671 }
672
673 return (*(u32 *) new_name);
674}
675
676/*******************************************************************************
677 *
678 * FUNCTION: acpi_ut_strtoul64
679 *
680 * PARAMETERS: String - Null terminated string
681 * Base - Radix of the string: 16 or ACPI_ANY_BASE;
682 * ACPI_ANY_BASE means 'in behalf of to_integer'
683 * ret_integer - Where the converted integer is returned
684 *
685 * RETURN: Status and Converted value
686 *
687 * DESCRIPTION: Convert a string into an unsigned value. Performs either a
688 * 32-bit or 64-bit conversion, depending on the current mode
689 * of the interpreter.
690 * NOTE: Does not support Octal strings, not needed.
691 *
692 ******************************************************************************/
693
694acpi_status
695acpi_ut_strtoul64(char *string, u32 base, acpi_integer * ret_integer)
696{
697 u32 this_digit = 0;
698 acpi_integer return_value = 0;
699 acpi_integer quotient;
700 acpi_integer dividend;
701 u32 to_integer_op = (base == ACPI_ANY_BASE);
702 u32 mode32 = (acpi_gbl_integer_byte_width == 4);
703 u8 valid_digits = 0;
704 u8 sign_of0x = 0;
705 u8 term = 0;
706
707 ACPI_FUNCTION_TRACE_STR(ut_stroul64, string);
708
709 switch (base) {
710 case ACPI_ANY_BASE:
711 case 16:
712 break;
713
714 default:
715 /* Invalid Base */
716 return_ACPI_STATUS(AE_BAD_PARAMETER);
717 }
718
719 if (!string) {
720 goto error_exit;
721 }
722
723 /* Skip over any white space in the buffer */
724
725 while ((*string) && (ACPI_IS_SPACE(*string) || *string == '\t')) {
726 string++;
727 }
728
729 if (to_integer_op) {
730 /*
731 * Base equal to ACPI_ANY_BASE means 'to_integer operation case'.
732 * We need to determine if it is decimal or hexadecimal.
733 */
734 if ((*string == '0') && (ACPI_TOLOWER(*(string + 1)) == 'x')) {
735 sign_of0x = 1;
736 base = 16;
737
738 /* Skip over the leading '0x' */
739 string += 2;
740 } else {
741 base = 10;
742 }
743 }
744
745 /* Any string left? Check that '0x' is not followed by white space. */
746
747 if (!(*string) || ACPI_IS_SPACE(*string) || *string == '\t') {
748 if (to_integer_op) {
749 goto error_exit;
750 } else {
751 goto all_done;
752 }
753 }
754
755 /*
756 * Perform a 32-bit or 64-bit conversion, depending upon the current
757 * execution mode of the interpreter
758 */
759 dividend = (mode32) ? ACPI_UINT32_MAX : ACPI_UINT64_MAX;
760
761 /* Main loop: convert the string to a 32- or 64-bit integer */
762
763 while (*string) {
764 if (ACPI_IS_DIGIT(*string)) {
765
766 /* Convert ASCII 0-9 to Decimal value */
767
768 this_digit = ((u8) * string) - '0';
769 } else if (base == 10) {
770
771 /* Digit is out of range; possible in to_integer case only */
772
773 term = 1;
774 } else {
775 this_digit = (u8) ACPI_TOUPPER(*string);
776 if (ACPI_IS_XDIGIT((char)this_digit)) {
777
778 /* Convert ASCII Hex char to value */
779
780 this_digit = this_digit - 'A' + 10;
781 } else {
782 term = 1;
783 }
784 }
785
786 if (term) {
787 if (to_integer_op) {
788 goto error_exit;
789 } else {
790 break;
791 }
792 } else if ((valid_digits == 0) && (this_digit == 0)
793 && !sign_of0x) {
794
795 /* Skip zeros */
796 string++;
797 continue;
798 }
799
800 valid_digits++;
801
802 if (sign_of0x && ((valid_digits > 16)
803 || ((valid_digits > 8) && mode32))) {
804 /*
805 * This is to_integer operation case.
806 * No any restrictions for string-to-integer conversion,
807 * see ACPI spec.
808 */
809 goto error_exit;
810 }
811
812 /* Divide the digit into the correct position */
813
814 (void)
815 acpi_ut_short_divide((dividend - (acpi_integer) this_digit),
816 base, &quotient, NULL);
817
818 if (return_value > quotient) {
819 if (to_integer_op) {
820 goto error_exit;
821 } else {
822 break;
823 }
824 }
825
826 return_value *= base;
827 return_value += this_digit;
828 string++;
829 }
830
831 /* All done, normal exit */
832
833 all_done:
834
835 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Converted value: %8.8X%8.8X\n",
836 ACPI_FORMAT_UINT64(return_value)));
837
838 *ret_integer = return_value;
839 return_ACPI_STATUS(AE_OK);
840
841 error_exit:
842 /* Base was set/validated above */
843
844 if (base == 10) {
845 return_ACPI_STATUS(AE_BAD_DECIMAL_CONSTANT);
846 } else {
847 return_ACPI_STATUS(AE_BAD_HEX_CONSTANT);
848 }
849}
850
851/*******************************************************************************
852 *
853 * FUNCTION: acpi_ut_create_update_state_and_push
854 *
855 * PARAMETERS: Object - Object to be added to the new state
856 * Action - Increment/Decrement
857 * state_list - List the state will be added to
858 *
859 * RETURN: Status
860 *
861 * DESCRIPTION: Create a new state and push it
862 *
863 ******************************************************************************/
864
865acpi_status
866acpi_ut_create_update_state_and_push(union acpi_operand_object *object,
867 u16 action,
868 union acpi_generic_state **state_list)
869{
870 union acpi_generic_state *state;
871
872 ACPI_FUNCTION_ENTRY();
873
874 /* Ignore null objects; these are expected */
875
876 if (!object) {
877 return (AE_OK);
878 }
879
880 state = acpi_ut_create_update_state(object, action);
881 if (!state) {
882 return (AE_NO_MEMORY);
883 }
884
885 acpi_ut_push_generic_state(state_list, state);
886 return (AE_OK);
887}
888
889/*******************************************************************************
890 *
891 * FUNCTION: acpi_ut_walk_package_tree
892 *
893 * PARAMETERS: source_object - The package to walk
894 * target_object - Target object (if package is being copied)
895 * walk_callback - Called once for each package element
896 * Context - Passed to the callback function
897 *
898 * RETURN: Status
899 *
900 * DESCRIPTION: Walk through a package
901 *
902 ******************************************************************************/
903
904acpi_status
905acpi_ut_walk_package_tree(union acpi_operand_object * source_object,
906 void *target_object,
907 acpi_pkg_callback walk_callback, void *context)
908{
909 acpi_status status = AE_OK;
910 union acpi_generic_state *state_list = NULL;
911 union acpi_generic_state *state;
912 u32 this_index;
913 union acpi_operand_object *this_source_obj;
914
915 ACPI_FUNCTION_TRACE(ut_walk_package_tree);
916
917 state = acpi_ut_create_pkg_state(source_object, target_object, 0);
918 if (!state) {
919 return_ACPI_STATUS(AE_NO_MEMORY);
920 }
921
922 while (state) {
923
924 /* Get one element of the package */
925
926 this_index = state->pkg.index;
927 this_source_obj = (union acpi_operand_object *)
928 state->pkg.source_object->package.elements[this_index];
929
930 /*
931 * Check for:
932 * 1) An uninitialized package element. It is completely
933 * legal to declare a package and leave it uninitialized
934 * 2) Not an internal object - can be a namespace node instead
935 * 3) Any type other than a package. Packages are handled in else
936 * case below.
937 */
938 if ((!this_source_obj) ||
939 (ACPI_GET_DESCRIPTOR_TYPE(this_source_obj) !=
940 ACPI_DESC_TYPE_OPERAND)
941 || (ACPI_GET_OBJECT_TYPE(this_source_obj) !=
942 ACPI_TYPE_PACKAGE)) {
943 status =
944 walk_callback(ACPI_COPY_TYPE_SIMPLE,
945 this_source_obj, state, context);
946 if (ACPI_FAILURE(status)) {
947 return_ACPI_STATUS(status);
948 }
949
950 state->pkg.index++;
951 while (state->pkg.index >=
952 state->pkg.source_object->package.count) {
953 /*
954 * We've handled all of the objects at this level, This means
955 * that we have just completed a package. That package may
956 * have contained one or more packages itself.
957 *
958 * Delete this state and pop the previous state (package).
959 */
960 acpi_ut_delete_generic_state(state);
961 state = acpi_ut_pop_generic_state(&state_list);
962
963 /* Finished when there are no more states */
964
965 if (!state) {
966 /*
967 * We have handled all of the objects in the top level
968 * package just add the length of the package objects
969 * and exit
970 */
971 return_ACPI_STATUS(AE_OK);
972 }
973
974 /*
975 * Go back up a level and move the index past the just
976 * completed package object.
977 */
978 state->pkg.index++;
979 }
980 } else {
981 /* This is a subobject of type package */
982
983 status =
984 walk_callback(ACPI_COPY_TYPE_PACKAGE,
985 this_source_obj, state, context);
986 if (ACPI_FAILURE(status)) {
987 return_ACPI_STATUS(status);
988 }
989
990 /*
991 * Push the current state and create a new one
992 * The callback above returned a new target package object.
993 */
994 acpi_ut_push_generic_state(&state_list, state);
995 state = acpi_ut_create_pkg_state(this_source_obj,
996 state->pkg.
997 this_target_obj, 0);
998 if (!state) {
999
1000 /* Free any stacked Update State objects */
1001
1002 while (state_list) {
1003 state =
1004 acpi_ut_pop_generic_state
1005 (&state_list);
1006 acpi_ut_delete_generic_state(state);
1007 }
1008 return_ACPI_STATUS(AE_NO_MEMORY);
1009 }
1010 }
1011 }
1012
1013 /* We should never get here */
1014
1015 return_ACPI_STATUS(AE_AML_INTERNAL);
1016}
1017
1018/*******************************************************************************
1019 *
1020 * FUNCTION: acpi_error, acpi_exception, acpi_warning, acpi_info
1021 *
1022 * PARAMETERS: module_name - Caller's module name (for error output)
1023 * line_number - Caller's line number (for error output)
1024 * Format - Printf format string + additional args
1025 *
1026 * RETURN: None
1027 *
1028 * DESCRIPTION: Print message with module/line/version info
1029 *
1030 ******************************************************************************/
1031
1032void ACPI_INTERNAL_VAR_XFACE
1033acpi_error(const char *module_name, u32 line_number, const char *format, ...)
1034{
1035 va_list args;
1036
1037 acpi_os_printf("ACPI Error (%s-%04d): ", module_name, line_number);
1038
1039 va_start(args, format);
1040 acpi_os_vprintf(format, args);
1041 acpi_os_printf(" [%X]\n", ACPI_CA_VERSION);
1042 va_end(args);
1043}
1044
1045void ACPI_INTERNAL_VAR_XFACE
1046acpi_exception(const char *module_name,
1047 u32 line_number, acpi_status status, const char *format, ...)
1048{
1049 va_list args;
1050
1051 acpi_os_printf("ACPI Exception (%s-%04d): %s, ", module_name,
1052 line_number, acpi_format_exception(status));
1053
1054 va_start(args, format);
1055 acpi_os_vprintf(format, args);
1056 acpi_os_printf(" [%X]\n", ACPI_CA_VERSION);
1057 va_end(args);
1058}
1059
1060void ACPI_INTERNAL_VAR_XFACE
1061acpi_warning(const char *module_name, u32 line_number, const char *format, ...)
1062{
1063 va_list args;
1064
1065 acpi_os_printf("ACPI Warning (%s-%04d): ", module_name, line_number);
1066
1067 va_start(args, format);
1068 acpi_os_vprintf(format, args);
1069 acpi_os_printf(" [%X]\n", ACPI_CA_VERSION);
1070 va_end(args);
1071}
1072
1073void ACPI_INTERNAL_VAR_XFACE
1074acpi_info(const char *module_name, u32 line_number, const char *format, ...)
1075{
1076 va_list args;
1077
1078 /*
1079 * Removed module_name, line_number, and acpica version, not needed
1080 * for info output
1081 */
1082 acpi_os_printf("ACPI: ");
1083
1084 va_start(args, format);
1085 acpi_os_vprintf(format, args);
1086 acpi_os_printf("\n");
1087 va_end(args);
1088}
1089
1090ACPI_EXPORT_SYMBOL(acpi_error)
1091ACPI_EXPORT_SYMBOL(acpi_exception)
1092ACPI_EXPORT_SYMBOL(acpi_warning)
1093ACPI_EXPORT_SYMBOL(acpi_info)
diff --git a/drivers/acpi/acpica/utmutex.c b/drivers/acpi/acpica/utmutex.c
new file mode 100644
index 00000000000..7b48ba3f3f8
--- /dev/null
+++ b/drivers/acpi/acpica/utmutex.c
@@ -0,0 +1,342 @@
1/*******************************************************************************
2 *
3 * Module Name: utmutex - local mutex support
4 *
5 ******************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46
47#define _COMPONENT ACPI_UTILITIES
48ACPI_MODULE_NAME("utmutex")
49
50/* Local prototypes */
51static acpi_status acpi_ut_create_mutex(acpi_mutex_handle mutex_id);
52
53static acpi_status acpi_ut_delete_mutex(acpi_mutex_handle mutex_id);
54
55/*******************************************************************************
56 *
57 * FUNCTION: acpi_ut_mutex_initialize
58 *
59 * PARAMETERS: None.
60 *
61 * RETURN: Status
62 *
63 * DESCRIPTION: Create the system mutex objects.
64 *
65 ******************************************************************************/
66
67acpi_status acpi_ut_mutex_initialize(void)
68{
69 u32 i;
70 acpi_status status;
71
72 ACPI_FUNCTION_TRACE(ut_mutex_initialize);
73
74 /*
75 * Create each of the predefined mutex objects
76 */
77 for (i = 0; i < ACPI_NUM_MUTEX; i++) {
78 status = acpi_ut_create_mutex(i);
79 if (ACPI_FAILURE(status)) {
80 return_ACPI_STATUS(status);
81 }
82 }
83
84 /* Create the spinlocks for use at interrupt level */
85
86 spin_lock_init(acpi_gbl_gpe_lock);
87 spin_lock_init(acpi_gbl_hardware_lock);
88
89 return_ACPI_STATUS(status);
90}
91
92/*******************************************************************************
93 *
94 * FUNCTION: acpi_ut_mutex_terminate
95 *
96 * PARAMETERS: None.
97 *
98 * RETURN: None.
99 *
100 * DESCRIPTION: Delete all of the system mutex objects.
101 *
102 ******************************************************************************/
103
104void acpi_ut_mutex_terminate(void)
105{
106 u32 i;
107
108 ACPI_FUNCTION_TRACE(ut_mutex_terminate);
109
110 /*
111 * Delete each predefined mutex object
112 */
113 for (i = 0; i < ACPI_NUM_MUTEX; i++) {
114 (void)acpi_ut_delete_mutex(i);
115 }
116
117 /* Delete the spinlocks */
118
119 acpi_os_delete_lock(acpi_gbl_gpe_lock);
120 acpi_os_delete_lock(acpi_gbl_hardware_lock);
121 return_VOID;
122}
123
124/*******************************************************************************
125 *
126 * FUNCTION: acpi_ut_create_mutex
127 *
128 * PARAMETERS: mutex_iD - ID of the mutex to be created
129 *
130 * RETURN: Status
131 *
132 * DESCRIPTION: Create a mutex object.
133 *
134 ******************************************************************************/
135
136static acpi_status acpi_ut_create_mutex(acpi_mutex_handle mutex_id)
137{
138 acpi_status status = AE_OK;
139
140 ACPI_FUNCTION_TRACE_U32(ut_create_mutex, mutex_id);
141
142 if (mutex_id > ACPI_MAX_MUTEX) {
143 return_ACPI_STATUS(AE_BAD_PARAMETER);
144 }
145
146 if (!acpi_gbl_mutex_info[mutex_id].mutex) {
147 status =
148 acpi_os_create_mutex(&acpi_gbl_mutex_info[mutex_id].mutex);
149 acpi_gbl_mutex_info[mutex_id].thread_id =
150 ACPI_MUTEX_NOT_ACQUIRED;
151 acpi_gbl_mutex_info[mutex_id].use_count = 0;
152 }
153
154 return_ACPI_STATUS(status);
155}
156
157/*******************************************************************************
158 *
159 * FUNCTION: acpi_ut_delete_mutex
160 *
161 * PARAMETERS: mutex_iD - ID of the mutex to be deleted
162 *
163 * RETURN: Status
164 *
165 * DESCRIPTION: Delete a mutex object.
166 *
167 ******************************************************************************/
168
169static acpi_status acpi_ut_delete_mutex(acpi_mutex_handle mutex_id)
170{
171
172 ACPI_FUNCTION_TRACE_U32(ut_delete_mutex, mutex_id);
173
174 if (mutex_id > ACPI_MAX_MUTEX) {
175 return_ACPI_STATUS(AE_BAD_PARAMETER);
176 }
177
178 acpi_os_delete_mutex(acpi_gbl_mutex_info[mutex_id].mutex);
179
180 acpi_gbl_mutex_info[mutex_id].mutex = NULL;
181 acpi_gbl_mutex_info[mutex_id].thread_id = ACPI_MUTEX_NOT_ACQUIRED;
182
183 return_ACPI_STATUS(AE_OK);
184}
185
186/*******************************************************************************
187 *
188 * FUNCTION: acpi_ut_acquire_mutex
189 *
190 * PARAMETERS: mutex_iD - ID of the mutex to be acquired
191 *
192 * RETURN: Status
193 *
194 * DESCRIPTION: Acquire a mutex object.
195 *
196 ******************************************************************************/
197
198acpi_status acpi_ut_acquire_mutex(acpi_mutex_handle mutex_id)
199{
200 acpi_status status;
201 acpi_thread_id this_thread_id;
202
203 ACPI_FUNCTION_NAME(ut_acquire_mutex);
204
205 if (mutex_id > ACPI_MAX_MUTEX) {
206 return (AE_BAD_PARAMETER);
207 }
208
209 this_thread_id = acpi_os_get_thread_id();
210
211#ifdef ACPI_MUTEX_DEBUG
212 {
213 u32 i;
214 /*
215 * Mutex debug code, for internal debugging only.
216 *
217 * Deadlock prevention. Check if this thread owns any mutexes of value
218 * greater than or equal to this one. If so, the thread has violated
219 * the mutex ordering rule. This indicates a coding error somewhere in
220 * the ACPI subsystem code.
221 */
222 for (i = mutex_id; i < ACPI_NUM_MUTEX; i++) {
223 if (acpi_gbl_mutex_info[i].thread_id == this_thread_id) {
224 if (i == mutex_id) {
225 ACPI_ERROR((AE_INFO,
226 "Mutex [%s] already acquired by this thread [%X]",
227 acpi_ut_get_mutex_name
228 (mutex_id),
229 this_thread_id));
230
231 return (AE_ALREADY_ACQUIRED);
232 }
233
234 ACPI_ERROR((AE_INFO,
235 "Invalid acquire order: Thread %X owns [%s], wants [%s]",
236 this_thread_id,
237 acpi_ut_get_mutex_name(i),
238 acpi_ut_get_mutex_name(mutex_id)));
239
240 return (AE_ACQUIRE_DEADLOCK);
241 }
242 }
243 }
244#endif
245
246 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
247 "Thread %lX attempting to acquire Mutex [%s]\n",
248 (unsigned long)this_thread_id,
249 acpi_ut_get_mutex_name(mutex_id)));
250
251 status = acpi_os_acquire_mutex(acpi_gbl_mutex_info[mutex_id].mutex,
252 ACPI_WAIT_FOREVER);
253 if (ACPI_SUCCESS(status)) {
254 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
255 "Thread %lX acquired Mutex [%s]\n",
256 (unsigned long)this_thread_id,
257 acpi_ut_get_mutex_name(mutex_id)));
258
259 acpi_gbl_mutex_info[mutex_id].use_count++;
260 acpi_gbl_mutex_info[mutex_id].thread_id = this_thread_id;
261 } else {
262 ACPI_EXCEPTION((AE_INFO, status,
263 "Thread %lX could not acquire Mutex [%X]",
264 (unsigned long)this_thread_id, mutex_id));
265 }
266
267 return (status);
268}
269
270/*******************************************************************************
271 *
272 * FUNCTION: acpi_ut_release_mutex
273 *
274 * PARAMETERS: mutex_iD - ID of the mutex to be released
275 *
276 * RETURN: Status
277 *
278 * DESCRIPTION: Release a mutex object.
279 *
280 ******************************************************************************/
281
282acpi_status acpi_ut_release_mutex(acpi_mutex_handle mutex_id)
283{
284 acpi_thread_id this_thread_id;
285
286 ACPI_FUNCTION_NAME(ut_release_mutex);
287
288 this_thread_id = acpi_os_get_thread_id();
289 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
290 "Thread %lX releasing Mutex [%s]\n",
291 (unsigned long)this_thread_id,
292 acpi_ut_get_mutex_name(mutex_id)));
293
294 if (mutex_id > ACPI_MAX_MUTEX) {
295 return (AE_BAD_PARAMETER);
296 }
297
298 /*
299 * Mutex must be acquired in order to release it!
300 */
301 if (acpi_gbl_mutex_info[mutex_id].thread_id == ACPI_MUTEX_NOT_ACQUIRED) {
302 ACPI_ERROR((AE_INFO,
303 "Mutex [%X] is not acquired, cannot release",
304 mutex_id));
305
306 return (AE_NOT_ACQUIRED);
307 }
308#ifdef ACPI_MUTEX_DEBUG
309 {
310 u32 i;
311 /*
312 * Mutex debug code, for internal debugging only.
313 *
314 * Deadlock prevention. Check if this thread owns any mutexes of value
315 * greater than this one. If so, the thread has violated the mutex
316 * ordering rule. This indicates a coding error somewhere in
317 * the ACPI subsystem code.
318 */
319 for (i = mutex_id; i < ACPI_NUM_MUTEX; i++) {
320 if (acpi_gbl_mutex_info[i].thread_id == this_thread_id) {
321 if (i == mutex_id) {
322 continue;
323 }
324
325 ACPI_ERROR((AE_INFO,
326 "Invalid release order: owns [%s], releasing [%s]",
327 acpi_ut_get_mutex_name(i),
328 acpi_ut_get_mutex_name(mutex_id)));
329
330 return (AE_RELEASE_DEADLOCK);
331 }
332 }
333 }
334#endif
335
336 /* Mark unlocked FIRST */
337
338 acpi_gbl_mutex_info[mutex_id].thread_id = ACPI_MUTEX_NOT_ACQUIRED;
339
340 acpi_os_release_mutex(acpi_gbl_mutex_info[mutex_id].mutex);
341 return (AE_OK);
342}
diff --git a/drivers/acpi/acpica/utobject.c b/drivers/acpi/acpica/utobject.c
new file mode 100644
index 00000000000..964b23c1161
--- /dev/null
+++ b/drivers/acpi/acpica/utobject.c
@@ -0,0 +1,677 @@
1/******************************************************************************
2 *
3 * Module Name: utobject - ACPI object create/delete/size/cache routines
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46#include <acpi/acnamesp.h>
47
48#define _COMPONENT ACPI_UTILITIES
49ACPI_MODULE_NAME("utobject")
50
51/* Local prototypes */
52static acpi_status
53acpi_ut_get_simple_object_size(union acpi_operand_object *obj,
54 acpi_size * obj_length);
55
56static acpi_status
57acpi_ut_get_package_object_size(union acpi_operand_object *obj,
58 acpi_size * obj_length);
59
60static acpi_status
61acpi_ut_get_element_length(u8 object_type,
62 union acpi_operand_object *source_object,
63 union acpi_generic_state *state, void *context);
64
65/*******************************************************************************
66 *
67 * FUNCTION: acpi_ut_create_internal_object_dbg
68 *
69 * PARAMETERS: module_name - Source file name of caller
70 * line_number - Line number of caller
71 * component_id - Component type of caller
72 * Type - ACPI Type of the new object
73 *
74 * RETURN: A new internal object, null on failure
75 *
76 * DESCRIPTION: Create and initialize a new internal object.
77 *
78 * NOTE: We always allocate the worst-case object descriptor because
79 * these objects are cached, and we want them to be
80 * one-size-satisifies-any-request. This in itself may not be
81 * the most memory efficient, but the efficiency of the object
82 * cache should more than make up for this!
83 *
84 ******************************************************************************/
85
86union acpi_operand_object *acpi_ut_create_internal_object_dbg(const char
87 *module_name,
88 u32 line_number,
89 u32 component_id,
90 acpi_object_type
91 type)
92{
93 union acpi_operand_object *object;
94 union acpi_operand_object *second_object;
95
96 ACPI_FUNCTION_TRACE_STR(ut_create_internal_object_dbg,
97 acpi_ut_get_type_name(type));
98
99 /* Allocate the raw object descriptor */
100
101 object =
102 acpi_ut_allocate_object_desc_dbg(module_name, line_number,
103 component_id);
104 if (!object) {
105 return_PTR(NULL);
106 }
107
108 switch (type) {
109 case ACPI_TYPE_REGION:
110 case ACPI_TYPE_BUFFER_FIELD:
111 case ACPI_TYPE_LOCAL_BANK_FIELD:
112
113 /* These types require a secondary object */
114
115 second_object = acpi_ut_allocate_object_desc_dbg(module_name,
116 line_number,
117 component_id);
118 if (!second_object) {
119 acpi_ut_delete_object_desc(object);
120 return_PTR(NULL);
121 }
122
123 second_object->common.type = ACPI_TYPE_LOCAL_EXTRA;
124 second_object->common.reference_count = 1;
125
126 /* Link the second object to the first */
127
128 object->common.next_object = second_object;
129 break;
130
131 default:
132 /* All others have no secondary object */
133 break;
134 }
135
136 /* Save the object type in the object descriptor */
137
138 object->common.type = (u8) type;
139
140 /* Init the reference count */
141
142 object->common.reference_count = 1;
143
144 /* Any per-type initialization should go here */
145
146 return_PTR(object);
147}
148
149/*******************************************************************************
150 *
151 * FUNCTION: acpi_ut_create_package_object
152 *
153 * PARAMETERS: Count - Number of package elements
154 *
155 * RETURN: Pointer to a new Package object, null on failure
156 *
157 * DESCRIPTION: Create a fully initialized package object
158 *
159 ******************************************************************************/
160
161union acpi_operand_object *acpi_ut_create_package_object(u32 count)
162{
163 union acpi_operand_object *package_desc;
164 union acpi_operand_object **package_elements;
165
166 ACPI_FUNCTION_TRACE_U32(ut_create_package_object, count);
167
168 /* Create a new Package object */
169
170 package_desc = acpi_ut_create_internal_object(ACPI_TYPE_PACKAGE);
171 if (!package_desc) {
172 return_PTR(NULL);
173 }
174
175 /*
176 * Create the element array. Count+1 allows the array to be null
177 * terminated.
178 */
179 package_elements = ACPI_ALLOCATE_ZEROED(((acpi_size) count +
180 1) * sizeof(void *));
181 if (!package_elements) {
182 acpi_ut_remove_reference(package_desc);
183 return_PTR(NULL);
184 }
185
186 package_desc->package.count = count;
187 package_desc->package.elements = package_elements;
188 return_PTR(package_desc);
189}
190
191/*******************************************************************************
192 *
193 * FUNCTION: acpi_ut_create_buffer_object
194 *
195 * PARAMETERS: buffer_size - Size of buffer to be created
196 *
197 * RETURN: Pointer to a new Buffer object, null on failure
198 *
199 * DESCRIPTION: Create a fully initialized buffer object
200 *
201 ******************************************************************************/
202
203union acpi_operand_object *acpi_ut_create_buffer_object(acpi_size buffer_size)
204{
205 union acpi_operand_object *buffer_desc;
206 u8 *buffer = NULL;
207
208 ACPI_FUNCTION_TRACE_U32(ut_create_buffer_object, buffer_size);
209
210 /* Create a new Buffer object */
211
212 buffer_desc = acpi_ut_create_internal_object(ACPI_TYPE_BUFFER);
213 if (!buffer_desc) {
214 return_PTR(NULL);
215 }
216
217 /* Create an actual buffer only if size > 0 */
218
219 if (buffer_size > 0) {
220
221 /* Allocate the actual buffer */
222
223 buffer = ACPI_ALLOCATE_ZEROED(buffer_size);
224 if (!buffer) {
225 ACPI_ERROR((AE_INFO, "Could not allocate size %X",
226 (u32) buffer_size));
227 acpi_ut_remove_reference(buffer_desc);
228 return_PTR(NULL);
229 }
230 }
231
232 /* Complete buffer object initialization */
233
234 buffer_desc->buffer.flags |= AOPOBJ_DATA_VALID;
235 buffer_desc->buffer.pointer = buffer;
236 buffer_desc->buffer.length = (u32) buffer_size;
237
238 /* Return the new buffer descriptor */
239
240 return_PTR(buffer_desc);
241}
242
243/*******************************************************************************
244 *
245 * FUNCTION: acpi_ut_create_string_object
246 *
247 * PARAMETERS: string_size - Size of string to be created. Does not
248 * include NULL terminator, this is added
249 * automatically.
250 *
251 * RETURN: Pointer to a new String object
252 *
253 * DESCRIPTION: Create a fully initialized string object
254 *
255 ******************************************************************************/
256
257union acpi_operand_object *acpi_ut_create_string_object(acpi_size string_size)
258{
259 union acpi_operand_object *string_desc;
260 char *string;
261
262 ACPI_FUNCTION_TRACE_U32(ut_create_string_object, string_size);
263
264 /* Create a new String object */
265
266 string_desc = acpi_ut_create_internal_object(ACPI_TYPE_STRING);
267 if (!string_desc) {
268 return_PTR(NULL);
269 }
270
271 /*
272 * Allocate the actual string buffer -- (Size + 1) for NULL terminator.
273 * NOTE: Zero-length strings are NULL terminated
274 */
275 string = ACPI_ALLOCATE_ZEROED(string_size + 1);
276 if (!string) {
277 ACPI_ERROR((AE_INFO, "Could not allocate size %X",
278 (u32) string_size));
279 acpi_ut_remove_reference(string_desc);
280 return_PTR(NULL);
281 }
282
283 /* Complete string object initialization */
284
285 string_desc->string.pointer = string;
286 string_desc->string.length = (u32) string_size;
287
288 /* Return the new string descriptor */
289
290 return_PTR(string_desc);
291}
292
293/*******************************************************************************
294 *
295 * FUNCTION: acpi_ut_valid_internal_object
296 *
297 * PARAMETERS: Object - Object to be validated
298 *
299 * RETURN: TRUE if object is valid, FALSE otherwise
300 *
301 * DESCRIPTION: Validate a pointer to be an union acpi_operand_object
302 *
303 ******************************************************************************/
304
305u8 acpi_ut_valid_internal_object(void *object)
306{
307
308 ACPI_FUNCTION_NAME(ut_valid_internal_object);
309
310 /* Check for a null pointer */
311
312 if (!object) {
313 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "**** Null Object Ptr\n"));
314 return (FALSE);
315 }
316
317 /* Check the descriptor type field */
318
319 switch (ACPI_GET_DESCRIPTOR_TYPE(object)) {
320 case ACPI_DESC_TYPE_OPERAND:
321
322 /* The object appears to be a valid union acpi_operand_object */
323
324 return (TRUE);
325
326 default:
327 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
328 "%p is not not an ACPI operand obj [%s]\n",
329 object, acpi_ut_get_descriptor_name(object)));
330 break;
331 }
332
333 return (FALSE);
334}
335
336/*******************************************************************************
337 *
338 * FUNCTION: acpi_ut_allocate_object_desc_dbg
339 *
340 * PARAMETERS: module_name - Caller's module name (for error output)
341 * line_number - Caller's line number (for error output)
342 * component_id - Caller's component ID (for error output)
343 *
344 * RETURN: Pointer to newly allocated object descriptor. Null on error
345 *
346 * DESCRIPTION: Allocate a new object descriptor. Gracefully handle
347 * error conditions.
348 *
349 ******************************************************************************/
350
351void *acpi_ut_allocate_object_desc_dbg(const char *module_name,
352 u32 line_number, u32 component_id)
353{
354 union acpi_operand_object *object;
355
356 ACPI_FUNCTION_TRACE(ut_allocate_object_desc_dbg);
357
358 object = acpi_os_acquire_object(acpi_gbl_operand_cache);
359 if (!object) {
360 ACPI_ERROR((module_name, line_number,
361 "Could not allocate an object descriptor"));
362
363 return_PTR(NULL);
364 }
365
366 /* Mark the descriptor type */
367
368 memset(object, 0, sizeof(union acpi_operand_object));
369 ACPI_SET_DESCRIPTOR_TYPE(object, ACPI_DESC_TYPE_OPERAND);
370
371 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, "%p Size %X\n",
372 object, (u32) sizeof(union acpi_operand_object)));
373
374 return_PTR(object);
375}
376
377/*******************************************************************************
378 *
379 * FUNCTION: acpi_ut_delete_object_desc
380 *
381 * PARAMETERS: Object - An Acpi internal object to be deleted
382 *
383 * RETURN: None.
384 *
385 * DESCRIPTION: Free an ACPI object descriptor or add it to the object cache
386 *
387 ******************************************************************************/
388
389void acpi_ut_delete_object_desc(union acpi_operand_object *object)
390{
391 ACPI_FUNCTION_TRACE_PTR(ut_delete_object_desc, object);
392
393 /* Object must be an union acpi_operand_object */
394
395 if (ACPI_GET_DESCRIPTOR_TYPE(object) != ACPI_DESC_TYPE_OPERAND) {
396 ACPI_ERROR((AE_INFO,
397 "%p is not an ACPI Operand object [%s]", object,
398 acpi_ut_get_descriptor_name(object)));
399 return_VOID;
400 }
401
402 (void)acpi_os_release_object(acpi_gbl_operand_cache, object);
403 return_VOID;
404}
405
406/*******************************************************************************
407 *
408 * FUNCTION: acpi_ut_get_simple_object_size
409 *
410 * PARAMETERS: internal_object - An ACPI operand object
411 * obj_length - Where the length is returned
412 *
413 * RETURN: Status
414 *
415 * DESCRIPTION: This function is called to determine the space required to
416 * contain a simple object for return to an external user.
417 *
418 * The length includes the object structure plus any additional
419 * needed space.
420 *
421 ******************************************************************************/
422
423static acpi_status
424acpi_ut_get_simple_object_size(union acpi_operand_object *internal_object,
425 acpi_size * obj_length)
426{
427 acpi_size length;
428 acpi_size size;
429 acpi_status status = AE_OK;
430
431 ACPI_FUNCTION_TRACE_PTR(ut_get_simple_object_size, internal_object);
432
433 /*
434 * Handle a null object (Could be a uninitialized package
435 * element -- which is legal)
436 */
437 if (!internal_object) {
438 *obj_length = sizeof(union acpi_object);
439 return_ACPI_STATUS(AE_OK);
440 }
441
442 /* Start with the length of the Acpi object */
443
444 length = sizeof(union acpi_object);
445
446 if (ACPI_GET_DESCRIPTOR_TYPE(internal_object) == ACPI_DESC_TYPE_NAMED) {
447
448 /* Object is a named object (reference), just return the length */
449
450 *obj_length = ACPI_ROUND_UP_TO_NATIVE_WORD(length);
451 return_ACPI_STATUS(status);
452 }
453
454 /*
455 * The final length depends on the object type
456 * Strings and Buffers are packed right up against the parent object and
457 * must be accessed bytewise or there may be alignment problems on
458 * certain processors
459 */
460 switch (ACPI_GET_OBJECT_TYPE(internal_object)) {
461 case ACPI_TYPE_STRING:
462
463 length += (acpi_size) internal_object->string.length + 1;
464 break;
465
466 case ACPI_TYPE_BUFFER:
467
468 length += (acpi_size) internal_object->buffer.length;
469 break;
470
471 case ACPI_TYPE_INTEGER:
472 case ACPI_TYPE_PROCESSOR:
473 case ACPI_TYPE_POWER:
474
475 /* No extra data for these types */
476
477 break;
478
479 case ACPI_TYPE_LOCAL_REFERENCE:
480
481 switch (internal_object->reference.class) {
482 case ACPI_REFCLASS_NAME:
483
484 /*
485 * Get the actual length of the full pathname to this object.
486 * The reference will be converted to the pathname to the object
487 */
488 size =
489 acpi_ns_get_pathname_length(internal_object->
490 reference.node);
491 if (!size) {
492 return_ACPI_STATUS(AE_BAD_PARAMETER);
493 }
494
495 length += ACPI_ROUND_UP_TO_NATIVE_WORD(size);
496 break;
497
498 default:
499
500 /*
501 * No other reference opcodes are supported.
502 * Notably, Locals and Args are not supported, but this may be
503 * required eventually.
504 */
505 ACPI_ERROR((AE_INFO,
506 "Cannot convert to external object - "
507 "unsupported Reference Class [%s] %X in object %p",
508 acpi_ut_get_reference_name(internal_object),
509 internal_object->reference.class,
510 internal_object));
511 status = AE_TYPE;
512 break;
513 }
514 break;
515
516 default:
517
518 ACPI_ERROR((AE_INFO, "Cannot convert to external object - "
519 "unsupported type [%s] %X in object %p",
520 acpi_ut_get_object_type_name(internal_object),
521 ACPI_GET_OBJECT_TYPE(internal_object),
522 internal_object));
523 status = AE_TYPE;
524 break;
525 }
526
527 /*
528 * Account for the space required by the object rounded up to the next
529 * multiple of the machine word size. This keeps each object aligned
530 * on a machine word boundary. (preventing alignment faults on some
531 * machines.)
532 */
533 *obj_length = ACPI_ROUND_UP_TO_NATIVE_WORD(length);
534 return_ACPI_STATUS(status);
535}
536
537/*******************************************************************************
538 *
539 * FUNCTION: acpi_ut_get_element_length
540 *
541 * PARAMETERS: acpi_pkg_callback
542 *
543 * RETURN: Status
544 *
545 * DESCRIPTION: Get the length of one package element.
546 *
547 ******************************************************************************/
548
549static acpi_status
550acpi_ut_get_element_length(u8 object_type,
551 union acpi_operand_object *source_object,
552 union acpi_generic_state *state, void *context)
553{
554 acpi_status status = AE_OK;
555 struct acpi_pkg_info *info = (struct acpi_pkg_info *)context;
556 acpi_size object_space;
557
558 switch (object_type) {
559 case ACPI_COPY_TYPE_SIMPLE:
560
561 /*
562 * Simple object - just get the size (Null object/entry is handled
563 * here also) and sum it into the running package length
564 */
565 status =
566 acpi_ut_get_simple_object_size(source_object,
567 &object_space);
568 if (ACPI_FAILURE(status)) {
569 return (status);
570 }
571
572 info->length += object_space;
573 break;
574
575 case ACPI_COPY_TYPE_PACKAGE:
576
577 /* Package object - nothing much to do here, let the walk handle it */
578
579 info->num_packages++;
580 state->pkg.this_target_obj = NULL;
581 break;
582
583 default:
584
585 /* No other types allowed */
586
587 return (AE_BAD_PARAMETER);
588 }
589
590 return (status);
591}
592
593/*******************************************************************************
594 *
595 * FUNCTION: acpi_ut_get_package_object_size
596 *
597 * PARAMETERS: internal_object - An ACPI internal object
598 * obj_length - Where the length is returned
599 *
600 * RETURN: Status
601 *
602 * DESCRIPTION: This function is called to determine the space required to
603 * contain a package object for return to an external user.
604 *
605 * This is moderately complex since a package contains other
606 * objects including packages.
607 *
608 ******************************************************************************/
609
610static acpi_status
611acpi_ut_get_package_object_size(union acpi_operand_object *internal_object,
612 acpi_size * obj_length)
613{
614 acpi_status status;
615 struct acpi_pkg_info info;
616
617 ACPI_FUNCTION_TRACE_PTR(ut_get_package_object_size, internal_object);
618
619 info.length = 0;
620 info.object_space = 0;
621 info.num_packages = 1;
622
623 status = acpi_ut_walk_package_tree(internal_object, NULL,
624 acpi_ut_get_element_length, &info);
625 if (ACPI_FAILURE(status)) {
626 return_ACPI_STATUS(status);
627 }
628
629 /*
630 * We have handled all of the objects in all levels of the package.
631 * just add the length of the package objects themselves.
632 * Round up to the next machine word.
633 */
634 info.length += ACPI_ROUND_UP_TO_NATIVE_WORD(sizeof(union acpi_object)) *
635 (acpi_size) info.num_packages;
636
637 /* Return the total package length */
638
639 *obj_length = info.length;
640 return_ACPI_STATUS(status);
641}
642
643/*******************************************************************************
644 *
645 * FUNCTION: acpi_ut_get_object_size
646 *
647 * PARAMETERS: internal_object - An ACPI internal object
648 * obj_length - Where the length will be returned
649 *
650 * RETURN: Status
651 *
652 * DESCRIPTION: This function is called to determine the space required to
653 * contain an object for return to an API user.
654 *
655 ******************************************************************************/
656
657acpi_status
658acpi_ut_get_object_size(union acpi_operand_object *internal_object,
659 acpi_size * obj_length)
660{
661 acpi_status status;
662
663 ACPI_FUNCTION_ENTRY();
664
665 if ((ACPI_GET_DESCRIPTOR_TYPE(internal_object) ==
666 ACPI_DESC_TYPE_OPERAND)
667 && (ACPI_GET_OBJECT_TYPE(internal_object) == ACPI_TYPE_PACKAGE)) {
668 status =
669 acpi_ut_get_package_object_size(internal_object,
670 obj_length);
671 } else {
672 status =
673 acpi_ut_get_simple_object_size(internal_object, obj_length);
674 }
675
676 return (status);
677}
diff --git a/drivers/acpi/acpica/utresrc.c b/drivers/acpi/acpica/utresrc.c
new file mode 100644
index 00000000000..0755c5cdbe1
--- /dev/null
+++ b/drivers/acpi/acpica/utresrc.c
@@ -0,0 +1,616 @@
1/*******************************************************************************
2 *
3 * Module Name: utresrc - Resource management utilities
4 *
5 ******************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46#include <acpi/amlresrc.h>
47
48#define _COMPONENT ACPI_UTILITIES
49ACPI_MODULE_NAME("utresrc")
50#if defined(ACPI_DISASSEMBLER) || defined (ACPI_DEBUGGER)
51/*
52 * Strings used to decode resource descriptors.
53 * Used by both the disasssembler and the debugger resource dump routines
54 */
55const char *acpi_gbl_bm_decode[] = {
56 "NotBusMaster",
57 "BusMaster"
58};
59
60const char *acpi_gbl_config_decode[] = {
61 "0 - Good Configuration",
62 "1 - Acceptable Configuration",
63 "2 - Suboptimal Configuration",
64 "3 - ***Invalid Configuration***",
65};
66
67const char *acpi_gbl_consume_decode[] = {
68 "ResourceProducer",
69 "ResourceConsumer"
70};
71
72const char *acpi_gbl_dec_decode[] = {
73 "PosDecode",
74 "SubDecode"
75};
76
77const char *acpi_gbl_he_decode[] = {
78 "Level",
79 "Edge"
80};
81
82const char *acpi_gbl_io_decode[] = {
83 "Decode10",
84 "Decode16"
85};
86
87const char *acpi_gbl_ll_decode[] = {
88 "ActiveHigh",
89 "ActiveLow"
90};
91
92const char *acpi_gbl_max_decode[] = {
93 "MaxNotFixed",
94 "MaxFixed"
95};
96
97const char *acpi_gbl_mem_decode[] = {
98 "NonCacheable",
99 "Cacheable",
100 "WriteCombining",
101 "Prefetchable"
102};
103
104const char *acpi_gbl_min_decode[] = {
105 "MinNotFixed",
106 "MinFixed"
107};
108
109const char *acpi_gbl_mtp_decode[] = {
110 "AddressRangeMemory",
111 "AddressRangeReserved",
112 "AddressRangeACPI",
113 "AddressRangeNVS"
114};
115
116const char *acpi_gbl_rng_decode[] = {
117 "InvalidRanges",
118 "NonISAOnlyRanges",
119 "ISAOnlyRanges",
120 "EntireRange"
121};
122
123const char *acpi_gbl_rw_decode[] = {
124 "ReadOnly",
125 "ReadWrite"
126};
127
128const char *acpi_gbl_shr_decode[] = {
129 "Exclusive",
130 "Shared"
131};
132
133const char *acpi_gbl_siz_decode[] = {
134 "Transfer8",
135 "Transfer8_16",
136 "Transfer16",
137 "InvalidSize"
138};
139
140const char *acpi_gbl_trs_decode[] = {
141 "DenseTranslation",
142 "SparseTranslation"
143};
144
145const char *acpi_gbl_ttp_decode[] = {
146 "TypeStatic",
147 "TypeTranslation"
148};
149
150const char *acpi_gbl_typ_decode[] = {
151 "Compatibility",
152 "TypeA",
153 "TypeB",
154 "TypeF"
155};
156
157#endif
158
159/*
160 * Base sizes of the raw AML resource descriptors, indexed by resource type.
161 * Zero indicates a reserved (and therefore invalid) resource type.
162 */
163const u8 acpi_gbl_resource_aml_sizes[] = {
164 /* Small descriptors */
165
166 0,
167 0,
168 0,
169 0,
170 ACPI_AML_SIZE_SMALL(struct aml_resource_irq),
171 ACPI_AML_SIZE_SMALL(struct aml_resource_dma),
172 ACPI_AML_SIZE_SMALL(struct aml_resource_start_dependent),
173 ACPI_AML_SIZE_SMALL(struct aml_resource_end_dependent),
174 ACPI_AML_SIZE_SMALL(struct aml_resource_io),
175 ACPI_AML_SIZE_SMALL(struct aml_resource_fixed_io),
176 0,
177 0,
178 0,
179 0,
180 ACPI_AML_SIZE_SMALL(struct aml_resource_vendor_small),
181 ACPI_AML_SIZE_SMALL(struct aml_resource_end_tag),
182
183 /* Large descriptors */
184
185 0,
186 ACPI_AML_SIZE_LARGE(struct aml_resource_memory24),
187 ACPI_AML_SIZE_LARGE(struct aml_resource_generic_register),
188 0,
189 ACPI_AML_SIZE_LARGE(struct aml_resource_vendor_large),
190 ACPI_AML_SIZE_LARGE(struct aml_resource_memory32),
191 ACPI_AML_SIZE_LARGE(struct aml_resource_fixed_memory32),
192 ACPI_AML_SIZE_LARGE(struct aml_resource_address32),
193 ACPI_AML_SIZE_LARGE(struct aml_resource_address16),
194 ACPI_AML_SIZE_LARGE(struct aml_resource_extended_irq),
195 ACPI_AML_SIZE_LARGE(struct aml_resource_address64),
196 ACPI_AML_SIZE_LARGE(struct aml_resource_extended_address64)
197};
198
199/*
200 * Resource types, used to validate the resource length field.
201 * The length of fixed-length types must match exactly, variable
202 * lengths must meet the minimum required length, etc.
203 * Zero indicates a reserved (and therefore invalid) resource type.
204 */
205static const u8 acpi_gbl_resource_types[] = {
206 /* Small descriptors */
207
208 0,
209 0,
210 0,
211 0,
212 ACPI_SMALL_VARIABLE_LENGTH,
213 ACPI_FIXED_LENGTH,
214 ACPI_SMALL_VARIABLE_LENGTH,
215 ACPI_FIXED_LENGTH,
216 ACPI_FIXED_LENGTH,
217 ACPI_FIXED_LENGTH,
218 0,
219 0,
220 0,
221 0,
222 ACPI_VARIABLE_LENGTH,
223 ACPI_FIXED_LENGTH,
224
225 /* Large descriptors */
226
227 0,
228 ACPI_FIXED_LENGTH,
229 ACPI_FIXED_LENGTH,
230 0,
231 ACPI_VARIABLE_LENGTH,
232 ACPI_FIXED_LENGTH,
233 ACPI_FIXED_LENGTH,
234 ACPI_VARIABLE_LENGTH,
235 ACPI_VARIABLE_LENGTH,
236 ACPI_VARIABLE_LENGTH,
237 ACPI_VARIABLE_LENGTH,
238 ACPI_FIXED_LENGTH
239};
240
241/*******************************************************************************
242 *
243 * FUNCTION: acpi_ut_walk_aml_resources
244 *
245 * PARAMETERS: Aml - Pointer to the raw AML resource template
246 * aml_length - Length of the entire template
247 * user_function - Called once for each descriptor found. If
248 * NULL, a pointer to the end_tag is returned
249 * Context - Passed to user_function
250 *
251 * RETURN: Status
252 *
253 * DESCRIPTION: Walk a raw AML resource list(buffer). User function called
254 * once for each resource found.
255 *
256 ******************************************************************************/
257
258acpi_status
259acpi_ut_walk_aml_resources(u8 * aml,
260 acpi_size aml_length,
261 acpi_walk_aml_callback user_function, void **context)
262{
263 acpi_status status;
264 u8 *end_aml;
265 u8 resource_index;
266 u32 length;
267 u32 offset = 0;
268
269 ACPI_FUNCTION_TRACE(ut_walk_aml_resources);
270
271 /* The absolute minimum resource template is one end_tag descriptor */
272
273 if (aml_length < sizeof(struct aml_resource_end_tag)) {
274 return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG);
275 }
276
277 /* Point to the end of the resource template buffer */
278
279 end_aml = aml + aml_length;
280
281 /* Walk the byte list, abort on any invalid descriptor type or length */
282
283 while (aml < end_aml) {
284
285 /* Validate the Resource Type and Resource Length */
286
287 status = acpi_ut_validate_resource(aml, &resource_index);
288 if (ACPI_FAILURE(status)) {
289 return_ACPI_STATUS(status);
290 }
291
292 /* Get the length of this descriptor */
293
294 length = acpi_ut_get_descriptor_length(aml);
295
296 /* Invoke the user function */
297
298 if (user_function) {
299 status =
300 user_function(aml, length, offset, resource_index,
301 context);
302 if (ACPI_FAILURE(status)) {
303 return (status);
304 }
305 }
306
307 /* An end_tag descriptor terminates this resource template */
308
309 if (acpi_ut_get_resource_type(aml) ==
310 ACPI_RESOURCE_NAME_END_TAG) {
311 /*
312 * There must be at least one more byte in the buffer for
313 * the 2nd byte of the end_tag
314 */
315 if ((aml + 1) >= end_aml) {
316 return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG);
317 }
318
319 /* Return the pointer to the end_tag if requested */
320
321 if (!user_function) {
322 *context = aml;
323 }
324
325 /* Normal exit */
326
327 return_ACPI_STATUS(AE_OK);
328 }
329
330 aml += length;
331 offset += length;
332 }
333
334 /* Did not find an end_tag descriptor */
335
336 return (AE_AML_NO_RESOURCE_END_TAG);
337}
338
339/*******************************************************************************
340 *
341 * FUNCTION: acpi_ut_validate_resource
342 *
343 * PARAMETERS: Aml - Pointer to the raw AML resource descriptor
344 * return_index - Where the resource index is returned. NULL
345 * if the index is not required.
346 *
347 * RETURN: Status, and optionally the Index into the global resource tables
348 *
349 * DESCRIPTION: Validate an AML resource descriptor by checking the Resource
350 * Type and Resource Length. Returns an index into the global
351 * resource information/dispatch tables for later use.
352 *
353 ******************************************************************************/
354
355acpi_status acpi_ut_validate_resource(void *aml, u8 * return_index)
356{
357 u8 resource_type;
358 u8 resource_index;
359 acpi_rs_length resource_length;
360 acpi_rs_length minimum_resource_length;
361
362 ACPI_FUNCTION_ENTRY();
363
364 /*
365 * 1) Validate the resource_type field (Byte 0)
366 */
367 resource_type = ACPI_GET8(aml);
368
369 /*
370 * Byte 0 contains the descriptor name (Resource Type)
371 * Examine the large/small bit in the resource header
372 */
373 if (resource_type & ACPI_RESOURCE_NAME_LARGE) {
374
375 /* Verify the large resource type (name) against the max */
376
377 if (resource_type > ACPI_RESOURCE_NAME_LARGE_MAX) {
378 return (AE_AML_INVALID_RESOURCE_TYPE);
379 }
380
381 /*
382 * Large Resource Type -- bits 6:0 contain the name
383 * Translate range 0x80-0x8B to index range 0x10-0x1B
384 */
385 resource_index = (u8) (resource_type - 0x70);
386 } else {
387 /*
388 * Small Resource Type -- bits 6:3 contain the name
389 * Shift range to index range 0x00-0x0F
390 */
391 resource_index = (u8)
392 ((resource_type & ACPI_RESOURCE_NAME_SMALL_MASK) >> 3);
393 }
394
395 /* Check validity of the resource type, zero indicates name is invalid */
396
397 if (!acpi_gbl_resource_types[resource_index]) {
398 return (AE_AML_INVALID_RESOURCE_TYPE);
399 }
400
401 /*
402 * 2) Validate the resource_length field. This ensures that the length
403 * is at least reasonable, and guarantees that it is non-zero.
404 */
405 resource_length = acpi_ut_get_resource_length(aml);
406 minimum_resource_length = acpi_gbl_resource_aml_sizes[resource_index];
407
408 /* Validate based upon the type of resource - fixed length or variable */
409
410 switch (acpi_gbl_resource_types[resource_index]) {
411 case ACPI_FIXED_LENGTH:
412
413 /* Fixed length resource, length must match exactly */
414
415 if (resource_length != minimum_resource_length) {
416 return (AE_AML_BAD_RESOURCE_LENGTH);
417 }
418 break;
419
420 case ACPI_VARIABLE_LENGTH:
421
422 /* Variable length resource, length must be at least the minimum */
423
424 if (resource_length < minimum_resource_length) {
425 return (AE_AML_BAD_RESOURCE_LENGTH);
426 }
427 break;
428
429 case ACPI_SMALL_VARIABLE_LENGTH:
430
431 /* Small variable length resource, length can be (Min) or (Min-1) */
432
433 if ((resource_length > minimum_resource_length) ||
434 (resource_length < (minimum_resource_length - 1))) {
435 return (AE_AML_BAD_RESOURCE_LENGTH);
436 }
437 break;
438
439 default:
440
441 /* Shouldn't happen (because of validation earlier), but be sure */
442
443 return (AE_AML_INVALID_RESOURCE_TYPE);
444 }
445
446 /* Optionally return the resource table index */
447
448 if (return_index) {
449 *return_index = resource_index;
450 }
451
452 return (AE_OK);
453}
454
455/*******************************************************************************
456 *
457 * FUNCTION: acpi_ut_get_resource_type
458 *
459 * PARAMETERS: Aml - Pointer to the raw AML resource descriptor
460 *
461 * RETURN: The Resource Type with no extraneous bits (except the
462 * Large/Small descriptor bit -- this is left alone)
463 *
464 * DESCRIPTION: Extract the Resource Type/Name from the first byte of
465 * a resource descriptor.
466 *
467 ******************************************************************************/
468
469u8 acpi_ut_get_resource_type(void *aml)
470{
471 ACPI_FUNCTION_ENTRY();
472
473 /*
474 * Byte 0 contains the descriptor name (Resource Type)
475 * Examine the large/small bit in the resource header
476 */
477 if (ACPI_GET8(aml) & ACPI_RESOURCE_NAME_LARGE) {
478
479 /* Large Resource Type -- bits 6:0 contain the name */
480
481 return (ACPI_GET8(aml));
482 } else {
483 /* Small Resource Type -- bits 6:3 contain the name */
484
485 return ((u8) (ACPI_GET8(aml) & ACPI_RESOURCE_NAME_SMALL_MASK));
486 }
487}
488
489/*******************************************************************************
490 *
491 * FUNCTION: acpi_ut_get_resource_length
492 *
493 * PARAMETERS: Aml - Pointer to the raw AML resource descriptor
494 *
495 * RETURN: Byte Length
496 *
497 * DESCRIPTION: Get the "Resource Length" of a raw AML descriptor. By
498 * definition, this does not include the size of the descriptor
499 * header or the length field itself.
500 *
501 ******************************************************************************/
502
503u16 acpi_ut_get_resource_length(void *aml)
504{
505 acpi_rs_length resource_length;
506
507 ACPI_FUNCTION_ENTRY();
508
509 /*
510 * Byte 0 contains the descriptor name (Resource Type)
511 * Examine the large/small bit in the resource header
512 */
513 if (ACPI_GET8(aml) & ACPI_RESOURCE_NAME_LARGE) {
514
515 /* Large Resource type -- bytes 1-2 contain the 16-bit length */
516
517 ACPI_MOVE_16_TO_16(&resource_length, ACPI_ADD_PTR(u8, aml, 1));
518
519 } else {
520 /* Small Resource type -- bits 2:0 of byte 0 contain the length */
521
522 resource_length = (u16) (ACPI_GET8(aml) &
523 ACPI_RESOURCE_NAME_SMALL_LENGTH_MASK);
524 }
525
526 return (resource_length);
527}
528
529/*******************************************************************************
530 *
531 * FUNCTION: acpi_ut_get_resource_header_length
532 *
533 * PARAMETERS: Aml - Pointer to the raw AML resource descriptor
534 *
535 * RETURN: Length of the AML header (depends on large/small descriptor)
536 *
537 * DESCRIPTION: Get the length of the header for this resource.
538 *
539 ******************************************************************************/
540
541u8 acpi_ut_get_resource_header_length(void *aml)
542{
543 ACPI_FUNCTION_ENTRY();
544
545 /* Examine the large/small bit in the resource header */
546
547 if (ACPI_GET8(aml) & ACPI_RESOURCE_NAME_LARGE) {
548 return (sizeof(struct aml_resource_large_header));
549 } else {
550 return (sizeof(struct aml_resource_small_header));
551 }
552}
553
554/*******************************************************************************
555 *
556 * FUNCTION: acpi_ut_get_descriptor_length
557 *
558 * PARAMETERS: Aml - Pointer to the raw AML resource descriptor
559 *
560 * RETURN: Byte length
561 *
562 * DESCRIPTION: Get the total byte length of a raw AML descriptor, including the
563 * length of the descriptor header and the length field itself.
564 * Used to walk descriptor lists.
565 *
566 ******************************************************************************/
567
568u32 acpi_ut_get_descriptor_length(void *aml)
569{
570 ACPI_FUNCTION_ENTRY();
571
572 /*
573 * Get the Resource Length (does not include header length) and add
574 * the header length (depends on if this is a small or large resource)
575 */
576 return (acpi_ut_get_resource_length(aml) +
577 acpi_ut_get_resource_header_length(aml));
578}
579
580/*******************************************************************************
581 *
582 * FUNCTION: acpi_ut_get_resource_end_tag
583 *
584 * PARAMETERS: obj_desc - The resource template buffer object
585 * end_tag - Where the pointer to the end_tag is returned
586 *
587 * RETURN: Status, pointer to the end tag
588 *
589 * DESCRIPTION: Find the end_tag resource descriptor in an AML resource template
590 * Note: allows a buffer length of zero.
591 *
592 ******************************************************************************/
593
594acpi_status
595acpi_ut_get_resource_end_tag(union acpi_operand_object * obj_desc,
596 u8 ** end_tag)
597{
598 acpi_status status;
599
600 ACPI_FUNCTION_TRACE(ut_get_resource_end_tag);
601
602 /* Allow a buffer length of zero */
603
604 if (!obj_desc->buffer.length) {
605 *end_tag = obj_desc->buffer.pointer;
606 return_ACPI_STATUS(AE_OK);
607 }
608
609 /* Validate the template and get a pointer to the end_tag */
610
611 status = acpi_ut_walk_aml_resources(obj_desc->buffer.pointer,
612 obj_desc->buffer.length, NULL,
613 (void **)end_tag);
614
615 return_ACPI_STATUS(status);
616}
diff --git a/drivers/acpi/acpica/utstate.c b/drivers/acpi/acpica/utstate.c
new file mode 100644
index 00000000000..54c3461e2f2
--- /dev/null
+++ b/drivers/acpi/acpica/utstate.c
@@ -0,0 +1,347 @@
1/*******************************************************************************
2 *
3 * Module Name: utstate - state object support procedures
4 *
5 ******************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46
47#define _COMPONENT ACPI_UTILITIES
48ACPI_MODULE_NAME("utstate")
49
50/*******************************************************************************
51 *
52 * FUNCTION: acpi_ut_create_pkg_state_and_push
53 *
54 * PARAMETERS: Object - Object to be added to the new state
55 * Action - Increment/Decrement
56 * state_list - List the state will be added to
57 *
58 * RETURN: Status
59 *
60 * DESCRIPTION: Create a new state and push it
61 *
62 ******************************************************************************/
63acpi_status
64acpi_ut_create_pkg_state_and_push(void *internal_object,
65 void *external_object,
66 u16 index,
67 union acpi_generic_state **state_list)
68{
69 union acpi_generic_state *state;
70
71 ACPI_FUNCTION_ENTRY();
72
73 state =
74 acpi_ut_create_pkg_state(internal_object, external_object, index);
75 if (!state) {
76 return (AE_NO_MEMORY);
77 }
78
79 acpi_ut_push_generic_state(state_list, state);
80 return (AE_OK);
81}
82
83/*******************************************************************************
84 *
85 * FUNCTION: acpi_ut_push_generic_state
86 *
87 * PARAMETERS: list_head - Head of the state stack
88 * State - State object to push
89 *
90 * RETURN: None
91 *
92 * DESCRIPTION: Push a state object onto a state stack
93 *
94 ******************************************************************************/
95
96void
97acpi_ut_push_generic_state(union acpi_generic_state **list_head,
98 union acpi_generic_state *state)
99{
100 ACPI_FUNCTION_TRACE(ut_push_generic_state);
101
102 /* Push the state object onto the front of the list (stack) */
103
104 state->common.next = *list_head;
105 *list_head = state;
106
107 return_VOID;
108}
109
110/*******************************************************************************
111 *
112 * FUNCTION: acpi_ut_pop_generic_state
113 *
114 * PARAMETERS: list_head - Head of the state stack
115 *
116 * RETURN: The popped state object
117 *
118 * DESCRIPTION: Pop a state object from a state stack
119 *
120 ******************************************************************************/
121
122union acpi_generic_state *acpi_ut_pop_generic_state(union acpi_generic_state
123 **list_head)
124{
125 union acpi_generic_state *state;
126
127 ACPI_FUNCTION_TRACE(ut_pop_generic_state);
128
129 /* Remove the state object at the head of the list (stack) */
130
131 state = *list_head;
132 if (state) {
133
134 /* Update the list head */
135
136 *list_head = state->common.next;
137 }
138
139 return_PTR(state);
140}
141
142/*******************************************************************************
143 *
144 * FUNCTION: acpi_ut_create_generic_state
145 *
146 * PARAMETERS: None
147 *
148 * RETURN: The new state object. NULL on failure.
149 *
150 * DESCRIPTION: Create a generic state object. Attempt to obtain one from
151 * the global state cache; If none available, create a new one.
152 *
153 ******************************************************************************/
154
155union acpi_generic_state *acpi_ut_create_generic_state(void)
156{
157 union acpi_generic_state *state;
158
159 ACPI_FUNCTION_ENTRY();
160
161 state = acpi_os_acquire_object(acpi_gbl_state_cache);
162 if (state) {
163
164 /* Initialize */
165 memset(state, 0, sizeof(union acpi_generic_state));
166 state->common.descriptor_type = ACPI_DESC_TYPE_STATE;
167 }
168
169 return (state);
170}
171
172/*******************************************************************************
173 *
174 * FUNCTION: acpi_ut_create_thread_state
175 *
176 * PARAMETERS: None
177 *
178 * RETURN: New Thread State. NULL on failure
179 *
180 * DESCRIPTION: Create a "Thread State" - a flavor of the generic state used
181 * to track per-thread info during method execution
182 *
183 ******************************************************************************/
184
185struct acpi_thread_state *acpi_ut_create_thread_state(void)
186{
187 union acpi_generic_state *state;
188
189 ACPI_FUNCTION_TRACE(ut_create_thread_state);
190
191 /* Create the generic state object */
192
193 state = acpi_ut_create_generic_state();
194 if (!state) {
195 return_PTR(NULL);
196 }
197
198 /* Init fields specific to the update struct */
199
200 state->common.descriptor_type = ACPI_DESC_TYPE_STATE_THREAD;
201 state->thread.thread_id = acpi_os_get_thread_id();
202
203 /* Check for invalid thread ID - zero is very bad, it will break things */
204
205 if (!state->thread.thread_id) {
206 ACPI_ERROR((AE_INFO, "Invalid zero ID from AcpiOsGetThreadId"));
207 state->thread.thread_id = (acpi_thread_id) 1;
208 }
209
210 return_PTR((struct acpi_thread_state *)state);
211}
212
213/*******************************************************************************
214 *
215 * FUNCTION: acpi_ut_create_update_state
216 *
217 * PARAMETERS: Object - Initial Object to be installed in the state
218 * Action - Update action to be performed
219 *
220 * RETURN: New state object, null on failure
221 *
222 * DESCRIPTION: Create an "Update State" - a flavor of the generic state used
223 * to update reference counts and delete complex objects such
224 * as packages.
225 *
226 ******************************************************************************/
227
228union acpi_generic_state *acpi_ut_create_update_state(union acpi_operand_object
229 *object, u16 action)
230{
231 union acpi_generic_state *state;
232
233 ACPI_FUNCTION_TRACE_PTR(ut_create_update_state, object);
234
235 /* Create the generic state object */
236
237 state = acpi_ut_create_generic_state();
238 if (!state) {
239 return_PTR(NULL);
240 }
241
242 /* Init fields specific to the update struct */
243
244 state->common.descriptor_type = ACPI_DESC_TYPE_STATE_UPDATE;
245 state->update.object = object;
246 state->update.value = action;
247
248 return_PTR(state);
249}
250
251/*******************************************************************************
252 *
253 * FUNCTION: acpi_ut_create_pkg_state
254 *
255 * PARAMETERS: Object - Initial Object to be installed in the state
256 * Action - Update action to be performed
257 *
258 * RETURN: New state object, null on failure
259 *
260 * DESCRIPTION: Create a "Package State"
261 *
262 ******************************************************************************/
263
264union acpi_generic_state *acpi_ut_create_pkg_state(void *internal_object,
265 void *external_object,
266 u16 index)
267{
268 union acpi_generic_state *state;
269
270 ACPI_FUNCTION_TRACE_PTR(ut_create_pkg_state, internal_object);
271
272 /* Create the generic state object */
273
274 state = acpi_ut_create_generic_state();
275 if (!state) {
276 return_PTR(NULL);
277 }
278
279 /* Init fields specific to the update struct */
280
281 state->common.descriptor_type = ACPI_DESC_TYPE_STATE_PACKAGE;
282 state->pkg.source_object = (union acpi_operand_object *)internal_object;
283 state->pkg.dest_object = external_object;
284 state->pkg.index = index;
285 state->pkg.num_packages = 1;
286
287 return_PTR(state);
288}
289
290/*******************************************************************************
291 *
292 * FUNCTION: acpi_ut_create_control_state
293 *
294 * PARAMETERS: None
295 *
296 * RETURN: New state object, null on failure
297 *
298 * DESCRIPTION: Create a "Control State" - a flavor of the generic state used
299 * to support nested IF/WHILE constructs in the AML.
300 *
301 ******************************************************************************/
302
303union acpi_generic_state *acpi_ut_create_control_state(void)
304{
305 union acpi_generic_state *state;
306
307 ACPI_FUNCTION_TRACE(ut_create_control_state);
308
309 /* Create the generic state object */
310
311 state = acpi_ut_create_generic_state();
312 if (!state) {
313 return_PTR(NULL);
314 }
315
316 /* Init fields specific to the control struct */
317
318 state->common.descriptor_type = ACPI_DESC_TYPE_STATE_CONTROL;
319 state->common.state = ACPI_CONTROL_CONDITIONAL_EXECUTING;
320
321 return_PTR(state);
322}
323
324/*******************************************************************************
325 *
326 * FUNCTION: acpi_ut_delete_generic_state
327 *
328 * PARAMETERS: State - The state object to be deleted
329 *
330 * RETURN: None
331 *
332 * DESCRIPTION: Release a state object to the state cache. NULL state objects
333 * are ignored.
334 *
335 ******************************************************************************/
336
337void acpi_ut_delete_generic_state(union acpi_generic_state *state)
338{
339 ACPI_FUNCTION_TRACE(ut_delete_generic_state);
340
341 /* Ignore null state */
342
343 if (state) {
344 (void)acpi_os_release_object(acpi_gbl_state_cache, state);
345 }
346 return_VOID;
347}
diff --git a/drivers/acpi/acpica/utxface.c b/drivers/acpi/acpica/utxface.c
new file mode 100644
index 00000000000..5b27724a274
--- /dev/null
+++ b/drivers/acpi/acpica/utxface.c
@@ -0,0 +1,512 @@
1/******************************************************************************
2 *
3 * Module Name: utxface - External interfaces for "global" ACPI functions
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2008, Intel Corp.
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#include <acpi/acpi.h>
45#include <acpi/accommon.h>
46#include <acpi/acevents.h>
47#include <acpi/acnamesp.h>
48#include <acpi/acdebug.h>
49#include <acpi/actables.h>
50
51#define _COMPONENT ACPI_UTILITIES
52ACPI_MODULE_NAME("utxface")
53
54#ifndef ACPI_ASL_COMPILER
55/*******************************************************************************
56 *
57 * FUNCTION: acpi_initialize_subsystem
58 *
59 * PARAMETERS: None
60 *
61 * RETURN: Status
62 *
63 * DESCRIPTION: Initializes all global variables. This is the first function
64 * called, so any early initialization belongs here.
65 *
66 ******************************************************************************/
67acpi_status __init acpi_initialize_subsystem(void)
68{
69 acpi_status status;
70
71 ACPI_FUNCTION_TRACE(acpi_initialize_subsystem);
72
73 acpi_gbl_startup_flags = ACPI_SUBSYSTEM_INITIALIZE;
74 ACPI_DEBUG_EXEC(acpi_ut_init_stack_ptr_trace());
75
76 /* Initialize the OS-Dependent layer */
77
78 status = acpi_os_initialize();
79 if (ACPI_FAILURE(status)) {
80 ACPI_EXCEPTION((AE_INFO, status, "During OSL initialization"));
81 return_ACPI_STATUS(status);
82 }
83
84 /* Initialize all globals used by the subsystem */
85
86 status = acpi_ut_init_globals();
87 if (ACPI_FAILURE(status)) {
88 ACPI_EXCEPTION((AE_INFO, status,
89 "During initialization of globals"));
90 return_ACPI_STATUS(status);
91 }
92
93 /* Create the default mutex objects */
94
95 status = acpi_ut_mutex_initialize();
96 if (ACPI_FAILURE(status)) {
97 ACPI_EXCEPTION((AE_INFO, status,
98 "During Global Mutex creation"));
99 return_ACPI_STATUS(status);
100 }
101
102 /*
103 * Initialize the namespace manager and
104 * the root of the namespace tree
105 */
106 status = acpi_ns_root_initialize();
107 if (ACPI_FAILURE(status)) {
108 ACPI_EXCEPTION((AE_INFO, status,
109 "During Namespace initialization"));
110 return_ACPI_STATUS(status);
111 }
112
113 /* If configured, initialize the AML debugger */
114
115 ACPI_DEBUGGER_EXEC(status = acpi_db_initialize());
116 return_ACPI_STATUS(status);
117}
118
119/*******************************************************************************
120 *
121 * FUNCTION: acpi_enable_subsystem
122 *
123 * PARAMETERS: Flags - Init/enable Options
124 *
125 * RETURN: Status
126 *
127 * DESCRIPTION: Completes the subsystem initialization including hardware.
128 * Puts system into ACPI mode if it isn't already.
129 *
130 ******************************************************************************/
131acpi_status acpi_enable_subsystem(u32 flags)
132{
133 acpi_status status = AE_OK;
134
135 ACPI_FUNCTION_TRACE(acpi_enable_subsystem);
136
137 /* Enable ACPI mode */
138
139 if (!(flags & ACPI_NO_ACPI_ENABLE)) {
140 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
141 "[Init] Going into ACPI mode\n"));
142
143 acpi_gbl_original_mode = acpi_hw_get_mode();
144
145 status = acpi_enable();
146 if (ACPI_FAILURE(status)) {
147 ACPI_WARNING((AE_INFO, "AcpiEnable failed"));
148 return_ACPI_STATUS(status);
149 }
150 }
151
152 /*
153 * Obtain a permanent mapping for the FACS. This is required for the
154 * Global Lock and the Firmware Waking Vector
155 */
156 status = acpi_tb_initialize_facs();
157 if (ACPI_FAILURE(status)) {
158 ACPI_WARNING((AE_INFO, "Could not map the FACS table"));
159 return_ACPI_STATUS(status);
160 }
161
162 /*
163 * Install the default op_region handlers. These are installed unless
164 * other handlers have already been installed via the
165 * install_address_space_handler interface.
166 */
167 if (!(flags & ACPI_NO_ADDRESS_SPACE_INIT)) {
168 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
169 "[Init] Installing default address space handlers\n"));
170
171 status = acpi_ev_install_region_handlers();
172 if (ACPI_FAILURE(status)) {
173 return_ACPI_STATUS(status);
174 }
175 }
176
177 /*
178 * Initialize ACPI Event handling (Fixed and General Purpose)
179 *
180 * Note1: We must have the hardware and events initialized before we can
181 * execute any control methods safely. Any control method can require
182 * ACPI hardware support, so the hardware must be fully initialized before
183 * any method execution!
184 *
185 * Note2: Fixed events are initialized and enabled here. GPEs are
186 * initialized, but cannot be enabled until after the hardware is
187 * completely initialized (SCI and global_lock activated)
188 */
189 if (!(flags & ACPI_NO_EVENT_INIT)) {
190 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
191 "[Init] Initializing ACPI events\n"));
192
193 status = acpi_ev_initialize_events();
194 if (ACPI_FAILURE(status)) {
195 return_ACPI_STATUS(status);
196 }
197 }
198
199 /*
200 * Install the SCI handler and Global Lock handler. This completes the
201 * hardware initialization.
202 */
203 if (!(flags & ACPI_NO_HANDLER_INIT)) {
204 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
205 "[Init] Installing SCI/GL handlers\n"));
206
207 status = acpi_ev_install_xrupt_handlers();
208 if (ACPI_FAILURE(status)) {
209 return_ACPI_STATUS(status);
210 }
211 }
212
213 return_ACPI_STATUS(status);
214}
215
216ACPI_EXPORT_SYMBOL(acpi_enable_subsystem)
217
218/*******************************************************************************
219 *
220 * FUNCTION: acpi_initialize_objects
221 *
222 * PARAMETERS: Flags - Init/enable Options
223 *
224 * RETURN: Status
225 *
226 * DESCRIPTION: Completes namespace initialization by initializing device
227 * objects and executing AML code for Regions, buffers, etc.
228 *
229 ******************************************************************************/
230acpi_status acpi_initialize_objects(u32 flags)
231{
232 acpi_status status = AE_OK;
233
234 ACPI_FUNCTION_TRACE(acpi_initialize_objects);
235
236 /*
237 * Run all _REG methods
238 *
239 * Note: Any objects accessed by the _REG methods will be automatically
240 * initialized, even if they contain executable AML (see the call to
241 * acpi_ns_initialize_objects below).
242 */
243 if (!(flags & ACPI_NO_ADDRESS_SPACE_INIT)) {
244 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
245 "[Init] Executing _REG OpRegion methods\n"));
246
247 status = acpi_ev_initialize_op_regions();
248 if (ACPI_FAILURE(status)) {
249 return_ACPI_STATUS(status);
250 }
251 }
252
253 /*
254 * Initialize the objects that remain uninitialized. This runs the
255 * executable AML that may be part of the declaration of these objects:
256 * operation_regions, buffer_fields, Buffers, and Packages.
257 */
258 if (!(flags & ACPI_NO_OBJECT_INIT)) {
259 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
260 "[Init] Completing Initialization of ACPI Objects\n"));
261
262 status = acpi_ns_initialize_objects();
263 if (ACPI_FAILURE(status)) {
264 return_ACPI_STATUS(status);
265 }
266 }
267
268 /*
269 * Initialize all device objects in the namespace. This runs the device
270 * _STA and _INI methods.
271 */
272 if (!(flags & ACPI_NO_DEVICE_INIT)) {
273 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
274 "[Init] Initializing ACPI Devices\n"));
275
276 status = acpi_ns_initialize_devices();
277 if (ACPI_FAILURE(status)) {
278 return_ACPI_STATUS(status);
279 }
280 }
281
282 /*
283 * Complete the GPE initialization for the GPE blocks defined in the FADT
284 * (GPE block 0 and 1).
285 *
286 * Note1: This is where the _PRW methods are executed for the GPEs. These
287 * methods can only be executed after the SCI and Global Lock handlers are
288 * installed and initialized.
289 *
290 * Note2: Currently, there seems to be no need to run the _REG methods
291 * before execution of the _PRW methods and enabling of the GPEs.
292 */
293 if (!(flags & ACPI_NO_EVENT_INIT)) {
294 status = acpi_ev_install_fadt_gpes();
295 if (ACPI_FAILURE(status))
296 return (status);
297 }
298
299 /*
300 * Empty the caches (delete the cached objects) on the assumption that
301 * the table load filled them up more than they will be at runtime --
302 * thus wasting non-paged memory.
303 */
304 status = acpi_purge_cached_objects();
305
306 acpi_gbl_startup_flags |= ACPI_INITIALIZED_OK;
307 return_ACPI_STATUS(status);
308}
309
310ACPI_EXPORT_SYMBOL(acpi_initialize_objects)
311
312#endif
313/*******************************************************************************
314 *
315 * FUNCTION: acpi_terminate
316 *
317 * PARAMETERS: None
318 *
319 * RETURN: Status
320 *
321 * DESCRIPTION: Shutdown the ACPI subsystem. Release all resources.
322 *
323 ******************************************************************************/
324acpi_status acpi_terminate(void)
325{
326 acpi_status status;
327
328 ACPI_FUNCTION_TRACE(acpi_terminate);
329
330 /* Terminate the AML Debugger if present */
331
332 ACPI_DEBUGGER_EXEC(acpi_gbl_db_terminate_threads = TRUE);
333
334 /* Shutdown and free all resources */
335
336 acpi_ut_subsystem_shutdown();
337
338 /* Free the mutex objects */
339
340 acpi_ut_mutex_terminate();
341
342#ifdef ACPI_DEBUGGER
343
344 /* Shut down the debugger */
345
346 acpi_db_terminate();
347#endif
348
349 /* Now we can shutdown the OS-dependent layer */
350
351 status = acpi_os_terminate();
352 return_ACPI_STATUS(status);
353}
354
355ACPI_EXPORT_SYMBOL(acpi_terminate)
356#ifndef ACPI_ASL_COMPILER
357#ifdef ACPI_FUTURE_USAGE
358/*******************************************************************************
359 *
360 * FUNCTION: acpi_subsystem_status
361 *
362 * PARAMETERS: None
363 *
364 * RETURN: Status of the ACPI subsystem
365 *
366 * DESCRIPTION: Other drivers that use the ACPI subsystem should call this
367 * before making any other calls, to ensure the subsystem
368 * initialized successfully.
369 *
370 ******************************************************************************/
371acpi_status acpi_subsystem_status(void)
372{
373
374 if (acpi_gbl_startup_flags & ACPI_INITIALIZED_OK) {
375 return (AE_OK);
376 } else {
377 return (AE_ERROR);
378 }
379}
380
381ACPI_EXPORT_SYMBOL(acpi_subsystem_status)
382
383/*******************************************************************************
384 *
385 * FUNCTION: acpi_get_system_info
386 *
387 * PARAMETERS: out_buffer - A buffer to receive the resources for the
388 * device
389 *
390 * RETURN: Status - the status of the call
391 *
392 * DESCRIPTION: This function is called to get information about the current
393 * state of the ACPI subsystem. It will return system information
394 * in the out_buffer.
395 *
396 * If the function fails an appropriate status will be returned
397 * and the value of out_buffer is undefined.
398 *
399 ******************************************************************************/
400acpi_status acpi_get_system_info(struct acpi_buffer * out_buffer)
401{
402 struct acpi_system_info *info_ptr;
403 acpi_status status;
404
405 ACPI_FUNCTION_TRACE(acpi_get_system_info);
406
407 /* Parameter validation */
408
409 status = acpi_ut_validate_buffer(out_buffer);
410 if (ACPI_FAILURE(status)) {
411 return_ACPI_STATUS(status);
412 }
413
414 /* Validate/Allocate/Clear caller buffer */
415
416 status =
417 acpi_ut_initialize_buffer(out_buffer,
418 sizeof(struct acpi_system_info));
419 if (ACPI_FAILURE(status)) {
420 return_ACPI_STATUS(status);
421 }
422
423 /*
424 * Populate the return buffer
425 */
426 info_ptr = (struct acpi_system_info *)out_buffer->pointer;
427
428 info_ptr->acpi_ca_version = ACPI_CA_VERSION;
429
430 /* System flags (ACPI capabilities) */
431
432 info_ptr->flags = ACPI_SYS_MODE_ACPI;
433
434 /* Timer resolution - 24 or 32 bits */
435
436 if (acpi_gbl_FADT.flags & ACPI_FADT_32BIT_TIMER) {
437 info_ptr->timer_resolution = 24;
438 } else {
439 info_ptr->timer_resolution = 32;
440 }
441
442 /* Clear the reserved fields */
443
444 info_ptr->reserved1 = 0;
445 info_ptr->reserved2 = 0;
446
447 /* Current debug levels */
448
449 info_ptr->debug_layer = acpi_dbg_layer;
450 info_ptr->debug_level = acpi_dbg_level;
451
452 return_ACPI_STATUS(AE_OK);
453}
454
455ACPI_EXPORT_SYMBOL(acpi_get_system_info)
456
457/*****************************************************************************
458 *
459 * FUNCTION: acpi_install_initialization_handler
460 *
461 * PARAMETERS: Handler - Callback procedure
462 * Function - Not (currently) used, see below
463 *
464 * RETURN: Status
465 *
466 * DESCRIPTION: Install an initialization handler
467 *
468 * TBD: When a second function is added, must save the Function also.
469 *
470 ****************************************************************************/
471acpi_status
472acpi_install_initialization_handler(acpi_init_handler handler, u32 function)
473{
474
475 if (!handler) {
476 return (AE_BAD_PARAMETER);
477 }
478
479 if (acpi_gbl_init_handler) {
480 return (AE_ALREADY_EXISTS);
481 }
482
483 acpi_gbl_init_handler = handler;
484 return AE_OK;
485}
486
487ACPI_EXPORT_SYMBOL(acpi_install_initialization_handler)
488#endif /* ACPI_FUTURE_USAGE */
489/*****************************************************************************
490 *
491 * FUNCTION: acpi_purge_cached_objects
492 *
493 * PARAMETERS: None
494 *
495 * RETURN: Status
496 *
497 * DESCRIPTION: Empty all caches (delete the cached objects)
498 *
499 ****************************************************************************/
500acpi_status acpi_purge_cached_objects(void)
501{
502 ACPI_FUNCTION_TRACE(acpi_purge_cached_objects);
503
504 (void)acpi_os_purge_cache(acpi_gbl_state_cache);
505 (void)acpi_os_purge_cache(acpi_gbl_operand_cache);
506 (void)acpi_os_purge_cache(acpi_gbl_ps_node_cache);
507 (void)acpi_os_purge_cache(acpi_gbl_ps_node_ext_cache);
508 return_ACPI_STATUS(AE_OK);
509}
510
511ACPI_EXPORT_SYMBOL(acpi_purge_cached_objects)
512#endif