- Call acpi_bus_set_power instead of acpi_power_transition
authorCameron Gutman <aicommander@gmail.com>
Sat, 6 Mar 2010 18:15:56 +0000 (18:15 +0000)
committerCameron Gutman <aicommander@gmail.com>
Sat, 6 Mar 2010 18:15:56 +0000 (18:15 +0000)
 - Make sure the device has power management capabilities before calling acpi_bus_set_power
 - Report the new power state with PoSetPowerState
 - Initialize PDOs with the correct device power state (Patch by Samuel Serapion)
 - Initialze PDOs with the correct system power state

svn path=/trunk/; revision=45959

reactos/drivers/bus/acpi/buspdo.c
reactos/drivers/bus/acpi/pnp.c
reactos/drivers/bus/acpi/power.c

index 8765638..92bc18b 100644 (file)
@@ -32,15 +32,10 @@ Bus_PDO_PnP (
     )
 {
     NTSTATUS                status;
-    struct acpi_device      *device = NULL;
     POWER_STATE             state;
 
     PAGED_CODE ();
 
-    if (DeviceData->AcpiHandle)
-        acpi_bus_get_device(DeviceData->AcpiHandle, &device);
-
-
     //
     // NB: Because we are a bus enumerator, we have no one to whom we could
     // defer these irps.  Therefore we do not pass them down but merely
@@ -56,9 +51,10 @@ Bus_PDO_PnP (
         // required to allow others to access this device.
         // Power up the device.
         //
-        if (device && !ACPI_SUCCESS(acpi_power_transition(device, ACPI_STATE_D0)))
+        if (DeviceData->AcpiHandle && acpi_bus_power_manageable(DeviceData->AcpiHandle) &&
+            !ACPI_SUCCESS(acpi_bus_set_power(DeviceData->AcpiHandle, ACPI_STATE_D0)))
         {
-            DPRINT1("Device %x failed to start!\n", device);
+            DPRINT1("Device %x failed to start!\n", DeviceData->AcpiHandle);
             status = STATUS_UNSUCCESSFUL;
             break;
         }
@@ -76,9 +72,10 @@ Bus_PDO_PnP (
         // Here we shut down the device and give up and unmap any resources
         // we acquired for the device.
         //
-        if (device && !ACPI_SUCCESS(acpi_power_transition(device, ACPI_STATE_D3)))
+        if (DeviceData->AcpiHandle && acpi_bus_power_manageable(DeviceData->AcpiHandle) &&
+            !ACPI_SUCCESS(acpi_bus_set_power(DeviceData->AcpiHandle, ACPI_STATE_D3)))
         {
-            DPRINT1("Device %x failed to stop!\n", device);
+            DPRINT1("Device %x failed to stop!\n", DeviceData->AcpiHandle);
             status = STATUS_UNSUCCESSFUL;
             break;
         }
@@ -125,8 +122,6 @@ Bus_PDO_PnP (
             // We did receive a query-stop, so restore.
             //
             RESTORE_PREVIOUS_PNP_STATE(DeviceData->Common);
-            if (device)
-               acpi_power_transition(device, ACPI_STATE_D0);
         }
         status = STATUS_SUCCESS;// We must not fail this IRP.
         break;
index 5b2338d..4778dc6 100644 (file)
@@ -417,6 +417,8 @@ Bus_InitializePdo (
     )
 {
     PPDO_DEVICE_DATA pdoData;
+    int acpistate;
+    DEVICE_POWER_STATE ntState;
 
     PAGED_CODE ();
 
@@ -424,6 +426,31 @@ Bus_InitializePdo (
 
     DPRINT("pdo 0x%p, extension 0x%p\n", Pdo, pdoData);
 
+    if (pdoData->AcpiHandle)
+        acpi_bus_get_power(pdoData->AcpiHandle, &acpistate);
+    else
+        acpistate = ACPI_STATE_D0;
+
+    switch(acpistate)
+    {
+        case ACPI_STATE_D0:
+            ntState = PowerDeviceD0;
+            break;
+        case ACPI_STATE_D1:
+            ntState = PowerDeviceD1;
+            break;
+        case ACPI_STATE_D2:
+            ntState = PowerDeviceD2;
+            break;
+        case ACPI_STATE_D3:
+            ntState = PowerDeviceD3;
+            break;
+        default:
+            DPRINT1("Unknown power state (%d) returned by acpi\n",acpistate);
+            ntState = PowerDeviceUnspecified;
+            break;
+    }
+
     //
     // Initialize the rest
     //
@@ -435,12 +462,8 @@ Bus_InitializePdo (
 
     INITIALIZE_PNP_STATE(pdoData->Common);
 
-    //
-    // PDO's usually start their life at D3
-    //
-
-    pdoData->Common.DevicePowerState = PowerDeviceD3;
-    pdoData->Common.SystemPowerState = PowerSystemWorking;
+    pdoData->Common.DevicePowerState = ntState;
+    pdoData->Common.SystemPowerState = FdoData->Common.SystemPowerState;
 
     Pdo->Flags |= DO_POWER_PAGABLE;
 
index eda6cb6..ac9c9f0 100644 (file)
@@ -63,6 +63,7 @@ Bus_FDO_Power (
     PIO_STACK_LOCATION  stack;
        ULONG AcpiState;
        ACPI_STATUS AcpiStatus;
+    SYSTEM_POWER_STATE  oldPowerState;
 
     stack = IoGetCurrentIrpStackLocation (Irp);
     powerType = stack->Parameters.Power.Type;
@@ -77,8 +78,8 @@ Bus_FDO_Power (
                DbgDevicePowerString(powerState.DeviceState)));
     }
 
-  if (powerType == SystemPowerState) {
-    status = STATUS_SUCCESS;
+  if (powerType == SystemPowerState)
+  {     
     switch (powerState.SystemState) {
     case PowerSystemSleeping1:
       AcpiState = ACPI_STATE_S1;
@@ -96,13 +97,17 @@ Bus_FDO_Power (
       AcpiState = ACPI_STATE_S5;
       break;
     default:
-        return STATUS_UNSUCCESSFUL;
-        break;
+      AcpiState = ACPI_STATE_UNKNOWN;
+      ASSERT(FALSE);
+      break;
     }
+      oldPowerState = Data->Common.SystemPowerState;
+      Data->Common.SystemPowerState = powerState.SystemState;
       AcpiStatus = AcpiEnterSleepState(AcpiState);
       if (!ACPI_SUCCESS(AcpiStatus)) {
         DPRINT1("Failed to enter sleep state %d (Status 0x%X)\n",
           AcpiState, AcpiStatus);
+        Data->Common.SystemPowerState = oldPowerState;
         status = STATUS_UNSUCCESSFUL;
       }
   }
@@ -124,15 +129,11 @@ Bus_PDO_Power (
     POWER_STATE         powerState;
     POWER_STATE_TYPE    powerType;
     ULONG               error;
-    struct acpi_device  *device;
 
     stack = IoGetCurrentIrpStackLocation (Irp);
     powerType = stack->Parameters.Power.Type;
     powerState = stack->Parameters.Power.State;
 
-    if (PdoData->AcpiHandle)
-        acpi_bus_get_device(PdoData->AcpiHandle, &device);
-
     switch (stack->MinorFunction) {
     case IRP_MN_SET_POWER:
 
@@ -144,8 +145,9 @@ Bus_PDO_Power (
 
         switch (powerType) {
             case DevicePowerState:
-                if (!device)
+                if (!PdoData->AcpiHandle || !acpi_bus_power_manageable(PdoData->AcpiHandle))
                 {
+                    PoSetPowerState(PdoData->Common.Self, DevicePowerState, powerState);
                     PdoData->Common.DevicePowerState = powerState.DeviceState;
                     status = STATUS_SUCCESS;
                     break;
@@ -154,19 +156,19 @@ Bus_PDO_Power (
                 switch (powerState.DeviceState)
                 {
                     case PowerDeviceD0:
-                      error = acpi_power_transition(device, ACPI_STATE_D0);
+                      error = acpi_bus_set_power(PdoData->AcpiHandle, ACPI_STATE_D0);
                       break;
 
                     case PowerDeviceD1:
-                      error = acpi_power_transition(device, ACPI_STATE_D1);
+                      error = acpi_bus_set_power(PdoData->AcpiHandle, ACPI_STATE_D1);
                       break;
 
                     case PowerDeviceD2:
-                      error = acpi_power_transition(device, ACPI_STATE_D2);
+                      error = acpi_bus_set_power(PdoData->AcpiHandle, ACPI_STATE_D2);
                       break;
 
                     case PowerDeviceD3:
-                      error = acpi_power_transition(device, ACPI_STATE_D3);
+                      error = acpi_bus_set_power(PdoData->AcpiHandle, ACPI_STATE_D3);
                       break;
 
                     default:
@@ -176,6 +178,7 @@ Bus_PDO_Power (
 
                 if (ACPI_SUCCESS(error))
                 {
+                    PoSetPowerState(PdoData->Common.Self, DevicePowerState, powerState);
                     PdoData->Common.DevicePowerState = powerState.DeviceState;
                     status = STATUS_SUCCESS;
                 }