/** * @brief Transition to fully powered state with interrupts enabled. * This is the first chance we have to interact with a fully functional device, * so collect the device configuration so we can create a USB pdo that can be * enumerated by PnP. * * Allow failures to "succeed" (return STATUS_SUCCESS) so that the * dreaded Yellow Bang does not occur. Instead, this device will appear * normally in Windows Device Manager, however it will not instantiate * its child RootHub PDO. * * @param[in] Device handle to the WDFDEVICE created by FdoEvtDeviceAdd(). * * @returns NTSTATUS value indicating success or failure. * */ NTSTATUS FdoEvtDeviceD0EntryPostInterruptsEnabled( IN WDFDEVICE device, IN WDF_POWER_DEVICE_STATE) { NTSTATUS status = STATUS_SUCCESS; PUSB_FDO_CONTEXT fdoContext = DeviceGetFdoContext(device); BOOLEAN online = XenCheckOnline(fdoContext->Xen); if (!online) { /* Backend device disappeared behind our back (while guest was in S3, for example), clean it up.. */ CleanupDisconnectedDevice(fdoContext); return STATUS_SUCCESS; } if (!fdoContext->XenConfigured) { status = XenConfigure(fdoContext); if (!NT_SUCCESS(status)) { return status; } WdfTimerStart(fdoContext->WatchdogTimer, WDF_REL_TIMEOUT_IN_SEC(2)); } return status; }
VOID FxWorkItem::WaitForSignal( VOID ) { LARGE_INTEGER timeOut; NTSTATUS status; ASSERT(Mx::MxGetCurrentIrql() == PASSIVE_LEVEL); timeOut.QuadPart = WDF_REL_TIMEOUT_IN_SEC(60); do { status = m_WorkItemCompleted.EnterCRAndWaitAndLeave(&timeOut.QuadPart); if (status == STATUS_TIMEOUT) { DbgPrint("Thread 0x%p is waiting on WDFWORKITEM 0x%p\n", Mx::GetCurrentEThread(), GetHandle()); } else { ASSERT(NT_SUCCESS(status)); break; } } WHILE(TRUE); ASSERT(NT_SUCCESS(status)); return; }
VOID Toastmon_EvtTimerPostRequests( IN WDFTIMER Timer ) /*++ Routine Description: Passive timer event to post read and write reqeuests. Return Value: None --*/ { PTARGET_DEVICE_INFO targetInfo; WDFIOTARGET ioTarget = GetTimerContext(Timer)->IoTarget; targetInfo = GetTargetDeviceInfo(ioTarget); // // Even though this routine and the completion routine check the // ReadRequest/WriteRequest field outside a lock, no harm is done. // Depending on how far the completion-routine has run, timer // may miss an opportunity to post a request. Even if we use a lock, // this race condition will still exist. // // // Send a read request to the target device // if(targetInfo->ReadRequest) { ToastMon_PostReadRequests(ioTarget); } // // Send a write request to the target device // if(targetInfo->WriteRequest) { ToastMon_PostWriteRequests(ioTarget); } // // Restart the passive timer. // WdfTimerStart(targetInfo->TimerForPostingRequests, WDF_REL_TIMEOUT_IN_SEC(1)); return; }
VOID ToastMon_EvtIoTargetRemoveCanceled( WDFIOTARGET IoTarget ) /*++ Routine Description: Called when the Target device received IRP_MN_CANCEL_REMOVE. This happens if another app or driver talking to the target device doesn't close handle or veto query-remove notification. Arguments: IoTarget - Return Value: --*/ { PTARGET_DEVICE_INFO targetDeviceInfo = NULL; WDF_IO_TARGET_OPEN_PARAMS openParams; NTSTATUS status; PAGED_CODE(); KdPrint((("Device Removal (remove cancelled) Notification\n"))); targetDeviceInfo = GetTargetDeviceInfo(IoTarget); // // Reopen the Target. // WDF_IO_TARGET_OPEN_PARAMS_INIT_REOPEN(&openParams); status = WdfIoTargetOpen(IoTarget, &openParams); if (!NT_SUCCESS(status)) { KdPrint(("WdfIoTargetOpen failed 0x%x\n", status)); WdfObjectDelete(IoTarget); return; } // // Restart the timer. // WdfTimerStart(targetDeviceInfo->TimerForPostingRequests, WDF_REL_TIMEOUT_IN_SEC(1)); }
//This routine sets the state of the Feature: in this case Segment Display on the USB FX2 board. NTSTATUS SendVendorCommand(_In_ WDFDEVICE hDevice, _In_ unsigned char bVendorCommand, _In_ unsigned char bCommandData) { NTSTATUS status = STATUS_SUCCESS; ULONG cBytesTransferred = 0; PDEVICE_EXTENSION pDevContext = NULL; WDF_MEMORY_DESCRIPTOR memDesc; WDF_USB_CONTROL_SETUP_PACKET controlSetupPacket; WDF_REQUEST_SEND_OPTIONS sendOptions; PAGED_CODE(); TraceVerbose(DBG_IOCTL, "(%!FUNC!) Enter\n"); pDevContext = GetDeviceContext(hDevice); TraceInfo(DBG_IOCTL, "(%!FUNC!): Command:0x%x, data: 0x%x\n", bVendorCommand, bCommandData); // Send the I/O with a timeout. // We do that because we send the I/O in the context of the user thread and if it gets stuck, it would prevent the user process from existing. WDF_REQUEST_SEND_OPTIONS_INIT(&sendOptions, WDF_REQUEST_SEND_OPTION_TIMEOUT); WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT(&sendOptions, WDF_REL_TIMEOUT_IN_SEC(5)); WDF_USB_CONTROL_SETUP_PACKET_INIT_VENDOR(&controlSetupPacket, BmRequestHostToDevice, BmRequestToDevice, bVendorCommand, // Request 0, // Value 0); // Index WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&memDesc, &bCommandData, sizeof(bCommandData)); status = WdfUsbTargetDeviceSendControlTransferSynchronously(pDevContext->hUsbDevice, WDF_NO_HANDLE, // Optional WDFREQUEST &sendOptions, // PWDF_REQUEST_SEND_OPTIONS &controlSetupPacket, &memDesc, &cBytesTransferred); if (!NT_SUCCESS(status)) { TraceErr(DBG_IOCTL, "(%!FUNC!): Failed to set Segment Display state - %!STATUS!\n", status); } TraceVerbose(DBG_IOCTL, "(%!FUNC!) Exit\n"); return status; }
/** * @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); } }
_Must_inspect_result_ NTSTATUS FxUsbDevice::SendSyncUmUrb( __inout PUMURB Urb, __in ULONGLONG Time, __in_opt WDFREQUEST Request, __in_opt PWDF_REQUEST_SEND_OPTIONS Options ) { NTSTATUS status; WDF_REQUEST_SEND_OPTIONS options; FxSyncRequest request(GetDriverGlobals(), NULL, Request); status = request.Initialize(); if (!NT_SUCCESS(status)) { DoTraceLevelMessage(GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGIOTARGET, "Failed to initialize FxSyncRequest"); return status; } if (NULL == Options) { Options = &options; } WDF_REQUEST_SEND_OPTIONS_INIT(Options, 0); WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT(Options, WDF_REL_TIMEOUT_IN_SEC(Time)); status = request.m_TrueRequest->ValidateTarget(this); if (NT_SUCCESS(status)) { FxUsbUmFormatRequest(request.m_TrueRequest, &Urb->UmUrbHeader, m_pHostTargetFile); status = SubmitSync(request.m_TrueRequest, Options); if (!NT_SUCCESS(status)) { DoTraceLevelMessage(GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGIOTARGET, "FxUsbDevice SubmitSync failed"); return status; } } return status; }
_Must_inspect_result_ NTSTATUS FxUsbDevice::SendSyncRequest( __in FxSyncRequest* Request, __in ULONGLONG Time ) { NTSTATUS status; WDF_REQUEST_SEND_OPTIONS options; WDF_REQUEST_SEND_OPTIONS_INIT(&options, 0); WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT(&options, WDF_REL_TIMEOUT_IN_SEC(Time)); status = SubmitSync(Request->m_TrueRequest, &options); if (!NT_SUCCESS(status)) { DoTraceLevelMessage(GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGIOTARGET, "FxUsbDevice SubmitSync failed"); goto Done; } Done: return status; }
NTSTATUS GetDevInfoData( __in PFILTER_EXTENSION filterExt, __in ULONG DevInfoLen, __out BYTE* pDevInfoData, __out size_t* bytesRead ) /*++ Routine Description This routine gets the data of the device Arguments: pDevInfoLen - One of our device extensions Return Value: NT status value --*/ { NTSTATUS status; WDF_USB_CONTROL_SETUP_PACKET controlSetupPacket; WDF_REQUEST_SEND_OPTIONS sendOptions; WDF_MEMORY_DESCRIPTOR memDesc; ULONG bytesTransferred; PAGED_CODE(); WDF_REQUEST_SEND_OPTIONS_INIT( &sendOptions, WDF_REQUEST_SEND_OPTION_TIMEOUT ); WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT( &sendOptions, WDF_REL_TIMEOUT_IN_SEC(5) ); WDF_USB_CONTROL_SETUP_PACKET_INIT_VENDOR(&controlSetupPacket, BmRequestDeviceToHost, BmRequestToDevice, USBFX2LK_READ_DEVINFO_DATA, // Request 0, // Value 0); // Index WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&memDesc, pDevInfoData, DevInfoLen); status = WdfUsbTargetDeviceSendControlTransferSynchronously( filterExt->UsbDevice, WDF_NO_HANDLE, // Optional WDFREQUEST &sendOptions, &controlSetupPacket, &memDesc, &bytesTransferred); if(!NT_SUCCESS(status)) { KdPrint( ("GetDevInfoData: Failed - 0x%x \n", status)); *bytesRead = 0; } else { KdPrint( ("GetDevInfoData: transferred bytes %d \n", bytesTransferred )); *bytesRead = (size_t)bytesTransferred; } return status; }
NTSTATUS GetDevInfoLength( __in PFILTER_EXTENSION filterExt, __out BYTE* pDevInfoLen ) /*++ Routine Description This routine gets the length of device info, so caller app can prepare proper buffer to retrieve the actual content info Arguments: pDevInfoLen - One of our device extensions Return Value: NT status value --*/ { NTSTATUS status; WDF_USB_CONTROL_SETUP_PACKET controlSetupPacket; WDF_REQUEST_SEND_OPTIONS sendOptions; WDF_MEMORY_DESCRIPTOR memDesc; ULONG bytesTransferred; PAGED_CODE(); WDF_REQUEST_SEND_OPTIONS_INIT( &sendOptions, WDF_REQUEST_SEND_OPTION_TIMEOUT ); WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT( &sendOptions, WDF_REL_TIMEOUT_IN_SEC(5) ); WDF_USB_CONTROL_SETUP_PACKET_INIT_VENDOR(&controlSetupPacket, BmRequestDeviceToHost, BmRequestToDevice, USBFX2LK_READ_DEVINFO_LEN, // Request 0, // Value 0); // Index // // Set the buffer to 0, the board will OR in everything that is set // *pDevInfoLen = 0; WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&memDesc, pDevInfoLen, sizeof(BYTE)); status = WdfUsbTargetDeviceSendControlTransferSynchronously( filterExt->UsbDevice, WDF_NO_HANDLE, // Optional WDFREQUEST &sendOptions, &controlSetupPacket, &memDesc, &bytesTransferred); if(!NT_SUCCESS(status)) { KdPrint( ("GetDevInfoLength: Failed - 0x%x \n", status)); } else { KdPrint( ("GetDevInfoLength: %d \n", *pDevInfoLen )); } return status; }
VOID ToastMon_EvtIoTargetRemoveCanceled( WDFIOTARGET IoTarget ) /*++ Routine Description: Called when the Target device received IRP_MN_CANCEL_REMOVE. This happens if another app or driver talking to the target device doesn't close handle or veto query-remove notification. Arguments: IoTarget - Return Value: --*/ { PTARGET_DEVICE_INFO targetDeviceInfo = NULL; WDFWAITLOCK targetDeviceCollectionLock; WDF_IO_TARGET_OPEN_PARAMS openParams; NTSTATUS status; PAGED_CODE(); KdPrint((("Device Removal (remove cancelled) Notification\n"))); targetDeviceInfo = GetTargetDeviceInfo(IoTarget); // // Reopen the Target. // WDF_IO_TARGET_OPEN_PARAMS_INIT_REOPEN(&openParams); status = WdfIoTargetOpen(IoTarget, &openParams); if (!NT_SUCCESS(status)) { KdPrint(("WdfIoTargetOpen failed 0x%x\n", status)); WdfObjectDelete(IoTarget); return; } targetDeviceCollectionLock = targetDeviceInfo->DeviceExtension->TargetDeviceCollectionLock; // // The query remove has failed and the target has been successfully reopened. Set Opened // back to TRUE to reflect the state change. // WdfWaitLockAcquire(targetDeviceCollectionLock, NULL); targetDeviceInfo->Opened = TRUE; WdfWaitLockRelease(targetDeviceCollectionLock); // // Restart the timer. // WdfTimerStart(targetDeviceInfo->TimerForPostingRequests, WDF_REL_TIMEOUT_IN_SEC(1)); }
NTSTATUS LateSetup(IN WDFDEVICE Device) { PUSB_FDO_CONTEXT fdoContext = DeviceGetFdoContext(Device); NTSTATUS status = STATUS_SUCCESS; // // set up the XEN connection. // if (!fdoContext->NxprepBoot) { status = XenConfigure(fdoContext); if (!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE, __FUNCTION__": Device %p xen configuration error %x", fdoContext->WdfDevice, status); return status; } // // get the USB device config data. // status = GetUsbConfigData(fdoContext); if (!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE, __FUNCTION__": %s GetUsbConfigData error %x\n", fdoContext->FrontEndPath, status); } else if (fdoContext->BlacklistDevice) { TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE, __FUNCTION__": %s Device is blacklisted. No PDO.\n", fdoContext->FrontEndPath); } else { fdoContext->PortConnected = TRUE; } } if (fdoContext->PortConnected || fdoContext->NxprepBoot) { // // create a child device. // status = CreateRootHubPdo(fdoContext); if (NT_SUCCESS(status) && !fdoContext->NxprepBoot) { WdfTimerStart(fdoContext->WatchdogTimer, WDF_REL_TIMEOUT_IN_SEC(2)); } } TraceEvents(NT_SUCCESS(status) ? TRACE_LEVEL_INFORMATION : TRACE_LEVEL_ERROR, TRACE_DEVICE, __FUNCTION__": %s Device %p status %x\n", fdoContext->FrontEndPath, fdoContext->WdfDevice, status); return status; }