diff options
author | jkim <jkim@FreeBSD.org> | 2013-05-17 23:13:40 +0000 |
---|---|---|
committer | jkim <jkim@FreeBSD.org> | 2013-05-17 23:13:40 +0000 |
commit | af69f95bba3597db53a980597cfd371c9f6ee7cf (patch) | |
tree | 740dae2325e162bb086ea6e7e5d481c4b669e232 /source/components/namespace/nsrepair2.c | |
parent | 00f95aec269522bc092cf85fe57fcfc19efecec9 (diff) | |
download | FreeBSD-src-af69f95bba3597db53a980597cfd371c9f6ee7cf.zip FreeBSD-src-af69f95bba3597db53a980597cfd371c9f6ee7cf.tar.gz |
Import ACPICA 20130517.
Diffstat (limited to 'source/components/namespace/nsrepair2.c')
-rw-r--r-- | source/components/namespace/nsrepair2.c | 304 |
1 files changed, 271 insertions, 33 deletions
diff --git a/source/components/namespace/nsrepair2.c b/source/components/namespace/nsrepair2.c index 63fb36d..0dcfaad 100644 --- a/source/components/namespace/nsrepair2.c +++ b/source/components/namespace/nsrepair2.c @@ -86,6 +86,11 @@ AcpiNsRepair_CID ( ACPI_OPERAND_OBJECT **ReturnObjectPtr); static ACPI_STATUS +AcpiNsRepair_CST ( + ACPI_EVALUATE_INFO *Info, + ACPI_OPERAND_OBJECT **ReturnObjectPtr); + +static ACPI_STATUS AcpiNsRepair_FDE ( ACPI_EVALUATE_INFO *Info, ACPI_OPERAND_OBJECT **ReturnObjectPtr); @@ -96,6 +101,11 @@ AcpiNsRepair_HID ( ACPI_OPERAND_OBJECT **ReturnObjectPtr); static ACPI_STATUS +AcpiNsRepair_PRT ( + ACPI_EVALUATE_INFO *Info, + ACPI_OPERAND_OBJECT **ReturnObjectPtr); + +static ACPI_STATUS AcpiNsRepair_PSS ( ACPI_EVALUATE_INFO *Info, ACPI_OPERAND_OBJECT **ReturnObjectPtr); @@ -109,11 +119,22 @@ static ACPI_STATUS AcpiNsCheckSortedList ( ACPI_EVALUATE_INFO *Info, ACPI_OPERAND_OBJECT *ReturnObject, + UINT32 StartIndex, UINT32 ExpectedCount, UINT32 SortIndex, UINT8 SortDirection, char *SortKeyName); +/* Values for SortDirection above */ + +#define ACPI_SORT_ASCENDING 0 +#define ACPI_SORT_DESCENDING 1 + +static void +AcpiNsRemoveElement ( + ACPI_OPERAND_OBJECT *ObjDesc, + UINT32 Index); + static void AcpiNsSortList ( ACPI_OPERAND_OBJECT **Elements, @@ -121,11 +142,6 @@ AcpiNsSortList ( UINT32 Index, UINT8 SortDirection); -/* Values for SortDirection above */ - -#define ACPI_SORT_ASCENDING 0 -#define ACPI_SORT_DESCENDING 1 - /* * This table contains the names of the predefined methods for which we can @@ -135,9 +151,11 @@ AcpiNsSortList ( * * _ALR: Sort the list ascending by AmbientIlluminance * _CID: Strings: uppercase all, remove any leading asterisk + * _CST: Sort the list ascending by C state type * _FDE: Convert Buffer of BYTEs to a Buffer of DWORDs * _GTM: Convert Buffer of BYTEs to a Buffer of DWORDs * _HID: Strings: uppercase all, remove any leading asterisk + * _PRT: Fix reversed SourceName and SourceIndex * _PSS: Sort the list descending by Power * _TSS: Sort the list descending by Power * @@ -152,9 +170,11 @@ static const ACPI_REPAIR_INFO AcpiNsRepairableNames[] = { {"_ALR", AcpiNsRepair_ALR}, {"_CID", AcpiNsRepair_CID}, + {"_CST", AcpiNsRepair_CST}, {"_FDE", AcpiNsRepair_FDE}, {"_GTM", AcpiNsRepair_FDE}, /* _GTM has same repair as _FDE */ {"_HID", AcpiNsRepair_HID}, + {"_PRT", AcpiNsRepair_PRT}, {"_PSS", AcpiNsRepair_PSS}, {"_TSS", AcpiNsRepair_TSS}, {{0,0,0,0}, NULL} /* Table terminator */ @@ -267,7 +287,7 @@ AcpiNsRepair_ALR ( ACPI_STATUS Status; - Status = AcpiNsCheckSortedList (Info, ReturnObject, 2, 1, + Status = AcpiNsCheckSortedList (Info, ReturnObject, 0, 2, 1, ACPI_SORT_ASCENDING, "AmbientIlluminance"); return (Status); @@ -354,6 +374,7 @@ AcpiNsRepair_FDE ( break; default: + return (AE_AML_OPERAND_TYPE); } @@ -446,6 +467,97 @@ AcpiNsRepair_CID ( /****************************************************************************** * + * FUNCTION: AcpiNsRepair_CST + * + * PARAMETERS: Info - Method execution information block + * ReturnObjectPtr - Pointer to the object returned from the + * evaluation of a method or object + * + * RETURN: Status. AE_OK if object is OK or was repaired successfully + * + * DESCRIPTION: Repair for the _CST object: + * 1. Sort the list ascending by C state type + * 2. Ensure type cannot be zero + * 3. A sub-package count of zero means _CST is meaningless + * 4. Count must match the number of C state sub-packages + * + *****************************************************************************/ + +static ACPI_STATUS +AcpiNsRepair_CST ( + ACPI_EVALUATE_INFO *Info, + ACPI_OPERAND_OBJECT **ReturnObjectPtr) +{ + ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; + ACPI_OPERAND_OBJECT **OuterElements; + UINT32 OuterElementCount; + ACPI_OPERAND_OBJECT *ObjDesc; + ACPI_STATUS Status; + BOOLEAN Removing; + UINT32 i; + + + ACPI_FUNCTION_NAME (NsRepair_CST); + + + /* + * Entries (subpackages) in the _CST Package must be sorted by the + * C-state type, in ascending order. + */ + Status = AcpiNsCheckSortedList (Info, ReturnObject, 1, 4, 1, + ACPI_SORT_ASCENDING, "C-State Type"); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + + /* + * We now know the list is correctly sorted by C-state type. Check if + * the C-state type values are proportional. + */ + OuterElementCount = ReturnObject->Package.Count - 1; + i = 0; + while (i < OuterElementCount) + { + OuterElements = &ReturnObject->Package.Elements[i + 1]; + Removing = FALSE; + + if ((*OuterElements)->Package.Count == 0) + { + ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags, + "SubPackage[%u] - removing entry due to zero count", i)); + Removing = TRUE; + } + + ObjDesc = (*OuterElements)->Package.Elements[1]; /* Index1 = Type */ + if ((UINT32) ObjDesc->Integer.Value == 0) + { + ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags, + "SubPackage[%u] - removing entry due to invalid Type(0)", i)); + Removing = TRUE; + } + + if (Removing) + { + AcpiNsRemoveElement (ReturnObject, i + 1); + OuterElementCount--; + } + else + { + i++; + } + } + + /* Update top-level package count, Type "Integer" checked elsewhere */ + + ObjDesc = ReturnObject->Package.Elements[0]; + ObjDesc->Integer.Value = OuterElementCount; + return (AE_OK); +} + + +/****************************************************************************** + * * FUNCTION: AcpiNsRepair_HID * * PARAMETERS: Info - Method execution information block @@ -536,7 +648,7 @@ AcpiNsRepair_HID ( /****************************************************************************** * - * FUNCTION: AcpiNsRepair_TSS + * FUNCTION: AcpiNsRepair_PRT * * PARAMETERS: Info - Method execution information block * ReturnObjectPtr - Pointer to the object returned from the @@ -544,40 +656,57 @@ AcpiNsRepair_HID ( * * RETURN: Status. AE_OK if object is OK or was repaired successfully * - * DESCRIPTION: Repair for the _TSS object. If necessary, sort the object list - * descending by the power dissipation values. + * DESCRIPTION: Repair for the _PRT object. If necessary, fix reversed + * SourceName and SourceIndex field, a common BIOS bug. * *****************************************************************************/ static ACPI_STATUS -AcpiNsRepair_TSS ( +AcpiNsRepair_PRT ( ACPI_EVALUATE_INFO *Info, ACPI_OPERAND_OBJECT **ReturnObjectPtr) { - ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; - ACPI_STATUS Status; - ACPI_NAMESPACE_NODE *Node; + ACPI_OPERAND_OBJECT *PackageObject = *ReturnObjectPtr; + ACPI_OPERAND_OBJECT **TopObjectList; + ACPI_OPERAND_OBJECT **SubObjectList; + ACPI_OPERAND_OBJECT *ObjDesc; + UINT32 ElementCount; + UINT32 Index; - /* - * We can only sort the _TSS return package if there is no _PSS in the - * same scope. This is because if _PSS is present, the ACPI specification - * dictates that the _TSS Power Dissipation field is to be ignored, and - * therefore some BIOSs leave garbage values in the _TSS Power field(s). - * In this case, it is best to just return the _TSS package as-is. - * (May, 2011) - */ - Status = AcpiNsGetNode (Info->Node, "^_PSS", - ACPI_NS_NO_UPSEARCH, &Node); - if (ACPI_SUCCESS (Status)) + /* Each element in the _PRT package is a subpackage */ + + TopObjectList = PackageObject->Package.Elements; + ElementCount = PackageObject->Package.Count; + + for (Index = 0; Index < ElementCount; Index++) { - return (AE_OK); - } + SubObjectList = (*TopObjectList)->Package.Elements; - Status = AcpiNsCheckSortedList (Info, ReturnObject, 5, 1, - ACPI_SORT_DESCENDING, "PowerDissipation"); + /* + * If the BIOS has erroneously reversed the _PRT SourceName (index 2) + * and the SourceIndex (index 3), fix it. _PRT is important enough to + * workaround this BIOS error. This also provides compatibility with + * other ACPI implementations. + */ + ObjDesc = SubObjectList[3]; + if (!ObjDesc || (ObjDesc->Common.Type != ACPI_TYPE_INTEGER)) + { + SubObjectList[3] = SubObjectList[2]; + SubObjectList[2] = ObjDesc; + Info->ReturnFlags |= ACPI_OBJECT_REPAIRED; - return (Status); + ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags, + "PRT[%X]: Fixed reversed SourceName and SourceIndex", + Index)); + } + + /* Point to the next ACPI_OPERAND_OBJECT in the top level package */ + + TopObjectList++; + } + + return (AE_OK); } @@ -619,7 +748,7 @@ AcpiNsRepair_PSS ( * incorrectly sorted, sort it. We sort by CpuFrequency, since this * should be proportional to the power. */ - Status =AcpiNsCheckSortedList (Info, ReturnObject, 6, 0, + Status =AcpiNsCheckSortedList (Info, ReturnObject, 0, 6, 0, ACPI_SORT_DESCENDING, "CpuFrequency"); if (ACPI_FAILURE (Status)) { @@ -656,10 +785,58 @@ AcpiNsRepair_PSS ( /****************************************************************************** * + * FUNCTION: AcpiNsRepair_TSS + * + * PARAMETERS: Info - Method execution information block + * ReturnObjectPtr - Pointer to the object returned from the + * evaluation of a method or object + * + * RETURN: Status. AE_OK if object is OK or was repaired successfully + * + * DESCRIPTION: Repair for the _TSS object. If necessary, sort the object list + * descending by the power dissipation values. + * + *****************************************************************************/ + +static ACPI_STATUS +AcpiNsRepair_TSS ( + ACPI_EVALUATE_INFO *Info, + ACPI_OPERAND_OBJECT **ReturnObjectPtr) +{ + ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; + ACPI_STATUS Status; + ACPI_NAMESPACE_NODE *Node; + + + /* + * We can only sort the _TSS return package if there is no _PSS in the + * same scope. This is because if _PSS is present, the ACPI specification + * dictates that the _TSS Power Dissipation field is to be ignored, and + * therefore some BIOSs leave garbage values in the _TSS Power field(s). + * In this case, it is best to just return the _TSS package as-is. + * (May, 2011) + */ + Status = AcpiNsGetNode (Info->Node, "^_PSS", + ACPI_NS_NO_UPSEARCH, &Node); + if (ACPI_SUCCESS (Status)) + { + return (AE_OK); + } + + Status = AcpiNsCheckSortedList (Info, ReturnObject, 0, 5, 1, + ACPI_SORT_DESCENDING, "PowerDissipation"); + + return (Status); +} + + +/****************************************************************************** + * * FUNCTION: AcpiNsCheckSortedList * * PARAMETERS: Info - Method execution information block * ReturnObject - Pointer to the top-level returned object + * StartIndex - Index of the first sub-package * ExpectedCount - Minimum length of each sub-package * SortIndex - Sub-package entry to sort on * SortDirection - Ascending or descending @@ -677,6 +854,7 @@ static ACPI_STATUS AcpiNsCheckSortedList ( ACPI_EVALUATE_INFO *Info, ACPI_OPERAND_OBJECT *ReturnObject, + UINT32 StartIndex, UINT32 ExpectedCount, UINT32 SortIndex, UINT8 SortDirection, @@ -705,13 +883,15 @@ AcpiNsCheckSortedList ( * Any NULL elements should have been removed by earlier call * to AcpiNsRemoveNullElements. */ - OuterElements = ReturnObject->Package.Elements; OuterElementCount = ReturnObject->Package.Count; - if (!OuterElementCount) + if (!OuterElementCount || StartIndex >= OuterElementCount) { return (AE_AML_PACKAGE_LIMIT); } + OuterElements = &ReturnObject->Package.Elements[StartIndex]; + OuterElementCount -= StartIndex; + PreviousValue = 0; if (SortDirection == ACPI_SORT_DESCENDING) { @@ -753,7 +933,7 @@ AcpiNsCheckSortedList ( ((SortDirection == ACPI_SORT_DESCENDING) && (ObjDesc->Integer.Value > PreviousValue))) { - AcpiNsSortList (ReturnObject->Package.Elements, + AcpiNsSortList (&ReturnObject->Package.Elements[StartIndex], OuterElementCount, SortIndex, SortDirection); Info->ReturnFlags |= ACPI_OBJECT_REPAIRED; @@ -826,3 +1006,61 @@ AcpiNsSortList ( } } } + + +/****************************************************************************** + * + * FUNCTION: AcpiNsRemoveElement + * + * PARAMETERS: ObjDesc - Package object element list + * Index - Index of element to remove + * + * RETURN: None + * + * DESCRIPTION: Remove the requested element of a package and delete it. + * + *****************************************************************************/ + +static void +AcpiNsRemoveElement ( + ACPI_OPERAND_OBJECT *ObjDesc, + UINT32 Index) +{ + ACPI_OPERAND_OBJECT **Source; + ACPI_OPERAND_OBJECT **Dest; + UINT32 Count; + UINT32 NewCount; + UINT32 i; + + + ACPI_FUNCTION_NAME (NsRemoveElement); + + + Count = ObjDesc->Package.Count; + NewCount = Count - 1; + + Source = ObjDesc->Package.Elements; + Dest = Source; + + /* Examine all elements of the package object, remove matched index */ + + for (i = 0; i < Count; i++) + { + if (i == Index) + { + AcpiUtRemoveReference (*Source); /* Remove one ref for being in pkg */ + AcpiUtRemoveReference (*Source); + } + else + { + *Dest = *Source; + Dest++; + } + Source++; + } + + /* NULL terminate list and update the package count */ + + *Dest = NULL; + ObjDesc->Package.Count = NewCount; +} |