Subversion Repositories Kolibri OS

Rev

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

  1.  
  2. /******************************************************************************
  3.  *
  4.  * Module Name: hwxface - Public ACPICA hardware interfaces
  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. #include "acpi.h"
  118. #include "accommon.h"
  119. #include "acnamesp.h"
  120.  
  121. #define _COMPONENT          ACPI_HARDWARE
  122.         ACPI_MODULE_NAME    ("hwxface")
  123.  
  124.  
  125. /******************************************************************************
  126.  *
  127.  * FUNCTION:    AcpiReset
  128.  *
  129.  * PARAMETERS:  None
  130.  *
  131.  * RETURN:      Status
  132.  *
  133.  * DESCRIPTION: Set reset register in memory or IO space. Note: Does not
  134.  *              support reset register in PCI config space, this must be
  135.  *              handled separately.
  136.  *
  137.  ******************************************************************************/
  138.  
  139. ACPI_STATUS
  140. AcpiReset (
  141.     void)
  142. {
  143.     ACPI_GENERIC_ADDRESS    *ResetReg;
  144.     ACPI_STATUS             Status;
  145.  
  146.  
  147.     ACPI_FUNCTION_TRACE (AcpiReset);
  148.  
  149.  
  150.     ResetReg = &AcpiGbl_FADT.ResetRegister;
  151.  
  152.     /* Check if the reset register is supported */
  153.  
  154.     if (!(AcpiGbl_FADT.Flags & ACPI_FADT_RESET_REGISTER) ||
  155.         !ResetReg->Address)
  156.     {
  157.         return_ACPI_STATUS (AE_NOT_EXIST);
  158.     }
  159.  
  160.     if (ResetReg->SpaceId == ACPI_ADR_SPACE_SYSTEM_IO)
  161.     {
  162.         /*
  163.          * For I/O space, write directly to the OSL. This bypasses the port
  164.          * validation mechanism, which may block a valid write to the reset
  165.          * register.
  166.          */
  167.         Status = AcpiOsWritePort ((ACPI_IO_ADDRESS) ResetReg->Address,
  168.                     AcpiGbl_FADT.ResetValue, ResetReg->BitWidth);
  169.     }
  170.     else
  171.     {
  172.         /* Write the reset value to the reset register */
  173.  
  174.         Status = AcpiHwWrite (AcpiGbl_FADT.ResetValue, ResetReg);
  175.     }
  176.  
  177.     return_ACPI_STATUS (Status);
  178. }
  179.  
  180. ACPI_EXPORT_SYMBOL (AcpiReset)
  181.  
  182.  
  183. /******************************************************************************
  184.  *
  185.  * FUNCTION:    AcpiRead
  186.  *
  187.  * PARAMETERS:  Value               - Where the value is returned
  188.  *              Reg                 - GAS register structure
  189.  *
  190.  * RETURN:      Status
  191.  *
  192.  * DESCRIPTION: Read from either memory or IO space.
  193.  *
  194.  * LIMITATIONS: <These limitations also apply to AcpiWrite>
  195.  *      BitWidth must be exactly 8, 16, 32, or 64.
  196.  *      SpaceID must be SystemMemory or SystemIO.
  197.  *      BitOffset and AccessWidth are currently ignored, as there has
  198.  *          not been a need to implement these.
  199.  *
  200.  ******************************************************************************/
  201.  
  202. ACPI_STATUS
  203. AcpiRead (
  204.     UINT64                  *ReturnValue,
  205.     ACPI_GENERIC_ADDRESS    *Reg)
  206. {
  207.     UINT32                  Value;
  208.     UINT32                  Width;
  209.     UINT64                  Address;
  210.     ACPI_STATUS             Status;
  211.  
  212.  
  213.     ACPI_FUNCTION_NAME (AcpiRead);
  214.  
  215.  
  216.     if (!ReturnValue)
  217.     {
  218.         return (AE_BAD_PARAMETER);
  219.     }
  220.  
  221.     /* Validate contents of the GAS register. Allow 64-bit transfers */
  222.  
  223.     Status = AcpiHwValidateRegister (Reg, 64, &Address);
  224.     if (ACPI_FAILURE (Status))
  225.     {
  226.         return (Status);
  227.     }
  228.  
  229.     Width = Reg->BitWidth;
  230.     if (Width == 64)
  231.     {
  232.         Width = 32; /* Break into two 32-bit transfers */
  233.     }
  234.  
  235.     /* Initialize entire 64-bit return value to zero */
  236.  
  237.     *ReturnValue = 0;
  238.     Value = 0;
  239.  
  240.     /*
  241.      * Two address spaces supported: Memory or IO. PCI_Config is
  242.      * not supported here because the GAS structure is insufficient
  243.      */
  244.     if (Reg->SpaceId == ACPI_ADR_SPACE_SYSTEM_MEMORY)
  245.     {
  246.         Status = AcpiOsReadMemory ((ACPI_PHYSICAL_ADDRESS)
  247.                     Address, &Value, Width);
  248.         if (ACPI_FAILURE (Status))
  249.         {
  250.             return (Status);
  251.         }
  252.         *ReturnValue = Value;
  253.  
  254.         if (Reg->BitWidth == 64)
  255.         {
  256.             /* Read the top 32 bits */
  257.  
  258.             Status = AcpiOsReadMemory ((ACPI_PHYSICAL_ADDRESS)
  259.                         (Address + 4), &Value, 32);
  260.             if (ACPI_FAILURE (Status))
  261.             {
  262.                 return (Status);
  263.             }
  264.             *ReturnValue |= ((UINT64) Value << 32);
  265.         }
  266.     }
  267.     else /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */
  268.     {
  269.         Status = AcpiHwReadPort ((ACPI_IO_ADDRESS)
  270.                     Address, &Value, Width);
  271.         if (ACPI_FAILURE (Status))
  272.         {
  273.             return (Status);
  274.         }
  275.         *ReturnValue = Value;
  276.  
  277.         if (Reg->BitWidth == 64)
  278.         {
  279.             /* Read the top 32 bits */
  280.  
  281.             Status = AcpiHwReadPort ((ACPI_IO_ADDRESS)
  282.                         (Address + 4), &Value, 32);
  283.             if (ACPI_FAILURE (Status))
  284.             {
  285.                 return (Status);
  286.             }
  287.             *ReturnValue |= ((UINT64) Value << 32);
  288.         }
  289.     }
  290.  
  291.     ACPI_DEBUG_PRINT ((ACPI_DB_IO,
  292.         "Read:  %8.8X%8.8X width %2d from %8.8X%8.8X (%s)\n",
  293.         ACPI_FORMAT_UINT64 (*ReturnValue), Reg->BitWidth,
  294.         ACPI_FORMAT_UINT64 (Address),
  295.         AcpiUtGetRegionName (Reg->SpaceId)));
  296.  
  297.     return (Status);
  298. }
  299.  
  300. ACPI_EXPORT_SYMBOL (AcpiRead)
  301.  
  302.  
  303. /******************************************************************************
  304.  *
  305.  * FUNCTION:    AcpiWrite
  306.  *
  307.  * PARAMETERS:  Value               - Value to be written
  308.  *              Reg                 - GAS register structure
  309.  *
  310.  * RETURN:      Status
  311.  *
  312.  * DESCRIPTION: Write to either memory or IO space.
  313.  *
  314.  ******************************************************************************/
  315.  
  316. ACPI_STATUS
  317. AcpiWrite (
  318.     UINT64                  Value,
  319.     ACPI_GENERIC_ADDRESS    *Reg)
  320. {
  321.     UINT32                  Width;
  322.     UINT64                  Address;
  323.     ACPI_STATUS             Status;
  324.  
  325.  
  326.     ACPI_FUNCTION_NAME (AcpiWrite);
  327.  
  328.  
  329.     /* Validate contents of the GAS register. Allow 64-bit transfers */
  330.  
  331.     Status = AcpiHwValidateRegister (Reg, 64, &Address);
  332.     if (ACPI_FAILURE (Status))
  333.     {
  334.         return (Status);
  335.     }
  336.  
  337.     Width = Reg->BitWidth;
  338.     if (Width == 64)
  339.     {
  340.         Width = 32; /* Break into two 32-bit transfers */
  341.     }
  342.  
  343.     /*
  344.      * Two address spaces supported: Memory or IO. PCI_Config is
  345.      * not supported here because the GAS structure is insufficient
  346.      */
  347.     if (Reg->SpaceId == ACPI_ADR_SPACE_SYSTEM_MEMORY)
  348.     {
  349.         Status = AcpiOsWriteMemory ((ACPI_PHYSICAL_ADDRESS)
  350.                     Address, ACPI_LODWORD (Value), Width);
  351.         if (ACPI_FAILURE (Status))
  352.         {
  353.             return (Status);
  354.         }
  355.  
  356.         if (Reg->BitWidth == 64)
  357.         {
  358.             Status = AcpiOsWriteMemory ((ACPI_PHYSICAL_ADDRESS)
  359.                         (Address + 4), ACPI_HIDWORD (Value), 32);
  360.             if (ACPI_FAILURE (Status))
  361.             {
  362.                 return (Status);
  363.             }
  364.         }
  365.     }
  366.     else /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */
  367.     {
  368.         Status = AcpiHwWritePort ((ACPI_IO_ADDRESS)
  369.                     Address, ACPI_LODWORD (Value), Width);
  370.         if (ACPI_FAILURE (Status))
  371.         {
  372.             return (Status);
  373.         }
  374.  
  375.         if (Reg->BitWidth == 64)
  376.         {
  377.             Status = AcpiHwWritePort ((ACPI_IO_ADDRESS)
  378.                         (Address + 4), ACPI_HIDWORD (Value), 32);
  379.             if (ACPI_FAILURE (Status))
  380.             {
  381.                 return (Status);
  382.             }
  383.         }
  384.     }
  385.  
  386.     ACPI_DEBUG_PRINT ((ACPI_DB_IO,
  387.         "Wrote: %8.8X%8.8X width %2d   to %8.8X%8.8X (%s)\n",
  388.         ACPI_FORMAT_UINT64 (Value), Reg->BitWidth,
  389.         ACPI_FORMAT_UINT64 (Address),
  390.         AcpiUtGetRegionName (Reg->SpaceId)));
  391.  
  392.     return (Status);
  393. }
  394.  
  395. ACPI_EXPORT_SYMBOL (AcpiWrite)
  396.  
  397.  
  398. /*******************************************************************************
  399.  *
  400.  * FUNCTION:    AcpiReadBitRegister
  401.  *
  402.  * PARAMETERS:  RegisterId      - ID of ACPI Bit Register to access
  403.  *              ReturnValue     - Value that was read from the register,
  404.  *                                normalized to bit position zero.
  405.  *
  406.  * RETURN:      Status and the value read from the specified Register. Value
  407.  *              returned is normalized to bit0 (is shifted all the way right)
  408.  *
  409.  * DESCRIPTION: ACPI BitRegister read function. Does not acquire the HW lock.
  410.  *
  411.  * SUPPORTS:    Bit fields in PM1 Status, PM1 Enable, PM1 Control, and
  412.  *              PM2 Control.
  413.  *
  414.  * Note: The hardware lock is not required when reading the ACPI bit registers
  415.  *       since almost all of them are single bit and it does not matter that
  416.  *       the parent hardware register can be split across two physical
  417.  *       registers. The only multi-bit field is SLP_TYP in the PM1 control
  418.  *       register, but this field does not cross an 8-bit boundary (nor does
  419.  *       it make much sense to actually read this field.)
  420.  *
  421.  ******************************************************************************/
  422.  
  423. ACPI_STATUS
  424. AcpiReadBitRegister (
  425.     UINT32                  RegisterId,
  426.     UINT32                  *ReturnValue)
  427. {
  428.     ACPI_BIT_REGISTER_INFO  *BitRegInfo;
  429.     UINT32                  RegisterValue;
  430.     UINT32                  Value;
  431.     ACPI_STATUS             Status;
  432.  
  433.  
  434.     ACPI_FUNCTION_TRACE_U32 (AcpiReadBitRegister, RegisterId);
  435.  
  436.  
  437.     /* Get the info structure corresponding to the requested ACPI Register */
  438.  
  439.     BitRegInfo = AcpiHwGetBitRegisterInfo (RegisterId);
  440.     if (!BitRegInfo)
  441.     {
  442.         return_ACPI_STATUS (AE_BAD_PARAMETER);
  443.     }
  444.  
  445.     /* Read the entire parent register */
  446.  
  447.     Status = AcpiHwRegisterRead (BitRegInfo->ParentRegister,
  448.                 &RegisterValue);
  449.     if (ACPI_FAILURE (Status))
  450.     {
  451.         return_ACPI_STATUS (Status);
  452.     }
  453.  
  454.     /* Normalize the value that was read, mask off other bits */
  455.  
  456.     Value = ((RegisterValue & BitRegInfo->AccessBitMask)
  457.                 >> BitRegInfo->BitPosition);
  458.  
  459.     ACPI_DEBUG_PRINT ((ACPI_DB_IO,
  460.         "BitReg %X, ParentReg %X, Actual %8.8X, ReturnValue %8.8X\n",
  461.         RegisterId, BitRegInfo->ParentRegister, RegisterValue, Value));
  462.  
  463.     *ReturnValue = Value;
  464.     return_ACPI_STATUS (AE_OK);
  465. }
  466.  
  467. ACPI_EXPORT_SYMBOL (AcpiReadBitRegister)
  468.  
  469.  
  470. /*******************************************************************************
  471.  *
  472.  * FUNCTION:    AcpiWriteBitRegister
  473.  *
  474.  * PARAMETERS:  RegisterId      - ID of ACPI Bit Register to access
  475.  *              Value           - Value to write to the register, in bit
  476.  *                                position zero. The bit is automaticallly
  477.  *                                shifted to the correct position.
  478.  *
  479.  * RETURN:      Status
  480.  *
  481.  * DESCRIPTION: ACPI Bit Register write function. Acquires the hardware lock
  482.  *              since most operations require a read/modify/write sequence.
  483.  *
  484.  * SUPPORTS:    Bit fields in PM1 Status, PM1 Enable, PM1 Control, and
  485.  *              PM2 Control.
  486.  *
  487.  * Note that at this level, the fact that there may be actually two
  488.  * hardware registers (A and B - and B may not exist) is abstracted.
  489.  *
  490.  ******************************************************************************/
  491.  
  492. ACPI_STATUS
  493. AcpiWriteBitRegister (
  494.     UINT32                  RegisterId,
  495.     UINT32                  Value)
  496. {
  497.     ACPI_BIT_REGISTER_INFO  *BitRegInfo;
  498.     ACPI_CPU_FLAGS          LockFlags;
  499.     UINT32                  RegisterValue;
  500.     ACPI_STATUS             Status = AE_OK;
  501.  
  502.  
  503.     ACPI_FUNCTION_TRACE_U32 (AcpiWriteBitRegister, RegisterId);
  504.  
  505.  
  506.     /* Get the info structure corresponding to the requested ACPI Register */
  507.  
  508.     BitRegInfo = AcpiHwGetBitRegisterInfo (RegisterId);
  509.     if (!BitRegInfo)
  510.     {
  511.         return_ACPI_STATUS (AE_BAD_PARAMETER);
  512.     }
  513.  
  514.     LockFlags = AcpiOsAcquireLock (AcpiGbl_HardwareLock);
  515.  
  516.     /*
  517.      * At this point, we know that the parent register is one of the
  518.      * following: PM1 Status, PM1 Enable, PM1 Control, or PM2 Control
  519.      */
  520.     if (BitRegInfo->ParentRegister != ACPI_REGISTER_PM1_STATUS)
  521.     {
  522.         /*
  523.          * 1) Case for PM1 Enable, PM1 Control, and PM2 Control
  524.          *
  525.          * Perform a register read to preserve the bits that we are not
  526.          * interested in
  527.          */
  528.         Status = AcpiHwRegisterRead (BitRegInfo->ParentRegister,
  529.                     &RegisterValue);
  530.         if (ACPI_FAILURE (Status))
  531.         {
  532.             goto UnlockAndExit;
  533.         }
  534.  
  535.         /*
  536.          * Insert the input bit into the value that was just read
  537.          * and write the register
  538.          */
  539.         ACPI_REGISTER_INSERT_VALUE (RegisterValue, BitRegInfo->BitPosition,
  540.             BitRegInfo->AccessBitMask, Value);
  541.  
  542.         Status = AcpiHwRegisterWrite (BitRegInfo->ParentRegister,
  543.                     RegisterValue);
  544.     }
  545.     else
  546.     {
  547.         /*
  548.          * 2) Case for PM1 Status
  549.          *
  550.          * The Status register is different from the rest. Clear an event
  551.          * by writing 1, writing 0 has no effect. So, the only relevant
  552.          * information is the single bit we're interested in, all others
  553.          * should be written as 0 so they will be left unchanged.
  554.          */
  555.         RegisterValue = ACPI_REGISTER_PREPARE_BITS (Value,
  556.             BitRegInfo->BitPosition, BitRegInfo->AccessBitMask);
  557.  
  558.         /* No need to write the register if value is all zeros */
  559.  
  560.         if (RegisterValue)
  561.         {
  562.             Status = AcpiHwRegisterWrite (ACPI_REGISTER_PM1_STATUS,
  563.                         RegisterValue);
  564.         }
  565.     }
  566.  
  567.     ACPI_DEBUG_PRINT ((ACPI_DB_IO,
  568.         "BitReg %X, ParentReg %X, Value %8.8X, Actual %8.8X\n",
  569.         RegisterId, BitRegInfo->ParentRegister, Value, RegisterValue));
  570.  
  571.  
  572. UnlockAndExit:
  573.  
  574.     AcpiOsReleaseLock (AcpiGbl_HardwareLock, LockFlags);
  575.     return_ACPI_STATUS (Status);
  576. }
  577.  
  578. ACPI_EXPORT_SYMBOL (AcpiWriteBitRegister)
  579.  
  580.  
  581. /*******************************************************************************
  582.  *
  583.  * FUNCTION:    AcpiGetSleepTypeData
  584.  *
  585.  * PARAMETERS:  SleepState          - Numeric sleep state
  586.  *              *SleepTypeA         - Where SLP_TYPa is returned
  587.  *              *SleepTypeB         - Where SLP_TYPb is returned
  588.  *
  589.  * RETURN:      Status - ACPI status
  590.  *
  591.  * DESCRIPTION: Obtain the SLP_TYPa and SLP_TYPb values for the requested sleep
  592.  *              state.
  593.  *
  594.  ******************************************************************************/
  595.  
  596. ACPI_STATUS
  597. AcpiGetSleepTypeData (
  598.     UINT8                   SleepState,
  599.     UINT8                   *SleepTypeA,
  600.     UINT8                   *SleepTypeB)
  601. {
  602.     ACPI_STATUS             Status = AE_OK;
  603.     ACPI_EVALUATE_INFO      *Info;
  604.  
  605.  
  606.     ACPI_FUNCTION_TRACE (AcpiGetSleepTypeData);
  607.  
  608.  
  609.     /* Validate parameters */
  610.  
  611.     if ((SleepState > ACPI_S_STATES_MAX) ||
  612.         !SleepTypeA ||
  613.         !SleepTypeB)
  614.     {
  615.         return_ACPI_STATUS (AE_BAD_PARAMETER);
  616.     }
  617.  
  618.     /* Allocate the evaluation information block */
  619.  
  620.     Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO));
  621.     if (!Info)
  622.     {
  623.         return_ACPI_STATUS (AE_NO_MEMORY);
  624.     }
  625.  
  626.     Info->Pathname = ACPI_CAST_PTR (char, AcpiGbl_SleepStateNames[SleepState]);
  627.  
  628.     /* Evaluate the namespace object containing the values for this state */
  629.  
  630.     Status = AcpiNsEvaluate (Info);
  631.     if (ACPI_FAILURE (Status))
  632.     {
  633.         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
  634.             "%s while evaluating SleepState [%s]\n",
  635.             AcpiFormatException (Status), Info->Pathname));
  636.  
  637.         goto Cleanup;
  638.     }
  639.  
  640.     /* Must have a return object */
  641.  
  642.     if (!Info->ReturnObject)
  643.     {
  644.         ACPI_ERROR ((AE_INFO, "No Sleep State object returned from [%s]",
  645.             Info->Pathname));
  646.         Status = AE_NOT_EXIST;
  647.     }
  648.  
  649.     /* It must be of type Package */
  650.  
  651.     else if (Info->ReturnObject->Common.Type != ACPI_TYPE_PACKAGE)
  652.     {
  653.         ACPI_ERROR ((AE_INFO, "Sleep State return object is not a Package"));
  654.         Status = AE_AML_OPERAND_TYPE;
  655.     }
  656.  
  657.     /*
  658.      * The package must have at least two elements. NOTE (March 2005): This
  659.      * goes against the current ACPI spec which defines this object as a
  660.      * package with one encoded DWORD element. However, existing practice
  661.      * by BIOS vendors seems to be to have 2 or more elements, at least
  662.      * one per sleep type (A/B).
  663.      */
  664.     else if (Info->ReturnObject->Package.Count < 2)
  665.     {
  666.         ACPI_ERROR ((AE_INFO,
  667.             "Sleep State return package does not have at least two elements"));
  668.         Status = AE_AML_NO_OPERAND;
  669.     }
  670.  
  671.     /* The first two elements must both be of type Integer */
  672.  
  673.     else if (((Info->ReturnObject->Package.Elements[0])->Common.Type
  674.                 != ACPI_TYPE_INTEGER) ||
  675.              ((Info->ReturnObject->Package.Elements[1])->Common.Type
  676.                 != ACPI_TYPE_INTEGER))
  677.     {
  678.         ACPI_ERROR ((AE_INFO,
  679.             "Sleep State return package elements are not both Integers "
  680.             "(%s, %s)",
  681.             AcpiUtGetObjectTypeName (Info->ReturnObject->Package.Elements[0]),
  682.             AcpiUtGetObjectTypeName (Info->ReturnObject->Package.Elements[1])));
  683.         Status = AE_AML_OPERAND_TYPE;
  684.     }
  685.     else
  686.     {
  687.         /* Valid _Sx_ package size, type, and value */
  688.  
  689.         *SleepTypeA = (UINT8)
  690.             (Info->ReturnObject->Package.Elements[0])->Integer.Value;
  691.         *SleepTypeB = (UINT8)
  692.             (Info->ReturnObject->Package.Elements[1])->Integer.Value;
  693.     }
  694.  
  695.     if (ACPI_FAILURE (Status))
  696.     {
  697.         ACPI_EXCEPTION ((AE_INFO, Status,
  698.             "While evaluating SleepState [%s], bad Sleep object %p type %s",
  699.             Info->Pathname, Info->ReturnObject,
  700.             AcpiUtGetObjectTypeName (Info->ReturnObject)));
  701.     }
  702.  
  703.     AcpiUtRemoveReference (Info->ReturnObject);
  704.  
  705. Cleanup:
  706.     ACPI_FREE (Info);
  707.     return_ACPI_STATUS (Status);
  708. }
  709.  
  710. ACPI_EXPORT_SYMBOL (AcpiGetSleepTypeData)
  711.