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