// This callback is called when the simulator wait time has expired and the simulator // is ready to switch to the next sample. The callback updates the sample index and // schedules the next wake up time. VOID HardwareSimulator::OnTimerExpire( _In_ WDFTIMER Timer) // WDF timer object { HardwareSimulator *pSimulator = nullptr; NTSTATUS Status = STATUS_SUCCESS; SENSOR_FunctionEnter(); pSimulator = GetHardwareSimulatorContextFromInstance(WdfTimerGetParentObject(Timer)); if (nullptr == pSimulator) { Status = STATUS_INSUFFICIENT_RESOURCES; TraceError("CSTM %!FUNC! GetHardwareSimulatorContextFromInstance failed %!STATUS!", Status); } if (NT_SUCCESS(Status)) { // Increment the sample index, roll over if the index reach the end of the array WdfWaitLockAcquire(pSimulator->m_Lock, NULL); pSimulator->m_Index++; pSimulator->m_Index = pSimulator->m_Index % ARRAYSIZE(SimulatorData); WdfWaitLockRelease(pSimulator->m_Lock); WdfTimerStart(pSimulator->m_Timer, WDF_REL_TIMEOUT_IN_MS(SIMULATOR_HARDWARE_INTERVAL_MS)); } SENSOR_FunctionExit(Status); }
// This callback is called when interval wait time has expired and driver is ready // to collect new sample. The callback reads current value, compare value to threshold, // pushes it up to CLX framework, and schedule next wake up time. VOID ActivityDevice::OnTimerExpire(_In_ WDFTIMER timer) { NTSTATUS status = STATUS_SUCCESS; SENSOR_FunctionEnter(); PActivityDevice pDevice = GetActivityContextFromSensorInstance(WdfTimerGetParentObject(timer)); if (nullptr == pDevice) { status = STATUS_INSUFFICIENT_RESOURCES; TraceError("ACT %!FUNC! GetActivityContextFromSensorInstance failed %!STATUS!", status); } else { // Get data and push to clx WdfWaitLockAcquire(pDevice->m_Lock, NULL); status = pDevice->GetData(); if (!NT_SUCCESS(status) && STATUS_DATA_NOT_ACCEPTED != status) { TraceError("ACT %!FUNC! GetAccData Failed %!STATUS!", status); } WdfWaitLockRelease(pDevice->m_Lock); // Schedule next wake up time if (Act_Default_MinDataInterval_Ms <= pDevice->m_Interval && FALSE != pDevice->m_PoweredOn && FALSE != pDevice->m_Started) { WdfTimerStart(pDevice->m_Timer, WDF_REL_TIMEOUT_IN_MS(pDevice->m_Interval)); } } SENSOR_FunctionExit(status); }
VOID SerialTimeoutImmediate( IN WDFTIMER Timer ) { PSERIAL_DEVICE_EXTENSION Extension = NULL; Extension = SerialGetDeviceExtension(WdfTimerGetParentObject(Timer)); SerialDbgPrintEx(TRACE_LEVEL_INFORMATION, DBG_IOCTLS, ">SerialTimeoutImmediate(%p)\n", Extension); SerialTryToCompleteCurrent( Extension, SerialGrabImmediateFromIsr, STATUS_TIMEOUT, &Extension->CurrentImmediateRequest, NULL, NULL, Extension->ImmediateTotalTimer, NULL, SerialGetNextImmediate, SERIAL_REF_TOTAL_TIMER ); SerialDbgPrintEx(TRACE_LEVEL_INFORMATION, DBG_IOCTLS, "<SerialTimeoutImmediate\n"); }
// This function gets called when the timeout period of debounce timer elapses. // It reports a switch change by completing a pending request // void HidFx2EvtTimerFunction(_In_ WDFTIMER hTimer) { WDFDEVICE hDevice = NULL; WDFREQUEST hRequest; PDEVICE_EXTENSION pDevContext = NULL; NTSTATUS status = STATUS_SUCCESS; size_t cBytesReturned = 0; unsigned char bToggledSwitch = 0; ULONG cBytesToCopy = 0; PHIDFX2_IO_REPORT pInputReport = NULL; TraceVerbose(DBG_IOCTL, "(%!FUNC!) Enter\n"); hDevice = WdfTimerGetParentObject(hTimer); pDevContext = GetDeviceContext(hDevice); bToggledSwitch = pDevContext->bLatestToggledSwitch; TraceInfo(DBG_IOCTL, "(%!FUNC!) mode %d switch %d\n", pDevContext->driverMode, bToggledSwitch); if (!((pDevContext->driverMode == DM_BUTTON || pDevContext->driverMode == DM_BUTTON_AND_LED) && bToggledSwitch == 0)) { // Check if there are any pending requests in the Interrupt Message Queue. // If a request is found then complete the pending request. status = WdfIoQueueRetrieveNextRequest(pDevContext->hInterruptMsgQueue, &hRequest); if (NT_SUCCESS(status)) { cBytesToCopy = sizeof(pInputReport[0]); status = WdfRequestRetrieveOutputBuffer(hRequest, cBytesToCopy, &pInputReport, &cBytesReturned); // BufferLength if (NT_SUCCESS(status)) { TraceInfo(DBG_IOCTL, "(%!FUNC!) WdfRequestRetrieveOutputBuffer switch %d\n", bToggledSwitch); pInputReport->bReportId = GENERIC_DESKTOP_REPORT_ID; pInputReport->bData = bToggledSwitch; cBytesReturned = cBytesToCopy; } else // WdfRequestRetrieveOutputBuffer failed { TraceErr(DBG_IOCTL, "(%!FUNC!) WdfRequestRetrieveOutputBuffer failed with status: %!STATUS!\n", status); } WdfRequestCompleteWithInformation(hRequest, status, cBytesReturned); } else if (status != STATUS_NO_MORE_ENTRIES) { TraceErr(DBG_IOCTL, "(%!FUNC!) WdfIoQueueRetrieveNextRequest status %!STATUS!\n", status); } } else { TraceInfo(DBG_IOCTL, "(%!FUNC!) ignore switch"); } TraceVerbose(DBG_IOCTL, "(%!FUNC!) Exit\n"); }
VOID SimSensorExpiredRequestTimer ( WDFTIMER Timer ) /*++ Routine Description: This routine is invoked when a request timer expires. A scan of the pending queue to complete expired and satisfied requests is initiated. Arguments: Timer - Supplies a handle to the timer which expired. --*/ { PFDO_DATA DevExt; WDFDEVICE Device; DebugEnter(); PAGED_CODE(); Device = (WDFDEVICE)WdfTimerGetParentObject(Timer); DevExt = GetDeviceExtension(Device); WdfWaitLockAcquire(DevExt->QueueLock, NULL); SimSensorScanPendingQueue(Device); WdfWaitLockRelease(DevExt->QueueLock); DebugExit(); }
/*++ Routine Description: This routine will try to timeout the current write. Arguments: Return Value: None. --*/ _Use_decl_annotations_ VOID SerialWriteTimeout( WDFTIMER Timer ) { PSERIAL_DEVICE_EXTENSION extension = NULL; extension = SerialGetDeviceExtension(WdfTimerGetParentObject(Timer)); TraceEvents(TRACE_LEVEL_INFORMATION, DBG_WRITE, "++SerialWriteTimeout(%p)\r\n", extension); SerialTryToCompleteCurrent(extension, SerialGrabWriteFromIsr, STATUS_TIMEOUT, &extension->CurrentWriteRequest, extension->WriteQueue, NULL, extension->WriteRequestTotalTimer, SerialStartWrite, SerialGetNextWrite, SERIAL_REF_TOTAL_TIMER); TraceEvents(TRACE_LEVEL_INFORMATION, DBG_WRITE, "--SerialWriteTimeout\r\n"); }
VOID HidFx2EvtTimerFunction( IN WDFTIMER Timer ) /*++ Routine Description: This function gets called when the timeout period of debounce timer elapses. Arguments: Timer - Handle to a framework timer object. Return Value: none --*/ { #ifndef USE_ALTERNATE_HID_REPORT_DESCRIPTOR PDEVICE_EXTENSION devContext = GetDeviceContext(WdfTimerGetParentObject(Timer)); // // Complete the request if there is a swicthed in toggled-on position // if (devContext->LatestToggledSwitch != 0) { HidFx2CompleteReadReport(WdfTimerGetParentObject(Timer)); } #else // // Always complete the read request for the vendor collection // input report. // HidFx2CompleteReadReport(WdfTimerGetParentObject(Timer)); #endif // USE_ALTERNATE_HID_REPORT_DESCRIPTOR }
// This callback is called when interval wait time has expired and driver is ready // to collect new sample. The callback stores activity data in history buffer, // and schedules next wake up time. VOID ActivityDevice::OnHistoryTimerExpire(_In_ WDFTIMER historyTimer) { NTSTATUS status = STATUS_SUCCESS; SENSOR_FunctionEnter(); PActivityDevice pDevice = GetActivityContextFromSensorInstance(WdfTimerGetParentObject(historyTimer)); if (nullptr == pDevice) { status = STATUS_INSUFFICIENT_RESOURCES; TraceError("ACT %!FUNC! GetActivityContextFromSensorInstance failed %!STATUS!", status); } else { ActivitySample data = {}; if (NULL != pDevice->m_SimulatorInstance) { PHardwareSimulator pSimulator = GetHardwareSimulatorContextFromInstance(pDevice->m_SimulatorInstance); if (nullptr != pSimulator) { status = pSimulator->GetSample(&data); } else { status = STATUS_INVALID_PARAMETER; } } GetSystemTimePreciseAsFileTime(&(data.Timestamp)); if (NT_SUCCESS(status)) { // Add data to the buffer WdfWaitLockAcquire(pDevice->m_HistoryLock, NULL); status = pDevice->AddDataElementToHistoryBuffer(&data); if (!NT_SUCCESS(status)) { TraceError("ACT %!FUNC! AddDataElementToHistoryBuffer Failed %!STATUS!", status); } WdfWaitLockRelease(pDevice->m_HistoryLock); } // Schedule next wake up time if (FALSE != pDevice->m_HistoryStarted) { WdfTimerStart(pDevice->m_HistoryTimer, WDF_REL_TIMEOUT_IN_MS(pDevice->m_HistoryIntervalInMs)); } } SENSOR_FunctionExit(status); }
void CyapaTimerFunc(_In_ WDFTIMER hTimer){ WDFDEVICE Device = (WDFDEVICE)WdfTimerGetParentObject(hTimer); PDEVICE_CONTEXT pDevice = GetDeviceContext(Device); if (!pDevice->ConnectInterrupt) return; if (!pDevice->RegsSet) return; struct cyapa_regs regs = pDevice->lastregs; cyapa_softc sc = pDevice->sc; TrackpadRawInput(pDevice, &sc, ®s, 1); pDevice->sc = sc; return; }
void CyapaBootTimer(_In_ WDFTIMER hTimer) { WDFDEVICE Device = (WDFDEVICE)WdfTimerGetParentObject(hTimer); PDEVICE_CONTEXT pDevice = GetDeviceContext(Device); WDF_OBJECT_ATTRIBUTES attributes; WDF_WORKITEM_CONFIG workitemConfig; WDFWORKITEM hWorkItem; WDF_OBJECT_ATTRIBUTES_INIT(&attributes); WDF_OBJECT_ATTRIBUTES_SET_CONTEXT_TYPE(&attributes, DEVICE_CONTEXT); attributes.ParentObject = Device; WDF_WORKITEM_CONFIG_INIT(&workitemConfig, CyapaBootWorkItem); WdfWorkItemCreate(&workitemConfig, &attributes, &hWorkItem); WdfWorkItemEnqueue(hWorkItem); WdfTimerStop(hTimer, FALSE); }
/** * @brief Watchdog timer * checks the operational state of the xen interface and initiates surprise removal if * the interface is not operational and the device is not unplugged. * * @param[in] Timer handle to timer allocated by FdoDeviceAdd() * */ VOID FdoEvtTimerFunc( IN WDFTIMER Timer) { PUSB_FDO_CONTEXT fdoContext = DeviceGetFdoContext(WdfTimerGetParentObject(Timer)); // XenCheckOperationalState waits on an event. Must be called at < DISPATCH_LEVEL. BOOLEAN operational = XenCheckOperationalState(fdoContext->Xen); AcquireFdoLock(fdoContext); if (!fdoContext->DeviceUnplugged) { if (operational) { // restart the timer. WdfTimerStart(Timer, WDF_REL_TIMEOUT_IN_SEC(1)); } else { TraceEvents(TRACE_LEVEL_WARNING, TRACE_DEVICE, __FUNCTION__": %s Device %p unplug detected by watchdog\n", fdoContext->FrontEndPath, fdoContext->WdfDevice); FdoUnplugDevice(fdoContext); ReleaseFdoLock(fdoContext); return; } } ReleaseFdoLock(fdoContext); // // @todo run the dpc - if this fixes anything fix the bug! // if (!fdoContext->DeviceUnplugged) { // // --XT-- Now passing the FDO context directly. // FdoEvtDeviceDpcFunc(fdoContext); } }
/*++ Routine Description: This routine is merely used to truely complete an xoff counter request, if its timer has run out. Arguments: Return Value: None. --*/ _Use_decl_annotations_ VOID SerialTimeoutXoff( WDFTIMER Timer ) { PSERIAL_DEVICE_EXTENSION extension = NULL; extension = SerialGetDeviceExtension(WdfTimerGetParentObject(Timer)); TraceEvents(TRACE_LEVEL_INFORMATION, DBG_WRITE, "++SerialTimeoutXoff(%p)\r\n", extension); SerialTryToCompleteCurrent(extension, SerialGrabXoffFromIsr, STATUS_SERIAL_COUNTER_TIMEOUT, &extension->CurrentXoffRequest, NULL, NULL, NULL, NULL, NULL, SERIAL_REF_TOTAL_TIMER); TraceEvents(TRACE_LEVEL_INFORMATION, DBG_WRITE, "--SerialTimeoutXoff\r\n"); }
VOID EchoEvtTimerFunc( IN WDFTIMER Timer ) /*++ Routine Description: This is the TimerDPC the driver sets up to complete requests. This function is registered when the WDFTIMER object is created, and will automatically synchronize with the I/O Queue callbacks and cancel routine. Arguments: Timer - Handle to a framework Timer object. Return Value: VOID --*/ { NTSTATUS Status; WDFREQUEST Request; WDFQUEUE queue; PQUEUE_CONTEXT queueContext ; queue = WdfTimerGetParentObject(Timer); queueContext = QueueGetContext(queue); // // DPC is automatically synchronized to the Queue lock, // so this is race free without explicit driver managed locking. // Request = queueContext->CurrentRequest; if( Request != NULL ) { // // Attempt to remove cancel status from the request. // // The request is not completed if it is already cancelled // since the EchoEvtIoCancel function has run, or is about to run // and we are racing with it. // Status = WdfRequestUnmarkCancelable(Request); if( Status != STATUS_CANCELLED ) { queueContext->CurrentRequest = NULL; Status = queueContext->CurrentStatus; KdPrint(("CustomTimerDPC Completing request 0x%p, Status 0x%x \n", Request,Status)); WdfRequestComplete(Request, Status); } else { KdPrint(("CustomTimerDPC Request 0x%p is STATUS_CANCELLED, not completing\n", Request)); } } // // Restart the Timer since WDF does not allow periodic timer // with autosynchronization at passive level // WdfTimerStart(Timer, TIMER_PERIOD); return; }
VOID NICWatchDogEvtTimerFunc( IN WDFTIMER Timer ) /*++ Routine Description: This DPC is used to do both link detection during hardware init and after that for hardware hang detection. Arguments: Return Value: None --*/ { PFDO_DATA FdoData = NULL; LARGE_INTEGER DueTime; NTSTATUS status = STATUS_SUCCESS; FdoData = FdoGetData(WdfTimerGetParentObject(Timer)); DueTime.QuadPart = NIC_CHECK_FOR_HANG_DELAY; if(!FdoData->CheckForHang){ // // We are still doing link detection // status = NICLinkDetection(FdoData); if(status == STATUS_PENDING) { // Wait for 100 ms FdoData->bLinkDetectionWait = TRUE; DueTime.QuadPart = NIC_LINK_DETECTION_DELAY; }else { FdoData->CheckForHang = TRUE; } }else { // // Link detection is over, let us check to see // if the hardware is stuck. // if(NICCheckForHang(FdoData)){ status = NICReset(FdoData); if(!NT_SUCCESS(status)){ goto Exit; } } } WdfTimerStart(FdoData->WatchDogTimer, // Timer DueTime.QuadPart // DueTime ); return; Exit: TraceEvents(TRACE_LEVEL_INFORMATION, DBG_DPC, "WatchDogTimer is exiting %x\n", status); return; }
// This callback is called when interval wait time has expired and driver is ready // to collect new sample. The callback reads current value, // pushes it up to CLX framework, and schedule next wake up time. VOID CustomSensorDevice::OnTimerExpire( _In_ WDFTIMER Timer // WDF timer object ) { PCustomSensorDevice pDevice = nullptr; NTSTATUS Status = STATUS_SUCCESS; SENSOR_FunctionEnter(); pDevice = GetCustomSensorContextFromSensorInstance(WdfTimerGetParentObject(Timer)); if (nullptr == pDevice) { Status = STATUS_INSUFFICIENT_RESOURCES; TraceError("CSTM %!FUNC! GetCustomSensorContextFromSensorInstance failed %!STATUS!", Status); } if (NT_SUCCESS(Status)) { // Get data and push to clx WdfWaitLockAcquire(pDevice->m_Lock, NULL); Status = pDevice->GetData(); if (!NT_SUCCESS(Status) && Status != STATUS_DATA_NOT_ACCEPTED) { TraceError("CSTM %!FUNC! GetCstmData Failed %!STATUS!", Status); } WdfWaitLockRelease(pDevice->m_Lock); // Schedule next wake up time if (FALSE != pDevice->m_PoweredOn && FALSE != pDevice->m_Started) { LONGLONG WaitTimeHundredNanoseconds = 0; // in unit of 100ns if (0 == pDevice->m_StartTime) { // in case we fail to get sensor start time, use static wait time WaitTimeHundredNanoseconds = WDF_REL_TIMEOUT_IN_MS(pDevice->m_Interval); } else { ULONG CurrentTimeMs = 0; // dynamically calculate wait time to avoid jitter Status = GetPerformanceTime(&CurrentTimeMs); if (!NT_SUCCESS(Status)) { TraceError("PED %!FUNC! GetPerformanceTime %!STATUS!", Status); WaitTimeHundredNanoseconds = WDF_REL_TIMEOUT_IN_MS(pDevice->m_Interval); } else { WaitTimeHundredNanoseconds = pDevice->m_Interval - ((CurrentTimeMs - pDevice->m_StartTime) % pDevice->m_Interval); WaitTimeHundredNanoseconds = WDF_REL_TIMEOUT_IN_MS(WaitTimeHundredNanoseconds); } } WdfTimerStart(pDevice->m_Timer, WaitTimeHundredNanoseconds); } } SENSOR_FunctionExit(Status); }
// This callback is called when interval wait time has expired and driver is ready // to collect new sample. The callback reads current value, compare value to threshold, // pushes it up to CLX framework, and schedule next wake up time. VOID PedometerDevice::OnTimerExpire( _In_ WDFTIMER Timer // WDF timer object ) { PPedometerDevice pDevice = nullptr; NTSTATUS Status = STATUS_SUCCESS; SENSOR_FunctionEnter(); pDevice = GetPedometerContextFromSensorInstance(WdfTimerGetParentObject(Timer)); if (nullptr == pDevice) { Status = STATUS_INSUFFICIENT_RESOURCES; TraceError("PED %!FUNC! GetPedometerContextFromSensorInstance failed %!STATUS!", Status); goto Exit; } // Get data and push to clx WdfWaitLockAcquire(pDevice->m_Lock, NULL); Status = pDevice->GetData(); if (!NT_SUCCESS(Status) && Status != STATUS_DATA_NOT_ACCEPTED) { TraceError("PED %!FUNC! GetData Failed %!STATUS!", Status); } WdfWaitLockRelease(pDevice->m_Lock); // Schedule next wake up time if (FALSE != pDevice->m_PoweredOn && FALSE != pDevice->m_Started) { LONGLONG WaitTimeHundredNanoseconds = 0; // in unit of 100ns if (0 == pDevice->m_StartTime) { // in case we fail to get sensor start time, use static wait time WaitTimeHundredNanoseconds = WDF_REL_TIMEOUT_IN_MS(pDevice->m_Interval); } else { ULONG CurrentTimeMs = 0; // dynamically calculate wait time to avoid jitter Status = GetPerformanceTime (&CurrentTimeMs); if (!NT_SUCCESS(Status)) { TraceError("PED %!FUNC! GetPerformanceTime %!STATUS!", Status); WaitTimeHundredNanoseconds = WDF_REL_TIMEOUT_IN_MS(pDevice->m_Interval); } else { pDevice->m_SampleCount++; if (CurrentTimeMs > (pDevice->m_StartTime + (pDevice->m_Interval * (pDevice->m_SampleCount + 1)))) { // If we skipped two or more beats, reschedule the timer with a zero due time to catch up on missing samples WaitTimeHundredNanoseconds = 0; } else { WaitTimeHundredNanoseconds = (pDevice->m_StartTime + (pDevice->m_Interval * (pDevice->m_SampleCount + 1))) - CurrentTimeMs; } WaitTimeHundredNanoseconds = WDF_REL_TIMEOUT_IN_MS(WaitTimeHundredNanoseconds); } } WdfTimerStart(pDevice->m_Timer, WaitTimeHundredNanoseconds); } Exit: SENSOR_FunctionExit(Status); }