Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygennsrepair.c
Go to the documentation of this file.
00001 /****************************************************************************** 00002 * 00003 * Module Name: nsrepair - Repair for objects returned by predefined methods 00004 * 00005 *****************************************************************************/ 00006 00007 /****************************************************************************** 00008 * 00009 * 1. Copyright Notice 00010 * 00011 * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp. 00012 * All rights reserved. 00013 * 00014 * 2. License 00015 * 00016 * 2.1. This is your license from Intel Corp. under its intellectual property 00017 * rights. You may have additional license terms from the party that provided 00018 * you this software, covering your right to use that party's intellectual 00019 * property rights. 00020 * 00021 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 00022 * copy of the source code appearing in this file ("Covered Code") an 00023 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 00024 * base code distributed originally by Intel ("Original Intel Code") to copy, 00025 * make derivatives, distribute, use and display any portion of the Covered 00026 * Code in any form, with the right to sublicense such rights; and 00027 * 00028 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 00029 * license (with the right to sublicense), under only those claims of Intel 00030 * patents that are infringed by the Original Intel Code, to make, use, sell, 00031 * offer to sell, and import the Covered Code and derivative works thereof 00032 * solely to the minimum extent necessary to exercise the above copyright 00033 * license, and in no event shall the patent license extend to any additions 00034 * to or modifications of the Original Intel Code. No other license or right 00035 * is granted directly or by implication, estoppel or otherwise; 00036 * 00037 * The above copyright and patent license is granted only if the following 00038 * conditions are met: 00039 * 00040 * 3. Conditions 00041 * 00042 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 00043 * Redistribution of source code of any substantial portion of the Covered 00044 * Code or modification with rights to further distribute source must include 00045 * the above Copyright Notice, the above License, this list of Conditions, 00046 * and the following Disclaimer and Export Compliance provision. In addition, 00047 * Licensee must cause all Covered Code to which Licensee contributes to 00048 * contain a file documenting the changes Licensee made to create that Covered 00049 * Code and the date of any change. Licensee must include in that file the 00050 * documentation of any changes made by any predecessor Licensee. Licensee 00051 * must include a prominent statement that the modification is derived, 00052 * directly or indirectly, from Original Intel Code. 00053 * 00054 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 00055 * Redistribution of source code of any substantial portion of the Covered 00056 * Code or modification without rights to further distribute source must 00057 * include the following Disclaimer and Export Compliance provision in the 00058 * documentation and/or other materials provided with distribution. In 00059 * addition, Licensee may not authorize further sublicense of source of any 00060 * portion of the Covered Code, and must include terms to the effect that the 00061 * license from Licensee to its licensee is limited to the intellectual 00062 * property embodied in the software Licensee provides to its licensee, and 00063 * not to intellectual property embodied in modifications its licensee may 00064 * make. 00065 * 00066 * 3.3. Redistribution of Executable. Redistribution in executable form of any 00067 * substantial portion of the Covered Code or modification must reproduce the 00068 * above Copyright Notice, and the following Disclaimer and Export Compliance 00069 * provision in the documentation and/or other materials provided with the 00070 * distribution. 00071 * 00072 * 3.4. Intel retains all right, title, and interest in and to the Original 00073 * Intel Code. 00074 * 00075 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 00076 * Intel shall be used in advertising or otherwise to promote the sale, use or 00077 * other dealings in products derived from or relating to the Covered Code 00078 * without prior written authorization from Intel. 00079 * 00080 * 4. Disclaimer and Export Compliance 00081 * 00082 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 00083 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 00084 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 00085 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 00086 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 00087 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 00088 * PARTICULAR PURPOSE. 00089 * 00090 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 00091 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 00092 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 00093 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 00094 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 00095 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 00096 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 00097 * LIMITED REMEDY. 00098 * 00099 * 4.3. Licensee shall not export, either directly or indirectly, any of this 00100 * software or system incorporating such software without first obtaining any 00101 * required license or other approval from the U. S. Department of Commerce or 00102 * any other agency or department of the United States Government. In the 00103 * event Licensee exports any such software from the United States or 00104 * re-exports any such software from a foreign destination, Licensee shall 00105 * ensure that the distribution and export/re-export of the software is in 00106 * compliance with all laws, regulations, orders, or other restrictions of the 00107 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 00108 * any of its subsidiaries will export/re-export any technical data, process, 00109 * software, or service, directly or indirectly, to any country for which the 00110 * United States government or any agency thereof requires an export license, 00111 * other governmental approval, or letter of assurance, without first obtaining 00112 * such license, approval or letter. 00113 * 00114 *****************************************************************************/ 00115 00116 #define __NSREPAIR_C__ 00117 00118 #include "acpi.h" 00119 #include "accommon.h" 00120 #include "acnamesp.h" 00121 #include "acinterp.h" 00122 #include "acpredef.h" 00123 00124 #define _COMPONENT ACPI_NAMESPACE 00125 ACPI_MODULE_NAME ("nsrepair") 00126 00127 00128 /******************************************************************************* 00129 * 00130 * This module attempts to repair or convert objects returned by the 00131 * predefined methods to an object type that is expected, as per the ACPI 00132 * specification. The need for this code is dictated by the many machines that 00133 * return incorrect types for the standard predefined methods. Performing these 00134 * conversions here, in one place, eliminates the need for individual ACPI 00135 * device drivers to do the same. Note: Most of these conversions are different 00136 * than the internal object conversion routines used for implicit object 00137 * conversion. 00138 * 00139 * The following conversions can be performed as necessary: 00140 * 00141 * Integer -> String 00142 * Integer -> Buffer 00143 * String -> Integer 00144 * String -> Buffer 00145 * Buffer -> Integer 00146 * Buffer -> String 00147 * Buffer -> Package of Integers 00148 * Package -> Package of one Package 00149 * 00150 * Additional possible repairs: 00151 * 00152 * Required package elements that are NULL replaced by Integer/String/Buffer 00153 * Incorrect standalone package wrapped with required outer package 00154 * 00155 ******************************************************************************/ 00156 00157 00158 /* Local prototypes */ 00159 00160 static ACPI_STATUS 00161 AcpiNsConvertToInteger ( 00162 ACPI_OPERAND_OBJECT *OriginalObject, 00163 ACPI_OPERAND_OBJECT **ReturnObject); 00164 00165 static ACPI_STATUS 00166 AcpiNsConvertToString ( 00167 ACPI_OPERAND_OBJECT *OriginalObject, 00168 ACPI_OPERAND_OBJECT **ReturnObject); 00169 00170 static ACPI_STATUS 00171 AcpiNsConvertToBuffer ( 00172 ACPI_OPERAND_OBJECT *OriginalObject, 00173 ACPI_OPERAND_OBJECT **ReturnObject); 00174 00175 static ACPI_STATUS 00176 AcpiNsConvertToPackage ( 00177 ACPI_OPERAND_OBJECT *OriginalObject, 00178 ACPI_OPERAND_OBJECT **ReturnObject); 00179 00180 00181 /******************************************************************************* 00182 * 00183 * FUNCTION: AcpiNsRepairObject 00184 * 00185 * PARAMETERS: Data - Pointer to validation data structure 00186 * ExpectedBtypes - Object types expected 00187 * PackageIndex - Index of object within parent package (if 00188 * applicable - ACPI_NOT_PACKAGE_ELEMENT 00189 * otherwise) 00190 * ReturnObjectPtr - Pointer to the object returned from the 00191 * evaluation of a method or object 00192 * 00193 * RETURN: Status. AE_OK if repair was successful. 00194 * 00195 * DESCRIPTION: Attempt to repair/convert a return object of a type that was 00196 * not expected. 00197 * 00198 ******************************************************************************/ 00199 00200 ACPI_STATUS 00201 AcpiNsRepairObject ( 00202 ACPI_PREDEFINED_DATA *Data, 00203 UINT32 ExpectedBtypes, 00204 UINT32 PackageIndex, 00205 ACPI_OPERAND_OBJECT **ReturnObjectPtr) 00206 { 00207 ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 00208 ACPI_OPERAND_OBJECT *NewObject; 00209 ACPI_STATUS Status; 00210 00211 00212 ACPI_FUNCTION_NAME (NsRepairObject); 00213 00214 00215 /* 00216 * At this point, we know that the type of the returned object was not 00217 * one of the expected types for this predefined name. Attempt to 00218 * repair the object by converting it to one of the expected object 00219 * types for this predefined name. 00220 */ 00221 if (ExpectedBtypes & ACPI_RTYPE_INTEGER) 00222 { 00223 Status = AcpiNsConvertToInteger (ReturnObject, &NewObject); 00224 if (ACPI_SUCCESS (Status)) 00225 { 00226 goto ObjectRepaired; 00227 } 00228 } 00229 if (ExpectedBtypes & ACPI_RTYPE_STRING) 00230 { 00231 Status = AcpiNsConvertToString (ReturnObject, &NewObject); 00232 if (ACPI_SUCCESS (Status)) 00233 { 00234 goto ObjectRepaired; 00235 } 00236 } 00237 if (ExpectedBtypes & ACPI_RTYPE_BUFFER) 00238 { 00239 Status = AcpiNsConvertToBuffer (ReturnObject, &NewObject); 00240 if (ACPI_SUCCESS (Status)) 00241 { 00242 goto ObjectRepaired; 00243 } 00244 } 00245 if (ExpectedBtypes & ACPI_RTYPE_PACKAGE) 00246 { 00247 Status = AcpiNsConvertToPackage (ReturnObject, &NewObject); 00248 if (ACPI_SUCCESS (Status)) 00249 { 00250 goto ObjectRepaired; 00251 } 00252 } 00253 00254 /* We cannot repair this object */ 00255 00256 return (AE_AML_OPERAND_TYPE); 00257 00258 00259 ObjectRepaired: 00260 00261 /* Object was successfully repaired */ 00262 00263 /* 00264 * If the original object is a package element, we need to: 00265 * 1. Set the reference count of the new object to match the 00266 * reference count of the old object. 00267 * 2. Decrement the reference count of the original object. 00268 */ 00269 if (PackageIndex != ACPI_NOT_PACKAGE_ELEMENT) 00270 { 00271 NewObject->Common.ReferenceCount = 00272 ReturnObject->Common.ReferenceCount; 00273 00274 if (ReturnObject->Common.ReferenceCount > 1) 00275 { 00276 ReturnObject->Common.ReferenceCount--; 00277 } 00278 00279 ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR, 00280 "%s: Converted %s to expected %s at index %u\n", 00281 Data->Pathname, AcpiUtGetObjectTypeName (ReturnObject), 00282 AcpiUtGetObjectTypeName (NewObject), PackageIndex)); 00283 } 00284 else 00285 { 00286 ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR, 00287 "%s: Converted %s to expected %s\n", 00288 Data->Pathname, AcpiUtGetObjectTypeName (ReturnObject), 00289 AcpiUtGetObjectTypeName (NewObject))); 00290 } 00291 00292 /* Delete old object, install the new return object */ 00293 00294 AcpiUtRemoveReference (ReturnObject); 00295 *ReturnObjectPtr = NewObject; 00296 Data->Flags |= ACPI_OBJECT_REPAIRED; 00297 return (AE_OK); 00298 } 00299 00300 00301 /******************************************************************************* 00302 * 00303 * FUNCTION: AcpiNsConvertToInteger 00304 * 00305 * PARAMETERS: OriginalObject - Object to be converted 00306 * ReturnObject - Where the new converted object is returned 00307 * 00308 * RETURN: Status. AE_OK if conversion was successful. 00309 * 00310 * DESCRIPTION: Attempt to convert a String/Buffer object to an Integer. 00311 * 00312 ******************************************************************************/ 00313 00314 static ACPI_STATUS 00315 AcpiNsConvertToInteger ( 00316 ACPI_OPERAND_OBJECT *OriginalObject, 00317 ACPI_OPERAND_OBJECT **ReturnObject) 00318 { 00319 ACPI_OPERAND_OBJECT *NewObject; 00320 ACPI_STATUS Status; 00321 UINT64 Value = 0; 00322 UINT32 i; 00323 00324 00325 switch (OriginalObject->Common.Type) 00326 { 00327 case ACPI_TYPE_STRING: 00328 00329 /* String-to-Integer conversion */ 00330 00331 Status = AcpiUtStrtoul64 (OriginalObject->String.Pointer, 00332 ACPI_ANY_BASE, &Value); 00333 if (ACPI_FAILURE (Status)) 00334 { 00335 return (Status); 00336 } 00337 break; 00338 00339 case ACPI_TYPE_BUFFER: 00340 00341 /* Buffer-to-Integer conversion. Max buffer size is 64 bits. */ 00342 00343 if (OriginalObject->Buffer.Length > 8) 00344 { 00345 return (AE_AML_OPERAND_TYPE); 00346 } 00347 00348 /* Extract each buffer byte to create the integer */ 00349 00350 for (i = 0; i < OriginalObject->Buffer.Length; i++) 00351 { 00352 Value |= ((UINT64) OriginalObject->Buffer.Pointer[i] << (i * 8)); 00353 } 00354 break; 00355 00356 default: 00357 return (AE_AML_OPERAND_TYPE); 00358 } 00359 00360 NewObject = AcpiUtCreateIntegerObject (Value); 00361 if (!NewObject) 00362 { 00363 return (AE_NO_MEMORY); 00364 } 00365 00366 *ReturnObject = NewObject; 00367 return (AE_OK); 00368 } 00369 00370 00371 /******************************************************************************* 00372 * 00373 * FUNCTION: AcpiNsConvertToString 00374 * 00375 * PARAMETERS: OriginalObject - Object to be converted 00376 * ReturnObject - Where the new converted object is returned 00377 * 00378 * RETURN: Status. AE_OK if conversion was successful. 00379 * 00380 * DESCRIPTION: Attempt to convert a Integer/Buffer object to a String. 00381 * 00382 ******************************************************************************/ 00383 00384 static ACPI_STATUS 00385 AcpiNsConvertToString ( 00386 ACPI_OPERAND_OBJECT *OriginalObject, 00387 ACPI_OPERAND_OBJECT **ReturnObject) 00388 { 00389 ACPI_OPERAND_OBJECT *NewObject; 00390 ACPI_SIZE Length; 00391 ACPI_STATUS Status; 00392 00393 00394 switch (OriginalObject->Common.Type) 00395 { 00396 case ACPI_TYPE_INTEGER: 00397 /* 00398 * Integer-to-String conversion. Commonly, convert 00399 * an integer of value 0 to a NULL string. The last element of 00400 * _BIF and _BIX packages occasionally need this fix. 00401 */ 00402 if (OriginalObject->Integer.Value == 0) 00403 { 00404 /* Allocate a new NULL string object */ 00405 00406 NewObject = AcpiUtCreateStringObject (0); 00407 if (!NewObject) 00408 { 00409 return (AE_NO_MEMORY); 00410 } 00411 } 00412 else 00413 { 00414 Status = AcpiExConvertToString (OriginalObject, &NewObject, 00415 ACPI_IMPLICIT_CONVERT_HEX); 00416 if (ACPI_FAILURE (Status)) 00417 { 00418 return (Status); 00419 } 00420 } 00421 break; 00422 00423 case ACPI_TYPE_BUFFER: 00424 /* 00425 * Buffer-to-String conversion. Use a ToString 00426 * conversion, no transform performed on the buffer data. The best 00427 * example of this is the _BIF method, where the string data from 00428 * the battery is often (incorrectly) returned as buffer object(s). 00429 */ 00430 Length = 0; 00431 while ((Length < OriginalObject->Buffer.Length) && 00432 (OriginalObject->Buffer.Pointer[Length])) 00433 { 00434 Length++; 00435 } 00436 00437 /* Allocate a new string object */ 00438 00439 NewObject = AcpiUtCreateStringObject (Length); 00440 if (!NewObject) 00441 { 00442 return (AE_NO_MEMORY); 00443 } 00444 00445 /* 00446 * Copy the raw buffer data with no transform. String is already NULL 00447 * terminated at Length+1. 00448 */ 00449 ACPI_MEMCPY (NewObject->String.Pointer, 00450 OriginalObject->Buffer.Pointer, Length); 00451 break; 00452 00453 default: 00454 return (AE_AML_OPERAND_TYPE); 00455 } 00456 00457 *ReturnObject = NewObject; 00458 return (AE_OK); 00459 } 00460 00461 00462 /******************************************************************************* 00463 * 00464 * FUNCTION: AcpiNsConvertToBuffer 00465 * 00466 * PARAMETERS: OriginalObject - Object to be converted 00467 * ReturnObject - Where the new converted object is returned 00468 * 00469 * RETURN: Status. AE_OK if conversion was successful. 00470 * 00471 * DESCRIPTION: Attempt to convert a Integer/String/Package object to a Buffer. 00472 * 00473 ******************************************************************************/ 00474 00475 static ACPI_STATUS 00476 AcpiNsConvertToBuffer ( 00477 ACPI_OPERAND_OBJECT *OriginalObject, 00478 ACPI_OPERAND_OBJECT **ReturnObject) 00479 { 00480 ACPI_OPERAND_OBJECT *NewObject; 00481 ACPI_STATUS Status; 00482 ACPI_OPERAND_OBJECT **Elements; 00483 UINT32 *DwordBuffer; 00484 UINT32 Count; 00485 UINT32 i; 00486 00487 00488 switch (OriginalObject->Common.Type) 00489 { 00490 case ACPI_TYPE_INTEGER: 00491 /* 00492 * Integer-to-Buffer conversion. 00493 * Convert the Integer to a packed-byte buffer. _MAT and other 00494 * objects need this sometimes, if a read has been performed on a 00495 * Field object that is less than or equal to the global integer 00496 * size (32 or 64 bits). 00497 */ 00498 Status = AcpiExConvertToBuffer (OriginalObject, &NewObject); 00499 if (ACPI_FAILURE (Status)) 00500 { 00501 return (Status); 00502 } 00503 break; 00504 00505 case ACPI_TYPE_STRING: 00506 00507 /* String-to-Buffer conversion. Simple data copy */ 00508 00509 NewObject = AcpiUtCreateBufferObject (OriginalObject->String.Length); 00510 if (!NewObject) 00511 { 00512 return (AE_NO_MEMORY); 00513 } 00514 00515 ACPI_MEMCPY (NewObject->Buffer.Pointer, 00516 OriginalObject->String.Pointer, OriginalObject->String.Length); 00517 break; 00518 00519 case ACPI_TYPE_PACKAGE: 00520 /* 00521 * This case is often seen for predefined names that must return a 00522 * Buffer object with multiple DWORD integers within. For example, 00523 * _FDE and _GTM. The Package can be converted to a Buffer. 00524 */ 00525 00526 /* All elements of the Package must be integers */ 00527 00528 Elements = OriginalObject->Package.Elements; 00529 Count = OriginalObject->Package.Count; 00530 00531 for (i = 0; i < Count; i++) 00532 { 00533 if ((!*Elements) || 00534 ((*Elements)->Common.Type != ACPI_TYPE_INTEGER)) 00535 { 00536 return (AE_AML_OPERAND_TYPE); 00537 } 00538 Elements++; 00539 } 00540 00541 /* Create the new buffer object to replace the Package */ 00542 00543 NewObject = AcpiUtCreateBufferObject (ACPI_MUL_4 (Count)); 00544 if (!NewObject) 00545 { 00546 return (AE_NO_MEMORY); 00547 } 00548 00549 /* Copy the package elements (integers) to the buffer as DWORDs */ 00550 00551 Elements = OriginalObject->Package.Elements; 00552 DwordBuffer = ACPI_CAST_PTR (UINT32, NewObject->Buffer.Pointer); 00553 00554 for (i = 0; i < Count; i++) 00555 { 00556 *DwordBuffer = (UINT32) (*Elements)->Integer.Value; 00557 DwordBuffer++; 00558 Elements++; 00559 } 00560 break; 00561 00562 default: 00563 return (AE_AML_OPERAND_TYPE); 00564 } 00565 00566 *ReturnObject = NewObject; 00567 return (AE_OK); 00568 } 00569 00570 00571 /******************************************************************************* 00572 * 00573 * FUNCTION: AcpiNsConvertToPackage 00574 * 00575 * PARAMETERS: OriginalObject - Object to be converted 00576 * ReturnObject - Where the new converted object is returned 00577 * 00578 * RETURN: Status. AE_OK if conversion was successful. 00579 * 00580 * DESCRIPTION: Attempt to convert a Buffer object to a Package. Each byte of 00581 * the buffer is converted to a single integer package element. 00582 * 00583 ******************************************************************************/ 00584 00585 static ACPI_STATUS 00586 AcpiNsConvertToPackage ( 00587 ACPI_OPERAND_OBJECT *OriginalObject, 00588 ACPI_OPERAND_OBJECT **ReturnObject) 00589 { 00590 ACPI_OPERAND_OBJECT *NewObject; 00591 ACPI_OPERAND_OBJECT **Elements; 00592 UINT32 Length; 00593 UINT8 *Buffer; 00594 00595 00596 switch (OriginalObject->Common.Type) 00597 { 00598 case ACPI_TYPE_BUFFER: 00599 00600 /* Buffer-to-Package conversion */ 00601 00602 Length = OriginalObject->Buffer.Length; 00603 NewObject = AcpiUtCreatePackageObject (Length); 00604 if (!NewObject) 00605 { 00606 return (AE_NO_MEMORY); 00607 } 00608 00609 /* Convert each buffer byte to an integer package element */ 00610 00611 Elements = NewObject->Package.Elements; 00612 Buffer = OriginalObject->Buffer.Pointer; 00613 00614 while (Length--) 00615 { 00616 *Elements = AcpiUtCreateIntegerObject ((UINT64) *Buffer); 00617 if (!*Elements) 00618 { 00619 AcpiUtRemoveReference (NewObject); 00620 return (AE_NO_MEMORY); 00621 } 00622 Elements++; 00623 Buffer++; 00624 } 00625 break; 00626 00627 default: 00628 return (AE_AML_OPERAND_TYPE); 00629 } 00630 00631 *ReturnObject = NewObject; 00632 return (AE_OK); 00633 } 00634 00635 00636 /******************************************************************************* 00637 * 00638 * FUNCTION: AcpiNsRepairNullElement 00639 * 00640 * PARAMETERS: Data - Pointer to validation data structure 00641 * ExpectedBtypes - Object types expected 00642 * PackageIndex - Index of object within parent package (if 00643 * applicable - ACPI_NOT_PACKAGE_ELEMENT 00644 * otherwise) 00645 * ReturnObjectPtr - Pointer to the object returned from the 00646 * evaluation of a method or object 00647 * 00648 * RETURN: Status. AE_OK if repair was successful. 00649 * 00650 * DESCRIPTION: Attempt to repair a NULL element of a returned Package object. 00651 * 00652 ******************************************************************************/ 00653 00654 ACPI_STATUS 00655 AcpiNsRepairNullElement ( 00656 ACPI_PREDEFINED_DATA *Data, 00657 UINT32 ExpectedBtypes, 00658 UINT32 PackageIndex, 00659 ACPI_OPERAND_OBJECT **ReturnObjectPtr) 00660 { 00661 ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 00662 ACPI_OPERAND_OBJECT *NewObject; 00663 00664 00665 ACPI_FUNCTION_NAME (NsRepairNullElement); 00666 00667 00668 /* No repair needed if return object is non-NULL */ 00669 00670 if (ReturnObject) 00671 { 00672 return (AE_OK); 00673 } 00674 00675 /* 00676 * Attempt to repair a NULL element of a Package object. This applies to 00677 * predefined names that return a fixed-length package and each element 00678 * is required. It does not apply to variable-length packages where NULL 00679 * elements are allowed, especially at the end of the package. 00680 */ 00681 if (ExpectedBtypes & ACPI_RTYPE_INTEGER) 00682 { 00683 /* Need an Integer - create a zero-value integer */ 00684 00685 NewObject = AcpiUtCreateIntegerObject ((UINT64) 0); 00686 } 00687 else if (ExpectedBtypes & ACPI_RTYPE_STRING) 00688 { 00689 /* Need a String - create a NULL string */ 00690 00691 NewObject = AcpiUtCreateStringObject (0); 00692 } 00693 else if (ExpectedBtypes & ACPI_RTYPE_BUFFER) 00694 { 00695 /* Need a Buffer - create a zero-length buffer */ 00696 00697 NewObject = AcpiUtCreateBufferObject (0); 00698 } 00699 else 00700 { 00701 /* Error for all other expected types */ 00702 00703 return (AE_AML_OPERAND_TYPE); 00704 } 00705 00706 if (!NewObject) 00707 { 00708 return (AE_NO_MEMORY); 00709 } 00710 00711 /* Set the reference count according to the parent Package object */ 00712 00713 NewObject->Common.ReferenceCount = Data->ParentPackage->Common.ReferenceCount; 00714 00715 ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR, 00716 "%s: Converted NULL package element to expected %s at index %u\n", 00717 Data->Pathname, AcpiUtGetObjectTypeName (NewObject), PackageIndex)); 00718 00719 *ReturnObjectPtr = NewObject; 00720 Data->Flags |= ACPI_OBJECT_REPAIRED; 00721 return (AE_OK); 00722 } 00723 00724 00725 /****************************************************************************** 00726 * 00727 * FUNCTION: AcpiNsRemoveNullElements 00728 * 00729 * PARAMETERS: Data - Pointer to validation data structure 00730 * PackageType - An AcpiReturnPackageTypes value 00731 * ObjDesc - A Package object 00732 * 00733 * RETURN: None. 00734 * 00735 * DESCRIPTION: Remove all NULL package elements from packages that contain 00736 * a variable number of sub-packages. For these types of 00737 * packages, NULL elements can be safely removed. 00738 * 00739 *****************************************************************************/ 00740 00741 void 00742 AcpiNsRemoveNullElements ( 00743 ACPI_PREDEFINED_DATA *Data, 00744 UINT8 PackageType, 00745 ACPI_OPERAND_OBJECT *ObjDesc) 00746 { 00747 ACPI_OPERAND_OBJECT **Source; 00748 ACPI_OPERAND_OBJECT **Dest; 00749 UINT32 Count; 00750 UINT32 NewCount; 00751 UINT32 i; 00752 00753 00754 ACPI_FUNCTION_NAME (NsRemoveNullElements); 00755 00756 00757 /* 00758 * We can safely remove all NULL elements from these package types: 00759 * PTYPE1_VAR packages contain a variable number of simple data types. 00760 * PTYPE2 packages contain a variable number of sub-packages. 00761 */ 00762 switch (PackageType) 00763 { 00764 case ACPI_PTYPE1_VAR: 00765 case ACPI_PTYPE2: 00766 case ACPI_PTYPE2_COUNT: 00767 case ACPI_PTYPE2_PKG_COUNT: 00768 case ACPI_PTYPE2_FIXED: 00769 case ACPI_PTYPE2_MIN: 00770 case ACPI_PTYPE2_REV_FIXED: 00771 break; 00772 00773 default: 00774 case ACPI_PTYPE1_FIXED: 00775 case ACPI_PTYPE1_OPTION: 00776 return; 00777 } 00778 00779 Count = ObjDesc->Package.Count; 00780 NewCount = Count; 00781 00782 Source = ObjDesc->Package.Elements; 00783 Dest = Source; 00784 00785 /* Examine all elements of the package object, remove nulls */ 00786 00787 for (i = 0; i < Count; i++) 00788 { 00789 if (!*Source) 00790 { 00791 NewCount--; 00792 } 00793 else 00794 { 00795 *Dest = *Source; 00796 Dest++; 00797 } 00798 Source++; 00799 } 00800 00801 /* Update parent package if any null elements were removed */ 00802 00803 if (NewCount < Count) 00804 { 00805 ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR, 00806 "%s: Found and removed %u NULL elements\n", 00807 Data->Pathname, (Count - NewCount))); 00808 00809 /* NULL terminate list and update the package count */ 00810 00811 *Dest = NULL; 00812 ObjDesc->Package.Count = NewCount; 00813 } 00814 } 00815 00816 00817 /******************************************************************************* 00818 * 00819 * FUNCTION: AcpiNsRepairPackageList 00820 * 00821 * PARAMETERS: Data - Pointer to validation data structure 00822 * ObjDescPtr - Pointer to the object to repair. The new 00823 * package object is returned here, 00824 * overwriting the old object. 00825 * 00826 * RETURN: Status, new object in *ObjDescPtr 00827 * 00828 * DESCRIPTION: Repair a common problem with objects that are defined to return 00829 * a variable-length Package of Packages. If the variable-length 00830 * is one, some BIOS code mistakenly simply declares a single 00831 * Package instead of a Package with one sub-Package. This 00832 * function attempts to repair this error by wrapping a Package 00833 * object around the original Package, creating the correct 00834 * Package with one sub-Package. 00835 * 00836 * Names that can be repaired in this manner include: 00837 * _ALR, _CSD, _HPX, _MLS, _PRT, _PSS, _TRT, TSS 00838 * 00839 ******************************************************************************/ 00840 00841 ACPI_STATUS 00842 AcpiNsRepairPackageList ( 00843 ACPI_PREDEFINED_DATA *Data, 00844 ACPI_OPERAND_OBJECT **ObjDescPtr) 00845 { 00846 ACPI_OPERAND_OBJECT *PkgObjDesc; 00847 00848 00849 ACPI_FUNCTION_NAME (NsRepairPackageList); 00850 00851 00852 /* 00853 * Create the new outer package and populate it. The new package will 00854 * have a single element, the lone subpackage. 00855 */ 00856 PkgObjDesc = AcpiUtCreatePackageObject (1); 00857 if (!PkgObjDesc) 00858 { 00859 return (AE_NO_MEMORY); 00860 } 00861 00862 PkgObjDesc->Package.Elements[0] = *ObjDescPtr; 00863 00864 /* Return the new object in the object pointer */ 00865 00866 *ObjDescPtr = PkgObjDesc; 00867 Data->Flags |= ACPI_OBJECT_REPAIRED; 00868 00869 ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR, 00870 "%s: Repaired incorrectly formed Package\n", Data->Pathname)); 00871 00872 return (AE_OK); 00873 } Generated on Sat May 26 2012 04:25:54 for ReactOS by
1.7.6.1
|