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

hwxface.c
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003  *
00004  * Module Name: hwxface - Public ACPICA hardware interfaces
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 #include "acnamesp.h"
00120 
00121 #define _COMPONENT          ACPI_HARDWARE
00122         ACPI_MODULE_NAME    ("hwxface")
00123 
00124 
00125 /******************************************************************************
00126  *
00127  * FUNCTION:    AcpiReset
00128  *
00129  * PARAMETERS:  None
00130  *
00131  * RETURN:      Status
00132  *
00133  * DESCRIPTION: Set reset register in memory or IO space. Note: Does not
00134  *              support reset register in PCI config space, this must be
00135  *              handled separately.
00136  *
00137  ******************************************************************************/
00138 
00139 ACPI_STATUS
00140 AcpiReset (
00141     void)
00142 {
00143     ACPI_GENERIC_ADDRESS    *ResetReg;
00144     ACPI_STATUS             Status;
00145 
00146 
00147     ACPI_FUNCTION_TRACE (AcpiReset);
00148 
00149 
00150     ResetReg = &AcpiGbl_FADT.ResetRegister;
00151 
00152     /* Check if the reset register is supported */
00153 
00154     if (!(AcpiGbl_FADT.Flags & ACPI_FADT_RESET_REGISTER) ||
00155         !ResetReg->Address)
00156     {
00157         return_ACPI_STATUS (AE_NOT_EXIST);
00158     }
00159 
00160     if (ResetReg->SpaceId == ACPI_ADR_SPACE_SYSTEM_IO)
00161     {
00162         /*
00163          * For I/O space, write directly to the OSL. This bypasses the port
00164          * validation mechanism, which may block a valid write to the reset
00165          * register.
00166          */
00167         Status = AcpiOsWritePort ((ACPI_IO_ADDRESS) ResetReg->Address,
00168                     AcpiGbl_FADT.ResetValue, ResetReg->BitWidth);
00169     }
00170     else
00171     {
00172         /* Write the reset value to the reset register */
00173 
00174         Status = AcpiHwWrite (AcpiGbl_FADT.ResetValue, ResetReg);
00175     }
00176 
00177     return_ACPI_STATUS (Status);
00178 }
00179 
00180 ACPI_EXPORT_SYMBOL (AcpiReset)
00181 
00182 
00183 /******************************************************************************
00184  *
00185  * FUNCTION:    AcpiRead
00186  *
00187  * PARAMETERS:  Value               - Where the value is returned
00188  *              Reg                 - GAS register structure
00189  *
00190  * RETURN:      Status
00191  *
00192  * DESCRIPTION: Read from either memory or IO space.
00193  *
00194  * LIMITATIONS: <These limitations also apply to AcpiWrite>
00195  *      BitWidth must be exactly 8, 16, 32, or 64.
00196  *      SpaceID must be SystemMemory or SystemIO.
00197  *      BitOffset and AccessWidth are currently ignored, as there has
00198  *          not been a need to implement these.
00199  *
00200  ******************************************************************************/
00201 
00202 ACPI_STATUS
00203 AcpiRead (
00204     UINT64                  *ReturnValue,
00205     ACPI_GENERIC_ADDRESS    *Reg)
00206 {
00207     UINT32                  Value;
00208     UINT32                  Width;
00209     UINT64                  Address;
00210     ACPI_STATUS             Status;
00211 
00212 
00213     ACPI_FUNCTION_NAME (AcpiRead);
00214 
00215 
00216     if (!ReturnValue)
00217     {
00218         return (AE_BAD_PARAMETER);
00219     }
00220 
00221     /* Validate contents of the GAS register. Allow 64-bit transfers */
00222 
00223     Status = AcpiHwValidateRegister (Reg, 64, &Address);
00224     if (ACPI_FAILURE (Status))
00225     {
00226         return (Status);
00227     }
00228 
00229     Width = Reg->BitWidth;
00230     if (Width == 64)
00231     {
00232         Width = 32; /* Break into two 32-bit transfers */
00233     }
00234 
00235     /* Initialize entire 64-bit return value to zero */
00236 
00237     *ReturnValue = 0;
00238     Value = 0;
00239 
00240     /*
00241      * Two address spaces supported: Memory or IO. PCI_Config is
00242      * not supported here because the GAS structure is insufficient
00243      */
00244     if (Reg->SpaceId == ACPI_ADR_SPACE_SYSTEM_MEMORY)
00245     {
00246         Status = AcpiOsReadMemory ((ACPI_PHYSICAL_ADDRESS)
00247                     Address, &Value, Width);
00248         if (ACPI_FAILURE (Status))
00249         {
00250             return (Status);
00251         }
00252         *ReturnValue = Value;
00253 
00254         if (Reg->BitWidth == 64)
00255         {
00256             /* Read the top 32 bits */
00257 
00258             Status = AcpiOsReadMemory ((ACPI_PHYSICAL_ADDRESS)
00259                         (Address + 4), &Value, 32);
00260             if (ACPI_FAILURE (Status))
00261             {
00262                 return (Status);
00263             }
00264             *ReturnValue |= ((UINT64) Value << 32);
00265         }
00266     }
00267     else /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */
00268     {
00269         Status = AcpiHwReadPort ((ACPI_IO_ADDRESS)
00270                     Address, &Value, Width);
00271         if (ACPI_FAILURE (Status))
00272         {
00273             return (Status);
00274         }
00275         *ReturnValue = Value;
00276 
00277         if (Reg->BitWidth == 64)
00278         {
00279             /* Read the top 32 bits */
00280 
00281             Status = AcpiHwReadPort ((ACPI_IO_ADDRESS)
00282                         (Address + 4), &Value, 32);
00283             if (ACPI_FAILURE (Status))
00284             {
00285                 return (Status);
00286             }
00287             *ReturnValue |= ((UINT64) Value << 32);
00288         }
00289     }
00290 
00291     ACPI_DEBUG_PRINT ((ACPI_DB_IO,
00292         "Read:  %8.8X%8.8X width %2d from %8.8X%8.8X (%s)\n",
00293         ACPI_FORMAT_UINT64 (*ReturnValue), Reg->BitWidth,
00294         ACPI_FORMAT_UINT64 (Address),
00295         AcpiUtGetRegionName (Reg->SpaceId)));
00296 
00297     return (Status);
00298 }
00299 
00300 ACPI_EXPORT_SYMBOL (AcpiRead)
00301 
00302 
00303 /******************************************************************************
00304  *
00305  * FUNCTION:    AcpiWrite
00306  *
00307  * PARAMETERS:  Value               - Value to be written
00308  *              Reg                 - GAS register structure
00309  *
00310  * RETURN:      Status
00311  *
00312  * DESCRIPTION: Write to either memory or IO space.
00313  *
00314  ******************************************************************************/
00315 
00316 ACPI_STATUS
00317 AcpiWrite (
00318     UINT64                  Value,
00319     ACPI_GENERIC_ADDRESS    *Reg)
00320 {
00321     UINT32                  Width;
00322     UINT64                  Address;
00323     ACPI_STATUS             Status;
00324 
00325 
00326     ACPI_FUNCTION_NAME (AcpiWrite);
00327 
00328 
00329     /* Validate contents of the GAS register. Allow 64-bit transfers */
00330 
00331     Status = AcpiHwValidateRegister (Reg, 64, &Address);
00332     if (ACPI_FAILURE (Status))
00333     {
00334         return (Status);
00335     }
00336 
00337     Width = Reg->BitWidth;
00338     if (Width == 64)
00339     {
00340         Width = 32; /* Break into two 32-bit transfers */
00341     }
00342 
00343     /*
00344      * Two address spaces supported: Memory or IO. PCI_Config is
00345      * not supported here because the GAS structure is insufficient
00346      */
00347     if (Reg->SpaceId == ACPI_ADR_SPACE_SYSTEM_MEMORY)
00348     {
00349         Status = AcpiOsWriteMemory ((ACPI_PHYSICAL_ADDRESS)
00350                     Address, ACPI_LODWORD (Value), Width);
00351         if (ACPI_FAILURE (Status))
00352         {
00353             return (Status);
00354         }
00355 
00356         if (Reg->BitWidth == 64)
00357         {
00358             Status = AcpiOsWriteMemory ((ACPI_PHYSICAL_ADDRESS)
00359                         (Address + 4), ACPI_HIDWORD (Value), 32);
00360             if (ACPI_FAILURE (Status))
00361             {
00362                 return (Status);
00363             }
00364         }
00365     }
00366     else /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */
00367     {
00368         Status = AcpiHwWritePort ((ACPI_IO_ADDRESS)
00369                     Address, ACPI_LODWORD (Value), Width);
00370         if (ACPI_FAILURE (Status))
00371         {
00372             return (Status);
00373         }
00374 
00375         if (Reg->BitWidth == 64)
00376         {
00377             Status = AcpiHwWritePort ((ACPI_IO_ADDRESS)
00378                         (Address + 4), ACPI_HIDWORD (Value), 32);
00379             if (ACPI_FAILURE (Status))
00380             {
00381                 return (Status);
00382             }
00383         }
00384     }
00385 
00386     ACPI_DEBUG_PRINT ((ACPI_DB_IO,
00387         "Wrote: %8.8X%8.8X width %2d   to %8.8X%8.8X (%s)\n",
00388         ACPI_FORMAT_UINT64 (Value), Reg->BitWidth,
00389         ACPI_FORMAT_UINT64 (Address),
00390         AcpiUtGetRegionName (Reg->SpaceId)));
00391 
00392     return (Status);
00393 }
00394 
00395 ACPI_EXPORT_SYMBOL (AcpiWrite)
00396 
00397 
00398 /*******************************************************************************
00399  *
00400  * FUNCTION:    AcpiReadBitRegister
00401  *
00402  * PARAMETERS:  RegisterId      - ID of ACPI Bit Register to access
00403  *              ReturnValue     - Value that was read from the register,
00404  *                                normalized to bit position zero.
00405  *
00406  * RETURN:      Status and the value read from the specified Register. Value
00407  *              returned is normalized to bit0 (is shifted all the way right)
00408  *
00409  * DESCRIPTION: ACPI BitRegister read function. Does not acquire the HW lock.
00410  *
00411  * SUPPORTS:    Bit fields in PM1 Status, PM1 Enable, PM1 Control, and
00412  *              PM2 Control.
00413  *
00414  * Note: The hardware lock is not required when reading the ACPI bit registers
00415  *       since almost all of them are single bit and it does not matter that
00416  *       the parent hardware register can be split across two physical
00417  *       registers. The only multi-bit field is SLP_TYP in the PM1 control
00418  *       register, but this field does not cross an 8-bit boundary (nor does
00419  *       it make much sense to actually read this field.)
00420  *
00421  ******************************************************************************/
00422 
00423 ACPI_STATUS
00424 AcpiReadBitRegister (
00425     UINT32                  RegisterId,
00426     UINT32                  *ReturnValue)
00427 {
00428     ACPI_BIT_REGISTER_INFO  *BitRegInfo;
00429     UINT32                  RegisterValue;
00430     UINT32                  Value;
00431     ACPI_STATUS             Status;
00432 
00433 
00434     ACPI_FUNCTION_TRACE_U32 (AcpiReadBitRegister, RegisterId);
00435 
00436 
00437     /* Get the info structure corresponding to the requested ACPI Register */
00438 
00439     BitRegInfo = AcpiHwGetBitRegisterInfo (RegisterId);
00440     if (!BitRegInfo)
00441     {
00442         return_ACPI_STATUS (AE_BAD_PARAMETER);
00443     }
00444 
00445     /* Read the entire parent register */
00446 
00447     Status = AcpiHwRegisterRead (BitRegInfo->ParentRegister,
00448                 &RegisterValue);
00449     if (ACPI_FAILURE (Status))
00450     {
00451         return_ACPI_STATUS (Status);
00452     }
00453 
00454     /* Normalize the value that was read, mask off other bits */
00455 
00456     Value = ((RegisterValue & BitRegInfo->AccessBitMask)
00457                 >> BitRegInfo->BitPosition);
00458 
00459     ACPI_DEBUG_PRINT ((ACPI_DB_IO,
00460         "BitReg %X, ParentReg %X, Actual %8.8X, ReturnValue %8.8X\n",
00461         RegisterId, BitRegInfo->ParentRegister, RegisterValue, Value));
00462 
00463     *ReturnValue = Value;
00464     return_ACPI_STATUS (AE_OK);
00465 }
00466 
00467 ACPI_EXPORT_SYMBOL (AcpiReadBitRegister)
00468 
00469 
00470 /*******************************************************************************
00471  *
00472  * FUNCTION:    AcpiWriteBitRegister
00473  *
00474  * PARAMETERS:  RegisterId      - ID of ACPI Bit Register to access
00475  *              Value           - Value to write to the register, in bit
00476  *                                position zero. The bit is automaticallly
00477  *                                shifted to the correct position.
00478  *
00479  * RETURN:      Status
00480  *
00481  * DESCRIPTION: ACPI Bit Register write function. Acquires the hardware lock
00482  *              since most operations require a read/modify/write sequence.
00483  *
00484  * SUPPORTS:    Bit fields in PM1 Status, PM1 Enable, PM1 Control, and
00485  *              PM2 Control.
00486  *
00487  * Note that at this level, the fact that there may be actually two
00488  * hardware registers (A and B - and B may not exist) is abstracted.
00489  *
00490  ******************************************************************************/
00491 
00492 ACPI_STATUS
00493 AcpiWriteBitRegister (
00494     UINT32                  RegisterId,
00495     UINT32                  Value)
00496 {
00497     ACPI_BIT_REGISTER_INFO  *BitRegInfo;
00498     ACPI_CPU_FLAGS          LockFlags;
00499     UINT32                  RegisterValue;
00500     ACPI_STATUS             Status = AE_OK;
00501 
00502 
00503     ACPI_FUNCTION_TRACE_U32 (AcpiWriteBitRegister, RegisterId);
00504 
00505 
00506     /* Get the info structure corresponding to the requested ACPI Register */
00507 
00508     BitRegInfo = AcpiHwGetBitRegisterInfo (RegisterId);
00509     if (!BitRegInfo)
00510     {
00511         return_ACPI_STATUS (AE_BAD_PARAMETER);
00512     }
00513 
00514     LockFlags = AcpiOsAcquireLock (AcpiGbl_HardwareLock);
00515 
00516     /*
00517      * At this point, we know that the parent register is one of the
00518      * following: PM1 Status, PM1 Enable, PM1 Control, or PM2 Control
00519      */
00520     if (BitRegInfo->ParentRegister != ACPI_REGISTER_PM1_STATUS)
00521     {
00522         /*
00523          * 1) Case for PM1 Enable, PM1 Control, and PM2 Control
00524          *
00525          * Perform a register read to preserve the bits that we are not
00526          * interested in
00527          */
00528         Status = AcpiHwRegisterRead (BitRegInfo->ParentRegister,
00529                     &RegisterValue);
00530         if (ACPI_FAILURE (Status))
00531         {
00532             goto UnlockAndExit;
00533         }
00534 
00535         /*
00536          * Insert the input bit into the value that was just read
00537          * and write the register
00538          */
00539         ACPI_REGISTER_INSERT_VALUE (RegisterValue, BitRegInfo->BitPosition,
00540             BitRegInfo->AccessBitMask, Value);
00541 
00542         Status = AcpiHwRegisterWrite (BitRegInfo->ParentRegister,
00543                     RegisterValue);
00544     }
00545     else
00546     {
00547         /*
00548          * 2) Case for PM1 Status
00549          *
00550          * The Status register is different from the rest. Clear an event
00551          * by writing 1, writing 0 has no effect. So, the only relevant
00552          * information is the single bit we're interested in, all others
00553          * should be written as 0 so they will be left unchanged.
00554          */
00555         RegisterValue = ACPI_REGISTER_PREPARE_BITS (Value,
00556             BitRegInfo->BitPosition, BitRegInfo->AccessBitMask);
00557 
00558         /* No need to write the register if value is all zeros */
00559 
00560         if (RegisterValue)
00561         {
00562             Status = AcpiHwRegisterWrite (ACPI_REGISTER_PM1_STATUS,
00563                         RegisterValue);
00564         }
00565     }
00566 
00567     ACPI_DEBUG_PRINT ((ACPI_DB_IO,
00568         "BitReg %X, ParentReg %X, Value %8.8X, Actual %8.8X\n",
00569         RegisterId, BitRegInfo->ParentRegister, Value, RegisterValue));
00570 
00571 
00572 UnlockAndExit:
00573 
00574     AcpiOsReleaseLock (AcpiGbl_HardwareLock, LockFlags);
00575     return_ACPI_STATUS (Status);
00576 }
00577 
00578 ACPI_EXPORT_SYMBOL (AcpiWriteBitRegister)
00579 
00580 
00581 /*******************************************************************************
00582  *
00583  * FUNCTION:    AcpiGetSleepTypeData
00584  *
00585  * PARAMETERS:  SleepState          - Numeric sleep state
00586  *              *SleepTypeA         - Where SLP_TYPa is returned
00587  *              *SleepTypeB         - Where SLP_TYPb is returned
00588  *
00589  * RETURN:      Status - ACPI status
00590  *
00591  * DESCRIPTION: Obtain the SLP_TYPa and SLP_TYPb values for the requested sleep
00592  *              state.
00593  *
00594  ******************************************************************************/
00595 
00596 ACPI_STATUS
00597 AcpiGetSleepTypeData (
00598     UINT8                   SleepState,
00599     UINT8                   *SleepTypeA,
00600     UINT8                   *SleepTypeB)
00601 {
00602     ACPI_STATUS             Status = AE_OK;
00603     ACPI_EVALUATE_INFO      *Info;
00604 
00605 
00606     ACPI_FUNCTION_TRACE (AcpiGetSleepTypeData);
00607 
00608 
00609     /* Validate parameters */
00610 
00611     if ((SleepState > ACPI_S_STATES_MAX) ||
00612         !SleepTypeA ||
00613         !SleepTypeB)
00614     {
00615         return_ACPI_STATUS (AE_BAD_PARAMETER);
00616     }
00617 
00618     /* Allocate the evaluation information block */
00619 
00620     Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO));
00621     if (!Info)
00622     {
00623         return_ACPI_STATUS (AE_NO_MEMORY);
00624     }
00625 
00626     Info->Pathname = ACPI_CAST_PTR (char, AcpiGbl_SleepStateNames[SleepState]);
00627 
00628     /* Evaluate the namespace object containing the values for this state */
00629 
00630     Status = AcpiNsEvaluate (Info);
00631     if (ACPI_FAILURE (Status))
00632     {
00633         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
00634             "%s while evaluating SleepState [%s]\n",
00635             AcpiFormatException (Status), Info->Pathname));
00636 
00637         goto Cleanup;
00638     }
00639 
00640     /* Must have a return object */
00641 
00642     if (!Info->ReturnObject)
00643     {
00644         ACPI_ERROR ((AE_INFO, "No Sleep State object returned from [%s]",
00645             Info->Pathname));
00646         Status = AE_NOT_EXIST;
00647     }
00648 
00649     /* It must be of type Package */
00650 
00651     else if (Info->ReturnObject->Common.Type != ACPI_TYPE_PACKAGE)
00652     {
00653         ACPI_ERROR ((AE_INFO, "Sleep State return object is not a Package"));
00654         Status = AE_AML_OPERAND_TYPE;
00655     }
00656 
00657     /*
00658      * The package must have at least two elements. NOTE (March 2005): This
00659      * goes against the current ACPI spec which defines this object as a
00660      * package with one encoded DWORD element. However, existing practice
00661      * by BIOS vendors seems to be to have 2 or more elements, at least
00662      * one per sleep type (A/B).
00663      */
00664     else if (Info->ReturnObject->Package.Count < 2)
00665     {
00666         ACPI_ERROR ((AE_INFO,
00667             "Sleep State return package does not have at least two elements"));
00668         Status = AE_AML_NO_OPERAND;
00669     }
00670 
00671     /* The first two elements must both be of type Integer */
00672 
00673     else if (((Info->ReturnObject->Package.Elements[0])->Common.Type
00674                 != ACPI_TYPE_INTEGER) ||
00675              ((Info->ReturnObject->Package.Elements[1])->Common.Type
00676                 != ACPI_TYPE_INTEGER))
00677     {
00678         ACPI_ERROR ((AE_INFO,
00679             "Sleep State return package elements are not both Integers "
00680             "(%s, %s)",
00681             AcpiUtGetObjectTypeName (Info->ReturnObject->Package.Elements[0]),
00682             AcpiUtGetObjectTypeName (Info->ReturnObject->Package.Elements[1])));
00683         Status = AE_AML_OPERAND_TYPE;
00684     }
00685     else
00686     {
00687         /* Valid _Sx_ package size, type, and value */
00688 
00689         *SleepTypeA = (UINT8)
00690             (Info->ReturnObject->Package.Elements[0])->Integer.Value;
00691         *SleepTypeB = (UINT8)
00692             (Info->ReturnObject->Package.Elements[1])->Integer.Value;
00693     }
00694 
00695     if (ACPI_FAILURE (Status))
00696     {
00697         ACPI_EXCEPTION ((AE_INFO, Status,
00698             "While evaluating SleepState [%s], bad Sleep object %p type %s",
00699             Info->Pathname, Info->ReturnObject,
00700             AcpiUtGetObjectTypeName (Info->ReturnObject)));
00701     }
00702 
00703     AcpiUtRemoveReference (Info->ReturnObject);
00704 
00705 Cleanup:
00706     ACPI_FREE (Info);
00707     return_ACPI_STATUS (Status);
00708 }
00709 
00710 ACPI_EXPORT_SYMBOL (AcpiGetSleepTypeData)

Generated on Sun May 27 2012 04:27:17 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.