aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBob Moore <robert.moore@intel.com>2013-03-08 04:23:03 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-03-11 19:45:05 -0400
commitd5a36100f62fa6db5541344e08b361b34e9114c5 (patch)
tree8d25f0eced2c1794b3db5cddc216e7c4ddf31b2e
parent6be58e2f21edd7362d985e0a44060352458c0f49 (diff)
ACPICA: Add mechanism for early object repairs on a per-name basis
Adds the framework to allow object repairs very early in the return object analysis. Enables repairs like string->unicode, etc. Bob Moore, Lv Zheng. Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Bob Moore <robert.moore@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r--drivers/acpi/acpica/aclocal.h15
-rw-r--r--drivers/acpi/acpica/acnamesp.h2
-rw-r--r--drivers/acpi/acpica/nspredef.c141
-rw-r--r--drivers/acpi/acpica/nsrepair.c134
-rw-r--r--drivers/acpi/acpica/nsrepair2.c16
5 files changed, 221 insertions, 87 deletions
diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h
index 805f419086ab..9d45f976a31e 100644
--- a/drivers/acpi/acpica/aclocal.h
+++ b/drivers/acpi/acpica/aclocal.h
@@ -363,6 +363,7 @@ struct acpi_predefined_data {
363 union acpi_operand_object *parent_package; 363 union acpi_operand_object *parent_package;
364 struct acpi_namespace_node *node; 364 struct acpi_namespace_node *node;
365 u32 flags; 365 u32 flags;
366 u32 return_btype;
366 u8 node_flags; 367 u8 node_flags;
367}; 368};
368 369
@@ -371,6 +372,20 @@ struct acpi_predefined_data {
371#define ACPI_OBJECT_REPAIRED 1 372#define ACPI_OBJECT_REPAIRED 1
372#define ACPI_OBJECT_WRAPPED 2 373#define ACPI_OBJECT_WRAPPED 2
373 374
375/* Return object auto-repair info */
376
377typedef acpi_status(*acpi_object_converter) (union acpi_operand_object
378 *original_object,
379 union acpi_operand_object
380 **converted_object);
381
382struct acpi_simple_repair_info {
383 char name[ACPI_NAME_SIZE];
384 u32 unexpected_btypes;
385 u32 package_index;
386 acpi_object_converter object_converter;
387};
388
374/* 389/*
375 * Bitmapped return value types 390 * Bitmapped return value types
376 * Note: the actual data types must be contiguous, a loop in nspredef.c 391 * Note: the actual data types must be contiguous, a loop in nspredef.c
diff --git a/drivers/acpi/acpica/acnamesp.h b/drivers/acpi/acpica/acnamesp.h
index 02cd5482ff8b..dec6e9ec2e0c 100644
--- a/drivers/acpi/acpica/acnamesp.h
+++ b/drivers/acpi/acpica/acnamesp.h
@@ -289,7 +289,7 @@ acpi_ns_get_attached_data(struct acpi_namespace_node *node,
289 * predefined methods/objects 289 * predefined methods/objects
290 */ 290 */
291acpi_status 291acpi_status
292acpi_ns_repair_object(struct acpi_predefined_data *data, 292acpi_ns_simple_repair(struct acpi_predefined_data *data,
293 u32 expected_btypes, 293 u32 expected_btypes,
294 u32 package_index, 294 u32 package_index,
295 union acpi_operand_object **return_object_ptr); 295 union acpi_operand_object **return_object_ptr);
diff --git a/drivers/acpi/acpica/nspredef.c b/drivers/acpi/acpica/nspredef.c
index 224c30053401..36f724085dca 100644
--- a/drivers/acpi/acpica/nspredef.c
+++ b/drivers/acpi/acpica/nspredef.c
@@ -78,6 +78,8 @@ acpi_ns_check_reference(struct acpi_predefined_data *data,
78 78
79static void acpi_ns_get_expected_types(char *buffer, u32 expected_btypes); 79static void acpi_ns_get_expected_types(char *buffer, u32 expected_btypes);
80 80
81static u32 acpi_ns_get_bitmapped_type(union acpi_operand_object *return_object);
82
81/* 83/*
82 * Names for the types that can be returned by the predefined objects. 84 * Names for the types that can be returned by the predefined objects.
83 * Used for warning messages. Must be in the same order as the ACPI_RTYPEs 85 * Used for warning messages. Must be in the same order as the ACPI_RTYPEs
@@ -112,7 +114,6 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node,
112 acpi_status return_status, 114 acpi_status return_status,
113 union acpi_operand_object **return_object_ptr) 115 union acpi_operand_object **return_object_ptr)
114{ 116{
115 union acpi_operand_object *return_object = *return_object_ptr;
116 acpi_status status = AE_OK; 117 acpi_status status = AE_OK;
117 const union acpi_predefined_info *predefined; 118 const union acpi_predefined_info *predefined;
118 char *pathname; 119 char *pathname;
@@ -152,25 +153,6 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node,
152 } 153 }
153 154
154 /* 155 /*
155 * If there is no return value, check if we require a return value for
156 * this predefined name. Either one return value is expected, or none,
157 * for both methods and other objects.
158 *
159 * Exit now if there is no return object. Warning if one was expected.
160 */
161 if (!return_object) {
162 if ((predefined->info.expected_btypes) &&
163 (!(predefined->info.expected_btypes & ACPI_RTYPE_NONE))) {
164 ACPI_WARN_PREDEFINED((AE_INFO, pathname,
165 ACPI_WARN_ALWAYS,
166 "Missing expected return value"));
167
168 status = AE_AML_NO_RETURN_VALUE;
169 }
170 goto cleanup;
171 }
172
173 /*
174 * Return value validation and possible repair. 156 * Return value validation and possible repair.
175 * 157 *
176 * 1) Don't perform return value validation/repair if this feature 158 * 1) Don't perform return value validation/repair if this feature
@@ -410,28 +392,12 @@ acpi_ns_check_object_type(struct acpi_predefined_data *data,
410{ 392{
411 union acpi_operand_object *return_object = *return_object_ptr; 393 union acpi_operand_object *return_object = *return_object_ptr;
412 acpi_status status = AE_OK; 394 acpi_status status = AE_OK;
413 u32 return_btype;
414 char type_buffer[48]; /* Room for 5 types */ 395 char type_buffer[48]; /* Room for 5 types */
415 396
416 /*
417 * If we get a NULL return_object here, it is a NULL package element.
418 * Since all extraneous NULL package elements were removed earlier by a
419 * call to acpi_ns_remove_null_elements, this is an unexpected NULL element.
420 * We will attempt to repair it.
421 */
422 if (!return_object) {
423 status = acpi_ns_repair_null_element(data, expected_btypes,
424 package_index,
425 return_object_ptr);
426 if (ACPI_SUCCESS(status)) {
427 return (AE_OK); /* Repair was successful */
428 }
429 goto type_error_exit;
430 }
431
432 /* A Namespace node should not get here, but make sure */ 397 /* A Namespace node should not get here, but make sure */
433 398
434 if (ACPI_GET_DESCRIPTOR_TYPE(return_object) == ACPI_DESC_TYPE_NAMED) { 399 if (return_object &&
400 ACPI_GET_DESCRIPTOR_TYPE(return_object) == ACPI_DESC_TYPE_NAMED) {
435 ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags, 401 ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags,
436 "Invalid return type - Found a Namespace node [%4.4s] type %s", 402 "Invalid return type - Found a Namespace node [%4.4s] type %s",
437 return_object->node.name.ascii, 403 return_object->node.name.ascii,
@@ -448,53 +414,25 @@ acpi_ns_check_object_type(struct acpi_predefined_data *data,
448 * from all of the predefined names (including elements of returned 414 * from all of the predefined names (including elements of returned
449 * packages) 415 * packages)
450 */ 416 */
451 switch (return_object->common.type) { 417 data->return_btype = acpi_ns_get_bitmapped_type(return_object);
452 case ACPI_TYPE_INTEGER: 418 if (data->return_btype == ACPI_RTYPE_ANY) {
453 return_btype = ACPI_RTYPE_INTEGER;
454 break;
455
456 case ACPI_TYPE_BUFFER:
457 return_btype = ACPI_RTYPE_BUFFER;
458 break;
459
460 case ACPI_TYPE_STRING:
461 return_btype = ACPI_RTYPE_STRING;
462 break;
463 419
464 case ACPI_TYPE_PACKAGE:
465 return_btype = ACPI_RTYPE_PACKAGE;
466 break;
467
468 case ACPI_TYPE_LOCAL_REFERENCE:
469 return_btype = ACPI_RTYPE_REFERENCE;
470 break;
471
472 default:
473 /* Not one of the supported objects, must be incorrect */ 420 /* Not one of the supported objects, must be incorrect */
474
475 goto type_error_exit; 421 goto type_error_exit;
476 } 422 }
477 423
478 /* Is the object one of the expected types? */ 424 /* For reference objects, check that the reference type is correct */
479
480 if (return_btype & expected_btypes) {
481
482 /* For reference objects, check that the reference type is correct */
483
484 if (return_object->common.type == ACPI_TYPE_LOCAL_REFERENCE) {
485 status = acpi_ns_check_reference(data, return_object);
486 }
487 425
426 if ((data->return_btype & expected_btypes) == ACPI_RTYPE_REFERENCE) {
427 status = acpi_ns_check_reference(data, return_object);
488 return (status); 428 return (status);
489 } 429 }
490 430
491 /* Type mismatch -- attempt repair of the returned object */ 431 /* Attempt simple repair of the returned object if necessary */
492 432
493 status = acpi_ns_repair_object(data, expected_btypes, 433 status = acpi_ns_simple_repair(data, expected_btypes,
494 package_index, return_object_ptr); 434 package_index, return_object_ptr);
495 if (ACPI_SUCCESS(status)) { 435 return (status);
496 return (AE_OK); /* Repair was successful */
497 }
498 436
499 type_error_exit: 437 type_error_exit:
500 438
@@ -558,6 +496,61 @@ acpi_ns_check_reference(struct acpi_predefined_data *data,
558 496
559/******************************************************************************* 497/*******************************************************************************
560 * 498 *
499 * FUNCTION: acpi_ns_get_bitmapped_type
500 *
501 * PARAMETERS: return_object - Object returned from method/obj evaluation
502 *
503 * RETURN: Object return type. ACPI_RTYPE_ANY indicates that the object
504 * type is not supported. ACPI_RTYPE_NONE indicates that no
505 * object was returned (return_object is NULL).
506 *
507 * DESCRIPTION: Convert object type into a bitmapped object return type.
508 *
509 ******************************************************************************/
510
511static u32 acpi_ns_get_bitmapped_type(union acpi_operand_object *return_object)
512{
513 u32 return_btype;
514
515 if (!return_object) {
516 return (ACPI_RTYPE_NONE);
517 }
518
519 /* Map acpi_object_type to internal bitmapped type */
520
521 switch (return_object->common.type) {
522 case ACPI_TYPE_INTEGER:
523 return_btype = ACPI_RTYPE_INTEGER;
524 break;
525
526 case ACPI_TYPE_BUFFER:
527 return_btype = ACPI_RTYPE_BUFFER;
528 break;
529
530 case ACPI_TYPE_STRING:
531 return_btype = ACPI_RTYPE_STRING;
532 break;
533
534 case ACPI_TYPE_PACKAGE:
535 return_btype = ACPI_RTYPE_PACKAGE;
536 break;
537
538 case ACPI_TYPE_LOCAL_REFERENCE:
539 return_btype = ACPI_RTYPE_REFERENCE;
540 break;
541
542 default:
543 /* Not one of the supported objects, must be incorrect */
544
545 return_btype = ACPI_RTYPE_ANY;
546 break;
547 }
548
549 return (return_btype);
550}
551
552/*******************************************************************************
553 *
561 * FUNCTION: acpi_ns_get_expected_types 554 * FUNCTION: acpi_ns_get_expected_types
562 * 555 *
563 * PARAMETERS: buffer - Pointer to where the string is returned 556 * PARAMETERS: buffer - Pointer to where the string is returned
diff --git a/drivers/acpi/acpica/nsrepair.c b/drivers/acpi/acpica/nsrepair.c
index 9e833353c06a..f9c9fd45cd1f 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:
@@ -90,9 +96,26 @@ static acpi_status
90acpi_ns_convert_to_buffer(union acpi_operand_object *original_object, 96acpi_ns_convert_to_buffer(union acpi_operand_object *original_object,
91 union acpi_operand_object **return_object); 97 union acpi_operand_object **return_object);
92 98
99static const struct acpi_simple_repair_info *acpi_ns_match_simple_repair(struct
100 acpi_namespace_node
101 *node,
102 u32
103 return_btype,
104 u32
105 package_index);
106
107/*
108 * Special but simple repairs for some names.
109 *
110 * 2nd argument: Unexpected types that can be repaired
111 */
112static const struct acpi_simple_repair_info acpi_object_repair_info[] = {
113 {{0, 0, 0, 0}, 0, 0, NULL} /* Table terminator */
114};
115
93/******************************************************************************* 116/*******************************************************************************
94 * 117 *
95 * FUNCTION: acpi_ns_repair_object 118 * FUNCTION: acpi_ns_simple_repair
96 * 119 *
97 * PARAMETERS: data - Pointer to validation data structure 120 * PARAMETERS: data - Pointer to validation data structure
98 * expected_btypes - Object types expected 121 * expected_btypes - Object types expected
@@ -110,16 +133,54 @@ acpi_ns_convert_to_buffer(union acpi_operand_object *original_object,
110 ******************************************************************************/ 133 ******************************************************************************/
111 134
112acpi_status 135acpi_status
113acpi_ns_repair_object(struct acpi_predefined_data *data, 136acpi_ns_simple_repair(struct acpi_predefined_data *data,
114 u32 expected_btypes, 137 u32 expected_btypes,
115 u32 package_index, 138 u32 package_index,
116 union acpi_operand_object **return_object_ptr) 139 union acpi_operand_object **return_object_ptr)
117{ 140{
118 union acpi_operand_object *return_object = *return_object_ptr; 141 union acpi_operand_object *return_object = *return_object_ptr;
119 union acpi_operand_object *new_object; 142 union acpi_operand_object *new_object = NULL;
120 acpi_status status; 143 acpi_status status;
144 const struct acpi_simple_repair_info *predefined;
121 145
122 ACPI_FUNCTION_NAME(ns_repair_object); 146 ACPI_FUNCTION_NAME(ns_simple_repair);
147
148 /*
149 * Special repairs for certain names that are in the repair table.
150 * Check if this name is in the list of repairable names.
151 */
152 predefined = acpi_ns_match_simple_repair(data->node,
153 data->return_btype,
154 package_index);
155 if (predefined) {
156 if (!return_object) {
157 ACPI_WARN_PREDEFINED((AE_INFO, data->pathname,
158 ACPI_WARN_ALWAYS,
159 "Missing expected return value"));
160 }
161
162 status =
163 predefined->object_converter(return_object, &new_object);
164 if (ACPI_FAILURE(status)) {
165
166 /* A fatal error occurred during a conversion */
167
168 ACPI_EXCEPTION((AE_INFO, status,
169 "During return object analysis"));
170 return (status);
171 }
172 if (new_object) {
173 goto object_repaired;
174 }
175 }
176
177 /*
178 * Do not perform simple object repair unless the return type is not
179 * expected.
180 */
181 if (data->return_btype & expected_btypes) {
182 return (AE_OK);
183 }
123 184
124 /* 185 /*
125 * At this point, we know that the type of the returned object was not 186 * At this point, we know that the type of the returned object was not
@@ -127,6 +188,24 @@ acpi_ns_repair_object(struct acpi_predefined_data *data,
127 * repair the object by converting it to one of the expected object 188 * repair the object by converting it to one of the expected object
128 * types for this predefined name. 189 * types for this predefined name.
129 */ 190 */
191
192 /*
193 * If there is no return value, check if we require a return value for
194 * this predefined name. Either one return value is expected, or none,
195 * for both methods and other objects.
196 *
197 * Exit now if there is no return object. Warning if one was expected.
198 */
199 if (!return_object) {
200 if (expected_btypes && (!(expected_btypes & ACPI_RTYPE_NONE))) {
201 ACPI_WARN_PREDEFINED((AE_INFO, data->pathname,
202 ACPI_WARN_ALWAYS,
203 "Missing expected return value"));
204
205 return (AE_AML_NO_RETURN_VALUE);
206 }
207 }
208
130 if (expected_btypes & ACPI_RTYPE_INTEGER) { 209 if (expected_btypes & ACPI_RTYPE_INTEGER) {
131 status = acpi_ns_convert_to_integer(return_object, &new_object); 210 status = acpi_ns_convert_to_integer(return_object, &new_object);
132 if (ACPI_SUCCESS(status)) { 211 if (ACPI_SUCCESS(status)) {
@@ -216,6 +295,53 @@ acpi_ns_repair_object(struct acpi_predefined_data *data,
216 return (AE_OK); 295 return (AE_OK);
217} 296}
218 297
298/******************************************************************************
299 *
300 * FUNCTION: acpi_ns_match_simple_repair
301 *
302 * PARAMETERS: node - Namespace node for the method/object
303 * return_btype - Object type that was returned
304 * package_index - Index of object within parent package (if
305 * applicable - ACPI_NOT_PACKAGE_ELEMENT
306 * otherwise)
307 *
308 * RETURN: Pointer to entry in repair table. NULL indicates not found.
309 *
310 * DESCRIPTION: Check an object name against the repairable object list.
311 *
312 *****************************************************************************/
313
314static const struct acpi_simple_repair_info *acpi_ns_match_simple_repair(struct
315 acpi_namespace_node
316 *node,
317 u32
318 return_btype,
319 u32
320 package_index)
321{
322 const struct acpi_simple_repair_info *this_name;
323
324 /* Search info table for a repairable predefined method/object name */
325
326 this_name = acpi_object_repair_info;
327 while (this_name->object_converter) {
328 if (ACPI_COMPARE_NAME(node->name.ascii, this_name->name)) {
329
330 /* Check if we can actually repair this name/type combination */
331
332 if ((return_btype & this_name->unexpected_btypes) &&
333 (package_index == this_name->package_index)) {
334 return (this_name);
335 }
336
337 return (NULL);
338 }
339 this_name++;
340 }
341
342 return (NULL); /* Name was not found in the repair table */
343}
344
219/******************************************************************************* 345/*******************************************************************************
220 * 346 *
221 * FUNCTION: acpi_ns_convert_to_integer 347 * FUNCTION: acpi_ns_convert_to_integer
diff --git a/drivers/acpi/acpica/nsrepair2.c b/drivers/acpi/acpica/nsrepair2.c
index ba4d98287c6a..149e9b9c2c1b 100644
--- a/drivers/acpi/acpica/nsrepair2.c
+++ b/drivers/acpi/acpica/nsrepair2.c
@@ -66,9 +66,9 @@ typedef struct acpi_repair_info {
66 66
67/* Local prototypes */ 67/* Local prototypes */
68 68
69static const struct acpi_repair_info *acpi_ns_match_repairable_name(struct 69static const struct acpi_repair_info *acpi_ns_match_complex_repair(struct
70 acpi_namespace_node 70 acpi_namespace_node
71 *node); 71 *node);
72 72
73static acpi_status 73static acpi_status
74acpi_ns_repair_ALR(struct acpi_predefined_data *data, 74acpi_ns_repair_ALR(struct acpi_predefined_data *data,
@@ -175,7 +175,7 @@ acpi_ns_complex_repairs(struct acpi_predefined_data *data,
175 175
176 /* Check if this name is in the list of repairable names */ 176 /* Check if this name is in the list of repairable names */
177 177
178 predefined = acpi_ns_match_repairable_name(node); 178 predefined = acpi_ns_match_complex_repair(node);
179 if (!predefined) { 179 if (!predefined) {
180 return (validate_status); 180 return (validate_status);
181 } 181 }
@@ -186,7 +186,7 @@ acpi_ns_complex_repairs(struct acpi_predefined_data *data,
186 186
187/****************************************************************************** 187/******************************************************************************
188 * 188 *
189 * FUNCTION: acpi_ns_match_repairable_name 189 * FUNCTION: acpi_ns_match_complex_repair
190 * 190 *
191 * PARAMETERS: node - Namespace node for the method/object 191 * PARAMETERS: node - Namespace node for the method/object
192 * 192 *
@@ -196,9 +196,9 @@ acpi_ns_complex_repairs(struct acpi_predefined_data *data,
196 * 196 *
197 *****************************************************************************/ 197 *****************************************************************************/
198 198
199static const struct acpi_repair_info *acpi_ns_match_repairable_name(struct 199static const struct acpi_repair_info *acpi_ns_match_complex_repair(struct
200 acpi_namespace_node 200 acpi_namespace_node
201 *node) 201 *node)
202{ 202{
203 const struct acpi_repair_info *this_name; 203 const struct acpi_repair_info *this_name;
204 204