Subversion Repositories Kolibri OS

Rev

Rev 1498 | 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 - 2011, 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_CID (
  157.     ACPI_PREDEFINED_DATA    *Data,
  158.     ACPI_OPERAND_OBJECT     **ReturnObjectPtr);
  159.  
  160. static ACPI_STATUS
  161. AcpiNsRepair_FDE (
  162.     ACPI_PREDEFINED_DATA    *Data,
  163.     ACPI_OPERAND_OBJECT     **ReturnObjectPtr);
  164.  
  165. static ACPI_STATUS
  166. AcpiNsRepair_HID (
  167.     ACPI_PREDEFINED_DATA    *Data,
  168.     ACPI_OPERAND_OBJECT     **ReturnObjectPtr);
  169.  
  170. static ACPI_STATUS
  171. AcpiNsRepair_PSS (
  172.     ACPI_PREDEFINED_DATA    *Data,
  173.     ACPI_OPERAND_OBJECT     **ReturnObjectPtr);
  174.  
  175. static ACPI_STATUS
  176. AcpiNsRepair_TSS (
  177.     ACPI_PREDEFINED_DATA    *Data,
  178.     ACPI_OPERAND_OBJECT     **ReturnObjectPtr);
  179.  
  180. static ACPI_STATUS
  181. AcpiNsCheckSortedList (
  182.     ACPI_PREDEFINED_DATA    *Data,
  183.     ACPI_OPERAND_OBJECT     *ReturnObject,
  184.     UINT32                  ExpectedCount,
  185.     UINT32                  SortIndex,
  186.     UINT8                   SortDirection,
  187.     char                    *SortKeyName);
  188.  
  189. static void
  190. AcpiNsSortList (
  191.     ACPI_OPERAND_OBJECT     **Elements,
  192.     UINT32                  Count,
  193.     UINT32                  Index,
  194.     UINT8                   SortDirection);
  195.  
  196. /* Values for SortDirection above */
  197.  
  198. #define ACPI_SORT_ASCENDING     0
  199. #define ACPI_SORT_DESCENDING    1
  200.  
  201.  
  202. /*
  203.  * This table contains the names of the predefined methods for which we can
  204.  * perform more complex repairs.
  205.  *
  206.  * As necessary:
  207.  *
  208.  * _ALR: Sort the list ascending by AmbientIlluminance
  209.  * _CID: Strings: uppercase all, remove any leading asterisk
  210.  * _FDE: Convert Buffer of BYTEs to a Buffer of DWORDs
  211.  * _GTM: Convert Buffer of BYTEs to a Buffer of DWORDs
  212.  * _HID: Strings: uppercase all, remove any leading asterisk
  213.  * _PSS: Sort the list descending by Power
  214.  * _TSS: Sort the list descending by Power
  215.  *
  216.  * Names that must be packages, but cannot be sorted:
  217.  *
  218.  * _BCL: Values are tied to the Package index where they appear, and cannot
  219.  * be moved or sorted. These index values are used for _BQC and _BCM.
  220.  * However, we can fix the case where a buffer is returned, by converting
  221.  * it to a Package of integers.
  222.  */
  223. static const ACPI_REPAIR_INFO       AcpiNsRepairableNames[] =
  224. {
  225.     {"_ALR", AcpiNsRepair_ALR},
  226.     {"_CID", AcpiNsRepair_CID},
  227.     {"_FDE", AcpiNsRepair_FDE},
  228.     {"_GTM", AcpiNsRepair_FDE},     /* _GTM has same repair as _FDE */
  229.     {"_HID", AcpiNsRepair_HID},
  230.     {"_PSS", AcpiNsRepair_PSS},
  231.     {"_TSS", AcpiNsRepair_TSS},
  232.     {{0,0,0,0}, NULL}               /* Table terminator */
  233. };
  234.  
  235.  
  236. #define ACPI_FDE_FIELD_COUNT        5
  237. #define ACPI_FDE_BYTE_BUFFER_SIZE   5
  238. #define ACPI_FDE_DWORD_BUFFER_SIZE  (ACPI_FDE_FIELD_COUNT * sizeof (UINT32))
  239.  
  240.  
  241. /******************************************************************************
  242.  *
  243.  * FUNCTION:    AcpiNsComplexRepairs
  244.  *
  245.  * PARAMETERS:  Data                - Pointer to validation data structure
  246.  *              Node                - Namespace node for the method/object
  247.  *              ValidateStatus      - Original status of earlier validation
  248.  *              ReturnObjectPtr     - Pointer to the object returned from the
  249.  *                                    evaluation of a method or object
  250.  *
  251.  * RETURN:      Status. AE_OK if repair was successful. If name is not
  252.  *              matched, ValidateStatus is returned.
  253.  *
  254.  * DESCRIPTION: Attempt to repair/convert a return object of a type that was
  255.  *              not expected.
  256.  *
  257.  *****************************************************************************/
  258.  
  259. ACPI_STATUS
  260. AcpiNsComplexRepairs (
  261.     ACPI_PREDEFINED_DATA    *Data,
  262.     ACPI_NAMESPACE_NODE     *Node,
  263.     ACPI_STATUS             ValidateStatus,
  264.     ACPI_OPERAND_OBJECT     **ReturnObjectPtr)
  265. {
  266.     const ACPI_REPAIR_INFO  *Predefined;
  267.     ACPI_STATUS             Status;
  268.  
  269.  
  270.     /* Check if this name is in the list of repairable names */
  271.  
  272.     Predefined = AcpiNsMatchRepairableName (Node);
  273.     if (!Predefined)
  274.     {
  275.         return (ValidateStatus);
  276.     }
  277.  
  278.     Status = Predefined->RepairFunction (Data, ReturnObjectPtr);
  279.     return (Status);
  280. }
  281.  
  282.  
  283. /******************************************************************************
  284.  *
  285.  * FUNCTION:    AcpiNsMatchRepairableName
  286.  *
  287.  * PARAMETERS:  Node                - Namespace node for the method/object
  288.  *
  289.  * RETURN:      Pointer to entry in repair table. NULL indicates not found.
  290.  *
  291.  * DESCRIPTION: Check an object name against the repairable object list.
  292.  *
  293.  *****************************************************************************/
  294.  
  295. static const ACPI_REPAIR_INFO *
  296. AcpiNsMatchRepairableName (
  297.     ACPI_NAMESPACE_NODE     *Node)
  298. {
  299.     const ACPI_REPAIR_INFO  *ThisName;
  300.  
  301.  
  302.     /* Search info table for a repairable predefined method/object name */
  303.  
  304.     ThisName = AcpiNsRepairableNames;
  305.     while (ThisName->RepairFunction)
  306.     {
  307.         if (ACPI_COMPARE_NAME (Node->Name.Ascii, ThisName->Name))
  308.         {
  309.             return (ThisName);
  310.         }
  311.         ThisName++;
  312.     }
  313.  
  314.     return (NULL); /* Not found */
  315. }
  316.  
  317.  
  318. /******************************************************************************
  319.  *
  320.  * FUNCTION:    AcpiNsRepair_ALR
  321.  *
  322.  * PARAMETERS:  Data                - Pointer to validation data structure
  323.  *              ReturnObjectPtr     - Pointer to the object returned from the
  324.  *                                    evaluation of a method or object
  325.  *
  326.  * RETURN:      Status. AE_OK if object is OK or was repaired successfully
  327.  *
  328.  * DESCRIPTION: Repair for the _ALR object. If necessary, sort the object list
  329.  *              ascending by the ambient illuminance values.
  330.  *
  331.  *****************************************************************************/
  332.  
  333. static ACPI_STATUS
  334. AcpiNsRepair_ALR (
  335.     ACPI_PREDEFINED_DATA    *Data,
  336.     ACPI_OPERAND_OBJECT     **ReturnObjectPtr)
  337. {
  338.     ACPI_OPERAND_OBJECT     *ReturnObject = *ReturnObjectPtr;
  339.     ACPI_STATUS             Status;
  340.  
  341.  
  342.     Status = AcpiNsCheckSortedList (Data, ReturnObject, 2, 1,
  343.                 ACPI_SORT_ASCENDING, "AmbientIlluminance");
  344.  
  345.     return (Status);
  346. }
  347.  
  348.  
  349. /******************************************************************************
  350.  *
  351.  * FUNCTION:    AcpiNsRepair_FDE
  352.  *
  353.  * PARAMETERS:  Data                - Pointer to validation data structure
  354.  *              ReturnObjectPtr     - Pointer to the object returned from the
  355.  *                                    evaluation of a method or object
  356.  *
  357.  * RETURN:      Status. AE_OK if object is OK or was repaired successfully
  358.  *
  359.  * DESCRIPTION: Repair for the _FDE and _GTM objects. The expected return
  360.  *              value is a Buffer of 5 DWORDs. This function repairs a common
  361.  *              problem where the return value is a Buffer of BYTEs, not
  362.  *              DWORDs.
  363.  *
  364.  *****************************************************************************/
  365.  
  366. static ACPI_STATUS
  367. AcpiNsRepair_FDE (
  368.     ACPI_PREDEFINED_DATA    *Data,
  369.     ACPI_OPERAND_OBJECT     **ReturnObjectPtr)
  370. {
  371.     ACPI_OPERAND_OBJECT     *ReturnObject = *ReturnObjectPtr;
  372.     ACPI_OPERAND_OBJECT     *BufferObject;
  373.     UINT8                   *ByteBuffer;
  374.     UINT32                  *DwordBuffer;
  375.     UINT32                  i;
  376.  
  377.  
  378.     ACPI_FUNCTION_NAME (NsRepair_FDE);
  379.  
  380.  
  381.     switch (ReturnObject->Common.Type)
  382.     {
  383.     case ACPI_TYPE_BUFFER:
  384.  
  385.         /* This is the expected type. Length should be (at least) 5 DWORDs */
  386.  
  387.         if (ReturnObject->Buffer.Length >= ACPI_FDE_DWORD_BUFFER_SIZE)
  388.         {
  389.             return (AE_OK);
  390.         }
  391.  
  392.         /* We can only repair if we have exactly 5 BYTEs */
  393.  
  394.         if (ReturnObject->Buffer.Length != ACPI_FDE_BYTE_BUFFER_SIZE)
  395.         {
  396.             ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
  397.                 "Incorrect return buffer length %u, expected %u",
  398.                 ReturnObject->Buffer.Length, ACPI_FDE_DWORD_BUFFER_SIZE));
  399.  
  400.             return (AE_AML_OPERAND_TYPE);
  401.         }
  402.  
  403.         /* Create the new (larger) buffer object */
  404.  
  405.         BufferObject = AcpiUtCreateBufferObject (ACPI_FDE_DWORD_BUFFER_SIZE);
  406.         if (!BufferObject)
  407.         {
  408.             return (AE_NO_MEMORY);
  409.         }
  410.  
  411.         /* Expand each byte to a DWORD */
  412.  
  413.         ByteBuffer = ReturnObject->Buffer.Pointer;
  414.         DwordBuffer = ACPI_CAST_PTR (UINT32, BufferObject->Buffer.Pointer);
  415.  
  416.         for (i = 0; i < ACPI_FDE_FIELD_COUNT; i++)
  417.         {
  418.             *DwordBuffer = (UINT32) *ByteBuffer;
  419.             DwordBuffer++;
  420.             ByteBuffer++;
  421.         }
  422.  
  423.         ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR,
  424.             "%s Expanded Byte Buffer to expected DWord Buffer\n",
  425.             Data->Pathname));
  426.         break;
  427.  
  428.     default:
  429.         return (AE_AML_OPERAND_TYPE);
  430.     }
  431.  
  432.     /* Delete the original return object, return the new buffer object */
  433.  
  434.     AcpiUtRemoveReference (ReturnObject);
  435.     *ReturnObjectPtr = BufferObject;
  436.  
  437.     Data->Flags |= ACPI_OBJECT_REPAIRED;
  438.     return (AE_OK);
  439. }
  440.  
  441.  
  442. /******************************************************************************
  443.  *
  444.  * FUNCTION:    AcpiNsRepair_CID
  445.  *
  446.  * PARAMETERS:  Data                - Pointer to validation data structure
  447.  *              ReturnObjectPtr     - Pointer to the object returned from the
  448.  *                                    evaluation of a method or object
  449.  *
  450.  * RETURN:      Status. AE_OK if object is OK or was repaired successfully
  451.  *
  452.  * DESCRIPTION: Repair for the _CID object. If a string, ensure that all
  453.  *              letters are uppercase and that there is no leading asterisk.
  454.  *              If a Package, ensure same for all string elements.
  455.  *
  456.  *****************************************************************************/
  457.  
  458. static ACPI_STATUS
  459. AcpiNsRepair_CID (
  460.     ACPI_PREDEFINED_DATA    *Data,
  461.     ACPI_OPERAND_OBJECT     **ReturnObjectPtr)
  462. {
  463.     ACPI_STATUS             Status;
  464.     ACPI_OPERAND_OBJECT     *ReturnObject = *ReturnObjectPtr;
  465.     ACPI_OPERAND_OBJECT     **ElementPtr;
  466.     ACPI_OPERAND_OBJECT     *OriginalElement;
  467.     UINT16                  OriginalRefCount;
  468.     UINT32                  i;
  469.  
  470.  
  471.     /* Check for _CID as a simple string */
  472.  
  473.     if (ReturnObject->Common.Type == ACPI_TYPE_STRING)
  474.     {
  475.         Status = AcpiNsRepair_HID (Data, ReturnObjectPtr);
  476.         return (Status);
  477.     }
  478.  
  479.     /* Exit if not a Package */
  480.  
  481.     if (ReturnObject->Common.Type != ACPI_TYPE_PACKAGE)
  482.     {
  483.         return (AE_OK);
  484.     }
  485.  
  486.     /* Examine each element of the _CID package */
  487.  
  488.     ElementPtr = ReturnObject->Package.Elements;
  489.     for (i = 0; i < ReturnObject->Package.Count; i++)
  490.     {
  491.         OriginalElement = *ElementPtr;
  492.         OriginalRefCount = OriginalElement->Common.ReferenceCount;
  493.  
  494.         Status = AcpiNsRepair_HID (Data, ElementPtr);
  495.         if (ACPI_FAILURE (Status))
  496.         {
  497.             return (Status);
  498.         }
  499.  
  500.         /* Take care with reference counts */
  501.  
  502.         if (OriginalElement != *ElementPtr)
  503.         {
  504.             /* Element was replaced */
  505.  
  506.             (*ElementPtr)->Common.ReferenceCount =
  507.                 OriginalRefCount;
  508.  
  509.             AcpiUtRemoveReference (OriginalElement);
  510.         }
  511.  
  512.         ElementPtr++;
  513.     }
  514.  
  515.     return (AE_OK);
  516. }
  517.  
  518.  
  519. /******************************************************************************
  520.  *
  521.  * FUNCTION:    AcpiNsRepair_HID
  522.  *
  523.  * PARAMETERS:  Data                - Pointer to validation data structure
  524.  *              ReturnObjectPtr     - Pointer to the object returned from the
  525.  *                                    evaluation of a method or object
  526.  *
  527.  * RETURN:      Status. AE_OK if object is OK or was repaired successfully
  528.  *
  529.  * DESCRIPTION: Repair for the _HID object. If a string, ensure that all
  530.  *              letters are uppercase and that there is no leading asterisk.
  531.  *
  532.  *****************************************************************************/
  533.  
  534. static ACPI_STATUS
  535. AcpiNsRepair_HID (
  536.     ACPI_PREDEFINED_DATA    *Data,
  537.     ACPI_OPERAND_OBJECT     **ReturnObjectPtr)
  538. {
  539.     ACPI_OPERAND_OBJECT     *ReturnObject = *ReturnObjectPtr;
  540.     ACPI_OPERAND_OBJECT     *NewString;
  541.     char                    *Source;
  542.     char                    *Dest;
  543.  
  544.  
  545.     ACPI_FUNCTION_NAME (NsRepair_HID);
  546.  
  547.  
  548.     /* We only care about string _HID objects (not integers) */
  549.  
  550.     if (ReturnObject->Common.Type != ACPI_TYPE_STRING)
  551.     {
  552.         return (AE_OK);
  553.     }
  554.  
  555.     if (ReturnObject->String.Length == 0)
  556.     {
  557.         ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
  558.             "Invalid zero-length _HID or _CID string"));
  559.  
  560.         /* Return AE_OK anyway, let driver handle it */
  561.  
  562.         Data->Flags |= ACPI_OBJECT_REPAIRED;
  563.         return (AE_OK);
  564.     }
  565.  
  566.     /* It is simplest to always create a new string object */
  567.  
  568.     NewString = AcpiUtCreateStringObject (ReturnObject->String.Length);
  569.     if (!NewString)
  570.     {
  571.         return (AE_NO_MEMORY);
  572.     }
  573.  
  574.     /*
  575.      * Remove a leading asterisk if present. For some unknown reason, there
  576.      * are many machines in the field that contains IDs like this.
  577.      *
  578.      * Examples: "*PNP0C03", "*ACPI0003"
  579.      */
  580.     Source = ReturnObject->String.Pointer;
  581.     if (*Source == '*')
  582.     {
  583.         Source++;
  584.         NewString->String.Length--;
  585.  
  586.         ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR,
  587.             "%s: Removed invalid leading asterisk\n", Data->Pathname));
  588.     }
  589.  
  590.     /*
  591.      * Copy and uppercase the string. From the ACPI specification:
  592.      *
  593.      * A valid PNP ID must be of the form "AAA####" where A is an uppercase
  594.      * letter and # is a hex digit. A valid ACPI ID must be of the form
  595.      * "ACPI####" where # is a hex digit.
  596.      */
  597.     for (Dest = NewString->String.Pointer; *Source; Dest++, Source++)
  598.     {
  599.         *Dest = (char) ACPI_TOUPPER (*Source);
  600.     }
  601.  
  602.     AcpiUtRemoveReference (ReturnObject);
  603.     *ReturnObjectPtr = NewString;
  604.     return (AE_OK);
  605. }
  606.  
  607.  
  608. /******************************************************************************
  609.  *
  610.  * FUNCTION:    AcpiNsRepair_TSS
  611.  *
  612.  * PARAMETERS:  Data                - Pointer to validation data structure
  613.  *              ReturnObjectPtr     - Pointer to the object returned from the
  614.  *                                    evaluation of a method or object
  615.  *
  616.  * RETURN:      Status. AE_OK if object is OK or was repaired successfully
  617.  *
  618.  * DESCRIPTION: Repair for the _TSS object. If necessary, sort the object list
  619.  *              descending by the power dissipation values.
  620.  *
  621.  *****************************************************************************/
  622.  
  623. static ACPI_STATUS
  624. AcpiNsRepair_TSS (
  625.     ACPI_PREDEFINED_DATA    *Data,
  626.     ACPI_OPERAND_OBJECT     **ReturnObjectPtr)
  627. {
  628.     ACPI_OPERAND_OBJECT     *ReturnObject = *ReturnObjectPtr;
  629.     ACPI_STATUS             Status;
  630.     ACPI_NAMESPACE_NODE     *Node;
  631.  
  632.  
  633.     /*
  634.      * We can only sort the _TSS return package if there is no _PSS in the
  635.      * same scope. This is because if _PSS is present, the ACPI specification
  636.      * dictates that the _TSS Power Dissipation field is to be ignored, and
  637.      * therefore some BIOSs leave garbage values in the _TSS Power field(s).
  638.      * In this case, it is best to just return the _TSS package as-is.
  639.      * (May, 2011)
  640.      */
  641.     Status = AcpiNsGetNode (Data->Node, "^_PSS", ACPI_NS_NO_UPSEARCH, &Node);
  642.     if (ACPI_SUCCESS (Status))
  643.     {
  644.         return (AE_OK);
  645.     }
  646.  
  647.     Status = AcpiNsCheckSortedList (Data, ReturnObject, 5, 1,
  648.                 ACPI_SORT_DESCENDING, "PowerDissipation");
  649.  
  650.     return (Status);
  651. }
  652.  
  653.  
  654. /******************************************************************************
  655.  *
  656.  * FUNCTION:    AcpiNsRepair_PSS
  657.  *
  658.  * PARAMETERS:  Data                - Pointer to validation data structure
  659.  *              ReturnObjectPtr     - Pointer to the object returned from the
  660.  *                                    evaluation of a method or object
  661.  *
  662.  * RETURN:      Status. AE_OK if object is OK or was repaired successfully
  663.  *
  664.  * DESCRIPTION: Repair for the _PSS object. If necessary, sort the object list
  665.  *              by the CPU frequencies. Check that the power dissipation values
  666.  *              are all proportional to CPU frequency (i.e., sorting by
  667.  *              frequency should be the same as sorting by power.)
  668.  *
  669.  *****************************************************************************/
  670.  
  671. static ACPI_STATUS
  672. AcpiNsRepair_PSS (
  673.     ACPI_PREDEFINED_DATA    *Data,
  674.     ACPI_OPERAND_OBJECT     **ReturnObjectPtr)
  675. {
  676.     ACPI_OPERAND_OBJECT     *ReturnObject = *ReturnObjectPtr;
  677.     ACPI_OPERAND_OBJECT     **OuterElements;
  678.     UINT32                  OuterElementCount;
  679.     ACPI_OPERAND_OBJECT     **Elements;
  680.     ACPI_OPERAND_OBJECT     *ObjDesc;
  681.     UINT32                  PreviousValue;
  682.     ACPI_STATUS             Status;
  683.     UINT32                  i;
  684.  
  685.  
  686.     /*
  687.      * Entries (sub-packages) in the _PSS Package must be sorted by power
  688.      * dissipation, in descending order. If it appears that the list is
  689.      * incorrectly sorted, sort it. We sort by CpuFrequency, since this
  690.      * should be proportional to the power.
  691.      */
  692.     Status =AcpiNsCheckSortedList (Data, ReturnObject, 6, 0,
  693.                 ACPI_SORT_DESCENDING, "CpuFrequency");
  694.     if (ACPI_FAILURE (Status))
  695.     {
  696.         return (Status);
  697.     }
  698.  
  699.     /*
  700.      * We now know the list is correctly sorted by CPU frequency. Check if
  701.      * the power dissipation values are proportional.
  702.      */
  703.     PreviousValue = ACPI_UINT32_MAX;
  704.     OuterElements = ReturnObject->Package.Elements;
  705.     OuterElementCount = ReturnObject->Package.Count;
  706.  
  707.     for (i = 0; i < OuterElementCount; i++)
  708.     {
  709.         Elements = (*OuterElements)->Package.Elements;
  710.         ObjDesc = Elements[1]; /* Index1 = PowerDissipation */
  711.  
  712.         if ((UINT32) ObjDesc->Integer.Value > PreviousValue)
  713.         {
  714.             ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
  715.                 "SubPackage[%u,%u] - suspicious power dissipation values",
  716.                 i-1, i));
  717.         }
  718.  
  719.         PreviousValue = (UINT32) ObjDesc->Integer.Value;
  720.         OuterElements++;
  721.     }
  722.  
  723.     return (AE_OK);
  724. }
  725.  
  726.  
  727. /******************************************************************************
  728.  *
  729.  * FUNCTION:    AcpiNsCheckSortedList
  730.  *
  731.  * PARAMETERS:  Data                - Pointer to validation data structure
  732.  *              ReturnObject        - Pointer to the top-level returned object
  733.  *              ExpectedCount       - Minimum length of each sub-package
  734.  *              SortIndex           - Sub-package entry to sort on
  735.  *              SortDirection       - Ascending or descending
  736.  *              SortKeyName         - Name of the SortIndex field
  737.  *
  738.  * RETURN:      Status. AE_OK if the list is valid and is sorted correctly or
  739.  *              has been repaired by sorting the list.
  740.  *
  741.  * DESCRIPTION: Check if the package list is valid and sorted correctly by the
  742.  *              SortIndex. If not, then sort the list.
  743.  *
  744.  *****************************************************************************/
  745.  
  746. static ACPI_STATUS
  747. AcpiNsCheckSortedList (
  748.     ACPI_PREDEFINED_DATA    *Data,
  749.     ACPI_OPERAND_OBJECT     *ReturnObject,
  750.     UINT32                  ExpectedCount,
  751.     UINT32                  SortIndex,
  752.     UINT8                   SortDirection,
  753.     char                    *SortKeyName)
  754. {
  755.     UINT32                  OuterElementCount;
  756.     ACPI_OPERAND_OBJECT     **OuterElements;
  757.     ACPI_OPERAND_OBJECT     **Elements;
  758.     ACPI_OPERAND_OBJECT     *ObjDesc;
  759.     UINT32                  i;
  760.     UINT32                  PreviousValue;
  761.  
  762.  
  763.     ACPI_FUNCTION_NAME (NsCheckSortedList);
  764.  
  765.  
  766.     /* The top-level object must be a package */
  767.  
  768.     if (ReturnObject->Common.Type != ACPI_TYPE_PACKAGE)
  769.     {
  770.         return (AE_AML_OPERAND_TYPE);
  771.     }
  772.  
  773.     /*
  774.      * NOTE: assumes list of sub-packages contains no NULL elements.
  775.      * Any NULL elements should have been removed by earlier call
  776.      * to AcpiNsRemoveNullElements.
  777.      */
  778.     OuterElements = ReturnObject->Package.Elements;
  779.     OuterElementCount = ReturnObject->Package.Count;
  780.     if (!OuterElementCount)
  781.     {
  782.         return (AE_AML_PACKAGE_LIMIT);
  783.     }
  784.  
  785.     PreviousValue = 0;
  786.     if (SortDirection == ACPI_SORT_DESCENDING)
  787.     {
  788.         PreviousValue = ACPI_UINT32_MAX;
  789.     }
  790.  
  791.     /* Examine each subpackage */
  792.  
  793.     for (i = 0; i < OuterElementCount; i++)
  794.     {
  795.         /* Each element of the top-level package must also be a package */
  796.  
  797.         if ((*OuterElements)->Common.Type != ACPI_TYPE_PACKAGE)
  798.         {
  799.             return (AE_AML_OPERAND_TYPE);
  800.         }
  801.  
  802.         /* Each sub-package must have the minimum length */
  803.  
  804.         if ((*OuterElements)->Package.Count < ExpectedCount)
  805.         {
  806.             return (AE_AML_PACKAGE_LIMIT);
  807.         }
  808.  
  809.         Elements = (*OuterElements)->Package.Elements;
  810.         ObjDesc = Elements[SortIndex];
  811.  
  812.         if (ObjDesc->Common.Type != ACPI_TYPE_INTEGER)
  813.         {
  814.             return (AE_AML_OPERAND_TYPE);
  815.         }
  816.  
  817.         /*
  818.          * The list must be sorted in the specified order. If we detect a
  819.          * discrepancy, sort the entire list.
  820.          */
  821.         if (((SortDirection == ACPI_SORT_ASCENDING) &&
  822.                 (ObjDesc->Integer.Value < PreviousValue)) ||
  823.             ((SortDirection == ACPI_SORT_DESCENDING) &&
  824.                 (ObjDesc->Integer.Value > PreviousValue)))
  825.         {
  826.             AcpiNsSortList (ReturnObject->Package.Elements,
  827.                 OuterElementCount, SortIndex, SortDirection);
  828.  
  829.             Data->Flags |= ACPI_OBJECT_REPAIRED;
  830.  
  831.             ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR,
  832.                 "%s: Repaired unsorted list - now sorted by %s\n",
  833.                 Data->Pathname, SortKeyName));
  834.             return (AE_OK);
  835.         }
  836.  
  837.         PreviousValue = (UINT32) ObjDesc->Integer.Value;
  838.         OuterElements++;
  839.     }
  840.  
  841.     return (AE_OK);
  842. }
  843.  
  844.  
  845. /******************************************************************************
  846.  *
  847.  * FUNCTION:    AcpiNsSortList
  848.  *
  849.  * PARAMETERS:  Elements            - Package object element list
  850.  *              Count               - Element count for above
  851.  *              Index               - Sort by which package element
  852.  *              SortDirection       - Ascending or Descending sort
  853.  *
  854.  * RETURN:      None
  855.  *
  856.  * DESCRIPTION: Sort the objects that are in a package element list.
  857.  *
  858.  * NOTE: Assumes that all NULL elements have been removed from the package,
  859.  *       and that all elements have been verified to be of type Integer.
  860.  *
  861.  *****************************************************************************/
  862.  
  863. static void
  864. AcpiNsSortList (
  865.     ACPI_OPERAND_OBJECT     **Elements,
  866.     UINT32                  Count,
  867.     UINT32                  Index,
  868.     UINT8                   SortDirection)
  869. {
  870.     ACPI_OPERAND_OBJECT     *ObjDesc1;
  871.     ACPI_OPERAND_OBJECT     *ObjDesc2;
  872.     ACPI_OPERAND_OBJECT     *TempObj;
  873.     UINT32                  i;
  874.     UINT32                  j;
  875.  
  876.  
  877.     /* Simple bubble sort */
  878.  
  879.     for (i = 1; i < Count; i++)
  880.     {
  881.         for (j = (Count - 1); j >= i; j--)
  882.         {
  883.             ObjDesc1 = Elements[j-1]->Package.Elements[Index];
  884.             ObjDesc2 = Elements[j]->Package.Elements[Index];
  885.  
  886.             if (((SortDirection == ACPI_SORT_ASCENDING) &&
  887.                     (ObjDesc1->Integer.Value > ObjDesc2->Integer.Value)) ||
  888.  
  889.                 ((SortDirection == ACPI_SORT_DESCENDING) &&
  890.                     (ObjDesc1->Integer.Value < ObjDesc2->Integer.Value)))
  891.             {
  892.                 TempObj = Elements[j-1];
  893.                 Elements[j-1] = Elements[j];
  894.                 Elements[j] = TempObj;
  895.             }
  896.         }
  897.     }
  898. }
  899.