1 /****************************************************************************** 2 * 3 * Module Name: nsrepair - Repair for objects returned by predefined methods 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2010, 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 * This module attempts to repair or convert objects returned by the 56 * predefined methods to an object type that is expected, as per the ACPI 57 * specification. The need for this code is dictated by the many machines that 58 * return incorrect types for the standard predefined methods. Performing these 59 * conversions here, in one place, eliminates the need for individual ACPI 60 * device drivers to do the same. Note: Most of these conversions are different 61 * than the internal object conversion routines used for implicit object 62 * conversion. 63 * 64 * The following conversions can be performed as necessary: 65 * 66 * Integer -> String 67 * Integer -> Buffer 68 * String -> Integer 69 * String -> Buffer 70 * Buffer -> Integer 71 * Buffer -> String 72 * Buffer -> Package of Integers 73 * Package -> Package of one Package 74 * 75 * Additional possible repairs: 76 * 77 * Optional/unnecessary NULL package elements removed 78 * Required package elements that are NULL replaced by Integer/String/Buffer 79 * Incorrect standalone package wrapped with required outer package 80 * 81 ******************************************************************************/ 82 /* Local prototypes */ 83 static acpi_status 84 acpi_ns_convert_to_integer(union acpi_operand_object *original_object, 85 union acpi_operand_object **return_object); 86 87 static acpi_status 88 acpi_ns_convert_to_string(union acpi_operand_object *original_object, 89 union acpi_operand_object **return_object); 90 91 static acpi_status 92 acpi_ns_convert_to_buffer(union acpi_operand_object *original_object, 93 union acpi_operand_object **return_object); 94 95 static acpi_status 96 acpi_ns_convert_to_package(union acpi_operand_object *original_object, 97 union acpi_operand_object **return_object); 98 99 /******************************************************************************* 100 * 101 * FUNCTION: acpi_ns_repair_object 102 * 103 * PARAMETERS: Data - Pointer to validation data structure 104 * expected_btypes - Object types expected 105 * package_index - Index of object within parent package (if 106 * applicable - ACPI_NOT_PACKAGE_ELEMENT 107 * otherwise) 108 * return_object_ptr - Pointer to the object returned from the 109 * evaluation of a method or object 110 * 111 * RETURN: Status. AE_OK if repair was successful. 112 * 113 * DESCRIPTION: Attempt to repair/convert a return object of a type that was 114 * not expected. 115 * 116 ******************************************************************************/ 117 118 acpi_status 119 acpi_ns_repair_object(struct acpi_predefined_data *data, 120 u32 expected_btypes, 121 u32 package_index, 122 union acpi_operand_object **return_object_ptr) 123 { 124 union acpi_operand_object *return_object = *return_object_ptr; 125 union acpi_operand_object *new_object; 126 acpi_status status; 127 128 ACPI_FUNCTION_NAME(ns_repair_object); 129 130 /* 131 * At this point, we know that the type of the returned object was not 132 * one of the expected types for this predefined name. Attempt to 133 * repair the object by converting it to one of the expected object 134 * types for this predefined name. 135 */ 136 if (expected_btypes & ACPI_RTYPE_INTEGER) { 137 status = acpi_ns_convert_to_integer(return_object, &new_object); 138 if (ACPI_SUCCESS(status)) { 139 goto object_repaired; 140 } 141 } 142 if (expected_btypes & ACPI_RTYPE_STRING) { 143 status = acpi_ns_convert_to_string(return_object, &new_object); 144 if (ACPI_SUCCESS(status)) { 145 goto object_repaired; 146 } 147 } 148 if (expected_btypes & ACPI_RTYPE_BUFFER) { 149 status = acpi_ns_convert_to_buffer(return_object, &new_object); 150 if (ACPI_SUCCESS(status)) { 151 goto object_repaired; 152 } 153 } 154 if (expected_btypes & ACPI_RTYPE_PACKAGE) { 155 status = acpi_ns_convert_to_package(return_object, &new_object); 156 if (ACPI_SUCCESS(status)) { 157 goto object_repaired; 158 } 159 } 160 161 /* We cannot repair this object */ 162 163 return (AE_AML_OPERAND_TYPE); 164 165 object_repaired: 166 167 /* Object was successfully repaired */ 168 169 /* 170 * If the original object is a package element, we need to: 171 * 1. Set the reference count of the new object to match the 172 * reference count of the old object. 173 * 2. Decrement the reference count of the original object. 174 */ 175 if (package_index != ACPI_NOT_PACKAGE_ELEMENT) { 176 new_object->common.reference_count = 177 return_object->common.reference_count; 178 179 if (return_object->common.reference_count > 1) { 180 return_object->common.reference_count--; 181 } 182 183 ACPI_DEBUG_PRINT((ACPI_DB_REPAIR, 184 "%s: Converted %s to expected %s at index %u\n", 185 data->pathname, 186 acpi_ut_get_object_type_name(return_object), 187 acpi_ut_get_object_type_name(new_object), 188 package_index)); 189 } else { 190 ACPI_DEBUG_PRINT((ACPI_DB_REPAIR, 191 "%s: Converted %s to expected %s\n", 192 data->pathname, 193 acpi_ut_get_object_type_name(return_object), 194 acpi_ut_get_object_type_name(new_object))); 195 } 196 197 /* Delete old object, install the new return object */ 198 199 acpi_ut_remove_reference(return_object); 200 *return_object_ptr = new_object; 201 data->flags |= ACPI_OBJECT_REPAIRED; 202 return (AE_OK); 203 } 204 205 /******************************************************************************* 206 * 207 * FUNCTION: acpi_ns_convert_to_integer 208 * 209 * PARAMETERS: original_object - Object to be converted 210 * return_object - Where the new converted object is returned 211 * 212 * RETURN: Status. AE_OK if conversion was successful. 213 * 214 * DESCRIPTION: Attempt to convert a String/Buffer object to an Integer. 215 * 216 ******************************************************************************/ 217 218 static acpi_status 219 acpi_ns_convert_to_integer(union acpi_operand_object *original_object, 220 union acpi_operand_object **return_object) 221 { 222 union acpi_operand_object *new_object; 223 acpi_status status; 224 u64 value = 0; 225 u32 i; 226 227 switch (original_object->common.type) { 228 case ACPI_TYPE_STRING: 229 230 /* String-to-Integer conversion */ 231 232 status = acpi_ut_strtoul64(original_object->string.pointer, 233 ACPI_ANY_BASE, &value); 234 if (ACPI_FAILURE(status)) { 235 return (status); 236 } 237 break; 238 239 case ACPI_TYPE_BUFFER: 240 241 /* Buffer-to-Integer conversion. Max buffer size is 64 bits. */ 242 243 if (original_object->buffer.length > 8) { 244 return (AE_AML_OPERAND_TYPE); 245 } 246 247 /* Extract each buffer byte to create the integer */ 248 249 for (i = 0; i < original_object->buffer.length; i++) { 250 value |= 251 ((u64) original_object->buffer. 252 pointer[i] << (i * 8)); 253 } 254 break; 255 256 default: 257 return (AE_AML_OPERAND_TYPE); 258 } 259 260 new_object = acpi_ut_create_integer_object(value); 261 if (!new_object) { 262 return (AE_NO_MEMORY); 263 } 264 265 *return_object = new_object; 266 return (AE_OK); 267 } 268 269 /******************************************************************************* 270 * 271 * FUNCTION: acpi_ns_convert_to_string 272 * 273 * PARAMETERS: original_object - Object to be converted 274 * return_object - Where the new converted object is returned 275 * 276 * RETURN: Status. AE_OK if conversion was successful. 277 * 278 * DESCRIPTION: Attempt to convert a Integer/Buffer object to a String. 279 * 280 ******************************************************************************/ 281 282 static acpi_status 283 acpi_ns_convert_to_string(union acpi_operand_object *original_object, 284 union acpi_operand_object **return_object) 285 { 286 union acpi_operand_object *new_object; 287 acpi_size length; 288 acpi_status status; 289 290 switch (original_object->common.type) { 291 case ACPI_TYPE_INTEGER: 292 /* 293 * Integer-to-String conversion. Commonly, convert 294 * an integer of value 0 to a NULL string. The last element of 295 * _BIF and _BIX packages occasionally need this fix. 296 */ 297 if (original_object->integer.value == 0) { 298 299 /* Allocate a new NULL string object */ 300 301 new_object = acpi_ut_create_string_object(0); 302 if (!new_object) { 303 return (AE_NO_MEMORY); 304 } 305 } else { 306 status = 307 acpi_ex_convert_to_string(original_object, 308 &new_object, 309 ACPI_IMPLICIT_CONVERT_HEX); 310 if (ACPI_FAILURE(status)) { 311 return (status); 312 } 313 } 314 break; 315 316 case ACPI_TYPE_BUFFER: 317 /* 318 * Buffer-to-String conversion. Use a to_string 319 * conversion, no transform performed on the buffer data. The best 320 * example of this is the _BIF method, where the string data from 321 * the battery is often (incorrectly) returned as buffer object(s). 322 */ 323 length = 0; 324 while ((length < original_object->buffer.length) && 325 (original_object->buffer.pointer[length])) { 326 length++; 327 } 328 329 /* Allocate a new string object */ 330 331 new_object = acpi_ut_create_string_object(length); 332 if (!new_object) { 333 return (AE_NO_MEMORY); 334 } 335 336 /* 337 * Copy the raw buffer data with no transform. String is already NULL 338 * terminated at Length+1. 339 */ 340 ACPI_MEMCPY(new_object->string.pointer, 341 original_object->buffer.pointer, length); 342 break; 343 344 default: 345 return (AE_AML_OPERAND_TYPE); 346 } 347 348 *return_object = new_object; 349 return (AE_OK); 350 } 351 352 /******************************************************************************* 353 * 354 * FUNCTION: acpi_ns_convert_to_buffer 355 * 356 * PARAMETERS: original_object - Object to be converted 357 * return_object - Where the new converted object is returned 358 * 359 * RETURN: Status. AE_OK if conversion was successful. 360 * 361 * DESCRIPTION: Attempt to convert a Integer/String/Package object to a Buffer. 362 * 363 ******************************************************************************/ 364 365 static acpi_status 366 acpi_ns_convert_to_buffer(union acpi_operand_object *original_object, 367 union acpi_operand_object **return_object) 368 { 369 union acpi_operand_object *new_object; 370 acpi_status status; 371 union acpi_operand_object **elements; 372 u32 *dword_buffer; 373 u32 count; 374 u32 i; 375 376 switch (original_object->common.type) { 377 case ACPI_TYPE_INTEGER: 378 /* 379 * Integer-to-Buffer conversion. 380 * Convert the Integer to a packed-byte buffer. _MAT and other 381 * objects need this sometimes, if a read has been performed on a 382 * Field object that is less than or equal to the global integer 383 * size (32 or 64 bits). 384 */ 385 status = 386 acpi_ex_convert_to_buffer(original_object, &new_object); 387 if (ACPI_FAILURE(status)) { 388 return (status); 389 } 390 break; 391 392 case ACPI_TYPE_STRING: 393 394 /* String-to-Buffer conversion. Simple data copy */ 395 396 new_object = 397 acpi_ut_create_buffer_object(original_object->string. 398 length); 399 if (!new_object) { 400 return (AE_NO_MEMORY); 401 } 402 403 ACPI_MEMCPY(new_object->buffer.pointer, 404 original_object->string.pointer, 405 original_object->string.length); 406 break; 407 408 case ACPI_TYPE_PACKAGE: 409 /* 410 * This case is often seen for predefined names that must return a 411 * Buffer object with multiple DWORD integers within. For example, 412 * _FDE and _GTM. The Package can be converted to a Buffer. 413 */ 414 415 /* All elements of the Package must be integers */ 416 417 elements = original_object->package.elements; 418 count = original_object->package.count; 419 420 for (i = 0; i < count; i++) { 421 if ((!*elements) || 422 ((*elements)->common.type != ACPI_TYPE_INTEGER)) { 423 return (AE_AML_OPERAND_TYPE); 424 } 425 elements++; 426 } 427 428 /* Create the new buffer object to replace the Package */ 429 430 new_object = acpi_ut_create_buffer_object(ACPI_MUL_4(count)); 431 if (!new_object) { 432 return (AE_NO_MEMORY); 433 } 434 435 /* Copy the package elements (integers) to the buffer as DWORDs */ 436 437 elements = original_object->package.elements; 438 dword_buffer = ACPI_CAST_PTR(u32, new_object->buffer.pointer); 439 440 for (i = 0; i < count; i++) { 441 *dword_buffer = (u32) (*elements)->integer.value; 442 dword_buffer++; 443 elements++; 444 } 445 break; 446 447 default: 448 return (AE_AML_OPERAND_TYPE); 449 } 450 451 *return_object = new_object; 452 return (AE_OK); 453 } 454 455 /******************************************************************************* 456 * 457 * FUNCTION: acpi_ns_convert_to_package 458 * 459 * PARAMETERS: original_object - Object to be converted 460 * return_object - Where the new converted object is returned 461 * 462 * RETURN: Status. AE_OK if conversion was successful. 463 * 464 * DESCRIPTION: Attempt to convert a Buffer object to a Package. Each byte of 465 * the buffer is converted to a single integer package element. 466 * 467 ******************************************************************************/ 468 469 static acpi_status 470 acpi_ns_convert_to_package(union acpi_operand_object *original_object, 471 union acpi_operand_object **return_object) 472 { 473 union acpi_operand_object *new_object; 474 union acpi_operand_object **elements; 475 u32 length; 476 u8 *buffer; 477 478 switch (original_object->common.type) { 479 case ACPI_TYPE_BUFFER: 480 481 /* Buffer-to-Package conversion */ 482 483 length = original_object->buffer.length; 484 new_object = acpi_ut_create_package_object(length); 485 if (!new_object) { 486 return (AE_NO_MEMORY); 487 } 488 489 /* Convert each buffer byte to an integer package element */ 490 491 elements = new_object->package.elements; 492 buffer = original_object->buffer.pointer; 493 494 while (length--) { 495 *elements = 496 acpi_ut_create_integer_object((u64) *buffer); 497 if (!*elements) { 498 acpi_ut_remove_reference(new_object); 499 return (AE_NO_MEMORY); 500 } 501 elements++; 502 buffer++; 503 } 504 break; 505 506 default: 507 return (AE_AML_OPERAND_TYPE); 508 } 509 510 *return_object = new_object; 511 return (AE_OK); 512 } 513 514 /******************************************************************************* 515 * 516 * FUNCTION: acpi_ns_repair_null_element 517 * 518 * PARAMETERS: Data - Pointer to validation data structure 519 * expected_btypes - Object types expected 520 * package_index - Index of object within parent package (if 521 * applicable - ACPI_NOT_PACKAGE_ELEMENT 522 * otherwise) 523 * return_object_ptr - Pointer to the object returned from the 524 * evaluation of a method or object 525 * 526 * RETURN: Status. AE_OK if repair was successful. 527 * 528 * DESCRIPTION: Attempt to repair a NULL element of a returned Package object. 529 * 530 ******************************************************************************/ 531 532 acpi_status 533 acpi_ns_repair_null_element(struct acpi_predefined_data *data, 534 u32 expected_btypes, 535 u32 package_index, 536 union acpi_operand_object **return_object_ptr) 537 { 538 union acpi_operand_object *return_object = *return_object_ptr; 539 union acpi_operand_object *new_object; 540 541 ACPI_FUNCTION_NAME(ns_repair_null_element); 542 543 /* No repair needed if return object is non-NULL */ 544 545 if (return_object) { 546 return (AE_OK); 547 } 548 549 /* 550 * Attempt to repair a NULL element of a Package object. This applies to 551 * predefined names that return a fixed-length package and each element 552 * is required. It does not apply to variable-length packages where NULL 553 * elements are allowed, especially at the end of the package. 554 */ 555 if (expected_btypes & ACPI_RTYPE_INTEGER) { 556 557 /* Need an Integer - create a zero-value integer */ 558 559 new_object = acpi_ut_create_integer_object((u64)0); 560 } else if (expected_btypes & ACPI_RTYPE_STRING) { 561 562 /* Need a String - create a NULL string */ 563 564 new_object = acpi_ut_create_string_object(0); 565 } else if (expected_btypes & ACPI_RTYPE_BUFFER) { 566 567 /* Need a Buffer - create a zero-length buffer */ 568 569 new_object = acpi_ut_create_buffer_object(0); 570 } else { 571 /* Error for all other expected types */ 572 573 return (AE_AML_OPERAND_TYPE); 574 } 575 576 if (!new_object) { 577 return (AE_NO_MEMORY); 578 } 579 580 /* Set the reference count according to the parent Package object */ 581 582 new_object->common.reference_count = 583 data->parent_package->common.reference_count; 584 585 ACPI_DEBUG_PRINT((ACPI_DB_REPAIR, 586 "%s: Converted NULL package element to expected %s at index %u\n", 587 data->pathname, 588 acpi_ut_get_object_type_name(new_object), 589 package_index)); 590 591 *return_object_ptr = new_object; 592 data->flags |= ACPI_OBJECT_REPAIRED; 593 return (AE_OK); 594 } 595 596 /****************************************************************************** 597 * 598 * FUNCTION: acpi_ns_remove_null_elements 599 * 600 * PARAMETERS: Data - Pointer to validation data structure 601 * package_type - An acpi_return_package_types value 602 * obj_desc - A Package object 603 * 604 * RETURN: None. 605 * 606 * DESCRIPTION: Remove all NULL package elements from packages that contain 607 * a variable number of sub-packages. For these types of 608 * packages, NULL elements can be safely removed. 609 * 610 *****************************************************************************/ 611 612 void 613 acpi_ns_remove_null_elements(struct acpi_predefined_data *data, 614 u8 package_type, 615 union acpi_operand_object *obj_desc) 616 { 617 union acpi_operand_object **source; 618 union acpi_operand_object **dest; 619 u32 count; 620 u32 new_count; 621 u32 i; 622 623 ACPI_FUNCTION_NAME(ns_remove_null_elements); 624 625 /* 626 * PTYPE1 packages contain no subpackages. 627 * PTYPE2 packages contain a variable number of sub-packages. We can 628 * safely remove all NULL elements from the PTYPE2 packages. 629 */ 630 switch (package_type) { 631 case ACPI_PTYPE1_FIXED: 632 case ACPI_PTYPE1_VAR: 633 case ACPI_PTYPE1_OPTION: 634 return; 635 636 case ACPI_PTYPE2: 637 case ACPI_PTYPE2_COUNT: 638 case ACPI_PTYPE2_PKG_COUNT: 639 case ACPI_PTYPE2_FIXED: 640 case ACPI_PTYPE2_MIN: 641 case ACPI_PTYPE2_REV_FIXED: 642 break; 643 644 default: 645 return; 646 } 647 648 count = obj_desc->package.count; 649 new_count = count; 650 651 source = obj_desc->package.elements; 652 dest = source; 653 654 /* Examine all elements of the package object, remove nulls */ 655 656 for (i = 0; i < count; i++) { 657 if (!*source) { 658 new_count--; 659 } else { 660 *dest = *source; 661 dest++; 662 } 663 source++; 664 } 665 666 /* Update parent package if any null elements were removed */ 667 668 if (new_count < count) { 669 ACPI_DEBUG_PRINT((ACPI_DB_REPAIR, 670 "%s: Found and removed %u NULL elements\n", 671 data->pathname, (count - new_count))); 672 673 /* NULL terminate list and update the package count */ 674 675 *dest = NULL; 676 obj_desc->package.count = new_count; 677 } 678 } 679 680 /******************************************************************************* 681 * 682 * FUNCTION: acpi_ns_repair_package_list 683 * 684 * PARAMETERS: Data - Pointer to validation data structure 685 * obj_desc_ptr - Pointer to the object to repair. The new 686 * package object is returned here, 687 * overwriting the old object. 688 * 689 * RETURN: Status, new object in *obj_desc_ptr 690 * 691 * DESCRIPTION: Repair a common problem with objects that are defined to return 692 * a variable-length Package of Packages. If the variable-length 693 * is one, some BIOS code mistakenly simply declares a single 694 * Package instead of a Package with one sub-Package. This 695 * function attempts to repair this error by wrapping a Package 696 * object around the original Package, creating the correct 697 * Package with one sub-Package. 698 * 699 * Names that can be repaired in this manner include: 700 * _ALR, _CSD, _HPX, _MLS, _PRT, _PSS, _TRT, TSS 701 * 702 ******************************************************************************/ 703 704 acpi_status 705 acpi_ns_repair_package_list(struct acpi_predefined_data *data, 706 union acpi_operand_object **obj_desc_ptr) 707 { 708 union acpi_operand_object *pkg_obj_desc; 709 710 ACPI_FUNCTION_NAME(ns_repair_package_list); 711 712 /* 713 * Create the new outer package and populate it. The new package will 714 * have a single element, the lone subpackage. 715 */ 716 pkg_obj_desc = acpi_ut_create_package_object(1); 717 if (!pkg_obj_desc) { 718 return (AE_NO_MEMORY); 719 } 720 721 pkg_obj_desc->package.elements[0] = *obj_desc_ptr; 722 723 /* Return the new object in the object pointer */ 724 725 *obj_desc_ptr = pkg_obj_desc; 726 data->flags |= ACPI_OBJECT_REPAIRED; 727 728 ACPI_DEBUG_PRINT((ACPI_DB_REPAIR, 729 "%s: Repaired incorrectly formed Package\n", 730 data->pathname)); 731 732 return (AE_OK); 733 } 734