NTSTATUS SimSensorSelfManagedIoSuspend ( _In_ WDFDEVICE Device ) /*++ Routine Description: Stops self-managed IO queues in preparation for D0 exit. Return Value: NTSTATUS --*/ { PFDO_DATA DevExt; PAGED_CODE(); DevExt = GetDeviceExtension(Device); WdfIoQueueStopSynchronously(DevExt->PendingRequestQueue); return STATUS_SUCCESS; }
_Use_decl_annotations_ NTSTATUS SerialFlush( WDFDEVICE Device, PIRP Irp ) /*++ Routine Description: This is the dispatch routine for flush. Flushing works by placing this request in the write queue. When this request reaches the front of the write queue we simply complete it since this implies that all previous writes have completed. Arguments: DeviceObject - Pointer to the device object for this device Irp - Pointer to the IRP for the current request Return Value: Could return status success, cancelled, or pending. --*/ { PSERIAL_DEVICE_EXTENSION extension; extension = SerialGetDeviceExtension(Device); TraceEvents(TRACE_LEVEL_INFORMATION, DBG_WRITE, ">SerialFlush(%p, %p)\n", Device, Irp); PAGED_CODE(); WdfIoQueueStopSynchronously(extension->WriteQueue); // // Flush is done - restart the queue // WdfIoQueueStart(extension->WriteQueue); Irp->IoStatus.Information = 0L; Irp->IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest(Irp, IO_NO_INCREMENT); TraceEvents(TRACE_LEVEL_INFORMATION, DBG_WRITE, "<SerialFlush\n"); return STATUS_SUCCESS; }
NTSTATUS EchoEvtDeviceSelfManagedIoSuspend( IN WDFDEVICE Device ) /*++ Routine Description: This event is called by the Framework when the device is stopped for resource rebalance or suspended when the system is entering Sx state. Arguments: Device - Handle to a framework device object. Return Value: NTSTATUS - The driver is not allowed to fail this function. If it does, the device stack will be torn down. --*/ { PQUEUE_CONTEXT queueContext = QueueGetContext(WdfDeviceGetDefaultQueue(Device)); PAGED_CODE(); KdPrint(("--> EchoEvtDeviceSelfManagedIoSuspend\n")); // // Before we stop the timer we should make sure there are no outstanding // i/o. We need to do that because framework cannot suspend the device // if there are requests owned by the driver. There are two ways to solve // this issue: 1) We can wait for the outstanding I/O to be complete by the // periodic timer 2) Register EvtIoStop callback on the queue and acknowledge // the request to inform the framework that it's okay to suspend the device // with outstanding I/O. In this sample we will use the 1st approach // because it's pretty easy to do. We will restart the queue when the // device is restarted. // WdfIoQueueStopSynchronously(WdfDeviceGetDefaultQueue(Device)); // // Stop the watchdog timer and wait for DPC to run to completion if it's already fired. // WdfTimerStop(queueContext->Timer, TRUE); KdPrint(( "<-- EchoEvtDeviceSelfManagedIoSuspend\n")); return STATUS_SUCCESS; }
NTSTATUS RequestProcessShutdownFlush( WDFDEVICE Device, PIRP Irp ) /*++ Routine Description: process IRP: IRP_MJ_SHUTDOWN, IRP_MJ_FLUSH_BUFFERS Arguments: Device - device object Irp - the irp Return Value: NTSTATUS --*/ { NTSTATUS status = STATUS_SUCCESS; PIO_STACK_LOCATION currentStack = NULL; PCDROM_DEVICE_EXTENSION deviceExtension = DeviceGetExtension(Device); //add trace info // acquire the shutdown/flush lock WdfWaitLockAcquire(deviceExtension->ShutdownFlushWaitLock, NULL); currentStack = IoGetCurrentIrpStackLocation(Irp); // finish all current requests WdfIoQueueStopSynchronously(deviceExtension->SerialIOQueue); // sync cache if (NT_SUCCESS(status)) { // safe to use scratch srb to send the request. status = DeviceScratchSyncCache(deviceExtension); } // For SHUTDOWN, allow media removal. if (NT_SUCCESS(status)) { if (currentStack->MajorFunction == IRP_MJ_SHUTDOWN) { // safe to use scratch srb to send the request. status = DeviceScratchPreventMediaRemoval(deviceExtension, FALSE); } } // Use original IRP, send SRB_FUNCTION_SHUTDOWN or SRB_FUNCTION_FLUSH (no retry) if (NT_SUCCESS(status)) { status = RequestIssueShutdownFlush(deviceExtension, Irp); } // restart queue to allow processing further requests. WdfIoQueueStart(deviceExtension->SerialIOQueue); // release the shutdown/flush lock WdfWaitLockRelease(deviceExtension->ShutdownFlushWaitLock); // 6. complete the irp Irp->IoStatus.Status = status; IoCompleteRequest(Irp, 0); return status; }