aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
authorBob Moore <robert.moore@intel.com>2010-09-15 02:11:02 -0400
committerLen Brown <len.brown@intel.com>2010-10-01 01:47:56 -0400
commit77b23f712bc40a65160e7d02b045f1562bb43ff1 (patch)
treedf0da95ce1d95a2c30c5b517cded2a016ea48744 /drivers/acpi
parentcc84e262b71bab53c3b2be2e71209c85b88b4b4d (diff)
ACPICA: Add repair for _HID and _CID strings
This dynamic repair will fix these problems: 1) Remove a leading asterisk in the string 2) Uppercase the entire string Signed-off-by: Bob Moore <robert.moore@intel.com> Signed-off-by: Lin Ming <ming.m.lin@intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/acpica/nsrepair2.c163
1 files changed, 163 insertions, 0 deletions
diff --git a/drivers/acpi/acpica/nsrepair2.c b/drivers/acpi/acpica/nsrepair2.c
index 4009498fbabd..4ef9f43ea926 100644
--- a/drivers/acpi/acpica/nsrepair2.c
+++ b/drivers/acpi/acpica/nsrepair2.c
@@ -74,10 +74,18 @@ acpi_ns_repair_ALR(struct acpi_predefined_data *data,
74 union acpi_operand_object **return_object_ptr); 74 union acpi_operand_object **return_object_ptr);
75 75
76static acpi_status 76static acpi_status
77acpi_ns_repair_CID(struct acpi_predefined_data *data,
78 union acpi_operand_object **return_object_ptr);
79
80static acpi_status
77acpi_ns_repair_FDE(struct acpi_predefined_data *data, 81acpi_ns_repair_FDE(struct acpi_predefined_data *data,
78 union acpi_operand_object **return_object_ptr); 82 union acpi_operand_object **return_object_ptr);
79 83
80static acpi_status 84static acpi_status
85acpi_ns_repair_HID(struct acpi_predefined_data *data,
86 union acpi_operand_object **return_object_ptr);
87
88static acpi_status
81acpi_ns_repair_PSS(struct acpi_predefined_data *data, 89acpi_ns_repair_PSS(struct acpi_predefined_data *data,
82 union acpi_operand_object **return_object_ptr); 90 union acpi_operand_object **return_object_ptr);
83 91
@@ -108,8 +116,10 @@ acpi_ns_sort_list(union acpi_operand_object **elements,
108 * As necessary: 116 * As necessary:
109 * 117 *
110 * _ALR: Sort the list ascending by ambient_illuminance 118 * _ALR: Sort the list ascending by ambient_illuminance
119 * _CID: Strings: uppercase all, remove any leading asterisk
111 * _FDE: Convert Buffer of BYTEs to a Buffer of DWORDs 120 * _FDE: Convert Buffer of BYTEs to a Buffer of DWORDs
112 * _GTM: Convert Buffer of BYTEs to a Buffer of DWORDs 121 * _GTM: Convert Buffer of BYTEs to a Buffer of DWORDs
122 * _HID: Strings: uppercase all, remove any leading asterisk
113 * _PSS: Sort the list descending by Power 123 * _PSS: Sort the list descending by Power
114 * _TSS: Sort the list descending by Power 124 * _TSS: Sort the list descending by Power
115 * 125 *
@@ -122,8 +132,10 @@ acpi_ns_sort_list(union acpi_operand_object **elements,
122 */ 132 */
123static const struct acpi_repair_info acpi_ns_repairable_names[] = { 133static const struct acpi_repair_info acpi_ns_repairable_names[] = {
124 {"_ALR", acpi_ns_repair_ALR}, 134 {"_ALR", acpi_ns_repair_ALR},
135 {"_CID", acpi_ns_repair_CID},
125 {"_FDE", acpi_ns_repair_FDE}, 136 {"_FDE", acpi_ns_repair_FDE},
126 {"_GTM", acpi_ns_repair_FDE}, /* _GTM has same repair as _FDE */ 137 {"_GTM", acpi_ns_repair_FDE}, /* _GTM has same repair as _FDE */
138 {"_HID", acpi_ns_repair_HID},
127 {"_PSS", acpi_ns_repair_PSS}, 139 {"_PSS", acpi_ns_repair_PSS},
128 {"_TSS", acpi_ns_repair_TSS}, 140 {"_TSS", acpi_ns_repair_TSS},
129 {{0, 0, 0, 0}, NULL} /* Table terminator */ 141 {{0, 0, 0, 0}, NULL} /* Table terminator */
@@ -321,6 +333,157 @@ acpi_ns_repair_FDE(struct acpi_predefined_data *data,
321 333
322/****************************************************************************** 334/******************************************************************************
323 * 335 *
336 * FUNCTION: acpi_ns_repair_CID
337 *
338 * PARAMETERS: Data - Pointer to validation data structure
339 * return_object_ptr - Pointer to the object returned from the
340 * evaluation of a method or object
341 *
342 * RETURN: Status. AE_OK if object is OK or was repaired successfully
343 *
344 * DESCRIPTION: Repair for the _CID object. If a string, ensure that all
345 * letters are uppercase and that there is no leading asterisk.
346 * If a Package, ensure same for all string elements.
347 *
348 *****************************************************************************/
349
350static acpi_status
351acpi_ns_repair_CID(struct acpi_predefined_data *data,
352 union acpi_operand_object **return_object_ptr)
353{
354 acpi_status status;
355 union acpi_operand_object *return_object = *return_object_ptr;
356 union acpi_operand_object **element_ptr;
357 union acpi_operand_object *original_element;
358 u16 original_ref_count;
359 u32 i;
360
361 /* Check for _CID as a simple string */
362
363 if (return_object->common.type == ACPI_TYPE_STRING) {
364 status = acpi_ns_repair_HID(data, return_object_ptr);
365 return (status);
366 }
367
368 /* Exit if not a Package */
369
370 if (return_object->common.type != ACPI_TYPE_PACKAGE) {
371 return (AE_OK);
372 }
373
374 /* Examine each element of the _CID package */
375
376 element_ptr = return_object->package.elements;
377 for (i = 0; i < return_object->package.count; i++) {
378 original_element = *element_ptr;
379 original_ref_count = original_element->common.reference_count;
380
381 status = acpi_ns_repair_HID(data, element_ptr);
382 if (ACPI_FAILURE(status)) {
383 return (status);
384 }
385
386 /* Take care with reference counts */
387
388 if (original_element != *element_ptr) {
389
390 /* Element was replaced */
391
392 (*element_ptr)->common.reference_count =
393 original_ref_count;
394
395 acpi_ut_remove_reference(original_element);
396 }
397
398 element_ptr++;
399 }
400
401 return (AE_OK);
402}
403
404/******************************************************************************
405 *
406 * FUNCTION: acpi_ns_repair_HID
407 *
408 * PARAMETERS: Data - Pointer to validation data structure
409 * return_object_ptr - Pointer to the object returned from the
410 * evaluation of a method or object
411 *
412 * RETURN: Status. AE_OK if object is OK or was repaired successfully
413 *
414 * DESCRIPTION: Repair for the _HID object. If a string, ensure that all
415 * letters are uppercase and that there is no leading asterisk.
416 *
417 *****************************************************************************/
418
419static acpi_status
420acpi_ns_repair_HID(struct acpi_predefined_data *data,
421 union acpi_operand_object **return_object_ptr)
422{
423 union acpi_operand_object *return_object = *return_object_ptr;
424 union acpi_operand_object *new_string;
425 char *source;
426 char *dest;
427
428 ACPI_FUNCTION_NAME(ns_repair_HID);
429
430 /* We only care about string _HID objects (not integers) */
431
432 if (return_object->common.type != ACPI_TYPE_STRING) {
433 return (AE_OK);
434 }
435
436 if (return_object->string.length == 0) {
437 ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags,
438 "Invalid zero-length _HID or _CID string"));
439
440 /* Return AE_OK anyway, let driver handle it */
441
442 data->flags |= ACPI_OBJECT_REPAIRED;
443 return (AE_OK);
444 }
445
446 /* It is simplest to always create a new string object */
447
448 new_string = acpi_ut_create_string_object(return_object->string.length);
449 if (!new_string) {
450 return (AE_NO_MEMORY);
451 }
452
453 /*
454 * Remove a leading asterisk if present. For some unknown reason, there
455 * are many machines in the field that contains IDs like this.
456 *
457 * Examples: "*PNP0C03", "*ACPI0003"
458 */
459 source = return_object->string.pointer;
460 if (*source == '*') {
461 source++;
462 new_string->string.length--;
463
464 ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
465 "%s: Removed invalid leading asterisk\n",
466 data->pathname));
467 }
468
469 /*
470 * Copy and uppercase the string. From the ACPI specification:
471 *
472 * A valid PNP ID must be of the form "AAA####" where A is an uppercase
473 * letter and # is a hex digit. A valid ACPI ID must be of the form
474 * "ACPI####" where # is a hex digit.
475 */
476 for (dest = new_string->string.pointer; *source; dest++, source++) {
477 *dest = (char)ACPI_TOUPPER(*source);
478 }
479
480 acpi_ut_remove_reference(return_object);
481 *return_object_ptr = new_string;
482 return (AE_OK);
483}
484
485/******************************************************************************
486 *
324 * FUNCTION: acpi_ns_repair_TSS 487 * FUNCTION: acpi_ns_repair_TSS
325 * 488 *
326 * PARAMETERS: Data - Pointer to validation data structure 489 * PARAMETERS: Data - Pointer to validation data structure