ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

hwsleep.c
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003  *
00004  * Name: hwsleep.c - ACPI Hardware Sleep/Wake Interface
00005  *
00006  *****************************************************************************/
00007 
00008 /******************************************************************************
00009  *
00010  * 1. Copyright Notice
00011  *
00012  * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
00013  * All rights reserved.
00014  *
00015  * 2. License
00016  *
00017  * 2.1. This is your license from Intel Corp. under its intellectual property
00018  * rights.  You may have additional license terms from the party that provided
00019  * you this software, covering your right to use that party's intellectual
00020  * property rights.
00021  *
00022  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
00023  * copy of the source code appearing in this file ("Covered Code") an
00024  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
00025  * base code distributed originally by Intel ("Original Intel Code") to copy,
00026  * make derivatives, distribute, use and display any portion of the Covered
00027  * Code in any form, with the right to sublicense such rights; and
00028  *
00029  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
00030  * license (with the right to sublicense), under only those claims of Intel
00031  * patents that are infringed by the Original Intel Code, to make, use, sell,
00032  * offer to sell, and import the Covered Code and derivative works thereof
00033  * solely to the minimum extent necessary to exercise the above copyright
00034  * license, and in no event shall the patent license extend to any additions
00035  * to or modifications of the Original Intel Code.  No other license or right
00036  * is granted directly or by implication, estoppel or otherwise;
00037  *
00038  * The above copyright and patent license is granted only if the following
00039  * conditions are met:
00040  *
00041  * 3. Conditions
00042  *
00043  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
00044  * Redistribution of source code of any substantial portion of the Covered
00045  * Code or modification with rights to further distribute source must include
00046  * the above Copyright Notice, the above License, this list of Conditions,
00047  * and the following Disclaimer and Export Compliance provision.  In addition,
00048  * Licensee must cause all Covered Code to which Licensee contributes to
00049  * contain a file documenting the changes Licensee made to create that Covered
00050  * Code and the date of any change.  Licensee must include in that file the
00051  * documentation of any changes made by any predecessor Licensee.  Licensee
00052  * must include a prominent statement that the modification is derived,
00053  * directly or indirectly, from Original Intel Code.
00054  *
00055  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
00056  * Redistribution of source code of any substantial portion of the Covered
00057  * Code or modification without rights to further distribute source must
00058  * include the following Disclaimer and Export Compliance provision in the
00059  * documentation and/or other materials provided with distribution.  In
00060  * addition, Licensee may not authorize further sublicense of source of any
00061  * portion of the Covered Code, and must include terms to the effect that the
00062  * license from Licensee to its licensee is limited to the intellectual
00063  * property embodied in the software Licensee provides to its licensee, and
00064  * not to intellectual property embodied in modifications its licensee may
00065  * make.
00066  *
00067  * 3.3. Redistribution of Executable. Redistribution in executable form of any
00068  * substantial portion of the Covered Code or modification must reproduce the
00069  * above Copyright Notice, and the following Disclaimer and Export Compliance
00070  * provision in the documentation and/or other materials provided with the
00071  * distribution.
00072  *
00073  * 3.4. Intel retains all right, title, and interest in and to the Original
00074  * Intel Code.
00075  *
00076  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
00077  * Intel shall be used in advertising or otherwise to promote the sale, use or
00078  * other dealings in products derived from or relating to the Covered Code
00079  * without prior written authorization from Intel.
00080  *
00081  * 4. Disclaimer and Export Compliance
00082  *
00083  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
00084  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
00085  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
00086  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
00087  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
00088  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
00089  * PARTICULAR PURPOSE.
00090  *
00091  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
00092  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
00093  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
00094  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
00095  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
00096  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
00097  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
00098  * LIMITED REMEDY.
00099  *
00100  * 4.3. Licensee shall not export, either directly or indirectly, any of this
00101  * software or system incorporating such software without first obtaining any
00102  * required license or other approval from the U. S. Department of Commerce or
00103  * any other agency or department of the United States Government.  In the
00104  * event Licensee exports any such software from the United States or
00105  * re-exports any such software from a foreign destination, Licensee shall
00106  * ensure that the distribution and export/re-export of the software is in
00107  * compliance with all laws, regulations, orders, or other restrictions of the
00108  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
00109  * any of its subsidiaries will export/re-export any technical data, process,
00110  * software, or service, directly or indirectly, to any country for which the
00111  * United States government or any agency thereof requires an export license,
00112  * other governmental approval, or letter of assurance, without first obtaining
00113  * such license, approval or letter.
00114  *
00115  *****************************************************************************/
00116 
00117 #include "acpi.h"
00118 #include "accommon.h"
00119 
00120 #define _COMPONENT          ACPI_HARDWARE
00121         ACPI_MODULE_NAME    ("hwsleep")
00122 
00123 
00124 /*******************************************************************************
00125  *
00126  * FUNCTION:    AcpiSetFirmwareWakingVector
00127  *
00128  * PARAMETERS:  PhysicalAddress     - 32-bit physical address of ACPI real mode
00129  *                                    entry point.
00130  *
00131  * RETURN:      Status
00132  *
00133  * DESCRIPTION: Sets the 32-bit FirmwareWakingVector field of the FACS
00134  *
00135  ******************************************************************************/
00136 
00137 ACPI_STATUS
00138 AcpiSetFirmwareWakingVector (
00139     UINT32                  PhysicalAddress)
00140 {
00141     ACPI_FUNCTION_TRACE (AcpiSetFirmwareWakingVector);
00142 
00143 
00144     /* Set the 32-bit vector */
00145 
00146     AcpiGbl_FACS->FirmwareWakingVector = PhysicalAddress;
00147 
00148     /* Clear the 64-bit vector if it exists */
00149 
00150     if ((AcpiGbl_FACS->Length > 32) && (AcpiGbl_FACS->Version >= 1))
00151     {
00152         AcpiGbl_FACS->XFirmwareWakingVector = 0;
00153     }
00154 
00155     return_ACPI_STATUS (AE_OK);
00156 }
00157 
00158 ACPI_EXPORT_SYMBOL (AcpiSetFirmwareWakingVector)
00159 
00160 
00161 #if ACPI_MACHINE_WIDTH == 64
00162 /*******************************************************************************
00163  *
00164  * FUNCTION:    AcpiSetFirmwareWakingVector64
00165  *
00166  * PARAMETERS:  PhysicalAddress     - 64-bit physical address of ACPI protected
00167  *                                    mode entry point.
00168  *
00169  * RETURN:      Status
00170  *
00171  * DESCRIPTION: Sets the 64-bit X_FirmwareWakingVector field of the FACS, if
00172  *              it exists in the table. This function is intended for use with
00173  *              64-bit host operating systems.
00174  *
00175  ******************************************************************************/
00176 
00177 ACPI_STATUS
00178 AcpiSetFirmwareWakingVector64 (
00179     UINT64                  PhysicalAddress)
00180 {
00181     ACPI_FUNCTION_TRACE (AcpiSetFirmwareWakingVector64);
00182 
00183 
00184     /* Determine if the 64-bit vector actually exists */
00185 
00186     if ((AcpiGbl_FACS->Length <= 32) || (AcpiGbl_FACS->Version < 1))
00187     {
00188         return_ACPI_STATUS (AE_NOT_EXIST);
00189     }
00190 
00191     /* Clear 32-bit vector, set the 64-bit X_ vector */
00192 
00193     AcpiGbl_FACS->FirmwareWakingVector = 0;
00194     AcpiGbl_FACS->XFirmwareWakingVector = PhysicalAddress;
00195     return_ACPI_STATUS (AE_OK);
00196 }
00197 
00198 ACPI_EXPORT_SYMBOL (AcpiSetFirmwareWakingVector64)
00199 #endif
00200 
00201 /*******************************************************************************
00202  *
00203  * FUNCTION:    AcpiEnterSleepStatePrep
00204  *
00205  * PARAMETERS:  SleepState          - Which sleep state to enter
00206  *
00207  * RETURN:      Status
00208  *
00209  * DESCRIPTION: Prepare to enter a system sleep state (see ACPI 2.0 spec p 231)
00210  *              This function must execute with interrupts enabled.
00211  *              We break sleeping into 2 stages so that OSPM can handle
00212  *              various OS-specific tasks between the two steps.
00213  *
00214  ******************************************************************************/
00215 
00216 ACPI_STATUS
00217 AcpiEnterSleepStatePrep (
00218     UINT8                   SleepState)
00219 {
00220     ACPI_STATUS             Status;
00221     ACPI_OBJECT_LIST        ArgList;
00222     ACPI_OBJECT             Arg;
00223 
00224 
00225     ACPI_FUNCTION_TRACE (AcpiEnterSleepStatePrep);
00226 
00227 
00228     /* _PSW methods could be run here to enable wake-on keyboard, LAN, etc. */
00229 
00230     Status = AcpiGetSleepTypeData (SleepState,
00231                     &AcpiGbl_SleepTypeA, &AcpiGbl_SleepTypeB);
00232     if (ACPI_FAILURE (Status))
00233     {
00234         return_ACPI_STATUS (Status);
00235     }
00236 
00237     /* Execute the _PTS method (Prepare To Sleep) */
00238 
00239     ArgList.Count = 1;
00240     ArgList.Pointer = &Arg;
00241     Arg.Type = ACPI_TYPE_INTEGER;
00242     Arg.Integer.Value = SleepState;
00243 
00244     Status = AcpiEvaluateObject (NULL, METHOD_NAME__PTS, &ArgList, NULL);
00245     if (ACPI_FAILURE (Status) && Status != AE_NOT_FOUND)
00246     {
00247         return_ACPI_STATUS (Status);
00248     }
00249 
00250     /* Setup the argument to the _SST method (System STatus) */
00251 
00252     switch (SleepState)
00253     {
00254     case ACPI_STATE_S0:
00255         Arg.Integer.Value = ACPI_SST_WORKING;
00256         break;
00257 
00258     case ACPI_STATE_S1:
00259     case ACPI_STATE_S2:
00260     case ACPI_STATE_S3:
00261         Arg.Integer.Value = ACPI_SST_SLEEPING;
00262         break;
00263 
00264     case ACPI_STATE_S4:
00265         Arg.Integer.Value = ACPI_SST_SLEEP_CONTEXT;
00266         break;
00267 
00268     default:
00269         Arg.Integer.Value = ACPI_SST_INDICATOR_OFF; /* Default is off */
00270         break;
00271     }
00272 
00273     /*
00274      * Set the system indicators to show the desired sleep state.
00275      * _SST is an optional method (return no error if not found)
00276      */
00277     Status = AcpiEvaluateObject (NULL, METHOD_NAME__SST, &ArgList, NULL);
00278     if (ACPI_FAILURE (Status) && Status != AE_NOT_FOUND)
00279     {
00280         ACPI_EXCEPTION ((AE_INFO, Status, "While executing method _SST"));
00281     }
00282 
00283     return_ACPI_STATUS (AE_OK);
00284 }
00285 
00286 ACPI_EXPORT_SYMBOL (AcpiEnterSleepStatePrep)
00287 
00288 
00289 /*******************************************************************************
00290  *
00291  * FUNCTION:    AcpiEnterSleepState
00292  *
00293  * PARAMETERS:  SleepState          - Which sleep state to enter
00294  *
00295  * RETURN:      Status
00296  *
00297  * DESCRIPTION: Enter a system sleep state
00298  *              THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED
00299  *
00300  ******************************************************************************/
00301 
00302 ACPI_STATUS
00303 AcpiEnterSleepState (
00304     UINT8                   SleepState)
00305 {
00306     UINT32                  Pm1aControl;
00307     UINT32                  Pm1bControl;
00308     ACPI_BIT_REGISTER_INFO  *SleepTypeRegInfo;
00309     ACPI_BIT_REGISTER_INFO  *SleepEnableRegInfo;
00310     UINT32                  InValue;
00311     ACPI_OBJECT_LIST        ArgList;
00312     ACPI_OBJECT             Arg;
00313     ACPI_STATUS             Status;
00314 
00315 
00316     ACPI_FUNCTION_TRACE (AcpiEnterSleepState);
00317 
00318 
00319     if ((AcpiGbl_SleepTypeA > ACPI_SLEEP_TYPE_MAX) ||
00320         (AcpiGbl_SleepTypeB > ACPI_SLEEP_TYPE_MAX))
00321     {
00322         ACPI_ERROR ((AE_INFO, "Sleep values out of range: A=0x%X B=0x%X",
00323             AcpiGbl_SleepTypeA, AcpiGbl_SleepTypeB));
00324         return_ACPI_STATUS (AE_AML_OPERAND_VALUE);
00325     }
00326 
00327     SleepTypeRegInfo   = AcpiHwGetBitRegisterInfo (ACPI_BITREG_SLEEP_TYPE);
00328     SleepEnableRegInfo = AcpiHwGetBitRegisterInfo (ACPI_BITREG_SLEEP_ENABLE);
00329 
00330     /* Clear wake status */
00331 
00332     Status = AcpiWriteBitRegister (ACPI_BITREG_WAKE_STATUS, ACPI_CLEAR_STATUS);
00333     if (ACPI_FAILURE (Status))
00334     {
00335         return_ACPI_STATUS (Status);
00336     }
00337 
00338     /* Clear all fixed and general purpose status bits */
00339 
00340     Status = AcpiHwClearAcpiStatus ();
00341     if (ACPI_FAILURE (Status))
00342     {
00343         return_ACPI_STATUS (Status);
00344     }
00345 
00346     if (SleepState != ACPI_STATE_S5)
00347     {
00348         /*
00349          * Disable BM arbitration. This feature is contained within an
00350          * optional register (PM2 Control), so ignore a BAD_ADDRESS
00351          * exception.
00352          */
00353         Status = AcpiWriteBitRegister (ACPI_BITREG_ARB_DISABLE, 1);
00354         if (ACPI_FAILURE (Status) && (Status != AE_BAD_ADDRESS))
00355         {
00356             return_ACPI_STATUS (Status);
00357         }
00358     }
00359 
00360     /*
00361      * 1) Disable/Clear all GPEs
00362      * 2) Enable all wakeup GPEs
00363      */
00364     Status = AcpiHwDisableAllGpes ();
00365     if (ACPI_FAILURE (Status))
00366     {
00367         return_ACPI_STATUS (Status);
00368     }
00369     AcpiGbl_SystemAwakeAndRunning = FALSE;
00370 
00371     Status = AcpiHwEnableAllWakeupGpes ();
00372     if (ACPI_FAILURE (Status))
00373     {
00374         return_ACPI_STATUS (Status);
00375     }
00376 
00377     /* Execute the _GTS method (Going To Sleep) */
00378 
00379     ArgList.Count = 1;
00380     ArgList.Pointer = &Arg;
00381     Arg.Type = ACPI_TYPE_INTEGER;
00382     Arg.Integer.Value = SleepState;
00383 
00384     Status = AcpiEvaluateObject (NULL, METHOD_NAME__GTS, &ArgList, NULL);
00385     if (ACPI_FAILURE (Status) && Status != AE_NOT_FOUND)
00386     {
00387         return_ACPI_STATUS (Status);
00388     }
00389 
00390     /* Get current value of PM1A control */
00391 
00392     Status = AcpiHwRegisterRead (ACPI_REGISTER_PM1_CONTROL,
00393                 &Pm1aControl);
00394     if (ACPI_FAILURE (Status))
00395     {
00396         return_ACPI_STATUS (Status);
00397     }
00398     ACPI_DEBUG_PRINT ((ACPI_DB_INIT,
00399         "Entering sleep state [S%u]\n", SleepState));
00400 
00401     /* Clear the SLP_EN and SLP_TYP fields */
00402 
00403     Pm1aControl &= ~(SleepTypeRegInfo->AccessBitMask |
00404                      SleepEnableRegInfo->AccessBitMask);
00405     Pm1bControl = Pm1aControl;
00406 
00407     /* Insert the SLP_TYP bits */
00408 
00409     Pm1aControl |= (AcpiGbl_SleepTypeA << SleepTypeRegInfo->BitPosition);
00410     Pm1bControl |= (AcpiGbl_SleepTypeB << SleepTypeRegInfo->BitPosition);
00411 
00412     /*
00413      * We split the writes of SLP_TYP and SLP_EN to workaround
00414      * poorly implemented hardware.
00415      */
00416 
00417     /* Write #1: write the SLP_TYP data to the PM1 Control registers */
00418 
00419     Status = AcpiHwWritePm1Control (Pm1aControl, Pm1bControl);
00420     if (ACPI_FAILURE (Status))
00421     {
00422         return_ACPI_STATUS (Status);
00423     }
00424 
00425     /* Insert the sleep enable (SLP_EN) bit */
00426 
00427     Pm1aControl |= SleepEnableRegInfo->AccessBitMask;
00428     Pm1bControl |= SleepEnableRegInfo->AccessBitMask;
00429 
00430     /* Flush caches, as per ACPI specification */
00431 
00432     ACPI_FLUSH_CPU_CACHE ();
00433 
00434     /* Write #2: Write both SLP_TYP + SLP_EN */
00435 
00436     Status = AcpiHwWritePm1Control (Pm1aControl, Pm1bControl);
00437     if (ACPI_FAILURE (Status))
00438     {
00439         return_ACPI_STATUS (Status);
00440     }
00441 
00442     if (SleepState > ACPI_STATE_S3)
00443     {
00444         /*
00445          * We wanted to sleep > S3, but it didn't happen (by virtue of the
00446          * fact that we are still executing!)
00447          *
00448          * Wait ten seconds, then try again. This is to get S4/S5 to work on
00449          * all machines.
00450          *
00451          * We wait so long to allow chipsets that poll this reg very slowly
00452          * to still read the right value. Ideally, this block would go
00453          * away entirely.
00454          */
00455         AcpiOsStall (10000000);
00456 
00457         Status = AcpiHwRegisterWrite (ACPI_REGISTER_PM1_CONTROL,
00458                     SleepEnableRegInfo->AccessBitMask);
00459         if (ACPI_FAILURE (Status))
00460         {
00461             return_ACPI_STATUS (Status);
00462         }
00463     }
00464 
00465     /* Wait until we enter sleep state */
00466 
00467     do
00468     {
00469         Status = AcpiReadBitRegister (ACPI_BITREG_WAKE_STATUS, &InValue);
00470         if (ACPI_FAILURE (Status))
00471         {
00472             return_ACPI_STATUS (Status);
00473         }
00474 
00475         /* Spin until we wake */
00476 
00477     } while (!InValue);
00478 
00479     return_ACPI_STATUS (AE_OK);
00480 }
00481 
00482 ACPI_EXPORT_SYMBOL (AcpiEnterSleepState)
00483 
00484 
00485 /*******************************************************************************
00486  *
00487  * FUNCTION:    AcpiEnterSleepStateS4bios
00488  *
00489  * PARAMETERS:  None
00490  *
00491  * RETURN:      Status
00492  *
00493  * DESCRIPTION: Perform a S4 bios request.
00494  *              THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED
00495  *
00496  ******************************************************************************/
00497 
00498 ACPI_STATUS
00499 AcpiEnterSleepStateS4bios (
00500     void)
00501 {
00502     UINT32                  InValue;
00503     ACPI_STATUS             Status;
00504 
00505 
00506     ACPI_FUNCTION_TRACE (AcpiEnterSleepStateS4bios);
00507 
00508 
00509     /* Clear the wake status bit (PM1) */
00510 
00511     Status = AcpiWriteBitRegister (ACPI_BITREG_WAKE_STATUS, ACPI_CLEAR_STATUS);
00512     if (ACPI_FAILURE (Status))
00513     {
00514         return_ACPI_STATUS (Status);
00515     }
00516 
00517     Status = AcpiHwClearAcpiStatus ();
00518     if (ACPI_FAILURE (Status))
00519     {
00520         return_ACPI_STATUS (Status);
00521     }
00522 
00523     /*
00524      * 1) Disable/Clear all GPEs
00525      * 2) Enable all wakeup GPEs
00526      */
00527     Status = AcpiHwDisableAllGpes ();
00528     if (ACPI_FAILURE (Status))
00529     {
00530         return_ACPI_STATUS (Status);
00531     }
00532     AcpiGbl_SystemAwakeAndRunning = FALSE;
00533 
00534     Status = AcpiHwEnableAllWakeupGpes ();
00535     if (ACPI_FAILURE (Status))
00536     {
00537         return_ACPI_STATUS (Status);
00538     }
00539 
00540     ACPI_FLUSH_CPU_CACHE ();
00541 
00542     Status = AcpiHwWritePort (AcpiGbl_FADT.SmiCommand,
00543                 (UINT32) AcpiGbl_FADT.S4BiosRequest, 8);
00544 
00545     do {
00546         AcpiOsStall(1000);
00547         Status = AcpiReadBitRegister (ACPI_BITREG_WAKE_STATUS, &InValue);
00548         if (ACPI_FAILURE (Status))
00549         {
00550             return_ACPI_STATUS (Status);
00551         }
00552     } while (!InValue);
00553 
00554     return_ACPI_STATUS (AE_OK);
00555 }
00556 
00557 ACPI_EXPORT_SYMBOL (AcpiEnterSleepStateS4bios)
00558 
00559 
00560 /*******************************************************************************
00561  *
00562  * FUNCTION:    AcpiLeaveSleepState
00563  *
00564  * PARAMETERS:  SleepState          - Which sleep state we just exited
00565  *
00566  * RETURN:      Status
00567  *
00568  * DESCRIPTION: Perform OS-independent ACPI cleanup after a sleep
00569  *              Called with interrupts ENABLED.
00570  *
00571  ******************************************************************************/
00572 
00573 ACPI_STATUS
00574 AcpiLeaveSleepState (
00575     UINT8                   SleepState)
00576 {
00577     ACPI_OBJECT_LIST        ArgList;
00578     ACPI_OBJECT             Arg;
00579     ACPI_STATUS             Status;
00580     ACPI_BIT_REGISTER_INFO  *SleepTypeRegInfo;
00581     ACPI_BIT_REGISTER_INFO  *SleepEnableRegInfo;
00582     UINT32                  Pm1aControl;
00583     UINT32                  Pm1bControl;
00584 
00585 
00586     ACPI_FUNCTION_TRACE (AcpiLeaveSleepState);
00587 
00588 
00589     /*
00590      * Set SLP_TYPE and SLP_EN to state S0.
00591      * This is unclear from the ACPI Spec, but it is required
00592      * by some machines.
00593      */
00594     Status = AcpiGetSleepTypeData (ACPI_STATE_S0,
00595                     &AcpiGbl_SleepTypeA, &AcpiGbl_SleepTypeB);
00596     if (ACPI_SUCCESS (Status))
00597     {
00598         SleepTypeRegInfo =
00599             AcpiHwGetBitRegisterInfo (ACPI_BITREG_SLEEP_TYPE);
00600         SleepEnableRegInfo =
00601             AcpiHwGetBitRegisterInfo (ACPI_BITREG_SLEEP_ENABLE);
00602 
00603         /* Get current value of PM1A control */
00604 
00605         Status = AcpiHwRegisterRead (ACPI_REGISTER_PM1_CONTROL,
00606                     &Pm1aControl);
00607         if (ACPI_SUCCESS (Status))
00608         {
00609             /* Clear the SLP_EN and SLP_TYP fields */
00610 
00611             Pm1aControl &= ~(SleepTypeRegInfo->AccessBitMask |
00612                 SleepEnableRegInfo->AccessBitMask);
00613             Pm1bControl = Pm1aControl;
00614 
00615             /* Insert the SLP_TYP bits */
00616 
00617             Pm1aControl |= (AcpiGbl_SleepTypeA <<
00618                 SleepTypeRegInfo->BitPosition);
00619             Pm1bControl |= (AcpiGbl_SleepTypeB <<
00620                 SleepTypeRegInfo->BitPosition);
00621 
00622             /* Write the control registers and ignore any errors */
00623 
00624             (void) AcpiHwWritePm1Control (Pm1aControl, Pm1bControl);
00625         }
00626     }
00627 
00628     /* Ensure EnterSleepStatePrep -> EnterSleepState ordering */
00629 
00630     AcpiGbl_SleepTypeA = ACPI_SLEEP_TYPE_INVALID;
00631 
00632     /* Setup parameter object */
00633 
00634     ArgList.Count = 1;
00635     ArgList.Pointer = &Arg;
00636     Arg.Type = ACPI_TYPE_INTEGER;
00637 
00638     /* Ignore any errors from these methods */
00639 
00640     Arg.Integer.Value = ACPI_SST_WAKING;
00641     Status = AcpiEvaluateObject (NULL, METHOD_NAME__SST, &ArgList, NULL);
00642     if (ACPI_FAILURE (Status) && Status != AE_NOT_FOUND)
00643     {
00644         ACPI_EXCEPTION ((AE_INFO, Status, "During Method _SST"));
00645     }
00646 
00647     Arg.Integer.Value = SleepState;
00648     Status = AcpiEvaluateObject (NULL, METHOD_NAME__BFS, &ArgList, NULL);
00649     if (ACPI_FAILURE (Status) && Status != AE_NOT_FOUND)
00650     {
00651         ACPI_EXCEPTION ((AE_INFO, Status, "During Method _BFS"));
00652     }
00653 
00654     Status = AcpiEvaluateObject (NULL, METHOD_NAME__WAK, &ArgList, NULL);
00655     if (ACPI_FAILURE (Status) && Status != AE_NOT_FOUND)
00656     {
00657         ACPI_EXCEPTION ((AE_INFO, Status, "During Method _WAK"));
00658     }
00659     /* TBD: _WAK "sometimes" returns stuff - do we want to look at it? */
00660 
00661     /*
00662      * Restore the GPEs:
00663      * 1) Disable/Clear all GPEs
00664      * 2) Enable all runtime GPEs
00665      */
00666     Status = AcpiHwDisableAllGpes ();
00667     if (ACPI_FAILURE (Status))
00668     {
00669         return_ACPI_STATUS (Status);
00670     }
00671     AcpiGbl_SystemAwakeAndRunning = TRUE;
00672 
00673     Status = AcpiHwEnableAllRuntimeGpes ();
00674     if (ACPI_FAILURE (Status))
00675     {
00676         return_ACPI_STATUS (Status);
00677     }
00678 
00679     /* Enable power button */
00680 
00681     (void) AcpiWriteBitRegister(
00682             AcpiGbl_FixedEventInfo[ACPI_EVENT_POWER_BUTTON].EnableRegisterId,
00683             ACPI_ENABLE_EVENT);
00684 
00685     (void) AcpiWriteBitRegister(
00686             AcpiGbl_FixedEventInfo[ACPI_EVENT_POWER_BUTTON].StatusRegisterId,
00687             ACPI_CLEAR_STATUS);
00688 
00689     /*
00690      * Enable BM arbitration. This feature is contained within an
00691      * optional register (PM2 Control), so ignore a BAD_ADDRESS
00692      * exception.
00693      */
00694     Status = AcpiWriteBitRegister (ACPI_BITREG_ARB_DISABLE, 0);
00695     if (ACPI_FAILURE (Status) && (Status != AE_BAD_ADDRESS))
00696     {
00697         return_ACPI_STATUS (Status);
00698     }
00699 
00700     Arg.Integer.Value = ACPI_SST_WORKING;
00701     Status = AcpiEvaluateObject (NULL, METHOD_NAME__SST, &ArgList, NULL);
00702     if (ACPI_FAILURE (Status) && Status != AE_NOT_FOUND)
00703     {
00704         ACPI_EXCEPTION ((AE_INFO, Status, "During Method _SST"));
00705     }
00706 
00707     return_ACPI_STATUS (Status);
00708 }
00709 
00710 ACPI_EXPORT_SYMBOL (AcpiLeaveSleepState)
00711 

Generated on Sat May 26 2012 04:25:47 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.