VOID OsrFxEvtIoStop( _In_ WDFQUEUE Queue, _In_ WDFREQUEST Request, _In_ ULONG ActionFlags ) /*++ Routine Description: This callback is invoked on every inflight request when the device is suspended or removed. Since our inflight read and write requests are actually pending in the target device, we will just acknowledge its presence. Until we acknowledge, complete, or requeue the requests framework will wait before allowing the device suspend or remove to proceeed. When the underlying USB stack gets the request to suspend or remove, it will fail all the pending requests. Arguments: Return Value: None --*/ { UNREFERENCED_PARAMETER(Queue); UNREFERENCED_PARAMETER(ActionFlags); if (ActionFlags & WdfRequestStopActionSuspend ) { WdfRequestStopAcknowledge(Request, FALSE); // Don't requeue } else if(ActionFlags & WdfRequestStopActionPurge) { WdfRequestCancelSentRequest(Request); } return; }
VOID VIOSerialPortIoStop( IN WDFQUEUE Queue, IN WDFREQUEST Request, IN ULONG ActionFlags ) { PRAWPDO_VIOSERIAL_PORT pdoData = RawPdoSerialPortGetData(WdfIoQueueGetDevice(Queue)); PVIOSERIAL_PORT pport = pdoData->port; ASSERT(pport->PendingReadRequest == Request); TraceEvents(TRACE_LEVEL_ERROR, DBG_READ, "-->%s\n", __FUNCTION__); WdfSpinLockAcquire(pport->InBufLock); if (ActionFlags & WdfRequestStopActionSuspend ) { WdfRequestStopAcknowledge(Request, FALSE); } else if(ActionFlags & WdfRequestStopActionPurge) { if (WdfRequestUnmarkCancelable(Request) != STATUS_CANCELLED) { pport->PendingReadRequest = NULL; WdfRequestCompleteWithInformation(Request , STATUS_CANCELLED, 0L); } } WdfSpinLockRelease(pport->InBufLock); return; }
VOID VIOSerialPortWriteIoStop(IN WDFQUEUE Queue, IN WDFREQUEST Request, IN ULONG ActionFlags) { PRAWPDO_VIOSERIAL_PORT pdoData = RawPdoSerialPortGetData( WdfIoQueueGetDevice(Queue)); PVIOSERIAL_PORT pport = pdoData->port; TraceEvents(TRACE_LEVEL_ERROR, DBG_WRITE, "--> %s\n", __FUNCTION__); WdfSpinLockAcquire(pport->OutVqLock); if (ActionFlags & WdfRequestStopActionSuspend) { WdfRequestStopAcknowledge(Request, FALSE); } else if (ActionFlags & WdfRequestStopActionPurge) { if (WdfRequestUnmarkCancelable(Request) != STATUS_CANCELLED) { pport->PendingWriteRequest = NULL; WdfRequestComplete(Request, STATUS_OBJECT_NO_LONGER_EXISTS); } } WdfSpinLockRelease(pport->OutVqLock); TraceEvents(TRACE_LEVEL_ERROR, DBG_WRITE, "<-- %s\n", __FUNCTION__); }
VOID SimSensorQueueIoStop ( _In_ WDFQUEUE Queue, _In_ WDFREQUEST Request, _In_ ULONG ActionFlags ) /*++ Routine Description: This routine is called when the framework is stopping the request's I/O queue. Arguments: Queue - Supplies handle to the framework queue object that is associated with the I/O request. Request - Supplies handle to a framework request object. ActionFlags - Supplies the reason that the callback is being called. Return Value: None. --*/ { NTSTATUS Status; UNREFERENCED_PARAMETER(Queue); if(ActionFlags & WdfRequestStopRequestCancelable) { Status = WdfRequestUnmarkCancelable(Request); if (Status == STATUS_CANCELLED) { goto SimSensorQueueIoStopEnd; } NT_ASSERT(NT_SUCCESS(Status)); } WdfRequestStopAcknowledge(Request, FALSE); SimSensorQueueIoStopEnd: return; }
/*++ Routine Description: This callback is invoked on every inflight request when the device is suspended or removed. Since our inflight read and write requests are actually pending in the target device, we will just acknowledge its presence. Until we acknowledge, complete, or requeue the requests framework will wait before allowing the device suspend or remove to proceed. When the underlying USB stack gets the request to suspend or remove, it will fail all the pending requests. Arguments: Return Value: None --*/ VOID PSDrvEvtIoStop(__in WDFQUEUE Queue, __in WDFREQUEST Request, __in ULONG ActionFlags) { PREQUEST_CONTEXT reqContext; UNREFERENCED_PARAMETER(Queue); reqContext=GetRequestContext(Request); if (ActionFlags & WdfRequestStopActionSuspend ) { WdfRequestStopAcknowledge(Request, FALSE); // Don't requeue } else if(ActionFlags & WdfRequestStopActionPurge) { WdfRequestCancelSentRequest(Request); } return; }
/* EvtIoStop Invoked for every inflight pipe write request. The callback executes when: 1) libusbK will stop the queue because of queue policy changes. 2) The system requests stand-by 3) The device is removed */ VOID Queue_OnStop( __in WDFQUEUE Queue, __in WDFREQUEST Request, __in ULONG ActionFlags) { PQUEUE_CONTEXT queueContext; PREQUEST_CONTEXT requestContext; if (Request == NULL || Queue == NULL) { USBERRN("Invalid wdf object."); return; } if ((queueContext = GetQueueContext(Queue)) == NULL) { USBERRN("Invalid queue context."); return; } if ((requestContext = GetRequestContext(Request)) == NULL) { USBERRN("Invalid request context."); return; } // None of the libusbK transfer functions set EvtRequestCancel, hence this should never happen. if (ActionFlags & WdfRequestStopRequestCancelable) { USBERRN("WdfRequestStopRequestCancelable! pipeID=%02Xh", queueContext->Info.EndpointAddress); WdfVerifierDbgBreakPoint(); return; } if (ActionFlags & WdfRequestStopActionSuspend) { USBDBGN("StopAcknowledge for ActionSuspend. pipeID=%02Xh request=%p timeout=%d", queueContext->Info.EndpointAddress, Request, requestContext->Timeout); WdfRequestStopAcknowledge(Request, FALSE); } else if(ActionFlags & WdfRequestStopActionPurge) { USBDBGN("CancelSentRequest for ActionPurge. pipeID=%02Xh request=%p timeout=%d", queueContext->Info.EndpointAddress, Request, requestContext->Timeout); WdfRequestCancelSentRequest(Request); } }
VCHIQ_PAGED_SEGMENT_END VCHIQ_NONPAGED_SEGMENT_BEGIN /*++ Routine Description: A driver's EvtIoStop event callback function completes, requeues, or suspends processing of a specified request because the request's I/O queue is being stopped. Arguments: Queue - A handle to the framework queue object that is associated with the I/O request. WdfRequest - A handle to a framework request object. ActionFlags - A bitwise OR of one or more WDF_REQUEST_STOP_ACTION_FLAGS typed flags that identify the reason that the callback function is being called and whether the request is cancelable. Return Value: NTSTATUS value --*/ _Use_decl_annotations_ VOID VchiqIoStop ( WDFQUEUE Queue, WDFREQUEST WdfRequest, ULONG ActionFlags ) { UNREFERENCED_PARAMETER(Queue); UNREFERENCED_PARAMETER(ActionFlags); // Requeue all pending request WdfRequestStopAcknowledge( WdfRequest, TRUE); return; }
VOID VirtRngEvtIoStop(IN WDFQUEUE Queue, IN WDFREQUEST Request, IN ULONG ActionFlags) { UNREFERENCED_PARAMETER(Queue); TraceEvents(TRACE_LEVEL_VERBOSE, DBG_READ, "--> %!FUNC! Request: %p", Request); if (ActionFlags & WdfRequestStopActionSuspend) { WdfRequestStopAcknowledge(Request, FALSE); } else if (ActionFlags & WdfRequestStopActionPurge) { if (WdfRequestUnmarkCancelable(Request) != STATUS_CANCELLED) { WdfRequestComplete(Request , STATUS_CANCELLED); } } TraceEvents(TRACE_LEVEL_VERBOSE, DBG_READ, "<-- %!FUNC!"); }
VOID VIOSerialPortWriteIoStop(IN WDFQUEUE Queue, IN WDFREQUEST Request, IN ULONG ActionFlags) { PRAWPDO_VIOSERIAL_PORT pdoData = RawPdoSerialPortGetData( WdfIoQueueGetDevice(Queue)); PVIOSERIAL_PORT pport = pdoData->port; TraceEvents(TRACE_LEVEL_ERROR, DBG_WRITE, "--> %s\n", __FUNCTION__); WdfSpinLockAcquire(pport->OutVqLock); if (ActionFlags & WdfRequestStopActionSuspend) { WdfRequestStopAcknowledge(Request, FALSE); } else if (ActionFlags & WdfRequestStopActionPurge) { if (WdfRequestUnmarkCancelable(Request) != STATUS_CANCELLED) { PSINGLE_LIST_ENTRY iter = &pport->WriteBuffersList; while ((iter = iter->Next) != NULL) { PWRITE_BUFFER_ENTRY entry = CONTAINING_RECORD(iter, WRITE_BUFFER_ENTRY, ListEntry); if (entry->Request == Request) { entry->Request = NULL; break; } } WdfRequestComplete(Request, STATUS_OBJECT_NO_LONGER_EXISTS); } } WdfSpinLockRelease(pport->OutVqLock); TraceEvents(TRACE_LEVEL_ERROR, DBG_WRITE, "<-- %s\n", __FUNCTION__); }
VOID SerialEvtIoStop( IN WDFQUEUE Queue, IN WDFREQUEST Request, IN ULONG ActionFlags ) /*++ Routine Description: This callback is invoked for every request pending in the driver (not queue) - in-flight request. The Action parameter tells us why the callback is invoked - because the device is being stopped, removed or suspended. In this driver, we have told the framework not to stop or remove when there are pending requests, so only reason for this callback is when the system is suspending. Arguments: Queue - Queue the request currently belongs to Request - Request that is currently out of queue and being processed by the driver Action - Reason for this callback Return Value: None. Acknowledge the request so that framework can contiue suspending the device. --*/ { PREQUEST_CONTEXT reqContext; UNREFERENCED_PARAMETER(Queue); reqContext = SerialGetRequestContext(Request); TraceEvents(TRACE_LEVEL_INFORMATION, DBG_WRITE, "--> SerialEvtIoStop %x %p\n", ActionFlags, Request); // // System suspends all the timers before asking the driver to goto // sleep. So let us not worry about cancelling the timers. Also the // framework will disconnect the interrupt before calling our // D0Exit handler so we can be sure that nobody will touch the hardware. // So just acknowledge callback to say that we are okay to stop due to // system suspend. Please note that since we have taken a power reference // we will never idle out when there is an open handle. Also we have told // the framework to not stop for resource rebalancing or remove when there are // open handles, so let us not worry about that either. // if (ActionFlags & WdfRequestStopRequestCancelable) { PFN_WDF_REQUEST_CANCEL cancelRoutine; // // Request is in a cancelable state. So unmark cancelable before you // acknowledge. We will mark the request cancelable when we resume. // cancelRoutine = reqContext->CancelRoutine; SerialClearCancelRoutine(Request, TRUE); // // SerialClearCancelRoutine clears the cancel-routine. So set it back // in the context. We will need that when we resume. // reqContext->CancelRoutine = cancelRoutine; reqContext->MarkCancelableOnResume = TRUE; ActionFlags &= ~WdfRequestStopRequestCancelable; } ASSERT(ActionFlags == WdfRequestStopActionSuspend); WdfRequestStopAcknowledge(Request, FALSE); // Don't requeue the request TraceEvents(TRACE_LEVEL_INFORMATION, DBG_WRITE, "<-- SerialEvtIoStop \n"); }