VOID SerialFlushRequests( IN WDFQUEUE QueueToClean, IN WDFREQUEST *CurrentOpRequest ) /*++ Routine Description: This function is used to cancel all queued and the current irps for reads or for writes. Called at DPC level. Arguments: QueueToClean - A pointer to the queue which we're going to clean out. CurrentOpRequest - Pointer to a pointer to the current request. Return Value: None. --*/ { SerialPurgeRequests(QueueToClean, CurrentOpRequest); // // Since purge puts the queue state to fail requests, we have to explicitly // change the queue state to accept requests. // WdfIoQueueStart(QueueToClean); }
VOID FfbActiveSet( BOOLEAN active, int id, PDEVICE_EXTENSION pDevContext ) { size_t szarry, szelement; int sz; // Check id szarry = sizeof(pDevContext->FfbEnable); szelement = sizeof(pDevContext->FfbEnable[0]); sz = szarry/szelement; if (id<1 || id>sz) return; // Has there been a change? if not do nothing // NO if (active == pDevContext->FfbEnable[id-1]) return; // YES if (active) { // FFB Activated //////////// ReadQ ///////////////////////////////////////// // Start queue WdfIoQueueStart(pDevContext->FfbReadQ[id - 1]); //////////// WriteQ ///////////////////////////////////////// // Start queue WdfIoQueueStart(pDevContext->FfbWriteQ[id - 1]); // Mark FFB as active pDevContext->FfbEnable[id-1] = TRUE; } else { // FFB Deactivated pDevContext->FfbEnable[id-1] = FALSE; // Purge queues WdfIoQueuePurge(pDevContext->FfbWriteQ[id - 1], NULL, NULL); WdfIoQueuePurge(pDevContext->FfbReadQ[id - 1], NULL, NULL); }; }
/////////////////////////////////////////////////////////////////////////////// // SmplPoFxComponentActiveConditionCallback // This callback is invoked by Power Framework to notify driver that one of its // components has become active. /////////////////////////////////////////////////////////////////////////////// VOID SmplPoFxComponentActiveConditionCallback( _In_ PVOID Context, _In_ ULONG Component ) { DEVICE_CONTEXT *pDeviceContext = DeviceGetContext((WDFDEVICE) Context); DbgPrintEx(DPFLTR_IHVDRIVER_ID, 1234,"SmplPoFxComponentActiveConditionCallback Component:%d\n", Component); WdfIoQueueStart(pDeviceContext->Queue); } // end SmplPoFxComponentActiveConditionCallback
_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 EchoEvtDeviceSelfManagedIoStart( IN WDFDEVICE Device ) /*++ Routine Description: This event is called by the Framework when the device is started or restarted after a suspend operation. This function is not marked pageable because this function is in the device power up path. When a function is marked pagable and the code section is paged out, it will generate a page fault which could impact the fast resume behavior because the client driver will have to wait until the system drivers can service this page fault. Arguments: Device - Handle to a framework device object. Return Value: NTSTATUS - Failures will result in the device stack being torn down. --*/ { PQUEUE_CONTEXT queueContext = QueueGetContext(WdfDeviceGetDefaultQueue(Device)); LARGE_INTEGER DueTime; KdPrint(("--> EchoEvtDeviceSelfManagedIoInit\n")); // // Restart the queue and the periodic timer. We stopped them before going // into low power state. // WdfIoQueueStart(WdfDeviceGetDefaultQueue(Device)); DueTime.QuadPart = WDF_REL_TIMEOUT_IN_MS(100); WdfTimerStart(queueContext->Timer, DueTime.QuadPart); KdPrint(( "<-- EchoEvtDeviceSelfManagedIoInit\n")); return STATUS_SUCCESS; }
// // PRE REQUIREMENTS: // * pipeContext->IsValid == FALSE // * Queue(if any) must be stopped // * IoTarget must be stopped // // On return the pipe and queue are started and the context is marked valid again. // NTSTATUS Pipe_InitContext(__in PDEVICE_CONTEXT deviceContext, __in PPIPE_CONTEXT pipeContext, __in BOOLEAN startIoTarget) { NTSTATUS status = STATUS_INVALID_HANDLE; WDFQUEUE queueOld = pipeContext->Queue; WDFQUEUE queueNew = NULL; if (!pipeContext->Pipe && pipeContext->PipeInformation.PipeType != WdfUsbPipeTypeControl) { USBERR("pipeID=%02Xh invalid pipe handle\n", pipeContext->PipeInformation.EndpointAddress); goto Done; } if (queueOld == NULL || ((pipeContext->PipeInformation.EndpointAddress & 0xF) && pipeContext->IsQueueDirty)) { pipeContext->IsQueueDirty = FALSE; if (queueOld != NULL) { // We need to delete the old pipe queue. USBDBGN("pipeID=%02Xh Destroying old pipe queue.", pipeContext->PipeInformation.EndpointAddress); WdfObjectDelete(queueOld); queueOld = NULL; } USBDBGN("pipeID=%02Xh Creating pipe queue.", pipeContext->PipeInformation.EndpointAddress); status = Pipe_InitQueue(deviceContext, pipeContext, &queueNew); if (!NT_SUCCESS(status)) { pipeContext->Queue = NULL; pipeContext->IsValid = FALSE; USBERRN("Pipe_InitQueue failed. pipeID=%02Xh status=%08Xh", pipeContext->PipeInformation.EndpointAddress, status); goto Done; } pipeContext->Queue = queueNew; } else { // Queue is already created and does not need to be updated. status = STATUS_SUCCESS; queueNew = queueOld; } if (!queueNew && NT_SUCCESS(status)) status = STATUS_INVALID_PIPE_STATE; if (NT_SUCCESS(status)) { if (pipeContext->PipeInformation.PipeType != WdfUsbPipeTypeControl) { if (startIoTarget) { // start pipe USBDBG("pipeID=%02Xh starting..\n", pipeContext->PipeInformation.EndpointAddress); status = PipeStart(pipeContext); if (!NT_SUCCESS(status)) { pipeContext->IsValid = FALSE; USBERR("WdfIoTargetStart failed. status=%Xh\n", status); goto Done; } } } // start queue USBDBG("pipeID=%02Xh queue starting..\n", pipeContext->PipeInformation.EndpointAddress); WdfIoQueueStart(queueNew); pipeContext->IsValid = TRUE; } else { USBERR("WdfIoQueueCreate failed. status=%Xh\n", status); pipeContext->IsValid = FALSE; goto Done; } Done: return status; }
VOID VIOSerialRenewAllPorts( IN WDFDEVICE Device ) { NTSTATUS status = STATUS_SUCCESS; WDFCHILDLIST list; WDF_CHILD_LIST_ITERATOR iterator; PPORTS_DEVICE pContext = GetPortsDevice(Device); TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,"--> %s\n", __FUNCTION__); if(pContext->isHostMultiport) { VIOSerialFillQueue(pContext->c_ivq, pContext->CVqLock); } list = WdfFdoGetDefaultChildList(Device); WDF_CHILD_LIST_ITERATOR_INIT(&iterator, WdfRetrievePresentChildren ); WdfChildListBeginIteration(list, &iterator); for (;;) { WDF_CHILD_RETRIEVE_INFO childInfo; VIOSERIAL_PORT vport; WDFDEVICE hChild; WDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER_INIT( &vport.Header, sizeof(vport) ); WDF_CHILD_RETRIEVE_INFO_INIT(&childInfo, &vport.Header); status = WdfChildListRetrieveNextDevice( list, &iterator, &hChild, &childInfo ); if (!NT_SUCCESS(status) || status == STATUS_NO_MORE_ENTRIES) { break; } ASSERT(childInfo.Status == WdfChildListRetrieveDeviceSuccess); VIOSerialEnableInterruptQueue(GetInQueue(&vport)); WdfIoQueueStart(vport.ReadQueue); WdfIoQueueStart(vport.WriteQueue); WdfIoQueueStart(vport.IoctlQueue); if(vport.GuestConnected) { VIOSerialSendCtrlMsg(vport.BusDevice, vport.PortId, VIRTIO_CONSOLE_PORT_OPEN, 1); } } WdfChildListEndIteration(list, &iterator); WdfChildListUpdateAllChildDescriptionsAsPresent(list); TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,"<-- %s\n", __FUNCTION__); return; }
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; }
VOID SingleCompWdmActiveConditionCallback( _In_ PVOID Context, _In_ ULONG Component ) /*++ Routine Description: This callback is invoked by Power Framework to notify driver that one of its components has become active. Arguments: Context - Context that we supplied when calling WdfDeviceWdmAssignPowerFrameworkSettings. Component - Component that have become active. Since we have only one component this value is always 0. Return Value: None --*/ { WDFDEVICE device; FDO_DATA *fdoContext = NULL; UCHAR i = 0; // // We have only component 0 // if (0 != Component) { Trace(TRACE_LEVEL_ERROR,"%!FUNC! - Unexpected component %d",Component); ASSERT(FALSE); } // // Get the device // device = (WDFDEVICE) Context; // // Get the device context // fdoContext = FdoGetContext(device); // // Mark ourselves as active // fdoContext->IsActive = TRUE; // // Start power-managed queues // for (i = 0; i < QUEUE_COUNT; i++) { WdfIoQueueStart(fdoContext->Queues[i]); } return; }