Hi folks,
Curious problem I am having during the enumeration of a device plugged into a windows 7 USB 3.0 port.
I am using an old (2012) Freescale USB stack for an HID device which has been performing fine in a product for over 6 months.
It now crashes if the device is plugged into a Windows 7 USB 3.0 port. Everything is fine on a USB 2 port.
It is crashing during the get string descriptor as windows sending a language ID of 0xFFFF. The stack does not support this language ID and leaves the index beyond the string array (I cannot see how this stack could ever work under these conditions!)
case USB_STRING_DESCRIPTOR:
{
if(index == 0)
{
/* return the string and size of all languages */
*descriptor = (uint_8_ptr)g_languages.
languages_supported_string;
*size = g_languages.languages_supported_size;
}
else
{
uint_8 lang_id = 0;
uint_8 lang_index = USB_MAX_LANGUAGES_SUPPORTED;
for(;lang_id < USB_MAX_LANGUAGES_SUPPORTED; lang_id++)
{
/* check whether we have a string for this language
*/
if(index ==
g_languages.usb_language[lang_id].language_id)
{
/* check for max descriptors */
if(str_num < USB_MAX_STRING_DESCRIPTORS)
{
/* setup index for the string to be
returned */
lang_index = str_num;
}
break;
}
}
/* set return val for descriptor and size */
*descriptor =
(uint_8_ptr)g_languages.usb_language[lang_id].
lang_desc[lang_index];
*size = g_languages.usb_language[lang_id].
lang_desc_size[lang_index];
}
}
break;
Solved! Go to Solution.
Hi Julian
I see that the string index is const (probably in Flash) but I don't think that the FSL USB stack can work with values directly there but only from RAM (without additional configuration).
When flash is used the USB controller can't access it and sends either 0x00 or 0xff since the read fails.
You could try removing the const definition to ensure that it is not sending back an incorrect index which the host is then using.
Possibly USB2.0 is defaulting to 0x0409 and not requesting index 0 (or ignoring unexpected values) and so the failure is only noticed with USB3.0 (?)
Regards
Mark
Kinetis: µTasker Kinetis support
I think the questions are - Has anyone seen this before? Why is Windows requesting language ID 0xFFFF on USB 3.0 ports?
Hi Julian
Do you see the requested language value with a USB analyser or from debug output in the code (which could also be incorrect)?
How is the string index 0 responded to since this may influence the index that the USB host requests using - if it was responded to with 0xffff it may be normal that later string requests use this (?). Otherwise I have only ever "seen" the US-English 0x0409 being used on USB2.0 and USB3.0 ports with Windows.
Regards
Mark
Kinetis: µTasker Kinetis support
Index 0 seems ok it is the standard:
uint_8 const USB_STR_0[USB_STR_0_SIZE + USB_STR_DESC_SIZE] =
{sizeof(USB_STR_0),
0x09, 0x04 // equivalent to 0x0409 = English - United States
};
Now I have fixed the crash (rejected the string request) I have logged the calls to USB_Desc_Get_Descriptor:
type index str_num
------- ------- --------
1 (device) 0 0
1 (device) 0 0
2 (config) 0 0
3 (string) 0 0
3 (string) 0xFFFF 2
6 (devQual) 0 0
1 (device) 0 0
2 (config) 0 0
2 (config) 0 0
Hi Julian
I see that the string index is const (probably in Flash) but I don't think that the FSL USB stack can work with values directly there but only from RAM (without additional configuration).
When flash is used the USB controller can't access it and sends either 0x00 or 0xff since the read fails.
You could try removing the const definition to ensure that it is not sending back an incorrect index which the host is then using.
Possibly USB2.0 is defaulting to 0x0409 and not requesting index 0 (or ignoring unexpected values) and so the failure is only noticed with USB3.0 (?)
Regards
Mark
Kinetis: µTasker Kinetis support
Brilliant! that's fixed it. Thanks and take a pay rise ;-)
Mind you, I still thing there is a bug in the search which should have prevented the crash. If you look at the routine you will see that lang_id will be incremented beyond the array size if the language is not found:
uint_8 lang_id=0;
uint_8 lang_index=USB_MAX_LANGUAGES_SUPPORTED;
for(;lang_id< USB_MAX_LANGUAGES_SUPPORTED;lang_id++)
/* check whether we have a string for this language */
if(index == g_languages.usb_language[lang_id].language_id)
{ /* check for max descriptors */
if(str_num < USB_MAX_STRING_DESCRIPTORS)
{ /* setup index for the string to be returned */
break;
/* set return val for descriptor and size */
*descriptor = (uint_8_ptr)g_languages.usb_language[lang_id].lang_desc[lang_index];
*size = g_languages.usb_language[lang_id].lang_desc_size[lang_index];
Julian
Yes, the code is not safe as it allows random behavior if something unforeseen takes place, whereby this was also pre-programmed to fail due to other code it relies on not being able to handle Flash accesses (such parts are certainly untested - at least on the Kinetis).
Generally the code is useful as a starting point but is unlikely to pass a software review, not least because it is extremely difficult to maintain due to its structure and hardware dependencies.
Regards
Mark
Kinetis: µTasker Kinetis support