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