diff options
| author | Bob Moore <robert.moore@intel.com> | 2010-09-15 02:11:02 -0400 |
|---|---|---|
| committer | Len Brown <len.brown@intel.com> | 2010-10-01 01:47:56 -0400 |
| commit | 77b23f712bc40a65160e7d02b045f1562bb43ff1 (patch) | |
| tree | df0da95ce1d95a2c30c5b517cded2a016ea48744 | |
| parent | cc84e262b71bab53c3b2be2e71209c85b88b4b4d (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>
| -rw-r--r-- | drivers/acpi/acpica/nsrepair2.c | 163 |
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 | ||
| 76 | static acpi_status | 76 | static acpi_status |
| 77 | acpi_ns_repair_CID(struct acpi_predefined_data *data, | ||
| 78 | union acpi_operand_object **return_object_ptr); | ||
| 79 | |||
| 80 | static acpi_status | ||
| 77 | acpi_ns_repair_FDE(struct acpi_predefined_data *data, | 81 | acpi_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 | ||
| 80 | static acpi_status | 84 | static acpi_status |
| 85 | acpi_ns_repair_HID(struct acpi_predefined_data *data, | ||
| 86 | union acpi_operand_object **return_object_ptr); | ||
| 87 | |||
| 88 | static acpi_status | ||
| 81 | acpi_ns_repair_PSS(struct acpi_predefined_data *data, | 89 | acpi_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 | */ |
| 123 | static const struct acpi_repair_info acpi_ns_repairable_names[] = { | 133 | static 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 | |||
| 350 | static acpi_status | ||
| 351 | acpi_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 | |||
| 419 | static acpi_status | ||
| 420 | acpi_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 |
