#include "usbsc.h" #include "usbscpwr.h" #include "usbscnt.h" NTSTATUS UsbScDevicePower( PDEVICE_OBJECT DeviceObject, PIRP Irp ) /*++ Routine Description: Handles Device Power Irps Arguments: Return Value: --*/ { NTSTATUS status = STATUS_SUCCESS; PDEVICE_EXTENSION pDevExt; PIO_STACK_LOCATION stack; BOOLEAN postWaitWake; POWER_STATE state; __try { SmartcardDebug( DEBUG_TRACE, ("%s!UsbScDevicePower Enter\n",DRIVER_NAME )); pDevExt = DeviceObject->DeviceExtension; stack = IoGetCurrentIrpStackLocation(Irp); state.DeviceState = stack->Parameters.Power.State.DeviceState; switch (stack->MinorFunction) { case IRP_MN_QUERY_POWER: // // Since we can always wait for our irps to complete, so we just always succeed // IoReleaseRemoveLock(&pDevExt->RemoveLock, Irp); PoStartNextPowerIrp(Irp); IoSkipCurrentIrpStackLocation(Irp); status = PoCallDriver(pDevExt->LowerDeviceObject, Irp); break; case IRP_MN_SET_POWER: if (state.DeviceState < pDevExt->PowerState) { // // We are coming up!! We must let lower drivers power up before we do // IoMarkIrpPending(Irp); IoCopyCurrentIrpStackLocationToNext(Irp); IoSetCompletionRoutine(Irp, UsbScDevicePowerUpCompletion, pDevExt, TRUE, TRUE, TRUE); status = PoCallDriver(pDevExt->LowerDeviceObject, Irp); status = STATUS_PENDING; } else { // // We are moving to a lower power state, so we handle it before // passing it down // status = UsbScSetDevicePowerState(DeviceObject, state.DeviceState, &postWaitWake); PoSetPowerState(DeviceObject, DevicePowerState, state); IoReleaseRemoveLock(&pDevExt->RemoveLock, Irp); PoStartNextPowerIrp(Irp); IoSkipCurrentIrpStackLocation(Irp); status = PoCallDriver(pDevExt->LowerDeviceObject, Irp); } break; default: // We shouldn't be here ASSERT(FALSE); break; } } __finally { SmartcardDebug( DEBUG_TRACE, ("%s!UsbScDevicePower Exit : 0x%x\n",DRIVER_NAME, status )); } return status; } NTSTATUS UsbScSystemPower( PDEVICE_OBJECT DeviceObject, PIRP Irp ) /*++ Routine Description: Handles system power irps Arguments: Return Value: --*/ { NTSTATUS status = STATUS_SUCCESS; PDEVICE_EXTENSION pDevExt; __try { SmartcardDebug( DEBUG_TRACE, ("%s!UsbScSystemPower Enter\n",DRIVER_NAME )); pDevExt = DeviceObject->DeviceExtension; IoMarkIrpPending(Irp); IoCopyCurrentIrpStackLocationToNext(Irp); IoSetCompletionRoutine(Irp, UsbScSystemPowerCompletion, pDevExt, TRUE, TRUE, TRUE); status = PoCallDriver(pDevExt->LowerDeviceObject, Irp); status = STATUS_PENDING; } __finally { SmartcardDebug( DEBUG_TRACE, ("%s!UsbScSystemPower Exit : 0x%x\n",DRIVER_NAME, status )); } return status; } NTSTATUS UsbScSystemPowerCompletion( PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context ) /*++ Routine Description: Completion routine called after system power irp has been passed down the stack. handles mapping system state to device state and requests the device power irp. Arguments: Return Value: --*/ { NTSTATUS status = STATUS_SUCCESS; PDEVICE_EXTENSION pDevExt; PIO_STACK_LOCATION irpStack; POWER_STATE state; POWER_STATE systemState; __try { SmartcardDebug( DEBUG_TRACE, ("%s!UsbScSystemPowerCompletion Enter\n",DRIVER_NAME )); pDevExt = (PDEVICE_EXTENSION) Context; if (!NT_SUCCESS(Irp->IoStatus.Status)) { SmartcardDebug( DEBUG_TRACE, ("%s!UsbScSystemPowerCompletion SIRP failed by lower driver\n",DRIVER_NAME )); PoStartNextPowerIrp(Irp); IoCompleteRequest(Irp, IO_NO_INCREMENT); status = Irp->IoStatus.Status; IoReleaseRemoveLock(&pDevExt->RemoveLock, Irp); __leave; } irpStack = IoGetCurrentIrpStackLocation(Irp); systemState = irpStack->Parameters.Power.State; state.DeviceState = pDevExt->DeviceCapabilities.DeviceState[systemState.SystemState]; status = PoRequestPowerIrp(DeviceObject, irpStack->MinorFunction, state, UsbScDeviceRequestCompletion, (PVOID) Irp, NULL); ASSERT(NT_SUCCESS(status)); status = STATUS_MORE_PROCESSING_REQUIRED; } __finally { SmartcardDebug( DEBUG_TRACE, ("%s!UsbScSystemPowerCompletion Exit : 0x%x\n",DRIVER_NAME, status )); } return status; } VOID UsbScDeviceRequestCompletion( PDEVICE_OBJECT DeviceObject, UCHAR MinorFunction, POWER_STATE PowerState, PVOID Context, PIO_STATUS_BLOCK IoStatus ) /*++ Routine Description: Completion routine called after device power irp completes. Completes the system power irp. Arguments: Return Value: --*/ { NTSTATUS status = STATUS_SUCCESS; PDEVICE_EXTENSION pDevExt; PIRP irp; __try { SmartcardDebug( DEBUG_TRACE, ("%s!UsbScDeviceRequestCompletion Enter\n",DRIVER_NAME )); pDevExt = DeviceObject->DeviceExtension; irp = (PIRP) Context; PoStartNextPowerIrp(irp); irp->IoStatus.Status = IoStatus->Status; IoCompleteRequest(irp, IO_NO_INCREMENT); IoReleaseRemoveLock(&pDevExt->RemoveLock, irp); } __finally { SmartcardDebug( DEBUG_TRACE, ("%s!UsbScDeviceRequestCompletion Exit : 0x%x\n",DRIVER_NAME, status )); } return; } NTSTATUS UsbScDevicePowerUpCompletion( PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context ) /*++ Routine Description: Completion routine called after device irp for higher power state has been passed down the stack. Arguments: Return Value: --*/ { NTSTATUS status = STATUS_SUCCESS; PDEVICE_EXTENSION pDevExt; PIO_STACK_LOCATION irpStack; BOOLEAN postWaitWake; // We don't really care about this __try { SmartcardDebug( DEBUG_TRACE, ("%s!UsbScDevicePowerUpCompletion Enter\n",DRIVER_NAME )); pDevExt = DeviceObject->DeviceExtension; irpStack = IoGetCurrentIrpStackLocation(Irp); status = UsbScSetDevicePowerState(DeviceObject, irpStack->Parameters.Power.State.DeviceState, &postWaitWake); PoSetPowerState(DeviceObject, DevicePowerState, irpStack->Parameters.Power.State); PoStartNextPowerIrp(Irp); } __finally { IoReleaseRemoveLock(&pDevExt->RemoveLock, Irp); SmartcardDebug( DEBUG_TRACE, ("%s!UsbScDevicePowerUpCompletion Exit : 0x%x\n",DRIVER_NAME, status )); } return status; }