PORTS Forum
Ports and Interfaces => USB => Topic started by: Renate on October 25, 2016, 06:32:27 am
-
I've seen on both Windows and Linux (and Android) that the system will ask a clearly labelled USB 2.0 (0x0200) device for BOS.
That's annoying.
Ok, so I STALL.
Both Windows and Linux (and Android) will ask three times!
Here's a capture off a Beagle USB 480:
http://imgur.com/a/FjC5t
Oh, I think I know why!
"Just the place for a Snark!" the Bellman cried,
As he landed his crew with care;
Supporting each man on the top of the tide
By a finger entwined in his hair.
"Just the place for a Snark! I have said it twice:
That alone should encourage the crew.
Just the place for a Snark! I have said it thrice:
What I tell you three times is true."
-
:)
-
What you receive is a request for the "Device_Qualifier" descriptor (descriptor type = 6) and not the BOS descriptor (descriptor type = 15).
Requesting the "Device_Qualifier" descriptor is perfectly valid for a USB 2.0 device. In fact it is ONLY valid for USB <= 2.0 (descriptor type = 6 is marked "reserved" in the USB 3.0 and USB 3.1 specs).
-
Oops, yeah, Device Qualifier, I got a bit mixed up.
In any case, the spec says:
If a full-speed only device (with a device descriptor version number equal to 0200H) receives a GetDescriptor() request for a device_qualifier, it must respond with a request error.
I thought that a stall was how you handled all unknown/invalid descriptor requests?
-
STALL is the correct response to a request error.
See 9.2.7 in the USB 2.0 spec.
-
Well, then I'm still confused.
The trace seems pretty explicit about what is happening.
You can see that the setup is acked and the in is stalled.
So why is it asking three times?
I think that I'll have to try some commercial FS only devices and see how they behave.
-
Good question, but if the host then moves on and all functions OK, I would be inclined to let it go.
-
Maybe I am misunderstand but initially you said that your device clearly indicates (via its "bcdUSB" field in the Standard device descriptor) that is Version 2.0.
I would not be surprised if Windows then assumes that it must be a high speed device, that is, NOT a full-speed only device.
Instead of stalling the get descriptor request for "device_qualifier" descriptor , why don't you just return the same info for the device_qualifier descriptor as for the standard device descrptor if you really can only support one Speed ?
If you REALLY have a full-speed only device you might want to set "bcdUSB" to 0x100 or 0x110 in which case Windows should NOT ask for for any "device_qualifier" descriptor as that one did not exist in USB spec 1.0 or 1.1.
-
Well, admitedly, this is more academic than useful.
As I said, I did conflate BOS requests and DQ request.
At some point I had Windows pestering me for BOS.
I went back and checked this over again.
It's only the Linux-based (for me Raspbian and Android) that do this triple stuff.
Looking at the code, I can see that Linux only asks for the DQ.
It ignores what is returned completely!
But, if it gets the correct size DQ then it warns you, "You know, this device could be operating at a higher speed if you plugged it in correctly".
This check is in an internal loop for configuration and it repeats the query 3 times.
Why this loop is not completing the first time is another question.
http://lxr.free-electrons.com/source/drivers/usb/core/hub.c#L4655
-
Ah, ok!
It's not this outer loop that is looping, it's a loop internal to usb_get_descriptor:
http://lxr.free-electrons.com/source/drivers/usb/core/message.c#L630
The problem is that Linux doesn't differentiate a stall from an actual error.
When it gets a stall it just repeats the request 3 times for "flakey devices".
So you'd have to return something and it would have to have 0x06 as the 2nd byte (bDescriptorType) or it's an error.
If you return any 10 bytes then check_highspeed would give a message of
"not running at top speed; connect to a high speed hub"
If you return less or more than 10 bytes it will accept this as a non-error but ignore it as a non-device qualifer.
Still, returning non-standard stuff to shut Linux up is stupid.
Of course, you could just set the bcdUSB to less than 0x0200, but there are some differences between USB 1.1 and 2.0.
(Um, number of allowed endpoints and ? ? ?)
So, the bottom line is: just live with it?
-
Just live with it would be my advice.
Seems like Linux is trying too hard to coax a response after a Stall but perhaps there was a good reason for it.
Thank you for posting what you learned.