1 /****************************************************************************** 2 * 3 * Module Name: nsrepair - Repair for objects returned by predefined methods 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2016, 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 #include "amlresrc.h" 50 51 #define _COMPONENT ACPI_NAMESPACE 52 ACPI_MODULE_NAME("nsrepair") 53 54 /******************************************************************************* 55 * 56 * This module attempts to repair or convert objects returned by the 57 * predefined methods to an object type that is expected, as per the ACPI 58 * specification. The need for this code is dictated by the many machines that 59 * return incorrect types for the standard predefined methods. Performing these 60 * conversions here, in one place, eliminates the need for individual ACPI 61 * device drivers to do the same. Note: Most of these conversions are different 62 * than the internal object conversion routines used for implicit object 63 * conversion. 64 * 65 * The following conversions can be performed as necessary: 66 * 67 * Integer -> String 68 * Integer -> Buffer 69 * String -> Integer 70 * String -> Buffer 71 * Buffer -> Integer 72 * Buffer -> String 73 * Buffer -> Package of Integers 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 * 80 * An incorrect standalone object is wrapped with required outer package 81 * 82 * Additional possible repairs: 83 * Required package elements that are NULL replaced by Integer/String/Buffer 84 * 85 ******************************************************************************/ 86 /* Local prototypes */ 87 static const struct acpi_simple_repair_info *acpi_ns_match_simple_repair(struct 88 acpi_namespace_node 89 *node, 90 u32 91 return_btype, 92 u32 93 package_index); 94 95 /* 96 * Special but simple repairs for some names. 97 * 98 * 2nd argument: Unexpected types that can be repaired 99 */ 100 static const struct acpi_simple_repair_info acpi_object_repair_info[] = { 101 /* Resource descriptor conversions */ 102 103 {"_CRS", 104 ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING | ACPI_RTYPE_BUFFER | 105 ACPI_RTYPE_NONE, 106 ACPI_NOT_PACKAGE_ELEMENT, 107 acpi_ns_convert_to_resource}, 108 {"_DMA", 109 ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING | ACPI_RTYPE_BUFFER | 110 ACPI_RTYPE_NONE, 111 ACPI_NOT_PACKAGE_ELEMENT, 112 acpi_ns_convert_to_resource}, 113 {"_PRS", 114 ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING | ACPI_RTYPE_BUFFER | 115 ACPI_RTYPE_NONE, 116 ACPI_NOT_PACKAGE_ELEMENT, 117 acpi_ns_convert_to_resource}, 118 119 /* Object reference conversions */ 120 121 {"_DEP", ACPI_RTYPE_STRING, ACPI_ALL_PACKAGE_ELEMENTS, 122 acpi_ns_convert_to_reference}, 123 124 /* Unicode conversions */ 125 126 {"_MLS", ACPI_RTYPE_STRING, 1, 127 acpi_ns_convert_to_unicode}, 128 {"_STR", ACPI_RTYPE_STRING | ACPI_RTYPE_BUFFER, 129 ACPI_NOT_PACKAGE_ELEMENT, 130 acpi_ns_convert_to_unicode}, 131 {{0, 0, 0, 0}, 0, 0, NULL} /* Table terminator */ 132 }; 133 134 /******************************************************************************* 135 * 136 * FUNCTION: acpi_ns_simple_repair 137 * 138 * PARAMETERS: info - Method execution information block 139 * expected_btypes - Object types expected 140 * package_index - Index of object within parent package (if 141 * applicable - ACPI_NOT_PACKAGE_ELEMENT 142 * otherwise) 143 * return_object_ptr - Pointer to the object returned from the 144 * evaluation of a method or object 145 * 146 * RETURN: Status. AE_OK if repair was successful. 147 * 148 * DESCRIPTION: Attempt to repair/convert a return object of a type that was 149 * not expected. 150 * 151 ******************************************************************************/ 152 153 acpi_status 154 acpi_ns_simple_repair(struct acpi_evaluate_info *info, 155 u32 expected_btypes, 156 u32 package_index, 157 union acpi_operand_object **return_object_ptr) 158 { 159 union acpi_operand_object *return_object = *return_object_ptr; 160 union acpi_operand_object *new_object = NULL; 161 acpi_status status; 162 const struct acpi_simple_repair_info *predefined; 163 164 ACPI_FUNCTION_NAME(ns_simple_repair); 165 166 /* 167 * Special repairs for certain names that are in the repair table. 168 * Check if this name is in the list of repairable names. 169 */ 170 predefined = acpi_ns_match_simple_repair(info->node, 171 info->return_btype, 172 package_index); 173 if (predefined) { 174 if (!return_object) { 175 ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname, 176 ACPI_WARN_ALWAYS, 177 "Missing expected return value")); 178 } 179 180 status = predefined->object_converter(info->node, return_object, 181 &new_object); 182 if (ACPI_FAILURE(status)) { 183 184 /* A fatal error occurred during a conversion */ 185 186 ACPI_EXCEPTION((AE_INFO, status, 187 "During return object analysis")); 188 return (status); 189 } 190 if (new_object) { 191 goto object_repaired; 192 } 193 } 194 195 /* 196 * Do not perform simple object repair unless the return type is not 197 * expected. 198 */ 199 if (info->return_btype & expected_btypes) { 200 return (AE_OK); 201 } 202 203 /* 204 * At this point, we know that the type of the returned object was not 205 * one of the expected types for this predefined name. Attempt to 206 * repair the object by converting it to one of the expected object 207 * types for this predefined name. 208 */ 209 210 /* 211 * If there is no return value, check if we require a return value for 212 * this predefined name. Either one return value is expected, or none, 213 * for both methods and other objects. 214 * 215 * Try to fix if there was no return object. Warning if failed to fix. 216 */ 217 if (!return_object) { 218 if (expected_btypes && (!(expected_btypes & ACPI_RTYPE_NONE))) { 219 if (package_index != ACPI_NOT_PACKAGE_ELEMENT) { 220 ACPI_WARN_PREDEFINED((AE_INFO, 221 info->full_pathname, 222 ACPI_WARN_ALWAYS, 223 "Found unexpected NULL package element")); 224 225 status = 226 acpi_ns_repair_null_element(info, 227 expected_btypes, 228 package_index, 229 return_object_ptr); 230 if (ACPI_SUCCESS(status)) { 231 return (AE_OK); /* Repair was successful */ 232 } 233 } else { 234 ACPI_WARN_PREDEFINED((AE_INFO, 235 info->full_pathname, 236 ACPI_WARN_ALWAYS, 237 "Missing expected return value")); 238 } 239 240 return (AE_AML_NO_RETURN_VALUE); 241 } 242 } 243 244 if (expected_btypes & ACPI_RTYPE_INTEGER) { 245 status = acpi_ns_convert_to_integer(return_object, &new_object); 246 if (ACPI_SUCCESS(status)) { 247 goto object_repaired; 248 } 249 } 250 if (expected_btypes & ACPI_RTYPE_STRING) { 251 status = acpi_ns_convert_to_string(return_object, &new_object); 252 if (ACPI_SUCCESS(status)) { 253 goto object_repaired; 254 } 255 } 256 if (expected_btypes & ACPI_RTYPE_BUFFER) { 257 status = acpi_ns_convert_to_buffer(return_object, &new_object); 258 if (ACPI_SUCCESS(status)) { 259 goto object_repaired; 260 } 261 } 262 if (expected_btypes & ACPI_RTYPE_PACKAGE) { 263 /* 264 * A package is expected. We will wrap the existing object with a 265 * new package object. It is often the case that if a variable-length 266 * package is required, but there is only a single object needed, the 267 * BIOS will return that object instead of wrapping it with a Package 268 * object. Note: after the wrapping, the package will be validated 269 * for correct contents (expected object type or types). 270 */ 271 status = 272 acpi_ns_wrap_with_package(info, return_object, &new_object); 273 if (ACPI_SUCCESS(status)) { 274 /* 275 * The original object just had its reference count 276 * incremented for being inserted into the new package. 277 */ 278 *return_object_ptr = new_object; /* New Package object */ 279 info->return_flags |= ACPI_OBJECT_REPAIRED; 280 return (AE_OK); 281 } 282 } 283 284 /* We cannot repair this object */ 285 286 return (AE_AML_OPERAND_TYPE); 287 288 object_repaired: 289 290 /* Object was successfully repaired */ 291 292 if (package_index != ACPI_NOT_PACKAGE_ELEMENT) { 293 /* 294 * The original object is a package element. We need to 295 * decrement the reference count of the original object, 296 * for removing it from the package. 297 * 298 * However, if the original object was just wrapped with a 299 * package object as part of the repair, we don't need to 300 * change the reference count. 301 */ 302 if (!(info->return_flags & ACPI_OBJECT_WRAPPED)) { 303 new_object->common.reference_count = 304 return_object->common.reference_count; 305 306 if (return_object->common.reference_count > 1) { 307 return_object->common.reference_count--; 308 } 309 } 310 311 ACPI_DEBUG_PRINT((ACPI_DB_REPAIR, 312 "%s: Converted %s to expected %s at Package index %u\n", 313 info->full_pathname, 314 acpi_ut_get_object_type_name(return_object), 315 acpi_ut_get_object_type_name(new_object), 316 package_index)); 317 } else { 318 ACPI_DEBUG_PRINT((ACPI_DB_REPAIR, 319 "%s: Converted %s to expected %s\n", 320 info->full_pathname, 321 acpi_ut_get_object_type_name(return_object), 322 acpi_ut_get_object_type_name(new_object))); 323 } 324 325 /* Delete old object, install the new return object */ 326 327 acpi_ut_remove_reference(return_object); 328 *return_object_ptr = new_object; 329 info->return_flags |= ACPI_OBJECT_REPAIRED; 330 return (AE_OK); 331 } 332 333 /****************************************************************************** 334 * 335 * FUNCTION: acpi_ns_match_simple_repair 336 * 337 * PARAMETERS: node - Namespace node for the method/object 338 * return_btype - Object type that was returned 339 * package_index - Index of object within parent package (if 340 * applicable - ACPI_NOT_PACKAGE_ELEMENT 341 * otherwise) 342 * 343 * RETURN: Pointer to entry in repair table. NULL indicates not found. 344 * 345 * DESCRIPTION: Check an object name against the repairable object list. 346 * 347 *****************************************************************************/ 348 349 static const struct acpi_simple_repair_info *acpi_ns_match_simple_repair(struct 350 acpi_namespace_node 351 *node, 352 u32 353 return_btype, 354 u32 355 package_index) 356 { 357 const struct acpi_simple_repair_info *this_name; 358 359 /* Search info table for a repairable predefined method/object name */ 360 361 this_name = acpi_object_repair_info; 362 while (this_name->object_converter) { 363 if (ACPI_COMPARE_NAME(node->name.ascii, this_name->name)) { 364 365 /* Check if we can actually repair this name/type combination */ 366 367 if ((return_btype & this_name->unexpected_btypes) && 368 (this_name->package_index == 369 ACPI_ALL_PACKAGE_ELEMENTS 370 || package_index == this_name->package_index)) { 371 return (this_name); 372 } 373 374 return (NULL); 375 } 376 377 this_name++; 378 } 379 380 return (NULL); /* Name was not found in the repair table */ 381 } 382 383 /******************************************************************************* 384 * 385 * FUNCTION: acpi_ns_repair_null_element 386 * 387 * PARAMETERS: info - Method execution information block 388 * expected_btypes - Object types expected 389 * package_index - Index of object within parent package (if 390 * applicable - ACPI_NOT_PACKAGE_ELEMENT 391 * otherwise) 392 * return_object_ptr - Pointer to the object returned from the 393 * evaluation of a method or object 394 * 395 * RETURN: Status. AE_OK if repair was successful. 396 * 397 * DESCRIPTION: Attempt to repair a NULL element of a returned Package object. 398 * 399 ******************************************************************************/ 400 401 acpi_status 402 acpi_ns_repair_null_element(struct acpi_evaluate_info *info, 403 u32 expected_btypes, 404 u32 package_index, 405 union acpi_operand_object **return_object_ptr) 406 { 407 union acpi_operand_object *return_object = *return_object_ptr; 408 union acpi_operand_object *new_object; 409 410 ACPI_FUNCTION_NAME(ns_repair_null_element); 411 412 /* No repair needed if return object is non-NULL */ 413 414 if (return_object) { 415 return (AE_OK); 416 } 417 418 /* 419 * Attempt to repair a NULL element of a Package object. This applies to 420 * predefined names that return a fixed-length package and each element 421 * is required. It does not apply to variable-length packages where NULL 422 * elements are allowed, especially at the end of the package. 423 */ 424 if (expected_btypes & ACPI_RTYPE_INTEGER) { 425 426 /* Need an integer - create a zero-value integer */ 427 428 new_object = acpi_ut_create_integer_object((u64)0); 429 } else if (expected_btypes & ACPI_RTYPE_STRING) { 430 431 /* Need a string - create a NULL string */ 432 433 new_object = acpi_ut_create_string_object(0); 434 } else if (expected_btypes & ACPI_RTYPE_BUFFER) { 435 436 /* Need a buffer - create a zero-length buffer */ 437 438 new_object = acpi_ut_create_buffer_object(0); 439 } else { 440 /* Error for all other expected types */ 441 442 return (AE_AML_OPERAND_TYPE); 443 } 444 445 if (!new_object) { 446 return (AE_NO_MEMORY); 447 } 448 449 /* Set the reference count according to the parent Package object */ 450 451 new_object->common.reference_count = 452 info->parent_package->common.reference_count; 453 454 ACPI_DEBUG_PRINT((ACPI_DB_REPAIR, 455 "%s: Converted NULL package element to expected %s at index %u\n", 456 info->full_pathname, 457 acpi_ut_get_object_type_name(new_object), 458 package_index)); 459 460 *return_object_ptr = new_object; 461 info->return_flags |= ACPI_OBJECT_REPAIRED; 462 return (AE_OK); 463 } 464 465 /****************************************************************************** 466 * 467 * FUNCTION: acpi_ns_remove_null_elements 468 * 469 * PARAMETERS: info - Method execution information block 470 * package_type - An acpi_return_package_types value 471 * obj_desc - A Package object 472 * 473 * RETURN: None. 474 * 475 * DESCRIPTION: Remove all NULL package elements from packages that contain 476 * a variable number of subpackages. For these types of 477 * packages, NULL elements can be safely removed. 478 * 479 *****************************************************************************/ 480 481 void 482 acpi_ns_remove_null_elements(struct acpi_evaluate_info *info, 483 u8 package_type, 484 union acpi_operand_object *obj_desc) 485 { 486 union acpi_operand_object **source; 487 union acpi_operand_object **dest; 488 u32 count; 489 u32 new_count; 490 u32 i; 491 492 ACPI_FUNCTION_NAME(ns_remove_null_elements); 493 494 /* 495 * We can safely remove all NULL elements from these package types: 496 * PTYPE1_VAR packages contain a variable number of simple data types. 497 * PTYPE2 packages contain a variable number of subpackages. 498 */ 499 switch (package_type) { 500 case ACPI_PTYPE1_VAR: 501 case ACPI_PTYPE2: 502 case ACPI_PTYPE2_COUNT: 503 case ACPI_PTYPE2_PKG_COUNT: 504 case ACPI_PTYPE2_FIXED: 505 case ACPI_PTYPE2_MIN: 506 case ACPI_PTYPE2_REV_FIXED: 507 case ACPI_PTYPE2_FIX_VAR: 508 break; 509 510 default: 511 case ACPI_PTYPE2_VAR_VAR: 512 case ACPI_PTYPE1_FIXED: 513 case ACPI_PTYPE1_OPTION: 514 return; 515 } 516 517 count = obj_desc->package.count; 518 new_count = count; 519 520 source = obj_desc->package.elements; 521 dest = source; 522 523 /* Examine all elements of the package object, remove nulls */ 524 525 for (i = 0; i < count; i++) { 526 if (!*source) { 527 new_count--; 528 } else { 529 *dest = *source; 530 dest++; 531 } 532 533 source++; 534 } 535 536 /* Update parent package if any null elements were removed */ 537 538 if (new_count < count) { 539 ACPI_DEBUG_PRINT((ACPI_DB_REPAIR, 540 "%s: Found and removed %u NULL elements\n", 541 info->full_pathname, (count - new_count))); 542 543 /* NULL terminate list and update the package count */ 544 545 *dest = NULL; 546 obj_desc->package.count = new_count; 547 } 548 } 549 550 /******************************************************************************* 551 * 552 * FUNCTION: acpi_ns_wrap_with_package 553 * 554 * PARAMETERS: info - Method execution information block 555 * original_object - Pointer to the object to repair. 556 * obj_desc_ptr - The new package object is returned here 557 * 558 * RETURN: Status, new object in *obj_desc_ptr 559 * 560 * DESCRIPTION: Repair a common problem with objects that are defined to 561 * return a variable-length Package of sub-objects. If there is 562 * only one sub-object, some BIOS code mistakenly simply declares 563 * the single object instead of a Package with one sub-object. 564 * This function attempts to repair this error by wrapping a 565 * Package object around the original object, creating the 566 * correct and expected Package with one sub-object. 567 * 568 * Names that can be repaired in this manner include: 569 * _ALR, _CSD, _HPX, _MLS, _PLD, _PRT, _PSS, _TRT, _TSS, 570 * _BCL, _DOD, _FIX, _Sx 571 * 572 ******************************************************************************/ 573 574 acpi_status 575 acpi_ns_wrap_with_package(struct acpi_evaluate_info *info, 576 union acpi_operand_object *original_object, 577 union acpi_operand_object **obj_desc_ptr) 578 { 579 union acpi_operand_object *pkg_obj_desc; 580 581 ACPI_FUNCTION_NAME(ns_wrap_with_package); 582 583 /* 584 * Create the new outer package and populate it. The new 585 * package will have a single element, the lone sub-object. 586 */ 587 pkg_obj_desc = acpi_ut_create_package_object(1); 588 if (!pkg_obj_desc) { 589 return (AE_NO_MEMORY); 590 } 591 592 pkg_obj_desc->package.elements[0] = original_object; 593 594 ACPI_DEBUG_PRINT((ACPI_DB_REPAIR, 595 "%s: Wrapped %s with expected Package object\n", 596 info->full_pathname, 597 acpi_ut_get_object_type_name(original_object))); 598 599 /* Return the new object in the object pointer */ 600 601 *obj_desc_ptr = pkg_obj_desc; 602 info->return_flags |= ACPI_OBJECT_REPAIRED | ACPI_OBJECT_WRAPPED; 603 return (AE_OK); 604 } 605