Hello, and thanks again to you all for the help with my filter driver. I have gotten a filter driver and a virtual HID device working well, and I thought I was nearly done with the kernel driver components since I have been working in userspace. Unfortunately, I seem to have a problem with losing interrupt data. My driver is a lower filter driver that uses WDF_USB_DEVICE_SELECT_CONFIG_PARAMS_INIT_URB, and I had been manually pending read requests on USB endpoints by using WdfUsbTargetPipeFormatRequestForUrb. This worked great, or so I thought – if I press a single button very rapidly on my device, I sometimes seem to lose data (i.e. losing “key up” packets, and only seeing adjacent “key down” packets). I have reason to believe that this is not a hardware issue with the device itself, and the packets are very small (5-20 bytes each).
Assuming it is not a hardware issue, the only reason I could see that happening is if I am not getting read requests pended to the hardware quickly enough. Since I was manually implementing a continuous reader, I thought I would go back and try the WDF continuous reader again, in the hopes that it would not miss any data. After I configure my pipes, I call WdfUsbTargetPipeConfigContinuousReader and WdfIoTargetStart, and they complete successfully. Unfortunately, the read complete handler (and for that matter, a readers failed handler) never get called for that pipe.
Is there some reason that the WDF continuous reader might not receive any data since I am doing the custom URB configuration to begin with? I am calling WdfUsbTargetPipeGetIoTarget on my WDFUSBPIPE. One issue -might- be that I am calling WdfIoTargetStart from somewhere other than D0Entry, but I was hoping that was not a requirement.
Alternatively, does anyone have any advice on how I can implement a better manual continuous reader? I am not sure how I could get userspace->kernel pending read requests down any faster than I am already doing, and I am pending two of them at a time (which never both seem to complete simultaneously, which would indicate that the data was overwhelming me). If there was a way to automatically re-pend a read request in my kernel driver I would do that, but I have read that I should not manually re-pend read requests in completion handlers since there is a risk of recursion due to some lower level driver and synchronous issues.
Thanks for reading!
xxxxx@gmail.com wrote:
Hello, and thanks again to you all for the help with my filter driver. I have gotten a filter driver and a virtual HID device working well, and I thought I was nearly done with the kernel driver components since I have been working in userspace. Unfortunately, I seem to have a problem with losing interrupt data. My driver is a lower filter driver that uses WDF_USB_DEVICE_SELECT_CONFIG_PARAMS_INIT_URB, and I had been manually pending read requests on USB endpoints by using WdfUsbTargetPipeFormatRequestForUrb. This worked great, or so I thought – if I press a single button very rapidly on my device, I sometimes seem to lose data (i.e. losing “key up” packets, and only seeing adjacent “key down” packets). I have reason to believe that this is not a hardware issue with the device itself, and the packets are very small (5-20 bytes each).
Assuming it is not a hardware issue, the only reason I could see that happening is if I am not getting read requests pended to the hardware quickly enough.
With such small packets, that’s surprising. How large are the buffers
in your device? You should only lose data if the buffers in the device
overflow.
Alternatively, does anyone have any advice on how I can implement a better manual continuous reader? I am not sure how I could get userspace->kernel pending read requests down any faster than I am already doing, and I am pending two of them at a time (which never both seem to complete simultaneously, which would indicate that the data was overwhelming me). If there was a way to automatically re-pend a read request in my kernel driver I would do that, but I have read that I should not manually re-pend read requests in completion handlers since there is a risk of recursion due to some lower level driver and synchronous issues.
Where did you read that? I’m not sure where that comes from.
To me, the phrase “pend a request” means that I am going to hold on to
the request within my driver until some future event. I’m guessing
that’s not what you mean. When you say “re-pend a read request”, do you
mean resubmitting the request back down to USBD? If so, as long as you
are checking for errors in your completion handler, there’s no real risk
of infinite recursion. I’ve done a number of USB streaming audio and
video drivers, and the only way to keep up is to copy the data in a
completion handler and resubmit the request immediately.
–
Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.
Thanks for the data. I am actually not sure of the buffer details of the device. It is unsupported by the manufacturer under Windows so I am working with what I have.
Where did you read that? I’m not sure where that comes from.
I almost feel like I tried resending a request and had some sort of feedback loop where Windows locked up, but I could be mistaken. I think the warning came from the WinDDK Toastmon example?
If I make sure to check for errors in the completion handler and can immediately do the WDF reuse and send request commands again, that would be an ideal situation. If the userland driver cannot keep up I will need to buffer multiple device packets into one packet to userland, but that is not a big deal.