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