diff options
author | Len Brown <len.brown@intel.com> | 2009-01-09 00:13:17 -0500 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2009-01-09 03:30:47 -0500 |
commit | 95b482a8d31116f3f5c2a5089569393234d06385 (patch) | |
tree | f32aec8673a285a9d188948be97af3034ee06e93 /drivers/acpi/executer | |
parent | 6620e0c49f577454b772fb381543d60ae53eb885 (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/executer')
24 files changed, 0 insertions, 12598 deletions
diff --git a/drivers/acpi/executer/Makefile b/drivers/acpi/executer/Makefile deleted file mode 100644 index e09998aa012f..000000000000 --- a/drivers/acpi/executer/Makefile +++ /dev/null | |||
@@ -1,10 +0,0 @@ | |||
1 | # | ||
2 | # Makefile for all Linux ACPI interpreter subdirectories | ||
3 | # | ||
4 | |||
5 | obj-y := exconfig.o exfield.o exnames.o exoparg6.o exresolv.o exstorob.o\ | ||
6 | exconvrt.o exfldio.o exoparg1.o exprep.o exresop.o exsystem.o\ | ||
7 | excreate.o exmisc.o exoparg2.o exregion.o exstore.o exutils.o \ | ||
8 | exdump.o exmutex.o exoparg3.o exresnte.o exstoren.o | ||
9 | |||
10 | EXTRA_CFLAGS += $(ACPI_CFLAGS) | ||
diff --git a/drivers/acpi/executer/exconfig.c b/drivers/acpi/executer/exconfig.c deleted file mode 100644 index be32d0105fe2..000000000000 --- a/drivers/acpi/executer/exconfig.c +++ /dev/null | |||
@@ -1,536 +0,0 @@ | |||
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 | ||
52 | ACPI_MODULE_NAME("exconfig") | ||
53 | |||
54 | /* Local prototypes */ | ||
55 | static acpi_status | ||
56 | acpi_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 | |||
75 | static acpi_status | ||
76 | acpi_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 | |||
125 | acpi_status | ||
126 | acpi_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, ¶meter_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 | |||
276 | acpi_status | ||
277 | acpi_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 | |||
487 | acpi_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/executer/exconvrt.c b/drivers/acpi/executer/exconvrt.c deleted file mode 100644 index caeead439e8c..000000000000 --- a/drivers/acpi/executer/exconvrt.c +++ /dev/null | |||
@@ -1,692 +0,0 @@ | |||
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 | ||
50 | ACPI_MODULE_NAME("exconvrt") | ||
51 | |||
52 | /* Local prototypes */ | ||
53 | static u32 | ||
54 | acpi_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 | |||
72 | acpi_status | ||
73 | acpi_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 | |||
200 | acpi_status | ||
201 | acpi_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 | |||
288 | static u32 | ||
289 | acpi_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 | |||
399 | acpi_status | ||
400 | acpi_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 | |||
575 | acpi_status | ||
576 | acpi_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/executer/excreate.c b/drivers/acpi/executer/excreate.c deleted file mode 100644 index 5aa65a214fc2..000000000000 --- a/drivers/acpi/executer/excreate.c +++ /dev/null | |||
@@ -1,522 +0,0 @@ | |||
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 | ||
51 | ACPI_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 | ******************************************************************************/ | ||
64 | acpi_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 | |||
170 | acpi_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 | |||
222 | acpi_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 | |||
279 | acpi_status | ||
280 | acpi_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 | |||
366 | acpi_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 | |||
413 | acpi_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 | |||
460 | acpi_status | ||
461 | acpi_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/executer/exdump.c b/drivers/acpi/executer/exdump.c deleted file mode 100644 index 8241b9eff6c1..000000000000 --- a/drivers/acpi/executer/exdump.c +++ /dev/null | |||
@@ -1,1060 +0,0 @@ | |||
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 | ||
51 | ACPI_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 */ | ||
58 | static void acpi_ex_out_string(char *title, char *value); | ||
59 | |||
60 | static void acpi_ex_out_pointer(char *title, void *value); | ||
61 | |||
62 | static void | ||
63 | acpi_ex_dump_object(union acpi_operand_object *obj_desc, | ||
64 | struct acpi_exdump_info *info); | ||
65 | |||
66 | static void acpi_ex_dump_reference_obj(union acpi_operand_object *obj_desc); | ||
67 | |||
68 | static void | ||
69 | acpi_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 | |||
81 | static 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 | |||
86 | static 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 | |||
93 | static 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 | |||
101 | static 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 | |||
109 | static 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 | |||
118 | static 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 | |||
123 | static 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 | |||
134 | static 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 | |||
143 | static 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 | |||
153 | static 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 | |||
165 | static 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 | |||
177 | static 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 | |||
186 | static 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 | |||
193 | static 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 | |||
199 | static 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 | |||
208 | static 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 | |||
217 | static 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 | |||
228 | static 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 | |||
239 | static 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 | |||
247 | static 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 | |||
255 | static 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 | |||
270 | static 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 | |||
280 | static 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 | |||
325 | static void | ||
326 | acpi_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 | |||
448 | void 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 | |||
760 | void | ||
761 | acpi_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 | |||
804 | static void acpi_ex_out_string(char *title, char *value) | ||
805 | { | ||
806 | acpi_os_printf("%20s : %s\n", title, value); | ||
807 | } | ||
808 | |||
809 | static 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 | |||
825 | void 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 | |||
857 | static 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 | |||
915 | static void | ||
916 | acpi_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 | |||
1010 | void | ||
1011 | acpi_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/executer/exfield.c b/drivers/acpi/executer/exfield.c deleted file mode 100644 index 7b6df031039d..000000000000 --- a/drivers/acpi/executer/exfield.c +++ /dev/null | |||
@@ -1,340 +0,0 @@ | |||
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 | ||
50 | ACPI_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 | ******************************************************************************/ | ||
66 | acpi_status | ||
67 | acpi_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 | |||
207 | acpi_status | ||
208 | acpi_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/executer/exfldio.c b/drivers/acpi/executer/exfldio.c deleted file mode 100644 index 33cd17a1064f..000000000000 --- a/drivers/acpi/executer/exfldio.c +++ /dev/null | |||
@@ -1,961 +0,0 @@ | |||
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 | ||
52 | ACPI_MODULE_NAME("exfldio") | ||
53 | |||
54 | /* Local prototypes */ | ||
55 | static acpi_status | ||
56 | acpi_ex_field_datum_io(union acpi_operand_object *obj_desc, | ||
57 | u32 field_datum_byte_offset, | ||
58 | acpi_integer * value, u32 read_write); | ||
59 | |||
60 | static u8 | ||
61 | acpi_ex_register_overflow(union acpi_operand_object *obj_desc, | ||
62 | acpi_integer value); | ||
63 | |||
64 | static acpi_status | ||
65 | acpi_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 | |||
84 | static acpi_status | ||
85 | acpi_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 | |||
224 | acpi_status | ||
225 | acpi_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 | |||
316 | static u8 | ||
317 | acpi_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 | |||
360 | static acpi_status | ||
361 | acpi_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 | |||
569 | acpi_status | ||
570 | acpi_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 | ¤t_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 | |||
673 | acpi_status | ||
674 | acpi_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 | |||
799 | acpi_status | ||
800 | acpi_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/executer/exmisc.c b/drivers/acpi/executer/exmisc.c deleted file mode 100644 index e445463de8a9..000000000000 --- a/drivers/acpi/executer/exmisc.c +++ /dev/null | |||
@@ -1,726 +0,0 @@ | |||
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 | ||
52 | ACPI_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 | ******************************************************************************/ | ||
68 | acpi_status | ||
69 | acpi_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 | |||
158 | acpi_status | ||
159 | acpi_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 | |||
243 | acpi_status | ||
244 | acpi_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 | |||
412 | acpi_integer | ||
413 | acpi_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 | |||
499 | acpi_status | ||
500 | acpi_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 | |||
561 | acpi_status | ||
562 | acpi_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/executer/exmutex.c b/drivers/acpi/executer/exmutex.c deleted file mode 100644 index f86bcee8d656..000000000000 --- a/drivers/acpi/executer/exmutex.c +++ /dev/null | |||
@@ -1,474 +0,0 @@ | |||
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 | ||
51 | ACPI_MODULE_NAME("exmutex") | ||
52 | |||
53 | /* Local prototypes */ | ||
54 | static void | ||
55 | acpi_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 | |||
70 | void 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 | |||
104 | static void | ||
105 | acpi_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 | |||
151 | acpi_status | ||
152 | acpi_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 | |||
215 | acpi_status | ||
216 | acpi_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 | |||
292 | acpi_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 | |||
347 | acpi_status | ||
348 | acpi_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 | |||
436 | void 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/executer/exnames.c b/drivers/acpi/executer/exnames.c deleted file mode 100644 index 12d3513531e1..000000000000 --- a/drivers/acpi/executer/exnames.c +++ /dev/null | |||
@@ -1,436 +0,0 @@ | |||
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 | ||
51 | ACPI_MODULE_NAME("exnames") | ||
52 | |||
53 | /* Local prototypes */ | ||
54 | static char *acpi_ex_allocate_name_string(u32 prefix_count, u32 num_name_segs); | ||
55 | |||
56 | static acpi_status | ||
57 | acpi_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 | |||
75 | static 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 | |||
159 | static 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 | |||
244 | acpi_status | ||
245 | acpi_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/executer/exoparg1.c b/drivers/acpi/executer/exoparg1.c deleted file mode 100644 index 52d78b8622be..000000000000 --- a/drivers/acpi/executer/exoparg1.c +++ /dev/null | |||
@@ -1,1050 +0,0 @@ | |||
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 | ||
54 | ACPI_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 | ******************************************************************************/ | ||
88 | acpi_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 | |||
148 | acpi_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 | |||
214 | acpi_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 | |||
256 | acpi_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 | |||
585 | acpi_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/executer/exoparg2.c b/drivers/acpi/executer/exoparg2.c deleted file mode 100644 index b01980df1365..000000000000 --- a/drivers/acpi/executer/exoparg2.c +++ /dev/null | |||
@@ -1,605 +0,0 @@ | |||
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 | ||
52 | ACPI_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 | ******************************************************************************/ | ||
89 | acpi_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 | |||
183 | acpi_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 | |||
281 | acpi_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 | |||
514 | acpi_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/executer/exoparg3.c b/drivers/acpi/executer/exoparg3.c deleted file mode 100644 index 26dbd5c2c1da..000000000000 --- a/drivers/acpi/executer/exoparg3.c +++ /dev/null | |||
@@ -1,273 +0,0 @@ | |||
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 | ||
52 | ACPI_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 | ******************************************************************************/ | ||
86 | acpi_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 | |||
145 | acpi_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/executer/exoparg6.c b/drivers/acpi/executer/exoparg6.c deleted file mode 100644 index bbbba504979f..000000000000 --- a/drivers/acpi/executer/exoparg6.c +++ /dev/null | |||
@@ -1,341 +0,0 @@ | |||
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 | ||
52 | ACPI_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 */ | ||
76 | static u8 | ||
77 | acpi_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 | |||
97 | static u8 | ||
98 | acpi_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 | |||
216 | acpi_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/executer/exprep.c b/drivers/acpi/executer/exprep.c deleted file mode 100644 index 8f2baa934e95..000000000000 --- a/drivers/acpi/executer/exprep.c +++ /dev/null | |||
@@ -1,590 +0,0 @@ | |||
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 | ||
52 | ACPI_MODULE_NAME("exprep") | ||
53 | |||
54 | /* Local prototypes */ | ||
55 | static u32 | ||
56 | acpi_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 | |||
61 | static u32 | ||
62 | acpi_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 | |||
87 | static u32 | ||
88 | acpi_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 | |||
224 | static u32 | ||
225 | acpi_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 | |||
316 | acpi_status | ||
317 | acpi_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 | |||
413 | acpi_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/executer/exregion.c b/drivers/acpi/executer/exregion.c deleted file mode 100644 index ceb269e45aba..000000000000 --- a/drivers/acpi/executer/exregion.c +++ /dev/null | |||
@@ -1,499 +0,0 @@ | |||
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 | ||
50 | ACPI_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 | ******************************************************************************/ | ||
69 | acpi_status | ||
70 | acpi_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 | |||
275 | acpi_status | ||
276 | acpi_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 | |||
334 | acpi_status | ||
335 | acpi_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 | |||
409 | acpi_status | ||
410 | acpi_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 | |||
441 | acpi_status | ||
442 | acpi_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 | |||
473 | acpi_status | ||
474 | acpi_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/executer/exresnte.c b/drivers/acpi/executer/exresnte.c deleted file mode 100644 index 77df6e490e70..000000000000 --- a/drivers/acpi/executer/exresnte.c +++ /dev/null | |||
@@ -1,278 +0,0 @@ | |||
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 | ||
52 | ACPI_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 | ******************************************************************************/ | ||
79 | acpi_status | ||
80 | acpi_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/executer/exresolv.c b/drivers/acpi/executer/exresolv.c deleted file mode 100644 index 42adde01bc93..000000000000 --- a/drivers/acpi/executer/exresolv.c +++ /dev/null | |||
@@ -1,551 +0,0 @@ | |||
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 | ||
53 | ACPI_MODULE_NAME("exresolv") | ||
54 | |||
55 | /* Local prototypes */ | ||
56 | static acpi_status | ||
57 | acpi_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 | |||
75 | acpi_status | ||
76 | acpi_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 | |||
137 | static acpi_status | ||
138 | acpi_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 | |||
336 | acpi_status | ||
337 | acpi_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/executer/exresop.c b/drivers/acpi/executer/exresop.c deleted file mode 100644 index 7602eaf5c479..000000000000 --- a/drivers/acpi/executer/exresop.c +++ /dev/null | |||
@@ -1,701 +0,0 @@ | |||
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 | ||
53 | ACPI_MODULE_NAME("exresop") | ||
54 | |||
55 | /* Local prototypes */ | ||
56 | static acpi_status | ||
57 | acpi_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 | |||
74 | static acpi_status | ||
75 | acpi_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 | |||
133 | acpi_status | ||
134 | acpi_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/executer/exstore.c b/drivers/acpi/executer/exstore.c deleted file mode 100644 index 6f5647fdc006..000000000000 --- a/drivers/acpi/executer/exstore.c +++ /dev/null | |||
@@ -1,716 +0,0 @@ | |||
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 | ||
53 | ACPI_MODULE_NAME("exstore") | ||
54 | |||
55 | /* Local prototypes */ | ||
56 | static void | ||
57 | acpi_ex_do_debug_object(union acpi_operand_object *source_desc, | ||
58 | u32 level, u32 index); | ||
59 | |||
60 | static acpi_status | ||
61 | acpi_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 | |||
79 | static void | ||
80 | acpi_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 | |||
292 | acpi_status | ||
293 | acpi_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 | |||
433 | static acpi_status | ||
434 | acpi_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 | |||
598 | acpi_status | ||
599 | acpi_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/executer/exstoren.c b/drivers/acpi/executer/exstoren.c deleted file mode 100644 index ad2047afa463..000000000000 --- a/drivers/acpi/executer/exstoren.c +++ /dev/null | |||
@@ -1,304 +0,0 @@ | |||
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 | ||
52 | ACPI_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 | ******************************************************************************/ | ||
68 | acpi_status | ||
69 | acpi_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 | |||
197 | acpi_status | ||
198 | acpi_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/executer/exstorob.c b/drivers/acpi/executer/exstorob.c deleted file mode 100644 index a48d580d71c2..000000000000 --- a/drivers/acpi/executer/exstorob.c +++ /dev/null | |||
@@ -1,209 +0,0 @@ | |||
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 | ||
50 | ACPI_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 | ******************************************************************************/ | ||
64 | acpi_status | ||
65 | acpi_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 | |||
155 | acpi_status | ||
156 | acpi_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/executer/exsystem.c b/drivers/acpi/executer/exsystem.c deleted file mode 100644 index a25b2c576eb1..000000000000 --- a/drivers/acpi/executer/exsystem.c +++ /dev/null | |||
@@ -1,303 +0,0 @@ | |||
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 | ||
50 | ACPI_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 | ******************************************************************************/ | ||
66 | acpi_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 | |||
112 | acpi_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 | |||
160 | acpi_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 | |||
196 | acpi_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 | |||
225 | acpi_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 | |||
254 | acpi_status | ||
255 | acpi_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 | |||
284 | acpi_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/executer/exutils.c b/drivers/acpi/executer/exutils.c deleted file mode 100644 index 0ecdb70c4980..000000000000 --- a/drivers/acpi/executer/exutils.c +++ /dev/null | |||
@@ -1,421 +0,0 @@ | |||
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 | ||
67 | ACPI_MODULE_NAME("exutils") | ||
68 | |||
69 | /* Local prototypes */ | ||
70 | static 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 | |||
87 | void 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 | |||
117 | void 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 | |||
147 | void 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 | |||
185 | void 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 | |||
213 | void 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 | |||
251 | void 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 | |||
290 | void 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 | |||
330 | static 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, ¤t_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 | |||
370 | void 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 | |||
404 | void 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 | ||