Should I write a driver to disregard the exposed polling interval of a non-HID vendor device ?

Mr. Roberts, in https://www.winvistatips.com/threads/modify-usb-device-descriptor-by-filter-driver.820278/ you answered to

Since device descriptor (firmed in chip) can’t be changed, I want to modify
it in a lower filter driver before host controller driver gets my devcie
descriptor. Can this lower filter driver achieve this goal?
with:
No. The host controller driver is the bottom-most driver in the USB stack.
It performs transfers through DMA. It doesn’t send any requests down for
you to filter, because there IS no driver below it.

and said in https://community.osr.com/discussion/190849/usb-polling-rate that :

[…]there was a custom driver for Windows XP
that increased the “USB polling rate,” which magically made the games
more responsive. Maybe you even used it. That driver doesn’t work on
Vista and beyond, so you want to write one. Is that right?
What that driver did was replace the standard USB HID driver with one
that submitted smaller buffers. It didn’t poll any faster (it can’t do
so – that’s determined by the hardware), but by submitting smaller
buffers more often, it was able to get results back with lower latency.

But Cay Bremer claims, supported by SweetLow, that

It consists primarily of a lower-level filter driver to HidUsb that
listens for IOCTL_INTERNAL_USB_SUBMIT_URB requests, and when an URB of
URB_FUNCTION_SELECT_CONFIGURATION arrives, sets the member bInterval of
the first endpoint descriptor of the first interface descriptor of the
configuration descriptor to a registry-supplied value. […]
Since Windows does not allow a polling interval below 8 ms for low-speed
USB devices, the driver furthermore attempts to remove this restriction by
patching the responsible driver usbport.sys in memory.

If I cross this information with Pavel_A’s

The endpoint descriptors are read by the host USB stack, and then the HCD is programmed by the host stack (software).
The host controller does not interpret the descriptors by itself.
So yes, if you can intercept the EP descriptor and change the interval, it can help verify your theory that the device can provide more data if polled faster.

Are you referring to HidUsbF when mentionning the driver that slices buffers ? If not, am I understand from your responses that:

  • The HCD schedules transfer directly, with one change per interval, interval that’s defined by the endpoint descriptor initially received by the HCD.

" the descriptor is being read and used by the host controller driver, which is in direct communication with the hardware. There is no slot into which you can insert a filter."

  • There is no way to insert a filter driver “before” the HCD, as in, that alters communication between the device and the HCD.
  • However, the HCD is initially configured by the software, in particular, by the driver. By writing a lower-level filter driver that intervenes before “the” driver (HidUsb in the legacy HidUsbF case, but not only anymore), you can mess with the Endpoint descriptor and get the HCD to receive altered data at initialization - which is the only shot at modifying its behaviour. Which is what HidUsbF does.

But then, why do we need a filter driver located before HidUsb instead of an alternative version of HidUsb directly ? Does it have any more rights ? Task difficulty apart, is there any reason a HidUsb clone that does the job of modifying the data it’s going to configure the HCD with itself wouldn’t work ?

As for the buffer slicing driver, I don’t get what “What that driver did was replace the standard USB HID driver with one that submitted smaller buffers.” means. What does submitting too large a buffer does ? Does you internally (at driver level) wait for enough reads to fill the buffer ? So for example, a 1000Hz-interval mice would read 8 times and then play it out by applying the result of the 8 reads in order over the next 8ms, and that driver would force the (naively expected ?) behaviour of the mice polling once a millisecond and the result being applied a.s.a.p ?

@SweetLow, if you indeed use a lower level filter driver and not buffer slicing tricks, that means the mouses you overclock above 1000Hz aren’t only mouses whose endpoint descriptor intervals were strictly below 8 to begin with, right ? (8 being 1000Hz for HighSpeed)

“HCD” means “host controller driver”, not “host controller”. I’m very careful to distinguish the two.
Mr. Roberts, I stand corrected, you’re right as typically you are.
What I tried to say, the OP has number of quick [and dirty] options to resolve his doubt - that the device can send data at higher rate.
These require either skills, or other way that we’re not allowed to discuss here :wink:
The host controller or OS should not be a limiting factor for this task. It can be replaced.

– pa

if you indeed use a lower level filter driver and not buffer slicing tricks, that means the mouses you overclock above 1000Hz aren’t only mouses whose endpoint descriptor intervals were strictly below 8 to begin with, right ? (8 being 1000Hz for HighSpeed)

[Unlike ordinary] overclocking over 1000Hz is some kind of hack. I use filter just to ask the lowest possible polling rates but instead of setting the lowest rates i change HCD code to set the highest rates when asked lowest rates. And no, i don’t fool HCD to “think” the device is High or Super speed, i just poll Full speed device with higher than standard rate.

I don’t understand most of this thread… and I’ve written a USB host controller driver, hub driver, and drivers for several USB client devices. Perhaps I am missing something very clever.

I’m not sure if people I this thread (I’m including you Mr. SweetLow) are talking in vague nonsensical terms to be clever, or if their command of English is just insufficient to allow them to describe what their meaning recisely and clearly.

But, regardless: there’s some pretty stupid shit in this thread.

Fact: The Host Controller Driver is responsible for building the schedule by which it polls devices.

Fact: It builds this schedule based on the content of device’s endpoint descriptors.

Fact: You can’t change that Host Controller Drivers schedule without either (a) changing the endpoint descriptors presented by the device to the host controller driver, or (b) changing the host controller driver itself to build the schedule differently.

Get a USB hardware analyzer and watch the device initializatuin sequence on the bus. It’s not rocket science.

That’s the way I understand USB works. If somebody would like to educate me on some other way(s) to change the actual polling rate on the bus, I’ll be most happy to hear it and I’ll thank them for their efforts.

Lacking that, let us not randomly spew nonsense and confuse the OP further, OK?

Peter

What does submitting too large a buffer does ?
From a software perspective, interrupt and bulk pipes are absolutely identical. You can see that they even use the same URB request code. In both cases, single “transfer” can span multiple packets.

So, let’s say my endpoint has a max packet size of 8 bytes (as mice often do), and I submit an URB to read 64 bytes. The “transfer” is not complete until either the buffer is full or the device returns a short packet. As long as the device keeps returning 8-byte packets, the request will remain pending until the devices sends 8 packets and the buffer fills.

The “optimization” discussed in those old messages was to intercept that 64-byte read and submit it as 8 separate 8-byte reads. The device doesn’t send any faster, but the driver would see the results faster.

Mr. @SweetLow is arguing that the host controller driver configures itself based on the configuration descriptor passed down in the URB_SELECT_CONFIGURATION request, and not on the configuration descriptor received from the hardware. I have not heard this claim before, and I am skeptical. If true, that does represent a way to work around odd device descriptor issues.

(a) changing the endpoint descriptors presented by the device to the host controller driver, or (b) changing the host controller driver itself to build the schedule differently.
That is exact what my driver do and intended for. Both (a) and (b) parts. Once again - Cay Bremer description is correct, my driver can do what Arte asked in the first post - make 2 or 1ms polling on device with 8ms bInterval in Interrupt Endpoint Descriptor. May be he asked something else - but i understand his question exactly this way.

That’s the way I understand USB works.
You understand right. But i don’t understand why you think that some driver can not do (a) and (b).

Lacking that, let us not randomly spew nonsense and confuse the OP further, OK?
Looks like OP lost interest in topic. But we can discuss his question here or in any other place.

@Tim_Roberts

If true, that does represent a way to work around odd device descriptor issues.
It’s very easy to test (take usbview.exe - and compare descriptor and pipe bInterval values). And was checked by hardware even:
https://www.overclock.net/forum/375-mice/1589644-usb-mouse-hard-overclocking-2000-hz-3.html#post24849487

some driver can not do (a) and (b)

We are clearly not understanding each other, and that’s why I’m confused. I assume there’s a language problem involved, so I apologize for only being being able to speak English. I mean that.

In order to do (b) you need the source code for the host controller driver. I suspect you do not have source code for the Windows USB Host Controller Driver. This is part of my confusion.

Peter

In order to do (b) you need the source code for the host controller driver.

What he said earlier in the thread is that they hot-patched usbport.sys on the fly. Does that make your skin crawl?

What he said earlier in the thread is that they hot-patched usbport.sys on the fly

You know, I must be getting stupid in my old age… but I can’t find that anywhere in this thread. I actually looked back, again, right now. I don’t see it. At least not in any way that I can understand it.

AH! OK… I see it’s in the other thread and sort-of quoted here.

Does that make your skin crawl?

It makes me positively nauseous.

I would re-do the descriptors on the device before I did that. Bring on the reflow station!

P

I certainly haven’t lost interest and won’t any time soon, I just like testing and researching based on the answers given before reacting, and I get little time to do that during work days.

So, addressing one point in particular, the too large sized buffers : I attempted to send to my device (the WinUsb one) buffer sizes twice too large than the actual transfer. Let’s say that’s the MaximumPacketSize is 50, the actual buffer size sent from the device is 50, and I’m sending a buffer of size 100 (or more generally, 50*n)

Must I conclude from the fact that pipe reads take twice as long, so, 16ms (or more generally, n times as long; 8*n ms) that internally, the device only feeds his USB device controller data every 8ms, in which case my dreams are gone (and the level of bad design in this device is astonishing), or did WinUsb broke down my pipe read attempt because I was violating the maximum packet size ?

I’m afraid the former is more likely, but eh, I still believe.

I just like testing and researching based on the answers given before reacting

Bravo. +5 points for Mr. Arte. Pretty soon, you’re well on your way to graduating to Senior Forum Member!

Must I conclude from the fact that pipe reads take twice as long…

You must conclude that the polling interval you expected was, in fact, the polling interval.

You know, you could save yourself a lot of time and guessing if you had a hardware USB Bus Analyzer. I’ve used several, including this one, and while it’s not my favorite, it’s very good… and extremely reasonable in price (just US$400). In the interest of full disclosure, I have no association with or interest in the manufacturer of this device.

Peter

The internal workings of the device I expected, since it’s an adapter and polls the controllers every 1.4ms ; was that every 1.4ms, it would convert and then push the obtained data to the device’s USB controller, and that data would be available to pull if the OS sent a request. Why else would it poll controllers every 1,4ms ? And then, for some reason, it tells the OS… that it only wants to be asked its state every 8ms.

This is why I’d be surprised to conclude that the USB controller only receives data every 8ms, internally. Can it be so badly made that it’s another buffer than the USB controller that’s filled after the data translation (assuming these 2 parts run asynchronously - which sounds logical to me as the controller polling occurs periodically very precisely, regardless of USB polls - it’s not that farfetched, you wouldn’t want to modify the buffer the USB controller is reading), but that buffer is only copied to the buffer the USB controller reads every 8ms ?

Also, I haven’t looked into physical USB analyzers. I’ll look into what it offers more than software ones (I’ve been using Microsoft Message Analyzer). To be honest the price scares me right away - that’s a big sum for me, I’m only beginning my career.

PS : I was reacting to SweetLow’s “Looks like OP lost interest in topic.”
PS2 : Misjudged the usage of usernames on these boards, had I known I would have used my real name. Not editable.

J. Bernard

Must I conclude from the fact that pipe reads take twice as long, so, 16ms (or more generally, n times as long; 8*n ms) that internally, the device only feeds his USB device controller data every 8ms

Exactly because of this, you don’t want to move large amounts of data over interrupt endpoints. Exactly because of this, they are named “interrupt”.
The purpose of interrupt endpoint is to pass a short message, like “I am ready to send /receive more data”.
Massive data pumping goes over bulk endpoints. As Mr. Roberts noted, interrupt and bulk pipes are absolutely identical -
except that bulk pipes do not have polling interval. The host controller moves the bulk data whenever the bus is free after the scheduled traffic.
HID devices use interrupt pipes for their main data, it’s understandable why.
Reports of normal HID devices should fit in the max. packet size ( < 8 bytes low speed, < 64 bytes full speed, such as your STM32).
Every single typical report is a short packet, and it ends the transfer.

So you’re asking, is this device badly designed? Maybe yes, maybe not.
All we know from you is that it is not HID, and the direction is OUT.
May be it indeed cannot consume data at high speed. You don’t know until you do the experiment (and use the USB analyzer!).
Are you the only customer of this vendor? Can you reach them for help or explanation?

– pa

The internal workings of the device I expected, since it’s an adapter and polls the controllers every 1.4ms ; was that every 1.4ms, it would convert and then push the obtained data to the device’s USB controller, and that data would be available to pull if the OS sent a request. Why else would it poll controllers every 1,4ms ? And then, for some reason, it tells the OS… that it only wants to be asked its state every 8ms.

This is why I’d be surprised to conclude that the USB controller only receives data every 8ms, internally. Can it be so badly made that it’s another buffer than the USB controller that’s filled after the data translation (assuming these 2 parts run asynchronously - which sounds logical to me as the controller polling occurs periodically very precisely, regardless of USB polls - it’s not that farfetched, you wouldn’t want to modify the buffer the USB controller is reading), but that buffer is only copied to the buffer the USB controller reads every 8ms ?

Also, I haven’t looked into physical USB analyzers. I’ll look into what it offers more than software ones (I’ve been using Microsoft Message Analyzer). To be honest the price scares me right away - that’s a big sum for me, I’m only beginning my career.

PS : I was reacting to SweetLow’s “Looks like OP lost interest in topic.”
PS2 : Misjudged the usage of usernames on these boards, had I known, I would have used my real name. Not editable.
J. Bernard

@Peter_Viscarola_(OSR)

It makes me positively nauseous.
Don’t forget - primary target of hidusbf is OVERclocking. And you are right, this is not open source, so I have to do it.

@Arte

I was reacting to SweetLow’s “Looks like OP lost interest in topic.”
In this case, i just ask for confirmation if i correctly understood your initial request:
“make 2 or 1ms polling on device with 8ms bInterval in Interrupt Endpoint Descriptor”

Mr. Bernard, formerly Mr, Arte… your username has been changed at your request. Thank you for using a real name, I appreciate it.

On Apr 11, 2019, at 2:38 PM, Arte wrote:
>
> This is why I’d be surprised to conclude that the USB controller only receives data every 8ms, internally. Can it be so badly made that it’s another buffer than the USB controller that’s filled after the data translation … but that buffer is only copied to the buffer the USB controller reads every 8ms ?

I think you may still be confused about how USB works.

Let’s say you have an endpoint descriptor with a max packet size of 50 bytes and an interval of 8ms. Let’s say you submit a read of 400 bytes. So, the host controller driver is layout the schedule for time 0ms. Since you have a request waiting, it will schedule time for your device. When the schedule is executed, the host controller will send one IN token. That tells your device it is allowed to transfer. It will send a 50-byte packet in return. Because that matches your device’s max packet size, the overall transfer is still not complete, so it remains pending.

Nothing else will happen for the next 7ms. When the host controller driver is laying out the schedule for the frame at 8ms, it will once again put your device on the schedule, and when executed, once again the controller will send exactly one IN token, and in response your device will send another 50-byte packet.

A USB device never gets to decide when to send. It has to wait until it get an invitation (i.e., an IN token), and an interrupt endpoint only gets an IN token ONCE during each interval.

Tim Roberts, timr@probo.com
Providenza & Boekelheide, Inc.

Note: The email was trying to reply to an invalid Comment (293418).

> The purpose of interrupt endpoint is to pass a short message, like "I am

ready to send /receive more data".

I see it a bit differently. It simulates real interrupt i.e. delivery of an asynchronous event (which definition depends on device or protocol designer). The main purpose is to save bandwidth and that’s what is polling interval for. Polling bulk endpoints is continuous, interrupt is polled much less frequently.

Are you the only customer of this vendor? Can you reach them for help or
explanation?

Actually, it should be the first. Ask the vendor why the device is designed this way and if it is a mistake, fix it on the device side. There can be a good reason for it. Or maybe not and the designer just thought 8 ms ought to be enough for anybody :wink:

Michal

Note: The email was trying to reply to an invalid Comment (293419).

but that buffer is only copied to the buffer the USB controller reads every 8ms

Well, it sort of makes sense. The device polls at some “very short” time period… for whatever reason, you know… Nyquist frequency or something… and accumulates some samples and sends those samples at a lower frequency to the host. I don’t think that’s necessarily a bad plan. It’s one of the advantages to having hardware on the “front end”…

Peter