- Call acpi_bus_set_power instead of acpi_power_transition

- 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
This commit is contained in:
Cameron Gutman 2010-03-06 18:15:56 +00:00
parent daa14c5f08
commit 53a7ff99b9
3 changed files with 51 additions and 30 deletions

View 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;

View 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;

View 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;
}