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