Subversion Repositories Kolibri OS

Rev

Rev 1498 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /******************************************************************************
  2.  *
  3.  * Module Name: nsrepair - Repair for objects returned by predefined methods
  4.  *
  5.  *****************************************************************************/
  6.  
  7. /******************************************************************************
  8.  *
  9.  * 1. Copyright Notice
  10.  *
  11.  * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
  12.  * All rights reserved.
  13.  *
  14.  * 2. License
  15.  *
  16.  * 2.1. This is your license from Intel Corp. under its intellectual property
  17.  * rights.  You may have additional license terms from the party that provided
  18.  * you this software, covering your right to use that party's intellectual
  19.  * property rights.
  20.  *
  21.  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
  22.  * copy of the source code appearing in this file ("Covered Code") an
  23.  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
  24.  * base code distributed originally by Intel ("Original Intel Code") to copy,
  25.  * make derivatives, distribute, use and display any portion of the Covered
  26.  * Code in any form, with the right to sublicense such rights; and
  27.  *
  28.  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
  29.  * license (with the right to sublicense), under only those claims of Intel
  30.  * patents that are infringed by the Original Intel Code, to make, use, sell,
  31.  * offer to sell, and import the Covered Code and derivative works thereof
  32.  * solely to the minimum extent necessary to exercise the above copyright
  33.  * license, and in no event shall the patent license extend to any additions
  34.  * to or modifications of the Original Intel Code.  No other license or right
  35.  * is granted directly or by implication, estoppel or otherwise;
  36.  *
  37.  * The above copyright and patent license is granted only if the following
  38.  * conditions are met:
  39.  *
  40.  * 3. Conditions
  41.  *
  42.  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
  43.  * Redistribution of source code of any substantial portion of the Covered
  44.  * Code or modification with rights to further distribute source must include
  45.  * the above Copyright Notice, the above License, this list of Conditions,
  46.  * and the following Disclaimer and Export Compliance provision.  In addition,
  47.  * Licensee must cause all Covered Code to which Licensee contributes to
  48.  * contain a file documenting the changes Licensee made to create that Covered
  49.  * Code and the date of any change.  Licensee must include in that file the
  50.  * documentation of any changes made by any predecessor Licensee.  Licensee
  51.  * must include a prominent statement that the modification is derived,
  52.  * directly or indirectly, from Original Intel Code.
  53.  *
  54.  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
  55.  * Redistribution of source code of any substantial portion of the Covered
  56.  * Code or modification without rights to further distribute source must
  57.  * include the following Disclaimer and Export Compliance provision in the
  58.  * documentation and/or other materials provided with distribution.  In
  59.  * addition, Licensee may not authorize further sublicense of source of any
  60.  * portion of the Covered Code, and must include terms to the effect that the
  61.  * license from Licensee to its licensee is limited to the intellectual
  62.  * property embodied in the software Licensee provides to its licensee, and
  63.  * not to intellectual property embodied in modifications its licensee may
  64.  * make.
  65.  *
  66.  * 3.3. Redistribution of Executable. Redistribution in executable form of any
  67.  * substantial portion of the Covered Code or modification must reproduce the
  68.  * above Copyright Notice, and the following Disclaimer and Export Compliance
  69.  * provision in the documentation and/or other materials provided with the
  70.  * distribution.
  71.  *
  72.  * 3.4. Intel retains all right, title, and interest in and to the Original
  73.  * Intel Code.
  74.  *
  75.  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
  76.  * Intel shall be used in advertising or otherwise to promote the sale, use or
  77.  * other dealings in products derived from or relating to the Covered Code
  78.  * without prior written authorization from Intel.
  79.  *
  80.  * 4. Disclaimer and Export Compliance
  81.  *
  82.  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
  83.  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
  84.  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
  85.  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
  86.  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
  87.  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
  88.  * PARTICULAR PURPOSE.
  89.  *
  90.  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
  91.  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
  92.  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
  93.  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
  94.  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
  95.  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
  96.  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
  97.  * LIMITED REMEDY.
  98.  *
  99.  * 4.3. Licensee shall not export, either directly or indirectly, any of this
  100.  * software or system incorporating such software without first obtaining any
  101.  * required license or other approval from the U. S. Department of Commerce or
  102.  * any other agency or department of the United States Government.  In the
  103.  * event Licensee exports any such software from the United States or
  104.  * re-exports any such software from a foreign destination, Licensee shall
  105.  * ensure that the distribution and export/re-export of the software is in
  106.  * compliance with all laws, regulations, orders, or other restrictions of the
  107.  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
  108.  * any of its subsidiaries will export/re-export any technical data, process,
  109.  * software, or service, directly or indirectly, to any country for which the
  110.  * United States government or any agency thereof requires an export license,
  111.  * other governmental approval, or letter of assurance, without first obtaining
  112.  * such license, approval or letter.
  113.  *
  114.  *****************************************************************************/
  115.  
  116. #define __NSREPAIR_C__
  117.  
  118. #include "acpi.h"
  119. #include "accommon.h"
  120. #include "acnamesp.h"
  121. #include "acinterp.h"
  122. #include "acpredef.h"
  123.  
  124. #define _COMPONENT          ACPI_NAMESPACE
  125.         ACPI_MODULE_NAME    ("nsrepair")
  126.  
  127.  
  128. /*******************************************************************************
  129.  *
  130.  * This module attempts to repair or convert objects returned by the
  131.  * predefined methods to an object type that is expected, as per the ACPI
  132.  * specification. The need for this code is dictated by the many machines that
  133.  * return incorrect types for the standard predefined methods. Performing these
  134.  * conversions here, in one place, eliminates the need for individual ACPI
  135.  * device drivers to do the same. Note: Most of these conversions are different
  136.  * than the internal object conversion routines used for implicit object
  137.  * conversion.
  138.  *
  139.  * The following conversions can be performed as necessary:
  140.  *
  141.  * Integer -> String
  142.  * Integer -> Buffer
  143.  * String  -> Integer
  144.  * String  -> Buffer
  145.  * Buffer  -> Integer
  146.  * Buffer  -> String
  147.  * Buffer  -> Package of Integers
  148.  * Package -> Package of one Package
  149.  *
  150.  * Additional possible repairs:
  151.  *
  152.  * Required package elements that are NULL replaced by Integer/String/Buffer
  153.  * Incorrect standalone package wrapped with required outer package
  154.  *
  155.  ******************************************************************************/
  156.  
  157.  
  158. /* Local prototypes */
  159.  
  160. static ACPI_STATUS
  161. AcpiNsConvertToInteger (
  162.     ACPI_OPERAND_OBJECT     *OriginalObject,
  163.     ACPI_OPERAND_OBJECT     **ReturnObject);
  164.  
  165. static ACPI_STATUS
  166. AcpiNsConvertToString (
  167.     ACPI_OPERAND_OBJECT     *OriginalObject,
  168.     ACPI_OPERAND_OBJECT     **ReturnObject);
  169.  
  170. static ACPI_STATUS
  171. AcpiNsConvertToBuffer (
  172.     ACPI_OPERAND_OBJECT     *OriginalObject,
  173.     ACPI_OPERAND_OBJECT     **ReturnObject);
  174.  
  175. static ACPI_STATUS
  176. AcpiNsConvertToPackage (
  177.     ACPI_OPERAND_OBJECT     *OriginalObject,
  178.     ACPI_OPERAND_OBJECT     **ReturnObject);
  179.  
  180.  
  181. /*******************************************************************************
  182.  *
  183.  * FUNCTION:    AcpiNsRepairObject
  184.  *
  185.  * PARAMETERS:  Data                - Pointer to validation data structure
  186.  *              ExpectedBtypes      - Object types expected
  187.  *              PackageIndex        - Index of object within parent package (if
  188.  *                                    applicable - ACPI_NOT_PACKAGE_ELEMENT
  189.  *                                    otherwise)
  190.  *              ReturnObjectPtr     - Pointer to the object returned from the
  191.  *                                    evaluation of a method or object
  192.  *
  193.  * RETURN:      Status. AE_OK if repair was successful.
  194.  *
  195.  * DESCRIPTION: Attempt to repair/convert a return object of a type that was
  196.  *              not expected.
  197.  *
  198.  ******************************************************************************/
  199.  
  200. ACPI_STATUS
  201. AcpiNsRepairObject (
  202.     ACPI_PREDEFINED_DATA    *Data,
  203.     UINT32                  ExpectedBtypes,
  204.     UINT32                  PackageIndex,
  205.     ACPI_OPERAND_OBJECT     **ReturnObjectPtr)
  206. {
  207.     ACPI_OPERAND_OBJECT     *ReturnObject = *ReturnObjectPtr;
  208.     ACPI_OPERAND_OBJECT     *NewObject;
  209.     ACPI_STATUS             Status;
  210.  
  211.  
  212.     ACPI_FUNCTION_NAME (NsRepairObject);
  213.  
  214.  
  215.     /*
  216.      * At this point, we know that the type of the returned object was not
  217.      * one of the expected types for this predefined name. Attempt to
  218.      * repair the object by converting it to one of the expected object
  219.      * types for this predefined name.
  220.      */
  221.     if (ExpectedBtypes & ACPI_RTYPE_INTEGER)
  222.     {
  223.         Status = AcpiNsConvertToInteger (ReturnObject, &NewObject);
  224.         if (ACPI_SUCCESS (Status))
  225.         {
  226.             goto ObjectRepaired;
  227.         }
  228.     }
  229.     if (ExpectedBtypes & ACPI_RTYPE_STRING)
  230.     {
  231.         Status = AcpiNsConvertToString (ReturnObject, &NewObject);
  232.         if (ACPI_SUCCESS (Status))
  233.         {
  234.             goto ObjectRepaired;
  235.         }
  236.     }
  237.     if (ExpectedBtypes & ACPI_RTYPE_BUFFER)
  238.     {
  239.         Status = AcpiNsConvertToBuffer (ReturnObject, &NewObject);
  240.         if (ACPI_SUCCESS (Status))
  241.         {
  242.             goto ObjectRepaired;
  243.         }
  244.     }
  245.     if (ExpectedBtypes & ACPI_RTYPE_PACKAGE)
  246.     {
  247.         Status = AcpiNsConvertToPackage (ReturnObject, &NewObject);
  248.         if (ACPI_SUCCESS (Status))
  249.         {
  250.             goto ObjectRepaired;
  251.         }
  252.     }
  253.  
  254.     /* We cannot repair this object */
  255.  
  256.     return (AE_AML_OPERAND_TYPE);
  257.  
  258.  
  259. ObjectRepaired:
  260.  
  261.     /* Object was successfully repaired */
  262.  
  263.     /*
  264.      * If the original object is a package element, we need to:
  265.      * 1. Set the reference count of the new object to match the
  266.      *    reference count of the old object.
  267.      * 2. Decrement the reference count of the original object.
  268.      */
  269.     if (PackageIndex != ACPI_NOT_PACKAGE_ELEMENT)
  270.     {
  271.         NewObject->Common.ReferenceCount =
  272.             ReturnObject->Common.ReferenceCount;
  273.  
  274.         if (ReturnObject->Common.ReferenceCount > 1)
  275.         {
  276.             ReturnObject->Common.ReferenceCount--;
  277.         }
  278.  
  279.         ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR,
  280.             "%s: Converted %s to expected %s at index %u\n",
  281.             Data->Pathname, AcpiUtGetObjectTypeName (ReturnObject),
  282.             AcpiUtGetObjectTypeName (NewObject), PackageIndex));
  283.     }
  284.     else
  285.     {
  286.         ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR,
  287.             "%s: Converted %s to expected %s\n",
  288.             Data->Pathname, AcpiUtGetObjectTypeName (ReturnObject),
  289.             AcpiUtGetObjectTypeName (NewObject)));
  290.     }
  291.  
  292.     /* Delete old object, install the new return object */
  293.  
  294.     AcpiUtRemoveReference (ReturnObject);
  295.     *ReturnObjectPtr = NewObject;
  296.     Data->Flags |= ACPI_OBJECT_REPAIRED;
  297.     return (AE_OK);
  298. }
  299.  
  300.  
  301. /*******************************************************************************
  302.  *
  303.  * FUNCTION:    AcpiNsConvertToInteger
  304.  *
  305.  * PARAMETERS:  OriginalObject      - Object to be converted
  306.  *              ReturnObject        - Where the new converted object is returned
  307.  *
  308.  * RETURN:      Status. AE_OK if conversion was successful.
  309.  *
  310.  * DESCRIPTION: Attempt to convert a String/Buffer object to an Integer.
  311.  *
  312.  ******************************************************************************/
  313.  
  314. static ACPI_STATUS
  315. AcpiNsConvertToInteger (
  316.     ACPI_OPERAND_OBJECT     *OriginalObject,
  317.     ACPI_OPERAND_OBJECT     **ReturnObject)
  318. {
  319.     ACPI_OPERAND_OBJECT     *NewObject;
  320.     ACPI_STATUS             Status;
  321.     UINT64                  Value = 0;
  322.     UINT32                  i;
  323.  
  324.  
  325.     switch (OriginalObject->Common.Type)
  326.     {
  327.     case ACPI_TYPE_STRING:
  328.  
  329.         /* String-to-Integer conversion */
  330.  
  331.         Status = AcpiUtStrtoul64 (OriginalObject->String.Pointer,
  332.                     ACPI_ANY_BASE, &Value);
  333.         if (ACPI_FAILURE (Status))
  334.         {
  335.             return (Status);
  336.         }
  337.         break;
  338.  
  339.     case ACPI_TYPE_BUFFER:
  340.  
  341.         /* Buffer-to-Integer conversion. Max buffer size is 64 bits. */
  342.  
  343.         if (OriginalObject->Buffer.Length > 8)
  344.         {
  345.             return (AE_AML_OPERAND_TYPE);
  346.         }
  347.  
  348.         /* Extract each buffer byte to create the integer */
  349.  
  350.         for (i = 0; i < OriginalObject->Buffer.Length; i++)
  351.         {
  352.             Value |= ((UINT64) OriginalObject->Buffer.Pointer[i] << (i * 8));
  353.         }
  354.         break;
  355.  
  356.     default:
  357.         return (AE_AML_OPERAND_TYPE);
  358.     }
  359.  
  360.     NewObject = AcpiUtCreateIntegerObject (Value);
  361.     if (!NewObject)
  362.     {
  363.         return (AE_NO_MEMORY);
  364.     }
  365.  
  366.     *ReturnObject = NewObject;
  367.     return (AE_OK);
  368. }
  369.  
  370.  
  371. /*******************************************************************************
  372.  *
  373.  * FUNCTION:    AcpiNsConvertToString
  374.  *
  375.  * PARAMETERS:  OriginalObject      - Object to be converted
  376.  *              ReturnObject        - Where the new converted object is returned
  377.  *
  378.  * RETURN:      Status. AE_OK if conversion was successful.
  379.  *
  380.  * DESCRIPTION: Attempt to convert a Integer/Buffer object to a String.
  381.  *
  382.  ******************************************************************************/
  383.  
  384. static ACPI_STATUS
  385. AcpiNsConvertToString (
  386.     ACPI_OPERAND_OBJECT     *OriginalObject,
  387.     ACPI_OPERAND_OBJECT     **ReturnObject)
  388. {
  389.     ACPI_OPERAND_OBJECT     *NewObject;
  390.     ACPI_SIZE               Length;
  391.     ACPI_STATUS             Status;
  392.  
  393.  
  394.     switch (OriginalObject->Common.Type)
  395.     {
  396.     case ACPI_TYPE_INTEGER:
  397.         /*
  398.          * Integer-to-String conversion. Commonly, convert
  399.          * an integer of value 0 to a NULL string. The last element of
  400.          * _BIF and _BIX packages occasionally need this fix.
  401.          */
  402.         if (OriginalObject->Integer.Value == 0)
  403.         {
  404.             /* Allocate a new NULL string object */
  405.  
  406.             NewObject = AcpiUtCreateStringObject (0);
  407.             if (!NewObject)
  408.             {
  409.                 return (AE_NO_MEMORY);
  410.             }
  411.         }
  412.         else
  413.         {
  414.             Status = AcpiExConvertToString (OriginalObject, &NewObject,
  415.                         ACPI_IMPLICIT_CONVERT_HEX);
  416.             if (ACPI_FAILURE (Status))
  417.             {
  418.                 return (Status);
  419.             }
  420.         }
  421.         break;
  422.  
  423.     case ACPI_TYPE_BUFFER:
  424.         /*
  425.          * Buffer-to-String conversion. Use a ToString
  426.          * conversion, no transform performed on the buffer data. The best
  427.          * example of this is the _BIF method, where the string data from
  428.          * the battery is often (incorrectly) returned as buffer object(s).
  429.          */
  430.         Length = 0;
  431.         while ((Length < OriginalObject->Buffer.Length) &&
  432.                 (OriginalObject->Buffer.Pointer[Length]))
  433.         {
  434.             Length++;
  435.         }
  436.  
  437.         /* Allocate a new string object */
  438.  
  439.         NewObject = AcpiUtCreateStringObject (Length);
  440.         if (!NewObject)
  441.         {
  442.             return (AE_NO_MEMORY);
  443.         }
  444.  
  445.         /*
  446.          * Copy the raw buffer data with no transform. String is already NULL
  447.          * terminated at Length+1.
  448.          */
  449.         ACPI_MEMCPY (NewObject->String.Pointer,
  450.             OriginalObject->Buffer.Pointer, Length);
  451.         break;
  452.  
  453.     default:
  454.         return (AE_AML_OPERAND_TYPE);
  455.     }
  456.  
  457.     *ReturnObject = NewObject;
  458.     return (AE_OK);
  459. }
  460.  
  461.  
  462. /*******************************************************************************
  463.  *
  464.  * FUNCTION:    AcpiNsConvertToBuffer
  465.  *
  466.  * PARAMETERS:  OriginalObject      - Object to be converted
  467.  *              ReturnObject        - Where the new converted object is returned
  468.  *
  469.  * RETURN:      Status. AE_OK if conversion was successful.
  470.  *
  471.  * DESCRIPTION: Attempt to convert a Integer/String/Package object to a Buffer.
  472.  *
  473.  ******************************************************************************/
  474.  
  475. static ACPI_STATUS
  476. AcpiNsConvertToBuffer (
  477.     ACPI_OPERAND_OBJECT     *OriginalObject,
  478.     ACPI_OPERAND_OBJECT     **ReturnObject)
  479. {
  480.     ACPI_OPERAND_OBJECT     *NewObject;
  481.     ACPI_STATUS             Status;
  482.     ACPI_OPERAND_OBJECT     **Elements;
  483.     UINT32                  *DwordBuffer;
  484.     UINT32                  Count;
  485.     UINT32                  i;
  486.  
  487.  
  488.     switch (OriginalObject->Common.Type)
  489.     {
  490.     case ACPI_TYPE_INTEGER:
  491.         /*
  492.          * Integer-to-Buffer conversion.
  493.          * Convert the Integer to a packed-byte buffer. _MAT and other
  494.          * objects need this sometimes, if a read has been performed on a
  495.          * Field object that is less than or equal to the global integer
  496.          * size (32 or 64 bits).
  497.          */
  498.         Status = AcpiExConvertToBuffer (OriginalObject, &NewObject);
  499.         if (ACPI_FAILURE (Status))
  500.         {
  501.             return (Status);
  502.         }
  503.         break;
  504.  
  505.     case ACPI_TYPE_STRING:
  506.  
  507.         /* String-to-Buffer conversion. Simple data copy */
  508.  
  509.         NewObject = AcpiUtCreateBufferObject (OriginalObject->String.Length);
  510.         if (!NewObject)
  511.         {
  512.             return (AE_NO_MEMORY);
  513.         }
  514.  
  515.         ACPI_MEMCPY (NewObject->Buffer.Pointer,
  516.             OriginalObject->String.Pointer, OriginalObject->String.Length);
  517.         break;
  518.  
  519.     case ACPI_TYPE_PACKAGE:
  520.         /*
  521.          * This case is often seen for predefined names that must return a
  522.          * Buffer object with multiple DWORD integers within. For example,
  523.          * _FDE and _GTM. The Package can be converted to a Buffer.
  524.          */
  525.  
  526.         /* All elements of the Package must be integers */
  527.  
  528.         Elements = OriginalObject->Package.Elements;
  529.         Count = OriginalObject->Package.Count;
  530.  
  531.         for (i = 0; i < Count; i++)
  532.         {
  533.             if ((!*Elements) ||
  534.                 ((*Elements)->Common.Type != ACPI_TYPE_INTEGER))
  535.             {
  536.                 return (AE_AML_OPERAND_TYPE);
  537.             }
  538.             Elements++;
  539.         }
  540.  
  541.         /* Create the new buffer object to replace the Package */
  542.  
  543.         NewObject = AcpiUtCreateBufferObject (ACPI_MUL_4 (Count));
  544.         if (!NewObject)
  545.         {
  546.             return (AE_NO_MEMORY);
  547.         }
  548.  
  549.         /* Copy the package elements (integers) to the buffer as DWORDs */
  550.  
  551.         Elements = OriginalObject->Package.Elements;
  552.         DwordBuffer = ACPI_CAST_PTR (UINT32, NewObject->Buffer.Pointer);
  553.  
  554.         for (i = 0; i < Count; i++)
  555.         {
  556.             *DwordBuffer = (UINT32) (*Elements)->Integer.Value;
  557.             DwordBuffer++;
  558.             Elements++;
  559.         }
  560.         break;
  561.  
  562.     default:
  563.         return (AE_AML_OPERAND_TYPE);
  564.     }
  565.  
  566.     *ReturnObject = NewObject;
  567.     return (AE_OK);
  568. }
  569.  
  570.  
  571. /*******************************************************************************
  572.  *
  573.  * FUNCTION:    AcpiNsConvertToPackage
  574.  *
  575.  * PARAMETERS:  OriginalObject      - Object to be converted
  576.  *              ReturnObject        - Where the new converted object is returned
  577.  *
  578.  * RETURN:      Status. AE_OK if conversion was successful.
  579.  *
  580.  * DESCRIPTION: Attempt to convert a Buffer object to a Package. Each byte of
  581.  *              the buffer is converted to a single integer package element.
  582.  *
  583.  ******************************************************************************/
  584.  
  585. static ACPI_STATUS
  586. AcpiNsConvertToPackage (
  587.     ACPI_OPERAND_OBJECT     *OriginalObject,
  588.     ACPI_OPERAND_OBJECT     **ReturnObject)
  589. {
  590.     ACPI_OPERAND_OBJECT     *NewObject;
  591.     ACPI_OPERAND_OBJECT     **Elements;
  592.     UINT32                  Length;
  593.     UINT8                   *Buffer;
  594.  
  595.  
  596.     switch (OriginalObject->Common.Type)
  597.     {
  598.     case ACPI_TYPE_BUFFER:
  599.  
  600.         /* Buffer-to-Package conversion */
  601.  
  602.         Length = OriginalObject->Buffer.Length;
  603.         NewObject = AcpiUtCreatePackageObject (Length);
  604.         if (!NewObject)
  605.         {
  606.             return (AE_NO_MEMORY);
  607.         }
  608.  
  609.         /* Convert each buffer byte to an integer package element */
  610.  
  611.         Elements = NewObject->Package.Elements;
  612.         Buffer = OriginalObject->Buffer.Pointer;
  613.  
  614.         while (Length--)
  615.         {
  616.             *Elements = AcpiUtCreateIntegerObject ((UINT64) *Buffer);
  617.             if (!*Elements)
  618.             {
  619.                 AcpiUtRemoveReference (NewObject);
  620.                 return (AE_NO_MEMORY);
  621.             }
  622.             Elements++;
  623.             Buffer++;
  624.         }
  625.         break;
  626.  
  627.     default:
  628.         return (AE_AML_OPERAND_TYPE);
  629.     }
  630.  
  631.     *ReturnObject = NewObject;
  632.     return (AE_OK);
  633. }
  634.  
  635.  
  636. /*******************************************************************************
  637.  *
  638.  * FUNCTION:    AcpiNsRepairNullElement
  639.  *
  640.  * PARAMETERS:  Data                - Pointer to validation data structure
  641.  *              ExpectedBtypes      - Object types expected
  642.  *              PackageIndex        - Index of object within parent package (if
  643.  *                                    applicable - ACPI_NOT_PACKAGE_ELEMENT
  644.  *                                    otherwise)
  645.  *              ReturnObjectPtr     - Pointer to the object returned from the
  646.  *                                    evaluation of a method or object
  647.  *
  648.  * RETURN:      Status. AE_OK if repair was successful.
  649.  *
  650.  * DESCRIPTION: Attempt to repair a NULL element of a returned Package object.
  651.  *
  652.  ******************************************************************************/
  653.  
  654. ACPI_STATUS
  655. AcpiNsRepairNullElement (
  656.     ACPI_PREDEFINED_DATA    *Data,
  657.     UINT32                  ExpectedBtypes,
  658.     UINT32                  PackageIndex,
  659.     ACPI_OPERAND_OBJECT     **ReturnObjectPtr)
  660. {
  661.     ACPI_OPERAND_OBJECT     *ReturnObject = *ReturnObjectPtr;
  662.     ACPI_OPERAND_OBJECT     *NewObject;
  663.  
  664.  
  665.     ACPI_FUNCTION_NAME (NsRepairNullElement);
  666.  
  667.  
  668.     /* No repair needed if return object is non-NULL */
  669.  
  670.     if (ReturnObject)
  671.     {
  672.         return (AE_OK);
  673.     }
  674.  
  675.     /*
  676.      * Attempt to repair a NULL element of a Package object. This applies to
  677.      * predefined names that return a fixed-length package and each element
  678.      * is required. It does not apply to variable-length packages where NULL
  679.      * elements are allowed, especially at the end of the package.
  680.      */
  681.     if (ExpectedBtypes & ACPI_RTYPE_INTEGER)
  682.     {
  683.         /* Need an Integer - create a zero-value integer */
  684.  
  685.         NewObject = AcpiUtCreateIntegerObject ((UINT64) 0);
  686.     }
  687.     else if (ExpectedBtypes & ACPI_RTYPE_STRING)
  688.     {
  689.         /* Need a String - create a NULL string */
  690.  
  691.         NewObject = AcpiUtCreateStringObject (0);
  692.     }
  693.     else if (ExpectedBtypes & ACPI_RTYPE_BUFFER)
  694.     {
  695.         /* Need a Buffer - create a zero-length buffer */
  696.  
  697.         NewObject = AcpiUtCreateBufferObject (0);
  698.     }
  699.     else
  700.     {
  701.         /* Error for all other expected types */
  702.  
  703.         return (AE_AML_OPERAND_TYPE);
  704.     }
  705.  
  706.     if (!NewObject)
  707.     {
  708.         return (AE_NO_MEMORY);
  709.     }
  710.  
  711.     /* Set the reference count according to the parent Package object */
  712.  
  713.     NewObject->Common.ReferenceCount = Data->ParentPackage->Common.ReferenceCount;
  714.  
  715.     ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR,
  716.         "%s: Converted NULL package element to expected %s at index %u\n",
  717.          Data->Pathname, AcpiUtGetObjectTypeName (NewObject), PackageIndex));
  718.  
  719.     *ReturnObjectPtr = NewObject;
  720.     Data->Flags |= ACPI_OBJECT_REPAIRED;
  721.     return (AE_OK);
  722. }
  723.  
  724.  
  725. /******************************************************************************
  726.  *
  727.  * FUNCTION:    AcpiNsRemoveNullElements
  728.  *
  729.  * PARAMETERS:  Data                - Pointer to validation data structure
  730.  *              PackageType         - An AcpiReturnPackageTypes value
  731.  *              ObjDesc             - A Package object
  732.  *
  733.  * RETURN:      None.
  734.  *
  735.  * DESCRIPTION: Remove all NULL package elements from packages that contain
  736.  *              a variable number of sub-packages. For these types of
  737.  *              packages, NULL elements can be safely removed.
  738.  *
  739.  *****************************************************************************/
  740.  
  741. void
  742. AcpiNsRemoveNullElements (
  743.     ACPI_PREDEFINED_DATA    *Data,
  744.     UINT8                   PackageType,
  745.     ACPI_OPERAND_OBJECT     *ObjDesc)
  746. {
  747.     ACPI_OPERAND_OBJECT     **Source;
  748.     ACPI_OPERAND_OBJECT     **Dest;
  749.     UINT32                  Count;
  750.     UINT32                  NewCount;
  751.     UINT32                  i;
  752.  
  753.  
  754.     ACPI_FUNCTION_NAME (NsRemoveNullElements);
  755.  
  756.  
  757.     /*
  758.      * We can safely remove all NULL elements from these package types:
  759.      * PTYPE1_VAR packages contain a variable number of simple data types.
  760.      * PTYPE2 packages contain a variable number of sub-packages.
  761.      */
  762.     switch (PackageType)
  763.     {
  764.     case ACPI_PTYPE1_VAR:
  765.     case ACPI_PTYPE2:
  766.     case ACPI_PTYPE2_COUNT:
  767.     case ACPI_PTYPE2_PKG_COUNT:
  768.     case ACPI_PTYPE2_FIXED:
  769.     case ACPI_PTYPE2_MIN:
  770.     case ACPI_PTYPE2_REV_FIXED:
  771.         break;
  772.  
  773.     default:
  774.     case ACPI_PTYPE1_FIXED:
  775.     case ACPI_PTYPE1_OPTION:
  776.         return;
  777.     }
  778.  
  779.     Count = ObjDesc->Package.Count;
  780.     NewCount = Count;
  781.  
  782.     Source = ObjDesc->Package.Elements;
  783.     Dest = Source;
  784.  
  785.     /* Examine all elements of the package object, remove nulls */
  786.  
  787.     for (i = 0; i < Count; i++)
  788.     {
  789.         if (!*Source)
  790.         {
  791.             NewCount--;
  792.         }
  793.         else
  794.         {
  795.             *Dest = *Source;
  796.             Dest++;
  797.         }
  798.         Source++;
  799.     }
  800.  
  801.     /* Update parent package if any null elements were removed */
  802.  
  803.     if (NewCount < Count)
  804.     {
  805.         ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR,
  806.             "%s: Found and removed %u NULL elements\n",
  807.             Data->Pathname, (Count - NewCount)));
  808.  
  809.         /* NULL terminate list and update the package count */
  810.  
  811.         *Dest = NULL;
  812.         ObjDesc->Package.Count = NewCount;
  813.     }
  814. }
  815.  
  816.  
  817. /*******************************************************************************
  818.  *
  819.  * FUNCTION:    AcpiNsRepairPackageList
  820.  *
  821.  * PARAMETERS:  Data                - Pointer to validation data structure
  822.  *              ObjDescPtr          - Pointer to the object to repair. The new
  823.  *                                    package object is returned here,
  824.  *                                    overwriting the old object.
  825.  *
  826.  * RETURN:      Status, new object in *ObjDescPtr
  827.  *
  828.  * DESCRIPTION: Repair a common problem with objects that are defined to return
  829.  *              a variable-length Package of Packages. If the variable-length
  830.  *              is one, some BIOS code mistakenly simply declares a single
  831.  *              Package instead of a Package with one sub-Package. This
  832.  *              function attempts to repair this error by wrapping a Package
  833.  *              object around the original Package, creating the correct
  834.  *              Package with one sub-Package.
  835.  *
  836.  *              Names that can be repaired in this manner include:
  837.  *              _ALR, _CSD, _HPX, _MLS, _PRT, _PSS, _TRT, TSS
  838.  *
  839.  ******************************************************************************/
  840.  
  841. ACPI_STATUS
  842. AcpiNsRepairPackageList (
  843.     ACPI_PREDEFINED_DATA    *Data,
  844.     ACPI_OPERAND_OBJECT     **ObjDescPtr)
  845. {
  846.     ACPI_OPERAND_OBJECT     *PkgObjDesc;
  847.  
  848.  
  849.     ACPI_FUNCTION_NAME (NsRepairPackageList);
  850.  
  851.  
  852.     /*
  853.      * Create the new outer package and populate it. The new package will
  854.      * have a single element, the lone subpackage.
  855.      */
  856.     PkgObjDesc = AcpiUtCreatePackageObject (1);
  857.     if (!PkgObjDesc)
  858.     {
  859.         return (AE_NO_MEMORY);
  860.     }
  861.  
  862.     PkgObjDesc->Package.Elements[0] = *ObjDescPtr;
  863.  
  864.     /* Return the new object in the object pointer */
  865.  
  866.     *ObjDescPtr = PkgObjDesc;
  867.     Data->Flags |= ACPI_OBJECT_REPAIRED;
  868.  
  869.     ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR,
  870.         "%s: Repaired incorrectly formed Package\n", Data->Pathname));
  871.  
  872.     return (AE_OK);
  873. }
  874.