- 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
)
{
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
// 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;
}
// 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;
}
// 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;
)
{
PPDO_DEVICE_DATA pdoData;
+ int acpistate;
+ DEVICE_POWER_STATE ntState;
PAGED_CODE ();
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
//
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;
PIO_STACK_LOCATION stack;
ULONG AcpiState;
ACPI_STATUS AcpiStatus;
+ SYSTEM_POWER_STATE oldPowerState;
stack = IoGetCurrentIrpStackLocation (Irp);
powerType = stack->Parameters.Power.Type;
DbgDevicePowerString(powerState.DeviceState)));
}
- if (powerType == SystemPowerState) {
- status = STATUS_SUCCESS;
+ if (powerType == SystemPowerState)
+ {
switch (powerState.SystemState) {
case PowerSystemSleeping1:
AcpiState = ACPI_STATE_S1;
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;
}
}
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:
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;
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:
if (ACPI_SUCCESS(error))
{
+ PoSetPowerState(PdoData->Common.Self, DevicePowerState, powerState);
PdoData->Common.DevicePowerState = powerState.DeviceState;
status = STATUS_SUCCESS;
}