ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / drivers / acpi / executer / exconvrt.c
1 /******************************************************************************
2  *
3  * Module Name: exconvrt - Object conversion routines
4  *
5  *****************************************************************************/
6
7 /*
8  * Copyright (C) 2000 - 2004, R. Byron Moore
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions, and the following disclaimer,
16  *    without modification.
17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18  *    substantially similar to the "NO WARRANTY" disclaimer below
19  *    ("Disclaimer") and any redistribution must be conditioned upon
20  *    including a substantially similar Disclaimer requirement for further
21  *    binary redistribution.
22  * 3. Neither the names of the above-listed copyright holders nor the names
23  *    of any contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * Alternatively, this software may be distributed under the terms of the
27  * GNU General Public License ("GPL") version 2 as published by the Free
28  * Software Foundation.
29  *
30  * NO WARRANTY
31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41  * POSSIBILITY OF SUCH DAMAGES.
42  */
43
44
45 #include <acpi/acpi.h>
46 #include <acpi/acinterp.h>
47 #include <acpi/amlcode.h>
48
49
50 #define _COMPONENT          ACPI_EXECUTER
51          ACPI_MODULE_NAME    ("exconvrt")
52
53
54 /*******************************************************************************
55  *
56  * FUNCTION:    acpi_ex_convert_to_integer
57  *
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
62  *
63  * RETURN:      Status
64  *
65  * DESCRIPTION: Convert an ACPI Object to an integer.
66  *
67  ******************************************************************************/
68
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)
74 {
75         u32                             i;
76         union acpi_operand_object       *ret_desc;
77         u32                             count;
78         u8                              *pointer;
79         acpi_integer                    result;
80         acpi_status                     status;
81
82
83         ACPI_FUNCTION_TRACE_PTR ("ex_convert_to_integer", obj_desc);
84
85
86         switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
87         case ACPI_TYPE_INTEGER:
88                 *result_desc = obj_desc;
89                 return_ACPI_STATUS (AE_OK);
90
91         case ACPI_TYPE_STRING:
92                 pointer = (u8 *) obj_desc->string.pointer;
93                 count   = obj_desc->string.length;
94                 break;
95
96         case ACPI_TYPE_BUFFER:
97                 pointer = obj_desc->buffer.pointer;
98                 count   = obj_desc->buffer.length;
99                 break;
100
101         default:
102                 return_ACPI_STATUS (AE_TYPE);
103         }
104
105         /*
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.
109          *
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
113          */
114         result = 0;
115
116         /* Transfer no more than an integer's worth of data */
117
118         if (count > acpi_gbl_integer_byte_width) {
119                 count = acpi_gbl_integer_byte_width;
120         }
121
122         /*
123          * String conversion is different than Buffer conversion
124          */
125         switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
126         case ACPI_TYPE_STRING:
127
128                 /*
129                  * Convert string to an integer
130                  * String must be hexadecimal as per the ACPI specification
131                  */
132                 status = acpi_ut_strtoul64 ((char *) pointer, 16, &result);
133                 if (ACPI_FAILURE (status)) {
134                         return_ACPI_STATUS (status);
135                 }
136                 break;
137
138
139         case ACPI_TYPE_BUFFER:
140
141                 /*
142                  * Buffer conversion - we simply grab enough raw data from the
143                  * buffer to fill an integer
144                  */
145                 for (i = 0; i < count; i++) {
146                         /*
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
150                          */
151                         result |= (((acpi_integer) pointer[i]) << (i * 8));
152                 }
153                 break;
154
155
156         default:
157                 /* No other types can get here */
158                 break;
159         }
160
161         /*
162          * Create a new integer
163          */
164         ret_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
165         if (!ret_desc) {
166                 return_ACPI_STATUS (AE_NO_MEMORY);
167         }
168
169         /* Save the Result */
170
171         ret_desc->integer.value = result;
172
173         /*
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.
177          */
178         if (*result_desc == obj_desc) {
179                 if (walk_state->opcode != AML_STORE_OP) {
180                         acpi_ut_remove_reference (obj_desc);
181                 }
182         }
183
184         *result_desc = ret_desc;
185         return_ACPI_STATUS (AE_OK);
186 }
187
188
189 /*******************************************************************************
190  *
191  * FUNCTION:    acpi_ex_convert_to_buffer
192  *
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
197  *
198  * RETURN:      Status
199  *
200  * DESCRIPTION: Convert an ACPI Object to a Buffer
201  *
202  ******************************************************************************/
203
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)
209 {
210         union acpi_operand_object       *ret_desc;
211         u32                             i;
212         u8                              *new_buf;
213
214
215         ACPI_FUNCTION_TRACE_PTR ("ex_convert_to_buffer", obj_desc);
216
217
218         switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
219         case ACPI_TYPE_BUFFER:
220
221                 /* No conversion necessary */
222
223                 *result_desc = obj_desc;
224                 return_ACPI_STATUS (AE_OK);
225
226
227         case ACPI_TYPE_INTEGER:
228
229                 /*
230                  * Create a new Buffer object.
231                  * Need enough space for one integer
232                  */
233                 ret_desc = acpi_ut_create_buffer_object (acpi_gbl_integer_byte_width);
234                 if (!ret_desc) {
235                         return_ACPI_STATUS (AE_NO_MEMORY);
236                 }
237
238                 /* Copy the integer to the buffer */
239
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));
243                 }
244                 break;
245
246
247         case ACPI_TYPE_STRING:
248
249                 /*
250                  * Create a new Buffer object
251                  * Size will be the string length
252                  */
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);
256                 }
257
258                 /* Copy the string to the buffer */
259
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;
264
265
266         default:
267                 return_ACPI_STATUS (AE_TYPE);
268         }
269
270         /* Mark buffer initialized */
271
272         ret_desc->common.flags |= AOPOBJ_DATA_VALID;
273
274         /*
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.
278          */
279         if (*result_desc == obj_desc) {
280                 if (walk_state->opcode != AML_STORE_OP) {
281                         acpi_ut_remove_reference (obj_desc);
282                 }
283         }
284
285         *result_desc = ret_desc;
286         return_ACPI_STATUS (AE_OK);
287 }
288
289
290 /*******************************************************************************
291  *
292  * FUNCTION:    acpi_ex_convert_ascii
293  *
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
298  *
299  * RETURN:      Actual string length
300  *
301  * DESCRIPTION: Convert an ACPI Integer to a hex or decimal string
302  *
303  ******************************************************************************/
304
305 u32
306 acpi_ex_convert_to_ascii (
307         acpi_integer                    integer,
308         u32                             base,
309         u8                              *string,
310         u8                              data_width)
311 {
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;
320
321
322         ACPI_FUNCTION_ENTRY ();
323
324
325         if (data_width < sizeof (acpi_integer)) {
326                 leading_zero = FALSE;
327                 length = data_width;
328         }
329         else {
330                 leading_zero = TRUE;
331                 length = sizeof (acpi_integer);
332         }
333
334         switch (base) {
335         case 10:
336
337                 remainder = 0;
338                 for (i = ACPI_MAX_DECIMAL_DIGITS; i > 0; i--) {
339                         /* Divide by nth factor of 10 */
340
341                         digit = integer;
342                         for (j = 0; j < i; j++) {
343                                 (void) acpi_ut_short_divide (&digit, 10, &digit, &remainder);
344                         }
345
346                         /* Create the decimal digit */
347
348                         if (remainder != 0) {
349                                 leading_zero = FALSE;
350                         }
351
352                         if (!leading_zero) {
353                                 string[k] = (u8) (ACPI_ASCII_ZERO + remainder);
354                                 k++;
355                         }
356                 }
357                 break;
358
359
360         case 16:
361
362                 /* Copy the integer to the buffer */
363
364                 for (i = 0, j = ((length * 2) -1); i < (length * 2); i++, j--) {
365
366                         hex_digit = acpi_ut_hex_to_ascii_char (integer, (j * 4));
367                         if (hex_digit != ACPI_ASCII_ZERO) {
368                                 leading_zero = FALSE;
369                         }
370
371                         if (!leading_zero) {
372                                 string[k] = (u8) hex_digit;
373                                 k++;
374                         }
375                 }
376                 break;
377
378
379         default:
380                 break;
381         }
382
383         /*
384          * Since leading zeros are supressed, we must check for the case where
385          * the integer equals 0
386          *
387          * Finally, null terminate the string and return the length
388          */
389         if (!k) {
390                 string [0] = ACPI_ASCII_ZERO;
391                 k = 1;
392         }
393
394         string [k] = 0;
395         return (k);
396 }
397
398
399 /*******************************************************************************
400  *
401  * FUNCTION:    acpi_ex_convert_to_string
402  *
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
409  *
410  * RETURN:      Status
411  *
412  * DESCRIPTION: Convert an ACPI Object to a string
413  *
414  ******************************************************************************/
415
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)
423 {
424         union acpi_operand_object       *ret_desc;
425         u8                              *new_buf;
426         u8                              *pointer;
427         u32                             string_length;
428         u32                             i;
429
430
431         ACPI_FUNCTION_TRACE_PTR ("ex_convert_to_string", obj_desc);
432
433
434         switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
435         case ACPI_TYPE_STRING:
436
437                 if (max_length >= obj_desc->string.length) {
438                         *result_desc = obj_desc;
439                         return_ACPI_STATUS (AE_OK);
440                 }
441                 else {
442                         /* Must copy the string first and then truncate it */
443
444                         return_ACPI_STATUS (AE_NOT_IMPLEMENTED);
445                 }
446
447
448         case ACPI_TYPE_INTEGER:
449
450                 string_length = acpi_gbl_integer_byte_width * 2;
451                 if (base == 10) {
452                         string_length = ACPI_MAX_DECIMAL_DIGITS;
453                 }
454
455                 /*
456                  * Create a new String
457                  */
458                 ret_desc = acpi_ut_create_internal_object (ACPI_TYPE_STRING);
459                 if (!ret_desc) {
460                         return_ACPI_STATUS (AE_NO_MEMORY);
461                 }
462
463                 /* Need enough space for one ASCII integer plus null terminator */
464
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);
471                 }
472
473                 /* Convert */
474
475                 i = acpi_ex_convert_to_ascii (obj_desc->integer.value, base, new_buf, sizeof (acpi_integer));
476
477                 /* Null terminate at the correct place */
478
479                 if (max_length < i) {
480                         new_buf[max_length] = 0;
481                         ret_desc->string.length = max_length;
482                 }
483                 else {
484                         new_buf [i] = 0;
485                         ret_desc->string.length = i;
486                 }
487
488                 ret_desc->buffer.pointer = new_buf;
489                 break;
490
491
492         case ACPI_TYPE_BUFFER:
493
494                 /* Find the string length */
495
496                 pointer = obj_desc->buffer.pointer;
497                 for (string_length = 0; string_length < obj_desc->buffer.length; string_length++) {
498                         /* Exit on null terminator */
499
500                         if (!pointer[string_length]) {
501                                 break;
502                         }
503                 }
504
505                 if (max_length > ACPI_MAX_STRING_CONVERSION) {
506                         if (string_length > ACPI_MAX_STRING_CONVERSION) {
507                                 return_ACPI_STATUS (AE_AML_STRING_LIMIT);
508                         }
509                 }
510
511                 /*
512                  * Create a new string object
513                  */
514                 ret_desc = acpi_ut_create_internal_object (ACPI_TYPE_STRING);
515                 if (!ret_desc) {
516                         return_ACPI_STATUS (AE_NO_MEMORY);
517                 }
518
519                 /* String length is the lesser of the Max or the actual length */
520
521                 if (max_length < string_length) {
522                         string_length = max_length;
523                 }
524
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);
531                 }
532
533                 /* Copy the appropriate number of buffer characters */
534
535                 ACPI_MEMCPY (new_buf, pointer, string_length);
536
537                 /* Null terminate */
538
539                 new_buf [string_length] = 0;
540                 ret_desc->buffer.pointer = new_buf;
541                 ret_desc->string.length = string_length;
542                 break;
543
544
545         default:
546                 return_ACPI_STATUS (AE_TYPE);
547         }
548
549         /*
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.
553          */
554         if (*result_desc == obj_desc) {
555                 if (walk_state->opcode != AML_STORE_OP) {
556                         acpi_ut_remove_reference (obj_desc);
557                 }
558         }
559
560         *result_desc = ret_desc;
561         return_ACPI_STATUS (AE_OK);
562 }
563
564
565 /*******************************************************************************
566  *
567  * FUNCTION:    acpi_ex_convert_to_target_type
568  *
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
573  *
574  * RETURN:      Status
575  *
576  * DESCRIPTION: Implements "implicit conversion" rules for storing an object.
577  *
578  ******************************************************************************/
579
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)
586 {
587         acpi_status                     status = AE_OK;
588
589
590         ACPI_FUNCTION_TRACE ("ex_convert_to_target_type");
591
592
593         /* Default behavior */
594
595         *result_desc = source_desc;
596
597         /*
598          * If required by the target,
599          * perform implicit conversion on the source before we store it.
600          */
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 */
605
606                 switch (destination_type) {
607                 case ACPI_TYPE_LOCAL_REGION_FIELD:
608                         /*
609                          * Named field can always handle conversions
610                          */
611                         break;
612
613                 default:
614                         /* No conversion allowed for these types */
615
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;
622                         }
623                 }
624                 break;
625
626
627         case ARGI_TARGETREF:
628
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:
634                         /*
635                          * These types require an Integer operand.  We can convert
636                          * a Buffer or a String to an Integer if necessary.
637                          */
638                         status = acpi_ex_convert_to_integer (source_desc, result_desc, walk_state);
639                         break;
640
641
642                 case ACPI_TYPE_STRING:
643
644                         /*
645                          * The operand must be a String.  We can convert an
646                          * Integer or Buffer if necessary
647                          */
648                         status = acpi_ex_convert_to_string (source_desc, result_desc, 16, ACPI_UINT32_MAX, walk_state);
649                         break;
650
651
652                 case ACPI_TYPE_BUFFER:
653
654                         /*
655                          * The operand must be a Buffer.  We can convert an
656                          * Integer or String if necessary
657                          */
658                         status = acpi_ex_convert_to_buffer (source_desc, result_desc, walk_state);
659                         break;
660
661
662                 default:
663                         ACPI_REPORT_ERROR (("Bad destination type during conversion: %X\n",
664                                 destination_type));
665                         status = AE_AML_INTERNAL;
666                         break;
667                 }
668                 break;
669
670
671         case ARGI_REFERENCE:
672                 /*
673                  * create_xxxx_field cases - we are storing the field object into the name
674                  */
675                 break;
676
677
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)));
683
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;
687         }
688
689         /*
690          * Source-to-Target conversion semantics:
691          *
692          * If conversion to the target type cannot be performed, then simply
693          * overwrite the target with the new object and type.
694          */
695         if (status == AE_TYPE) {
696                 status = AE_OK;
697         }
698
699         return_ACPI_STATUS (status);
700 }
701
702