2017-11-27 05:01 AM
I've successfully implemented MSC device on USB FS port, it works perfectly under Windows (7 and XP) and Linux (Ubuntu 16)...
...but only if MaxLun is 0.
I've implemented 3 independent storage devices (actually, all of them are RAM-drives, for debugging purposes; just with slightly different capacity), modified some functions, modified USB BOT handler so it could track status for each LUN independently. Under Linux, I've achieved write speed about 1MB/s with some code optimizations. I've tested all LUNs under linux by formatting/writing/copying files, by playback of MP3 and video; i've copied data from system disk to ramdrive and between ramdrives, in each possible combination.
In my debugging console I see INQUIRY requests for each LUN when device is connected to Linux host (it asks for maxlun and then sends INQUIRY to each of them). I see how Linux host poking each LUN for ready flag. But Windows hosts asks only LUN0 and never asks others, never tests them for anything.
I've found (by googling) that it may be problem with Device Serial number, but I have correct device descriptor with correct serial number : twelve utf16 chars, '000000000001'.
I guess, it may be problem with the Windows host itself, but I don't know how to diagnose it. More than that, i have cardreader device with 4 LUNs and it works perfectly under same windows host!
Any ideas?
2018-02-08 06:21 PM
Ok, thanks. In the meantime I figured out the problem. It seems the USB MSC driver from ST and the Windows driver do not communicate properly when using LUNs with different block size.
2018-02-09 03:23 AM
On enumeration, Windows host asks for standard descriptors: device, configuration and strings. And when it asks for strings, one of the requests is obviously incorrect (or, as I said, it maybe just my own misunderstanding of correctness): it asks for string descriptor, but requests 2 byte response. Means, device should return only header of requested descriptor (length + type, but not contents).
This is actually a valid behavior for reading variable-size descriptors:
(The other approach is to request the descriptor with maximum length the first time.)
So this behavior is only incorrect if the second request doesn't arrive.
2018-02-09 07:25 AM
There are numerous problems with ST MSC code. First, single LUN support is hard-coded in at least 2 places, so you cannot increase the number of LUNs until you correct this. Second, you must change the way in which ST code handles inquiry requests to provide for independent data structure for each LUN. Third, ST code stores the geometry of the last inquired LUN and uses it to check the validity of parms for any LUN it operates on. In my case I completely rewrote the msc_if.c and made several changes to SCSI layer to make both units 'LUN-config-agnostic'. I have a structure for each LUN containing its parms, inquiry data and pointers to read/write/whatever functions.
2018-02-09 08:37 AM
Thank you. I also discovered these problems today, after debugging the weird behavior of the MSC driver when using 2 LUNs. My solution to the geometry problem was to update the LUN geometry in the MSC data structure at the beginning of each read/write request instead of creating separate data structures for each LUN. This only required changes in the SCSI layer.
Another problem I discovered while making these changes is that block IDs are transformed into absolute addresses in the SCSI layer, but saved into the same uint32_t variable - this does not perform as expected for data blocks located beyond the 4GB limit. Not cool.
2018-02-22 02:01 AM
It is correct and it is not correct in same time. Windows COULD ask for header only and wait for header only, but in fact it asks for header, but awaits for full length descriptor. Linux (distro I'm using) never asks for silly descriptors.