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 297