Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /******************************************************************************
  2.  *
  3.  * Module Name: nsrepair2 - Repair for objects returned by specific
  4.  *                          predefined methods
  5.  *
  6.  *****************************************************************************/
  7.  
  8. /******************************************************************************
  9.  *
  10.  * 1. Copyright Notice
  11.  *
  12.  * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp.
  13.  * All rights reserved.
  14.  *
  15.  * 2. License
  16.  *
  17.  * 2.1. This is your license from Intel Corp. under its intellectual property
  18.  * rights.  You may have additional license terms from the party that provided
  19.  * you this software, covering your right to use that party's intellectual
  20.  * property rights.
  21.  *
  22.  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
  23.  * copy of the source code appearing in this file ("Covered Code") an
  24.  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
  25.  * base code distributed originally by Intel ("Original Intel Code") to copy,
  26.  * make derivatives, distribute, use and display any portion of the Covered
  27.  * Code in any form, with the right to sublicense such rights; and
  28.  *
  29.  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
  30.  * license (with the right to sublicense), under only those claims of Intel
  31.  * patents that are infringed by the Original Intel Code, to make, use, sell,
  32.  * offer to sell, and import the Covered Code and derivative works thereof
  33.  * solely to the minimum extent necessary to exercise the above copyright
  34.  * license, and in no event shall the patent license extend to any additions
  35.  * to or modifications of the Original Intel Code.  No other license or right
  36.  * is granted directly or by implication, estoppel or otherwise;
  37.  *
  38.  * The above copyright and patent license is granted only if the following
  39.  * conditions are met:
  40.  *
  41.  * 3. Conditions
  42.  *
  43.  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
  44.  * Redistribution of source code of any substantial portion of the Covered
  45.  * Code or modification with rights to further distribute source must include
  46.  * the above Copyright Notice, the above License, this list of Conditions,
  47.  * and the following Disclaimer and Export Compliance provision.  In addition,
  48.  * Licensee must cause all Covered Code to which Licensee contributes to
  49.  * contain a file documenting the changes Licensee made to create that Covered
  50.  * Code and the date of any change.  Licensee must include in that file the
  51.  * documentation of any changes made by any predecessor Licensee.  Licensee
  52.  * must include a prominent statement that the modification is derived,
  53.  * directly or indirectly, from Original Intel Code.
  54.  *
  55.  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
  56.  * Redistribution of source code of any substantial portion of the Covered
  57.  * Code or modification without rights to further distribute source must
  58.  * include the following Disclaimer and Export Compliance provision in the
  59.  * documentation and/or other materials provided with distribution.  In
  60.  * addition, Licensee may not authorize further sublicense of source of any
  61.  * portion of the Covered Code, and must include terms to the effect that the
  62.  * license from Licensee to its licensee is limited to the intellectual
  63.  * property embodied in the software Licensee provides to its licensee, and
  64.  * not to intellectual property embodied in modifications its licensee may
  65.  * make.
  66.  *
  67.  * 3.3. Redistribution of Executable. Redistribution in executable form of any
  68.  * substantial portion of the Covered Code or modification must reproduce the
  69.  * above Copyright Notice, and the following Disclaimer and Export Compliance
  70.  * provision in the documentation and/or other materials provided with the
  71.  * distribution.
  72.  *
  73.  * 3.4. Intel retains all right, title, and interest in and to the Original
  74.  * Intel Code.
  75.  *
  76.  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
  77.  * Intel shall be used in advertising or otherwise to promote the sale, use or
  78.  * other dealings in products derived from or relating to the Covered Code
  79.  * without prior written authorization from Intel.
  80.  *
  81.  * 4. Disclaimer and Export Compliance
  82.  *
  83.  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
  84.  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
  85.  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
  86.  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
  87.  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
  88.  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
  89.  * PARTICULAR PURPOSE.
  90.  *
  91.  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
  92.  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
  93.  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
  94.  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
  95.  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
  96.  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
  97.  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
  98.  * LIMITED REMEDY.
  99.  *
  100.  * 4.3. Licensee shall not export, either directly or indirectly, any of this
  101.  * software or system incorporating such software without first obtaining any
  102.  * required license or other approval from the U. S. Department of Commerce or
  103.  * any other agency or department of the United States Government.  In the
  104.  * event Licensee exports any such software from the United States or
  105.  * re-exports any such software from a foreign destination, Licensee shall
  106.  * ensure that the distribution and export/re-export of the software is in
  107.  * compliance with all laws, regulations, orders, or other restrictions of the
  108.  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
  109.  * any of its subsidiaries will export/re-export any technical data, process,
  110.  * software, or service, directly or indirectly, to any country for which the
  111.  * United States government or any agency thereof requires an export license,
  112.  * other governmental approval, or letter of assurance, without first obtaining
  113.  * such license, approval or letter.
  114.  *
  115.  *****************************************************************************/
  116.  
  117. #define __NSREPAIR2_C__
  118.  
  119. #include "acpi.h"
  120. #include "accommon.h"
  121. #include "acnamesp.h"
  122.  
  123. #define _COMPONENT          ACPI_NAMESPACE
  124.         ACPI_MODULE_NAME    ("nsrepair2")
  125.  
  126.  
  127. /*
  128.  * Information structure and handler for ACPI predefined names that can
  129.  * be repaired on a per-name basis.
  130.  */
  131. typedef
  132. ACPI_STATUS (*ACPI_REPAIR_FUNCTION) (
  133.     ACPI_PREDEFINED_DATA    *Data,
  134.     ACPI_OPERAND_OBJECT     **ReturnObjectPtr);
  135.  
  136. typedef struct acpi_repair_info
  137. {
  138.     char                    Name[ACPI_NAME_SIZE];
  139.     ACPI_REPAIR_FUNCTION    RepairFunction;
  140.  
  141. } ACPI_REPAIR_INFO;
  142.  
  143.  
  144. /* Local prototypes */
  145.  
  146. static const ACPI_REPAIR_INFO *
  147. AcpiNsMatchRepairableName (
  148.     ACPI_NAMESPACE_NODE     *Node);
  149.  
  150. static ACPI_STATUS
  151. AcpiNsRepair_ALR (
  152.     ACPI_PREDEFINED_DATA    *Data,
  153.     ACPI_OPERAND_OBJECT     **ReturnObjectPtr);
  154.  
  155. static ACPI_STATUS
  156. AcpiNsRepair_FDE (
  157.     ACPI_PREDEFINED_DATA    *Data,
  158.     ACPI_OPERAND_OBJECT     **ReturnObjectPtr);
  159.  
  160. static ACPI_STATUS
  161. AcpiNsRepair_PSS (
  162.     ACPI_PREDEFINED_DATA    *Data,
  163.     ACPI_OPERAND_OBJECT     **ReturnObjectPtr);
  164.  
  165. static ACPI_STATUS
  166. AcpiNsRepair_TSS (
  167.     ACPI_PREDEFINED_DATA    *Data,
  168.     ACPI_OPERAND_OBJECT     **ReturnObjectPtr);
  169.  
  170. static ACPI_STATUS
  171. AcpiNsCheckSortedList (
  172.     ACPI_PREDEFINED_DATA    *Data,
  173.     ACPI_OPERAND_OBJECT     *ReturnObject,
  174.     UINT32                  ExpectedCount,
  175.     UINT32                  SortIndex,
  176.     UINT8                   SortDirection,
  177.     char                    *SortKeyName);
  178.  
  179. static void
  180. AcpiNsSortList (
  181.     ACPI_OPERAND_OBJECT     **Elements,
  182.     UINT32                  Count,
  183.     UINT32                  Index,
  184.     UINT8                   SortDirection);
  185.  
  186. /* Values for SortDirection above */
  187.  
  188. #define ACPI_SORT_ASCENDING     0
  189. #define ACPI_SORT_DESCENDING    1
  190.  
  191.  
  192. /*
  193.  * This table contains the names of the predefined methods for which we can
  194.  * perform more complex repairs.
  195.  *
  196.  * As necessary:
  197.  *
  198.  * _ALR: Sort the list ascending by AmbientIlluminance
  199.  * _FDE: Convert Buffer of BYTEs to a Buffer of DWORDs
  200.  * _GTM: Convert Buffer of BYTEs to a Buffer of DWORDs
  201.  * _PSS: Sort the list descending by Power
  202.  * _TSS: Sort the list descending by Power
  203.  *
  204.  * Names that must be packages, but cannot be sorted:
  205.  *
  206.  * _BCL: Values are tied to the Package index where they appear, and cannot
  207.  * be moved or sorted. These index values are used for _BQC and _BCM.
  208.  * However, we can fix the case where a buffer is returned, by converting
  209.  * it to a Package of integers.
  210.  */
  211. static const ACPI_REPAIR_INFO       AcpiNsRepairableNames[] =
  212. {
  213.     {"_ALR", AcpiNsRepair_ALR},
  214.     {"_FDE", AcpiNsRepair_FDE},
  215.     {"_GTM", AcpiNsRepair_FDE},     /* _GTM has same repair as _FDE */
  216.     {"_PSS", AcpiNsRepair_PSS},
  217.     {"_TSS", AcpiNsRepair_TSS},
  218.     {{0,0,0,0}, NULL}               /* Table terminator */
  219. };
  220.  
  221.  
  222. #define ACPI_FDE_FIELD_COUNT        5
  223. #define ACPI_FDE_BYTE_BUFFER_SIZE   5
  224. #define ACPI_FDE_DWORD_BUFFER_SIZE  (ACPI_FDE_FIELD_COUNT * sizeof (UINT32))
  225.  
  226.  
  227. /******************************************************************************
  228.  *
  229.  * FUNCTION:    AcpiNsComplexRepairs
  230.  *
  231.  * PARAMETERS:  Data                - Pointer to validation data structure
  232.  *              Node                - Namespace node for the method/object
  233.  *              ValidateStatus      - Original status of earlier validation
  234.  *              ReturnObjectPtr     - Pointer to the object returned from the
  235.  *                                    evaluation of a method or object
  236.  *
  237.  * RETURN:      Status. AE_OK if repair was successful. If name is not
  238.  *              matched, ValidateStatus is returned.
  239.  *
  240.  * DESCRIPTION: Attempt to repair/convert a return object of a type that was
  241.  *              not expected.
  242.  *
  243.  *****************************************************************************/
  244.  
  245. ACPI_STATUS
  246. AcpiNsComplexRepairs (
  247.     ACPI_PREDEFINED_DATA    *Data,
  248.     ACPI_NAMESPACE_NODE     *Node,
  249.     ACPI_STATUS             ValidateStatus,
  250.     ACPI_OPERAND_OBJECT     **ReturnObjectPtr)
  251. {
  252.     const ACPI_REPAIR_INFO  *Predefined;
  253.     ACPI_STATUS             Status;
  254.  
  255.  
  256.     /* Check if this name is in the list of repairable names */
  257.  
  258.     Predefined = AcpiNsMatchRepairableName (Node);
  259.     if (!Predefined)
  260.     {
  261.         return (ValidateStatus);
  262.     }
  263.  
  264.     Status = Predefined->RepairFunction (Data, ReturnObjectPtr);
  265.     return (Status);
  266. }
  267.  
  268.  
  269. /******************************************************************************
  270.  *
  271.  * FUNCTION:    AcpiNsMatchRepairableName
  272.  *
  273.  * PARAMETERS:  Node                - Namespace node for the method/object
  274.  *
  275.  * RETURN:      Pointer to entry in repair table. NULL indicates not found.
  276.  *
  277.  * DESCRIPTION: Check an object name against the repairable object list.
  278.  *
  279.  *****************************************************************************/
  280.  
  281. static const ACPI_REPAIR_INFO *
  282. AcpiNsMatchRepairableName (
  283.     ACPI_NAMESPACE_NODE     *Node)
  284. {
  285.     const ACPI_REPAIR_INFO  *ThisName;
  286.  
  287.  
  288.     /* Search info table for a repairable predefined method/object name */
  289.  
  290.     ThisName = AcpiNsRepairableNames;
  291.     while (ThisName->RepairFunction)
  292.     {
  293.         if (ACPI_COMPARE_NAME (Node->Name.Ascii, ThisName->Name))
  294.         {
  295.             return (ThisName);
  296.         }
  297.         ThisName++;
  298.     }
  299.  
  300.     return (NULL); /* Not found */
  301. }
  302.  
  303.  
  304. /******************************************************************************
  305.  *
  306.  * FUNCTION:    AcpiNsRepair_ALR
  307.  *
  308.  * PARAMETERS:  Data                - Pointer to validation data structure
  309.  *              ReturnObjectPtr     - Pointer to the object returned from the
  310.  *                                    evaluation of a method or object
  311.  *
  312.  * RETURN:      Status. AE_OK if object is OK or was repaired successfully
  313.  *
  314.  * DESCRIPTION: Repair for the _ALR object. If necessary, sort the object list
  315.  *              ascending by the ambient illuminance values.
  316.  *
  317.  *****************************************************************************/
  318.  
  319. static ACPI_STATUS
  320. AcpiNsRepair_ALR (
  321.     ACPI_PREDEFINED_DATA    *Data,
  322.     ACPI_OPERAND_OBJECT     **ReturnObjectPtr)
  323. {
  324.     ACPI_OPERAND_OBJECT     *ReturnObject = *ReturnObjectPtr;
  325.     ACPI_STATUS             Status;
  326.  
  327.  
  328.     Status = AcpiNsCheckSortedList (Data, ReturnObject, 2, 1,
  329.                 ACPI_SORT_ASCENDING, "AmbientIlluminance");
  330.  
  331.     return (Status);
  332. }
  333.  
  334.  
  335. /******************************************************************************
  336.  *
  337.  * FUNCTION:    AcpiNsRepair_FDE
  338.  *
  339.  * PARAMETERS:  Data                - Pointer to validation data structure
  340.  *              ReturnObjectPtr     - Pointer to the object returned from the
  341.  *                                    evaluation of a method or object
  342.  *
  343.  * RETURN:      Status. AE_OK if object is OK or was repaired successfully
  344.  *
  345.  * DESCRIPTION: Repair for the _FDE and _GTM objects. The expected return
  346.  *              value is a Buffer of 5 DWORDs. This function repairs a common
  347.  *              problem where the return value is a Buffer of BYTEs, not
  348.  *              DWORDs.
  349.  *
  350.  *****************************************************************************/
  351.  
  352. static ACPI_STATUS
  353. AcpiNsRepair_FDE (
  354.     ACPI_PREDEFINED_DATA    *Data,
  355.     ACPI_OPERAND_OBJECT     **ReturnObjectPtr)
  356. {
  357.     ACPI_OPERAND_OBJECT     *ReturnObject = *ReturnObjectPtr;
  358.     ACPI_OPERAND_OBJECT     *BufferObject;
  359.     UINT8                   *ByteBuffer;
  360.     UINT32                  *DwordBuffer;
  361.     UINT32                  i;
  362.  
  363.  
  364.     ACPI_FUNCTION_NAME (NsRepair_FDE);
  365.  
  366.  
  367.     switch (ReturnObject->Common.Type)
  368.     {
  369.     case ACPI_TYPE_BUFFER:
  370.  
  371.         /* This is the expected type. Length should be (at least) 5 DWORDs */
  372.  
  373.         if (ReturnObject->Buffer.Length >= ACPI_FDE_DWORD_BUFFER_SIZE)
  374.         {
  375.             return (AE_OK);
  376.         }
  377.  
  378.         /* We can only repair if we have exactly 5 BYTEs */
  379.  
  380.         if (ReturnObject->Buffer.Length != ACPI_FDE_BYTE_BUFFER_SIZE)
  381.         {
  382.             ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
  383.                 "Incorrect return buffer length %u, expected %u",
  384.                 ReturnObject->Buffer.Length, ACPI_FDE_DWORD_BUFFER_SIZE));
  385.  
  386.             return (AE_AML_OPERAND_TYPE);
  387.         }
  388.  
  389.         /* Create the new (larger) buffer object */
  390.  
  391.         BufferObject = AcpiUtCreateBufferObject (ACPI_FDE_DWORD_BUFFER_SIZE);
  392.         if (!BufferObject)
  393.         {
  394.             return (AE_NO_MEMORY);
  395.         }
  396.  
  397.         /* Expand each byte to a DWORD */
  398.  
  399.         ByteBuffer = ReturnObject->Buffer.Pointer;
  400.         DwordBuffer = ACPI_CAST_PTR (UINT32, BufferObject->Buffer.Pointer);
  401.  
  402.         for (i = 0; i < ACPI_FDE_FIELD_COUNT; i++)
  403.         {
  404.             *DwordBuffer = (UINT32) *ByteBuffer;
  405.             DwordBuffer++;
  406.             ByteBuffer++;
  407.         }
  408.  
  409.         ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR,
  410.             "%s Expanded Byte Buffer to expected DWord Buffer\n",
  411.             Data->Pathname));
  412.         break;
  413.  
  414.     default:
  415.         return (AE_AML_OPERAND_TYPE);
  416.     }
  417.  
  418.     /* Delete the original return object, return the new buffer object */
  419.  
  420.     AcpiUtRemoveReference (ReturnObject);
  421.     *ReturnObjectPtr = BufferObject;
  422.  
  423.     Data->Flags |= ACPI_OBJECT_REPAIRED;
  424.     return (AE_OK);
  425. }
  426.  
  427.  
  428. /******************************************************************************
  429.  *
  430.  * FUNCTION:    AcpiNsRepair_TSS
  431.  *
  432.  * PARAMETERS:  Data                - Pointer to validation data structure
  433.  *              ReturnObjectPtr     - Pointer to the object returned from the
  434.  *                                    evaluation of a method or object
  435.  *
  436.  * RETURN:      Status. AE_OK if object is OK or was repaired successfully
  437.  *
  438.  * DESCRIPTION: Repair for the _TSS object. If necessary, sort the object list
  439.  *              descending by the power dissipation values.
  440.  *
  441.  *****************************************************************************/
  442.  
  443. static ACPI_STATUS
  444. AcpiNsRepair_TSS (
  445.     ACPI_PREDEFINED_DATA    *Data,
  446.     ACPI_OPERAND_OBJECT     **ReturnObjectPtr)
  447. {
  448.     ACPI_OPERAND_OBJECT     *ReturnObject = *ReturnObjectPtr;
  449.     ACPI_STATUS             Status;
  450.  
  451.  
  452.     Status = AcpiNsCheckSortedList (Data, ReturnObject, 5, 1,
  453.                 ACPI_SORT_DESCENDING, "PowerDissipation");
  454.  
  455.     return (Status);
  456. }
  457.  
  458.  
  459. /******************************************************************************
  460.  *
  461.  * FUNCTION:    AcpiNsRepair_PSS
  462.  *
  463.  * PARAMETERS:  Data                - Pointer to validation data structure
  464.  *              ReturnObjectPtr     - Pointer to the object returned from the
  465.  *                                    evaluation of a method or object
  466.  *
  467.  * RETURN:      Status. AE_OK if object is OK or was repaired successfully
  468.  *
  469.  * DESCRIPTION: Repair for the _PSS object. If necessary, sort the object list
  470.  *              by the CPU frequencies. Check that the power dissipation values
  471.  *              are all proportional to CPU frequency (i.e., sorting by
  472.  *              frequency should be the same as sorting by power.)
  473.  *
  474.  *****************************************************************************/
  475.  
  476. static ACPI_STATUS
  477. AcpiNsRepair_PSS (
  478.     ACPI_PREDEFINED_DATA    *Data,
  479.     ACPI_OPERAND_OBJECT     **ReturnObjectPtr)
  480. {
  481.     ACPI_OPERAND_OBJECT     *ReturnObject = *ReturnObjectPtr;
  482.     ACPI_OPERAND_OBJECT     **OuterElements;
  483.     UINT32                  OuterElementCount;
  484.     ACPI_OPERAND_OBJECT     **Elements;
  485.     ACPI_OPERAND_OBJECT     *ObjDesc;
  486.     UINT32                  PreviousValue;
  487.     ACPI_STATUS             Status;
  488.     UINT32                  i;
  489.  
  490.  
  491.     /*
  492.      * Entries (sub-packages) in the _PSS Package must be sorted by power
  493.      * dissipation, in descending order. If it appears that the list is
  494.      * incorrectly sorted, sort it. We sort by CpuFrequency, since this
  495.      * should be proportional to the power.
  496.      */
  497.     Status =AcpiNsCheckSortedList (Data, ReturnObject, 6, 0,
  498.                 ACPI_SORT_DESCENDING, "CpuFrequency");
  499.     if (ACPI_FAILURE (Status))
  500.     {
  501.         return (Status);
  502.     }
  503.  
  504.     /*
  505.      * We now know the list is correctly sorted by CPU frequency. Check if
  506.      * the power dissipation values are proportional.
  507.      */
  508.     PreviousValue = ACPI_UINT32_MAX;
  509.     OuterElements = ReturnObject->Package.Elements;
  510.     OuterElementCount = ReturnObject->Package.Count;
  511.  
  512.     for (i = 0; i < OuterElementCount; i++)
  513.     {
  514.         Elements = (*OuterElements)->Package.Elements;
  515.         ObjDesc = Elements[1]; /* Index1 = PowerDissipation */
  516.  
  517.         if ((UINT32) ObjDesc->Integer.Value > PreviousValue)
  518.         {
  519.             ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
  520.                 "SubPackage[%u,%u] - suspicious power dissipation values",
  521.                 i-1, i));
  522.         }
  523.  
  524.         PreviousValue = (UINT32) ObjDesc->Integer.Value;
  525.         OuterElements++;
  526.     }
  527.  
  528.     return (AE_OK);
  529. }
  530.  
  531.  
  532. /******************************************************************************
  533.  *
  534.  * FUNCTION:    AcpiNsCheckSortedList
  535.  *
  536.  * PARAMETERS:  Data                - Pointer to validation data structure
  537.  *              ReturnObject        - Pointer to the top-level returned object
  538.  *              ExpectedCount       - Minimum length of each sub-package
  539.  *              SortIndex           - Sub-package entry to sort on
  540.  *              SortDirection       - Ascending or descending
  541.  *              SortKeyName         - Name of the SortIndex field
  542.  *
  543.  * RETURN:      Status. AE_OK if the list is valid and is sorted correctly or
  544.  *              has been repaired by sorting the list.
  545.  *
  546.  * DESCRIPTION: Check if the package list is valid and sorted correctly by the
  547.  *              SortIndex. If not, then sort the list.
  548.  *
  549.  *****************************************************************************/
  550.  
  551. static ACPI_STATUS
  552. AcpiNsCheckSortedList (
  553.     ACPI_PREDEFINED_DATA    *Data,
  554.     ACPI_OPERAND_OBJECT     *ReturnObject,
  555.     UINT32                  ExpectedCount,
  556.     UINT32                  SortIndex,
  557.     UINT8                   SortDirection,
  558.     char                    *SortKeyName)
  559. {
  560.     UINT32                  OuterElementCount;
  561.     ACPI_OPERAND_OBJECT     **OuterElements;
  562.     ACPI_OPERAND_OBJECT     **Elements;
  563.     ACPI_OPERAND_OBJECT     *ObjDesc;
  564.     UINT32                  i;
  565.     UINT32                  PreviousValue;
  566.  
  567.  
  568.     ACPI_FUNCTION_NAME (NsCheckSortedList);
  569.  
  570.  
  571.     /* The top-level object must be a package */
  572.  
  573.     if (ReturnObject->Common.Type != ACPI_TYPE_PACKAGE)
  574.     {
  575.         return (AE_AML_OPERAND_TYPE);
  576.     }
  577.  
  578.     /*
  579.      * NOTE: assumes list of sub-packages contains no NULL elements.
  580.      * Any NULL elements should have been removed by earlier call
  581.      * to AcpiNsRemoveNullElements.
  582.      */
  583.     OuterElements = ReturnObject->Package.Elements;
  584.     OuterElementCount = ReturnObject->Package.Count;
  585.     if (!OuterElementCount)
  586.     {
  587.         return (AE_AML_PACKAGE_LIMIT);
  588.     }
  589.  
  590.     PreviousValue = 0;
  591.     if (SortDirection == ACPI_SORT_DESCENDING)
  592.     {
  593.         PreviousValue = ACPI_UINT32_MAX;
  594.     }
  595.  
  596.     /* Examine each subpackage */
  597.  
  598.     for (i = 0; i < OuterElementCount; i++)
  599.     {
  600.         /* Each element of the top-level package must also be a package */
  601.  
  602.         if ((*OuterElements)->Common.Type != ACPI_TYPE_PACKAGE)
  603.         {
  604.             return (AE_AML_OPERAND_TYPE);
  605.         }
  606.  
  607.         /* Each sub-package must have the minimum length */
  608.  
  609.         if ((*OuterElements)->Package.Count < ExpectedCount)
  610.         {
  611.             return (AE_AML_PACKAGE_LIMIT);
  612.         }
  613.  
  614.         Elements = (*OuterElements)->Package.Elements;
  615.         ObjDesc = Elements[SortIndex];
  616.  
  617.         if (ObjDesc->Common.Type != ACPI_TYPE_INTEGER)
  618.         {
  619.             return (AE_AML_OPERAND_TYPE);
  620.         }
  621.  
  622.         /*
  623.          * The list must be sorted in the specified order. If we detect a
  624.          * discrepancy, sort the entire list.
  625.          */
  626.         if (((SortDirection == ACPI_SORT_ASCENDING) &&
  627.                 (ObjDesc->Integer.Value < PreviousValue)) ||
  628.             ((SortDirection == ACPI_SORT_DESCENDING) &&
  629.                 (ObjDesc->Integer.Value > PreviousValue)))
  630.         {
  631.             AcpiNsSortList (ReturnObject->Package.Elements,
  632.                 OuterElementCount, SortIndex, SortDirection);
  633.  
  634.             Data->Flags |= ACPI_OBJECT_REPAIRED;
  635.  
  636.             ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR,
  637.                 "%s: Repaired unsorted list - now sorted by %s\n",
  638.                 Data->Pathname, SortKeyName));
  639.             return (AE_OK);
  640.         }
  641.  
  642.         PreviousValue = (UINT32) ObjDesc->Integer.Value;
  643.         OuterElements++;
  644.     }
  645.  
  646.     return (AE_OK);
  647. }
  648.  
  649.  
  650. /******************************************************************************
  651.  *
  652.  * FUNCTION:    AcpiNsSortList
  653.  *
  654.  * PARAMETERS:  Elements            - Package object element list
  655.  *              Count               - Element count for above
  656.  *              Index               - Sort by which package element
  657.  *              SortDirection       - Ascending or Descending sort
  658.  *
  659.  * RETURN:      None
  660.  *
  661.  * DESCRIPTION: Sort the objects that are in a package element list.
  662.  *
  663.  * NOTE: Assumes that all NULL elements have been removed from the package,
  664.  *       and that all elements have been verified to be of type Integer.
  665.  *
  666.  *****************************************************************************/
  667.  
  668. static void
  669. AcpiNsSortList (
  670.     ACPI_OPERAND_OBJECT     **Elements,
  671.     UINT32                  Count,
  672.     UINT32                  Index,
  673.     UINT8                   SortDirection)
  674. {
  675.     ACPI_OPERAND_OBJECT     *ObjDesc1;
  676.     ACPI_OPERAND_OBJECT     *ObjDesc2;
  677.     ACPI_OPERAND_OBJECT     *TempObj;
  678.     UINT32                  i;
  679.     UINT32                  j;
  680.  
  681.  
  682.     /* Simple bubble sort */
  683.  
  684.     for (i = 1; i < Count; i++)
  685.     {
  686.         for (j = (Count - 1); j >= i; j--)
  687.         {
  688.             ObjDesc1 = Elements[j-1]->Package.Elements[Index];
  689.             ObjDesc2 = Elements[j]->Package.Elements[Index];
  690.  
  691.             if (((SortDirection == ACPI_SORT_ASCENDING) &&
  692.                     (ObjDesc1->Integer.Value > ObjDesc2->Integer.Value)) ||
  693.  
  694.                 ((SortDirection == ACPI_SORT_DESCENDING) &&
  695.                     (ObjDesc1->Integer.Value < ObjDesc2->Integer.Value)))
  696.             {
  697.                 TempObj = Elements[j-1];
  698.                 Elements[j-1] = Elements[j];
  699.                 Elements[j] = TempObj;
  700.             }
  701.         }
  702.     }
  703. }
  704.