ACPICA: Update all ACPICA copyrights and signons to 2010
[linux-2.6.git] / drivers / acpi / acpica / nsrepair.c
1 /******************************************************************************
2  *
3  * Module Name: nsrepair - Repair for objects returned by predefined methods
4  *
5  *****************************************************************************/
6
7 /*
8  * Copyright (C) 2000 - 2010, 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 "accommon.h"
46 #include "acnamesp.h"
47 #include "acinterp.h"
48
49 #define _COMPONENT          ACPI_NAMESPACE
50 ACPI_MODULE_NAME("nsrepair")
51
52 /*******************************************************************************
53  *
54  * This module attempts to repair or convert objects returned by the
55  * predefined methods to an object type that is expected, as per the ACPI
56  * specification. The need for this code is dictated by the many machines that
57  * return incorrect types for the standard predefined methods. Performing these
58  * conversions here, in one place, eliminates the need for individual ACPI
59  * device drivers to do the same. Note: Most of these conversions are different
60  * than the internal object conversion routines used for implicit object
61  * conversion.
62  *
63  * The following conversions can be performed as necessary:
64  *
65  * Integer -> String
66  * Integer -> Buffer
67  * String  -> Integer
68  * String  -> Buffer
69  * Buffer  -> Integer
70  * Buffer  -> String
71  * Buffer  -> Package of Integers
72  * Package -> Package of one Package
73  *
74  ******************************************************************************/
75 /* Local prototypes */
76 static acpi_status
77 acpi_ns_convert_to_integer(union acpi_operand_object *original_object,
78                            union acpi_operand_object **return_object);
79
80 static acpi_status
81 acpi_ns_convert_to_string(union acpi_operand_object *original_object,
82                           union acpi_operand_object **return_object);
83
84 static acpi_status
85 acpi_ns_convert_to_buffer(union acpi_operand_object *original_object,
86                           union acpi_operand_object **return_object);
87
88 static acpi_status
89 acpi_ns_convert_to_package(union acpi_operand_object *original_object,
90                            union acpi_operand_object **return_object);
91
92 /*******************************************************************************
93  *
94  * FUNCTION:    acpi_ns_repair_object
95  *
96  * PARAMETERS:  Data                - Pointer to validation data structure
97  *              expected_btypes     - Object types expected
98  *              package_index       - Index of object within parent package (if
99  *                                    applicable - ACPI_NOT_PACKAGE_ELEMENT
100  *                                    otherwise)
101  *              return_object_ptr   - Pointer to the object returned from the
102  *                                    evaluation of a method or object
103  *
104  * RETURN:      Status. AE_OK if repair was successful.
105  *
106  * DESCRIPTION: Attempt to repair/convert a return object of a type that was
107  *              not expected.
108  *
109  ******************************************************************************/
110
111 acpi_status
112 acpi_ns_repair_object(struct acpi_predefined_data *data,
113                       u32 expected_btypes,
114                       u32 package_index,
115                       union acpi_operand_object **return_object_ptr)
116 {
117         union acpi_operand_object *return_object = *return_object_ptr;
118         union acpi_operand_object *new_object;
119         acpi_status status;
120
121         ACPI_FUNCTION_NAME(ns_repair_object);
122
123         /*
124          * At this point, we know that the type of the returned object was not
125          * one of the expected types for this predefined name. Attempt to
126          * repair the object by converting it to one of the expected object
127          * types for this predefined name.
128          */
129         if (expected_btypes & ACPI_RTYPE_INTEGER) {
130                 status = acpi_ns_convert_to_integer(return_object, &new_object);
131                 if (ACPI_SUCCESS(status)) {
132                         goto object_repaired;
133                 }
134         }
135         if (expected_btypes & ACPI_RTYPE_STRING) {
136                 status = acpi_ns_convert_to_string(return_object, &new_object);
137                 if (ACPI_SUCCESS(status)) {
138                         goto object_repaired;
139                 }
140         }
141         if (expected_btypes & ACPI_RTYPE_BUFFER) {
142                 status = acpi_ns_convert_to_buffer(return_object, &new_object);
143                 if (ACPI_SUCCESS(status)) {
144                         goto object_repaired;
145                 }
146         }
147         if (expected_btypes & ACPI_RTYPE_PACKAGE) {
148                 status = acpi_ns_convert_to_package(return_object, &new_object);
149                 if (ACPI_SUCCESS(status)) {
150                         goto object_repaired;
151                 }
152         }
153
154         /* We cannot repair this object */
155
156         return (AE_AML_OPERAND_TYPE);
157
158       object_repaired:
159
160         /* Object was successfully repaired */
161
162         /*
163          * If the original object is a package element, we need to:
164          * 1. Set the reference count of the new object to match the
165          *    reference count of the old object.
166          * 2. Decrement the reference count of the original object.
167          */
168         if (package_index != ACPI_NOT_PACKAGE_ELEMENT) {
169                 new_object->common.reference_count =
170                     return_object->common.reference_count;
171
172                 if (return_object->common.reference_count > 1) {
173                         return_object->common.reference_count--;
174                 }
175
176                 ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
177                                   "%s: Converted %s to expected %s at index %u\n",
178                                   data->pathname,
179                                   acpi_ut_get_object_type_name(return_object),
180                                   acpi_ut_get_object_type_name(new_object),
181                                   package_index));
182         } else {
183                 ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
184                                   "%s: Converted %s to expected %s\n",
185                                   data->pathname,
186                                   acpi_ut_get_object_type_name(return_object),
187                                   acpi_ut_get_object_type_name(new_object)));
188         }
189
190         /* Delete old object, install the new return object */
191
192         acpi_ut_remove_reference(return_object);
193         *return_object_ptr = new_object;
194         data->flags |= ACPI_OBJECT_REPAIRED;
195         return (AE_OK);
196 }
197
198 /*******************************************************************************
199  *
200  * FUNCTION:    acpi_ns_convert_to_integer
201  *
202  * PARAMETERS:  original_object     - Object to be converted
203  *              return_object       - Where the new converted object is returned
204  *
205  * RETURN:      Status. AE_OK if conversion was successful.
206  *
207  * DESCRIPTION: Attempt to convert a String/Buffer object to an Integer.
208  *
209  ******************************************************************************/
210
211 static acpi_status
212 acpi_ns_convert_to_integer(union acpi_operand_object *original_object,
213                            union acpi_operand_object **return_object)
214 {
215         union acpi_operand_object *new_object;
216         acpi_status status;
217         u64 value = 0;
218         u32 i;
219
220         switch (original_object->common.type) {
221         case ACPI_TYPE_STRING:
222
223                 /* String-to-Integer conversion */
224
225                 status = acpi_ut_strtoul64(original_object->string.pointer,
226                                            ACPI_ANY_BASE, &value);
227                 if (ACPI_FAILURE(status)) {
228                         return (status);
229                 }
230                 break;
231
232         case ACPI_TYPE_BUFFER:
233
234                 /* Buffer-to-Integer conversion. Max buffer size is 64 bits. */
235
236                 if (original_object->buffer.length > 8) {
237                         return (AE_AML_OPERAND_TYPE);
238                 }
239
240                 /* Extract each buffer byte to create the integer */
241
242                 for (i = 0; i < original_object->buffer.length; i++) {
243                         value |=
244                             ((u64) original_object->buffer.
245                              pointer[i] << (i * 8));
246                 }
247                 break;
248
249         default:
250                 return (AE_AML_OPERAND_TYPE);
251         }
252
253         new_object = acpi_ut_create_integer_object(value);
254         if (!new_object) {
255                 return (AE_NO_MEMORY);
256         }
257
258         *return_object = new_object;
259         return (AE_OK);
260 }
261
262 /*******************************************************************************
263  *
264  * FUNCTION:    acpi_ns_convert_to_string
265  *
266  * PARAMETERS:  original_object     - Object to be converted
267  *              return_object       - Where the new converted object is returned
268  *
269  * RETURN:      Status. AE_OK if conversion was successful.
270  *
271  * DESCRIPTION: Attempt to convert a Integer/Buffer object to a String.
272  *
273  ******************************************************************************/
274
275 static acpi_status
276 acpi_ns_convert_to_string(union acpi_operand_object *original_object,
277                           union acpi_operand_object **return_object)
278 {
279         union acpi_operand_object *new_object;
280         acpi_size length;
281         acpi_status status;
282
283         switch (original_object->common.type) {
284         case ACPI_TYPE_INTEGER:
285                 /*
286                  * Integer-to-String conversion. Commonly, convert
287                  * an integer of value 0 to a NULL string. The last element of
288                  * _BIF and _BIX packages occasionally need this fix.
289                  */
290                 if (original_object->integer.value == 0) {
291
292                         /* Allocate a new NULL string object */
293
294                         new_object = acpi_ut_create_string_object(0);
295                         if (!new_object) {
296                                 return (AE_NO_MEMORY);
297                         }
298                 } else {
299                         status =
300                             acpi_ex_convert_to_string(original_object,
301                                                       &new_object,
302                                                       ACPI_IMPLICIT_CONVERT_HEX);
303                         if (ACPI_FAILURE(status)) {
304                                 return (status);
305                         }
306                 }
307                 break;
308
309         case ACPI_TYPE_BUFFER:
310                 /*
311                  * Buffer-to-String conversion. Use a to_string
312                  * conversion, no transform performed on the buffer data. The best
313                  * example of this is the _BIF method, where the string data from
314                  * the battery is often (incorrectly) returned as buffer object(s).
315                  */
316                 length = 0;
317                 while ((length < original_object->buffer.length) &&
318                        (original_object->buffer.pointer[length])) {
319                         length++;
320                 }
321
322                 /* Allocate a new string object */
323
324                 new_object = acpi_ut_create_string_object(length);
325                 if (!new_object) {
326                         return (AE_NO_MEMORY);
327                 }
328
329                 /*
330                  * Copy the raw buffer data with no transform. String is already NULL
331                  * terminated at Length+1.
332                  */
333                 ACPI_MEMCPY(new_object->string.pointer,
334                             original_object->buffer.pointer, length);
335                 break;
336
337         default:
338                 return (AE_AML_OPERAND_TYPE);
339         }
340
341         *return_object = new_object;
342         return (AE_OK);
343 }
344
345 /*******************************************************************************
346  *
347  * FUNCTION:    acpi_ns_convert_to_buffer
348  *
349  * PARAMETERS:  original_object     - Object to be converted
350  *              return_object       - Where the new converted object is returned
351  *
352  * RETURN:      Status. AE_OK if conversion was successful.
353  *
354  * DESCRIPTION: Attempt to convert a Integer/String/Package object to a Buffer.
355  *
356  ******************************************************************************/
357
358 static acpi_status
359 acpi_ns_convert_to_buffer(union acpi_operand_object *original_object,
360                           union acpi_operand_object **return_object)
361 {
362         union acpi_operand_object *new_object;
363         acpi_status status;
364         union acpi_operand_object **elements;
365         u32 *dword_buffer;
366         u32 count;
367         u32 i;
368
369         switch (original_object->common.type) {
370         case ACPI_TYPE_INTEGER:
371                 /*
372                  * Integer-to-Buffer conversion.
373                  * Convert the Integer to a packed-byte buffer. _MAT and other
374                  * objects need this sometimes, if a read has been performed on a
375                  * Field object that is less than or equal to the global integer
376                  * size (32 or 64 bits).
377                  */
378                 status =
379                     acpi_ex_convert_to_buffer(original_object, &new_object);
380                 if (ACPI_FAILURE(status)) {
381                         return (status);
382                 }
383                 break;
384
385         case ACPI_TYPE_STRING:
386
387                 /* String-to-Buffer conversion. Simple data copy */
388
389                 new_object =
390                     acpi_ut_create_buffer_object(original_object->string.
391                                                  length);
392                 if (!new_object) {
393                         return (AE_NO_MEMORY);
394                 }
395
396                 ACPI_MEMCPY(new_object->buffer.pointer,
397                             original_object->string.pointer,
398                             original_object->string.length);
399                 break;
400
401         case ACPI_TYPE_PACKAGE:
402                 /*
403                  * This case is often seen for predefined names that must return a
404                  * Buffer object with multiple DWORD integers within. For example,
405                  * _FDE and _GTM. The Package can be converted to a Buffer.
406                  */
407
408                 /* All elements of the Package must be integers */
409
410                 elements = original_object->package.elements;
411                 count = original_object->package.count;
412
413                 for (i = 0; i < count; i++) {
414                         if ((!*elements) ||
415                             ((*elements)->common.type != ACPI_TYPE_INTEGER)) {
416                                 return (AE_AML_OPERAND_TYPE);
417                         }
418                         elements++;
419                 }
420
421                 /* Create the new buffer object to replace the Package */
422
423                 new_object = acpi_ut_create_buffer_object(ACPI_MUL_4(count));
424                 if (!new_object) {
425                         return (AE_NO_MEMORY);
426                 }
427
428                 /* Copy the package elements (integers) to the buffer as DWORDs */
429
430                 elements = original_object->package.elements;
431                 dword_buffer = ACPI_CAST_PTR(u32, new_object->buffer.pointer);
432
433                 for (i = 0; i < count; i++) {
434                         *dword_buffer = (u32) (*elements)->integer.value;
435                         dword_buffer++;
436                         elements++;
437                 }
438                 break;
439
440         default:
441                 return (AE_AML_OPERAND_TYPE);
442         }
443
444         *return_object = new_object;
445         return (AE_OK);
446 }
447
448 /*******************************************************************************
449  *
450  * FUNCTION:    acpi_ns_convert_to_package
451  *
452  * PARAMETERS:  original_object     - Object to be converted
453  *              return_object       - Where the new converted object is returned
454  *
455  * RETURN:      Status. AE_OK if conversion was successful.
456  *
457  * DESCRIPTION: Attempt to convert a Buffer object to a Package. Each byte of
458  *              the buffer is converted to a single integer package element.
459  *
460  ******************************************************************************/
461
462 static acpi_status
463 acpi_ns_convert_to_package(union acpi_operand_object *original_object,
464                            union acpi_operand_object **return_object)
465 {
466         union acpi_operand_object *new_object;
467         union acpi_operand_object **elements;
468         u32 length;
469         u8 *buffer;
470
471         switch (original_object->common.type) {
472         case ACPI_TYPE_BUFFER:
473
474                 /* Buffer-to-Package conversion */
475
476                 length = original_object->buffer.length;
477                 new_object = acpi_ut_create_package_object(length);
478                 if (!new_object) {
479                         return (AE_NO_MEMORY);
480                 }
481
482                 /* Convert each buffer byte to an integer package element */
483
484                 elements = new_object->package.elements;
485                 buffer = original_object->buffer.pointer;
486
487                 while (length--) {
488                         *elements =
489                             acpi_ut_create_integer_object((u64) *buffer);
490                         if (!*elements) {
491                                 acpi_ut_remove_reference(new_object);
492                                 return (AE_NO_MEMORY);
493                         }
494                         elements++;
495                         buffer++;
496                 }
497                 break;
498
499         default:
500                 return (AE_AML_OPERAND_TYPE);
501         }
502
503         *return_object = new_object;
504         return (AE_OK);
505 }
506
507 /*******************************************************************************
508  *
509  * FUNCTION:    acpi_ns_repair_package_list
510  *
511  * PARAMETERS:  Data                - Pointer to validation data structure
512  *              obj_desc_ptr        - Pointer to the object to repair. The new
513  *                                    package object is returned here,
514  *                                    overwriting the old object.
515  *
516  * RETURN:      Status, new object in *obj_desc_ptr
517  *
518  * DESCRIPTION: Repair a common problem with objects that are defined to return
519  *              a variable-length Package of Packages. If the variable-length
520  *              is one, some BIOS code mistakenly simply declares a single
521  *              Package instead of a Package with one sub-Package. This
522  *              function attempts to repair this error by wrapping a Package
523  *              object around the original Package, creating the correct
524  *              Package with one sub-Package.
525  *
526  *              Names that can be repaired in this manner include:
527  *              _ALR, _CSD, _HPX, _MLS, _PRT, _PSS, _TRT, TSS
528  *
529  ******************************************************************************/
530
531 acpi_status
532 acpi_ns_repair_package_list(struct acpi_predefined_data *data,
533                             union acpi_operand_object **obj_desc_ptr)
534 {
535         union acpi_operand_object *pkg_obj_desc;
536
537         ACPI_FUNCTION_NAME(ns_repair_package_list);
538
539         /*
540          * Create the new outer package and populate it. The new package will
541          * have a single element, the lone subpackage.
542          */
543         pkg_obj_desc = acpi_ut_create_package_object(1);
544         if (!pkg_obj_desc) {
545                 return (AE_NO_MEMORY);
546         }
547
548         pkg_obj_desc->package.elements[0] = *obj_desc_ptr;
549
550         /* Return the new object in the object pointer */
551
552         *obj_desc_ptr = pkg_obj_desc;
553         data->flags |= ACPI_OBJECT_REPAIRED;
554
555         ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
556                           "%s: Repaired incorrectly formed Package\n",
557                           data->pathname));
558
559         return (AE_OK);
560 }