MOXA linux-2.6.x / linux-2.6.9-uc0 from sdlinux-moxaart.tgz
[linux-2.6.9-moxart.git] / drivers / acpi / executer / exconvrt.c
blob04c04e4ae39bcfb9283a4e1ec42ebc39ea758442
1 /******************************************************************************
3 * Module Name: exconvrt - Object conversion routines
5 *****************************************************************************/
7 /*
8 * Copyright (C) 2000 - 2004, R. Byron Moore
9 * All rights reserved.
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.
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.
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.
45 #include <acpi/acpi.h>
46 #include <acpi/acinterp.h>
47 #include <acpi/amlcode.h>
50 #define _COMPONENT ACPI_EXECUTER
51 ACPI_MODULE_NAME ("exconvrt")
54 /*******************************************************************************
56 * FUNCTION: acpi_ex_convert_to_integer
58 * PARAMETERS: obj_desc - Object to be converted. Must be an
59 * Integer, Buffer, or String
60 * result_desc - Where the new Integer object is returned
61 * walk_state - Current method state
63 * RETURN: Status
65 * DESCRIPTION: Convert an ACPI Object to an integer.
67 ******************************************************************************/
69 acpi_status
70 acpi_ex_convert_to_integer (
71 union acpi_operand_object *obj_desc,
72 union acpi_operand_object **result_desc,
73 struct acpi_walk_state *walk_state)
75 u32 i;
76 union acpi_operand_object *ret_desc;
77 u32 count;
78 u8 *pointer;
79 acpi_integer result;
80 acpi_status status;
83 ACPI_FUNCTION_TRACE_PTR ("ex_convert_to_integer", obj_desc);
86 switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
87 case ACPI_TYPE_INTEGER:
88 *result_desc = obj_desc;
89 return_ACPI_STATUS (AE_OK);
91 case ACPI_TYPE_STRING:
92 pointer = (u8 *) obj_desc->string.pointer;
93 count = obj_desc->string.length;
94 break;
96 case ACPI_TYPE_BUFFER:
97 pointer = obj_desc->buffer.pointer;
98 count = obj_desc->buffer.length;
99 break;
101 default:
102 return_ACPI_STATUS (AE_TYPE);
106 * Convert the buffer/string to an integer. Note that both buffers and
107 * strings are treated as raw data - we don't convert ascii to hex for
108 * strings.
110 * There are two terminating conditions for the loop:
111 * 1) The size of an integer has been reached, or
112 * 2) The end of the buffer or string has been reached
114 result = 0;
116 /* Transfer no more than an integer's worth of data */
118 if (count > acpi_gbl_integer_byte_width) {
119 count = acpi_gbl_integer_byte_width;
123 * String conversion is different than Buffer conversion
125 switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
126 case ACPI_TYPE_STRING:
129 * Convert string to an integer
130 * String must be hexadecimal as per the ACPI specification
132 status = acpi_ut_strtoul64 ((char *) pointer, 16, &result);
133 if (ACPI_FAILURE (status)) {
134 return_ACPI_STATUS (status);
136 break;
139 case ACPI_TYPE_BUFFER:
142 * Buffer conversion - we simply grab enough raw data from the
143 * buffer to fill an integer
145 for (i = 0; i < count; i++) {
147 * Get next byte and shift it into the Result.
148 * Little endian is used, meaning that the first byte of the buffer
149 * is the LSB of the integer
151 result |= (((acpi_integer) pointer[i]) << (i * 8));
153 break;
156 default:
157 /* No other types can get here */
158 break;
162 * Create a new integer
164 ret_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
165 if (!ret_desc) {
166 return_ACPI_STATUS (AE_NO_MEMORY);
169 /* Save the Result */
171 ret_desc->integer.value = result;
174 * If we are about to overwrite the original object on the operand stack,
175 * we must remove a reference on the original object because we are
176 * essentially removing it from the stack.
178 if (*result_desc == obj_desc) {
179 if (walk_state->opcode != AML_STORE_OP) {
180 acpi_ut_remove_reference (obj_desc);
184 *result_desc = ret_desc;
185 return_ACPI_STATUS (AE_OK);
189 /*******************************************************************************
191 * FUNCTION: acpi_ex_convert_to_buffer
193 * PARAMETERS: obj_desc - Object to be converted. Must be an
194 * Integer, Buffer, or String
195 * result_desc - Where the new buffer object is returned
196 * walk_state - Current method state
198 * RETURN: Status
200 * DESCRIPTION: Convert an ACPI Object to a Buffer
202 ******************************************************************************/
204 acpi_status
205 acpi_ex_convert_to_buffer (
206 union acpi_operand_object *obj_desc,
207 union acpi_operand_object **result_desc,
208 struct acpi_walk_state *walk_state)
210 union acpi_operand_object *ret_desc;
211 u32 i;
212 u8 *new_buf;
215 ACPI_FUNCTION_TRACE_PTR ("ex_convert_to_buffer", obj_desc);
218 switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
219 case ACPI_TYPE_BUFFER:
221 /* No conversion necessary */
223 *result_desc = obj_desc;
224 return_ACPI_STATUS (AE_OK);
227 case ACPI_TYPE_INTEGER:
230 * Create a new Buffer object.
231 * Need enough space for one integer
233 ret_desc = acpi_ut_create_buffer_object (acpi_gbl_integer_byte_width);
234 if (!ret_desc) {
235 return_ACPI_STATUS (AE_NO_MEMORY);
238 /* Copy the integer to the buffer */
240 new_buf = ret_desc->buffer.pointer;
241 for (i = 0; i < acpi_gbl_integer_byte_width; i++) {
242 new_buf[i] = (u8) (obj_desc->integer.value >> (i * 8));
244 break;
247 case ACPI_TYPE_STRING:
250 * Create a new Buffer object
251 * Size will be the string length
253 ret_desc = acpi_ut_create_buffer_object ((acpi_size) obj_desc->string.length);
254 if (!ret_desc) {
255 return_ACPI_STATUS (AE_NO_MEMORY);
258 /* Copy the string to the buffer */
260 new_buf = ret_desc->buffer.pointer;
261 ACPI_STRNCPY ((char *) new_buf, (char *) obj_desc->string.pointer,
262 obj_desc->string.length);
263 break;
266 default:
267 return_ACPI_STATUS (AE_TYPE);
270 /* Mark buffer initialized */
272 ret_desc->common.flags |= AOPOBJ_DATA_VALID;
275 * If we are about to overwrite the original object on the operand stack,
276 * we must remove a reference on the original object because we are
277 * essentially removing it from the stack.
279 if (*result_desc == obj_desc) {
280 if (walk_state->opcode != AML_STORE_OP) {
281 acpi_ut_remove_reference (obj_desc);
285 *result_desc = ret_desc;
286 return_ACPI_STATUS (AE_OK);
290 /*******************************************************************************
292 * FUNCTION: acpi_ex_convert_ascii
294 * PARAMETERS: Integer - Value to be converted
295 * Base - 10 or 16
296 * String - Where the string is returned
297 * data_width - Size of data item to be converted
299 * RETURN: Actual string length
301 * DESCRIPTION: Convert an ACPI Integer to a hex or decimal string
303 ******************************************************************************/
306 acpi_ex_convert_to_ascii (
307 acpi_integer integer,
308 u32 base,
309 u8 *string,
310 u8 data_width)
312 u32 i;
313 u32 j;
314 u32 k = 0;
315 char hex_digit;
316 acpi_integer digit;
317 u32 remainder;
318 u32 length;
319 u8 leading_zero;
322 ACPI_FUNCTION_ENTRY ();
325 if (data_width < sizeof (acpi_integer)) {
326 leading_zero = FALSE;
327 length = data_width;
329 else {
330 leading_zero = TRUE;
331 length = sizeof (acpi_integer);
334 switch (base) {
335 case 10:
337 remainder = 0;
338 for (i = ACPI_MAX_DECIMAL_DIGITS; i > 0; i--) {
339 /* Divide by nth factor of 10 */
341 digit = integer;
342 for (j = 0; j < i; j++) {
343 (void) acpi_ut_short_divide (&digit, 10, &digit, &remainder);
346 /* Create the decimal digit */
348 if (remainder != 0) {
349 leading_zero = FALSE;
352 if (!leading_zero) {
353 string[k] = (u8) (ACPI_ASCII_ZERO + remainder);
354 k++;
357 break;
360 case 16:
362 /* Copy the integer to the buffer */
364 for (i = 0, j = ((length * 2) -1); i < (length * 2); i++, j--) {
366 hex_digit = acpi_ut_hex_to_ascii_char (integer, (j * 4));
367 if (hex_digit != ACPI_ASCII_ZERO) {
368 leading_zero = FALSE;
371 if (!leading_zero) {
372 string[k] = (u8) hex_digit;
373 k++;
376 break;
379 default:
380 break;
384 * Since leading zeros are supressed, we must check for the case where
385 * the integer equals 0
387 * Finally, null terminate the string and return the length
389 if (!k) {
390 string [0] = ACPI_ASCII_ZERO;
391 k = 1;
394 string [k] = 0;
395 return (k);
399 /*******************************************************************************
401 * FUNCTION: acpi_ex_convert_to_string
403 * PARAMETERS: obj_desc - Object to be converted. Must be an
404 * Integer, Buffer, or String
405 * result_desc - Where the string object is returned
406 * Base - 10 or 16
407 * max_length - Max length of the returned string
408 * walk_state - Current method state
410 * RETURN: Status
412 * DESCRIPTION: Convert an ACPI Object to a string
414 ******************************************************************************/
416 acpi_status
417 acpi_ex_convert_to_string (
418 union acpi_operand_object *obj_desc,
419 union acpi_operand_object **result_desc,
420 u32 base,
421 u32 max_length,
422 struct acpi_walk_state *walk_state)
424 union acpi_operand_object *ret_desc;
425 u8 *new_buf;
426 u8 *pointer;
427 u32 string_length;
428 u32 i;
431 ACPI_FUNCTION_TRACE_PTR ("ex_convert_to_string", obj_desc);
434 switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
435 case ACPI_TYPE_STRING:
437 if (max_length >= obj_desc->string.length) {
438 *result_desc = obj_desc;
439 return_ACPI_STATUS (AE_OK);
441 else {
442 /* Must copy the string first and then truncate it */
444 return_ACPI_STATUS (AE_NOT_IMPLEMENTED);
448 case ACPI_TYPE_INTEGER:
450 string_length = acpi_gbl_integer_byte_width * 2;
451 if (base == 10) {
452 string_length = ACPI_MAX_DECIMAL_DIGITS;
456 * Create a new String
458 ret_desc = acpi_ut_create_internal_object (ACPI_TYPE_STRING);
459 if (!ret_desc) {
460 return_ACPI_STATUS (AE_NO_MEMORY);
463 /* Need enough space for one ASCII integer plus null terminator */
465 new_buf = ACPI_MEM_CALLOCATE ((acpi_size) string_length + 1);
466 if (!new_buf) {
467 ACPI_REPORT_ERROR
468 (("ex_convert_to_string: Buffer allocation failure\n"));
469 acpi_ut_remove_reference (ret_desc);
470 return_ACPI_STATUS (AE_NO_MEMORY);
473 /* Convert */
475 i = acpi_ex_convert_to_ascii (obj_desc->integer.value, base, new_buf, sizeof (acpi_integer));
477 /* Null terminate at the correct place */
479 if (max_length < i) {
480 new_buf[max_length] = 0;
481 ret_desc->string.length = max_length;
483 else {
484 new_buf [i] = 0;
485 ret_desc->string.length = i;
488 ret_desc->buffer.pointer = new_buf;
489 break;
492 case ACPI_TYPE_BUFFER:
494 /* Find the string length */
496 pointer = obj_desc->buffer.pointer;
497 for (string_length = 0; string_length < obj_desc->buffer.length; string_length++) {
498 /* Exit on null terminator */
500 if (!pointer[string_length]) {
501 break;
505 if (max_length > ACPI_MAX_STRING_CONVERSION) {
506 if (string_length > ACPI_MAX_STRING_CONVERSION) {
507 return_ACPI_STATUS (AE_AML_STRING_LIMIT);
512 * Create a new string object
514 ret_desc = acpi_ut_create_internal_object (ACPI_TYPE_STRING);
515 if (!ret_desc) {
516 return_ACPI_STATUS (AE_NO_MEMORY);
519 /* String length is the lesser of the Max or the actual length */
521 if (max_length < string_length) {
522 string_length = max_length;
525 new_buf = ACPI_MEM_CALLOCATE ((acpi_size) string_length + 1);
526 if (!new_buf) {
527 ACPI_REPORT_ERROR
528 (("ex_convert_to_string: Buffer allocation failure\n"));
529 acpi_ut_remove_reference (ret_desc);
530 return_ACPI_STATUS (AE_NO_MEMORY);
533 /* Copy the appropriate number of buffer characters */
535 ACPI_MEMCPY (new_buf, pointer, string_length);
537 /* Null terminate */
539 new_buf [string_length] = 0;
540 ret_desc->buffer.pointer = new_buf;
541 ret_desc->string.length = string_length;
542 break;
545 default:
546 return_ACPI_STATUS (AE_TYPE);
550 * If we are about to overwrite the original object on the operand stack,
551 * we must remove a reference on the original object because we are
552 * essentially removing it from the stack.
554 if (*result_desc == obj_desc) {
555 if (walk_state->opcode != AML_STORE_OP) {
556 acpi_ut_remove_reference (obj_desc);
560 *result_desc = ret_desc;
561 return_ACPI_STATUS (AE_OK);
565 /*******************************************************************************
567 * FUNCTION: acpi_ex_convert_to_target_type
569 * PARAMETERS: destination_type - Current type of the destination
570 * source_desc - Source object to be converted.
571 * result_desc - Where the converted object is returned
572 * walk_state - Current method state
574 * RETURN: Status
576 * DESCRIPTION: Implements "implicit conversion" rules for storing an object.
578 ******************************************************************************/
580 acpi_status
581 acpi_ex_convert_to_target_type (
582 acpi_object_type destination_type,
583 union acpi_operand_object *source_desc,
584 union acpi_operand_object **result_desc,
585 struct acpi_walk_state *walk_state)
587 acpi_status status = AE_OK;
590 ACPI_FUNCTION_TRACE ("ex_convert_to_target_type");
593 /* Default behavior */
595 *result_desc = source_desc;
598 * If required by the target,
599 * perform implicit conversion on the source before we store it.
601 switch (GET_CURRENT_ARG_TYPE (walk_state->op_info->runtime_args)) {
602 case ARGI_SIMPLE_TARGET:
603 case ARGI_FIXED_TARGET:
604 case ARGI_INTEGER_REF: /* Handles Increment, Decrement cases */
606 switch (destination_type) {
607 case ACPI_TYPE_LOCAL_REGION_FIELD:
609 * Named field can always handle conversions
611 break;
613 default:
614 /* No conversion allowed for these types */
616 if (destination_type != ACPI_GET_OBJECT_TYPE (source_desc)) {
617 ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
618 "Explicit operator, will store (%s) over existing type (%s)\n",
619 acpi_ut_get_object_type_name (source_desc),
620 acpi_ut_get_type_name (destination_type)));
621 status = AE_TYPE;
624 break;
627 case ARGI_TARGETREF:
629 switch (destination_type) {
630 case ACPI_TYPE_INTEGER:
631 case ACPI_TYPE_BUFFER_FIELD:
632 case ACPI_TYPE_LOCAL_BANK_FIELD:
633 case ACPI_TYPE_LOCAL_INDEX_FIELD:
635 * These types require an Integer operand. We can convert
636 * a Buffer or a String to an Integer if necessary.
638 status = acpi_ex_convert_to_integer (source_desc, result_desc, walk_state);
639 break;
642 case ACPI_TYPE_STRING:
645 * The operand must be a String. We can convert an
646 * Integer or Buffer if necessary
648 status = acpi_ex_convert_to_string (source_desc, result_desc, 16, ACPI_UINT32_MAX, walk_state);
649 break;
652 case ACPI_TYPE_BUFFER:
655 * The operand must be a Buffer. We can convert an
656 * Integer or String if necessary
658 status = acpi_ex_convert_to_buffer (source_desc, result_desc, walk_state);
659 break;
662 default:
663 ACPI_REPORT_ERROR (("Bad destination type during conversion: %X\n",
664 destination_type));
665 status = AE_AML_INTERNAL;
666 break;
668 break;
671 case ARGI_REFERENCE:
673 * create_xxxx_field cases - we are storing the field object into the name
675 break;
678 default:
679 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
680 "Unknown Target type ID 0x%X Op %s dest_type %s\n",
681 GET_CURRENT_ARG_TYPE (walk_state->op_info->runtime_args),
682 walk_state->op_info->name, acpi_ut_get_type_name (destination_type)));
684 ACPI_REPORT_ERROR (("Bad Target Type (ARGI): %X\n",
685 GET_CURRENT_ARG_TYPE (walk_state->op_info->runtime_args)))
686 status = AE_AML_INTERNAL;
690 * Source-to-Target conversion semantics:
692 * If conversion to the target type cannot be performed, then simply
693 * overwrite the target with the new object and type.
695 if (status == AE_TYPE) {
696 status = AE_OK;
699 return_ACPI_STATUS (status);