xref: /freebsd-src/sys/contrib/dev/acpica/components/namespace/nsrepair2.c (revision 804fe2660352e090f4481f2c1d646b508859e79a)
1a159c266SJung-uk Kim /******************************************************************************
2a159c266SJung-uk Kim  *
3a159c266SJung-uk Kim  * Module Name: nsrepair2 - Repair for objects returned by specific
4a159c266SJung-uk Kim  *                          predefined methods
5a159c266SJung-uk Kim  *
6a159c266SJung-uk Kim  *****************************************************************************/
7a159c266SJung-uk Kim 
80d84335fSJung-uk Kim /******************************************************************************
90d84335fSJung-uk Kim  *
100d84335fSJung-uk Kim  * 1. Copyright Notice
110d84335fSJung-uk Kim  *
12*804fe266SJung-uk Kim  * Some or all of this work - Copyright (c) 1999 - 2024, Intel Corp.
13a159c266SJung-uk Kim  * All rights reserved.
14a159c266SJung-uk Kim  *
150d84335fSJung-uk Kim  * 2. License
160d84335fSJung-uk Kim  *
170d84335fSJung-uk Kim  * 2.1. This is your license from Intel Corp. under its intellectual property
180d84335fSJung-uk Kim  * rights. You may have additional license terms from the party that provided
190d84335fSJung-uk Kim  * you this software, covering your right to use that party's intellectual
200d84335fSJung-uk Kim  * property rights.
210d84335fSJung-uk Kim  *
220d84335fSJung-uk Kim  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
230d84335fSJung-uk Kim  * copy of the source code appearing in this file ("Covered Code") an
240d84335fSJung-uk Kim  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
250d84335fSJung-uk Kim  * base code distributed originally by Intel ("Original Intel Code") to copy,
260d84335fSJung-uk Kim  * make derivatives, distribute, use and display any portion of the Covered
270d84335fSJung-uk Kim  * Code in any form, with the right to sublicense such rights; and
280d84335fSJung-uk Kim  *
290d84335fSJung-uk Kim  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
300d84335fSJung-uk Kim  * license (with the right to sublicense), under only those claims of Intel
310d84335fSJung-uk Kim  * patents that are infringed by the Original Intel Code, to make, use, sell,
320d84335fSJung-uk Kim  * offer to sell, and import the Covered Code and derivative works thereof
330d84335fSJung-uk Kim  * solely to the minimum extent necessary to exercise the above copyright
340d84335fSJung-uk Kim  * license, and in no event shall the patent license extend to any additions
350d84335fSJung-uk Kim  * to or modifications of the Original Intel Code. No other license or right
360d84335fSJung-uk Kim  * is granted directly or by implication, estoppel or otherwise;
370d84335fSJung-uk Kim  *
380d84335fSJung-uk Kim  * The above copyright and patent license is granted only if the following
390d84335fSJung-uk Kim  * conditions are met:
400d84335fSJung-uk Kim  *
410d84335fSJung-uk Kim  * 3. Conditions
420d84335fSJung-uk Kim  *
430d84335fSJung-uk Kim  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
440d84335fSJung-uk Kim  * Redistribution of source code of any substantial portion of the Covered
450d84335fSJung-uk Kim  * Code or modification with rights to further distribute source must include
460d84335fSJung-uk Kim  * the above Copyright Notice, the above License, this list of Conditions,
470d84335fSJung-uk Kim  * and the following Disclaimer and Export Compliance provision. In addition,
480d84335fSJung-uk Kim  * Licensee must cause all Covered Code to which Licensee contributes to
490d84335fSJung-uk Kim  * contain a file documenting the changes Licensee made to create that Covered
500d84335fSJung-uk Kim  * Code and the date of any change. Licensee must include in that file the
510d84335fSJung-uk Kim  * documentation of any changes made by any predecessor Licensee. Licensee
520d84335fSJung-uk Kim  * must include a prominent statement that the modification is derived,
530d84335fSJung-uk Kim  * directly or indirectly, from Original Intel Code.
540d84335fSJung-uk Kim  *
550d84335fSJung-uk Kim  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
560d84335fSJung-uk Kim  * Redistribution of source code of any substantial portion of the Covered
570d84335fSJung-uk Kim  * Code or modification without rights to further distribute source must
580d84335fSJung-uk Kim  * include the following Disclaimer and Export Compliance provision in the
590d84335fSJung-uk Kim  * documentation and/or other materials provided with distribution. In
600d84335fSJung-uk Kim  * addition, Licensee may not authorize further sublicense of source of any
610d84335fSJung-uk Kim  * portion of the Covered Code, and must include terms to the effect that the
620d84335fSJung-uk Kim  * license from Licensee to its licensee is limited to the intellectual
630d84335fSJung-uk Kim  * property embodied in the software Licensee provides to its licensee, and
640d84335fSJung-uk Kim  * not to intellectual property embodied in modifications its licensee may
650d84335fSJung-uk Kim  * make.
660d84335fSJung-uk Kim  *
670d84335fSJung-uk Kim  * 3.3. Redistribution of Executable. Redistribution in executable form of any
680d84335fSJung-uk Kim  * substantial portion of the Covered Code or modification must reproduce the
690d84335fSJung-uk Kim  * above Copyright Notice, and the following Disclaimer and Export Compliance
700d84335fSJung-uk Kim  * provision in the documentation and/or other materials provided with the
710d84335fSJung-uk Kim  * distribution.
720d84335fSJung-uk Kim  *
730d84335fSJung-uk Kim  * 3.4. Intel retains all right, title, and interest in and to the Original
740d84335fSJung-uk Kim  * Intel Code.
750d84335fSJung-uk Kim  *
760d84335fSJung-uk Kim  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
770d84335fSJung-uk Kim  * Intel shall be used in advertising or otherwise to promote the sale, use or
780d84335fSJung-uk Kim  * other dealings in products derived from or relating to the Covered Code
790d84335fSJung-uk Kim  * without prior written authorization from Intel.
800d84335fSJung-uk Kim  *
810d84335fSJung-uk Kim  * 4. Disclaimer and Export Compliance
820d84335fSJung-uk Kim  *
830d84335fSJung-uk Kim  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
840d84335fSJung-uk Kim  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
850d84335fSJung-uk Kim  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
860d84335fSJung-uk Kim  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
870d84335fSJung-uk Kim  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
880d84335fSJung-uk Kim  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
890d84335fSJung-uk Kim  * PARTICULAR PURPOSE.
900d84335fSJung-uk Kim  *
910d84335fSJung-uk Kim  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
920d84335fSJung-uk Kim  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
930d84335fSJung-uk Kim  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
940d84335fSJung-uk Kim  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
950d84335fSJung-uk Kim  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
960d84335fSJung-uk Kim  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
970d84335fSJung-uk Kim  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
980d84335fSJung-uk Kim  * LIMITED REMEDY.
990d84335fSJung-uk Kim  *
1000d84335fSJung-uk Kim  * 4.3. Licensee shall not export, either directly or indirectly, any of this
1010d84335fSJung-uk Kim  * software or system incorporating such software without first obtaining any
1020d84335fSJung-uk Kim  * required license or other approval from the U. S. Department of Commerce or
1030d84335fSJung-uk Kim  * any other agency or department of the United States Government. In the
1040d84335fSJung-uk Kim  * event Licensee exports any such software from the United States or
1050d84335fSJung-uk Kim  * re-exports any such software from a foreign destination, Licensee shall
1060d84335fSJung-uk Kim  * ensure that the distribution and export/re-export of the software is in
1070d84335fSJung-uk Kim  * compliance with all laws, regulations, orders, or other restrictions of the
1080d84335fSJung-uk Kim  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
1090d84335fSJung-uk Kim  * any of its subsidiaries will export/re-export any technical data, process,
1100d84335fSJung-uk Kim  * software, or service, directly or indirectly, to any country for which the
1110d84335fSJung-uk Kim  * United States government or any agency thereof requires an export license,
1120d84335fSJung-uk Kim  * other governmental approval, or letter of assurance, without first obtaining
1130d84335fSJung-uk Kim  * such license, approval or letter.
1140d84335fSJung-uk Kim  *
1150d84335fSJung-uk Kim  *****************************************************************************
1160d84335fSJung-uk Kim  *
1170d84335fSJung-uk Kim  * Alternatively, you may choose to be licensed under the terms of the
1180d84335fSJung-uk Kim  * following license:
1190d84335fSJung-uk Kim  *
120a159c266SJung-uk Kim  * Redistribution and use in source and binary forms, with or without
121a159c266SJung-uk Kim  * modification, are permitted provided that the following conditions
122a159c266SJung-uk Kim  * are met:
123a159c266SJung-uk Kim  * 1. Redistributions of source code must retain the above copyright
124a159c266SJung-uk Kim  *    notice, this list of conditions, and the following disclaimer,
125a159c266SJung-uk Kim  *    without modification.
126a159c266SJung-uk Kim  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
127a159c266SJung-uk Kim  *    substantially similar to the "NO WARRANTY" disclaimer below
128a159c266SJung-uk Kim  *    ("Disclaimer") and any redistribution must be conditioned upon
129a159c266SJung-uk Kim  *    including a substantially similar Disclaimer requirement for further
130a159c266SJung-uk Kim  *    binary redistribution.
131a159c266SJung-uk Kim  * 3. Neither the names of the above-listed copyright holders nor the names
132a159c266SJung-uk Kim  *    of any contributors may be used to endorse or promote products derived
133a159c266SJung-uk Kim  *    from this software without specific prior written permission.
134a159c266SJung-uk Kim  *
1350d84335fSJung-uk Kim  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1360d84335fSJung-uk Kim  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1370d84335fSJung-uk Kim  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1380d84335fSJung-uk Kim  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
1390d84335fSJung-uk Kim  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
1400d84335fSJung-uk Kim  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
1410d84335fSJung-uk Kim  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
1420d84335fSJung-uk Kim  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
1430d84335fSJung-uk Kim  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1440d84335fSJung-uk Kim  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
1450d84335fSJung-uk Kim  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1460d84335fSJung-uk Kim  *
1470d84335fSJung-uk Kim  * Alternatively, you may choose to be licensed under the terms of the
148a159c266SJung-uk Kim  * GNU General Public License ("GPL") version 2 as published by the Free
149a159c266SJung-uk Kim  * Software Foundation.
150a159c266SJung-uk Kim  *
1510d84335fSJung-uk Kim  *****************************************************************************/
152a159c266SJung-uk Kim 
153a159c266SJung-uk Kim #include <contrib/dev/acpica/include/acpi.h>
154a159c266SJung-uk Kim #include <contrib/dev/acpica/include/accommon.h>
155a159c266SJung-uk Kim #include <contrib/dev/acpica/include/acnamesp.h>
156a159c266SJung-uk Kim 
157a159c266SJung-uk Kim #define _COMPONENT          ACPI_NAMESPACE
158a159c266SJung-uk Kim         ACPI_MODULE_NAME    ("nsrepair2")
159a159c266SJung-uk Kim 
160a159c266SJung-uk Kim 
161a159c266SJung-uk Kim /*
162a159c266SJung-uk Kim  * Information structure and handler for ACPI predefined names that can
163a159c266SJung-uk Kim  * be repaired on a per-name basis.
164a159c266SJung-uk Kim  */
165a159c266SJung-uk Kim typedef
166a159c266SJung-uk Kim ACPI_STATUS (*ACPI_REPAIR_FUNCTION) (
167895f26a9SJung-uk Kim     ACPI_EVALUATE_INFO      *Info,
168a159c266SJung-uk Kim     ACPI_OPERAND_OBJECT     **ReturnObjectPtr);
169a159c266SJung-uk Kim 
170a159c266SJung-uk Kim typedef struct acpi_repair_info
171a159c266SJung-uk Kim {
172278f0de6SJung-uk Kim     char                    Name[ACPI_NAMESEG_SIZE];
173a159c266SJung-uk Kim     ACPI_REPAIR_FUNCTION    RepairFunction;
174a159c266SJung-uk Kim 
175a159c266SJung-uk Kim } ACPI_REPAIR_INFO;
176a159c266SJung-uk Kim 
177a159c266SJung-uk Kim 
178a159c266SJung-uk Kim /* Local prototypes */
179a159c266SJung-uk Kim 
180a159c266SJung-uk Kim static const ACPI_REPAIR_INFO *
1819c48c75eSJung-uk Kim AcpiNsMatchComplexRepair (
182a159c266SJung-uk Kim     ACPI_NAMESPACE_NODE     *Node);
183a159c266SJung-uk Kim 
184a159c266SJung-uk Kim static ACPI_STATUS
185a159c266SJung-uk Kim AcpiNsRepair_ALR (
186895f26a9SJung-uk Kim     ACPI_EVALUATE_INFO      *Info,
187a159c266SJung-uk Kim     ACPI_OPERAND_OBJECT     **ReturnObjectPtr);
188a159c266SJung-uk Kim 
189a159c266SJung-uk Kim static ACPI_STATUS
190a159c266SJung-uk Kim AcpiNsRepair_CID (
191895f26a9SJung-uk Kim     ACPI_EVALUATE_INFO      *Info,
192a159c266SJung-uk Kim     ACPI_OPERAND_OBJECT     **ReturnObjectPtr);
193a159c266SJung-uk Kim 
194a159c266SJung-uk Kim static ACPI_STATUS
195a9d8d09cSJung-uk Kim AcpiNsRepair_CST (
196a9d8d09cSJung-uk Kim     ACPI_EVALUATE_INFO      *Info,
197a9d8d09cSJung-uk Kim     ACPI_OPERAND_OBJECT     **ReturnObjectPtr);
198a9d8d09cSJung-uk Kim 
199a9d8d09cSJung-uk Kim static ACPI_STATUS
200a159c266SJung-uk Kim AcpiNsRepair_FDE (
201895f26a9SJung-uk Kim     ACPI_EVALUATE_INFO      *Info,
202a159c266SJung-uk Kim     ACPI_OPERAND_OBJECT     **ReturnObjectPtr);
203a159c266SJung-uk Kim 
204a159c266SJung-uk Kim static ACPI_STATUS
205a159c266SJung-uk Kim AcpiNsRepair_HID (
206895f26a9SJung-uk Kim     ACPI_EVALUATE_INFO      *Info,
207a159c266SJung-uk Kim     ACPI_OPERAND_OBJECT     **ReturnObjectPtr);
208a159c266SJung-uk Kim 
209a159c266SJung-uk Kim static ACPI_STATUS
210a9d8d09cSJung-uk Kim AcpiNsRepair_PRT (
211a9d8d09cSJung-uk Kim     ACPI_EVALUATE_INFO      *Info,
212a9d8d09cSJung-uk Kim     ACPI_OPERAND_OBJECT     **ReturnObjectPtr);
213a9d8d09cSJung-uk Kim 
214a9d8d09cSJung-uk Kim static ACPI_STATUS
215a159c266SJung-uk Kim AcpiNsRepair_PSS (
216895f26a9SJung-uk Kim     ACPI_EVALUATE_INFO      *Info,
217a159c266SJung-uk Kim     ACPI_OPERAND_OBJECT     **ReturnObjectPtr);
218a159c266SJung-uk Kim 
219a159c266SJung-uk Kim static ACPI_STATUS
220a159c266SJung-uk Kim AcpiNsRepair_TSS (
221895f26a9SJung-uk Kim     ACPI_EVALUATE_INFO      *Info,
222a159c266SJung-uk Kim     ACPI_OPERAND_OBJECT     **ReturnObjectPtr);
223a159c266SJung-uk Kim 
224a159c266SJung-uk Kim static ACPI_STATUS
225a159c266SJung-uk Kim AcpiNsCheckSortedList (
226895f26a9SJung-uk Kim     ACPI_EVALUATE_INFO      *Info,
227a159c266SJung-uk Kim     ACPI_OPERAND_OBJECT     *ReturnObject,
228a9d8d09cSJung-uk Kim     UINT32                  StartIndex,
229a159c266SJung-uk Kim     UINT32                  ExpectedCount,
230a159c266SJung-uk Kim     UINT32                  SortIndex,
231a159c266SJung-uk Kim     UINT8                   SortDirection,
232a159c266SJung-uk Kim     char                    *SortKeyName);
233a159c266SJung-uk Kim 
234a9d8d09cSJung-uk Kim /* Values for SortDirection above */
235a9d8d09cSJung-uk Kim 
236a9d8d09cSJung-uk Kim #define ACPI_SORT_ASCENDING     0
237a9d8d09cSJung-uk Kim #define ACPI_SORT_DESCENDING    1
238a9d8d09cSJung-uk Kim 
239a9d8d09cSJung-uk Kim static void
240a9d8d09cSJung-uk Kim AcpiNsRemoveElement (
241a9d8d09cSJung-uk Kim     ACPI_OPERAND_OBJECT     *ObjDesc,
242a9d8d09cSJung-uk Kim     UINT32                  Index);
243a9d8d09cSJung-uk Kim 
244a159c266SJung-uk Kim static void
245a159c266SJung-uk Kim AcpiNsSortList (
246a159c266SJung-uk Kim     ACPI_OPERAND_OBJECT     **Elements,
247a159c266SJung-uk Kim     UINT32                  Count,
248a159c266SJung-uk Kim     UINT32                  Index,
249a159c266SJung-uk Kim     UINT8                   SortDirection);
250a159c266SJung-uk Kim 
251a159c266SJung-uk Kim 
252a159c266SJung-uk Kim /*
253a159c266SJung-uk Kim  * This table contains the names of the predefined methods for which we can
254a159c266SJung-uk Kim  * perform more complex repairs.
255a159c266SJung-uk Kim  *
256a159c266SJung-uk Kim  * As necessary:
257a159c266SJung-uk Kim  *
258a159c266SJung-uk Kim  * _ALR: Sort the list ascending by AmbientIlluminance
259a159c266SJung-uk Kim  * _CID: Strings: uppercase all, remove any leading asterisk
260a9d8d09cSJung-uk Kim  * _CST: Sort the list ascending by C state type
261a159c266SJung-uk Kim  * _FDE: Convert Buffer of BYTEs to a Buffer of DWORDs
262a159c266SJung-uk Kim  * _GTM: Convert Buffer of BYTEs to a Buffer of DWORDs
263a159c266SJung-uk Kim  * _HID: Strings: uppercase all, remove any leading asterisk
264a9d8d09cSJung-uk Kim  * _PRT: Fix reversed SourceName and SourceIndex
265a159c266SJung-uk Kim  * _PSS: Sort the list descending by Power
266a159c266SJung-uk Kim  * _TSS: Sort the list descending by Power
267a159c266SJung-uk Kim  *
268a159c266SJung-uk Kim  * Names that must be packages, but cannot be sorted:
269a159c266SJung-uk Kim  *
270a159c266SJung-uk Kim  * _BCL: Values are tied to the Package index where they appear, and cannot
271a159c266SJung-uk Kim  * be moved or sorted. These index values are used for _BQC and _BCM.
272a159c266SJung-uk Kim  * However, we can fix the case where a buffer is returned, by converting
273a159c266SJung-uk Kim  * it to a Package of integers.
274a159c266SJung-uk Kim  */
275a159c266SJung-uk Kim static const ACPI_REPAIR_INFO       AcpiNsRepairableNames[] =
276a159c266SJung-uk Kim {
277a159c266SJung-uk Kim     {"_ALR", AcpiNsRepair_ALR},
278a159c266SJung-uk Kim     {"_CID", AcpiNsRepair_CID},
279a9d8d09cSJung-uk Kim     {"_CST", AcpiNsRepair_CST},
280a159c266SJung-uk Kim     {"_FDE", AcpiNsRepair_FDE},
281a159c266SJung-uk Kim     {"_GTM", AcpiNsRepair_FDE},     /* _GTM has same repair as _FDE */
282a159c266SJung-uk Kim     {"_HID", AcpiNsRepair_HID},
283a9d8d09cSJung-uk Kim     {"_PRT", AcpiNsRepair_PRT},
284a159c266SJung-uk Kim     {"_PSS", AcpiNsRepair_PSS},
285a159c266SJung-uk Kim     {"_TSS", AcpiNsRepair_TSS},
286a159c266SJung-uk Kim     {{0,0,0,0}, NULL}               /* Table terminator */
287a159c266SJung-uk Kim };
288a159c266SJung-uk Kim 
289a159c266SJung-uk Kim 
290a159c266SJung-uk Kim #define ACPI_FDE_FIELD_COUNT        5
291a159c266SJung-uk Kim #define ACPI_FDE_BYTE_BUFFER_SIZE   5
292a009b7dcSJung-uk Kim #define ACPI_FDE_DWORD_BUFFER_SIZE  (ACPI_FDE_FIELD_COUNT * (UINT32) sizeof (UINT32))
293a159c266SJung-uk Kim 
294a159c266SJung-uk Kim 
295a159c266SJung-uk Kim /******************************************************************************
296a159c266SJung-uk Kim  *
297a159c266SJung-uk Kim  * FUNCTION:    AcpiNsComplexRepairs
298a159c266SJung-uk Kim  *
299895f26a9SJung-uk Kim  * PARAMETERS:  Info                - Method execution information block
300a159c266SJung-uk Kim  *              Node                - Namespace node for the method/object
301a159c266SJung-uk Kim  *              ValidateStatus      - Original status of earlier validation
302a159c266SJung-uk Kim  *              ReturnObjectPtr     - Pointer to the object returned from the
303a159c266SJung-uk Kim  *                                    evaluation of a method or object
304a159c266SJung-uk Kim  *
305a159c266SJung-uk Kim  * RETURN:      Status. AE_OK if repair was successful. If name is not
306a159c266SJung-uk Kim  *              matched, ValidateStatus is returned.
307a159c266SJung-uk Kim  *
308a159c266SJung-uk Kim  * DESCRIPTION: Attempt to repair/convert a return object of a type that was
309a159c266SJung-uk Kim  *              not expected.
310a159c266SJung-uk Kim  *
311a159c266SJung-uk Kim  *****************************************************************************/
312a159c266SJung-uk Kim 
313a159c266SJung-uk Kim ACPI_STATUS
314a159c266SJung-uk Kim AcpiNsComplexRepairs (
315895f26a9SJung-uk Kim     ACPI_EVALUATE_INFO      *Info,
316a159c266SJung-uk Kim     ACPI_NAMESPACE_NODE     *Node,
317a159c266SJung-uk Kim     ACPI_STATUS             ValidateStatus,
318a159c266SJung-uk Kim     ACPI_OPERAND_OBJECT     **ReturnObjectPtr)
319a159c266SJung-uk Kim {
320a159c266SJung-uk Kim     const ACPI_REPAIR_INFO  *Predefined;
321a159c266SJung-uk Kim     ACPI_STATUS             Status;
322a159c266SJung-uk Kim 
323a159c266SJung-uk Kim 
324fbde3477SJung-uk Kim     ACPI_FUNCTION_TRACE (NsComplexRepairs);
325fbde3477SJung-uk Kim 
326a159c266SJung-uk Kim     /* Check if this name is in the list of repairable names */
327a159c266SJung-uk Kim 
3289c48c75eSJung-uk Kim     Predefined = AcpiNsMatchComplexRepair (Node);
329a159c266SJung-uk Kim     if (!Predefined)
330a159c266SJung-uk Kim     {
331fbde3477SJung-uk Kim         return_ACPI_STATUS (ValidateStatus);
332a159c266SJung-uk Kim     }
333a159c266SJung-uk Kim 
334895f26a9SJung-uk Kim     Status = Predefined->RepairFunction (Info, ReturnObjectPtr);
335fbde3477SJung-uk Kim     return_ACPI_STATUS (Status);
336a159c266SJung-uk Kim }
337a159c266SJung-uk Kim 
338a159c266SJung-uk Kim 
339a159c266SJung-uk Kim /******************************************************************************
340a159c266SJung-uk Kim  *
3419c48c75eSJung-uk Kim  * FUNCTION:    AcpiNsMatchComplexRepair
342a159c266SJung-uk Kim  *
343a159c266SJung-uk Kim  * PARAMETERS:  Node                - Namespace node for the method/object
344a159c266SJung-uk Kim  *
345a159c266SJung-uk Kim  * RETURN:      Pointer to entry in repair table. NULL indicates not found.
346a159c266SJung-uk Kim  *
347a159c266SJung-uk Kim  * DESCRIPTION: Check an object name against the repairable object list.
348a159c266SJung-uk Kim  *
349a159c266SJung-uk Kim  *****************************************************************************/
350a159c266SJung-uk Kim 
351a159c266SJung-uk Kim static const ACPI_REPAIR_INFO *
3529c48c75eSJung-uk Kim AcpiNsMatchComplexRepair (
353a159c266SJung-uk Kim     ACPI_NAMESPACE_NODE     *Node)
354a159c266SJung-uk Kim {
355a159c266SJung-uk Kim     const ACPI_REPAIR_INFO  *ThisName;
356a159c266SJung-uk Kim 
357a159c266SJung-uk Kim 
358a159c266SJung-uk Kim     /* Search info table for a repairable predefined method/object name */
359a159c266SJung-uk Kim 
360a159c266SJung-uk Kim     ThisName = AcpiNsRepairableNames;
361a159c266SJung-uk Kim     while (ThisName->RepairFunction)
362a159c266SJung-uk Kim     {
363278f0de6SJung-uk Kim         if (ACPI_COMPARE_NAMESEG (Node->Name.Ascii, ThisName->Name))
364a159c266SJung-uk Kim         {
365a159c266SJung-uk Kim             return (ThisName);
366a159c266SJung-uk Kim         }
367f8146b88SJung-uk Kim 
368a159c266SJung-uk Kim         ThisName++;
369a159c266SJung-uk Kim     }
370a159c266SJung-uk Kim 
371a159c266SJung-uk Kim     return (NULL); /* Not found */
372a159c266SJung-uk Kim }
373a159c266SJung-uk Kim 
374a159c266SJung-uk Kim 
375a159c266SJung-uk Kim /******************************************************************************
376a159c266SJung-uk Kim  *
377a159c266SJung-uk Kim  * FUNCTION:    AcpiNsRepair_ALR
378a159c266SJung-uk Kim  *
379895f26a9SJung-uk Kim  * PARAMETERS:  Info                - Method execution information block
380a159c266SJung-uk Kim  *              ReturnObjectPtr     - Pointer to the object returned from the
381a159c266SJung-uk Kim  *                                    evaluation of a method or object
382a159c266SJung-uk Kim  *
383a159c266SJung-uk Kim  * RETURN:      Status. AE_OK if object is OK or was repaired successfully
384a159c266SJung-uk Kim  *
385a159c266SJung-uk Kim  * DESCRIPTION: Repair for the _ALR object. If necessary, sort the object list
386a159c266SJung-uk Kim  *              ascending by the ambient illuminance values.
387a159c266SJung-uk Kim  *
388a159c266SJung-uk Kim  *****************************************************************************/
389a159c266SJung-uk Kim 
390a159c266SJung-uk Kim static ACPI_STATUS
391a159c266SJung-uk Kim AcpiNsRepair_ALR (
392895f26a9SJung-uk Kim     ACPI_EVALUATE_INFO      *Info,
393a159c266SJung-uk Kim     ACPI_OPERAND_OBJECT     **ReturnObjectPtr)
394a159c266SJung-uk Kim {
395a159c266SJung-uk Kim     ACPI_OPERAND_OBJECT     *ReturnObject = *ReturnObjectPtr;
396a159c266SJung-uk Kim     ACPI_STATUS             Status;
397a159c266SJung-uk Kim 
398a159c266SJung-uk Kim 
399a9d8d09cSJung-uk Kim     Status = AcpiNsCheckSortedList (Info, ReturnObject, 0, 2, 1,
400a159c266SJung-uk Kim         ACPI_SORT_ASCENDING, "AmbientIlluminance");
401a159c266SJung-uk Kim 
402a159c266SJung-uk Kim     return (Status);
403a159c266SJung-uk Kim }
404a159c266SJung-uk Kim 
405a159c266SJung-uk Kim 
406a159c266SJung-uk Kim /******************************************************************************
407a159c266SJung-uk Kim  *
408a159c266SJung-uk Kim  * FUNCTION:    AcpiNsRepair_FDE
409a159c266SJung-uk Kim  *
410895f26a9SJung-uk Kim  * PARAMETERS:  Info                - Method execution information block
411a159c266SJung-uk Kim  *              ReturnObjectPtr     - Pointer to the object returned from the
412a159c266SJung-uk Kim  *                                    evaluation of a method or object
413a159c266SJung-uk Kim  *
414a159c266SJung-uk Kim  * RETURN:      Status. AE_OK if object is OK or was repaired successfully
415a159c266SJung-uk Kim  *
416a159c266SJung-uk Kim  * DESCRIPTION: Repair for the _FDE and _GTM objects. The expected return
417a159c266SJung-uk Kim  *              value is a Buffer of 5 DWORDs. This function repairs a common
418a159c266SJung-uk Kim  *              problem where the return value is a Buffer of BYTEs, not
419a159c266SJung-uk Kim  *              DWORDs.
420a159c266SJung-uk Kim  *
421a159c266SJung-uk Kim  *****************************************************************************/
422a159c266SJung-uk Kim 
423a159c266SJung-uk Kim static ACPI_STATUS
424a159c266SJung-uk Kim AcpiNsRepair_FDE (
425895f26a9SJung-uk Kim     ACPI_EVALUATE_INFO      *Info,
426a159c266SJung-uk Kim     ACPI_OPERAND_OBJECT     **ReturnObjectPtr)
427a159c266SJung-uk Kim {
428a159c266SJung-uk Kim     ACPI_OPERAND_OBJECT     *ReturnObject = *ReturnObjectPtr;
429a159c266SJung-uk Kim     ACPI_OPERAND_OBJECT     *BufferObject;
430a159c266SJung-uk Kim     UINT8                   *ByteBuffer;
431a159c266SJung-uk Kim     UINT32                  *DwordBuffer;
432a159c266SJung-uk Kim     UINT32                  i;
433a159c266SJung-uk Kim 
434a159c266SJung-uk Kim 
435a159c266SJung-uk Kim     ACPI_FUNCTION_NAME (NsRepair_FDE);
436a159c266SJung-uk Kim 
437a159c266SJung-uk Kim 
438a159c266SJung-uk Kim     switch (ReturnObject->Common.Type)
439a159c266SJung-uk Kim     {
440a159c266SJung-uk Kim     case ACPI_TYPE_BUFFER:
441a159c266SJung-uk Kim 
442a159c266SJung-uk Kim         /* This is the expected type. Length should be (at least) 5 DWORDs */
443a159c266SJung-uk Kim 
444a159c266SJung-uk Kim         if (ReturnObject->Buffer.Length >= ACPI_FDE_DWORD_BUFFER_SIZE)
445a159c266SJung-uk Kim         {
446a159c266SJung-uk Kim             return (AE_OK);
447a159c266SJung-uk Kim         }
448a159c266SJung-uk Kim 
449a159c266SJung-uk Kim         /* We can only repair if we have exactly 5 BYTEs */
450a159c266SJung-uk Kim 
451a159c266SJung-uk Kim         if (ReturnObject->Buffer.Length != ACPI_FDE_BYTE_BUFFER_SIZE)
452a159c266SJung-uk Kim         {
453f8146b88SJung-uk Kim             ACPI_WARN_PREDEFINED ((AE_INFO,
454f8146b88SJung-uk Kim                 Info->FullPathname, Info->NodeFlags,
455a159c266SJung-uk Kim                 "Incorrect return buffer length %u, expected %u",
456a159c266SJung-uk Kim                 ReturnObject->Buffer.Length, ACPI_FDE_DWORD_BUFFER_SIZE));
457a159c266SJung-uk Kim 
458a159c266SJung-uk Kim             return (AE_AML_OPERAND_TYPE);
459a159c266SJung-uk Kim         }
460a159c266SJung-uk Kim 
461a159c266SJung-uk Kim         /* Create the new (larger) buffer object */
462a159c266SJung-uk Kim 
463f8146b88SJung-uk Kim         BufferObject = AcpiUtCreateBufferObject (
464f8146b88SJung-uk Kim             ACPI_FDE_DWORD_BUFFER_SIZE);
465a159c266SJung-uk Kim         if (!BufferObject)
466a159c266SJung-uk Kim         {
467a159c266SJung-uk Kim             return (AE_NO_MEMORY);
468a159c266SJung-uk Kim         }
469a159c266SJung-uk Kim 
470a159c266SJung-uk Kim         /* Expand each byte to a DWORD */
471a159c266SJung-uk Kim 
472a159c266SJung-uk Kim         ByteBuffer = ReturnObject->Buffer.Pointer;
473f8146b88SJung-uk Kim         DwordBuffer = ACPI_CAST_PTR (UINT32,
474f8146b88SJung-uk Kim             BufferObject->Buffer.Pointer);
475a159c266SJung-uk Kim 
476a159c266SJung-uk Kim         for (i = 0; i < ACPI_FDE_FIELD_COUNT; i++)
477a159c266SJung-uk Kim         {
478a159c266SJung-uk Kim             *DwordBuffer = (UINT32) *ByteBuffer;
479a159c266SJung-uk Kim             DwordBuffer++;
480a159c266SJung-uk Kim             ByteBuffer++;
481a159c266SJung-uk Kim         }
482a159c266SJung-uk Kim 
483a159c266SJung-uk Kim         ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR,
484a159c266SJung-uk Kim             "%s Expanded Byte Buffer to expected DWord Buffer\n",
485895f26a9SJung-uk Kim             Info->FullPathname));
486a159c266SJung-uk Kim         break;
487a159c266SJung-uk Kim 
488a159c266SJung-uk Kim     default:
489a9d8d09cSJung-uk Kim 
490a159c266SJung-uk Kim         return (AE_AML_OPERAND_TYPE);
491a159c266SJung-uk Kim     }
492a159c266SJung-uk Kim 
493a159c266SJung-uk Kim     /* Delete the original return object, return the new buffer object */
494a159c266SJung-uk Kim 
495a159c266SJung-uk Kim     AcpiUtRemoveReference (ReturnObject);
496a159c266SJung-uk Kim     *ReturnObjectPtr = BufferObject;
497a159c266SJung-uk Kim 
498895f26a9SJung-uk Kim     Info->ReturnFlags |= ACPI_OBJECT_REPAIRED;
499a159c266SJung-uk Kim     return (AE_OK);
500a159c266SJung-uk Kim }
501a159c266SJung-uk Kim 
502a159c266SJung-uk Kim 
503a159c266SJung-uk Kim /******************************************************************************
504a159c266SJung-uk Kim  *
505a159c266SJung-uk Kim  * FUNCTION:    AcpiNsRepair_CID
506a159c266SJung-uk Kim  *
507895f26a9SJung-uk Kim  * PARAMETERS:  Info                - Method execution information block
508a159c266SJung-uk Kim  *              ReturnObjectPtr     - Pointer to the object returned from the
509a159c266SJung-uk Kim  *                                    evaluation of a method or object
510a159c266SJung-uk Kim  *
511a159c266SJung-uk Kim  * RETURN:      Status. AE_OK if object is OK or was repaired successfully
512a159c266SJung-uk Kim  *
513a159c266SJung-uk Kim  * DESCRIPTION: Repair for the _CID object. If a string, ensure that all
514a159c266SJung-uk Kim  *              letters are uppercase and that there is no leading asterisk.
515a159c266SJung-uk Kim  *              If a Package, ensure same for all string elements.
516a159c266SJung-uk Kim  *
517a159c266SJung-uk Kim  *****************************************************************************/
518a159c266SJung-uk Kim 
519a159c266SJung-uk Kim static ACPI_STATUS
520a159c266SJung-uk Kim AcpiNsRepair_CID (
521895f26a9SJung-uk Kim     ACPI_EVALUATE_INFO      *Info,
522a159c266SJung-uk Kim     ACPI_OPERAND_OBJECT     **ReturnObjectPtr)
523a159c266SJung-uk Kim {
524a159c266SJung-uk Kim     ACPI_STATUS             Status;
525a159c266SJung-uk Kim     ACPI_OPERAND_OBJECT     *ReturnObject = *ReturnObjectPtr;
526a159c266SJung-uk Kim     ACPI_OPERAND_OBJECT     **ElementPtr;
527a159c266SJung-uk Kim     ACPI_OPERAND_OBJECT     *OriginalElement;
528a159c266SJung-uk Kim     UINT16                  OriginalRefCount;
529a159c266SJung-uk Kim     UINT32                  i;
530a159c266SJung-uk Kim 
531fbde3477SJung-uk Kim     ACPI_FUNCTION_TRACE (NsRepair_CID);
532a159c266SJung-uk Kim 
533a159c266SJung-uk Kim     /* Check for _CID as a simple string */
534a159c266SJung-uk Kim 
535a159c266SJung-uk Kim     if (ReturnObject->Common.Type == ACPI_TYPE_STRING)
536a159c266SJung-uk Kim     {
537895f26a9SJung-uk Kim         Status = AcpiNsRepair_HID (Info, ReturnObjectPtr);
538fbde3477SJung-uk Kim         return_ACPI_STATUS (Status);
539a159c266SJung-uk Kim     }
540a159c266SJung-uk Kim 
541a159c266SJung-uk Kim     /* Exit if not a Package */
542a159c266SJung-uk Kim 
543a159c266SJung-uk Kim     if (ReturnObject->Common.Type != ACPI_TYPE_PACKAGE)
544a159c266SJung-uk Kim     {
545fbde3477SJung-uk Kim         return_ACPI_STATUS (AE_OK);
546a159c266SJung-uk Kim     }
547a159c266SJung-uk Kim 
548a159c266SJung-uk Kim     /* Examine each element of the _CID package */
549a159c266SJung-uk Kim 
550a159c266SJung-uk Kim     ElementPtr = ReturnObject->Package.Elements;
551a159c266SJung-uk Kim     for (i = 0; i < ReturnObject->Package.Count; i++)
552a159c266SJung-uk Kim     {
553a159c266SJung-uk Kim         OriginalElement = *ElementPtr;
554a159c266SJung-uk Kim         OriginalRefCount = OriginalElement->Common.ReferenceCount;
555a159c266SJung-uk Kim 
556895f26a9SJung-uk Kim         Status = AcpiNsRepair_HID (Info, ElementPtr);
557a159c266SJung-uk Kim         if (ACPI_FAILURE (Status))
558a159c266SJung-uk Kim         {
559fbde3477SJung-uk Kim             return_ACPI_STATUS (Status);
560a159c266SJung-uk Kim         }
561a159c266SJung-uk Kim 
562a159c266SJung-uk Kim         if (OriginalElement != *ElementPtr)
563a159c266SJung-uk Kim         {
5640d84335fSJung-uk Kim             /* Update reference count of new object */
565a159c266SJung-uk Kim 
566a159c266SJung-uk Kim             (*ElementPtr)->Common.ReferenceCount =
567a159c266SJung-uk Kim                 OriginalRefCount;
568a159c266SJung-uk Kim         }
569a159c266SJung-uk Kim 
570a159c266SJung-uk Kim         ElementPtr++;
571a159c266SJung-uk Kim     }
572a159c266SJung-uk Kim 
573fbde3477SJung-uk Kim     return_ACPI_STATUS (AE_OK);
574a159c266SJung-uk Kim }
575a159c266SJung-uk Kim 
576a159c266SJung-uk Kim 
577a159c266SJung-uk Kim /******************************************************************************
578a159c266SJung-uk Kim  *
579a9d8d09cSJung-uk Kim  * FUNCTION:    AcpiNsRepair_CST
580a9d8d09cSJung-uk Kim  *
581a9d8d09cSJung-uk Kim  * PARAMETERS:  Info                - Method execution information block
582a9d8d09cSJung-uk Kim  *              ReturnObjectPtr     - Pointer to the object returned from the
583a9d8d09cSJung-uk Kim  *                                    evaluation of a method or object
584a9d8d09cSJung-uk Kim  *
585a9d8d09cSJung-uk Kim  * RETURN:      Status. AE_OK if object is OK or was repaired successfully
586a9d8d09cSJung-uk Kim  *
587a9d8d09cSJung-uk Kim  * DESCRIPTION: Repair for the _CST object:
588a9d8d09cSJung-uk Kim  *              1. Sort the list ascending by C state type
589a9d8d09cSJung-uk Kim  *              2. Ensure type cannot be zero
590313a0c13SJung-uk Kim  *              3. A subpackage count of zero means _CST is meaningless
591313a0c13SJung-uk Kim  *              4. Count must match the number of C state subpackages
592a9d8d09cSJung-uk Kim  *
593a9d8d09cSJung-uk Kim  *****************************************************************************/
594a9d8d09cSJung-uk Kim 
595a9d8d09cSJung-uk Kim static ACPI_STATUS
596a9d8d09cSJung-uk Kim AcpiNsRepair_CST (
597a9d8d09cSJung-uk Kim     ACPI_EVALUATE_INFO      *Info,
598a9d8d09cSJung-uk Kim     ACPI_OPERAND_OBJECT     **ReturnObjectPtr)
599a9d8d09cSJung-uk Kim {
600a9d8d09cSJung-uk Kim     ACPI_OPERAND_OBJECT     *ReturnObject = *ReturnObjectPtr;
601a9d8d09cSJung-uk Kim     ACPI_OPERAND_OBJECT     **OuterElements;
602a9d8d09cSJung-uk Kim     UINT32                  OuterElementCount;
603a9d8d09cSJung-uk Kim     ACPI_OPERAND_OBJECT     *ObjDesc;
604a9d8d09cSJung-uk Kim     ACPI_STATUS             Status;
605a9d8d09cSJung-uk Kim     BOOLEAN                 Removing;
606a9d8d09cSJung-uk Kim     UINT32                  i;
607a9d8d09cSJung-uk Kim 
608a9d8d09cSJung-uk Kim 
609a9d8d09cSJung-uk Kim     ACPI_FUNCTION_NAME (NsRepair_CST);
610a9d8d09cSJung-uk Kim 
611a9d8d09cSJung-uk Kim 
612a9d8d09cSJung-uk Kim     /*
6138d744e47SJung-uk Kim      * Check if the C-state type values are proportional.
614a9d8d09cSJung-uk Kim      */
615a9d8d09cSJung-uk Kim     OuterElementCount = ReturnObject->Package.Count - 1;
616a9d8d09cSJung-uk Kim     i = 0;
617a9d8d09cSJung-uk Kim     while (i < OuterElementCount)
618a9d8d09cSJung-uk Kim     {
619a9d8d09cSJung-uk Kim         OuterElements = &ReturnObject->Package.Elements[i + 1];
620a9d8d09cSJung-uk Kim         Removing = FALSE;
621a9d8d09cSJung-uk Kim 
622a9d8d09cSJung-uk Kim         if ((*OuterElements)->Package.Count == 0)
623a9d8d09cSJung-uk Kim         {
624f8146b88SJung-uk Kim             ACPI_WARN_PREDEFINED ((AE_INFO,
625f8146b88SJung-uk Kim                 Info->FullPathname, Info->NodeFlags,
626a9d8d09cSJung-uk Kim                 "SubPackage[%u] - removing entry due to zero count", i));
627a9d8d09cSJung-uk Kim             Removing = TRUE;
6288d744e47SJung-uk Kim             goto RemoveElement;
629a9d8d09cSJung-uk Kim         }
630a9d8d09cSJung-uk Kim 
631a9d8d09cSJung-uk Kim         ObjDesc = (*OuterElements)->Package.Elements[1]; /* Index1 = Type */
632a9d8d09cSJung-uk Kim         if ((UINT32) ObjDesc->Integer.Value == 0)
633a9d8d09cSJung-uk Kim         {
634f8146b88SJung-uk Kim             ACPI_WARN_PREDEFINED ((AE_INFO,
635f8146b88SJung-uk Kim                 Info->FullPathname, Info->NodeFlags,
636a9d8d09cSJung-uk Kim                 "SubPackage[%u] - removing entry due to invalid Type(0)", i));
637a9d8d09cSJung-uk Kim             Removing = TRUE;
638a9d8d09cSJung-uk Kim         }
639a9d8d09cSJung-uk Kim 
6408d744e47SJung-uk Kim RemoveElement:
641a9d8d09cSJung-uk Kim         if (Removing)
642a9d8d09cSJung-uk Kim         {
643a9d8d09cSJung-uk Kim             AcpiNsRemoveElement (ReturnObject, i + 1);
644a9d8d09cSJung-uk Kim             OuterElementCount--;
645a9d8d09cSJung-uk Kim         }
646a9d8d09cSJung-uk Kim         else
647a9d8d09cSJung-uk Kim         {
648a9d8d09cSJung-uk Kim             i++;
649a9d8d09cSJung-uk Kim         }
650a9d8d09cSJung-uk Kim     }
651a9d8d09cSJung-uk Kim 
652a9d8d09cSJung-uk Kim     /* Update top-level package count, Type "Integer" checked elsewhere */
653a9d8d09cSJung-uk Kim 
654a9d8d09cSJung-uk Kim     ObjDesc = ReturnObject->Package.Elements[0];
655a9d8d09cSJung-uk Kim     ObjDesc->Integer.Value = OuterElementCount;
6568d744e47SJung-uk Kim 
6578d744e47SJung-uk Kim     /*
6588d744e47SJung-uk Kim      * Entries (subpackages) in the _CST Package must be sorted by the
6598d744e47SJung-uk Kim      * C-state type, in ascending order.
6608d744e47SJung-uk Kim      */
6618d744e47SJung-uk Kim     Status = AcpiNsCheckSortedList (Info, ReturnObject, 1, 4, 1,
6628d744e47SJung-uk Kim         ACPI_SORT_ASCENDING, "C-State Type");
6638d744e47SJung-uk Kim     if (ACPI_FAILURE (Status))
6648d744e47SJung-uk Kim     {
6658d744e47SJung-uk Kim         return (Status);
6668d744e47SJung-uk Kim     }
6678d744e47SJung-uk Kim 
668a9d8d09cSJung-uk Kim     return (AE_OK);
669a9d8d09cSJung-uk Kim }
670a9d8d09cSJung-uk Kim 
671a9d8d09cSJung-uk Kim 
672a9d8d09cSJung-uk Kim /******************************************************************************
673a9d8d09cSJung-uk Kim  *
674a159c266SJung-uk Kim  * FUNCTION:    AcpiNsRepair_HID
675a159c266SJung-uk Kim  *
676895f26a9SJung-uk Kim  * PARAMETERS:  Info                - Method execution information block
677a159c266SJung-uk Kim  *              ReturnObjectPtr     - Pointer to the object returned from the
678a159c266SJung-uk Kim  *                                    evaluation of a method or object
679a159c266SJung-uk Kim  *
680a159c266SJung-uk Kim  * RETURN:      Status. AE_OK if object is OK or was repaired successfully
681a159c266SJung-uk Kim  *
682a159c266SJung-uk Kim  * DESCRIPTION: Repair for the _HID object. If a string, ensure that all
683a159c266SJung-uk Kim  *              letters are uppercase and that there is no leading asterisk.
684a159c266SJung-uk Kim  *
685a159c266SJung-uk Kim  *****************************************************************************/
686a159c266SJung-uk Kim 
687a159c266SJung-uk Kim static ACPI_STATUS
688a159c266SJung-uk Kim AcpiNsRepair_HID (
689895f26a9SJung-uk Kim     ACPI_EVALUATE_INFO      *Info,
690a159c266SJung-uk Kim     ACPI_OPERAND_OBJECT     **ReturnObjectPtr)
691a159c266SJung-uk Kim {
692a159c266SJung-uk Kim     ACPI_OPERAND_OBJECT     *ReturnObject = *ReturnObjectPtr;
693cfd1ed46SJung-uk Kim     ACPI_OPERAND_OBJECT     *NewString;
694fbde3477SJung-uk Kim     char                    *Source;
695cfd1ed46SJung-uk Kim     char                    *Dest;
696a159c266SJung-uk Kim 
697a159c266SJung-uk Kim 
698722b1667SJung-uk Kim     ACPI_FUNCTION_TRACE (NsRepair_HID);
699a159c266SJung-uk Kim 
700a159c266SJung-uk Kim 
701a159c266SJung-uk Kim     /* We only care about string _HID objects (not integers) */
702a159c266SJung-uk Kim 
703a159c266SJung-uk Kim     if (ReturnObject->Common.Type != ACPI_TYPE_STRING)
704a159c266SJung-uk Kim     {
705fbde3477SJung-uk Kim         return_ACPI_STATUS (AE_OK);
706a159c266SJung-uk Kim     }
707a159c266SJung-uk Kim 
708a159c266SJung-uk Kim     if (ReturnObject->String.Length == 0)
709a159c266SJung-uk Kim     {
710f8146b88SJung-uk Kim         ACPI_WARN_PREDEFINED ((AE_INFO,
711f8146b88SJung-uk Kim             Info->FullPathname, Info->NodeFlags,
712a159c266SJung-uk Kim             "Invalid zero-length _HID or _CID string"));
713a159c266SJung-uk Kim 
714a159c266SJung-uk Kim         /* Return AE_OK anyway, let driver handle it */
715a159c266SJung-uk Kim 
716895f26a9SJung-uk Kim         Info->ReturnFlags |= ACPI_OBJECT_REPAIRED;
717fbde3477SJung-uk Kim         return_ACPI_STATUS (AE_OK);
718a159c266SJung-uk Kim     }
719a159c266SJung-uk Kim 
720cfd1ed46SJung-uk Kim     /* It is simplest to always create a new string object */
721cfd1ed46SJung-uk Kim 
722cfd1ed46SJung-uk Kim     NewString = AcpiUtCreateStringObject (ReturnObject->String.Length);
723cfd1ed46SJung-uk Kim     if (!NewString)
724cfd1ed46SJung-uk Kim     {
725cfd1ed46SJung-uk Kim         return_ACPI_STATUS (AE_NO_MEMORY);
726cfd1ed46SJung-uk Kim     }
727cfd1ed46SJung-uk Kim 
728a159c266SJung-uk Kim     /*
729a159c266SJung-uk Kim      * Remove a leading asterisk if present. For some unknown reason, there
730a159c266SJung-uk Kim      * are many machines in the field that contains IDs like this.
731a159c266SJung-uk Kim      *
732a159c266SJung-uk Kim      * Examples: "*PNP0C03", "*ACPI0003"
733a159c266SJung-uk Kim      */
734a159c266SJung-uk Kim     Source = ReturnObject->String.Pointer;
735a159c266SJung-uk Kim     if (*Source == '*')
736a159c266SJung-uk Kim     {
737a159c266SJung-uk Kim         Source++;
738cfd1ed46SJung-uk Kim         NewString->String.Length--;
739a159c266SJung-uk Kim 
740a159c266SJung-uk Kim         ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR,
741895f26a9SJung-uk Kim             "%s: Removed invalid leading asterisk\n", Info->FullPathname));
742a159c266SJung-uk Kim     }
743a159c266SJung-uk Kim 
744a159c266SJung-uk Kim     /*
745a159c266SJung-uk Kim      * Copy and uppercase the string. From the ACPI 5.0 specification:
746a159c266SJung-uk Kim      *
747a159c266SJung-uk Kim      * A valid PNP ID must be of the form "AAA####" where A is an uppercase
748a159c266SJung-uk Kim      * letter and # is a hex digit. A valid ACPI ID must be of the form
749a159c266SJung-uk Kim      * "NNNN####" where N is an uppercase letter or decimal digit, and
750a159c266SJung-uk Kim      * # is a hex digit.
751a159c266SJung-uk Kim      */
752cfd1ed46SJung-uk Kim     for (Dest = NewString->String.Pointer; *Source; Dest++, Source++)
753a159c266SJung-uk Kim     {
7545ef50723SJung-uk Kim         *Dest = (char) toupper ((int) *Source);
755a159c266SJung-uk Kim     }
756a159c266SJung-uk Kim 
757cfd1ed46SJung-uk Kim     AcpiUtRemoveReference (ReturnObject);
758cfd1ed46SJung-uk Kim     *ReturnObjectPtr = NewString;
759fbde3477SJung-uk Kim     return_ACPI_STATUS (AE_OK);
760a159c266SJung-uk Kim }
761a159c266SJung-uk Kim 
762a159c266SJung-uk Kim 
763a159c266SJung-uk Kim /******************************************************************************
764a159c266SJung-uk Kim  *
765a9d8d09cSJung-uk Kim  * FUNCTION:    AcpiNsRepair_PRT
766a159c266SJung-uk Kim  *
767895f26a9SJung-uk Kim  * PARAMETERS:  Info                - Method execution information block
768a159c266SJung-uk Kim  *              ReturnObjectPtr     - Pointer to the object returned from the
769a159c266SJung-uk Kim  *                                    evaluation of a method or object
770a159c266SJung-uk Kim  *
771a159c266SJung-uk Kim  * RETURN:      Status. AE_OK if object is OK or was repaired successfully
772a159c266SJung-uk Kim  *
773a9d8d09cSJung-uk Kim  * DESCRIPTION: Repair for the _PRT object. If necessary, fix reversed
774a9d8d09cSJung-uk Kim  *              SourceName and SourceIndex field, a common BIOS bug.
775a159c266SJung-uk Kim  *
776a159c266SJung-uk Kim  *****************************************************************************/
777a159c266SJung-uk Kim 
778a159c266SJung-uk Kim static ACPI_STATUS
779a9d8d09cSJung-uk Kim AcpiNsRepair_PRT (
780895f26a9SJung-uk Kim     ACPI_EVALUATE_INFO      *Info,
781a159c266SJung-uk Kim     ACPI_OPERAND_OBJECT     **ReturnObjectPtr)
782a159c266SJung-uk Kim {
783a9d8d09cSJung-uk Kim     ACPI_OPERAND_OBJECT     *PackageObject = *ReturnObjectPtr;
784a9d8d09cSJung-uk Kim     ACPI_OPERAND_OBJECT     **TopObjectList;
785a9d8d09cSJung-uk Kim     ACPI_OPERAND_OBJECT     **SubObjectList;
786a9d8d09cSJung-uk Kim     ACPI_OPERAND_OBJECT     *ObjDesc;
787313a0c13SJung-uk Kim     ACPI_OPERAND_OBJECT     *SubPackage;
788a9d8d09cSJung-uk Kim     UINT32                  ElementCount;
789a9d8d09cSJung-uk Kim     UINT32                  Index;
790a159c266SJung-uk Kim 
791a159c266SJung-uk Kim 
792a9d8d09cSJung-uk Kim     /* Each element in the _PRT package is a subpackage */
793a9d8d09cSJung-uk Kim 
794a9d8d09cSJung-uk Kim     TopObjectList = PackageObject->Package.Elements;
795a9d8d09cSJung-uk Kim     ElementCount = PackageObject->Package.Count;
796a9d8d09cSJung-uk Kim 
797313a0c13SJung-uk Kim     /* Examine each subpackage */
798313a0c13SJung-uk Kim 
799313a0c13SJung-uk Kim     for (Index = 0; Index < ElementCount; Index++, TopObjectList++)
800a9d8d09cSJung-uk Kim     {
801313a0c13SJung-uk Kim         SubPackage = *TopObjectList;
802313a0c13SJung-uk Kim         SubObjectList = SubPackage->Package.Elements;
803313a0c13SJung-uk Kim 
804313a0c13SJung-uk Kim         /* Check for minimum required element count */
805313a0c13SJung-uk Kim 
806313a0c13SJung-uk Kim         if (SubPackage->Package.Count < 4)
807313a0c13SJung-uk Kim         {
808313a0c13SJung-uk Kim             continue;
809313a0c13SJung-uk Kim         }
810a9d8d09cSJung-uk Kim 
811a159c266SJung-uk Kim         /*
812a9d8d09cSJung-uk Kim          * If the BIOS has erroneously reversed the _PRT SourceName (index 2)
813a9d8d09cSJung-uk Kim          * and the SourceIndex (index 3), fix it. _PRT is important enough to
814a9d8d09cSJung-uk Kim          * workaround this BIOS error. This also provides compatibility with
815a9d8d09cSJung-uk Kim          * other ACPI implementations.
816a159c266SJung-uk Kim          */
817a9d8d09cSJung-uk Kim         ObjDesc = SubObjectList[3];
818a9d8d09cSJung-uk Kim         if (!ObjDesc || (ObjDesc->Common.Type != ACPI_TYPE_INTEGER))
819a159c266SJung-uk Kim         {
820a9d8d09cSJung-uk Kim             SubObjectList[3] = SubObjectList[2];
821a9d8d09cSJung-uk Kim             SubObjectList[2] = ObjDesc;
822a9d8d09cSJung-uk Kim             Info->ReturnFlags |= ACPI_OBJECT_REPAIRED;
823a9d8d09cSJung-uk Kim 
824313a0c13SJung-uk Kim             ACPI_WARN_PREDEFINED ((AE_INFO,
825313a0c13SJung-uk Kim                 Info->FullPathname, Info->NodeFlags,
826a9d8d09cSJung-uk Kim                 "PRT[%X]: Fixed reversed SourceName and SourceIndex",
827a9d8d09cSJung-uk Kim                 Index));
828a159c266SJung-uk Kim         }
829a9d8d09cSJung-uk Kim     }
830a9d8d09cSJung-uk Kim 
831a9d8d09cSJung-uk Kim     return (AE_OK);
832a159c266SJung-uk Kim }
833a159c266SJung-uk Kim 
834a159c266SJung-uk Kim 
835a159c266SJung-uk Kim /******************************************************************************
836a159c266SJung-uk Kim  *
837a159c266SJung-uk Kim  * FUNCTION:    AcpiNsRepair_PSS
838a159c266SJung-uk Kim  *
839895f26a9SJung-uk Kim  * PARAMETERS:  Info                - Method execution information block
840a159c266SJung-uk Kim  *              ReturnObjectPtr     - Pointer to the object returned from the
841a159c266SJung-uk Kim  *                                    evaluation of a method or object
842a159c266SJung-uk Kim  *
843a159c266SJung-uk Kim  * RETURN:      Status. AE_OK if object is OK or was repaired successfully
844a159c266SJung-uk Kim  *
845a159c266SJung-uk Kim  * DESCRIPTION: Repair for the _PSS object. If necessary, sort the object list
846a159c266SJung-uk Kim  *              by the CPU frequencies. Check that the power dissipation values
847a159c266SJung-uk Kim  *              are all proportional to CPU frequency (i.e., sorting by
848a159c266SJung-uk Kim  *              frequency should be the same as sorting by power.)
849a159c266SJung-uk Kim  *
850a159c266SJung-uk Kim  *****************************************************************************/
851a159c266SJung-uk Kim 
852a159c266SJung-uk Kim static ACPI_STATUS
853a159c266SJung-uk Kim AcpiNsRepair_PSS (
854895f26a9SJung-uk Kim     ACPI_EVALUATE_INFO      *Info,
855a159c266SJung-uk Kim     ACPI_OPERAND_OBJECT     **ReturnObjectPtr)
856a159c266SJung-uk Kim {
857a159c266SJung-uk Kim     ACPI_OPERAND_OBJECT     *ReturnObject = *ReturnObjectPtr;
858a159c266SJung-uk Kim     ACPI_OPERAND_OBJECT     **OuterElements;
859a159c266SJung-uk Kim     UINT32                  OuterElementCount;
860a159c266SJung-uk Kim     ACPI_OPERAND_OBJECT     **Elements;
861a159c266SJung-uk Kim     ACPI_OPERAND_OBJECT     *ObjDesc;
862a159c266SJung-uk Kim     UINT32                  PreviousValue;
863a159c266SJung-uk Kim     ACPI_STATUS             Status;
864a159c266SJung-uk Kim     UINT32                  i;
865a159c266SJung-uk Kim 
866a159c266SJung-uk Kim 
867a159c266SJung-uk Kim     /*
868313a0c13SJung-uk Kim      * Entries (subpackages) in the _PSS Package must be sorted by power
869a159c266SJung-uk Kim      * dissipation, in descending order. If it appears that the list is
870a159c266SJung-uk Kim      * incorrectly sorted, sort it. We sort by CpuFrequency, since this
871a159c266SJung-uk Kim      * should be proportional to the power.
872a159c266SJung-uk Kim      */
873a9d8d09cSJung-uk Kim     Status = AcpiNsCheckSortedList (Info, ReturnObject, 0, 6, 0,
874a159c266SJung-uk Kim         ACPI_SORT_DESCENDING, "CpuFrequency");
875a159c266SJung-uk Kim     if (ACPI_FAILURE (Status))
876a159c266SJung-uk Kim     {
877a159c266SJung-uk Kim         return (Status);
878a159c266SJung-uk Kim     }
879a159c266SJung-uk Kim 
880a159c266SJung-uk Kim     /*
881a159c266SJung-uk Kim      * We now know the list is correctly sorted by CPU frequency. Check if
882a159c266SJung-uk Kim      * the power dissipation values are proportional.
883a159c266SJung-uk Kim      */
884a159c266SJung-uk Kim     PreviousValue = ACPI_UINT32_MAX;
885a159c266SJung-uk Kim     OuterElements = ReturnObject->Package.Elements;
886a159c266SJung-uk Kim     OuterElementCount = ReturnObject->Package.Count;
887a159c266SJung-uk Kim 
888a159c266SJung-uk Kim     for (i = 0; i < OuterElementCount; i++)
889a159c266SJung-uk Kim     {
890a159c266SJung-uk Kim         Elements = (*OuterElements)->Package.Elements;
891a159c266SJung-uk Kim         ObjDesc = Elements[1]; /* Index1 = PowerDissipation */
892a159c266SJung-uk Kim 
893a159c266SJung-uk Kim         if ((UINT32) ObjDesc->Integer.Value > PreviousValue)
894a159c266SJung-uk Kim         {
895f8146b88SJung-uk Kim             ACPI_WARN_PREDEFINED ((AE_INFO,
896f8146b88SJung-uk Kim                 Info->FullPathname, Info->NodeFlags,
897a159c266SJung-uk Kim                 "SubPackage[%u,%u] - suspicious power dissipation values",
898a159c266SJung-uk Kim                 i-1, i));
899a159c266SJung-uk Kim         }
900a159c266SJung-uk Kim 
901a159c266SJung-uk Kim         PreviousValue = (UINT32) ObjDesc->Integer.Value;
902a159c266SJung-uk Kim         OuterElements++;
903a159c266SJung-uk Kim     }
904a159c266SJung-uk Kim 
905a159c266SJung-uk Kim     return (AE_OK);
906a159c266SJung-uk Kim }
907a159c266SJung-uk Kim 
908a159c266SJung-uk Kim 
909a159c266SJung-uk Kim /******************************************************************************
910a159c266SJung-uk Kim  *
911a9d8d09cSJung-uk Kim  * FUNCTION:    AcpiNsRepair_TSS
912a9d8d09cSJung-uk Kim  *
913a9d8d09cSJung-uk Kim  * PARAMETERS:  Info                - Method execution information block
914a9d8d09cSJung-uk Kim  *              ReturnObjectPtr     - Pointer to the object returned from the
915a9d8d09cSJung-uk Kim  *                                    evaluation of a method or object
916a9d8d09cSJung-uk Kim  *
917a9d8d09cSJung-uk Kim  * RETURN:      Status. AE_OK if object is OK or was repaired successfully
918a9d8d09cSJung-uk Kim  *
919a9d8d09cSJung-uk Kim  * DESCRIPTION: Repair for the _TSS object. If necessary, sort the object list
920a9d8d09cSJung-uk Kim  *              descending by the power dissipation values.
921a9d8d09cSJung-uk Kim  *
922a9d8d09cSJung-uk Kim  *****************************************************************************/
923a9d8d09cSJung-uk Kim 
924a9d8d09cSJung-uk Kim static ACPI_STATUS
925a9d8d09cSJung-uk Kim AcpiNsRepair_TSS (
926a9d8d09cSJung-uk Kim     ACPI_EVALUATE_INFO      *Info,
927a9d8d09cSJung-uk Kim     ACPI_OPERAND_OBJECT     **ReturnObjectPtr)
928a9d8d09cSJung-uk Kim {
929a9d8d09cSJung-uk Kim     ACPI_OPERAND_OBJECT     *ReturnObject = *ReturnObjectPtr;
930a9d8d09cSJung-uk Kim     ACPI_STATUS             Status;
931a9d8d09cSJung-uk Kim     ACPI_NAMESPACE_NODE     *Node;
932a9d8d09cSJung-uk Kim 
933a9d8d09cSJung-uk Kim 
934a9d8d09cSJung-uk Kim     /*
935a9d8d09cSJung-uk Kim      * We can only sort the _TSS return package if there is no _PSS in the
936a9d8d09cSJung-uk Kim      * same scope. This is because if _PSS is present, the ACPI specification
937a9d8d09cSJung-uk Kim      * dictates that the _TSS Power Dissipation field is to be ignored, and
938a9d8d09cSJung-uk Kim      * therefore some BIOSs leave garbage values in the _TSS Power field(s).
939a9d8d09cSJung-uk Kim      * In this case, it is best to just return the _TSS package as-is.
940a9d8d09cSJung-uk Kim      * (May, 2011)
941a9d8d09cSJung-uk Kim      */
942a9d8d09cSJung-uk Kim     Status = AcpiNsGetNode (Info->Node, "^_PSS",
943a9d8d09cSJung-uk Kim         ACPI_NS_NO_UPSEARCH, &Node);
944a9d8d09cSJung-uk Kim     if (ACPI_SUCCESS (Status))
945a9d8d09cSJung-uk Kim     {
946a9d8d09cSJung-uk Kim         return (AE_OK);
947a9d8d09cSJung-uk Kim     }
948a9d8d09cSJung-uk Kim 
949a9d8d09cSJung-uk Kim     Status = AcpiNsCheckSortedList (Info, ReturnObject, 0, 5, 1,
950a9d8d09cSJung-uk Kim         ACPI_SORT_DESCENDING, "PowerDissipation");
951a9d8d09cSJung-uk Kim 
952a9d8d09cSJung-uk Kim     return (Status);
953a9d8d09cSJung-uk Kim }
954a9d8d09cSJung-uk Kim 
955a9d8d09cSJung-uk Kim 
956a9d8d09cSJung-uk Kim /******************************************************************************
957a9d8d09cSJung-uk Kim  *
958a159c266SJung-uk Kim  * FUNCTION:    AcpiNsCheckSortedList
959a159c266SJung-uk Kim  *
960895f26a9SJung-uk Kim  * PARAMETERS:  Info                - Method execution information block
961a159c266SJung-uk Kim  *              ReturnObject        - Pointer to the top-level returned object
962313a0c13SJung-uk Kim  *              StartIndex          - Index of the first subpackage
963313a0c13SJung-uk Kim  *              ExpectedCount       - Minimum length of each subpackage
964313a0c13SJung-uk Kim  *              SortIndex           - Subpackage entry to sort on
965a159c266SJung-uk Kim  *              SortDirection       - Ascending or descending
966a159c266SJung-uk Kim  *              SortKeyName         - Name of the SortIndex field
967a159c266SJung-uk Kim  *
968a159c266SJung-uk Kim  * RETURN:      Status. AE_OK if the list is valid and is sorted correctly or
969a159c266SJung-uk Kim  *              has been repaired by sorting the list.
970a159c266SJung-uk Kim  *
971a159c266SJung-uk Kim  * DESCRIPTION: Check if the package list is valid and sorted correctly by the
972a159c266SJung-uk Kim  *              SortIndex. If not, then sort the list.
973a159c266SJung-uk Kim  *
974a159c266SJung-uk Kim  *****************************************************************************/
975a159c266SJung-uk Kim 
976a159c266SJung-uk Kim static ACPI_STATUS
977a159c266SJung-uk Kim AcpiNsCheckSortedList (
978895f26a9SJung-uk Kim     ACPI_EVALUATE_INFO      *Info,
979a159c266SJung-uk Kim     ACPI_OPERAND_OBJECT     *ReturnObject,
980a9d8d09cSJung-uk Kim     UINT32                  StartIndex,
981a159c266SJung-uk Kim     UINT32                  ExpectedCount,
982a159c266SJung-uk Kim     UINT32                  SortIndex,
983a159c266SJung-uk Kim     UINT8                   SortDirection,
984a159c266SJung-uk Kim     char                    *SortKeyName)
985a159c266SJung-uk Kim {
986a159c266SJung-uk Kim     UINT32                  OuterElementCount;
987a159c266SJung-uk Kim     ACPI_OPERAND_OBJECT     **OuterElements;
988a159c266SJung-uk Kim     ACPI_OPERAND_OBJECT     **Elements;
989a159c266SJung-uk Kim     ACPI_OPERAND_OBJECT     *ObjDesc;
990a159c266SJung-uk Kim     UINT32                  i;
991a159c266SJung-uk Kim     UINT32                  PreviousValue;
992a159c266SJung-uk Kim 
993a159c266SJung-uk Kim 
994a159c266SJung-uk Kim     ACPI_FUNCTION_NAME (NsCheckSortedList);
995a159c266SJung-uk Kim 
996a159c266SJung-uk Kim 
997a159c266SJung-uk Kim     /* The top-level object must be a package */
998a159c266SJung-uk Kim 
999a159c266SJung-uk Kim     if (ReturnObject->Common.Type != ACPI_TYPE_PACKAGE)
1000a159c266SJung-uk Kim     {
1001a159c266SJung-uk Kim         return (AE_AML_OPERAND_TYPE);
1002a159c266SJung-uk Kim     }
1003a159c266SJung-uk Kim 
1004a159c266SJung-uk Kim     /*
1005313a0c13SJung-uk Kim      * NOTE: assumes list of subpackages contains no NULL elements.
1006a159c266SJung-uk Kim      * Any NULL elements should have been removed by earlier call
1007a159c266SJung-uk Kim      * to AcpiNsRemoveNullElements.
1008a159c266SJung-uk Kim      */
1009a159c266SJung-uk Kim     OuterElementCount = ReturnObject->Package.Count;
1010a9d8d09cSJung-uk Kim     if (!OuterElementCount || StartIndex >= OuterElementCount)
1011a159c266SJung-uk Kim     {
1012a159c266SJung-uk Kim         return (AE_AML_PACKAGE_LIMIT);
1013a159c266SJung-uk Kim     }
1014a159c266SJung-uk Kim 
1015a9d8d09cSJung-uk Kim     OuterElements = &ReturnObject->Package.Elements[StartIndex];
1016a9d8d09cSJung-uk Kim     OuterElementCount -= StartIndex;
1017a9d8d09cSJung-uk Kim 
1018a159c266SJung-uk Kim     PreviousValue = 0;
1019a159c266SJung-uk Kim     if (SortDirection == ACPI_SORT_DESCENDING)
1020a159c266SJung-uk Kim     {
1021a159c266SJung-uk Kim         PreviousValue = ACPI_UINT32_MAX;
1022a159c266SJung-uk Kim     }
1023a159c266SJung-uk Kim 
1024a159c266SJung-uk Kim     /* Examine each subpackage */
1025a159c266SJung-uk Kim 
1026a159c266SJung-uk Kim     for (i = 0; i < OuterElementCount; i++)
1027a159c266SJung-uk Kim     {
1028a159c266SJung-uk Kim         /* Each element of the top-level package must also be a package */
1029a159c266SJung-uk Kim 
1030a159c266SJung-uk Kim         if ((*OuterElements)->Common.Type != ACPI_TYPE_PACKAGE)
1031a159c266SJung-uk Kim         {
1032a159c266SJung-uk Kim             return (AE_AML_OPERAND_TYPE);
1033a159c266SJung-uk Kim         }
1034a159c266SJung-uk Kim 
1035313a0c13SJung-uk Kim         /* Each subpackage must have the minimum length */
1036a159c266SJung-uk Kim 
1037a159c266SJung-uk Kim         if ((*OuterElements)->Package.Count < ExpectedCount)
1038a159c266SJung-uk Kim         {
1039a159c266SJung-uk Kim             return (AE_AML_PACKAGE_LIMIT);
1040a159c266SJung-uk Kim         }
1041a159c266SJung-uk Kim 
1042a159c266SJung-uk Kim         Elements = (*OuterElements)->Package.Elements;
1043a159c266SJung-uk Kim         ObjDesc = Elements[SortIndex];
1044a159c266SJung-uk Kim 
1045a159c266SJung-uk Kim         if (ObjDesc->Common.Type != ACPI_TYPE_INTEGER)
1046a159c266SJung-uk Kim         {
1047a159c266SJung-uk Kim             return (AE_AML_OPERAND_TYPE);
1048a159c266SJung-uk Kim         }
1049a159c266SJung-uk Kim 
1050a159c266SJung-uk Kim         /*
1051a159c266SJung-uk Kim          * The list must be sorted in the specified order. If we detect a
1052a159c266SJung-uk Kim          * discrepancy, sort the entire list.
1053a159c266SJung-uk Kim          */
1054a159c266SJung-uk Kim         if (((SortDirection == ACPI_SORT_ASCENDING) &&
1055a159c266SJung-uk Kim                 (ObjDesc->Integer.Value < PreviousValue)) ||
1056a159c266SJung-uk Kim             ((SortDirection == ACPI_SORT_DESCENDING) &&
1057a159c266SJung-uk Kim                 (ObjDesc->Integer.Value > PreviousValue)))
1058a159c266SJung-uk Kim         {
1059a9d8d09cSJung-uk Kim             AcpiNsSortList (&ReturnObject->Package.Elements[StartIndex],
1060a159c266SJung-uk Kim                 OuterElementCount, SortIndex, SortDirection);
1061a159c266SJung-uk Kim 
1062895f26a9SJung-uk Kim             Info->ReturnFlags |= ACPI_OBJECT_REPAIRED;
1063a159c266SJung-uk Kim 
1064a159c266SJung-uk Kim             ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR,
1065a159c266SJung-uk Kim                 "%s: Repaired unsorted list - now sorted by %s\n",
1066895f26a9SJung-uk Kim                 Info->FullPathname, SortKeyName));
1067a159c266SJung-uk Kim             return (AE_OK);
1068a159c266SJung-uk Kim         }
1069a159c266SJung-uk Kim 
1070a159c266SJung-uk Kim         PreviousValue = (UINT32) ObjDesc->Integer.Value;
1071a159c266SJung-uk Kim         OuterElements++;
1072a159c266SJung-uk Kim     }
1073a159c266SJung-uk Kim 
1074a159c266SJung-uk Kim     return (AE_OK);
1075a159c266SJung-uk Kim }
1076a159c266SJung-uk Kim 
1077a159c266SJung-uk Kim 
1078a159c266SJung-uk Kim /******************************************************************************
1079a159c266SJung-uk Kim  *
1080a159c266SJung-uk Kim  * FUNCTION:    AcpiNsSortList
1081a159c266SJung-uk Kim  *
1082a159c266SJung-uk Kim  * PARAMETERS:  Elements            - Package object element list
1083a159c266SJung-uk Kim  *              Count               - Element count for above
1084a159c266SJung-uk Kim  *              Index               - Sort by which package element
1085a159c266SJung-uk Kim  *              SortDirection       - Ascending or Descending sort
1086a159c266SJung-uk Kim  *
1087a159c266SJung-uk Kim  * RETURN:      None
1088a159c266SJung-uk Kim  *
1089a159c266SJung-uk Kim  * DESCRIPTION: Sort the objects that are in a package element list.
1090a159c266SJung-uk Kim  *
1091a159c266SJung-uk Kim  * NOTE: Assumes that all NULL elements have been removed from the package,
1092a159c266SJung-uk Kim  *       and that all elements have been verified to be of type Integer.
1093a159c266SJung-uk Kim  *
1094a159c266SJung-uk Kim  *****************************************************************************/
1095a159c266SJung-uk Kim 
1096a159c266SJung-uk Kim static void
1097a159c266SJung-uk Kim AcpiNsSortList (
1098a159c266SJung-uk Kim     ACPI_OPERAND_OBJECT     **Elements,
1099a159c266SJung-uk Kim     UINT32                  Count,
1100a159c266SJung-uk Kim     UINT32                  Index,
1101a159c266SJung-uk Kim     UINT8                   SortDirection)
1102a159c266SJung-uk Kim {
1103a159c266SJung-uk Kim     ACPI_OPERAND_OBJECT     *ObjDesc1;
1104a159c266SJung-uk Kim     ACPI_OPERAND_OBJECT     *ObjDesc2;
1105a159c266SJung-uk Kim     ACPI_OPERAND_OBJECT     *TempObj;
1106a159c266SJung-uk Kim     UINT32                  i;
1107a159c266SJung-uk Kim     UINT32                  j;
1108a159c266SJung-uk Kim 
1109a159c266SJung-uk Kim 
1110a159c266SJung-uk Kim     /* Simple bubble sort */
1111a159c266SJung-uk Kim 
1112a159c266SJung-uk Kim     for (i = 1; i < Count; i++)
1113a159c266SJung-uk Kim     {
1114a159c266SJung-uk Kim         for (j = (Count - 1); j >= i; j--)
1115a159c266SJung-uk Kim         {
1116a159c266SJung-uk Kim             ObjDesc1 = Elements[j-1]->Package.Elements[Index];
1117a159c266SJung-uk Kim             ObjDesc2 = Elements[j]->Package.Elements[Index];
1118a159c266SJung-uk Kim 
1119a159c266SJung-uk Kim             if (((SortDirection == ACPI_SORT_ASCENDING) &&
1120a159c266SJung-uk Kim                     (ObjDesc1->Integer.Value > ObjDesc2->Integer.Value)) ||
1121a159c266SJung-uk Kim 
1122a159c266SJung-uk Kim                 ((SortDirection == ACPI_SORT_DESCENDING) &&
1123a159c266SJung-uk Kim                     (ObjDesc1->Integer.Value < ObjDesc2->Integer.Value)))
1124a159c266SJung-uk Kim             {
1125a159c266SJung-uk Kim                 TempObj = Elements[j-1];
1126a159c266SJung-uk Kim                 Elements[j-1] = Elements[j];
1127a159c266SJung-uk Kim                 Elements[j] = TempObj;
1128a159c266SJung-uk Kim             }
1129a159c266SJung-uk Kim         }
1130a159c266SJung-uk Kim     }
1131a159c266SJung-uk Kim }
1132a9d8d09cSJung-uk Kim 
1133a9d8d09cSJung-uk Kim 
1134a9d8d09cSJung-uk Kim /******************************************************************************
1135a9d8d09cSJung-uk Kim  *
1136a9d8d09cSJung-uk Kim  * FUNCTION:    AcpiNsRemoveElement
1137a9d8d09cSJung-uk Kim  *
1138a9d8d09cSJung-uk Kim  * PARAMETERS:  ObjDesc             - Package object element list
1139a9d8d09cSJung-uk Kim  *              Index               - Index of element to remove
1140a9d8d09cSJung-uk Kim  *
1141a9d8d09cSJung-uk Kim  * RETURN:      None
1142a9d8d09cSJung-uk Kim  *
1143a9d8d09cSJung-uk Kim  * DESCRIPTION: Remove the requested element of a package and delete it.
1144a9d8d09cSJung-uk Kim  *
1145a9d8d09cSJung-uk Kim  *****************************************************************************/
1146a9d8d09cSJung-uk Kim 
1147a9d8d09cSJung-uk Kim static void
1148a9d8d09cSJung-uk Kim AcpiNsRemoveElement (
1149a9d8d09cSJung-uk Kim     ACPI_OPERAND_OBJECT     *ObjDesc,
1150a9d8d09cSJung-uk Kim     UINT32                  Index)
1151a9d8d09cSJung-uk Kim {
1152a9d8d09cSJung-uk Kim     ACPI_OPERAND_OBJECT     **Source;
1153a9d8d09cSJung-uk Kim     ACPI_OPERAND_OBJECT     **Dest;
1154a9d8d09cSJung-uk Kim     UINT32                  Count;
1155a9d8d09cSJung-uk Kim     UINT32                  NewCount;
1156a9d8d09cSJung-uk Kim     UINT32                  i;
1157a9d8d09cSJung-uk Kim 
1158a9d8d09cSJung-uk Kim 
1159a9d8d09cSJung-uk Kim     ACPI_FUNCTION_NAME (NsRemoveElement);
1160a9d8d09cSJung-uk Kim 
1161a9d8d09cSJung-uk Kim 
1162a9d8d09cSJung-uk Kim     Count = ObjDesc->Package.Count;
1163a9d8d09cSJung-uk Kim     NewCount = Count - 1;
1164a9d8d09cSJung-uk Kim 
1165a9d8d09cSJung-uk Kim     Source = ObjDesc->Package.Elements;
1166a9d8d09cSJung-uk Kim     Dest = Source;
1167a9d8d09cSJung-uk Kim 
1168a9d8d09cSJung-uk Kim     /* Examine all elements of the package object, remove matched index */
1169a9d8d09cSJung-uk Kim 
1170a9d8d09cSJung-uk Kim     for (i = 0; i < Count; i++)
1171a9d8d09cSJung-uk Kim     {
1172a9d8d09cSJung-uk Kim         if (i == Index)
1173a9d8d09cSJung-uk Kim         {
1174a9d8d09cSJung-uk Kim             AcpiUtRemoveReference (*Source); /* Remove one ref for being in pkg */
1175a9d8d09cSJung-uk Kim             AcpiUtRemoveReference (*Source);
1176a9d8d09cSJung-uk Kim         }
1177a9d8d09cSJung-uk Kim         else
1178a9d8d09cSJung-uk Kim         {
1179a9d8d09cSJung-uk Kim             *Dest = *Source;
1180a9d8d09cSJung-uk Kim             Dest++;
1181a9d8d09cSJung-uk Kim         }
1182f8146b88SJung-uk Kim 
1183a9d8d09cSJung-uk Kim         Source++;
1184a9d8d09cSJung-uk Kim     }
1185a9d8d09cSJung-uk Kim 
1186a9d8d09cSJung-uk Kim     /* NULL terminate list and update the package count */
1187a9d8d09cSJung-uk Kim 
1188a9d8d09cSJung-uk Kim     *Dest = NULL;
1189a9d8d09cSJung-uk Kim     ObjDesc->Package.Count = NewCount;
1190a9d8d09cSJung-uk Kim }
1191