![]() |
|
|||
File indexing completed on 2025-05-11 08:24:03
0001 /****************************************************************************** 0002 * 0003 * Module Name: nsrepair2 - Repair for objects returned by specific 0004 * predefined methods 0005 * 0006 *****************************************************************************/ 0007 0008 /****************************************************************************** 0009 * 0010 * 1. Copyright Notice 0011 * 0012 * Some or all of this work - Copyright (c) 1999 - 2024, Intel Corp. 0013 * All rights reserved. 0014 * 0015 * 2. License 0016 * 0017 * 2.1. This is your license from Intel Corp. under its intellectual property 0018 * rights. You may have additional license terms from the party that provided 0019 * you this software, covering your right to use that party's intellectual 0020 * property rights. 0021 * 0022 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 0023 * copy of the source code appearing in this file ("Covered Code") an 0024 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 0025 * base code distributed originally by Intel ("Original Intel Code") to copy, 0026 * make derivatives, distribute, use and display any portion of the Covered 0027 * Code in any form, with the right to sublicense such rights; and 0028 * 0029 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 0030 * license (with the right to sublicense), under only those claims of Intel 0031 * patents that are infringed by the Original Intel Code, to make, use, sell, 0032 * offer to sell, and import the Covered Code and derivative works thereof 0033 * solely to the minimum extent necessary to exercise the above copyright 0034 * license, and in no event shall the patent license extend to any additions 0035 * to or modifications of the Original Intel Code. No other license or right 0036 * is granted directly or by implication, estoppel or otherwise; 0037 * 0038 * The above copyright and patent license is granted only if the following 0039 * conditions are met: 0040 * 0041 * 3. Conditions 0042 * 0043 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 0044 * Redistribution of source code of any substantial portion of the Covered 0045 * Code or modification with rights to further distribute source must include 0046 * the above Copyright Notice, the above License, this list of Conditions, 0047 * and the following Disclaimer and Export Compliance provision. In addition, 0048 * Licensee must cause all Covered Code to which Licensee contributes to 0049 * contain a file documenting the changes Licensee made to create that Covered 0050 * Code and the date of any change. Licensee must include in that file the 0051 * documentation of any changes made by any predecessor Licensee. Licensee 0052 * must include a prominent statement that the modification is derived, 0053 * directly or indirectly, from Original Intel Code. 0054 * 0055 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 0056 * Redistribution of source code of any substantial portion of the Covered 0057 * Code or modification without rights to further distribute source must 0058 * include the following Disclaimer and Export Compliance provision in the 0059 * documentation and/or other materials provided with distribution. In 0060 * addition, Licensee may not authorize further sublicense of source of any 0061 * portion of the Covered Code, and must include terms to the effect that the 0062 * license from Licensee to its licensee is limited to the intellectual 0063 * property embodied in the software Licensee provides to its licensee, and 0064 * not to intellectual property embodied in modifications its licensee may 0065 * make. 0066 * 0067 * 3.3. Redistribution of Executable. Redistribution in executable form of any 0068 * substantial portion of the Covered Code or modification must reproduce the 0069 * above Copyright Notice, and the following Disclaimer and Export Compliance 0070 * provision in the documentation and/or other materials provided with the 0071 * distribution. 0072 * 0073 * 3.4. Intel retains all right, title, and interest in and to the Original 0074 * Intel Code. 0075 * 0076 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 0077 * Intel shall be used in advertising or otherwise to promote the sale, use or 0078 * other dealings in products derived from or relating to the Covered Code 0079 * without prior written authorization from Intel. 0080 * 0081 * 4. Disclaimer and Export Compliance 0082 * 0083 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 0084 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 0085 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 0086 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 0087 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 0088 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 0089 * PARTICULAR PURPOSE. 0090 * 0091 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 0092 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 0093 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 0094 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 0095 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 0096 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 0097 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 0098 * LIMITED REMEDY. 0099 * 0100 * 4.3. Licensee shall not export, either directly or indirectly, any of this 0101 * software or system incorporating such software without first obtaining any 0102 * required license or other approval from the U. S. Department of Commerce or 0103 * any other agency or department of the United States Government. In the 0104 * event Licensee exports any such software from the United States or 0105 * re-exports any such software from a foreign destination, Licensee shall 0106 * ensure that the distribution and export/re-export of the software is in 0107 * compliance with all laws, regulations, orders, or other restrictions of the 0108 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 0109 * any of its subsidiaries will export/re-export any technical data, process, 0110 * software, or service, directly or indirectly, to any country for which the 0111 * United States government or any agency thereof requires an export license, 0112 * other governmental approval, or letter of assurance, without first obtaining 0113 * such license, approval or letter. 0114 * 0115 ***************************************************************************** 0116 * 0117 * Alternatively, you may choose to be licensed under the terms of the 0118 * following license: 0119 * 0120 * Redistribution and use in source and binary forms, with or without 0121 * modification, are permitted provided that the following conditions 0122 * are met: 0123 * 1. Redistributions of source code must retain the above copyright 0124 * notice, this list of conditions, and the following disclaimer, 0125 * without modification. 0126 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 0127 * substantially similar to the "NO WARRANTY" disclaimer below 0128 * ("Disclaimer") and any redistribution must be conditioned upon 0129 * including a substantially similar Disclaimer requirement for further 0130 * binary redistribution. 0131 * 3. Neither the names of the above-listed copyright holders nor the names 0132 * of any contributors may be used to endorse or promote products derived 0133 * from this software without specific prior written permission. 0134 * 0135 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 0136 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 0137 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 0138 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 0139 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 0140 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 0141 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 0142 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 0143 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 0144 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 0145 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 0146 * 0147 * Alternatively, you may choose to be licensed under the terms of the 0148 * GNU General Public License ("GPL") version 2 as published by the Free 0149 * Software Foundation. 0150 * 0151 *****************************************************************************/ 0152 0153 #include "acpi.h" 0154 #include "accommon.h" 0155 #include "acnamesp.h" 0156 0157 #define _COMPONENT ACPI_NAMESPACE 0158 ACPI_MODULE_NAME ("nsrepair2") 0159 0160 0161 /* 0162 * Information structure and handler for ACPI predefined names that can 0163 * be repaired on a per-name basis. 0164 */ 0165 typedef 0166 ACPI_STATUS (*ACPI_REPAIR_FUNCTION) ( 0167 ACPI_EVALUATE_INFO *Info, 0168 ACPI_OPERAND_OBJECT **ReturnObjectPtr); 0169 0170 typedef struct acpi_repair_info 0171 { 0172 char Name[ACPI_NAMESEG_SIZE]; 0173 ACPI_REPAIR_FUNCTION RepairFunction; 0174 0175 } ACPI_REPAIR_INFO; 0176 0177 0178 /* Local prototypes */ 0179 0180 static const ACPI_REPAIR_INFO * 0181 AcpiNsMatchComplexRepair ( 0182 ACPI_NAMESPACE_NODE *Node); 0183 0184 static ACPI_STATUS 0185 AcpiNsRepair_ALR ( 0186 ACPI_EVALUATE_INFO *Info, 0187 ACPI_OPERAND_OBJECT **ReturnObjectPtr); 0188 0189 static ACPI_STATUS 0190 AcpiNsRepair_CID ( 0191 ACPI_EVALUATE_INFO *Info, 0192 ACPI_OPERAND_OBJECT **ReturnObjectPtr); 0193 0194 static ACPI_STATUS 0195 AcpiNsRepair_CST ( 0196 ACPI_EVALUATE_INFO *Info, 0197 ACPI_OPERAND_OBJECT **ReturnObjectPtr); 0198 0199 static ACPI_STATUS 0200 AcpiNsRepair_FDE ( 0201 ACPI_EVALUATE_INFO *Info, 0202 ACPI_OPERAND_OBJECT **ReturnObjectPtr); 0203 0204 static ACPI_STATUS 0205 AcpiNsRepair_HID ( 0206 ACPI_EVALUATE_INFO *Info, 0207 ACPI_OPERAND_OBJECT **ReturnObjectPtr); 0208 0209 static ACPI_STATUS 0210 AcpiNsRepair_PRT ( 0211 ACPI_EVALUATE_INFO *Info, 0212 ACPI_OPERAND_OBJECT **ReturnObjectPtr); 0213 0214 static ACPI_STATUS 0215 AcpiNsRepair_PSS ( 0216 ACPI_EVALUATE_INFO *Info, 0217 ACPI_OPERAND_OBJECT **ReturnObjectPtr); 0218 0219 static ACPI_STATUS 0220 AcpiNsRepair_TSS ( 0221 ACPI_EVALUATE_INFO *Info, 0222 ACPI_OPERAND_OBJECT **ReturnObjectPtr); 0223 0224 static ACPI_STATUS 0225 AcpiNsCheckSortedList ( 0226 ACPI_EVALUATE_INFO *Info, 0227 ACPI_OPERAND_OBJECT *ReturnObject, 0228 UINT32 StartIndex, 0229 UINT32 ExpectedCount, 0230 UINT32 SortIndex, 0231 UINT8 SortDirection, 0232 char *SortKeyName); 0233 0234 /* Values for SortDirection above */ 0235 0236 #define ACPI_SORT_ASCENDING 0 0237 #define ACPI_SORT_DESCENDING 1 0238 0239 static void 0240 AcpiNsRemoveElement ( 0241 ACPI_OPERAND_OBJECT *ObjDesc, 0242 UINT32 Index); 0243 0244 static void 0245 AcpiNsSortList ( 0246 ACPI_OPERAND_OBJECT **Elements, 0247 UINT32 Count, 0248 UINT32 Index, 0249 UINT8 SortDirection); 0250 0251 0252 /* 0253 * This table contains the names of the predefined methods for which we can 0254 * perform more complex repairs. 0255 * 0256 * As necessary: 0257 * 0258 * _ALR: Sort the list ascending by AmbientIlluminance 0259 * _CID: Strings: uppercase all, remove any leading asterisk 0260 * _CST: Sort the list ascending by C state type 0261 * _FDE: Convert Buffer of BYTEs to a Buffer of DWORDs 0262 * _GTM: Convert Buffer of BYTEs to a Buffer of DWORDs 0263 * _HID: Strings: uppercase all, remove any leading asterisk 0264 * _PRT: Fix reversed SourceName and SourceIndex 0265 * _PSS: Sort the list descending by Power 0266 * _TSS: Sort the list descending by Power 0267 * 0268 * Names that must be packages, but cannot be sorted: 0269 * 0270 * _BCL: Values are tied to the Package index where they appear, and cannot 0271 * be moved or sorted. These index values are used for _BQC and _BCM. 0272 * However, we can fix the case where a buffer is returned, by converting 0273 * it to a Package of integers. 0274 */ 0275 static const ACPI_REPAIR_INFO AcpiNsRepairableNames[] = 0276 { 0277 {"_ALR", AcpiNsRepair_ALR}, 0278 {"_CID", AcpiNsRepair_CID}, 0279 {"_CST", AcpiNsRepair_CST}, 0280 {"_FDE", AcpiNsRepair_FDE}, 0281 {"_GTM", AcpiNsRepair_FDE}, /* _GTM has same repair as _FDE */ 0282 {"_HID", AcpiNsRepair_HID}, 0283 {"_PRT", AcpiNsRepair_PRT}, 0284 {"_PSS", AcpiNsRepair_PSS}, 0285 {"_TSS", AcpiNsRepair_TSS}, 0286 {{0,0,0,0}, NULL} /* Table terminator */ 0287 }; 0288 0289 0290 #define ACPI_FDE_FIELD_COUNT 5 0291 #define ACPI_FDE_BYTE_BUFFER_SIZE 5 0292 #define ACPI_FDE_DWORD_BUFFER_SIZE (ACPI_FDE_FIELD_COUNT * (UINT32) sizeof (UINT32)) 0293 0294 0295 /****************************************************************************** 0296 * 0297 * FUNCTION: AcpiNsComplexRepairs 0298 * 0299 * PARAMETERS: Info - Method execution information block 0300 * Node - Namespace node for the method/object 0301 * ValidateStatus - Original status of earlier validation 0302 * ReturnObjectPtr - Pointer to the object returned from the 0303 * evaluation of a method or object 0304 * 0305 * RETURN: Status. AE_OK if repair was successful. If name is not 0306 * matched, ValidateStatus is returned. 0307 * 0308 * DESCRIPTION: Attempt to repair/convert a return object of a type that was 0309 * not expected. 0310 * 0311 *****************************************************************************/ 0312 0313 ACPI_STATUS 0314 AcpiNsComplexRepairs ( 0315 ACPI_EVALUATE_INFO *Info, 0316 ACPI_NAMESPACE_NODE *Node, 0317 ACPI_STATUS ValidateStatus, 0318 ACPI_OPERAND_OBJECT **ReturnObjectPtr) 0319 { 0320 const ACPI_REPAIR_INFO *Predefined; 0321 ACPI_STATUS Status; 0322 0323 0324 ACPI_FUNCTION_TRACE (NsComplexRepairs); 0325 0326 /* Check if this name is in the list of repairable names */ 0327 0328 Predefined = AcpiNsMatchComplexRepair (Node); 0329 if (!Predefined) 0330 { 0331 return_ACPI_STATUS (ValidateStatus); 0332 } 0333 0334 Status = Predefined->RepairFunction (Info, ReturnObjectPtr); 0335 return_ACPI_STATUS (Status); 0336 } 0337 0338 0339 /****************************************************************************** 0340 * 0341 * FUNCTION: AcpiNsMatchComplexRepair 0342 * 0343 * PARAMETERS: Node - Namespace node for the method/object 0344 * 0345 * RETURN: Pointer to entry in repair table. NULL indicates not found. 0346 * 0347 * DESCRIPTION: Check an object name against the repairable object list. 0348 * 0349 *****************************************************************************/ 0350 0351 static const ACPI_REPAIR_INFO * 0352 AcpiNsMatchComplexRepair ( 0353 ACPI_NAMESPACE_NODE *Node) 0354 { 0355 const ACPI_REPAIR_INFO *ThisName; 0356 0357 0358 /* Search info table for a repairable predefined method/object name */ 0359 0360 ThisName = AcpiNsRepairableNames; 0361 while (ThisName->RepairFunction) 0362 { 0363 if (ACPI_COMPARE_NAMESEG (Node->Name.Ascii, ThisName->Name)) 0364 { 0365 return (ThisName); 0366 } 0367 0368 ThisName++; 0369 } 0370 0371 return (NULL); /* Not found */ 0372 } 0373 0374 0375 /****************************************************************************** 0376 * 0377 * FUNCTION: AcpiNsRepair_ALR 0378 * 0379 * PARAMETERS: Info - Method execution information block 0380 * ReturnObjectPtr - Pointer to the object returned from the 0381 * evaluation of a method or object 0382 * 0383 * RETURN: Status. AE_OK if object is OK or was repaired successfully 0384 * 0385 * DESCRIPTION: Repair for the _ALR object. If necessary, sort the object list 0386 * ascending by the ambient illuminance values. 0387 * 0388 *****************************************************************************/ 0389 0390 static ACPI_STATUS 0391 AcpiNsRepair_ALR ( 0392 ACPI_EVALUATE_INFO *Info, 0393 ACPI_OPERAND_OBJECT **ReturnObjectPtr) 0394 { 0395 ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 0396 ACPI_STATUS Status; 0397 0398 0399 Status = AcpiNsCheckSortedList (Info, ReturnObject, 0, 2, 1, 0400 ACPI_SORT_ASCENDING, "AmbientIlluminance"); 0401 0402 return (Status); 0403 } 0404 0405 0406 /****************************************************************************** 0407 * 0408 * FUNCTION: AcpiNsRepair_FDE 0409 * 0410 * PARAMETERS: Info - Method execution information block 0411 * ReturnObjectPtr - Pointer to the object returned from the 0412 * evaluation of a method or object 0413 * 0414 * RETURN: Status. AE_OK if object is OK or was repaired successfully 0415 * 0416 * DESCRIPTION: Repair for the _FDE and _GTM objects. The expected return 0417 * value is a Buffer of 5 DWORDs. This function repairs a common 0418 * problem where the return value is a Buffer of BYTEs, not 0419 * DWORDs. 0420 * 0421 *****************************************************************************/ 0422 0423 static ACPI_STATUS 0424 AcpiNsRepair_FDE ( 0425 ACPI_EVALUATE_INFO *Info, 0426 ACPI_OPERAND_OBJECT **ReturnObjectPtr) 0427 { 0428 ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 0429 ACPI_OPERAND_OBJECT *BufferObject; 0430 UINT8 *ByteBuffer; 0431 UINT32 *DwordBuffer; 0432 UINT32 i; 0433 0434 0435 ACPI_FUNCTION_NAME (NsRepair_FDE); 0436 0437 0438 switch (ReturnObject->Common.Type) 0439 { 0440 case ACPI_TYPE_BUFFER: 0441 0442 /* This is the expected type. Length should be (at least) 5 DWORDs */ 0443 0444 if (ReturnObject->Buffer.Length >= ACPI_FDE_DWORD_BUFFER_SIZE) 0445 { 0446 return (AE_OK); 0447 } 0448 0449 /* We can only repair if we have exactly 5 BYTEs */ 0450 0451 if (ReturnObject->Buffer.Length != ACPI_FDE_BYTE_BUFFER_SIZE) 0452 { 0453 ACPI_WARN_PREDEFINED ((AE_INFO, 0454 Info->FullPathname, Info->NodeFlags, 0455 "Incorrect return buffer length %u, expected %u", 0456 ReturnObject->Buffer.Length, ACPI_FDE_DWORD_BUFFER_SIZE)); 0457 0458 return (AE_AML_OPERAND_TYPE); 0459 } 0460 0461 /* Create the new (larger) buffer object */ 0462 0463 BufferObject = AcpiUtCreateBufferObject ( 0464 ACPI_FDE_DWORD_BUFFER_SIZE); 0465 if (!BufferObject) 0466 { 0467 return (AE_NO_MEMORY); 0468 } 0469 0470 /* Expand each byte to a DWORD */ 0471 0472 ByteBuffer = ReturnObject->Buffer.Pointer; 0473 DwordBuffer = ACPI_CAST_PTR (UINT32, 0474 BufferObject->Buffer.Pointer); 0475 0476 for (i = 0; i < ACPI_FDE_FIELD_COUNT; i++) 0477 { 0478 *DwordBuffer = (UINT32) *ByteBuffer; 0479 DwordBuffer++; 0480 ByteBuffer++; 0481 } 0482 0483 ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR, 0484 "%s Expanded Byte Buffer to expected DWord Buffer\n", 0485 Info->FullPathname)); 0486 break; 0487 0488 default: 0489 0490 return (AE_AML_OPERAND_TYPE); 0491 } 0492 0493 /* Delete the original return object, return the new buffer object */ 0494 0495 AcpiUtRemoveReference (ReturnObject); 0496 *ReturnObjectPtr = BufferObject; 0497 0498 Info->ReturnFlags |= ACPI_OBJECT_REPAIRED; 0499 return (AE_OK); 0500 } 0501 0502 0503 /****************************************************************************** 0504 * 0505 * FUNCTION: AcpiNsRepair_CID 0506 * 0507 * PARAMETERS: Info - Method execution information block 0508 * ReturnObjectPtr - Pointer to the object returned from the 0509 * evaluation of a method or object 0510 * 0511 * RETURN: Status. AE_OK if object is OK or was repaired successfully 0512 * 0513 * DESCRIPTION: Repair for the _CID object. If a string, ensure that all 0514 * letters are uppercase and that there is no leading asterisk. 0515 * If a Package, ensure same for all string elements. 0516 * 0517 *****************************************************************************/ 0518 0519 static ACPI_STATUS 0520 AcpiNsRepair_CID ( 0521 ACPI_EVALUATE_INFO *Info, 0522 ACPI_OPERAND_OBJECT **ReturnObjectPtr) 0523 { 0524 ACPI_STATUS Status; 0525 ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 0526 ACPI_OPERAND_OBJECT **ElementPtr; 0527 ACPI_OPERAND_OBJECT *OriginalElement; 0528 UINT16 OriginalRefCount; 0529 UINT32 i; 0530 0531 ACPI_FUNCTION_TRACE (NsRepair_CID); 0532 0533 /* Check for _CID as a simple string */ 0534 0535 if (ReturnObject->Common.Type == ACPI_TYPE_STRING) 0536 { 0537 Status = AcpiNsRepair_HID (Info, ReturnObjectPtr); 0538 return_ACPI_STATUS (Status); 0539 } 0540 0541 /* Exit if not a Package */ 0542 0543 if (ReturnObject->Common.Type != ACPI_TYPE_PACKAGE) 0544 { 0545 return_ACPI_STATUS (AE_OK); 0546 } 0547 0548 /* Examine each element of the _CID package */ 0549 0550 ElementPtr = ReturnObject->Package.Elements; 0551 for (i = 0; i < ReturnObject->Package.Count; i++) 0552 { 0553 OriginalElement = *ElementPtr; 0554 OriginalRefCount = OriginalElement->Common.ReferenceCount; 0555 0556 Status = AcpiNsRepair_HID (Info, ElementPtr); 0557 if (ACPI_FAILURE (Status)) 0558 { 0559 return_ACPI_STATUS (Status); 0560 } 0561 0562 if (OriginalElement != *ElementPtr) 0563 { 0564 /* Update reference count of new object */ 0565 0566 (*ElementPtr)->Common.ReferenceCount = 0567 OriginalRefCount; 0568 } 0569 0570 ElementPtr++; 0571 } 0572 0573 return_ACPI_STATUS (AE_OK); 0574 } 0575 0576 0577 /****************************************************************************** 0578 * 0579 * FUNCTION: AcpiNsRepair_CST 0580 * 0581 * PARAMETERS: Info - Method execution information block 0582 * ReturnObjectPtr - Pointer to the object returned from the 0583 * evaluation of a method or object 0584 * 0585 * RETURN: Status. AE_OK if object is OK or was repaired successfully 0586 * 0587 * DESCRIPTION: Repair for the _CST object: 0588 * 1. Sort the list ascending by C state type 0589 * 2. Ensure type cannot be zero 0590 * 3. A subpackage count of zero means _CST is meaningless 0591 * 4. Count must match the number of C state subpackages 0592 * 0593 *****************************************************************************/ 0594 0595 static ACPI_STATUS 0596 AcpiNsRepair_CST ( 0597 ACPI_EVALUATE_INFO *Info, 0598 ACPI_OPERAND_OBJECT **ReturnObjectPtr) 0599 { 0600 ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 0601 ACPI_OPERAND_OBJECT **OuterElements; 0602 UINT32 OuterElementCount; 0603 ACPI_OPERAND_OBJECT *ObjDesc; 0604 ACPI_STATUS Status; 0605 BOOLEAN Removing; 0606 UINT32 i; 0607 0608 0609 ACPI_FUNCTION_NAME (NsRepair_CST); 0610 0611 0612 /* 0613 * Check if the C-state type values are proportional. 0614 */ 0615 OuterElementCount = ReturnObject->Package.Count - 1; 0616 i = 0; 0617 while (i < OuterElementCount) 0618 { 0619 OuterElements = &ReturnObject->Package.Elements[i + 1]; 0620 Removing = FALSE; 0621 0622 if ((*OuterElements)->Package.Count == 0) 0623 { 0624 ACPI_WARN_PREDEFINED ((AE_INFO, 0625 Info->FullPathname, Info->NodeFlags, 0626 "SubPackage[%u] - removing entry due to zero count", i)); 0627 Removing = TRUE; 0628 goto RemoveElement; 0629 } 0630 0631 ObjDesc = (*OuterElements)->Package.Elements[1]; /* Index1 = Type */ 0632 if ((UINT32) ObjDesc->Integer.Value == 0) 0633 { 0634 ACPI_WARN_PREDEFINED ((AE_INFO, 0635 Info->FullPathname, Info->NodeFlags, 0636 "SubPackage[%u] - removing entry due to invalid Type(0)", i)); 0637 Removing = TRUE; 0638 } 0639 0640 RemoveElement: 0641 if (Removing) 0642 { 0643 AcpiNsRemoveElement (ReturnObject, i + 1); 0644 OuterElementCount--; 0645 } 0646 else 0647 { 0648 i++; 0649 } 0650 } 0651 0652 /* Update top-level package count, Type "Integer" checked elsewhere */ 0653 0654 ObjDesc = ReturnObject->Package.Elements[0]; 0655 ObjDesc->Integer.Value = OuterElementCount; 0656 0657 /* 0658 * Entries (subpackages) in the _CST Package must be sorted by the 0659 * C-state type, in ascending order. 0660 */ 0661 Status = AcpiNsCheckSortedList (Info, ReturnObject, 1, 4, 1, 0662 ACPI_SORT_ASCENDING, "C-State Type"); 0663 if (ACPI_FAILURE (Status)) 0664 { 0665 return (Status); 0666 } 0667 0668 return (AE_OK); 0669 } 0670 0671 0672 /****************************************************************************** 0673 * 0674 * FUNCTION: AcpiNsRepair_HID 0675 * 0676 * PARAMETERS: Info - Method execution information block 0677 * ReturnObjectPtr - Pointer to the object returned from the 0678 * evaluation of a method or object 0679 * 0680 * RETURN: Status. AE_OK if object is OK or was repaired successfully 0681 * 0682 * DESCRIPTION: Repair for the _HID object. If a string, ensure that all 0683 * letters are uppercase and that there is no leading asterisk. 0684 * 0685 *****************************************************************************/ 0686 0687 static ACPI_STATUS 0688 AcpiNsRepair_HID ( 0689 ACPI_EVALUATE_INFO *Info, 0690 ACPI_OPERAND_OBJECT **ReturnObjectPtr) 0691 { 0692 ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 0693 ACPI_OPERAND_OBJECT *NewString; 0694 char *Source; 0695 char *Dest; 0696 0697 0698 ACPI_FUNCTION_TRACE (NsRepair_HID); 0699 0700 0701 /* We only care about string _HID objects (not integers) */ 0702 0703 if (ReturnObject->Common.Type != ACPI_TYPE_STRING) 0704 { 0705 return_ACPI_STATUS (AE_OK); 0706 } 0707 0708 if (ReturnObject->String.Length == 0) 0709 { 0710 ACPI_WARN_PREDEFINED ((AE_INFO, 0711 Info->FullPathname, Info->NodeFlags, 0712 "Invalid zero-length _HID or _CID string")); 0713 0714 /* Return AE_OK anyway, let driver handle it */ 0715 0716 Info->ReturnFlags |= ACPI_OBJECT_REPAIRED; 0717 return_ACPI_STATUS (AE_OK); 0718 } 0719 0720 /* It is simplest to always create a new string object */ 0721 0722 NewString = AcpiUtCreateStringObject (ReturnObject->String.Length); 0723 if (!NewString) 0724 { 0725 return_ACPI_STATUS (AE_NO_MEMORY); 0726 } 0727 0728 /* 0729 * Remove a leading asterisk if present. For some unknown reason, there 0730 * are many machines in the field that contains IDs like this. 0731 * 0732 * Examples: "*PNP0C03", "*ACPI0003" 0733 */ 0734 Source = ReturnObject->String.Pointer; 0735 if (*Source == '*') 0736 { 0737 Source++; 0738 NewString->String.Length--; 0739 0740 ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR, 0741 "%s: Removed invalid leading asterisk\n", Info->FullPathname)); 0742 } 0743 0744 /* 0745 * Copy and uppercase the string. From the ACPI 5.0 specification: 0746 * 0747 * A valid PNP ID must be of the form "AAA####" where A is an uppercase 0748 * letter and # is a hex digit. A valid ACPI ID must be of the form 0749 * "NNNN####" where N is an uppercase letter or decimal digit, and 0750 * # is a hex digit. 0751 */ 0752 for (Dest = NewString->String.Pointer; *Source; Dest++, Source++) 0753 { 0754 *Dest = (char) toupper ((int) *Source); 0755 } 0756 0757 AcpiUtRemoveReference (ReturnObject); 0758 *ReturnObjectPtr = NewString; 0759 return_ACPI_STATUS (AE_OK); 0760 } 0761 0762 0763 /****************************************************************************** 0764 * 0765 * FUNCTION: AcpiNsRepair_PRT 0766 * 0767 * PARAMETERS: Info - Method execution information block 0768 * ReturnObjectPtr - Pointer to the object returned from the 0769 * evaluation of a method or object 0770 * 0771 * RETURN: Status. AE_OK if object is OK or was repaired successfully 0772 * 0773 * DESCRIPTION: Repair for the _PRT object. If necessary, fix reversed 0774 * SourceName and SourceIndex field, a common BIOS bug. 0775 * 0776 *****************************************************************************/ 0777 0778 static ACPI_STATUS 0779 AcpiNsRepair_PRT ( 0780 ACPI_EVALUATE_INFO *Info, 0781 ACPI_OPERAND_OBJECT **ReturnObjectPtr) 0782 { 0783 ACPI_OPERAND_OBJECT *PackageObject = *ReturnObjectPtr; 0784 ACPI_OPERAND_OBJECT **TopObjectList; 0785 ACPI_OPERAND_OBJECT **SubObjectList; 0786 ACPI_OPERAND_OBJECT *ObjDesc; 0787 ACPI_OPERAND_OBJECT *SubPackage; 0788 UINT32 ElementCount; 0789 UINT32 Index; 0790 0791 0792 /* Each element in the _PRT package is a subpackage */ 0793 0794 TopObjectList = PackageObject->Package.Elements; 0795 ElementCount = PackageObject->Package.Count; 0796 0797 /* Examine each subpackage */ 0798 0799 for (Index = 0; Index < ElementCount; Index++, TopObjectList++) 0800 { 0801 SubPackage = *TopObjectList; 0802 SubObjectList = SubPackage->Package.Elements; 0803 0804 /* Check for minimum required element count */ 0805 0806 if (SubPackage->Package.Count < 4) 0807 { 0808 continue; 0809 } 0810 0811 /* 0812 * If the BIOS has erroneously reversed the _PRT SourceName (index 2) 0813 * and the SourceIndex (index 3), fix it. _PRT is important enough to 0814 * workaround this BIOS error. This also provides compatibility with 0815 * other ACPI implementations. 0816 */ 0817 ObjDesc = SubObjectList[3]; 0818 if (!ObjDesc || (ObjDesc->Common.Type != ACPI_TYPE_INTEGER)) 0819 { 0820 SubObjectList[3] = SubObjectList[2]; 0821 SubObjectList[2] = ObjDesc; 0822 Info->ReturnFlags |= ACPI_OBJECT_REPAIRED; 0823 0824 ACPI_WARN_PREDEFINED ((AE_INFO, 0825 Info->FullPathname, Info->NodeFlags, 0826 "PRT[%X]: Fixed reversed SourceName and SourceIndex", 0827 Index)); 0828 } 0829 } 0830 0831 return (AE_OK); 0832 } 0833 0834 0835 /****************************************************************************** 0836 * 0837 * FUNCTION: AcpiNsRepair_PSS 0838 * 0839 * PARAMETERS: Info - Method execution information block 0840 * ReturnObjectPtr - Pointer to the object returned from the 0841 * evaluation of a method or object 0842 * 0843 * RETURN: Status. AE_OK if object is OK or was repaired successfully 0844 * 0845 * DESCRIPTION: Repair for the _PSS object. If necessary, sort the object list 0846 * by the CPU frequencies. Check that the power dissipation values 0847 * are all proportional to CPU frequency (i.e., sorting by 0848 * frequency should be the same as sorting by power.) 0849 * 0850 *****************************************************************************/ 0851 0852 static ACPI_STATUS 0853 AcpiNsRepair_PSS ( 0854 ACPI_EVALUATE_INFO *Info, 0855 ACPI_OPERAND_OBJECT **ReturnObjectPtr) 0856 { 0857 ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 0858 ACPI_OPERAND_OBJECT **OuterElements; 0859 UINT32 OuterElementCount; 0860 ACPI_OPERAND_OBJECT **Elements; 0861 ACPI_OPERAND_OBJECT *ObjDesc; 0862 UINT32 PreviousValue; 0863 ACPI_STATUS Status; 0864 UINT32 i; 0865 0866 0867 /* 0868 * Entries (subpackages) in the _PSS Package must be sorted by power 0869 * dissipation, in descending order. If it appears that the list is 0870 * incorrectly sorted, sort it. We sort by CpuFrequency, since this 0871 * should be proportional to the power. 0872 */ 0873 Status = AcpiNsCheckSortedList (Info, ReturnObject, 0, 6, 0, 0874 ACPI_SORT_DESCENDING, "CpuFrequency"); 0875 if (ACPI_FAILURE (Status)) 0876 { 0877 return (Status); 0878 } 0879 0880 /* 0881 * We now know the list is correctly sorted by CPU frequency. Check if 0882 * the power dissipation values are proportional. 0883 */ 0884 PreviousValue = ACPI_UINT32_MAX; 0885 OuterElements = ReturnObject->Package.Elements; 0886 OuterElementCount = ReturnObject->Package.Count; 0887 0888 for (i = 0; i < OuterElementCount; i++) 0889 { 0890 Elements = (*OuterElements)->Package.Elements; 0891 ObjDesc = Elements[1]; /* Index1 = PowerDissipation */ 0892 0893 if ((UINT32) ObjDesc->Integer.Value > PreviousValue) 0894 { 0895 ACPI_WARN_PREDEFINED ((AE_INFO, 0896 Info->FullPathname, Info->NodeFlags, 0897 "SubPackage[%u,%u] - suspicious power dissipation values", 0898 i-1, i)); 0899 } 0900 0901 PreviousValue = (UINT32) ObjDesc->Integer.Value; 0902 OuterElements++; 0903 } 0904 0905 return (AE_OK); 0906 } 0907 0908 0909 /****************************************************************************** 0910 * 0911 * FUNCTION: AcpiNsRepair_TSS 0912 * 0913 * PARAMETERS: Info - Method execution information block 0914 * ReturnObjectPtr - Pointer to the object returned from the 0915 * evaluation of a method or object 0916 * 0917 * RETURN: Status. AE_OK if object is OK or was repaired successfully 0918 * 0919 * DESCRIPTION: Repair for the _TSS object. If necessary, sort the object list 0920 * descending by the power dissipation values. 0921 * 0922 *****************************************************************************/ 0923 0924 static ACPI_STATUS 0925 AcpiNsRepair_TSS ( 0926 ACPI_EVALUATE_INFO *Info, 0927 ACPI_OPERAND_OBJECT **ReturnObjectPtr) 0928 { 0929 ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 0930 ACPI_STATUS Status; 0931 ACPI_NAMESPACE_NODE *Node; 0932 0933 0934 /* 0935 * We can only sort the _TSS return package if there is no _PSS in the 0936 * same scope. This is because if _PSS is present, the ACPI specification 0937 * dictates that the _TSS Power Dissipation field is to be ignored, and 0938 * therefore some BIOSs leave garbage values in the _TSS Power field(s). 0939 * In this case, it is best to just return the _TSS package as-is. 0940 * (May, 2011) 0941 */ 0942 Status = AcpiNsGetNode (Info->Node, "^_PSS", 0943 ACPI_NS_NO_UPSEARCH, &Node); 0944 if (ACPI_SUCCESS (Status)) 0945 { 0946 return (AE_OK); 0947 } 0948 0949 Status = AcpiNsCheckSortedList (Info, ReturnObject, 0, 5, 1, 0950 ACPI_SORT_DESCENDING, "PowerDissipation"); 0951 0952 return (Status); 0953 } 0954 0955 0956 /****************************************************************************** 0957 * 0958 * FUNCTION: AcpiNsCheckSortedList 0959 * 0960 * PARAMETERS: Info - Method execution information block 0961 * ReturnObject - Pointer to the top-level returned object 0962 * StartIndex - Index of the first subpackage 0963 * ExpectedCount - Minimum length of each subpackage 0964 * SortIndex - Subpackage entry to sort on 0965 * SortDirection - Ascending or descending 0966 * SortKeyName - Name of the SortIndex field 0967 * 0968 * RETURN: Status. AE_OK if the list is valid and is sorted correctly or 0969 * has been repaired by sorting the list. 0970 * 0971 * DESCRIPTION: Check if the package list is valid and sorted correctly by the 0972 * SortIndex. If not, then sort the list. 0973 * 0974 *****************************************************************************/ 0975 0976 static ACPI_STATUS 0977 AcpiNsCheckSortedList ( 0978 ACPI_EVALUATE_INFO *Info, 0979 ACPI_OPERAND_OBJECT *ReturnObject, 0980 UINT32 StartIndex, 0981 UINT32 ExpectedCount, 0982 UINT32 SortIndex, 0983 UINT8 SortDirection, 0984 char *SortKeyName) 0985 { 0986 UINT32 OuterElementCount; 0987 ACPI_OPERAND_OBJECT **OuterElements; 0988 ACPI_OPERAND_OBJECT **Elements; 0989 ACPI_OPERAND_OBJECT *ObjDesc; 0990 UINT32 i; 0991 UINT32 PreviousValue; 0992 0993 0994 ACPI_FUNCTION_NAME (NsCheckSortedList); 0995 0996 0997 /* The top-level object must be a package */ 0998 0999 if (ReturnObject->Common.Type != ACPI_TYPE_PACKAGE) 1000 { 1001 return (AE_AML_OPERAND_TYPE); 1002 } 1003 1004 /* 1005 * NOTE: assumes list of subpackages contains no NULL elements. 1006 * Any NULL elements should have been removed by earlier call 1007 * to AcpiNsRemoveNullElements. 1008 */ 1009 OuterElementCount = ReturnObject->Package.Count; 1010 if (!OuterElementCount || StartIndex >= OuterElementCount) 1011 { 1012 return (AE_AML_PACKAGE_LIMIT); 1013 } 1014 1015 OuterElements = &ReturnObject->Package.Elements[StartIndex]; 1016 OuterElementCount -= StartIndex; 1017 1018 PreviousValue = 0; 1019 if (SortDirection == ACPI_SORT_DESCENDING) 1020 { 1021 PreviousValue = ACPI_UINT32_MAX; 1022 } 1023 1024 /* Examine each subpackage */ 1025 1026 for (i = 0; i < OuterElementCount; i++) 1027 { 1028 /* Each element of the top-level package must also be a package */ 1029 1030 if ((*OuterElements)->Common.Type != ACPI_TYPE_PACKAGE) 1031 { 1032 return (AE_AML_OPERAND_TYPE); 1033 } 1034 1035 /* Each subpackage must have the minimum length */ 1036 1037 if ((*OuterElements)->Package.Count < ExpectedCount) 1038 { 1039 return (AE_AML_PACKAGE_LIMIT); 1040 } 1041 1042 Elements = (*OuterElements)->Package.Elements; 1043 ObjDesc = Elements[SortIndex]; 1044 1045 if (ObjDesc->Common.Type != ACPI_TYPE_INTEGER) 1046 { 1047 return (AE_AML_OPERAND_TYPE); 1048 } 1049 1050 /* 1051 * The list must be sorted in the specified order. If we detect a 1052 * discrepancy, sort the entire list. 1053 */ 1054 if (((SortDirection == ACPI_SORT_ASCENDING) && 1055 (ObjDesc->Integer.Value < PreviousValue)) || 1056 ((SortDirection == ACPI_SORT_DESCENDING) && 1057 (ObjDesc->Integer.Value > PreviousValue))) 1058 { 1059 AcpiNsSortList (&ReturnObject->Package.Elements[StartIndex], 1060 OuterElementCount, SortIndex, SortDirection); 1061 1062 Info->ReturnFlags |= ACPI_OBJECT_REPAIRED; 1063 1064 ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR, 1065 "%s: Repaired unsorted list - now sorted by %s\n", 1066 Info->FullPathname, SortKeyName)); 1067 return (AE_OK); 1068 } 1069 1070 PreviousValue = (UINT32) ObjDesc->Integer.Value; 1071 OuterElements++; 1072 } 1073 1074 return (AE_OK); 1075 } 1076 1077 1078 /****************************************************************************** 1079 * 1080 * FUNCTION: AcpiNsSortList 1081 * 1082 * PARAMETERS: Elements - Package object element list 1083 * Count - Element count for above 1084 * Index - Sort by which package element 1085 * SortDirection - Ascending or Descending sort 1086 * 1087 * RETURN: None 1088 * 1089 * DESCRIPTION: Sort the objects that are in a package element list. 1090 * 1091 * NOTE: Assumes that all NULL elements have been removed from the package, 1092 * and that all elements have been verified to be of type Integer. 1093 * 1094 *****************************************************************************/ 1095 1096 static void 1097 AcpiNsSortList ( 1098 ACPI_OPERAND_OBJECT **Elements, 1099 UINT32 Count, 1100 UINT32 Index, 1101 UINT8 SortDirection) 1102 { 1103 ACPI_OPERAND_OBJECT *ObjDesc1; 1104 ACPI_OPERAND_OBJECT *ObjDesc2; 1105 ACPI_OPERAND_OBJECT *TempObj; 1106 UINT32 i; 1107 UINT32 j; 1108 1109 1110 /* Simple bubble sort */ 1111 1112 for (i = 1; i < Count; i++) 1113 { 1114 for (j = (Count - 1); j >= i; j--) 1115 { 1116 ObjDesc1 = Elements[j-1]->Package.Elements[Index]; 1117 ObjDesc2 = Elements[j]->Package.Elements[Index]; 1118 1119 if (((SortDirection == ACPI_SORT_ASCENDING) && 1120 (ObjDesc1->Integer.Value > ObjDesc2->Integer.Value)) || 1121 1122 ((SortDirection == ACPI_SORT_DESCENDING) && 1123 (ObjDesc1->Integer.Value < ObjDesc2->Integer.Value))) 1124 { 1125 TempObj = Elements[j-1]; 1126 Elements[j-1] = Elements[j]; 1127 Elements[j] = TempObj; 1128 } 1129 } 1130 } 1131 } 1132 1133 1134 /****************************************************************************** 1135 * 1136 * FUNCTION: AcpiNsRemoveElement 1137 * 1138 * PARAMETERS: ObjDesc - Package object element list 1139 * Index - Index of element to remove 1140 * 1141 * RETURN: None 1142 * 1143 * DESCRIPTION: Remove the requested element of a package and delete it. 1144 * 1145 *****************************************************************************/ 1146 1147 static void 1148 AcpiNsRemoveElement ( 1149 ACPI_OPERAND_OBJECT *ObjDesc, 1150 UINT32 Index) 1151 { 1152 ACPI_OPERAND_OBJECT **Source; 1153 ACPI_OPERAND_OBJECT **Dest; 1154 UINT32 Count; 1155 UINT32 NewCount; 1156 UINT32 i; 1157 1158 1159 ACPI_FUNCTION_NAME (NsRemoveElement); 1160 1161 1162 Count = ObjDesc->Package.Count; 1163 NewCount = Count - 1; 1164 1165 Source = ObjDesc->Package.Elements; 1166 Dest = Source; 1167 1168 /* Examine all elements of the package object, remove matched index */ 1169 1170 for (i = 0; i < Count; i++) 1171 { 1172 if (i == Index) 1173 { 1174 AcpiUtRemoveReference (*Source); /* Remove one ref for being in pkg */ 1175 AcpiUtRemoveReference (*Source); 1176 } 1177 else 1178 { 1179 *Dest = *Source; 1180 Dest++; 1181 } 1182 1183 Source++; 1184 } 1185 1186 /* NULL terminate list and update the package count */ 1187 1188 *Dest = NULL; 1189 ObjDesc->Package.Count = NewCount; 1190 }
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |