Author: cgutman
Date: Sat Mar 6 07:03:04 2010
New Revision: 45907
URL: http://svn.reactos.org/svn/reactos?rev=45907&view=rev
Log:
- Transition the physical device into D0 state when we receive IRP_MN_START_DEVICE
- Actually do the power state transtion when a PDO receives IRP_MN_SET_POWER for DevicePowerState
- Fill the DEVICE_CHARACTERISTICS struct based on values in the acpi_device struct
- Lots of unhacking
Modified:
trunk/reactos/drivers/bus/acpi/buspdo.c
trunk/reactos/drivers/bus/acpi/power.c
Modified: trunk/reactos/drivers/bus/acpi/buspdo.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/bus/acpi/buspdo.c?…
==============================================================================
--- trunk/reactos/drivers/bus/acpi/buspdo.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/bus/acpi/buspdo.c [iso-8859-1] Sat Mar 6 07:03:04 2010
@@ -32,8 +32,13 @@
)
{
NTSTATUS status;
+ struct acpi_device *device = NULL;
+ POWER_STATE state;
PAGED_CODE ();
+
+ if (DeviceData->AcpiHandle)
+ acpi_bus_get_device(DeviceData->AcpiHandle, &device);
//
@@ -51,6 +56,15 @@
// required to allow others to access this device.
// Power up the device.
//
+ if (device && !ACPI_SUCCESS(acpi_power_transition(device, ACPI_STATE_D0)))
+ {
+ DPRINT1("Device %x failed to start!\n", device);
+ status = STATUS_UNSUCCESSFUL;
+ break;
+ }
+
+ state.DeviceState = PowerDeviceD0;
+ PoSetPowerState(DeviceData->Common.Self, DevicePowerState, state);
DeviceData->Common.DevicePowerState = PowerDeviceD0;
SET_NEW_PNP_STATE(DeviceData->Common, Started);
status = STATUS_SUCCESS;
@@ -62,7 +76,16 @@
// 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)))
+ {
+ DPRINT1("Device %x failed to stop!\n", device);
+ status = STATUS_UNSUCCESSFUL;
+ break;
+ }
+
+ state.DeviceState = PowerDeviceD3;
+ PoSetPowerState(DeviceData->Common.Self, DevicePowerState, state);
+ DeviceData->Common.DevicePowerState = PowerDeviceD3;
SET_NEW_PNP_STATE(DeviceData->Common, Stopped);
status = STATUS_SUCCESS;
break;
@@ -102,6 +125,8 @@
// 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;
@@ -212,9 +237,6 @@
return status;
}
-//
-// FIX ME FIX ME FIX ME !!!
-//
NTSTATUS
Bus_PDO_QueryDeviceCaps(
PPDO_DEVICE_DATA DeviceData,
@@ -223,10 +245,13 @@
PIO_STACK_LOCATION stack;
PDEVICE_CAPABILITIES deviceCapabilities;
- DEVICE_CAPABILITIES parentCapabilities;
- NTSTATUS status;
+ struct acpi_device *device = NULL;
+ ULONG i;
PAGED_CODE ();
+
+ if (DeviceData->AcpiHandle)
+ acpi_bus_get_device(DeviceData->AcpiHandle, &device);
stack = IoGetCurrentIrpStackLocation (Irp);
@@ -245,131 +270,80 @@
return STATUS_UNSUCCESSFUL;
}
- //
- // Get the device capabilities of the parent
- //
- status = Bus_GetDeviceCapabilities(
- FDO_FROM_PDO(DeviceData)->NextLowerDriver, &parentCapabilities);
- if (!NT_SUCCESS(status)) {
-
- DPRINT("\tQueryDeviceCaps failed\n");
- return status;
-
+ deviceCapabilities->D1Latency = 0;
+ deviceCapabilities->D2Latency = 0;
+ deviceCapabilities->D3Latency = 0;
+
+ deviceCapabilities->DeviceState[PowerSystemWorking] = PowerDeviceD0;
+ deviceCapabilities->DeviceState[PowerSystemSleeping1] = PowerDeviceD3;
+ deviceCapabilities->DeviceState[PowerSystemSleeping2] = PowerDeviceD3;
+ deviceCapabilities->DeviceState[PowerSystemSleeping3] = PowerDeviceD3;
+
+ for (i = 0; i < ACPI_D_STATE_COUNT && device; i++)
+ {
+ if (!device->power.states[i].flags.valid)
+ continue;
+
+ switch (i)
+ {
+ case ACPI_STATE_D0:
+ deviceCapabilities->DeviceState[PowerSystemWorking] = PowerDeviceD0;
+ break;
+
+ case ACPI_STATE_D1:
+ deviceCapabilities->DeviceState[PowerSystemSleeping1] = PowerDeviceD1;
+ deviceCapabilities->D1Latency = device->power.states[i].latency;
+ break;
+
+ case ACPI_STATE_D2:
+ deviceCapabilities->DeviceState[PowerSystemSleeping2] = PowerDeviceD2;
+ deviceCapabilities->D2Latency = device->power.states[i].latency;
+ break;
+
+ case ACPI_STATE_D3:
+ deviceCapabilities->DeviceState[PowerSystemSleeping3] = PowerDeviceD3;
+ deviceCapabilities->D3Latency = device->power.states[i].latency;
+ break;
+ }
}
-
- //
- // The entries in the DeviceState array are based on the capabilities
- // of the parent devnode. These entries signify the highest-powered
- // state that the device can support for the corresponding system
- // state. A driver can specify a lower (less-powered) state than the
- // bus driver. For eg: Suppose the acpi bus controller supports
- // D0, D2, and D3; and the acpi Device supports D0, D1, D2, and D3.
- // Following the above rule, the device cannot specify D1 as one of
- // it's power state. A driver can make the rules more restrictive
- // but cannot loosen them.
- // First copy the parent's S to D state mapping
- //
-
- RtlCopyMemory(
- deviceCapabilities->DeviceState,
- parentCapabilities.DeviceState,
- (PowerSystemShutdown + 1) * sizeof(DEVICE_POWER_STATE)
- );
-
- //
- // Adjust the caps to what your device supports.
- // Our device just supports D0 and D3.
- //
-
- deviceCapabilities->DeviceState[PowerSystemWorking] = PowerDeviceD0;
-
- if (deviceCapabilities->DeviceState[PowerSystemSleeping1] != PowerDeviceD0)
- deviceCapabilities->DeviceState[PowerSystemSleeping1] = PowerDeviceD1;
-
- if (deviceCapabilities->DeviceState[PowerSystemSleeping2] != PowerDeviceD0)
- deviceCapabilities->DeviceState[PowerSystemSleeping2] = PowerDeviceD3;
-
- if (deviceCapabilities->DeviceState[PowerSystemSleeping3] != PowerDeviceD0)
- deviceCapabilities->DeviceState[PowerSystemSleeping3] = PowerDeviceD3;
// We can wake the system from D1
deviceCapabilities->DeviceWake = PowerDeviceD1;
- //
- // Specifies whether the device hardware supports the D1 and D2
- // power state. Set these bits explicitly.
- //
-
- deviceCapabilities->DeviceD1 = TRUE; // Yes we can
- deviceCapabilities->DeviceD2 = FALSE;
-
- //
- // Specifies whether the device can respond to an external wake
- // signal while in the D0, D1, D2, and D3 state.
- // Set these bits explicitly.
- //
+
+ deviceCapabilities->DeviceD1 =
+ (deviceCapabilities->DeviceState[PowerSystemSleeping1] == PowerDeviceD1) ? TRUE : FALSE;
+ deviceCapabilities->DeviceD2 =
+ (deviceCapabilities->DeviceState[PowerSystemSleeping2] == PowerDeviceD2) ? TRUE : FALSE;
deviceCapabilities->WakeFromD0 = FALSE;
deviceCapabilities->WakeFromD1 = TRUE; //Yes we can
deviceCapabilities->WakeFromD2 = FALSE;
deviceCapabilities->WakeFromD3 = FALSE;
-
- // We have no latencies
-
- deviceCapabilities->D1Latency = 0;
- deviceCapabilities->D2Latency = 0;
- deviceCapabilities->D3Latency = 0;
-
- // Ejection supported
-
- deviceCapabilities->EjectSupported = TRUE;
-
- //
- // This flag specifies whether the device's hardware is disabled.
- // The PnP Manager only checks this bit right after the device is
- // enumerated. Once the device is started, this bit is ignored.
- //
- deviceCapabilities->HardwareDisabled = FALSE;
-
- //
- // Out simulated device can be physically removed.
- //
- deviceCapabilities->Removable = TRUE;
- //
- // Setting it to TURE prevents the warning dialog from appearing
- // whenever the device is surprise removed.
- //
- deviceCapabilities->SurpriseRemovalOK = TRUE;
-
- // We don't support system-wide unique IDs.
-
- deviceCapabilities->UniqueID = FALSE;
-
- //
- // Specify whether the Device Manager should suppress all
- // installation pop-ups except required pop-ups such as
- // "no compatible drivers found."
- //
+ if (device)
+ {
+ deviceCapabilities->EjectSupported = device->flags.ejectable;
+ deviceCapabilities->HardwareDisabled = !device->status.enabled;
+ deviceCapabilities->Removable = device->flags.removable;
+ deviceCapabilities->SurpriseRemovalOK = device->flags.suprise_removal_ok;
+ deviceCapabilities->UniqueID = device->flags.unique_id;
+ deviceCapabilities->NoDisplayInUI = !device->status.show_in_ui;
+ deviceCapabilities->Address = device->pnp.bus_address;
+ }
+ else
+ {
+ deviceCapabilities->EjectSupported = FALSE;
+ deviceCapabilities->HardwareDisabled = FALSE;
+ deviceCapabilities->Removable = FALSE;
+ deviceCapabilities->SurpriseRemovalOK = FALSE;
+ deviceCapabilities->UniqueID = FALSE;
+ deviceCapabilities->NoDisplayInUI = FALSE;
+ deviceCapabilities->Address = 0;
+ }
deviceCapabilities->SilentInstall = FALSE;
-
- //
- // Specifies an address indicating where the device is located
- // on its underlying bus. The interpretation of this number is
- // bus-specific. If the address is unknown or the bus driver
- // does not support an address, the bus driver leaves this
- // member at its default value of 0xFFFFFFFF. In this example
- // the location address is same as instance id.
- //
-
- //deviceCapabilities->Address = DeviceData->SerialNo;
-
- //
- // UINumber specifies a number associated with the device that can
- // be displayed in the user interface.
- //
- //deviceCapabilities->UINumber = DeviceData->SerialNo;
+ deviceCapabilities->UINumber = (ULONG)-1;
return STATUS_SUCCESS;
Modified: trunk/reactos/drivers/bus/acpi/power.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/bus/acpi/power.c?r…
==============================================================================
--- trunk/reactos/drivers/bus/acpi/power.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/bus/acpi/power.c [iso-8859-1] Sat Mar 6 07:03:04 2010
@@ -123,10 +123,15 @@
PIO_STACK_LOCATION stack;
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:
@@ -139,9 +144,43 @@
switch (powerType) {
case DevicePowerState:
- PoSetPowerState (PdoData->Common.Self, powerType, powerState);
- PdoData->Common.DevicePowerState = powerState.DeviceState;
- status = STATUS_SUCCESS;
+ if (!device)
+ {
+ PdoData->Common.DevicePowerState = powerState.DeviceState;
+ status = STATUS_SUCCESS;
+ break;
+ }
+
+ switch (powerState.DeviceState)
+ {
+ case PowerDeviceD0:
+ error = acpi_power_transition(device, ACPI_STATE_D0);
+ break;
+
+ case PowerDeviceD1:
+ error = acpi_power_transition(device, ACPI_STATE_D1);
+ break;
+
+ case PowerDeviceD2:
+ error = acpi_power_transition(device, ACPI_STATE_D2);
+ break;
+
+ case PowerDeviceD3:
+ error = acpi_power_transition(device, ACPI_STATE_D3);
+ break;
+
+ default:
+ error = 0;
+ break;
+ }
+
+ if (ACPI_SUCCESS(error))
+ {
+ PdoData->Common.DevicePowerState = powerState.DeviceState;
+ status = STATUS_SUCCESS;
+ }
+ else
+ status = STATUS_UNSUCCESSFUL;
break;
case SystemPowerState: