1 /****************************************************************************** 2 * 3 * Module Name: nsrepair - Repair for objects returned by predefined methods 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2012, 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 * An incorrect standalone object is wrapped with required outer package 75 * 76 * Additional possible repairs: 77 * Required package elements that are NULL replaced by Integer/String/Buffer 78 * 79 ******************************************************************************/ 80 /* Local prototypes */ 81 static acpi_status 82 acpi_ns_convert_to_integer(union acpi_operand_object *original_object, 83 union acpi_operand_object **return_object); 84 85 static acpi_status 86 acpi_ns_convert_to_string(union acpi_operand_object *original_object, 87 union acpi_operand_object **return_object); 88 89 static acpi_status 90 acpi_ns_convert_to_buffer(union acpi_operand_object *original_object, 91 union acpi_operand_object **return_object); 92 93 /******************************************************************************* 94 * 95 * FUNCTION: acpi_ns_repair_object 96 * 97 * PARAMETERS: data - Pointer to validation data structure 98 * expected_btypes - Object types expected 99 * package_index - Index of object within parent package (if 100 * applicable - ACPI_NOT_PACKAGE_ELEMENT 101 * otherwise) 102 * return_object_ptr - Pointer to the object returned from the 103 * evaluation of a method or object 104 * 105 * RETURN: Status. AE_OK if repair was successful. 106 * 107 * DESCRIPTION: Attempt to repair/convert a return object of a type that was 108 * not expected. 109 * 110 ******************************************************************************/ 111 112 acpi_status 113 acpi_ns_repair_object(struct acpi_predefined_data *data, 114 u32 expected_btypes, 115 u32 package_index, 116 union acpi_operand_object **return_object_ptr) 117 { 118 union acpi_operand_object *return_object = *return_object_ptr; 119 union acpi_operand_object *new_object; 120 acpi_status status; 121 122 ACPI_FUNCTION_NAME(ns_repair_object); 123 124 /* 125 * At this point, we know that the type of the returned object was not 126 * one of the expected types for this predefined name. Attempt to 127 * repair the object by converting it to one of the expected object 128 * types for this predefined name. 129 */ 130 if (expected_btypes & ACPI_RTYPE_INTEGER) { 131 status = acpi_ns_convert_to_integer(return_object, &new_object); 132 if (ACPI_SUCCESS(status)) { 133 goto object_repaired; 134 } 135 } 136 if (expected_btypes & ACPI_RTYPE_STRING) { 137 status = acpi_ns_convert_to_string(return_object, &new_object); 138 if (ACPI_SUCCESS(status)) { 139 goto object_repaired; 140 } 141 } 142 if (expected_btypes & ACPI_RTYPE_BUFFER) { 143 status = acpi_ns_convert_to_buffer(return_object, &new_object); 144 if (ACPI_SUCCESS(status)) { 145 goto object_repaired; 146 } 147 } 148 if (expected_btypes & ACPI_RTYPE_PACKAGE) { 149 /* 150 * A package is expected. We will wrap the existing object with a 151 * new package object. It is often the case that if a variable-length 152 * package is required, but there is only a single object needed, the 153 * BIOS will return that object instead of wrapping it with a Package 154 * object. Note: after the wrapping, the package will be validated 155 * for correct contents (expected object type or types). 156 */ 157 status = 158 acpi_ns_wrap_with_package(data, return_object, &new_object); 159 if (ACPI_SUCCESS(status)) { 160 /* 161 * The original object just had its reference count 162 * incremented for being inserted into the new package. 163 */ 164 *return_object_ptr = new_object; /* New Package object */ 165 data->flags |= ACPI_OBJECT_REPAIRED; 166 return (AE_OK); 167 } 168 } 169 170 /* We cannot repair this object */ 171 172 return (AE_AML_OPERAND_TYPE); 173 174 object_repaired: 175 176 /* Object was successfully repaired */ 177 178 if (package_index != ACPI_NOT_PACKAGE_ELEMENT) { 179 /* 180 * The original object is a package element. We need to 181 * decrement the reference count of the original object, 182 * for removing it from the package. 183 * 184 * However, if the original object was just wrapped with a 185 * package object as part of the repair, we don't need to 186 * change the reference count. 187 */ 188 if (!(data->flags & ACPI_OBJECT_WRAPPED)) { 189 new_object->common.reference_count = 190 return_object->common.reference_count; 191 192 if (return_object->common.reference_count > 1) { 193 return_object->common.reference_count--; 194 } 195 } 196 197 ACPI_DEBUG_PRINT((ACPI_DB_REPAIR, 198 "%s: Converted %s to expected %s at Package index %u\n", 199 data->pathname, 200 acpi_ut_get_object_type_name(return_object), 201 acpi_ut_get_object_type_name(new_object), 202 package_index)); 203 } else { 204 ACPI_DEBUG_PRINT((ACPI_DB_REPAIR, 205 "%s: Converted %s to expected %s\n", 206 data->pathname, 207 acpi_ut_get_object_type_name(return_object), 208 acpi_ut_get_object_type_name(new_object))); 209 } 210 211 /* Delete old object, install the new return object */ 212 213 acpi_ut_remove_reference(return_object); 214 *return_object_ptr = new_object; 215 data->flags |= ACPI_OBJECT_REPAIRED; 216 return (AE_OK); 217 } 218 219 /******************************************************************************* 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 232 static acpi_status 233 acpi_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 296 static acpi_status 297 acpi_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 * 368 * FUNCTION: acpi_ns_convert_to_buffer 369 * 370 * PARAMETERS: original_object - Object to be converted 371 * return_object - Where the new converted object is returned 372 * 373 * RETURN: Status. AE_OK if conversion was successful. 374 * 375 * DESCRIPTION: Attempt to convert a Integer/String/Package object to a Buffer. 376 * 377 ******************************************************************************/ 378 379 static acpi_status 380 acpi_ns_convert_to_buffer(union acpi_operand_object *original_object, 381 union acpi_operand_object **return_object) 382 { 383 union acpi_operand_object *new_object; 384 acpi_status status; 385 union acpi_operand_object **elements; 386 u32 *dword_buffer; 387 u32 count; 388 u32 i; 389 390 switch (original_object->common.type) { 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 406 case ACPI_TYPE_STRING: 407 408 /* String-to-Buffer conversion. Simple data copy */ 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 417 ACPI_MEMCPY(new_object->buffer.pointer, 418 original_object->string.pointer, 419 original_object->string.length); 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 } 439 elements++; 440 } 441 442 /* Create the new buffer object to replace the Package */ 443 444 new_object = acpi_ut_create_buffer_object(ACPI_MUL_4(count)); 445 if (!new_object) { 446 return (AE_NO_MEMORY); 447 } 448 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 } 464 465 *return_object = new_object; 466 return (AE_OK); 467 } 468 469 /******************************************************************************* 470 * 471 * FUNCTION: acpi_ns_repair_null_element 472 * 473 * PARAMETERS: data - Pointer to validation data structure 474 * expected_btypes - Object types expected 475 * package_index - Index of object within parent package (if 476 * applicable - ACPI_NOT_PACKAGE_ELEMENT 477 * otherwise) 478 * return_object_ptr - Pointer to the object returned from the 479 * evaluation of a method or object 480 * 481 * RETURN: Status. AE_OK if repair was successful. 482 * 483 * DESCRIPTION: Attempt to repair a NULL element of a returned Package object. 484 * 485 ******************************************************************************/ 486 487 acpi_status 488 acpi_ns_repair_null_element(struct acpi_predefined_data *data, 489 u32 expected_btypes, 490 u32 package_index, 491 union acpi_operand_object **return_object_ptr) 492 { 493 union acpi_operand_object *return_object = *return_object_ptr; 494 union acpi_operand_object *new_object; 495 496 ACPI_FUNCTION_NAME(ns_repair_null_element); 497 498 /* No repair needed if return object is non-NULL */ 499 500 if (return_object) { 501 return (AE_OK); 502 } 503 504 /* 505 * Attempt to repair a NULL element of a Package object. This applies to 506 * predefined names that return a fixed-length package and each element 507 * is required. It does not apply to variable-length packages where NULL 508 * elements are allowed, especially at the end of the package. 509 */ 510 if (expected_btypes & ACPI_RTYPE_INTEGER) { 511 512 /* Need an integer - create a zero-value integer */ 513 514 new_object = acpi_ut_create_integer_object((u64)0); 515 } else if (expected_btypes & ACPI_RTYPE_STRING) { 516 517 /* Need a string - create a NULL string */ 518 519 new_object = acpi_ut_create_string_object(0); 520 } else if (expected_btypes & ACPI_RTYPE_BUFFER) { 521 522 /* Need a buffer - create a zero-length buffer */ 523 524 new_object = acpi_ut_create_buffer_object(0); 525 } else { 526 /* Error for all other expected types */ 527 528 return (AE_AML_OPERAND_TYPE); 529 } 530 531 if (!new_object) { 532 return (AE_NO_MEMORY); 533 } 534 535 /* Set the reference count according to the parent Package object */ 536 537 new_object->common.reference_count = 538 data->parent_package->common.reference_count; 539 540 ACPI_DEBUG_PRINT((ACPI_DB_REPAIR, 541 "%s: Converted NULL package element to expected %s at index %u\n", 542 data->pathname, 543 acpi_ut_get_object_type_name(new_object), 544 package_index)); 545 546 *return_object_ptr = new_object; 547 data->flags |= ACPI_OBJECT_REPAIRED; 548 return (AE_OK); 549 } 550 551 /****************************************************************************** 552 * 553 * FUNCTION: acpi_ns_remove_null_elements 554 * 555 * PARAMETERS: data - Pointer to validation data structure 556 * package_type - An acpi_return_package_types value 557 * obj_desc - A Package object 558 * 559 * RETURN: None. 560 * 561 * DESCRIPTION: Remove all NULL package elements from packages that contain 562 * a variable number of sub-packages. For these types of 563 * packages, NULL elements can be safely removed. 564 * 565 *****************************************************************************/ 566 567 void 568 acpi_ns_remove_null_elements(struct acpi_predefined_data *data, 569 u8 package_type, 570 union acpi_operand_object *obj_desc) 571 { 572 union acpi_operand_object **source; 573 union acpi_operand_object **dest; 574 u32 count; 575 u32 new_count; 576 u32 i; 577 578 ACPI_FUNCTION_NAME(ns_remove_null_elements); 579 580 /* 581 * We can safely remove all NULL elements from these package types: 582 * PTYPE1_VAR packages contain a variable number of simple data types. 583 * PTYPE2 packages contain a variable number of sub-packages. 584 */ 585 switch (package_type) { 586 case ACPI_PTYPE1_VAR: 587 case ACPI_PTYPE2: 588 case ACPI_PTYPE2_COUNT: 589 case ACPI_PTYPE2_PKG_COUNT: 590 case ACPI_PTYPE2_FIXED: 591 case ACPI_PTYPE2_MIN: 592 case ACPI_PTYPE2_REV_FIXED: 593 case ACPI_PTYPE2_FIX_VAR: 594 break; 595 596 default: 597 case ACPI_PTYPE1_FIXED: 598 case ACPI_PTYPE1_OPTION: 599 return; 600 } 601 602 count = obj_desc->package.count; 603 new_count = count; 604 605 source = obj_desc->package.elements; 606 dest = source; 607 608 /* Examine all elements of the package object, remove nulls */ 609 610 for (i = 0; i < count; i++) { 611 if (!*source) { 612 new_count--; 613 } else { 614 *dest = *source; 615 dest++; 616 } 617 source++; 618 } 619 620 /* Update parent package if any null elements were removed */ 621 622 if (new_count < count) { 623 ACPI_DEBUG_PRINT((ACPI_DB_REPAIR, 624 "%s: Found and removed %u NULL elements\n", 625 data->pathname, (count - new_count))); 626 627 /* NULL terminate list and update the package count */ 628 629 *dest = NULL; 630 obj_desc->package.count = new_count; 631 } 632 } 633 634 /******************************************************************************* 635 * 636 * FUNCTION: acpi_ns_wrap_with_package 637 * 638 * PARAMETERS: data - Pointer to validation data structure 639 * original_object - Pointer to the object to repair. 640 * obj_desc_ptr - The new package object is returned here 641 * 642 * RETURN: Status, new object in *obj_desc_ptr 643 * 644 * DESCRIPTION: Repair a common problem with objects that are defined to 645 * return a variable-length Package of sub-objects. If there is 646 * only one sub-object, some BIOS code mistakenly simply declares 647 * the single object instead of a Package with one sub-object. 648 * This function attempts to repair this error by wrapping a 649 * Package object around the original object, creating the 650 * correct and expected Package with one sub-object. 651 * 652 * Names that can be repaired in this manner include: 653 * _ALR, _CSD, _HPX, _MLS, _PLD, _PRT, _PSS, _TRT, _TSS, 654 * _BCL, _DOD, _FIX, _Sx 655 * 656 ******************************************************************************/ 657 658 acpi_status 659 acpi_ns_wrap_with_package(struct acpi_predefined_data *data, 660 union acpi_operand_object *original_object, 661 union acpi_operand_object **obj_desc_ptr) 662 { 663 union acpi_operand_object *pkg_obj_desc; 664 665 ACPI_FUNCTION_NAME(ns_wrap_with_package); 666 667 /* 668 * Create the new outer package and populate it. The new package will 669 * have a single element, the lone sub-object. 670 */ 671 pkg_obj_desc = acpi_ut_create_package_object(1); 672 if (!pkg_obj_desc) { 673 return (AE_NO_MEMORY); 674 } 675 676 pkg_obj_desc->package.elements[0] = original_object; 677 678 ACPI_DEBUG_PRINT((ACPI_DB_REPAIR, 679 "%s: Wrapped %s with expected Package object\n", 680 data->pathname, 681 acpi_ut_get_object_type_name(original_object))); 682 683 /* Return the new object in the object pointer */ 684 685 *obj_desc_ptr = pkg_obj_desc; 686 data->flags |= ACPI_OBJECT_REPAIRED | ACPI_OBJECT_WRAPPED; 687 return (AE_OK); 688 } 689