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

system.c
Go to the documentation of this file.
00001 /*
00002  *  acpi_system.c - ACPI System Driver ($Revision: 57 $)
00003  *
00004  *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
00005  *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
00006  *
00007  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00008  *
00009  *  This program is free software; you can redistribute it and/or modify
00010  *  it under the terms of the GNU General Public License as published by
00011  *  the Free Software Foundation; either version 2 of the License, or (at
00012  *  your option) any later version.
00013  *
00014  *  This program is distributed in the hope that it will be useful, but
00015  *  WITHOUT ANY WARRANTY; without even the implied warranty of
00016  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017  *  General Public License for more details.
00018  *
00019  *  You should have received a copy of the GNU General Public License along
00020  *  with this program; if not, write to the Free Software Foundation, Inc.,
00021  *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
00022  *
00023  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00024  */
00025 
00026 /* Modified for ReactOS and latest ACPICA
00027  * Copyright (C)2009  Samuel Serapion 
00028  */
00029 #include <ntddk.h>
00030 #include <acpi.h>
00031 #include <acpi_bus.h>
00032 #include <acpi_drivers.h>
00033 #include "list.h"
00034 
00035 #define NDEBUG
00036 #include <debug.h>
00037 
00038 ACPI_STATUS acpi_system_save_state(UINT32);
00039 
00040 #define _COMPONENT      ACPI_SYSTEM_COMPONENT
00041 ACPI_MODULE_NAME        ("acpi_system")
00042 
00043 #define PREFIX          "ACPI: "
00044 
00045 static int acpi_system_add (struct acpi_device *device);
00046 static int acpi_system_remove (struct acpi_device *device, int type);
00047 
00048 ACPI_STATUS acpi_suspend (UINT32 state);
00049 
00050 static struct acpi_driver acpi_system_driver = {
00051     {0,0},
00052     ACPI_SYSTEM_DRIVER_NAME,
00053     ACPI_SYSTEM_CLASS,
00054     0,
00055     0,
00056     ACPI_SYSTEM_HID,
00057     {acpi_system_add, acpi_system_remove}
00058 };
00059 
00060 struct acpi_system
00061 {
00062     ACPI_HANDLE     handle;
00063     UINT8           states[ACPI_S_STATE_COUNT];
00064 };
00065 
00066 
00067 static int
00068 acpi_system_add (
00069     struct acpi_device  *device)
00070 {
00071     int         result = 0;
00072     ACPI_STATUS     status = AE_OK;
00073     struct acpi_system  *system = NULL;
00074     UINT8           i = 0;
00075 
00076     ACPI_FUNCTION_TRACE("acpi_system_add");
00077 
00078     if (!device)
00079         return_VALUE(-1);
00080 
00081     system = ExAllocatePoolWithTag(NonPagedPool,sizeof(struct acpi_system),'IPCA');
00082     if (!system)
00083         return_VALUE(-14);
00084     memset(system, 0, sizeof(struct acpi_system));
00085 
00086     system->handle = device->handle;
00087     sprintf(acpi_device_name(device), "%s", ACPI_SYSTEM_DEVICE_NAME);
00088     sprintf(acpi_device_class(device), "%s", ACPI_SYSTEM_CLASS);
00089     acpi_driver_data(device) = system;
00090 
00091     DPRINT("%s [%s] (supports", 
00092         acpi_device_name(device), acpi_device_bid(device));
00093     for (i=0; i<ACPI_S_STATE_COUNT; i++) {
00094         UINT8 type_a, type_b;
00095         status = AcpiGetSleepTypeData(i, &type_a, &type_b);
00096         switch (i) {
00097         case ACPI_STATE_S4:
00098             if (/*AcpiGbl_FACS->S4bios_f &&*/
00099                 0 != AcpiGbl_FADT.SmiCommand) {
00100                 DPRINT(" S4bios");
00101                 system->states[i] = 1;
00102             }
00103             /* no break */
00104         default: 
00105             if (ACPI_SUCCESS(status)) {
00106                 system->states[i] = 1;
00107                 DPRINT(" S%d", i);
00108             }
00109         }
00110     }
00111 
00112 //#ifdef CONFIG_PM
00113 //  /* Install the soft-off (S5) handler. */
00114 //  if (system->states[ACPI_STATE_S5]) {
00115 //      pm_power_off = acpi_power_off;
00116 //      register_sysrq_key('o', &sysrq_acpi_poweroff_op);
00117 //  }
00118 //#endif
00119 
00120     if (result)
00121         ExFreePoolWithTag(system, 'IPCA');
00122 
00123     return_VALUE(result);
00124 }
00125 
00126 static int
00127 acpi_system_remove (
00128     struct acpi_device  *device,
00129     int         type)
00130 {
00131     struct acpi_system  *system = NULL;
00132 
00133     ACPI_FUNCTION_TRACE("acpi_system_remove");
00134 
00135     if (!device || !acpi_driver_data(device))
00136         return_VALUE(-1);
00137 
00138     system = (struct acpi_system *) acpi_driver_data(device);
00139 
00140 //#ifdef CONFIG_PM
00141 //  /* Remove the soft-off (S5) handler. */
00142 //  if (system->states[ACPI_STATE_S5]) {
00143 //      unregister_sysrq_key('o', &sysrq_acpi_poweroff_op);
00144 //      pm_power_off = NULL;
00145 //  }
00146 //#endif
00147 //
00148 //
00149     ExFreePoolWithTag(system, 'IPCA');
00150 
00151     return 0;
00152 }
00153 
00162 ACPI_STATUS
00163 acpi_system_restore_state(
00164     UINT32          state)
00165 {
00166     /* 
00167      * We should only be here if we're coming back from STR or STD.
00168      * And, in the case of the latter, the memory image should have already
00169      * been loaded from disk.
00170      */
00171     if (state > ACPI_STATE_S1) {
00172         //acpi_restore_state_mem();
00173 
00174         /* Do _early_ resume for irqs.  Required by
00175          * ACPI specs.
00176          */
00177         /* TBD: call arch dependant reinitialization of the 
00178          * interrupts.
00179          */
00180 #ifdef _X86_
00181         //init_8259A(0);
00182 #endif
00183         /* wait for power to come back */
00184         KeStallExecutionProcessor(100);
00185 
00186     }
00187 
00188     /* Be really sure that irqs are disabled. */
00189     //ACPI_DISABLE_IRQS();
00190 
00191     /* Wait a little again, just in case... */
00192     KeStallExecutionProcessor(10);
00193 
00194     /* enable interrupts once again */
00195     //ACPI_ENABLE_IRQS();
00196 
00197     /* turn all the devices back on */
00198     //if (state > ACPI_STATE_S1)
00199         //pm_send_all(PM_RESUME, (void *)0);
00200 
00201     return AE_OK;
00202 }
00203 
00204 
00218 ACPI_STATUS
00219 acpi_system_save_state(
00220     UINT32          state)
00221 {
00222     int         error = 0;
00223 
00224     /* Send notification to devices that they will be suspended.
00225      * If any device or driver cannot make the transition, either up
00226      * or down, we'll get an error back.
00227      */
00228     /*if (state > ACPI_STATE_S1) {
00229         error = pm_send_all(PM_SAVE_STATE, (void *)3);
00230         if (error)
00231             return AE_ERROR;
00232     }*/
00233 
00234     //if (state <= ACPI_STATE_S5) {
00235     //  /* Tell devices to stop I/O and actually save their state.
00236     //   * It is theoretically possible that something could fail,
00237     //   * so handle that gracefully..
00238     //   */
00239     //  if (state > ACPI_STATE_S1 && state != ACPI_STATE_S5) {
00240     //      error = pm_send_all(PM_SUSPEND, (void *)3);
00241     //      if (error) {
00242     //          /* Tell devices to restore state if they have
00243     //           * it saved and to start taking I/O requests.
00244     //           */
00245     //          pm_send_all(PM_RESUME, (void *)0);
00246     //          return error;
00247     //      }
00248     //  }
00249         
00250         /* flush caches */
00251         ACPI_FLUSH_CPU_CACHE();
00252 
00253         /* Do arch specific saving of state. */
00254         if (state > ACPI_STATE_S1) {
00255             error = 0;//acpi_save_state_mem();
00256 
00257             /* TBD: if no s4bios, write codes for
00258              * acpi_save_state_disk()...
00259              */
00260 #if 0
00261             if (!error && (state == ACPI_STATE_S4))
00262                 error = acpi_save_state_disk();
00263 #endif
00264             /*if (error) {
00265                 pm_send_all(PM_RESUME, (void *)0);
00266                 return error;
00267             }*/
00268         }
00269     //}
00270     /* disable interrupts
00271      * Note that acpi_suspend -- our caller -- will do this once we return.
00272      * But, we want it done early, so we don't get any suprises during
00273      * the device suspend sequence.
00274      */
00275     //ACPI_DISABLE_IRQS();
00276 
00277     /* Unconditionally turn off devices.
00278      * Obvious if we enter a sleep state.
00279      * If entering S5 (soft off), this should put devices in a
00280      * quiescent state.
00281      */
00282 
00283     //if (state > ACPI_STATE_S1) {
00284     //  error = pm_send_all(PM_SUSPEND, (void *)3);
00285 
00286     //  /* We're pretty screwed if we got an error from this.
00287     //   * We try to recover by simply calling our own restore_state
00288     //   * function; see above for definition.
00289     //   *
00290     //   * If it's S5 though, go through with it anyway..
00291     //   */
00292     //  if (error && state != ACPI_STATE_S5)
00293     //      acpi_system_restore_state(state);
00294     //}
00295     return error ? AE_ERROR : AE_OK;
00296 }
00297 
00298 
00299 /****************************************************************************
00300  *
00301  * FUNCTION:    acpi_system_suspend
00302  *
00303  * PARAMETERS:  %state: Sleep state to enter.
00304  *
00305  * RETURN:      ACPI_STATUS, whether or not we successfully entered and
00306  *              exited sleep.
00307  *
00308  * DESCRIPTION: Perform OS-specific action to enter sleep state.
00309  *              This is the final step in going to sleep, per spec.  If we
00310  *              know we're coming back (i.e. not entering S5), we save the
00311  *              processor flags. [ We'll have to save and restore them anyway,
00312  *              so we use the arch-agnostic save_flags and restore_flags
00313  *              here.]  We then set the place to return to in arch-specific
00314  *              globals using arch_set_return_point. Finally, we call the
00315  *              ACPI function to write the proper values to I/O ports.
00316  *
00317  ****************************************************************************/
00318 
00319 ACPI_STATUS
00320 acpi_system_suspend(
00321     UINT32      state)
00322 {
00323     ACPI_STATUS     status = AE_ERROR;
00324     //unsigned long     flags = 0;
00325 
00326     //local_irq_save(flags);
00327     /* kernel_fpu_begin(); */
00328 
00329     switch (state) {
00330     case ACPI_STATE_S1:
00331     case ACPI_STATE_S5:
00332         //barrier();
00333         status = AcpiEnterSleepState(state);
00334         break;
00335     case ACPI_STATE_S4:
00336         //do_suspend_lowlevel_s4bios(0);
00337         break;
00338     }
00339 
00340     /* kernel_fpu_end(); */
00341     //local_irq_restore(flags);
00342 
00343     return status;
00344 }
00345 
00346 
00347 
00353 ACPI_STATUS
00354 acpi_suspend (
00355     UINT32          state)
00356 {
00357     ACPI_STATUS status;
00358 
00359     /* only support S1 and S5 on kernel 2.4 */
00360     //if (state != ACPI_STATE_S1 && state != ACPI_STATE_S4
00361     //    && state != ACPI_STATE_S5)
00362     //  return AE_ERROR;
00363 
00364 
00365     //if (ACPI_STATE_S4 == state) {
00366     //  /* For s4bios, we need a wakeup address. */
00367     //  if (1 == AcpiGbl_FACS->S4bios_f &&
00368     //      0 != AcpiGbl_FADT->smi_cmd) {
00369     //      if (!acpi_wakeup_address)
00370     //          return AE_ERROR;
00371     //      AcpiSetFirmwareWakingVector((acpi_physical_address) acpi_wakeup_address);
00372     //  } else
00373     //      /* We don't support S4 under 2.4.  Give up */
00374     //      return AE_ERROR;
00375     //}
00376     AcpiEnterSleepStatePrep(state);
00377 
00378     status = AcpiEnterSleepState(state);
00379     if (!ACPI_SUCCESS(status) && state != ACPI_STATE_S5)
00380         return status;
00381 
00382     /* disable interrupts and flush caches */
00383     _disable();
00384     ACPI_FLUSH_CPU_CACHE();
00385 
00386     /* perform OS-specific sleep actions */
00387     status = acpi_system_suspend(state);
00388 
00389     /* Even if we failed to go to sleep, all of the devices are in an suspended
00390      * mode. So, we run these unconditionaly to make sure we have a usable system
00391      * no matter what.
00392      */
00393     AcpiLeaveSleepState(state);
00394     acpi_system_restore_state(state);
00395 
00396     /* make sure interrupts are enabled */
00397     _enable();
00398 
00399     /* reset firmware waking vector */
00400     AcpiSetFirmwareWakingVector((ACPI_PHYSICAL_ADDRESS) 0);
00401 
00402     return status;
00403 }
00404 
00405 int 
00406 acpi_system_init (void)
00407 {
00408     int         result = 0;
00409 
00410     ACPI_FUNCTION_TRACE("acpi_system_init");
00411 
00412     result = acpi_bus_register_driver(&acpi_system_driver);
00413     if (result < 0)
00414         return_VALUE(AE_NOT_FOUND);
00415 
00416     return_VALUE(0);
00417 }
00418 
00419 
00420 void
00421 acpi_system_exit (void)
00422 {
00423     ACPI_FUNCTION_TRACE("acpi_system_exit");
00424     acpi_bus_unregister_driver(&acpi_system_driver);
00425     return_VOID;
00426 }
00427 

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