Fix garbage messages on device de-enumeration#53
Fix garbage messages on device de-enumeration#53Cristian Manca (CristianManca) wants to merge 1 commit into
Conversation
6142c6b to
b896853
Compare
|
Hi Cristian Manca (@CristianManca), Is this issue introduced by interval timeout implementation only? Best, |
|
I removed the changes in src/windows/wdfserial/QCRD.c regarding interval timeout. Regards, |
b896853 to
9caf3ff
Compare
PR description needs to be updated to reflect final changes |
Chenxi Han (5656hcx)
left a comment
There was a problem hiding this comment.
Please update the pull request description to reflect the latest changes.
Also, making the buffer cleanup outside read thread is unsafe.
| ("<%ws> QCPNP_EvtDeviceD0Exit D3Final: clearing ring buffer\n", pDevContext->PortName) | ||
| ); | ||
| QCUTIL_RingBufferClear(&pDevContext->ReadRingBuffer); | ||
| pDevContext->AmountInInQueue = 0; |
There was a problem hiding this comment.
Updating the ReadRingBuffer outside read thread may experience race condition
There was a problem hiding this comment.
I modified the patch and added changes in QCRD.c
There was a problem hiding this comment.
In QCPNP_EvtDeviceD0Exit (src/windows/wdfserial/QCPNP.c), I removed the if block (TargetState == WdfPowerDeviceD3Final) that directly cleared the ReadRingBuffer outside the read thread (QCUTIL_RingBufferClear + update AmountInInQueue + related logs).
Now, the RX buffer clearing is handled only in the read thread's path (QCRD_ReadRequestHandlerThread / READ_THREAD_DEVICE_D0_EXIT_EVENT), eliminating the issue reported by the reviewer.
9caf3ff to
1533a42
Compare
|
I modified the patch and added changes in QCRD.c |
| PREQUEST_CONTEXT pReqContext = QCReqGetContext(Request); | ||
| NTSTATUS status = WdfRequestGetStatus(Request); | ||
| size_t availableLength = Params->Parameters.Usb.Completion->Parameters.PipeRead.Length; | ||
| size_t availableLength = (NT_SUCCESS(status) ? Params->IoStatus.Information : 0); |
There was a problem hiding this comment.
The Windows Sample Drivers uses Params->Parameters.Usb.Completion->Parameters.PipeRead.Length
Also we need to support partial transfer, can't just set this to 0.
There was a problem hiding this comment.
Thanks for the feedback — agreed.
I see two valid options here:
1. Conservative/defensive path (avoid overcount if values diverge):
size_t ioLen = Params->IoStatus.Information;
size_t usbLen = Params->Parameters.Usb.Completion->Parameters.PipeRead.Length;
size_t availableLength = (usbLen == 0) ? ioLen : min(ioLen, usbLen);
This keeps compatibility with the USB completion field used in Microsoft samples, while preventing overcount if IoStatus.Information and PipeRead.Length differ.
2. Simpler path without forcing 0 on non-success status (preserve partial-transfer behavior):
size_t availableLength = Params->IoStatus.Information
This keeps partial bytes when present and avoids dropping valid data on mixed-status completions.
QCRD.c — D0Exit race: Clear ring buffer and completion list inside the read thread's D0_EXIT_EVENT handler before signaling D0ExitReadyEvent, removing the race where stale URB completions wrote old AT responses into the ring buffer after D0Exit, causing garbage messages on re-enumeration. Reset bBufferOverflow/bDeviceGone/devErrCnt on D0Exit and FileClose for clean pipeline state. QCRD.c — surprise removal URB retry storm: Add bDeviceGone flag (set on STATUS_NO_SUCH_DEVICE completion) and guard free-list re-dispatch in REQUEST_ARRIVE_EVENT to skip when the device is gone. Prevents the ~40000/sec URB retry loop during surprise removal. QCRD.c — fixes: - EvtIoReadCompletionAsync: use IoStatus.Information for availableLength instead of PipeRead.Length (requested vs actual). Signed-off-by: Cristian Manca <Cristian.Manca@telit.com>
1533a42 to
39dd56e
Compare
This patch fixes garbage messages emitted by qcwdfser during device de-enumeration/re-enumeration by hardening the read pipeline teardown path and preventing stale data reuse.
Root cause
Garbage AT replies were caused by a combination of issues during remove/power transitions:
What this patch changes
Read pipeline hardening (QCRD.c)
Read completion correctness (QCRD.c)
Result
The de-enumeration path no longer re-delivers stale AT response data, and surprise-removal handling no longer drives repeated URB re-dispatch while the device is gone.