157190917SDana Myers /******************************************************************************
257190917SDana Myers *
357190917SDana Myers * Module Name: nsrepair2 - Repair for objects returned by specific
457190917SDana Myers * predefined methods
557190917SDana Myers *
657190917SDana Myers *****************************************************************************/
757190917SDana Myers
826f3cdf0SGordon Ross /*
9*cb565728SJerry Jelinek * Copyright (C) 2000 - 2016, Intel Corp.
1057190917SDana Myers * All rights reserved.
1157190917SDana Myers *
1226f3cdf0SGordon Ross * Redistribution and use in source and binary forms, with or without
1326f3cdf0SGordon Ross * modification, are permitted provided that the following conditions
1426f3cdf0SGordon Ross * are met:
1526f3cdf0SGordon Ross * 1. Redistributions of source code must retain the above copyright
1626f3cdf0SGordon Ross * notice, this list of conditions, and the following disclaimer,
1726f3cdf0SGordon Ross * without modification.
1826f3cdf0SGordon Ross * 2. Redistributions in binary form must reproduce at minimum a disclaimer
1926f3cdf0SGordon Ross * substantially similar to the "NO WARRANTY" disclaimer below
2026f3cdf0SGordon Ross * ("Disclaimer") and any redistribution must be conditioned upon
2126f3cdf0SGordon Ross * including a substantially similar Disclaimer requirement for further
2226f3cdf0SGordon Ross * binary redistribution.
2326f3cdf0SGordon Ross * 3. Neither the names of the above-listed copyright holders nor the names
2426f3cdf0SGordon Ross * of any contributors may be used to endorse or promote products derived
2526f3cdf0SGordon Ross * from this software without specific prior written permission.
2657190917SDana Myers *
2726f3cdf0SGordon Ross * Alternatively, this software may be distributed under the terms of the
2826f3cdf0SGordon Ross * GNU General Public License ("GPL") version 2 as published by the Free
2926f3cdf0SGordon Ross * Software Foundation.
3057190917SDana Myers *
3126f3cdf0SGordon Ross * NO WARRANTY
3226f3cdf0SGordon Ross * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
3326f3cdf0SGordon Ross * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3426f3cdf0SGordon Ross * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
3526f3cdf0SGordon Ross * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3626f3cdf0SGordon Ross * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
3726f3cdf0SGordon Ross * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
3826f3cdf0SGordon Ross * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3926f3cdf0SGordon Ross * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
4026f3cdf0SGordon Ross * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
4126f3cdf0SGordon Ross * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
4226f3cdf0SGordon Ross * POSSIBILITY OF SUCH DAMAGES.
4326f3cdf0SGordon Ross */
4457190917SDana Myers
4557190917SDana Myers #include "acpi.h"
4657190917SDana Myers #include "accommon.h"
4757190917SDana Myers #include "acnamesp.h"
4857190917SDana Myers
4957190917SDana Myers #define _COMPONENT ACPI_NAMESPACE
5057190917SDana Myers ACPI_MODULE_NAME ("nsrepair2")
5157190917SDana Myers
5257190917SDana Myers
5357190917SDana Myers /*
5457190917SDana Myers * Information structure and handler for ACPI predefined names that can
5557190917SDana Myers * be repaired on a per-name basis.
5657190917SDana Myers */
5757190917SDana Myers typedef
5857190917SDana Myers ACPI_STATUS (*ACPI_REPAIR_FUNCTION) (
59*cb565728SJerry Jelinek ACPI_EVALUATE_INFO *Info,
6057190917SDana Myers ACPI_OPERAND_OBJECT **ReturnObjectPtr);
6157190917SDana Myers
6257190917SDana Myers typedef struct acpi_repair_info
6357190917SDana Myers {
6457190917SDana Myers char Name[ACPI_NAME_SIZE];
6557190917SDana Myers ACPI_REPAIR_FUNCTION RepairFunction;
6657190917SDana Myers
6757190917SDana Myers } ACPI_REPAIR_INFO;
6857190917SDana Myers
6957190917SDana Myers
7057190917SDana Myers /* Local prototypes */
7157190917SDana Myers
7257190917SDana Myers static const ACPI_REPAIR_INFO *
73*cb565728SJerry Jelinek AcpiNsMatchComplexRepair (
7457190917SDana Myers ACPI_NAMESPACE_NODE *Node);
7557190917SDana Myers
7657190917SDana Myers static ACPI_STATUS
7757190917SDana Myers AcpiNsRepair_ALR (
78*cb565728SJerry Jelinek ACPI_EVALUATE_INFO *Info,
7957190917SDana Myers ACPI_OPERAND_OBJECT **ReturnObjectPtr);
8057190917SDana Myers
8157190917SDana Myers static ACPI_STATUS
8226f3cdf0SGordon Ross AcpiNsRepair_CID (
83*cb565728SJerry Jelinek ACPI_EVALUATE_INFO *Info,
84*cb565728SJerry Jelinek ACPI_OPERAND_OBJECT **ReturnObjectPtr);
85*cb565728SJerry Jelinek
86*cb565728SJerry Jelinek static ACPI_STATUS
87*cb565728SJerry Jelinek AcpiNsRepair_CST (
88*cb565728SJerry Jelinek ACPI_EVALUATE_INFO *Info,
8926f3cdf0SGordon Ross ACPI_OPERAND_OBJECT **ReturnObjectPtr);
9026f3cdf0SGordon Ross
9126f3cdf0SGordon Ross static ACPI_STATUS
9226f3cdf0SGordon Ross AcpiNsRepair_FDE (
93*cb565728SJerry Jelinek ACPI_EVALUATE_INFO *Info,
9426f3cdf0SGordon Ross ACPI_OPERAND_OBJECT **ReturnObjectPtr);
9526f3cdf0SGordon Ross
9626f3cdf0SGordon Ross static ACPI_STATUS
9726f3cdf0SGordon Ross AcpiNsRepair_HID (
98*cb565728SJerry Jelinek ACPI_EVALUATE_INFO *Info,
99*cb565728SJerry Jelinek ACPI_OPERAND_OBJECT **ReturnObjectPtr);
100*cb565728SJerry Jelinek
101*cb565728SJerry Jelinek static ACPI_STATUS
102*cb565728SJerry Jelinek AcpiNsRepair_PRT (
103*cb565728SJerry Jelinek ACPI_EVALUATE_INFO *Info,
10426f3cdf0SGordon Ross ACPI_OPERAND_OBJECT **ReturnObjectPtr);
10526f3cdf0SGordon Ross
10626f3cdf0SGordon Ross static ACPI_STATUS
10757190917SDana Myers AcpiNsRepair_PSS (
108*cb565728SJerry Jelinek ACPI_EVALUATE_INFO *Info,
10957190917SDana Myers ACPI_OPERAND_OBJECT **ReturnObjectPtr);
11057190917SDana Myers
11157190917SDana Myers static ACPI_STATUS
11257190917SDana Myers AcpiNsRepair_TSS (
113*cb565728SJerry Jelinek ACPI_EVALUATE_INFO *Info,
11457190917SDana Myers ACPI_OPERAND_OBJECT **ReturnObjectPtr);
11557190917SDana Myers
11657190917SDana Myers static ACPI_STATUS
11757190917SDana Myers AcpiNsCheckSortedList (
118*cb565728SJerry Jelinek ACPI_EVALUATE_INFO *Info,
11957190917SDana Myers ACPI_OPERAND_OBJECT *ReturnObject,
120*cb565728SJerry Jelinek UINT32 StartIndex,
12157190917SDana Myers UINT32 ExpectedCount,
12257190917SDana Myers UINT32 SortIndex,
12357190917SDana Myers UINT8 SortDirection,
12457190917SDana Myers char *SortKeyName);
12557190917SDana Myers
126*cb565728SJerry Jelinek /* Values for SortDirection above */
127*cb565728SJerry Jelinek
128*cb565728SJerry Jelinek #define ACPI_SORT_ASCENDING 0
129*cb565728SJerry Jelinek #define ACPI_SORT_DESCENDING 1
130*cb565728SJerry Jelinek
131*cb565728SJerry Jelinek static void
132*cb565728SJerry Jelinek AcpiNsRemoveElement (
133*cb565728SJerry Jelinek ACPI_OPERAND_OBJECT *ObjDesc,
134*cb565728SJerry Jelinek UINT32 Index);
135*cb565728SJerry Jelinek
13626f3cdf0SGordon Ross static void
13757190917SDana Myers AcpiNsSortList (
13857190917SDana Myers ACPI_OPERAND_OBJECT **Elements,
13957190917SDana Myers UINT32 Count,
14057190917SDana Myers UINT32 Index,
14157190917SDana Myers UINT8 SortDirection);
14257190917SDana Myers
14357190917SDana Myers
14457190917SDana Myers /*
14557190917SDana Myers * This table contains the names of the predefined methods for which we can
14657190917SDana Myers * perform more complex repairs.
14757190917SDana Myers *
14826f3cdf0SGordon Ross * As necessary:
14926f3cdf0SGordon Ross *
15026f3cdf0SGordon Ross * _ALR: Sort the list ascending by AmbientIlluminance
15126f3cdf0SGordon Ross * _CID: Strings: uppercase all, remove any leading asterisk
152*cb565728SJerry Jelinek * _CST: Sort the list ascending by C state type
15326f3cdf0SGordon Ross * _FDE: Convert Buffer of BYTEs to a Buffer of DWORDs
15426f3cdf0SGordon Ross * _GTM: Convert Buffer of BYTEs to a Buffer of DWORDs
15526f3cdf0SGordon Ross * _HID: Strings: uppercase all, remove any leading asterisk
156*cb565728SJerry Jelinek * _PRT: Fix reversed SourceName and SourceIndex
15726f3cdf0SGordon Ross * _PSS: Sort the list descending by Power
15826f3cdf0SGordon Ross * _TSS: Sort the list descending by Power
15926f3cdf0SGordon Ross *
16026f3cdf0SGordon Ross * Names that must be packages, but cannot be sorted:
16126f3cdf0SGordon Ross *
16226f3cdf0SGordon Ross * _BCL: Values are tied to the Package index where they appear, and cannot
16326f3cdf0SGordon Ross * be moved or sorted. These index values are used for _BQC and _BCM.
16426f3cdf0SGordon Ross * However, we can fix the case where a buffer is returned, by converting
16526f3cdf0SGordon Ross * it to a Package of integers.
16657190917SDana Myers */
16757190917SDana Myers static const ACPI_REPAIR_INFO AcpiNsRepairableNames[] =
16857190917SDana Myers {
16957190917SDana Myers {"_ALR", AcpiNsRepair_ALR},
17026f3cdf0SGordon Ross {"_CID", AcpiNsRepair_CID},
171*cb565728SJerry Jelinek {"_CST", AcpiNsRepair_CST},
17226f3cdf0SGordon Ross {"_FDE", AcpiNsRepair_FDE},
17326f3cdf0SGordon Ross {"_GTM", AcpiNsRepair_FDE}, /* _GTM has same repair as _FDE */
17426f3cdf0SGordon Ross {"_HID", AcpiNsRepair_HID},
175*cb565728SJerry Jelinek {"_PRT", AcpiNsRepair_PRT},
17657190917SDana Myers {"_PSS", AcpiNsRepair_PSS},
17757190917SDana Myers {"_TSS", AcpiNsRepair_TSS},
17857190917SDana Myers {{0,0,0,0}, NULL} /* Table terminator */
17957190917SDana Myers };
18057190917SDana Myers
18157190917SDana Myers
18226f3cdf0SGordon Ross #define ACPI_FDE_FIELD_COUNT 5
18326f3cdf0SGordon Ross #define ACPI_FDE_BYTE_BUFFER_SIZE 5
18426f3cdf0SGordon Ross #define ACPI_FDE_DWORD_BUFFER_SIZE (ACPI_FDE_FIELD_COUNT * sizeof (UINT32))
18526f3cdf0SGordon Ross
18626f3cdf0SGordon Ross
18757190917SDana Myers /******************************************************************************
18857190917SDana Myers *
18957190917SDana Myers * FUNCTION: AcpiNsComplexRepairs
19057190917SDana Myers *
191*cb565728SJerry Jelinek * PARAMETERS: Info - Method execution information block
19257190917SDana Myers * Node - Namespace node for the method/object
19357190917SDana Myers * ValidateStatus - Original status of earlier validation
19457190917SDana Myers * ReturnObjectPtr - Pointer to the object returned from the
19557190917SDana Myers * evaluation of a method or object
19657190917SDana Myers *
19757190917SDana Myers * RETURN: Status. AE_OK if repair was successful. If name is not
19857190917SDana Myers * matched, ValidateStatus is returned.
19957190917SDana Myers *
20057190917SDana Myers * DESCRIPTION: Attempt to repair/convert a return object of a type that was
20157190917SDana Myers * not expected.
20257190917SDana Myers *
20357190917SDana Myers *****************************************************************************/
20457190917SDana Myers
20557190917SDana Myers ACPI_STATUS
AcpiNsComplexRepairs(ACPI_EVALUATE_INFO * Info,ACPI_NAMESPACE_NODE * Node,ACPI_STATUS ValidateStatus,ACPI_OPERAND_OBJECT ** ReturnObjectPtr)20657190917SDana Myers AcpiNsComplexRepairs (
207*cb565728SJerry Jelinek ACPI_EVALUATE_INFO *Info,
20857190917SDana Myers ACPI_NAMESPACE_NODE *Node,
20957190917SDana Myers ACPI_STATUS ValidateStatus,
21057190917SDana Myers ACPI_OPERAND_OBJECT **ReturnObjectPtr)
21157190917SDana Myers {
21257190917SDana Myers const ACPI_REPAIR_INFO *Predefined;
21357190917SDana Myers ACPI_STATUS Status;
21457190917SDana Myers
21557190917SDana Myers
21657190917SDana Myers /* Check if this name is in the list of repairable names */
21757190917SDana Myers
218*cb565728SJerry Jelinek Predefined = AcpiNsMatchComplexRepair (Node);
21957190917SDana Myers if (!Predefined)
22057190917SDana Myers {
22157190917SDana Myers return (ValidateStatus);
22257190917SDana Myers }
22357190917SDana Myers
224*cb565728SJerry Jelinek Status = Predefined->RepairFunction (Info, ReturnObjectPtr);
22557190917SDana Myers return (Status);
22657190917SDana Myers }
22757190917SDana Myers
22857190917SDana Myers
22957190917SDana Myers /******************************************************************************
23057190917SDana Myers *
231*cb565728SJerry Jelinek * FUNCTION: AcpiNsMatchComplexRepair
23257190917SDana Myers *
23357190917SDana Myers * PARAMETERS: Node - Namespace node for the method/object
23457190917SDana Myers *
23557190917SDana Myers * RETURN: Pointer to entry in repair table. NULL indicates not found.
23657190917SDana Myers *
23757190917SDana Myers * DESCRIPTION: Check an object name against the repairable object list.
23857190917SDana Myers *
23957190917SDana Myers *****************************************************************************/
24057190917SDana Myers
24157190917SDana Myers static const ACPI_REPAIR_INFO *
AcpiNsMatchComplexRepair(ACPI_NAMESPACE_NODE * Node)242*cb565728SJerry Jelinek AcpiNsMatchComplexRepair (
24357190917SDana Myers ACPI_NAMESPACE_NODE *Node)
24457190917SDana Myers {
24557190917SDana Myers const ACPI_REPAIR_INFO *ThisName;
24657190917SDana Myers
24757190917SDana Myers
24857190917SDana Myers /* Search info table for a repairable predefined method/object name */
24957190917SDana Myers
25057190917SDana Myers ThisName = AcpiNsRepairableNames;
25157190917SDana Myers while (ThisName->RepairFunction)
25257190917SDana Myers {
25357190917SDana Myers if (ACPI_COMPARE_NAME (Node->Name.Ascii, ThisName->Name))
25457190917SDana Myers {
25557190917SDana Myers return (ThisName);
25657190917SDana Myers }
257*cb565728SJerry Jelinek
25857190917SDana Myers ThisName++;
25957190917SDana Myers }
26057190917SDana Myers
26157190917SDana Myers return (NULL); /* Not found */
26257190917SDana Myers }
26357190917SDana Myers
26457190917SDana Myers
26557190917SDana Myers /******************************************************************************
26657190917SDana Myers *
26757190917SDana Myers * FUNCTION: AcpiNsRepair_ALR
26857190917SDana Myers *
269*cb565728SJerry Jelinek * PARAMETERS: Info - Method execution information block
27057190917SDana Myers * ReturnObjectPtr - Pointer to the object returned from the
27157190917SDana Myers * evaluation of a method or object
27257190917SDana Myers *
27357190917SDana Myers * RETURN: Status. AE_OK if object is OK or was repaired successfully
27457190917SDana Myers *
27557190917SDana Myers * DESCRIPTION: Repair for the _ALR object. If necessary, sort the object list
27657190917SDana Myers * ascending by the ambient illuminance values.
27757190917SDana Myers *
27857190917SDana Myers *****************************************************************************/
27957190917SDana Myers
28057190917SDana Myers static ACPI_STATUS
AcpiNsRepair_ALR(ACPI_EVALUATE_INFO * Info,ACPI_OPERAND_OBJECT ** ReturnObjectPtr)28157190917SDana Myers AcpiNsRepair_ALR (
282*cb565728SJerry Jelinek ACPI_EVALUATE_INFO *Info,
28357190917SDana Myers ACPI_OPERAND_OBJECT **ReturnObjectPtr)
28457190917SDana Myers {
28557190917SDana Myers ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr;
28657190917SDana Myers ACPI_STATUS Status;
28757190917SDana Myers
28857190917SDana Myers
289*cb565728SJerry Jelinek Status = AcpiNsCheckSortedList (Info, ReturnObject, 0, 2, 1,
29057190917SDana Myers ACPI_SORT_ASCENDING, "AmbientIlluminance");
29157190917SDana Myers
29257190917SDana Myers return (Status);
29357190917SDana Myers }
29457190917SDana Myers
29557190917SDana Myers
29657190917SDana Myers /******************************************************************************
29757190917SDana Myers *
29826f3cdf0SGordon Ross * FUNCTION: AcpiNsRepair_FDE
29926f3cdf0SGordon Ross *
300*cb565728SJerry Jelinek * PARAMETERS: Info - Method execution information block
30126f3cdf0SGordon Ross * ReturnObjectPtr - Pointer to the object returned from the
30226f3cdf0SGordon Ross * evaluation of a method or object
30326f3cdf0SGordon Ross *
30426f3cdf0SGordon Ross * RETURN: Status. AE_OK if object is OK or was repaired successfully
30526f3cdf0SGordon Ross *
30626f3cdf0SGordon Ross * DESCRIPTION: Repair for the _FDE and _GTM objects. The expected return
30726f3cdf0SGordon Ross * value is a Buffer of 5 DWORDs. This function repairs a common
30826f3cdf0SGordon Ross * problem where the return value is a Buffer of BYTEs, not
30926f3cdf0SGordon Ross * DWORDs.
31026f3cdf0SGordon Ross *
31126f3cdf0SGordon Ross *****************************************************************************/
31226f3cdf0SGordon Ross
31326f3cdf0SGordon Ross static ACPI_STATUS
AcpiNsRepair_FDE(ACPI_EVALUATE_INFO * Info,ACPI_OPERAND_OBJECT ** ReturnObjectPtr)31426f3cdf0SGordon Ross AcpiNsRepair_FDE (
315*cb565728SJerry Jelinek ACPI_EVALUATE_INFO *Info,
31626f3cdf0SGordon Ross ACPI_OPERAND_OBJECT **ReturnObjectPtr)
31726f3cdf0SGordon Ross {
31826f3cdf0SGordon Ross ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr;
31926f3cdf0SGordon Ross ACPI_OPERAND_OBJECT *BufferObject;
32026f3cdf0SGordon Ross UINT8 *ByteBuffer;
32126f3cdf0SGordon Ross UINT32 *DwordBuffer;
32226f3cdf0SGordon Ross UINT32 i;
32326f3cdf0SGordon Ross
32426f3cdf0SGordon Ross
32526f3cdf0SGordon Ross ACPI_FUNCTION_NAME (NsRepair_FDE);
32626f3cdf0SGordon Ross
32726f3cdf0SGordon Ross
32826f3cdf0SGordon Ross switch (ReturnObject->Common.Type)
32926f3cdf0SGordon Ross {
33026f3cdf0SGordon Ross case ACPI_TYPE_BUFFER:
33126f3cdf0SGordon Ross
33226f3cdf0SGordon Ross /* This is the expected type. Length should be (at least) 5 DWORDs */
33326f3cdf0SGordon Ross
33426f3cdf0SGordon Ross if (ReturnObject->Buffer.Length >= ACPI_FDE_DWORD_BUFFER_SIZE)
33526f3cdf0SGordon Ross {
33626f3cdf0SGordon Ross return (AE_OK);
33726f3cdf0SGordon Ross }
33826f3cdf0SGordon Ross
33926f3cdf0SGordon Ross /* We can only repair if we have exactly 5 BYTEs */
34026f3cdf0SGordon Ross
34126f3cdf0SGordon Ross if (ReturnObject->Buffer.Length != ACPI_FDE_BYTE_BUFFER_SIZE)
34226f3cdf0SGordon Ross {
343*cb565728SJerry Jelinek ACPI_WARN_PREDEFINED ((AE_INFO,
344*cb565728SJerry Jelinek Info->FullPathname, Info->NodeFlags,
34526f3cdf0SGordon Ross "Incorrect return buffer length %u, expected %u",
34626f3cdf0SGordon Ross ReturnObject->Buffer.Length, ACPI_FDE_DWORD_BUFFER_SIZE));
34726f3cdf0SGordon Ross
34826f3cdf0SGordon Ross return (AE_AML_OPERAND_TYPE);
34926f3cdf0SGordon Ross }
35026f3cdf0SGordon Ross
35126f3cdf0SGordon Ross /* Create the new (larger) buffer object */
35226f3cdf0SGordon Ross
353*cb565728SJerry Jelinek BufferObject = AcpiUtCreateBufferObject (
354*cb565728SJerry Jelinek ACPI_FDE_DWORD_BUFFER_SIZE);
35526f3cdf0SGordon Ross if (!BufferObject)
35626f3cdf0SGordon Ross {
35726f3cdf0SGordon Ross return (AE_NO_MEMORY);
35826f3cdf0SGordon Ross }
35926f3cdf0SGordon Ross
36026f3cdf0SGordon Ross /* Expand each byte to a DWORD */
36126f3cdf0SGordon Ross
36226f3cdf0SGordon Ross ByteBuffer = ReturnObject->Buffer.Pointer;
363*cb565728SJerry Jelinek DwordBuffer = ACPI_CAST_PTR (UINT32,
364*cb565728SJerry Jelinek BufferObject->Buffer.Pointer);
36526f3cdf0SGordon Ross
36626f3cdf0SGordon Ross for (i = 0; i < ACPI_FDE_FIELD_COUNT; i++)
36726f3cdf0SGordon Ross {
36826f3cdf0SGordon Ross *DwordBuffer = (UINT32) *ByteBuffer;
36926f3cdf0SGordon Ross DwordBuffer++;
37026f3cdf0SGordon Ross ByteBuffer++;
37126f3cdf0SGordon Ross }
37226f3cdf0SGordon Ross
37326f3cdf0SGordon Ross ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR,
37426f3cdf0SGordon Ross "%s Expanded Byte Buffer to expected DWord Buffer\n",
375*cb565728SJerry Jelinek Info->FullPathname));
37626f3cdf0SGordon Ross break;
37726f3cdf0SGordon Ross
37826f3cdf0SGordon Ross default:
379*cb565728SJerry Jelinek
38026f3cdf0SGordon Ross return (AE_AML_OPERAND_TYPE);
38126f3cdf0SGordon Ross }
38226f3cdf0SGordon Ross
38326f3cdf0SGordon Ross /* Delete the original return object, return the new buffer object */
38426f3cdf0SGordon Ross
38526f3cdf0SGordon Ross AcpiUtRemoveReference (ReturnObject);
38626f3cdf0SGordon Ross *ReturnObjectPtr = BufferObject;
38726f3cdf0SGordon Ross
388*cb565728SJerry Jelinek Info->ReturnFlags |= ACPI_OBJECT_REPAIRED;
38926f3cdf0SGordon Ross return (AE_OK);
39026f3cdf0SGordon Ross }
39126f3cdf0SGordon Ross
39226f3cdf0SGordon Ross
39326f3cdf0SGordon Ross /******************************************************************************
39426f3cdf0SGordon Ross *
39526f3cdf0SGordon Ross * FUNCTION: AcpiNsRepair_CID
39626f3cdf0SGordon Ross *
397*cb565728SJerry Jelinek * PARAMETERS: Info - Method execution information block
39826f3cdf0SGordon Ross * ReturnObjectPtr - Pointer to the object returned from the
39926f3cdf0SGordon Ross * evaluation of a method or object
40026f3cdf0SGordon Ross *
40126f3cdf0SGordon Ross * RETURN: Status. AE_OK if object is OK or was repaired successfully
40226f3cdf0SGordon Ross *
40326f3cdf0SGordon Ross * DESCRIPTION: Repair for the _CID object. If a string, ensure that all
40426f3cdf0SGordon Ross * letters are uppercase and that there is no leading asterisk.
40526f3cdf0SGordon Ross * If a Package, ensure same for all string elements.
40626f3cdf0SGordon Ross *
40726f3cdf0SGordon Ross *****************************************************************************/
40826f3cdf0SGordon Ross
40926f3cdf0SGordon Ross static ACPI_STATUS
AcpiNsRepair_CID(ACPI_EVALUATE_INFO * Info,ACPI_OPERAND_OBJECT ** ReturnObjectPtr)41026f3cdf0SGordon Ross AcpiNsRepair_CID (
411*cb565728SJerry Jelinek ACPI_EVALUATE_INFO *Info,
41226f3cdf0SGordon Ross ACPI_OPERAND_OBJECT **ReturnObjectPtr)
41326f3cdf0SGordon Ross {
41426f3cdf0SGordon Ross ACPI_STATUS Status;
41526f3cdf0SGordon Ross ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr;
41626f3cdf0SGordon Ross ACPI_OPERAND_OBJECT **ElementPtr;
41726f3cdf0SGordon Ross ACPI_OPERAND_OBJECT *OriginalElement;
41826f3cdf0SGordon Ross UINT16 OriginalRefCount;
41926f3cdf0SGordon Ross UINT32 i;
42026f3cdf0SGordon Ross
42126f3cdf0SGordon Ross
42226f3cdf0SGordon Ross /* Check for _CID as a simple string */
42326f3cdf0SGordon Ross
42426f3cdf0SGordon Ross if (ReturnObject->Common.Type == ACPI_TYPE_STRING)
42526f3cdf0SGordon Ross {
426*cb565728SJerry Jelinek Status = AcpiNsRepair_HID (Info, ReturnObjectPtr);
42726f3cdf0SGordon Ross return (Status);
42826f3cdf0SGordon Ross }
42926f3cdf0SGordon Ross
43026f3cdf0SGordon Ross /* Exit if not a Package */
43126f3cdf0SGordon Ross
43226f3cdf0SGordon Ross if (ReturnObject->Common.Type != ACPI_TYPE_PACKAGE)
43326f3cdf0SGordon Ross {
43426f3cdf0SGordon Ross return (AE_OK);
43526f3cdf0SGordon Ross }
43626f3cdf0SGordon Ross
43726f3cdf0SGordon Ross /* Examine each element of the _CID package */
43826f3cdf0SGordon Ross
43926f3cdf0SGordon Ross ElementPtr = ReturnObject->Package.Elements;
44026f3cdf0SGordon Ross for (i = 0; i < ReturnObject->Package.Count; i++)
44126f3cdf0SGordon Ross {
44226f3cdf0SGordon Ross OriginalElement = *ElementPtr;
44326f3cdf0SGordon Ross OriginalRefCount = OriginalElement->Common.ReferenceCount;
44426f3cdf0SGordon Ross
445*cb565728SJerry Jelinek Status = AcpiNsRepair_HID (Info, ElementPtr);
44626f3cdf0SGordon Ross if (ACPI_FAILURE (Status))
44726f3cdf0SGordon Ross {
44826f3cdf0SGordon Ross return (Status);
44926f3cdf0SGordon Ross }
45026f3cdf0SGordon Ross
45126f3cdf0SGordon Ross /* Take care with reference counts */
45226f3cdf0SGordon Ross
45326f3cdf0SGordon Ross if (OriginalElement != *ElementPtr)
45426f3cdf0SGordon Ross {
45526f3cdf0SGordon Ross /* Element was replaced */
45626f3cdf0SGordon Ross
45726f3cdf0SGordon Ross (*ElementPtr)->Common.ReferenceCount =
45826f3cdf0SGordon Ross OriginalRefCount;
45926f3cdf0SGordon Ross
46026f3cdf0SGordon Ross AcpiUtRemoveReference (OriginalElement);
46126f3cdf0SGordon Ross }
46226f3cdf0SGordon Ross
46326f3cdf0SGordon Ross ElementPtr++;
46426f3cdf0SGordon Ross }
46526f3cdf0SGordon Ross
46626f3cdf0SGordon Ross return (AE_OK);
46726f3cdf0SGordon Ross }
46826f3cdf0SGordon Ross
46926f3cdf0SGordon Ross
47026f3cdf0SGordon Ross /******************************************************************************
47126f3cdf0SGordon Ross *
472*cb565728SJerry Jelinek * FUNCTION: AcpiNsRepair_CST
473*cb565728SJerry Jelinek *
474*cb565728SJerry Jelinek * PARAMETERS: Info - Method execution information block
475*cb565728SJerry Jelinek * ReturnObjectPtr - Pointer to the object returned from the
476*cb565728SJerry Jelinek * evaluation of a method or object
477*cb565728SJerry Jelinek *
478*cb565728SJerry Jelinek * RETURN: Status. AE_OK if object is OK or was repaired successfully
479*cb565728SJerry Jelinek *
480*cb565728SJerry Jelinek * DESCRIPTION: Repair for the _CST object:
481*cb565728SJerry Jelinek * 1. Sort the list ascending by C state type
482*cb565728SJerry Jelinek * 2. Ensure type cannot be zero
483*cb565728SJerry Jelinek * 3. A subpackage count of zero means _CST is meaningless
484*cb565728SJerry Jelinek * 4. Count must match the number of C state subpackages
485*cb565728SJerry Jelinek *
486*cb565728SJerry Jelinek *****************************************************************************/
487*cb565728SJerry Jelinek
488*cb565728SJerry Jelinek static ACPI_STATUS
AcpiNsRepair_CST(ACPI_EVALUATE_INFO * Info,ACPI_OPERAND_OBJECT ** ReturnObjectPtr)489*cb565728SJerry Jelinek AcpiNsRepair_CST (
490*cb565728SJerry Jelinek ACPI_EVALUATE_INFO *Info,
491*cb565728SJerry Jelinek ACPI_OPERAND_OBJECT **ReturnObjectPtr)
492*cb565728SJerry Jelinek {
493*cb565728SJerry Jelinek ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr;
494*cb565728SJerry Jelinek ACPI_OPERAND_OBJECT **OuterElements;
495*cb565728SJerry Jelinek UINT32 OuterElementCount;
496*cb565728SJerry Jelinek ACPI_OPERAND_OBJECT *ObjDesc;
497*cb565728SJerry Jelinek ACPI_STATUS Status;
498*cb565728SJerry Jelinek BOOLEAN Removing;
499*cb565728SJerry Jelinek UINT32 i;
500*cb565728SJerry Jelinek
501*cb565728SJerry Jelinek
502*cb565728SJerry Jelinek ACPI_FUNCTION_NAME (NsRepair_CST);
503*cb565728SJerry Jelinek
504*cb565728SJerry Jelinek
505*cb565728SJerry Jelinek /*
506*cb565728SJerry Jelinek * Check if the C-state type values are proportional.
507*cb565728SJerry Jelinek */
508*cb565728SJerry Jelinek OuterElementCount = ReturnObject->Package.Count - 1;
509*cb565728SJerry Jelinek i = 0;
510*cb565728SJerry Jelinek while (i < OuterElementCount)
511*cb565728SJerry Jelinek {
512*cb565728SJerry Jelinek OuterElements = &ReturnObject->Package.Elements[i + 1];
513*cb565728SJerry Jelinek Removing = FALSE;
514*cb565728SJerry Jelinek
515*cb565728SJerry Jelinek if ((*OuterElements)->Package.Count == 0)
516*cb565728SJerry Jelinek {
517*cb565728SJerry Jelinek ACPI_WARN_PREDEFINED ((AE_INFO,
518*cb565728SJerry Jelinek Info->FullPathname, Info->NodeFlags,
519*cb565728SJerry Jelinek "SubPackage[%u] - removing entry due to zero count", i));
520*cb565728SJerry Jelinek Removing = TRUE;
521*cb565728SJerry Jelinek goto RemoveElement;
522*cb565728SJerry Jelinek }
523*cb565728SJerry Jelinek
524*cb565728SJerry Jelinek ObjDesc = (*OuterElements)->Package.Elements[1]; /* Index1 = Type */
525*cb565728SJerry Jelinek if ((UINT32) ObjDesc->Integer.Value == 0)
526*cb565728SJerry Jelinek {
527*cb565728SJerry Jelinek ACPI_WARN_PREDEFINED ((AE_INFO,
528*cb565728SJerry Jelinek Info->FullPathname, Info->NodeFlags,
529*cb565728SJerry Jelinek "SubPackage[%u] - removing entry due to invalid Type(0)", i));
530*cb565728SJerry Jelinek Removing = TRUE;
531*cb565728SJerry Jelinek }
532*cb565728SJerry Jelinek
533*cb565728SJerry Jelinek RemoveElement:
534*cb565728SJerry Jelinek if (Removing)
535*cb565728SJerry Jelinek {
536*cb565728SJerry Jelinek AcpiNsRemoveElement (ReturnObject, i + 1);
537*cb565728SJerry Jelinek OuterElementCount--;
538*cb565728SJerry Jelinek }
539*cb565728SJerry Jelinek else
540*cb565728SJerry Jelinek {
541*cb565728SJerry Jelinek i++;
542*cb565728SJerry Jelinek }
543*cb565728SJerry Jelinek }
544*cb565728SJerry Jelinek
545*cb565728SJerry Jelinek /* Update top-level package count, Type "Integer" checked elsewhere */
546*cb565728SJerry Jelinek
547*cb565728SJerry Jelinek ObjDesc = ReturnObject->Package.Elements[0];
548*cb565728SJerry Jelinek ObjDesc->Integer.Value = OuterElementCount;
549*cb565728SJerry Jelinek
550*cb565728SJerry Jelinek /*
551*cb565728SJerry Jelinek * Entries (subpackages) in the _CST Package must be sorted by the
552*cb565728SJerry Jelinek * C-state type, in ascending order.
553*cb565728SJerry Jelinek */
554*cb565728SJerry Jelinek Status = AcpiNsCheckSortedList (Info, ReturnObject, 1, 4, 1,
555*cb565728SJerry Jelinek ACPI_SORT_ASCENDING, "C-State Type");
556*cb565728SJerry Jelinek if (ACPI_FAILURE (Status))
557*cb565728SJerry Jelinek {
558*cb565728SJerry Jelinek return (Status);
559*cb565728SJerry Jelinek }
560*cb565728SJerry Jelinek
561*cb565728SJerry Jelinek return (AE_OK);
562*cb565728SJerry Jelinek }
563*cb565728SJerry Jelinek
564*cb565728SJerry Jelinek
565*cb565728SJerry Jelinek /******************************************************************************
566*cb565728SJerry Jelinek *
56726f3cdf0SGordon Ross * FUNCTION: AcpiNsRepair_HID
56826f3cdf0SGordon Ross *
569*cb565728SJerry Jelinek * PARAMETERS: Info - Method execution information block
57026f3cdf0SGordon Ross * ReturnObjectPtr - Pointer to the object returned from the
57126f3cdf0SGordon Ross * evaluation of a method or object
57226f3cdf0SGordon Ross *
57326f3cdf0SGordon Ross * RETURN: Status. AE_OK if object is OK or was repaired successfully
57426f3cdf0SGordon Ross *
57526f3cdf0SGordon Ross * DESCRIPTION: Repair for the _HID object. If a string, ensure that all
57626f3cdf0SGordon Ross * letters are uppercase and that there is no leading asterisk.
57726f3cdf0SGordon Ross *
57826f3cdf0SGordon Ross *****************************************************************************/
57926f3cdf0SGordon Ross
58026f3cdf0SGordon Ross static ACPI_STATUS
AcpiNsRepair_HID(ACPI_EVALUATE_INFO * Info,ACPI_OPERAND_OBJECT ** ReturnObjectPtr)58126f3cdf0SGordon Ross AcpiNsRepair_HID (
582*cb565728SJerry Jelinek ACPI_EVALUATE_INFO *Info,
58326f3cdf0SGordon Ross ACPI_OPERAND_OBJECT **ReturnObjectPtr)
58426f3cdf0SGordon Ross {
58526f3cdf0SGordon Ross ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr;
58626f3cdf0SGordon Ross ACPI_OPERAND_OBJECT *NewString;
58726f3cdf0SGordon Ross char *Source;
58826f3cdf0SGordon Ross char *Dest;
58926f3cdf0SGordon Ross
59026f3cdf0SGordon Ross
59126f3cdf0SGordon Ross ACPI_FUNCTION_NAME (NsRepair_HID);
59226f3cdf0SGordon Ross
59326f3cdf0SGordon Ross
59426f3cdf0SGordon Ross /* We only care about string _HID objects (not integers) */
59526f3cdf0SGordon Ross
59626f3cdf0SGordon Ross if (ReturnObject->Common.Type != ACPI_TYPE_STRING)
59726f3cdf0SGordon Ross {
59826f3cdf0SGordon Ross return (AE_OK);
59926f3cdf0SGordon Ross }
60026f3cdf0SGordon Ross
60126f3cdf0SGordon Ross if (ReturnObject->String.Length == 0)
60226f3cdf0SGordon Ross {
603*cb565728SJerry Jelinek ACPI_WARN_PREDEFINED ((AE_INFO,
604*cb565728SJerry Jelinek Info->FullPathname, Info->NodeFlags,
60526f3cdf0SGordon Ross "Invalid zero-length _HID or _CID string"));
60626f3cdf0SGordon Ross
60726f3cdf0SGordon Ross /* Return AE_OK anyway, let driver handle it */
60826f3cdf0SGordon Ross
609*cb565728SJerry Jelinek Info->ReturnFlags |= ACPI_OBJECT_REPAIRED;
61026f3cdf0SGordon Ross return (AE_OK);
61126f3cdf0SGordon Ross }
61226f3cdf0SGordon Ross
61326f3cdf0SGordon Ross /* It is simplest to always create a new string object */
61426f3cdf0SGordon Ross
61526f3cdf0SGordon Ross NewString = AcpiUtCreateStringObject (ReturnObject->String.Length);
61626f3cdf0SGordon Ross if (!NewString)
61726f3cdf0SGordon Ross {
61826f3cdf0SGordon Ross return (AE_NO_MEMORY);
61926f3cdf0SGordon Ross }
62026f3cdf0SGordon Ross
62126f3cdf0SGordon Ross /*
62226f3cdf0SGordon Ross * Remove a leading asterisk if present. For some unknown reason, there
62326f3cdf0SGordon Ross * are many machines in the field that contains IDs like this.
62426f3cdf0SGordon Ross *
62526f3cdf0SGordon Ross * Examples: "*PNP0C03", "*ACPI0003"
62626f3cdf0SGordon Ross */
62726f3cdf0SGordon Ross Source = ReturnObject->String.Pointer;
62826f3cdf0SGordon Ross if (*Source == '*')
62926f3cdf0SGordon Ross {
63026f3cdf0SGordon Ross Source++;
63126f3cdf0SGordon Ross NewString->String.Length--;
63226f3cdf0SGordon Ross
63326f3cdf0SGordon Ross ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR,
634*cb565728SJerry Jelinek "%s: Removed invalid leading asterisk\n", Info->FullPathname));
63526f3cdf0SGordon Ross }
63626f3cdf0SGordon Ross
63726f3cdf0SGordon Ross /*
638*cb565728SJerry Jelinek * Copy and uppercase the string. From the ACPI 5.0 specification:
63926f3cdf0SGordon Ross *
64026f3cdf0SGordon Ross * A valid PNP ID must be of the form "AAA####" where A is an uppercase
64126f3cdf0SGordon Ross * letter and # is a hex digit. A valid ACPI ID must be of the form
642*cb565728SJerry Jelinek * "NNNN####" where N is an uppercase letter or decimal digit, and
643*cb565728SJerry Jelinek * # is a hex digit.
64426f3cdf0SGordon Ross */
64526f3cdf0SGordon Ross for (Dest = NewString->String.Pointer; *Source; Dest++, Source++)
64626f3cdf0SGordon Ross {
647*cb565728SJerry Jelinek *Dest = (char) toupper ((int) *Source);
64826f3cdf0SGordon Ross }
64926f3cdf0SGordon Ross
65026f3cdf0SGordon Ross AcpiUtRemoveReference (ReturnObject);
65126f3cdf0SGordon Ross *ReturnObjectPtr = NewString;
65226f3cdf0SGordon Ross return (AE_OK);
65326f3cdf0SGordon Ross }
65426f3cdf0SGordon Ross
65526f3cdf0SGordon Ross
65626f3cdf0SGordon Ross /******************************************************************************
65726f3cdf0SGordon Ross *
658*cb565728SJerry Jelinek * FUNCTION: AcpiNsRepair_PRT
65957190917SDana Myers *
660*cb565728SJerry Jelinek * PARAMETERS: Info - Method execution information block
66157190917SDana Myers * ReturnObjectPtr - Pointer to the object returned from the
66257190917SDana Myers * evaluation of a method or object
66357190917SDana Myers *
66457190917SDana Myers * RETURN: Status. AE_OK if object is OK or was repaired successfully
66557190917SDana Myers *
666*cb565728SJerry Jelinek * DESCRIPTION: Repair for the _PRT object. If necessary, fix reversed
667*cb565728SJerry Jelinek * SourceName and SourceIndex field, a common BIOS bug.
66857190917SDana Myers *
66957190917SDana Myers *****************************************************************************/
67057190917SDana Myers
67157190917SDana Myers static ACPI_STATUS
AcpiNsRepair_PRT(ACPI_EVALUATE_INFO * Info,ACPI_OPERAND_OBJECT ** ReturnObjectPtr)672*cb565728SJerry Jelinek AcpiNsRepair_PRT (
673*cb565728SJerry Jelinek ACPI_EVALUATE_INFO *Info,
67457190917SDana Myers ACPI_OPERAND_OBJECT **ReturnObjectPtr)
67557190917SDana Myers {
676*cb565728SJerry Jelinek ACPI_OPERAND_OBJECT *PackageObject = *ReturnObjectPtr;
677*cb565728SJerry Jelinek ACPI_OPERAND_OBJECT **TopObjectList;
678*cb565728SJerry Jelinek ACPI_OPERAND_OBJECT **SubObjectList;
679*cb565728SJerry Jelinek ACPI_OPERAND_OBJECT *ObjDesc;
680*cb565728SJerry Jelinek ACPI_OPERAND_OBJECT *SubPackage;
681*cb565728SJerry Jelinek UINT32 ElementCount;
682*cb565728SJerry Jelinek UINT32 Index;
68357190917SDana Myers
68457190917SDana Myers
685*cb565728SJerry Jelinek /* Each element in the _PRT package is a subpackage */
68657190917SDana Myers
687*cb565728SJerry Jelinek TopObjectList = PackageObject->Package.Elements;
688*cb565728SJerry Jelinek ElementCount = PackageObject->Package.Count;
689*cb565728SJerry Jelinek
690*cb565728SJerry Jelinek /* Examine each subpackage */
691*cb565728SJerry Jelinek
692*cb565728SJerry Jelinek for (Index = 0; Index < ElementCount; Index++, TopObjectList++)
693*cb565728SJerry Jelinek {
694*cb565728SJerry Jelinek SubPackage = *TopObjectList;
695*cb565728SJerry Jelinek SubObjectList = SubPackage->Package.Elements;
696*cb565728SJerry Jelinek
697*cb565728SJerry Jelinek /* Check for minimum required element count */
698*cb565728SJerry Jelinek
699*cb565728SJerry Jelinek if (SubPackage->Package.Count < 4)
700*cb565728SJerry Jelinek {
701*cb565728SJerry Jelinek continue;
702*cb565728SJerry Jelinek }
703*cb565728SJerry Jelinek
704*cb565728SJerry Jelinek /*
705*cb565728SJerry Jelinek * If the BIOS has erroneously reversed the _PRT SourceName (index 2)
706*cb565728SJerry Jelinek * and the SourceIndex (index 3), fix it. _PRT is important enough to
707*cb565728SJerry Jelinek * workaround this BIOS error. This also provides compatibility with
708*cb565728SJerry Jelinek * other ACPI implementations.
709*cb565728SJerry Jelinek */
710*cb565728SJerry Jelinek ObjDesc = SubObjectList[3];
711*cb565728SJerry Jelinek if (!ObjDesc || (ObjDesc->Common.Type != ACPI_TYPE_INTEGER))
712*cb565728SJerry Jelinek {
713*cb565728SJerry Jelinek SubObjectList[3] = SubObjectList[2];
714*cb565728SJerry Jelinek SubObjectList[2] = ObjDesc;
715*cb565728SJerry Jelinek Info->ReturnFlags |= ACPI_OBJECT_REPAIRED;
716*cb565728SJerry Jelinek
717*cb565728SJerry Jelinek ACPI_WARN_PREDEFINED ((AE_INFO,
718*cb565728SJerry Jelinek Info->FullPathname, Info->NodeFlags,
719*cb565728SJerry Jelinek "PRT[%X]: Fixed reversed SourceName and SourceIndex",
720*cb565728SJerry Jelinek Index));
721*cb565728SJerry Jelinek }
722*cb565728SJerry Jelinek }
723*cb565728SJerry Jelinek
724*cb565728SJerry Jelinek return (AE_OK);
72557190917SDana Myers }
72657190917SDana Myers
72757190917SDana Myers
72857190917SDana Myers /******************************************************************************
72957190917SDana Myers *
73057190917SDana Myers * FUNCTION: AcpiNsRepair_PSS
73157190917SDana Myers *
732*cb565728SJerry Jelinek * PARAMETERS: Info - Method execution information block
73357190917SDana Myers * ReturnObjectPtr - Pointer to the object returned from the
73457190917SDana Myers * evaluation of a method or object
73557190917SDana Myers *
73657190917SDana Myers * RETURN: Status. AE_OK if object is OK or was repaired successfully
73757190917SDana Myers *
73857190917SDana Myers * DESCRIPTION: Repair for the _PSS object. If necessary, sort the object list
73957190917SDana Myers * by the CPU frequencies. Check that the power dissipation values
74057190917SDana Myers * are all proportional to CPU frequency (i.e., sorting by
74157190917SDana Myers * frequency should be the same as sorting by power.)
74257190917SDana Myers *
74357190917SDana Myers *****************************************************************************/
74457190917SDana Myers
74557190917SDana Myers static ACPI_STATUS
AcpiNsRepair_PSS(ACPI_EVALUATE_INFO * Info,ACPI_OPERAND_OBJECT ** ReturnObjectPtr)74657190917SDana Myers AcpiNsRepair_PSS (
747*cb565728SJerry Jelinek ACPI_EVALUATE_INFO *Info,
74857190917SDana Myers ACPI_OPERAND_OBJECT **ReturnObjectPtr)
74957190917SDana Myers {
75057190917SDana Myers ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr;
75157190917SDana Myers ACPI_OPERAND_OBJECT **OuterElements;
75257190917SDana Myers UINT32 OuterElementCount;
75357190917SDana Myers ACPI_OPERAND_OBJECT **Elements;
75457190917SDana Myers ACPI_OPERAND_OBJECT *ObjDesc;
75557190917SDana Myers UINT32 PreviousValue;
75657190917SDana Myers ACPI_STATUS Status;
75757190917SDana Myers UINT32 i;
75857190917SDana Myers
75957190917SDana Myers
76057190917SDana Myers /*
761*cb565728SJerry Jelinek * Entries (subpackages) in the _PSS Package must be sorted by power
76257190917SDana Myers * dissipation, in descending order. If it appears that the list is
76357190917SDana Myers * incorrectly sorted, sort it. We sort by CpuFrequency, since this
76457190917SDana Myers * should be proportional to the power.
76557190917SDana Myers */
766*cb565728SJerry Jelinek Status = AcpiNsCheckSortedList (Info, ReturnObject, 0, 6, 0,
76757190917SDana Myers ACPI_SORT_DESCENDING, "CpuFrequency");
76857190917SDana Myers if (ACPI_FAILURE (Status))
76957190917SDana Myers {
77057190917SDana Myers return (Status);
77157190917SDana Myers }
77257190917SDana Myers
77357190917SDana Myers /*
77457190917SDana Myers * We now know the list is correctly sorted by CPU frequency. Check if
77557190917SDana Myers * the power dissipation values are proportional.
77657190917SDana Myers */
77757190917SDana Myers PreviousValue = ACPI_UINT32_MAX;
77857190917SDana Myers OuterElements = ReturnObject->Package.Elements;
77957190917SDana Myers OuterElementCount = ReturnObject->Package.Count;
78057190917SDana Myers
78157190917SDana Myers for (i = 0; i < OuterElementCount; i++)
78257190917SDana Myers {
78357190917SDana Myers Elements = (*OuterElements)->Package.Elements;
78457190917SDana Myers ObjDesc = Elements[1]; /* Index1 = PowerDissipation */
78557190917SDana Myers
78657190917SDana Myers if ((UINT32) ObjDesc->Integer.Value > PreviousValue)
78757190917SDana Myers {
788*cb565728SJerry Jelinek ACPI_WARN_PREDEFINED ((AE_INFO,
789*cb565728SJerry Jelinek Info->FullPathname, Info->NodeFlags,
79057190917SDana Myers "SubPackage[%u,%u] - suspicious power dissipation values",
79157190917SDana Myers i-1, i));
79257190917SDana Myers }
79357190917SDana Myers
79457190917SDana Myers PreviousValue = (UINT32) ObjDesc->Integer.Value;
79557190917SDana Myers OuterElements++;
79657190917SDana Myers }
79757190917SDana Myers
79857190917SDana Myers return (AE_OK);
79957190917SDana Myers }
80057190917SDana Myers
80157190917SDana Myers
80257190917SDana Myers /******************************************************************************
80357190917SDana Myers *
804*cb565728SJerry Jelinek * FUNCTION: AcpiNsRepair_TSS
805*cb565728SJerry Jelinek *
806*cb565728SJerry Jelinek * PARAMETERS: Info - Method execution information block
807*cb565728SJerry Jelinek * ReturnObjectPtr - Pointer to the object returned from the
808*cb565728SJerry Jelinek * evaluation of a method or object
809*cb565728SJerry Jelinek *
810*cb565728SJerry Jelinek * RETURN: Status. AE_OK if object is OK or was repaired successfully
811*cb565728SJerry Jelinek *
812*cb565728SJerry Jelinek * DESCRIPTION: Repair for the _TSS object. If necessary, sort the object list
813*cb565728SJerry Jelinek * descending by the power dissipation values.
814*cb565728SJerry Jelinek *
815*cb565728SJerry Jelinek *****************************************************************************/
816*cb565728SJerry Jelinek
817*cb565728SJerry Jelinek static ACPI_STATUS
AcpiNsRepair_TSS(ACPI_EVALUATE_INFO * Info,ACPI_OPERAND_OBJECT ** ReturnObjectPtr)818*cb565728SJerry Jelinek AcpiNsRepair_TSS (
819*cb565728SJerry Jelinek ACPI_EVALUATE_INFO *Info,
820*cb565728SJerry Jelinek ACPI_OPERAND_OBJECT **ReturnObjectPtr)
821*cb565728SJerry Jelinek {
822*cb565728SJerry Jelinek ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr;
823*cb565728SJerry Jelinek ACPI_STATUS Status;
824*cb565728SJerry Jelinek ACPI_NAMESPACE_NODE *Node;
825*cb565728SJerry Jelinek
826*cb565728SJerry Jelinek
827*cb565728SJerry Jelinek /*
828*cb565728SJerry Jelinek * We can only sort the _TSS return package if there is no _PSS in the
829*cb565728SJerry Jelinek * same scope. This is because if _PSS is present, the ACPI specification
830*cb565728SJerry Jelinek * dictates that the _TSS Power Dissipation field is to be ignored, and
831*cb565728SJerry Jelinek * therefore some BIOSs leave garbage values in the _TSS Power field(s).
832*cb565728SJerry Jelinek * In this case, it is best to just return the _TSS package as-is.
833*cb565728SJerry Jelinek * (May, 2011)
834*cb565728SJerry Jelinek */
835*cb565728SJerry Jelinek Status = AcpiNsGetNode (Info->Node, "^_PSS",
836*cb565728SJerry Jelinek ACPI_NS_NO_UPSEARCH, &Node);
837*cb565728SJerry Jelinek if (ACPI_SUCCESS (Status))
838*cb565728SJerry Jelinek {
839*cb565728SJerry Jelinek return (AE_OK);
840*cb565728SJerry Jelinek }
841*cb565728SJerry Jelinek
842*cb565728SJerry Jelinek Status = AcpiNsCheckSortedList (Info, ReturnObject, 0, 5, 1,
843*cb565728SJerry Jelinek ACPI_SORT_DESCENDING, "PowerDissipation");
844*cb565728SJerry Jelinek
845*cb565728SJerry Jelinek return (Status);
846*cb565728SJerry Jelinek }
847*cb565728SJerry Jelinek
848*cb565728SJerry Jelinek
849*cb565728SJerry Jelinek /******************************************************************************
850*cb565728SJerry Jelinek *
85157190917SDana Myers * FUNCTION: AcpiNsCheckSortedList
85257190917SDana Myers *
853*cb565728SJerry Jelinek * PARAMETERS: Info - Method execution information block
85457190917SDana Myers * ReturnObject - Pointer to the top-level returned object
855*cb565728SJerry Jelinek * StartIndex - Index of the first subpackage
856*cb565728SJerry Jelinek * ExpectedCount - Minimum length of each subpackage
857*cb565728SJerry Jelinek * SortIndex - Subpackage entry to sort on
85857190917SDana Myers * SortDirection - Ascending or descending
85957190917SDana Myers * SortKeyName - Name of the SortIndex field
86057190917SDana Myers *
86157190917SDana Myers * RETURN: Status. AE_OK if the list is valid and is sorted correctly or
86257190917SDana Myers * has been repaired by sorting the list.
86357190917SDana Myers *
86457190917SDana Myers * DESCRIPTION: Check if the package list is valid and sorted correctly by the
86557190917SDana Myers * SortIndex. If not, then sort the list.
86657190917SDana Myers *
86757190917SDana Myers *****************************************************************************/
86857190917SDana Myers
86957190917SDana Myers static ACPI_STATUS
AcpiNsCheckSortedList(ACPI_EVALUATE_INFO * Info,ACPI_OPERAND_OBJECT * ReturnObject,UINT32 StartIndex,UINT32 ExpectedCount,UINT32 SortIndex,UINT8 SortDirection,char * SortKeyName)87057190917SDana Myers AcpiNsCheckSortedList (
871*cb565728SJerry Jelinek ACPI_EVALUATE_INFO *Info,
87257190917SDana Myers ACPI_OPERAND_OBJECT *ReturnObject,
873*cb565728SJerry Jelinek UINT32 StartIndex,
87457190917SDana Myers UINT32 ExpectedCount,
87557190917SDana Myers UINT32 SortIndex,
87657190917SDana Myers UINT8 SortDirection,
87757190917SDana Myers char *SortKeyName)
87857190917SDana Myers {
87957190917SDana Myers UINT32 OuterElementCount;
88057190917SDana Myers ACPI_OPERAND_OBJECT **OuterElements;
88157190917SDana Myers ACPI_OPERAND_OBJECT **Elements;
88257190917SDana Myers ACPI_OPERAND_OBJECT *ObjDesc;
88357190917SDana Myers UINT32 i;
88457190917SDana Myers UINT32 PreviousValue;
88526f3cdf0SGordon Ross
88626f3cdf0SGordon Ross
88726f3cdf0SGordon Ross ACPI_FUNCTION_NAME (NsCheckSortedList);
88857190917SDana Myers
88957190917SDana Myers
89057190917SDana Myers /* The top-level object must be a package */
89157190917SDana Myers
89257190917SDana Myers if (ReturnObject->Common.Type != ACPI_TYPE_PACKAGE)
89357190917SDana Myers {
89457190917SDana Myers return (AE_AML_OPERAND_TYPE);
89557190917SDana Myers }
89657190917SDana Myers
89757190917SDana Myers /*
898*cb565728SJerry Jelinek * NOTE: assumes list of subpackages contains no NULL elements.
89926f3cdf0SGordon Ross * Any NULL elements should have been removed by earlier call
90026f3cdf0SGordon Ross * to AcpiNsRemoveNullElements.
90157190917SDana Myers */
90257190917SDana Myers OuterElementCount = ReturnObject->Package.Count;
903*cb565728SJerry Jelinek if (!OuterElementCount || StartIndex >= OuterElementCount)
90457190917SDana Myers {
90557190917SDana Myers return (AE_AML_PACKAGE_LIMIT);
90657190917SDana Myers }
90757190917SDana Myers
908*cb565728SJerry Jelinek OuterElements = &ReturnObject->Package.Elements[StartIndex];
909*cb565728SJerry Jelinek OuterElementCount -= StartIndex;
910*cb565728SJerry Jelinek
91157190917SDana Myers PreviousValue = 0;
91257190917SDana Myers if (SortDirection == ACPI_SORT_DESCENDING)
91357190917SDana Myers {
91457190917SDana Myers PreviousValue = ACPI_UINT32_MAX;
91557190917SDana Myers }
91657190917SDana Myers
91757190917SDana Myers /* Examine each subpackage */
91857190917SDana Myers
91957190917SDana Myers for (i = 0; i < OuterElementCount; i++)
92057190917SDana Myers {
92157190917SDana Myers /* Each element of the top-level package must also be a package */
92257190917SDana Myers
92357190917SDana Myers if ((*OuterElements)->Common.Type != ACPI_TYPE_PACKAGE)
92457190917SDana Myers {
92557190917SDana Myers return (AE_AML_OPERAND_TYPE);
92657190917SDana Myers }
92757190917SDana Myers
928*cb565728SJerry Jelinek /* Each subpackage must have the minimum length */
92957190917SDana Myers
93057190917SDana Myers if ((*OuterElements)->Package.Count < ExpectedCount)
93157190917SDana Myers {
93257190917SDana Myers return (AE_AML_PACKAGE_LIMIT);
93357190917SDana Myers }
93457190917SDana Myers
93557190917SDana Myers Elements = (*OuterElements)->Package.Elements;
93657190917SDana Myers ObjDesc = Elements[SortIndex];
93757190917SDana Myers
93857190917SDana Myers if (ObjDesc->Common.Type != ACPI_TYPE_INTEGER)
93957190917SDana Myers {
94057190917SDana Myers return (AE_AML_OPERAND_TYPE);
94157190917SDana Myers }
94257190917SDana Myers
94357190917SDana Myers /*
94457190917SDana Myers * The list must be sorted in the specified order. If we detect a
94526f3cdf0SGordon Ross * discrepancy, sort the entire list.
94657190917SDana Myers */
94757190917SDana Myers if (((SortDirection == ACPI_SORT_ASCENDING) &&
94857190917SDana Myers (ObjDesc->Integer.Value < PreviousValue)) ||
94957190917SDana Myers ((SortDirection == ACPI_SORT_DESCENDING) &&
95057190917SDana Myers (ObjDesc->Integer.Value > PreviousValue)))
95157190917SDana Myers {
952*cb565728SJerry Jelinek AcpiNsSortList (&ReturnObject->Package.Elements[StartIndex],
95357190917SDana Myers OuterElementCount, SortIndex, SortDirection);
95457190917SDana Myers
955*cb565728SJerry Jelinek Info->ReturnFlags |= ACPI_OBJECT_REPAIRED;
95657190917SDana Myers
95726f3cdf0SGordon Ross ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR,
95826f3cdf0SGordon Ross "%s: Repaired unsorted list - now sorted by %s\n",
959*cb565728SJerry Jelinek Info->FullPathname, SortKeyName));
96057190917SDana Myers return (AE_OK);
96157190917SDana Myers }
96257190917SDana Myers
96357190917SDana Myers PreviousValue = (UINT32) ObjDesc->Integer.Value;
96457190917SDana Myers OuterElements++;
96557190917SDana Myers }
96657190917SDana Myers
96757190917SDana Myers return (AE_OK);
96857190917SDana Myers }
96957190917SDana Myers
97057190917SDana Myers
97157190917SDana Myers /******************************************************************************
97257190917SDana Myers *
97357190917SDana Myers * FUNCTION: AcpiNsSortList
97457190917SDana Myers *
97557190917SDana Myers * PARAMETERS: Elements - Package object element list
97657190917SDana Myers * Count - Element count for above
97757190917SDana Myers * Index - Sort by which package element
97857190917SDana Myers * SortDirection - Ascending or Descending sort
97957190917SDana Myers *
98026f3cdf0SGordon Ross * RETURN: None
98157190917SDana Myers *
98257190917SDana Myers * DESCRIPTION: Sort the objects that are in a package element list.
98357190917SDana Myers *
98426f3cdf0SGordon Ross * NOTE: Assumes that all NULL elements have been removed from the package,
98526f3cdf0SGordon Ross * and that all elements have been verified to be of type Integer.
98657190917SDana Myers *
98757190917SDana Myers *****************************************************************************/
98857190917SDana Myers
98926f3cdf0SGordon Ross static void
AcpiNsSortList(ACPI_OPERAND_OBJECT ** Elements,UINT32 Count,UINT32 Index,UINT8 SortDirection)99057190917SDana Myers AcpiNsSortList (
99157190917SDana Myers ACPI_OPERAND_OBJECT **Elements,
99257190917SDana Myers UINT32 Count,
99357190917SDana Myers UINT32 Index,
99457190917SDana Myers UINT8 SortDirection)
99557190917SDana Myers {
99657190917SDana Myers ACPI_OPERAND_OBJECT *ObjDesc1;
99757190917SDana Myers ACPI_OPERAND_OBJECT *ObjDesc2;
99857190917SDana Myers ACPI_OPERAND_OBJECT *TempObj;
99957190917SDana Myers UINT32 i;
100057190917SDana Myers UINT32 j;
100157190917SDana Myers
100257190917SDana Myers
100357190917SDana Myers /* Simple bubble sort */
100457190917SDana Myers
100557190917SDana Myers for (i = 1; i < Count; i++)
100657190917SDana Myers {
100757190917SDana Myers for (j = (Count - 1); j >= i; j--)
100857190917SDana Myers {
100957190917SDana Myers ObjDesc1 = Elements[j-1]->Package.Elements[Index];
101057190917SDana Myers ObjDesc2 = Elements[j]->Package.Elements[Index];
101157190917SDana Myers
101257190917SDana Myers if (((SortDirection == ACPI_SORT_ASCENDING) &&
101357190917SDana Myers (ObjDesc1->Integer.Value > ObjDesc2->Integer.Value)) ||
101457190917SDana Myers
101557190917SDana Myers ((SortDirection == ACPI_SORT_DESCENDING) &&
101657190917SDana Myers (ObjDesc1->Integer.Value < ObjDesc2->Integer.Value)))
101757190917SDana Myers {
101857190917SDana Myers TempObj = Elements[j-1];
101957190917SDana Myers Elements[j-1] = Elements[j];
102057190917SDana Myers Elements[j] = TempObj;
102157190917SDana Myers }
102257190917SDana Myers }
102357190917SDana Myers }
102457190917SDana Myers }
1025*cb565728SJerry Jelinek
1026*cb565728SJerry Jelinek
1027*cb565728SJerry Jelinek /******************************************************************************
1028*cb565728SJerry Jelinek *
1029*cb565728SJerry Jelinek * FUNCTION: AcpiNsRemoveElement
1030*cb565728SJerry Jelinek *
1031*cb565728SJerry Jelinek * PARAMETERS: ObjDesc - Package object element list
1032*cb565728SJerry Jelinek * Index - Index of element to remove
1033*cb565728SJerry Jelinek *
1034*cb565728SJerry Jelinek * RETURN: None
1035*cb565728SJerry Jelinek *
1036*cb565728SJerry Jelinek * DESCRIPTION: Remove the requested element of a package and delete it.
1037*cb565728SJerry Jelinek *
1038*cb565728SJerry Jelinek *****************************************************************************/
1039*cb565728SJerry Jelinek
1040*cb565728SJerry Jelinek static void
AcpiNsRemoveElement(ACPI_OPERAND_OBJECT * ObjDesc,UINT32 Index)1041*cb565728SJerry Jelinek AcpiNsRemoveElement (
1042*cb565728SJerry Jelinek ACPI_OPERAND_OBJECT *ObjDesc,
1043*cb565728SJerry Jelinek UINT32 Index)
1044*cb565728SJerry Jelinek {
1045*cb565728SJerry Jelinek ACPI_OPERAND_OBJECT **Source;
1046*cb565728SJerry Jelinek ACPI_OPERAND_OBJECT **Dest;
1047*cb565728SJerry Jelinek UINT32 Count;
1048*cb565728SJerry Jelinek UINT32 NewCount;
1049*cb565728SJerry Jelinek UINT32 i;
1050*cb565728SJerry Jelinek
1051*cb565728SJerry Jelinek
1052*cb565728SJerry Jelinek ACPI_FUNCTION_NAME (NsRemoveElement);
1053*cb565728SJerry Jelinek
1054*cb565728SJerry Jelinek
1055*cb565728SJerry Jelinek Count = ObjDesc->Package.Count;
1056*cb565728SJerry Jelinek NewCount = Count - 1;
1057*cb565728SJerry Jelinek
1058*cb565728SJerry Jelinek Source = ObjDesc->Package.Elements;
1059*cb565728SJerry Jelinek Dest = Source;
1060*cb565728SJerry Jelinek
1061*cb565728SJerry Jelinek /* Examine all elements of the package object, remove matched index */
1062*cb565728SJerry Jelinek
1063*cb565728SJerry Jelinek for (i = 0; i < Count; i++)
1064*cb565728SJerry Jelinek {
1065*cb565728SJerry Jelinek if (i == Index)
1066*cb565728SJerry Jelinek {
1067*cb565728SJerry Jelinek AcpiUtRemoveReference (*Source); /* Remove one ref for being in pkg */
1068*cb565728SJerry Jelinek AcpiUtRemoveReference (*Source);
1069*cb565728SJerry Jelinek }
1070*cb565728SJerry Jelinek else
1071*cb565728SJerry Jelinek {
1072*cb565728SJerry Jelinek *Dest = *Source;
1073*cb565728SJerry Jelinek Dest++;
1074*cb565728SJerry Jelinek }
1075*cb565728SJerry Jelinek
1076*cb565728SJerry Jelinek Source++;
1077*cb565728SJerry Jelinek }
1078*cb565728SJerry Jelinek
1079*cb565728SJerry Jelinek /* NULL terminate list and update the package count */
1080*cb565728SJerry Jelinek
1081*cb565728SJerry Jelinek *Dest = NULL;
1082*cb565728SJerry Jelinek ObjDesc->Package.Count = NewCount;
1083*cb565728SJerry Jelinek }
1084