Rockbox

Tasklist

FS#12910 - Sansa zip clip fails to enumerate over USB under Windows.

Attached to Project: Rockbox
Opened by B Quach (braincell38) - Tuesday, 05 November 2013, 18:28 GMT
Task Type Bugs
Category Drivers
Status Unconfirmed
Assigned To No-one
Operating System All players
Severity Low
Priority Normal
Reported Version Daily build (which?)
Due in Version Undecided
Due Date Undecided
Percent Complete 0%
Votes 0
Private No

Details

Build 3a97e12.

When attaching to USB, the device STALLS the string descriptor request. Mass storage device is yellow banged and says "cannot start" and never appears under disks. This occurs in windows but not under linux. Device is hung after the failure.
   sansa.JPG (254.1 KiB)
This task depends upon

Comment by B Quach (braincell38) - Tuesday, 05 November 2013, 19:12 GMT
Windows appear to be asking for String index 0xEE (MSFT OS string descriptor) which causes device to STALL the EP. You aren't supposed to STALL EP0 IN.

It believe it should should be "usb_drv_stall(EP_CONTROL, true, false);" below in the else statement in usb_core.c:


case USB_DT_STRING:
logf("STRING %d", index);
if((unsigned)index < (sizeof(usb_strings) /
sizeof(struct usb_string_descriptor*))) {
size = usb_strings[index]->bLength;
ptr = usb_strings[index];
}
else {
logf("bad string id %d", index);
usb_drv_stall(EP_CONTROL, true, true);
}
break;
Comment by Frank Gevaerts (fg) - Tuesday, 05 November 2013, 20:17 GMT
Well, Microsoft shouldn't have said we can STALL then.

http://msdn.microsoft.com/en-us/library/hh881271.aspx

edit: a clearer thing: http://msdn.microsoft.com/en-us/library/windows/hardware/ff537430%28v=vs.85%29.aspx#why_does_windows_issue_a_string_descriptor_request_to_index_0xee_ is clearer. "If a device does not contain a valid string descriptor at index 0xEE, it must respond with a stall packet (in other words, a packet that contains a packet identifier of type STALL),"
Comment by B Quach (braincell38) - Tuesday, 05 November 2013, 21:03 GMT
Windows appear to be asking for String index 0xEE (MSFT OS string descriptor) which causes device to STALL the EP. You aren't supposed to STALL EP0 IN.

It believe it should should be "usb_drv_stall(EP_CONTROL, true, false);" below in the else statement in usb_core.c:


case USB_DT_STRING:
logf("STRING %d", index);
if((unsigned)index < (sizeof(usb_strings) /
sizeof(struct usb_string_descriptor*))) {
size = usb_strings[index]->bLength;
ptr = usb_strings[index];
}
else {
logf("bad string id %d", index);
usb_drv_stall(EP_CONTROL, true, true);
}
break;
Comment by B Quach (braincell38) - Tuesday, 05 November 2013, 21:07 GMT
Perhaps the problem is that after OS descriptor request is STALLED, the device doesn't respond to any regular string descriptor requests. It doesn't STALL, it just NAKs.
Comment by B Quach (braincell38) - Tuesday, 05 November 2013, 21:08 GMT
See naks in second screenshot.
   sansa2.JPG (181.9 KiB)
Comment by B Quach (braincell38) - Tuesday, 05 November 2013, 21:14 GMT
I stand corrected. You are supposed to STALL string index 0xEE. But after the next SETUP packet you receive, you have to automatically clear the STALL condition and respond appropriately.

Comment by Frank Gevaerts (fg) - Tuesday, 05 November 2013, 21:32 GMT
Indeed.

It looks to me as if the STALL condition *is* cleared properly (there's just the one), but we're not responding to the requests any more (in that trace, anyway). I assume the NAKing keeps going on in your trace?

The weird thing is that while we know there are issues with usb (especially) on this particular controller core, we *do* have reports of it connecting to windows at least some of the time, so I'm a bit confused here.

I wish this wasn't such a long time ago. I used to be quite familiar with usb...
Comment by B Quach (braincell38) - Wednesday, 06 November 2013, 03:25 GMT
Yes, it is NAKed forever.

Window's was updated to start reading this OS descriptor. If the device was previously stored in the registry, it will not try to read this descriptor again. If you use usboblivion to clear USB devices from the registry, it should be 100% reproducible. I couldn't find where in the source code that the STALL is cleared upon receipt of a new SETUP packet. I could not find the reference manual for the SoC so not sure how it's USB core works.
Comment by Frank Gevaerts (fg) - Wednesday, 06 November 2013, 09:26 GMT
The core will clear the STALL by itself. The S3C6400X datasheet (for a different SoC, but same USB core) says: "The application can only set this bit, and the core clears it, when a SETUP token is received for this endpoint."

Another datasheet to look for is STM32F4. (last night on irc: 23:37:35 <TheSeven> gevaerts: I think the best one is the STM32F4 series datasheet, which uses a slightly different version of the core).
Comment by Frank Gevaerts (fg) - Wednesday, 06 November 2013, 20:19 GMT
I've made a quick python script (using pyusb 0.4) to test this. It currently looks for sandisk devices.

What it does is ask for a valid string descriptor, then 0xEE, then a valid string descriptor again. It expects OK, fail, OK.

This works fine on my fuzev2 in the OF, and on my e200v1 (different USB core) in rockbox. It fails on my fuzev2.

The fuzev2 has the same USB core as the clip zip (although I don't know if it's the same revision).
Comment by B Quach (braincell38) - Wednesday, 06 November 2013, 20:45 GMT
Since the setup packet is ACKed after the initial STALL, the core is receiving it okay. The question is whether an interrupt is generated so the driver processes it and responds. The device just NAKs at that point (no STALL) so I think the STALL is cleared automatically.

A FW build that logs to a file would help narrow it down.
Comment by MichaelGiacomelli (saratoga) - Wednesday, 29 January 2014, 01:13 GMT
>A FW build that logs to a file would help narrow it down.

Just saw this now. FWIW, I think you can do this using logdiskf. Basically, it lets you printf to a buffer that is flushed whenever the storage is available. See: http://git.rockbox.org/?p=rockbox.git;a=blob;f=firmware/export/logdiskf.h

I think if you include that header, you should be able to ERRORF("blah") and get the output from .rockbox/rockbox_log.txt afterwards. Never tried it with USB, but AFAIK it should work.

Loading...