[CMAKE]
[reactos.git] / drivers / bus / acpi / power.c
1 #include <ntddk.h>
2
3 #include <acpi.h>
4 #include <acpisys.h>
5
6 #include <acpi_bus.h>
7 #include <acpi_drivers.h>
8
9 #define NDEBUG
10 #include <debug.h>
11
12 NTSTATUS
13 NTAPI
14 Bus_Power (
15 PDEVICE_OBJECT DeviceObject,
16 PIRP Irp
17 )
18 {
19 PIO_STACK_LOCATION irpStack;
20 NTSTATUS status;
21 PCOMMON_DEVICE_DATA commonData;
22
23 status = STATUS_SUCCESS;
24 irpStack = IoGetCurrentIrpStackLocation (Irp);
25 ASSERT (IRP_MJ_POWER == irpStack->MajorFunction);
26
27 commonData = (PCOMMON_DEVICE_DATA) DeviceObject->DeviceExtension;
28
29 if (commonData->IsFDO) {
30
31 DPRINT("FDO %s IRP:0x%p %s %s\n",
32 PowerMinorFunctionString(irpStack->MinorFunction), Irp,
33 DbgSystemPowerString(commonData->SystemPowerState),
34 DbgDevicePowerString(commonData->DevicePowerState));
35
36
37 status = Bus_FDO_Power ((PFDO_DEVICE_DATA)DeviceObject->DeviceExtension,
38 Irp);
39 } else {
40
41 DPRINT("PDO %s IRP:0x%p %s %s\n",
42 PowerMinorFunctionString(irpStack->MinorFunction), Irp,
43 DbgSystemPowerString(commonData->SystemPowerState),
44 DbgDevicePowerString(commonData->DevicePowerState));
45
46 status = Bus_PDO_Power ((PPDO_DEVICE_DATA)DeviceObject->DeviceExtension,
47 Irp);
48 }
49
50 return status;
51 }
52
53
54 NTSTATUS
55 Bus_FDO_Power (
56 PFDO_DEVICE_DATA Data,
57 PIRP Irp
58 )
59 {
60 NTSTATUS status = STATUS_SUCCESS;
61 POWER_STATE powerState;
62 POWER_STATE_TYPE powerType;
63 PIO_STACK_LOCATION stack;
64 ULONG AcpiState;
65 ACPI_STATUS AcpiStatus;
66 SYSTEM_POWER_STATE oldPowerState;
67
68 stack = IoGetCurrentIrpStackLocation (Irp);
69 powerType = stack->Parameters.Power.Type;
70 powerState = stack->Parameters.Power.State;
71
72
73 if (stack->MinorFunction == IRP_MN_SET_POWER) {
74 DPRINT("\tRequest to set %s state to %s\n",
75 ((powerType == SystemPowerState) ? "System" : "Device"),
76 ((powerType == SystemPowerState) ? \
77 DbgSystemPowerString(powerState.SystemState) :\
78 DbgDevicePowerString(powerState.DeviceState)));
79 }
80
81 if (powerType == SystemPowerState)
82 {
83 switch (powerState.SystemState) {
84 case PowerSystemSleeping1:
85 AcpiState = ACPI_STATE_S1;
86 break;
87 case PowerSystemSleeping2:
88 AcpiState = ACPI_STATE_S2;
89 break;
90 case PowerSystemSleeping3:
91 AcpiState = ACPI_STATE_S3;
92 break;
93 case PowerSystemHibernate:
94 AcpiState = ACPI_STATE_S4;
95 break;
96 case PowerSystemShutdown:
97 AcpiState = ACPI_STATE_S5;
98 break;
99 default:
100 AcpiState = ACPI_STATE_UNKNOWN;
101 ASSERT(FALSE);
102 break;
103 }
104 oldPowerState = Data->Common.SystemPowerState;
105 Data->Common.SystemPowerState = powerState.SystemState;
106 AcpiStatus = acpi_suspend(AcpiState);
107 if (!ACPI_SUCCESS(AcpiStatus)) {
108 DPRINT1("Failed to enter sleep state %d (Status 0x%X)\n",
109 AcpiState, AcpiStatus);
110 Data->Common.SystemPowerState = oldPowerState;
111 status = STATUS_UNSUCCESSFUL;
112 }
113 }
114 PoStartNextPowerIrp (Irp);
115 IoSkipCurrentIrpStackLocation(Irp);
116 status = PoCallDriver (Data->NextLowerDriver, Irp);
117 return status;
118 }
119
120
121 NTSTATUS
122 Bus_PDO_Power (
123 PPDO_DEVICE_DATA PdoData,
124 PIRP Irp
125 )
126 {
127 NTSTATUS status;
128 PIO_STACK_LOCATION stack;
129 POWER_STATE powerState;
130 POWER_STATE_TYPE powerType;
131 ULONG error;
132
133 stack = IoGetCurrentIrpStackLocation (Irp);
134 powerType = stack->Parameters.Power.Type;
135 powerState = stack->Parameters.Power.State;
136
137 switch (stack->MinorFunction) {
138 case IRP_MN_SET_POWER:
139
140 DPRINT("\tSetting %s power state to %s\n",
141 ((powerType == SystemPowerState) ? "System" : "Device"),
142 ((powerType == SystemPowerState) ? \
143 DbgSystemPowerString(powerState.SystemState) : \
144 DbgDevicePowerString(powerState.DeviceState)));
145
146 switch (powerType) {
147 case DevicePowerState:
148 if (!PdoData->AcpiHandle || !acpi_bus_power_manageable(PdoData->AcpiHandle))
149 {
150 PoSetPowerState(PdoData->Common.Self, DevicePowerState, powerState);
151 PdoData->Common.DevicePowerState = powerState.DeviceState;
152 status = STATUS_SUCCESS;
153 break;
154 }
155
156 switch (powerState.DeviceState)
157 {
158 case PowerDeviceD0:
159 error = acpi_bus_set_power(PdoData->AcpiHandle, ACPI_STATE_D0);
160 break;
161
162 case PowerDeviceD1:
163 error = acpi_bus_set_power(PdoData->AcpiHandle, ACPI_STATE_D1);
164 break;
165
166 case PowerDeviceD2:
167 error = acpi_bus_set_power(PdoData->AcpiHandle, ACPI_STATE_D2);
168 break;
169
170 case PowerDeviceD3:
171 error = acpi_bus_set_power(PdoData->AcpiHandle, ACPI_STATE_D3);
172 break;
173
174 default:
175 error = 0;
176 break;
177 }
178
179 if (ACPI_SUCCESS(error))
180 {
181 PoSetPowerState(PdoData->Common.Self, DevicePowerState, powerState);
182 PdoData->Common.DevicePowerState = powerState.DeviceState;
183 status = STATUS_SUCCESS;
184 }
185 else
186 status = STATUS_UNSUCCESSFUL;
187 break;
188
189 case SystemPowerState:
190 PdoData->Common.SystemPowerState = powerState.SystemState;
191 status = STATUS_SUCCESS;
192 break;
193
194 default:
195 status = STATUS_NOT_SUPPORTED;
196 break;
197 }
198 break;
199
200 case IRP_MN_QUERY_POWER:
201 status = STATUS_SUCCESS;
202 break;
203
204 case IRP_MN_WAIT_WAKE:
205 //
206 // We cannot support wait-wake because we are root-enumerated
207 // driver, and our parent, the PnP manager, doesn't support wait-wake.
208 //
209 case IRP_MN_POWER_SEQUENCE:
210 default:
211 status = STATUS_NOT_SUPPORTED;
212 break;
213 }
214
215 if (status != STATUS_NOT_SUPPORTED) {
216
217 Irp->IoStatus.Status = status;
218 }
219
220 PoStartNextPowerIrp(Irp);
221 status = Irp->IoStatus.Status;
222 IoCompleteRequest (Irp, IO_NO_INCREMENT);
223
224 return status;
225 }
226
227 #ifndef NDEBUG
228
229 PCHAR
230 PowerMinorFunctionString (
231 UCHAR MinorFunction
232 )
233 {
234 switch (MinorFunction)
235 {
236 case IRP_MN_SET_POWER:
237 return "IRP_MN_SET_POWER";
238 case IRP_MN_QUERY_POWER:
239 return "IRP_MN_QUERY_POWER";
240 case IRP_MN_POWER_SEQUENCE:
241 return "IRP_MN_POWER_SEQUENCE";
242 case IRP_MN_WAIT_WAKE:
243 return "IRP_MN_WAIT_WAKE";
244
245 default:
246 return "unknown_power_irp";
247 }
248 }
249
250 PCHAR
251 DbgSystemPowerString(
252 SYSTEM_POWER_STATE Type
253 )
254 {
255 switch (Type)
256 {
257 case PowerSystemUnspecified:
258 return "PowerSystemUnspecified";
259 case PowerSystemWorking:
260 return "PowerSystemWorking";
261 case PowerSystemSleeping1:
262 return "PowerSystemSleeping1";
263 case PowerSystemSleeping2:
264 return "PowerSystemSleeping2";
265 case PowerSystemSleeping3:
266 return "PowerSystemSleeping3";
267 case PowerSystemHibernate:
268 return "PowerSystemHibernate";
269 case PowerSystemShutdown:
270 return "PowerSystemShutdown";
271 case PowerSystemMaximum:
272 return "PowerSystemMaximum";
273 default:
274 return "UnKnown System Power State";
275 }
276 }
277
278 PCHAR
279 DbgDevicePowerString(
280 DEVICE_POWER_STATE Type
281 )
282 {
283 switch (Type)
284 {
285 case PowerDeviceUnspecified:
286 return "PowerDeviceUnspecified";
287 case PowerDeviceD0:
288 return "PowerDeviceD0";
289 case PowerDeviceD1:
290 return "PowerDeviceD1";
291 case PowerDeviceD2:
292 return "PowerDeviceD2";
293 case PowerDeviceD3:
294 return "PowerDeviceD3";
295 case PowerDeviceMaximum:
296 return "PowerDeviceMaximum";
297 default:
298 return "UnKnown Device Power State";
299 }
300 }
301
302 #endif