Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions docs/windows-driver.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,13 @@ and explicitly wait for pending completion instead of mixing synchronous calls
with an asynchronous handle. Each caller thread reuses its event to avoid
creating a kernel handle for every input report.

The pending output read also participates in the UMDF power-managed queue
lifecycle. When the system sleeps, the driver acknowledges the queue stop while
retaining the cancelable request, then resumes that same request after the
control device returns to D0. This allows sleep to complete without waiting for
controller feedback and keeps the runtime's control handle and virtual devices
valid across resume.

The driver opens a separate VHF source target for each virtual HID device and
parents that target to the control-file handle that created it. If the creating
process exits or crashes, Windows cleans up devices that were not explicitly
Expand Down
26 changes: 26 additions & 0 deletions src/platform/windows/driver/libvirtualhid_umdf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ EVT_WDF_DEVICE_PREPARE_HARDWARE LvhEvtDevicePrepareHardware;
EVT_WDF_DEVICE_RELEASE_HARDWARE LvhEvtDeviceReleaseHardware;
EVT_WDF_FILE_CLEANUP LvhEvtFileCleanup;
EVT_WDF_IO_QUEUE_IO_DEVICE_CONTROL LvhEvtIoDeviceControl;
EVT_WDF_IO_QUEUE_IO_RESUME LvhEvtIoResume;
EVT_WDF_IO_QUEUE_IO_STOP LvhEvtIoStop;
EVT_WDF_OBJECT_CONTEXT_CLEANUP LvhEvtDeviceCleanup;
EVT_WDF_REQUEST_CANCEL LvhEvtOutputReadCanceled;
EVT_VHF_ASYNC_OPERATION LvhEvtVhfGetFeature;
Expand Down Expand Up @@ -1270,6 +1272,8 @@ NTSTATUS LvhEvtDeviceAdd(WDFDRIVER driver, PWDFDEVICE_INIT device_init) {
WDF_IO_QUEUE_CONFIG queue_config;
WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&queue_config, WdfIoQueueDispatchParallel);
queue_config.EvtIoDeviceControl = LvhEvtIoDeviceControl;
queue_config.EvtIoStop = LvhEvtIoStop;
queue_config.EvtIoResume = LvhEvtIoResume;

status = WdfIoQueueCreate(device, &queue_config, WDF_NO_OBJECT_ATTRIBUTES, WDF_NO_HANDLE);
trace_status("EvtDeviceAdd WdfIoQueueCreate", status);
Expand Down Expand Up @@ -1321,6 +1325,28 @@ void LvhEvtOutputReadCanceled(WDFREQUEST request) {
}
}

void LvhEvtIoStop(WDFQUEUE queue, WDFREQUEST request, ULONG action_flags) {
UNREFERENCED_PARAMETER(queue);
UNREFERENCED_PARAMETER(action_flags);

trace_status("EvtIoStop suspend output request");

// Output reads intentionally remain pending until VHF produces feedback.
// Keep the cancelable request under driver ownership while the power-managed
// queue stops so it cannot block the system power transition. WDF calls the
// matching resume callback after the device returns to D0.
WdfRequestStopAcknowledge(request, FALSE);
}

void LvhEvtIoResume(WDFQUEUE queue, WDFREQUEST request) {
UNREFERENCED_PARAMETER(queue);
UNREFERENCED_PARAMETER(request);

// The pending output read does not access hardware while it waits, so no
// restart operation is necessary after WDF restores the queue to D0.
trace_status("EvtIoResume output request");
}

void LvhEvtVhfReadyForNextReadReport(VhfContext vhf_client_context) {
auto *record = static_cast<DeviceRecord *>(vhf_client_context);
if (record == nullptr) {
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/test_windows_consumers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -763,7 +763,7 @@ TEST_F(WindowsConsumerTest, SdlExposesSubmittedBatteryStateForNonXboxProfiles) {
SDL_UpdateGamepads();
SDL_PumpEvents();
power_state = SDL_GetGamepadPowerInfo(gamepad.get(), &percentage);
if (power_state != SDL_POWERSTATE_UNKNOWN && percentage >= 0) {
if (power_state == SDL_POWERSTATE_ON_BATTERY && percentage == expected_percentage) {
break;
}
std::this_thread::sleep_for(20ms);
Expand Down
Loading