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*de5d74c2SJerry 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*de5d74c2SJerry 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*de5d74c2SJerry Jelinek AcpiNsMatchComplexRepair (
7457190917SDana Myers ACPI_NAMESPACE_NODE *Node);
7557190917SDana Myers
7657190917SDana Myers static ACPI_STATUS
7757190917SDana Myers AcpiNsRepair_ALR (
78*de5d74c2SJerry Jelinek ACPI_EVALUATE_INFO *Info,
7957190917SDana Myers ACPI_OPERAND_OBJECT **ReturnObjectPtr);
8057190917SDana Myers
8157190917SDana Myers static ACPI_STATUS
8226f3cdf0SGordon Ross AcpiNsRepair_CID (
83*de5d74c2SJerry Jelinek ACPI_EVALUATE_INFO *Info,
84*de5d74c2SJerry Jelinek ACPI_OPERAND_OBJECT **ReturnObjectPtr);
85*de5d74c2SJerry Jelinek
86*de5d74c2SJerry Jelinek static ACPI_STATUS
87*de5d74c2SJerry Jelinek AcpiNsRepair_CST (
88*de5d74c2SJerry Jelinek ACPI_EVALUATE_INFO *Info,
8926f3cdf0SGordon Ross ACPI_OPERAND_OBJECT **ReturnObjectPtr);
9026f3cdf0SGordon Ross
9126f3cdf0SGordon Ross static ACPI_STATUS
9226f3cdf0SGordon Ross AcpiNsRepair_FDE (
93*de5d74c2SJerry Jelinek ACPI_EVALUATE_INFO *Info,
9426f3cdf0SGordon Ross ACPI_OPERAND_OBJECT **ReturnObjectPtr);
9526f3cdf0SGordon Ross
9626f3cdf0SGordon Ross static ACPI_STATUS
9726f3cdf0SGordon Ross AcpiNsRepair_HID (
98*de5d74c2SJerry Jelinek ACPI_EVALUATE_INFO *Info,
99*de5d74c2SJerry Jelinek ACPI_OPERAND_OBJECT **ReturnObjectPtr);
100*de5d74c2SJerry Jelinek
101*de5d74c2SJerry Jelinek static ACPI_STATUS
102*de5d74c2SJerry Jelinek AcpiNsRepair_PRT (
103*de5d74c2SJerry Jelinek ACPI_EVALUATE_INFO *Info,
10426f3cdf0SGordon Ross ACPI_OPERAND_OBJECT **ReturnObjectPtr);
10526f3cdf0SGordon Ross
10626f3cdf0SGordon Ross static ACPI_STATUS
10757190917SDana Myers AcpiNsRepair_PSS (
108*de5d74c2SJerry Jelinek ACPI_EVALUATE_INFO *Info,
10957190917SDana Myers ACPI_OPERAND_OBJECT **ReturnObjectPtr);
11057190917SDana Myers
11157190917SDana Myers static ACPI_STATUS
11257190917SDana Myers AcpiNsRepair_TSS (
113*de5d74c2SJerry Jelinek ACPI_EVALUATE_INFO *Info,
11457190917SDana Myers ACPI_OPERAND_OBJECT **ReturnObjectPtr);
11557190917SDana Myers
11657190917SDana Myers static ACPI_STATUS
11757190917SDana Myers AcpiNsCheckSortedList (
118*de5d74c2SJerry Jelinek ACPI_EVALUATE_INFO *Info,
11957190917SDana Myers ACPI_OPERAND_OBJECT *ReturnObject,
120*de5d74c2SJerry Jelinek UINT32 StartIndex,
12157190917SDana Myers UINT32 ExpectedCount,
12257190917SDana Myers UINT32 SortIndex,
12357190917SDana Myers UINT8 SortDirection,
12457190917SDana Myers char *SortKeyName);
12557190917SDana Myers
126*de5d74c2SJerry Jelinek /* Values for SortDirection above */
127*de5d74c2SJerry Jelinek
128*de5d74c2SJerry Jelinek #define ACPI_SORT_ASCENDING 0
129*de5d74c2SJerry Jelinek #define ACPI_SORT_DESCENDING 1
130*de5d74c2SJerry Jelinek
131*de5d74c2SJerry Jelinek static void
132*de5d74c2SJerry Jelinek AcpiNsRemoveElement (
133*de5d74c2SJerry Jelinek ACPI_OPERAND_OBJECT *ObjDesc,
134*de5d74c2SJerry Jelinek UINT32 Index);
135*de5d74c2SJerry 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*de5d74c2SJerry 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*de5d74c2SJerry 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*de5d74c2SJerry 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*de5d74c2SJerry 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*de5d74c2SJerry 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*de5d74c2SJerry 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*de5d74c2SJerry Jelinek Predefined = AcpiNsMatchComplexRepair (Node);
21957190917SDana Myers if (!Predefined)
22057190917SDana Myers {
22157190917SDana Myers return (ValidateStatus);
22257190917SDana Myers }
22357190917SDana Myers
224*de5d74c2SJerry Jelinek Status = Predefined->RepairFunction (Info, ReturnObjectPtr);
22557190917SDana Myers return (Status);
22657190917SDana Myers }
22757190917SDana Myers
22857190917SDana Myers
22957190917SDana Myers /******************************************************************************
23057190917SDana Myers *
231*de5d74c2SJerry 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*de5d74c2SJerry 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*de5d74c2SJerry 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*de5d74c2SJerry 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*de5d74c2SJerry 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*de5d74c2SJerry 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*de5d74c2SJerry 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*de5d74c2SJerry 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*de5d74c2SJerry Jelinek ACPI_WARN_PREDEFINED ((AE_INFO,
344*de5d74c2SJerry 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*de5d74c2SJerry Jelinek BufferObject = AcpiUtCreateBufferObject (
354*de5d74c2SJerry 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*de5d74c2SJerry Jelinek DwordBuffer = ACPI_CAST_PTR (UINT32,
364*de5d74c2SJerry 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*de5d74c2SJerry Jelinek Info->FullPathname));
37626f3cdf0SGordon Ross break;
37726f3cdf0SGordon Ross
37826f3cdf0SGordon Ross default:
379*de5d74c2SJerry 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*de5d74c2SJerry 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*de5d74c2SJerry 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*de5d74c2SJerry 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*de5d74c2SJerry 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*de5d74c2SJerry 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*de5d74c2SJerry Jelinek * FUNCTION: AcpiNsRepair_CST
473*de5d74c2SJerry Jelinek *
474*de5d74c2SJerry Jelinek * PARAMETERS: Info - Method execution information block
475*de5d74c2SJerry Jelinek * ReturnObjectPtr - Pointer to the object returned from the
476*de5d74c2SJerry Jelinek * evaluation of a method or object
477*de5d74c2SJerry Jelinek *
478*de5d74c2SJerry Jelinek * RETURN: Status. AE_OK if object is OK or was repaired successfully
479*de5d74c2SJerry Jelinek *
480*de5d74c2SJerry Jelinek * DESCRIPTION: Repair for the _CST object:
481*de5d74c2SJerry Jelinek * 1. Sort the list ascending by C state type
482*de5d74c2SJerry Jelinek * 2. Ensure type cannot be zero
483*de5d74c2SJerry Jelinek * 3. A subpackage count of zero means _CST is meaningless
484*de5d74c2SJerry Jelinek * 4. Count must match the number of C state subpackages
485*de5d74c2SJerry Jelinek *
486*de5d74c2SJerry Jelinek *****************************************************************************/
487*de5d74c2SJerry Jelinek
488*de5d74c2SJerry Jelinek static ACPI_STATUS
AcpiNsRepair_CST(ACPI_EVALUATE_INFO * Info,ACPI_OPERAND_OBJECT ** ReturnObjectPtr)489*de5d74c2SJerry Jelinek AcpiNsRepair_CST (
490*de5d74c2SJerry Jelinek ACPI_EVALUATE_INFO *Info,
491*de5d74c2SJerry Jelinek ACPI_OPERAND_OBJECT **ReturnObjectPtr)
492*de5d74c2SJerry Jelinek {
493*de5d74c2SJerry Jelinek ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr;
494*de5d74c2SJerry Jelinek ACPI_OPERAND_OBJECT **OuterElements;
495*de5d74c2SJerry Jelinek UINT32 OuterElementCount;
496*de5d74c2SJerry Jelinek ACPI_OPERAND_OBJECT *ObjDesc;
497*de5d74c2SJerry Jelinek ACPI_STATUS Status;
498*de5d74c2SJerry Jelinek BOOLEAN Removing;
499*de5d74c2SJerry Jelinek UINT32 i;
500*de5d74c2SJerry Jelinek
501*de5d74c2SJerry Jelinek
502*de5d74c2SJerry Jelinek ACPI_FUNCTION_NAME (NsRepair_CST);
503*de5d74c2SJerry Jelinek
504*de5d74c2SJerry Jelinek
505*de5d74c2SJerry Jelinek /*
506*de5d74c2SJerry Jelinek * Check if the C-state type values are proportional.
507*de5d74c2SJerry Jelinek */
508*de5d74c2SJerry Jelinek OuterElementCount = ReturnObject->Package.Count - 1;
509*de5d74c2SJerry Jelinek i = 0;
510*de5d74c2SJerry Jelinek while (i < OuterElementCount)
511*de5d74c2SJerry Jelinek {
512*de5d74c2SJerry Jelinek OuterElements = &ReturnObject->Package.Elements[i + 1];
513*de5d74c2SJerry Jelinek Removing = FALSE;
514*de5d74c2SJerry Jelinek
515*de5d74c2SJerry Jelinek if ((*OuterElements)->Package.Count == 0)
516*de5d74c2SJerry Jelinek {
517*de5d74c2SJerry Jelinek ACPI_WARN_PREDEFINED ((AE_INFO,
518*de5d74c2SJerry Jelinek Info->FullPathname, Info->NodeFlags,
519*de5d74c2SJerry Jelinek "SubPackage[%u] - removing entry due to zero count", i));
520*de5d74c2SJerry Jelinek Removing = TRUE;
521*de5d74c2SJerry Jelinek goto RemoveElement;
522*de5d74c2SJerry Jelinek }
523*de5d74c2SJerry Jelinek
524*de5d74c2SJerry Jelinek ObjDesc = (*OuterElements)->Package.Elements[1]; /* Index1 = Type */
525*de5d74c2SJerry Jelinek if ((UINT32) ObjDesc->Integer.Value == 0)
526*de5d74c2SJerry Jelinek {
527*de5d74c2SJerry Jelinek ACPI_WARN_PREDEFINED ((AE_INFO,
528*de5d74c2SJerry Jelinek Info->FullPathname, Info->NodeFlags,
529*de5d74c2SJerry Jelinek "SubPackage[%u] - removing entry due to invalid Type(0)", i));
530*de5d74c2SJerry Jelinek Removing = TRUE;
531*de5d74c2SJerry Jelinek }
532*de5d74c2SJerry Jelinek
533*de5d74c2SJerry Jelinek RemoveElement:
534*de5d74c2SJerry Jelinek if (Removing)
535*de5d74c2SJerry Jelinek {
536*de5d74c2SJerry Jelinek AcpiNsRemoveElement (ReturnObject, i + 1);
537*de5d74c2SJerry Jelinek OuterElementCount--;
538*de5d74c2SJerry Jelinek }
539*de5d74c2SJerry Jelinek else
540*de5d74c2SJerry Jelinek {
541*de5d74c2SJerry Jelinek i++;
542*de5d74c2SJerry Jelinek }
543*de5d74c2SJerry Jelinek }
544*de5d74c2SJerry Jelinek
545*de5d74c2SJerry Jelinek /* Update top-level package count, Type "Integer" checked elsewhere */
546*de5d74c2SJerry Jelinek
547*de5d74c2SJerry Jelinek ObjDesc = ReturnObject->Package.Elements[0];
548*de5d74c2SJerry Jelinek ObjDesc->Integer.Value = OuterElementCount;
549*de5d74c2SJerry Jelinek
550*de5d74c2SJerry Jelinek /*
551*de5d74c2SJerry Jelinek * Entries (subpackages) in the _CST Package must be sorted by the
552*de5d74c2SJerry Jelinek * C-state type, in ascending order.
553*de5d74c2SJerry Jelinek */
554*de5d74c2SJerry Jelinek Status = AcpiNsCheckSortedList (Info, ReturnObject, 1, 4, 1,
555*de5d74c2SJerry Jelinek ACPI_SORT_ASCENDING, "C-State Type");
556*de5d74c2SJerry Jelinek if (ACPI_FAILURE (Status))
557*de5d74c2SJerry Jelinek {
558*de5d74c2SJerry Jelinek return (Status);
559*de5d74c2SJerry Jelinek }
560*de5d74c2SJerry Jelinek
561*de5d74c2SJerry Jelinek return (AE_OK);
562*de5d74c2SJerry Jelinek }
563*de5d74c2SJerry Jelinek
564*de5d74c2SJerry Jelinek
565*de5d74c2SJerry Jelinek /******************************************************************************
566*de5d74c2SJerry Jelinek *
56726f3cdf0SGordon Ross * FUNCTION: AcpiNsRepair_HID
56826f3cdf0SGordon Ross *
569*de5d74c2SJerry 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*de5d74c2SJerry 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*de5d74c2SJerry Jelinek ACPI_WARN_PREDEFINED ((AE_INFO,
604*de5d74c2SJerry 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*de5d74c2SJerry 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*de5d74c2SJerry Jelinek "%s: Removed invalid leading asterisk\n", Info->FullPathname));
63526f3cdf0SGordon Ross }
63626f3cdf0SGordon Ross
63726f3cdf0SGordon Ross /*
638*de5d74c2SJerry 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*de5d74c2SJerry Jelinek * "NNNN####" where N is an uppercase letter or decimal digit, and
643*de5d74c2SJerry Jelinek * # is a hex digit.
64426f3cdf0SGordon Ross */
64526f3cdf0SGordon Ross for (Dest = NewString->String.Pointer; *Source; Dest++, Source++)
64626f3cdf0SGordon Ross {
647*de5d74c2SJerry 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*de5d74c2SJerry Jelinek * FUNCTION: AcpiNsRepair_PRT
65957190917SDana Myers *
660*de5d74c2SJerry 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*de5d74c2SJerry Jelinek * DESCRIPTION: Repair for the _PRT object. If necessary, fix reversed
667*de5d74c2SJerry 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*de5d74c2SJerry Jelinek AcpiNsRepair_PRT (
673*de5d74c2SJerry Jelinek ACPI_EVALUATE_INFO *Info,
67457190917SDana Myers ACPI_OPERAND_OBJECT **ReturnObjectPtr)
67557190917SDana Myers {
676*de5d74c2SJerry Jelinek ACPI_OPERAND_OBJECT *PackageObject = *ReturnObjectPtr;
677*de5d74c2SJerry Jelinek ACPI_OPERAND_OBJECT **TopObjectList;
678*de5d74c2SJerry Jelinek ACPI_OPERAND_OBJECT **SubObjectList;
679*de5d74c2SJerry Jelinek ACPI_OPERAND_OBJECT *ObjDesc;
680*de5d74c2SJerry Jelinek ACPI_OPERAND_OBJECT *SubPackage;
681*de5d74c2SJerry Jelinek UINT32 ElementCount;
682*de5d74c2SJerry Jelinek UINT32 Index;
68357190917SDana Myers
68457190917SDana Myers
685*de5d74c2SJerry Jelinek /* Each element in the _PRT package is a subpackage */
68657190917SDana Myers
687*de5d74c2SJerry Jelinek TopObjectList = PackageObject->Package.Elements;
688*de5d74c2SJerry Jelinek ElementCount = PackageObject->Package.Count;
689*de5d74c2SJerry Jelinek
690*de5d74c2SJerry Jelinek /* Examine each subpackage */
691*de5d74c2SJerry Jelinek
692*de5d74c2SJerry Jelinek for (Index = 0; Index < ElementCount; Index++, TopObjectList++)
693*de5d74c2SJerry Jelinek {
694*de5d74c2SJerry Jelinek SubPackage = *TopObjectList;
695*de5d74c2SJerry Jelinek SubObjectList = SubPackage->Package.Elements;
696*de5d74c2SJerry Jelinek
697*de5d74c2SJerry Jelinek /* Check for minimum required element count */
698*de5d74c2SJerry Jelinek
699*de5d74c2SJerry Jelinek if (SubPackage->Package.Count < 4)
700*de5d74c2SJerry Jelinek {
701*de5d74c2SJerry Jelinek continue;
702*de5d74c2SJerry Jelinek }
703*de5d74c2SJerry Jelinek
704*de5d74c2SJerry Jelinek /*
705*de5d74c2SJerry Jelinek * If the BIOS has erroneously reversed the _PRT SourceName (index 2)
706*de5d74c2SJerry Jelinek * and the SourceIndex (index 3), fix it. _PRT is important enough to
707*de5d74c2SJerry Jelinek * workaround this BIOS error. This also provides compatibility with
708*de5d74c2SJerry Jelinek * other ACPI implementations.
709*de5d74c2SJerry Jelinek */
710*de5d74c2SJerry Jelinek ObjDesc = SubObjectList[3];
711*de5d74c2SJerry Jelinek if (!ObjDesc || (ObjDesc->Common.Type != ACPI_TYPE_INTEGER))
712*de5d74c2SJerry Jelinek {
713*de5d74c2SJerry Jelinek SubObjectList[3] = SubObjectList[2];
714*de5d74c2SJerry Jelinek SubObjectList[2] = ObjDesc;
715*de5d74c2SJerry Jelinek Info->ReturnFlags |= ACPI_OBJECT_REPAIRED;
716*de5d74c2SJerry Jelinek
717*de5d74c2SJerry Jelinek ACPI_WARN_PREDEFINED ((AE_INFO,
718*de5d74c2SJerry Jelinek Info->FullPathname, Info->NodeFlags,
719*de5d74c2SJerry Jelinek "PRT[%X]: Fixed reversed SourceName and SourceIndex",
720*de5d74c2SJerry Jelinek Index));
721*de5d74c2SJerry Jelinek }
722*de5d74c2SJerry Jelinek }
723*de5d74c2SJerry Jelinek
724*de5d74c2SJerry Jelinek return (AE_OK);
72557190917SDana Myers }
72657190917SDana Myers
72757190917SDana Myers
72857190917SDana Myers /******************************************************************************
72957190917SDana Myers *
73057190917SDana Myers * FUNCTION: AcpiNsRepair_PSS
73157190917SDana Myers *
732*de5d74c2SJerry 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*de5d74c2SJerry 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*de5d74c2SJerry 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*de5d74c2SJerry 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*de5d74c2SJerry Jelinek ACPI_WARN_PREDEFINED ((AE_INFO,
789*de5d74c2SJerry 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*de5d74c2SJerry Jelinek * FUNCTION: AcpiNsRepair_TSS
805*de5d74c2SJerry Jelinek *
806*de5d74c2SJerry Jelinek * PARAMETERS: Info - Method execution information block
807*de5d74c2SJerry Jelinek * ReturnObjectPtr - Pointer to the object returned from the
808*de5d74c2SJerry Jelinek * evaluation of a method or object
809*de5d74c2SJerry Jelinek *
810*de5d74c2SJerry Jelinek * RETURN: Status. AE_OK if object is OK or was repaired successfully
811*de5d74c2SJerry Jelinek *
812*de5d74c2SJerry Jelinek * DESCRIPTION: Repair for the _TSS object. If necessary, sort the object list
813*de5d74c2SJerry Jelinek * descending by the power dissipation values.
814*de5d74c2SJerry Jelinek *
815*de5d74c2SJerry Jelinek *****************************************************************************/
816*de5d74c2SJerry Jelinek
817*de5d74c2SJerry Jelinek static ACPI_STATUS
AcpiNsRepair_TSS(ACPI_EVALUATE_INFO * Info,ACPI_OPERAND_OBJECT ** ReturnObjectPtr)818*de5d74c2SJerry Jelinek AcpiNsRepair_TSS (
819*de5d74c2SJerry Jelinek ACPI_EVALUATE_INFO *Info,
820*de5d74c2SJerry Jelinek ACPI_OPERAND_OBJECT **ReturnObjectPtr)
821*de5d74c2SJerry Jelinek {
822*de5d74c2SJerry Jelinek ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr;
823*de5d74c2SJerry Jelinek ACPI_STATUS Status;
824*de5d74c2SJerry Jelinek ACPI_NAMESPACE_NODE *Node;
825*de5d74c2SJerry Jelinek
826*de5d74c2SJerry Jelinek
827*de5d74c2SJerry Jelinek /*
828*de5d74c2SJerry Jelinek * We can only sort the _TSS return package if there is no _PSS in the
829*de5d74c2SJerry Jelinek * same scope. This is because if _PSS is present, the ACPI specification
830*de5d74c2SJerry Jelinek * dictates that the _TSS Power Dissipation field is to be ignored, and
831*de5d74c2SJerry Jelinek * therefore some BIOSs leave garbage values in the _TSS Power field(s).
832*de5d74c2SJerry Jelinek * In this case, it is best to just return the _TSS package as-is.
833*de5d74c2SJerry Jelinek * (May, 2011)
834*de5d74c2SJerry Jelinek */
835*de5d74c2SJerry Jelinek Status = AcpiNsGetNode (Info->Node, "^_PSS",
836*de5d74c2SJerry Jelinek ACPI_NS_NO_UPSEARCH, &Node);
837*de5d74c2SJerry Jelinek if (ACPI_SUCCESS (Status))
838*de5d74c2SJerry Jelinek {
839*de5d74c2SJerry Jelinek return (AE_OK);
840*de5d74c2SJerry Jelinek }
841*de5d74c2SJerry Jelinek
842*de5d74c2SJerry Jelinek Status = AcpiNsCheckSortedList (Info, ReturnObject, 0, 5, 1,
843*de5d74c2SJerry Jelinek ACPI_SORT_DESCENDING, "PowerDissipation");
844*de5d74c2SJerry Jelinek
845*de5d74c2SJerry Jelinek return (Status);
846*de5d74c2SJerry Jelinek }
847*de5d74c2SJerry Jelinek
848*de5d74c2SJerry Jelinek
849*de5d74c2SJerry Jelinek /******************************************************************************
850*de5d74c2SJerry Jelinek *
85157190917SDana Myers * FUNCTION: AcpiNsCheckSortedList
85257190917SDana Myers *
853*de5d74c2SJerry Jelinek * PARAMETERS: Info - Method execution information block
85457190917SDana Myers * ReturnObject - Pointer to the top-level returned object
855*de5d74c2SJerry Jelinek * StartIndex - Index of the first subpackage
856*de5d74c2SJerry Jelinek * ExpectedCount - Minimum length of each subpackage
857*de5d74c2SJerry 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*de5d74c2SJerry Jelinek ACPI_EVALUATE_INFO *Info,
87257190917SDana Myers ACPI_OPERAND_OBJECT *ReturnObject,
873*de5d74c2SJerry 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*de5d74c2SJerry 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*de5d74c2SJerry Jelinek if (!OuterElementCount || StartIndex >= OuterElementCount)
90457190917SDana Myers {
90557190917SDana Myers return (AE_AML_PACKAGE_LIMIT);
90657190917SDana Myers }
90757190917SDana Myers
908*de5d74c2SJerry Jelinek OuterElements = &ReturnObject->Package.Elements[StartIndex];
909*de5d74c2SJerry Jelinek OuterElementCount -= StartIndex;
910*de5d74c2SJerry 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*de5d74c2SJerry 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*de5d74c2SJerry Jelinek AcpiNsSortList (&ReturnObject->Package.Elements[StartIndex],
95357190917SDana Myers OuterElementCount, SortIndex, SortDirection);
95457190917SDana Myers
955*de5d74c2SJerry 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*de5d74c2SJerry 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*de5d74c2SJerry Jelinek
1026*de5d74c2SJerry Jelinek
1027*de5d74c2SJerry Jelinek /******************************************************************************
1028*de5d74c2SJerry Jelinek *
1029*de5d74c2SJerry Jelinek * FUNCTION: AcpiNsRemoveElement
1030*de5d74c2SJerry Jelinek *
1031*de5d74c2SJerry Jelinek * PARAMETERS: ObjDesc - Package object element list
1032*de5d74c2SJerry Jelinek * Index - Index of element to remove
1033*de5d74c2SJerry Jelinek *
1034*de5d74c2SJerry Jelinek * RETURN: None
1035*de5d74c2SJerry Jelinek *
1036*de5d74c2SJerry Jelinek * DESCRIPTION: Remove the requested element of a package and delete it.
1037*de5d74c2SJerry Jelinek *
1038*de5d74c2SJerry Jelinek *****************************************************************************/
1039*de5d74c2SJerry Jelinek
1040*de5d74c2SJerry Jelinek static void
AcpiNsRemoveElement(ACPI_OPERAND_OBJECT * ObjDesc,UINT32 Index)1041*de5d74c2SJerry Jelinek AcpiNsRemoveElement (
1042*de5d74c2SJerry Jelinek ACPI_OPERAND_OBJECT *ObjDesc,
1043*de5d74c2SJerry Jelinek UINT32 Index)
1044*de5d74c2SJerry Jelinek {
1045*de5d74c2SJerry Jelinek ACPI_OPERAND_OBJECT **Source;
1046*de5d74c2SJerry Jelinek ACPI_OPERAND_OBJECT **Dest;
1047*de5d74c2SJerry Jelinek UINT32 Count;
1048*de5d74c2SJerry Jelinek UINT32 NewCount;
1049*de5d74c2SJerry Jelinek UINT32 i;
1050*de5d74c2SJerry Jelinek
1051*de5d74c2SJerry Jelinek
1052*de5d74c2SJerry Jelinek ACPI_FUNCTION_NAME (NsRemoveElement);
1053*de5d74c2SJerry Jelinek
1054*de5d74c2SJerry Jelinek
1055*de5d74c2SJerry Jelinek Count = ObjDesc->Package.Count;
1056*de5d74c2SJerry Jelinek NewCount = Count - 1;
1057*de5d74c2SJerry Jelinek
1058*de5d74c2SJerry Jelinek Source = ObjDesc->Package.Elements;
1059*de5d74c2SJerry Jelinek Dest = Source;
1060*de5d74c2SJerry Jelinek
1061*de5d74c2SJerry Jelinek /* Examine all elements of the package object, remove matched index */
1062*de5d74c2SJerry Jelinek
1063*de5d74c2SJerry Jelinek for (i = 0; i < Count; i++)
1064*de5d74c2SJerry Jelinek {
1065*de5d74c2SJerry Jelinek if (i == Index)
1066*de5d74c2SJerry Jelinek {
1067*de5d74c2SJerry Jelinek AcpiUtRemoveReference (*Source); /* Remove one ref for being in pkg */
1068*de5d74c2SJerry Jelinek AcpiUtRemoveReference (*Source);
1069*de5d74c2SJerry Jelinek }
1070*de5d74c2SJerry Jelinek else
1071*de5d74c2SJerry Jelinek {
1072*de5d74c2SJerry Jelinek *Dest = *Source;
1073*de5d74c2SJerry Jelinek Dest++;
1074*de5d74c2SJerry Jelinek }
1075*de5d74c2SJerry Jelinek
1076*de5d74c2SJerry Jelinek Source++;
1077*de5d74c2SJerry Jelinek }
1078*de5d74c2SJerry Jelinek
1079*de5d74c2SJerry Jelinek /* NULL terminate list and update the package count */
1080*de5d74c2SJerry Jelinek
1081*de5d74c2SJerry Jelinek *Dest = NULL;
1082*de5d74c2SJerry Jelinek ObjDesc->Package.Count = NewCount;
1083*de5d74c2SJerry Jelinek }
1084