Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/bp/bp
[sfrench/cifs-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 - 2009, 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 #include "acpredef.h"
49
50 #define _COMPONENT          ACPI_NAMESPACE
51 ACPI_MODULE_NAME("nsrepair")
52
53 /*******************************************************************************
54  *
55  * FUNCTION:    acpi_ns_repair_object
56  *
57  * PARAMETERS:  Data                - Pointer to validation data structure
58  *              expected_btypes     - Object types expected
59  *              package_index       - Index of object within parent package (if
60  *                                    applicable - ACPI_NOT_PACKAGE_ELEMENT
61  *                                    otherwise)
62  *              return_object_ptr   - Pointer to the object returned from the
63  *                                    evaluation of a method or object
64  *
65  * RETURN:      Status. AE_OK if repair was successful.
66  *
67  * DESCRIPTION: Attempt to repair/convert a return object of a type that was
68  *              not expected.
69  *
70  ******************************************************************************/
71 acpi_status
72 acpi_ns_repair_object(struct acpi_predefined_data *data,
73                       u32 expected_btypes,
74                       u32 package_index,
75                       union acpi_operand_object **return_object_ptr)
76 {
77         union acpi_operand_object *return_object = *return_object_ptr;
78         union acpi_operand_object *new_object;
79         acpi_size length;
80         acpi_status status;
81
82         /*
83          * At this point, we know that the type of the returned object was not
84          * one of the expected types for this predefined name. Attempt to
85          * repair the object. Only a limited number of repairs are possible.
86          */
87         switch (return_object->common.type) {
88         case ACPI_TYPE_BUFFER:
89
90                 /* Does the method/object legally return a string? */
91
92                 if (!(expected_btypes & ACPI_RTYPE_STRING)) {
93                         return (AE_AML_OPERAND_TYPE);
94                 }
95
96                 /*
97                  * Have a Buffer, expected a String, convert. Use a to_string
98                  * conversion, no transform performed on the buffer data. The best
99                  * example of this is the _BIF method, where the string data from
100                  * the battery is often (incorrectly) returned as buffer object(s).
101                  */
102                 length = 0;
103                 while ((length < return_object->buffer.length) &&
104                        (return_object->buffer.pointer[length])) {
105                         length++;
106                 }
107
108                 /* Allocate a new string object */
109
110                 new_object = acpi_ut_create_string_object(length);
111                 if (!new_object) {
112                         return (AE_NO_MEMORY);
113                 }
114
115                 /*
116                  * Copy the raw buffer data with no transform. String is already NULL
117                  * terminated at Length+1.
118                  */
119                 ACPI_MEMCPY(new_object->string.pointer,
120                             return_object->buffer.pointer, length);
121                 break;
122
123         case ACPI_TYPE_INTEGER:
124
125                 /* 1) Does the method/object legally return a buffer? */
126
127                 if (expected_btypes & ACPI_RTYPE_BUFFER) {
128                         /*
129                          * Convert the Integer to a packed-byte buffer. _MAT needs
130                          * this sometimes, if a read has been performed on a Field
131                          * object that is less than or equal to the global integer
132                          * size (32 or 64 bits).
133                          */
134                         status =
135                             acpi_ex_convert_to_buffer(return_object,
136                                                       &new_object);
137                         if (ACPI_FAILURE(status)) {
138                                 return (status);
139                         }
140                 }
141
142                 /* 2) Does the method/object legally return a string? */
143
144                 else if (expected_btypes & ACPI_RTYPE_STRING) {
145                         /*
146                          * The only supported Integer-to-String conversion is to convert
147                          * an integer of value 0 to a NULL string. The last element of
148                          * _BIF and _BIX packages occasionally need this fix.
149                          */
150                         if (return_object->integer.value != 0) {
151                                 return (AE_AML_OPERAND_TYPE);
152                         }
153
154                         /* Allocate a new NULL string object */
155
156                         new_object = acpi_ut_create_string_object(0);
157                         if (!new_object) {
158                                 return (AE_NO_MEMORY);
159                         }
160                 } else {
161                         return (AE_AML_OPERAND_TYPE);
162                 }
163                 break;
164
165         default:
166
167                 /* We cannot repair this object */
168
169                 return (AE_AML_OPERAND_TYPE);
170         }
171
172         /* Object was successfully repaired */
173
174         /*
175          * If the original object is a package element, we need to:
176          * 1. Set the reference count of the new object to match the
177          *    reference count of the old object.
178          * 2. Decrement the reference count of the original object.
179          */
180         if (package_index != ACPI_NOT_PACKAGE_ELEMENT) {
181                 new_object->common.reference_count =
182                     return_object->common.reference_count;
183
184                 if (return_object->common.reference_count > 1) {
185                         return_object->common.reference_count--;
186                 }
187
188                 ACPI_INFO_PREDEFINED((AE_INFO, data->pathname, data->node_flags,
189                                       "Converted %s to expected %s at index %u",
190                                       acpi_ut_get_object_type_name
191                                       (return_object),
192                                       acpi_ut_get_object_type_name(new_object),
193                                       package_index));
194         } else {
195                 ACPI_INFO_PREDEFINED((AE_INFO, data->pathname, data->node_flags,
196                                       "Converted %s to expected %s",
197                                       acpi_ut_get_object_type_name
198                                       (return_object),
199                                       acpi_ut_get_object_type_name
200                                       (new_object)));
201         }
202
203         /* Delete old object, install the new return object */
204
205         acpi_ut_remove_reference(return_object);
206         *return_object_ptr = new_object;
207         data->flags |= ACPI_OBJECT_REPAIRED;
208         return (AE_OK);
209 }
210
211 /*******************************************************************************
212  *
213  * FUNCTION:    acpi_ns_repair_package_list
214  *
215  * PARAMETERS:  Data                - Pointer to validation data structure
216  *              obj_desc_ptr        - Pointer to the object to repair. The new
217  *                                    package object is returned here,
218  *                                    overwriting the old object.
219  *
220  * RETURN:      Status, new object in *obj_desc_ptr
221  *
222  * DESCRIPTION: Repair a common problem with objects that are defined to return
223  *              a variable-length Package of Packages. If the variable-length
224  *              is one, some BIOS code mistakenly simply declares a single
225  *              Package instead of a Package with one sub-Package. This
226  *              function attempts to repair this error by wrapping a Package
227  *              object around the original Package, creating the correct
228  *              Package with one sub-Package.
229  *
230  *              Names that can be repaired in this manner include:
231  *              _ALR, _CSD, _HPX, _MLS, _PRT, _PSS, _TRT, TSS
232  *
233  ******************************************************************************/
234
235 acpi_status
236 acpi_ns_repair_package_list(struct acpi_predefined_data *data,
237                             union acpi_operand_object **obj_desc_ptr)
238 {
239         union acpi_operand_object *pkg_obj_desc;
240
241         /*
242          * Create the new outer package and populate it. The new package will
243          * have a single element, the lone subpackage.
244          */
245         pkg_obj_desc = acpi_ut_create_package_object(1);
246         if (!pkg_obj_desc) {
247                 return (AE_NO_MEMORY);
248         }
249
250         pkg_obj_desc->package.elements[0] = *obj_desc_ptr;
251
252         /* Return the new object in the object pointer */
253
254         *obj_desc_ptr = pkg_obj_desc;
255         data->flags |= ACPI_OBJECT_REPAIRED;
256
257         ACPI_INFO_PREDEFINED((AE_INFO, data->pathname, data->node_flags,
258                               "Repaired Incorrectly formed Package"));
259
260         return (AE_OK);
261 }