device qualifier descriptor request on rpi linux for USB 2.0 FS only device - Page 1
Forum section: electronics / general

author: metebalci
author_rank: Frequent Contributor
timestamp: November 20, 2023, 01:19:20 pm
content: I am working on a USB 2.0 FS device implementation on STM32H5. Setup/Enumeration works but Linux (Rpi 3B+ raspian) requests device qualifier descriptor and even if I send request error (stall) it keeps repeating the request and the enumeration is not completed. Windows works. If I send a device qualifier descriptor with other speed configurations=0, then Linux also works. USB 2.0 spec says FS only device should return a request error for such a request but I dont get why Linux insists requesting this. Is this a known issue, problem with RPi or Linux or am I missing something ?

author: zilp
author_rank: Frequent Contributor
timestamp: November 20, 2023, 08:55:38 pm
content: Are you responding with STALL in the SETUP transaction or in the following IN or OUT transaction(s)?

author: metebalci
author_rank: Frequent Contributor
timestamp: November 20, 2023, 09:15:07 pm
content: Quote from: zilp on November 20, 2023, 08:55:38 pmIn the following IN. As far as I understand that is how request error should work ? I am not very sure why first IN is responded with NAK, might be because I am logging things to console but I think I tried without and the result was the same.I attached captures. One with returning device qualifier where enumeration succeeds. The other two are with stall, also showing it is in IN trx.

author: zilp
author_rank: Frequent Contributor
timestamp: November 20, 2023, 09:58:28 pm
content: Quote from: metebalci on November 20, 2023, 09:15:07 pmYeah, that should be OK.My guess would be that the device descriptor specifies something that's incompatible with FS and Linux tries to work around that by forcing HS, maybe?

author: abyrvalg
author_rank: Frequent Contributor
timestamp: November 21, 2023, 01:27:35 am
content: What do you have in device descriptor bcdUSB? 2.0? Try changing it to 1.1

author: metebalci
author_rank: Frequent Contributor
timestamp: November 21, 2023, 09:55:47 am
content: Quote from: abyrvalg on November 21, 2023, 01:27:35 amYes I know it works with 1.1 as it does not request the device qualifier descriptor. I wonder why this happens with 2.0. I will try to find a USB 2.0 FS device if I can and compare.

author: metebalci
author_rank: Frequent Contributor
timestamp: November 21, 2023, 10:00:04 am
content: Quote from: zilp on November 20, 2023, 09:58:28 pmThat would make sense but I think there is nothing related to speed in the descriptors. I will check other devices if I can find one and maybe another non-rpi linux.

author: zilp
author_rank: Frequent Contributor
timestamp: November 21, 2023, 10:24:19 am
content: Quote from: metebalci on November 21, 2023, 10:00:04 amYeah, but stuff like packet sizes also depends on speed.Quote from: metebalci on November 21, 2023, 10:00:04 amI wouldn't really expect them to be patching the USB stack for raspian.

author: metebalci
author_rank: Frequent Contributor
timestamp: November 21, 2023, 10:42:04 am
content: Quote from: zilp on November 21, 2023, 10:24:19 amI am using 64 bytes so it should work with FS, and actually also interestingly the device I mention below uses 16 and although an HS device should use only 64, Linux still requests device qualifier from that one. It seems the driver is not checking that.Meanwhile I found the issue. I checked another device, luckily I found a USB 2.0 FS device (a midi interface) quickly and it seems Linux requests the device qualifier descriptor 3 times (even after STALL is returned to the first and to the second). So after replying STALL to each then it gives up and continues to other things. I was only responding to the first one (not on purpose, it was a mistake anyway). So, now always replying STALL and it continues requesting other things.

author: zilp
author_rank: Frequent Contributor
timestamp: November 21, 2023, 11:11:46 am
content: Quote from: metebalci on November 21, 2023, 10:42:04 amBut that would be the correct behaviour?! I mean, the "normal" device descriptor is not relevant for HS operation anyhow, so it would be perfectly fine to specify 16 bytes there, while still supporting HS operation!? But if the "FS decriptor" specified a packet size not allowed with FS, then one possible workaround for that would be to probe for HS and use that if it isn't broken, and give up if that's not supported ...Quote from: metebalci on November 21, 2023, 10:42:04 amWell, it was a workaround for something else then that confused you ;-)

author: metebalci
author_rank: Frequent Contributor
timestamp: November 21, 2023, 01:22:22 pm
content: Quote from: zilp on November 21, 2023, 11:11:46 amI should first say I did not read all the spec word by word, not yet at least. I also did not look at HS specific things in detail yet. I saw the packet sizes are given in control transfer packet size constraints, not exactly sure why there is such a constraint (LS should be 8 bytes, FS any of 8,16,32,64 and HS 64 bytes), but I think they are not meant to be used as LS, FS, HS distinction. LS, FS is already distinguished by the pullups and I think HS support is first checked by this device qualifier descriptor. I dont know if HS signalling (chirps?) is tried before this or it is not tried at all if there is no valid device qualifier (and then there is a other speed configuration descriptor).I dont know what happens when the device is really HS and does everything properly, but reports MaxPacketLen0 as 16 bytes. Partly the issue with the enumeration is I think the spec does not normatively say how it should be done (and fail). Then the host controllers might behave differently, maybe to support some historically bad behaving devices also, not sure.I just saw in Linux kernel source code (drivers/usb/core/message.c) this comment:Code:/* The USB spec says configuration 0 means unconfigured.* But if a device includes a configuration numbered 0,* we will accept it as a correctly configured state.* Use -1 if you really want to unconfigure the device.*/Sounds very strange to me.

author: metebalci
author_rank: Frequent Contributor
timestamp: November 21, 2023, 01:55:16 pm
content: Related to what just said, for example, I accidentally set the max packet len to 256 for FS device also in bulk transfer endpoint (I thought it could be higher than 64) but the spec says it can be maximum 64. So when connected to Linux, the enumeration actually completes, but Linux logs:Code:config 1 interface 0 altsetting 0 endpoint 0x1 has invalid maxpacket 256, setting to 64so it implicitly sets the packet len to 64 rather than failing the enumeration.

author: zilp
author_rank: Frequent Contributor
timestamp: November 21, 2023, 02:01:14 pm
content: Quote from: metebalci on November 21, 2023, 01:22:22 pmIt's not about whether they *should* be used for distinction, it's just about whether they *are* used to handle broken devices. Though I was confusing non-EP0 packet size limits with EP0 size limits, because on non-EP0, HS allows larger packets than FS (by one byte ...).Quote from: metebalci on November 21, 2023, 01:22:22 pmThe host controller really doesn't have anything to do with that, that's all done by the USB stack of the OS. But, yeah, whenever you see USB host software do something weird (like trying to read the qualifier descriptor three times in a row), you can bet there is some broken device out there that that weird behaviour is a workaround for.Quote from: metebalci on November 21, 2023, 01:22:22 pmWell, apparently, there are devices out there that have a configuration with number 0 in their descriptors, which isn't allowed by the standard (because 0 should indicate an unconfigured device). This is how Linux makes those broken devices work.

author: metebalci
author_rank: Frequent Contributor
timestamp: November 23, 2023, 10:43:14 am
content: Quote from: zilp on November 21, 2023, 02:01:14 pmIt seems this try 3 times thing is a common thing, I see it in various places, might be written in the spec as well.Quote from: zilp on November 21, 2023, 02:01:14 pmSome workarounds I understand but hard to understand how some mistakes are made, how they managed to make a device with configuration value 0 is an interesting one.

author: metebalci
author_rank: Frequent Contributor
timestamp: November 23, 2023, 03:58:06 pm
content: Quote from: metebalci on November 21, 2023, 01:22:22 pmI just read the parts relevant to HS handshake in the spec. So the HS handshake actually happens during reset (after the normal FS reset), so definitely before requesting the device qualifier descriptor. So the question is why the host even requests this descriptor if HS handshake cannot be done, it is obvious the device is not HS and it will not return a device qualifier descriptor.

author: abyrvalg
author_rank: Frequent Contributor
timestamp: November 23, 2023, 07:07:17 pm
content: There are cases when HS device can’t respond to HS chirp (extremely bad cable, FS hub etc), but the OS finds it out and says something like “This device can work faster when plugged into HS port” (seen that on Windows at least).And the recipe to make a device with config value 0 is simple: instead of reading the official spec and torturing the device with official USB Command Verifier tool, people ask on SO and use some obscure libs.

author: zilp
author_rank: Frequent Contributor
timestamp: November 23, 2023, 08:09:36 pm
content: Quote from: metebalci on November 23, 2023, 10:43:14 amThat wouldn't really make a whole lot of sense as the device isn't even allowed to give different responses to repeat requests. And in the case of transmission errors, the device shouldn't respond with a STALL.My guess is that the repeat requests are actually subtly different to work around some device bugs.Quote from: metebalci on November 23, 2023, 10:43:14 amPresumably by testing it with some system that didn't care and not reading the specs? I mean, that's how broken devices get created, isn't it?Quote from: metebalci on November 23, 2023, 03:58:06 pmYeah, indeed, I was confused about the details--it's been a while ...But the purpose is to detect when a device might be limited in functionality because of slow link speed, either because of a bad connection, as abyrvalg mentioned, or because it's connected to a non-HS port.

author: metebalci
author_rank: Frequent Contributor
timestamp: November 24, 2023, 06:36:58 am
content: Quote from: abyrvalg on November 23, 2023, 07:07:17 pmGood point, I see.

author: metebalci
author_rank: Frequent Contributor
timestamp: November 24, 2023, 06:38:31 am
content: Quote from: zilp on November 23, 2023, 08:09:36 pmYes I understand, that makes sense.