aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/acpica/nsrepair.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/acpica/nsrepair.c')
-rw-r--r--drivers/acpi/acpica/nsrepair.c381
1 files changed, 135 insertions, 246 deletions
diff --git a/drivers/acpi/acpica/nsrepair.c b/drivers/acpi/acpica/nsrepair.c
index 9e833353c06a..18f02e4ece01 100644
--- a/drivers/acpi/acpica/nsrepair.c
+++ b/drivers/acpi/acpica/nsrepair.c
@@ -46,6 +46,7 @@
46#include "acnamesp.h" 46#include "acnamesp.h"
47#include "acinterp.h" 47#include "acinterp.h"
48#include "acpredef.h" 48#include "acpredef.h"
49#include "amlresrc.h"
49 50
50#define _COMPONENT ACPI_NAMESPACE 51#define _COMPONENT ACPI_NAMESPACE
51ACPI_MODULE_NAME("nsrepair") 52ACPI_MODULE_NAME("nsrepair")
@@ -71,6 +72,11 @@ ACPI_MODULE_NAME("nsrepair")
71 * Buffer -> String 72 * Buffer -> String
72 * Buffer -> Package of Integers 73 * Buffer -> Package of Integers
73 * Package -> Package of one Package 74 * Package -> Package of one Package
75 *
76 * Additional conversions that are available:
77 * Convert a null return or zero return value to an end_tag descriptor
78 * Convert an ASCII string to a Unicode buffer
79 *
74 * An incorrect standalone object is wrapped with required outer package 80 * An incorrect standalone object is wrapped with required outer package
75 * 81 *
76 * Additional possible repairs: 82 * Additional possible repairs:
@@ -78,21 +84,51 @@ ACPI_MODULE_NAME("nsrepair")
78 * 84 *
79 ******************************************************************************/ 85 ******************************************************************************/
80/* Local prototypes */ 86/* Local prototypes */
81static acpi_status 87static const struct acpi_simple_repair_info *acpi_ns_match_simple_repair(struct
82acpi_ns_convert_to_integer(union acpi_operand_object *original_object, 88 acpi_namespace_node
83 union acpi_operand_object **return_object); 89 *node,
84 90 u32
85static acpi_status 91 return_btype,
86acpi_ns_convert_to_string(union acpi_operand_object *original_object, 92 u32
87 union acpi_operand_object **return_object); 93 package_index);
88 94
89static acpi_status 95/*
90acpi_ns_convert_to_buffer(union acpi_operand_object *original_object, 96 * Special but simple repairs for some names.
91 union acpi_operand_object **return_object); 97 *
98 * 2nd argument: Unexpected types that can be repaired
99 */
100static const struct acpi_simple_repair_info acpi_object_repair_info[] = {
101 /* Resource descriptor conversions */
102
103 {"_CRS",
104 ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING | ACPI_RTYPE_BUFFER |
105 ACPI_RTYPE_NONE,
106 ACPI_NOT_PACKAGE_ELEMENT,
107 acpi_ns_convert_to_resource},
108 {"_DMA",
109 ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING | ACPI_RTYPE_BUFFER |
110 ACPI_RTYPE_NONE,
111 ACPI_NOT_PACKAGE_ELEMENT,
112 acpi_ns_convert_to_resource},
113 {"_PRS",
114 ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING | ACPI_RTYPE_BUFFER |
115 ACPI_RTYPE_NONE,
116 ACPI_NOT_PACKAGE_ELEMENT,
117 acpi_ns_convert_to_resource},
118
119 /* Unicode conversions */
120
121 {"_MLS", ACPI_RTYPE_STRING, 1,
122 acpi_ns_convert_to_unicode},
123 {"_STR", ACPI_RTYPE_STRING | ACPI_RTYPE_BUFFER,
124 ACPI_NOT_PACKAGE_ELEMENT,
125 acpi_ns_convert_to_unicode},
126 {{0, 0, 0, 0}, 0, 0, NULL} /* Table terminator */
127};
92 128
93/******************************************************************************* 129/*******************************************************************************
94 * 130 *
95 * FUNCTION: acpi_ns_repair_object 131 * FUNCTION: acpi_ns_simple_repair
96 * 132 *
97 * PARAMETERS: data - Pointer to validation data structure 133 * PARAMETERS: data - Pointer to validation data structure
98 * expected_btypes - Object types expected 134 * expected_btypes - Object types expected
@@ -110,16 +146,54 @@ acpi_ns_convert_to_buffer(union acpi_operand_object *original_object,
110 ******************************************************************************/ 146 ******************************************************************************/
111 147
112acpi_status 148acpi_status
113acpi_ns_repair_object(struct acpi_predefined_data *data, 149acpi_ns_simple_repair(struct acpi_predefined_data *data,
114 u32 expected_btypes, 150 u32 expected_btypes,
115 u32 package_index, 151 u32 package_index,
116 union acpi_operand_object **return_object_ptr) 152 union acpi_operand_object **return_object_ptr)
117{ 153{
118 union acpi_operand_object *return_object = *return_object_ptr; 154 union acpi_operand_object *return_object = *return_object_ptr;
119 union acpi_operand_object *new_object; 155 union acpi_operand_object *new_object = NULL;
120 acpi_status status; 156 acpi_status status;
157 const struct acpi_simple_repair_info *predefined;
158
159 ACPI_FUNCTION_NAME(ns_simple_repair);
160
161 /*
162 * Special repairs for certain names that are in the repair table.
163 * Check if this name is in the list of repairable names.
164 */
165 predefined = acpi_ns_match_simple_repair(data->node,
166 data->return_btype,
167 package_index);
168 if (predefined) {
169 if (!return_object) {
170 ACPI_WARN_PREDEFINED((AE_INFO, data->pathname,
171 ACPI_WARN_ALWAYS,
172 "Missing expected return value"));
173 }
174
175 status =
176 predefined->object_converter(return_object, &new_object);
177 if (ACPI_FAILURE(status)) {
178
179 /* A fatal error occurred during a conversion */
180
181 ACPI_EXCEPTION((AE_INFO, status,
182 "During return object analysis"));
183 return (status);
184 }
185 if (new_object) {
186 goto object_repaired;
187 }
188 }
121 189
122 ACPI_FUNCTION_NAME(ns_repair_object); 190 /*
191 * Do not perform simple object repair unless the return type is not
192 * expected.
193 */
194 if (data->return_btype & expected_btypes) {
195 return (AE_OK);
196 }
123 197
124 /* 198 /*
125 * At this point, we know that the type of the returned object was not 199 * At this point, we know that the type of the returned object was not
@@ -127,6 +201,24 @@ acpi_ns_repair_object(struct acpi_predefined_data *data,
127 * repair the object by converting it to one of the expected object 201 * repair the object by converting it to one of the expected object
128 * types for this predefined name. 202 * types for this predefined name.
129 */ 203 */
204
205 /*
206 * If there is no return value, check if we require a return value for
207 * this predefined name. Either one return value is expected, or none,
208 * for both methods and other objects.
209 *
210 * Exit now if there is no return object. Warning if one was expected.
211 */
212 if (!return_object) {
213 if (expected_btypes && (!(expected_btypes & ACPI_RTYPE_NONE))) {
214 ACPI_WARN_PREDEFINED((AE_INFO, data->pathname,
215 ACPI_WARN_ALWAYS,
216 "Missing expected return value"));
217
218 return (AE_AML_NO_RETURN_VALUE);
219 }
220 }
221
130 if (expected_btypes & ACPI_RTYPE_INTEGER) { 222 if (expected_btypes & ACPI_RTYPE_INTEGER) {
131 status = acpi_ns_convert_to_integer(return_object, &new_object); 223 status = acpi_ns_convert_to_integer(return_object, &new_object);
132 if (ACPI_SUCCESS(status)) { 224 if (ACPI_SUCCESS(status)) {
@@ -216,254 +308,51 @@ acpi_ns_repair_object(struct acpi_predefined_data *data,
216 return (AE_OK); 308 return (AE_OK);
217} 309}
218 310
219/******************************************************************************* 311/******************************************************************************
220 *
221 * FUNCTION: acpi_ns_convert_to_integer
222 *
223 * PARAMETERS: original_object - Object to be converted
224 * return_object - Where the new converted object is returned
225 *
226 * RETURN: Status. AE_OK if conversion was successful.
227 *
228 * DESCRIPTION: Attempt to convert a String/Buffer object to an Integer.
229 *
230 ******************************************************************************/
231
232static acpi_status
233acpi_ns_convert_to_integer(union acpi_operand_object *original_object,
234 union acpi_operand_object **return_object)
235{
236 union acpi_operand_object *new_object;
237 acpi_status status;
238 u64 value = 0;
239 u32 i;
240
241 switch (original_object->common.type) {
242 case ACPI_TYPE_STRING:
243
244 /* String-to-Integer conversion */
245
246 status = acpi_ut_strtoul64(original_object->string.pointer,
247 ACPI_ANY_BASE, &value);
248 if (ACPI_FAILURE(status)) {
249 return (status);
250 }
251 break;
252
253 case ACPI_TYPE_BUFFER:
254
255 /* Buffer-to-Integer conversion. Max buffer size is 64 bits. */
256
257 if (original_object->buffer.length > 8) {
258 return (AE_AML_OPERAND_TYPE);
259 }
260
261 /* Extract each buffer byte to create the integer */
262
263 for (i = 0; i < original_object->buffer.length; i++) {
264 value |=
265 ((u64) original_object->buffer.
266 pointer[i] << (i * 8));
267 }
268 break;
269
270 default:
271 return (AE_AML_OPERAND_TYPE);
272 }
273
274 new_object = acpi_ut_create_integer_object(value);
275 if (!new_object) {
276 return (AE_NO_MEMORY);
277 }
278
279 *return_object = new_object;
280 return (AE_OK);
281}
282
283/*******************************************************************************
284 *
285 * FUNCTION: acpi_ns_convert_to_string
286 *
287 * PARAMETERS: original_object - Object to be converted
288 * return_object - Where the new converted object is returned
289 *
290 * RETURN: Status. AE_OK if conversion was successful.
291 *
292 * DESCRIPTION: Attempt to convert a Integer/Buffer object to a String.
293 *
294 ******************************************************************************/
295
296static acpi_status
297acpi_ns_convert_to_string(union acpi_operand_object *original_object,
298 union acpi_operand_object **return_object)
299{
300 union acpi_operand_object *new_object;
301 acpi_size length;
302 acpi_status status;
303
304 switch (original_object->common.type) {
305 case ACPI_TYPE_INTEGER:
306 /*
307 * Integer-to-String conversion. Commonly, convert
308 * an integer of value 0 to a NULL string. The last element of
309 * _BIF and _BIX packages occasionally need this fix.
310 */
311 if (original_object->integer.value == 0) {
312
313 /* Allocate a new NULL string object */
314
315 new_object = acpi_ut_create_string_object(0);
316 if (!new_object) {
317 return (AE_NO_MEMORY);
318 }
319 } else {
320 status =
321 acpi_ex_convert_to_string(original_object,
322 &new_object,
323 ACPI_IMPLICIT_CONVERT_HEX);
324 if (ACPI_FAILURE(status)) {
325 return (status);
326 }
327 }
328 break;
329
330 case ACPI_TYPE_BUFFER:
331 /*
332 * Buffer-to-String conversion. Use a to_string
333 * conversion, no transform performed on the buffer data. The best
334 * example of this is the _BIF method, where the string data from
335 * the battery is often (incorrectly) returned as buffer object(s).
336 */
337 length = 0;
338 while ((length < original_object->buffer.length) &&
339 (original_object->buffer.pointer[length])) {
340 length++;
341 }
342
343 /* Allocate a new string object */
344
345 new_object = acpi_ut_create_string_object(length);
346 if (!new_object) {
347 return (AE_NO_MEMORY);
348 }
349
350 /*
351 * Copy the raw buffer data with no transform. String is already NULL
352 * terminated at Length+1.
353 */
354 ACPI_MEMCPY(new_object->string.pointer,
355 original_object->buffer.pointer, length);
356 break;
357
358 default:
359 return (AE_AML_OPERAND_TYPE);
360 }
361
362 *return_object = new_object;
363 return (AE_OK);
364}
365
366/*******************************************************************************
367 * 312 *
368 * FUNCTION: acpi_ns_convert_to_buffer 313 * FUNCTION: acpi_ns_match_simple_repair
369 * 314 *
370 * PARAMETERS: original_object - Object to be converted 315 * PARAMETERS: node - Namespace node for the method/object
371 * return_object - Where the new converted object is returned 316 * return_btype - Object type that was returned
317 * package_index - Index of object within parent package (if
318 * applicable - ACPI_NOT_PACKAGE_ELEMENT
319 * otherwise)
372 * 320 *
373 * RETURN: Status. AE_OK if conversion was successful. 321 * RETURN: Pointer to entry in repair table. NULL indicates not found.
374 * 322 *
375 * DESCRIPTION: Attempt to convert a Integer/String/Package object to a Buffer. 323 * DESCRIPTION: Check an object name against the repairable object list.
376 * 324 *
377 ******************************************************************************/ 325 *****************************************************************************/
378 326
379static acpi_status 327static const struct acpi_simple_repair_info *acpi_ns_match_simple_repair(struct
380acpi_ns_convert_to_buffer(union acpi_operand_object *original_object, 328 acpi_namespace_node
381 union acpi_operand_object **return_object) 329 *node,
330 u32
331 return_btype,
332 u32
333 package_index)
382{ 334{
383 union acpi_operand_object *new_object; 335 const struct acpi_simple_repair_info *this_name;
384 acpi_status status;
385 union acpi_operand_object **elements;
386 u32 *dword_buffer;
387 u32 count;
388 u32 i;
389 336
390 switch (original_object->common.type) { 337 /* Search info table for a repairable predefined method/object name */
391 case ACPI_TYPE_INTEGER:
392 /*
393 * Integer-to-Buffer conversion.
394 * Convert the Integer to a packed-byte buffer. _MAT and other
395 * objects need this sometimes, if a read has been performed on a
396 * Field object that is less than or equal to the global integer
397 * size (32 or 64 bits).
398 */
399 status =
400 acpi_ex_convert_to_buffer(original_object, &new_object);
401 if (ACPI_FAILURE(status)) {
402 return (status);
403 }
404 break;
405 338
406 case ACPI_TYPE_STRING: 339 this_name = acpi_object_repair_info;
340 while (this_name->object_converter) {
341 if (ACPI_COMPARE_NAME(node->name.ascii, this_name->name)) {
407 342
408 /* String-to-Buffer conversion. Simple data copy */ 343 /* Check if we can actually repair this name/type combination */
409
410 new_object =
411 acpi_ut_create_buffer_object(original_object->string.
412 length);
413 if (!new_object) {
414 return (AE_NO_MEMORY);
415 }
416 344
417 ACPI_MEMCPY(new_object->buffer.pointer, 345 if ((return_btype & this_name->unexpected_btypes) &&
418 original_object->string.pointer, 346 (package_index == this_name->package_index)) {
419 original_object->string.length); 347 return (this_name);
420 break;
421
422 case ACPI_TYPE_PACKAGE:
423 /*
424 * This case is often seen for predefined names that must return a
425 * Buffer object with multiple DWORD integers within. For example,
426 * _FDE and _GTM. The Package can be converted to a Buffer.
427 */
428
429 /* All elements of the Package must be integers */
430
431 elements = original_object->package.elements;
432 count = original_object->package.count;
433
434 for (i = 0; i < count; i++) {
435 if ((!*elements) ||
436 ((*elements)->common.type != ACPI_TYPE_INTEGER)) {
437 return (AE_AML_OPERAND_TYPE);
438 } 348 }
439 elements++;
440 }
441
442 /* Create the new buffer object to replace the Package */
443 349
444 new_object = acpi_ut_create_buffer_object(ACPI_MUL_4(count)); 350 return (NULL);
445 if (!new_object) {
446 return (AE_NO_MEMORY);
447 } 351 }
448 352 this_name++;
449 /* Copy the package elements (integers) to the buffer as DWORDs */
450
451 elements = original_object->package.elements;
452 dword_buffer = ACPI_CAST_PTR(u32, new_object->buffer.pointer);
453
454 for (i = 0; i < count; i++) {
455 *dword_buffer = (u32) (*elements)->integer.value;
456 dword_buffer++;
457 elements++;
458 }
459 break;
460
461 default:
462 return (AE_AML_OPERAND_TYPE);
463 } 353 }
464 354
465 *return_object = new_object; 355 return (NULL); /* Name was not found in the repair table */
466 return (AE_OK);
467} 356}
468 357
469/******************************************************************************* 358/*******************************************************************************