NTSTATUS NTAPI SetDeviceFunctional(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PDEVICE_EXTENSION DeviceExtension) { KIRQL oldIrql; NTSTATUS ntStatus; POWER_STATE newState; PIO_STACK_LOCATION irpStack; DEVICE_POWER_STATE newDevState, oldDevState; ntStatus = Irp->IoStatus.Status; irpStack = IoGetCurrentIrpStackLocation(Irp); newState = irpStack->Parameters.Power.State; newDevState = newState.DeviceState; oldDevState = DeviceExtension->DevPower; FreeBT_DbgPrint(3, ("FBTUSB: SetDeviceFunctional: Entered\n")); // update the cached state DeviceExtension->DevPower = newDevState; // restore appropriate amount of state to our h/w // this driver does not implement partial context // save/restore. PoSetPowerState(DeviceObject, DevicePowerState, newState); if(PowerDeviceD0 == newDevState) { KeAcquireSpinLock(&DeviceExtension->DevStateLock, &oldIrql); DeviceExtension->QueueState = AllowRequests; KeReleaseSpinLock(&DeviceExtension->DevStateLock, oldIrql); ProcessQueuedRequests(DeviceExtension); } PoStartNextPowerIrp(Irp); Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); FreeBT_DbgPrint(3, ("FBTUSB: SetDeviceFunctional::")); FreeBT_IoDecrement(DeviceExtension); FreeBT_DbgPrint(3, ("FBTUSB: SetDeviceFunctional: Leaving\n")); return STATUS_SUCCESS; }
NTSTATUS SetDeviceFunctional( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PDEVICE_EXTENSION DeviceExtension ) /*++ Routine Description: This routine processes queue of pending irps. Arguments: DeviceObject - pointer to device object Irp - I/O request packet DeviceExtension - pointer to device extension Return Value: NT status value --*/ { KIRQL oldIrql; NTSTATUS ntStatus; POWER_STATE newState; PIO_STACK_LOCATION irpStack; DEVICE_POWER_STATE newDevState, oldDevState; // // initialize variables // ntStatus = Irp->IoStatus.Status; irpStack = IoGetCurrentIrpStackLocation(Irp); newState = irpStack->Parameters.Power.State; newDevState = newState.DeviceState; oldDevState = DeviceExtension->DevPower; MobiUsb_DbgPrint(3, ("file mobipwr: SetDeviceFunctional - begins\n")); // // update the cached state // DeviceExtension->DevPower = newDevState; // // restore appropriate amount of state to our h/w // this driver does not implement partial context // save/restore. // PoSetPowerState(DeviceObject, DevicePowerState, newState); if(PowerDeviceD0 == newDevState) { // // empty existing queue of all pending irps. // KeAcquireSpinLock(&DeviceExtension->DevStateLock, &oldIrql); DeviceExtension->QueueState = AllowRequests; KeReleaseSpinLock(&DeviceExtension->DevStateLock, oldIrql); ProcessQueuedRequests(DeviceExtension); } PoStartNextPowerIrp(Irp); Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); MobiUsb_DbgPrint(3, ("file mobipwr: SetDeviceFunctional::")); MobiUsb_IoDecrement(DeviceExtension); MobiUsb_DbgPrint(3, ("file mobipwr: SetDeviceFunctional - ends\n")); return STATUS_SUCCESS; }
NTSTATUS NTAPI HandleDeviceSetPower(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { KIRQL oldIrql; NTSTATUS ntStatus; POWER_STATE newState; PIO_STACK_LOCATION irpStack; PDEVICE_EXTENSION deviceExtension; DEVICE_POWER_STATE newDevState, oldDevState; FreeBT_DbgPrint(3, ("FBTUSB: HandleDeviceSetPower: Entered\n")); deviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; irpStack = IoGetCurrentIrpStackLocation(Irp); oldDevState = deviceExtension->DevPower; newState = irpStack->Parameters.Power.State; newDevState = newState.DeviceState; FreeBT_DbgPrint(3, ("FBTUSB: HandleDeviceSetPower: Set request for device power state D%X\n" "FBTUSB: HandleDeviceSetPower: Current device power state D%X\n", newDevState - 1, deviceExtension->DevPower - 1)); if (newDevState < oldDevState) { FreeBT_DbgPrint(3, ("FBTUSB: HandleDeviceSetPower: Adding power to the device\n")); IoCopyCurrentIrpStackLocationToNext(Irp); IoSetCompletionRoutine( Irp, (PIO_COMPLETION_ROUTINE)FinishDevPoUpIrp, deviceExtension, TRUE, TRUE, TRUE); ntStatus = PoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp); } else { // newDevState >= oldDevState // hold I/O if transition from D0 -> DX (X = 1, 2, 3) // if transition from D1 or D2 to deeper sleep states, // I/O queue is already on hold. if(PowerDeviceD0 == oldDevState && newDevState > oldDevState) { // D0 -> DX transition FreeBT_DbgPrint(3, ("FBTUSB: HandleDeviceSetPower: Removing power from the device\n")); ntStatus = HoldIoRequests(DeviceObject, Irp); if (!NT_SUCCESS(ntStatus)) { PoStartNextPowerIrp(Irp); Irp->IoStatus.Status = ntStatus; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); FreeBT_DbgPrint(3, ("FBTUSB: HandleDeviceSetPower::")); FreeBT_IoDecrement(deviceExtension); return ntStatus; } else { goto HandleDeviceSetPower_Exit; } } else if (PowerDeviceD0 == oldDevState && PowerDeviceD0 == newDevState) { // D0 -> D0 // unblock the queue which may have been blocked processing // query irp FreeBT_DbgPrint(3, ("FBTUSB: HandleDeviceSetPower: A SetD0 request\n")); KeAcquireSpinLock(&deviceExtension->DevStateLock, &oldIrql); deviceExtension->QueueState = AllowRequests; KeReleaseSpinLock(&deviceExtension->DevStateLock, oldIrql); ProcessQueuedRequests(deviceExtension); } IoCopyCurrentIrpStackLocationToNext(Irp); IoSetCompletionRoutine( Irp, (PIO_COMPLETION_ROUTINE) FinishDevPoDnIrp, deviceExtension, TRUE, TRUE, TRUE); ntStatus = PoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp); if(!NT_SUCCESS(ntStatus)) { FreeBT_DbgPrint(1, ("FBTUSB: HandleDeviceSetPower: Lower drivers failed a power Irp\n")); } } HandleDeviceSetPower_Exit: FreeBT_DbgPrint(3, ("FBTUSB: HandleDeviceSetPower: Leaving\n")); return STATUS_PENDING; }
NTSTATUS HandleDeviceSetPower( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) /*++ Routine Description: This routine services irps of minor type IRP_MN_SET_POWER for the device power state Arguments: DeviceObject - pointer to device object Irp - I/O request packet sent by the power manager Return Value: NT status value --*/ { KIRQL oldIrql; NTSTATUS ntStatus; POWER_STATE newState; PIO_STACK_LOCATION irpStack; PDEVICE_EXTENSION deviceExtension; DEVICE_POWER_STATE newDevState, oldDevState; MobiUsb_DbgPrint(3, ("file mobipwr: HandleDeviceSetPower - begins\n")); // // initialize variables // deviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; irpStack = IoGetCurrentIrpStackLocation(Irp); oldDevState = deviceExtension->DevPower; newState = irpStack->Parameters.Power.State; newDevState = newState.DeviceState; MobiUsb_DbgPrint(3, ("file mobipwr: Set request for device power state D%X\n" "Current device power state D%X\n", newDevState - 1, deviceExtension->DevPower - 1)); if(newDevState < oldDevState) { // // adding power // MobiUsb_DbgPrint(3, ("file mobipwr: Adding power to the device\n")); // // send the power IRP to the next driver in the stack // IoCopyCurrentIrpStackLocationToNext(Irp); IoSetCompletionRoutine( Irp, (PIO_COMPLETION_ROUTINE)FinishDevPoUpIrp, deviceExtension, TRUE, TRUE, TRUE); ntStatus = PoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp); } else { // // newDevState >= oldDevState // // hold I/O if transition from D0 -> DX (X = 1, 2, 3) // if transition from D1 or D2 to deeper sleep states, // I/O queue is already on hold. // if(PowerDeviceD0 == oldDevState && newDevState > oldDevState) { // // D0 -> DX transition // MobiUsb_DbgPrint(3, ("file mobipwr: Removing power from the device\n")); ntStatus = HoldIoRequests(DeviceObject, Irp); if(!NT_SUCCESS(ntStatus)) { PoStartNextPowerIrp(Irp); Irp->IoStatus.Status = ntStatus; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); MobiUsb_DbgPrint(3, ("file mobipwr: HandleDeviceSetPower::")); MobiUsb_IoDecrement(deviceExtension); return ntStatus; } else { goto HandleDeviceSetPower_Exit; } } else if(PowerDeviceD0 == oldDevState && PowerDeviceD0 == newDevState) { // // D0 -> D0 // unblock the queue which may have been blocked processing // query irp // MobiUsb_DbgPrint(3, ("file mobipwr: A SetD0 request\n")); KeAcquireSpinLock(&deviceExtension->DevStateLock, &oldIrql); deviceExtension->QueueState = AllowRequests; KeReleaseSpinLock(&deviceExtension->DevStateLock, oldIrql); ProcessQueuedRequests(deviceExtension); } IoCopyCurrentIrpStackLocationToNext(Irp); IoSetCompletionRoutine( Irp, (PIO_COMPLETION_ROUTINE) FinishDevPoDnIrp, deviceExtension, TRUE, TRUE, TRUE); ntStatus = PoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp); if(!NT_SUCCESS(ntStatus)) { MobiUsb_DbgPrint(1, ("file mobipwr: Lower drivers failed a power Irp\n")); } } HandleDeviceSetPower_Exit: MobiUsb_DbgPrint(3, ("file mobipwr: HandleDeviceSetPower - ends\n")); return STATUS_PENDING; }