**WARNING*** MSC ROM Driver LPC4357 Buggy ROM!! Do not use!

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 

**WARNING*** MSC ROM Driver LPC4357 Buggy ROM!! Do not use!

1,505 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by ehughes on Wed May 21 08:31:14 MST 2014
Just as a warning to others..... Do not rely on the USB MSC drivers. 

I have been spending time trying to get the MSC ROM drivers to work with the SD card interface.    It is apparent that there are some fundamental architectural bugs in the ROM drivers.

Exhibit A

UM10503 Rev 1.8 - 28 January 2014

Table 596

The are descriptions of the MSC_Write, etc call backs.    The MSC_RAM example in V2.xx all show an extra argument called hi_offset THAT IS NOT DOCUMENTED IN THE MANUAL.

What is the true function prototype?   Stack corruption can/will occur

Exhibit B

In the Write Callback,  (translate_wr())    I can get Length and Offsets that make no sense

For example,  when I try to plumb in my disk_io layer (which I have verified working with FatFs),   I can get lengths that are not increments of a 512 byte block (this violates the SCSI rules for USB MSC).

Furthermore,  when I get these odd lengths,   the offset is not aligned to a 512 byte boundary.    even if add/subtract the "length" parameter,  it DOES NOT exist on a block boundary.  In fact,  the Length + Offset can span 2 blocks

These is no sane way of interfacing to a block based device (SD) card if this is the way thing work.    the USB MSC spec never requires this kind of access. 

Exhibit C

There are many cases where the length field is set to zero.    This behavior is useless.


Exhibit D


During USB write transaction,   the rom driver tends to hang around this address:

0x10402b80
标签 (1)
0 项奖励
回复
5 回复数

1,370 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by emh203 on Fri Nov 21 07:45:49 MST 2014


Is there a way I can determine "A"?


I am running into this issue again.

As for B/D,     it looks like it is always a 512 byte packet before the length 31.
0 项奖励
回复

1,370 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by ehughes on Fri May 23 05:32:00 MST 2014
A.

The issue is that if you don't know which version of ROM you have,  you may try to use hi_offset in your calculation.   in my case I am pretty sure I have an older ROM as I the data coming in appears to be invalid.

A comment in the code could be useful so someone doesn't try to use this offset (this was part of my issue)

Where can I find out which ROM version I have?    Is there a date/lot code?

B,D...


I am working on a clean example that instruments the code and dumps a trace to the debug port for Analysis. I should have it ready soon
0 项奖励
回复

1,370 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by nxpsupport on Thu May 22 15:52:00 MST 2014
A. Mainly done to support 64 bit expansion to support higher capacity SD cards. Older version of ROM can support block devices only up to 2GB. The fourth param trick is used to keep user code binary compatible. App developed using old ROM interface should still work with new ROM and not corrupt stack.


B.  If you are receiving 31 byte packet that means you are get CBW packet. These CBW packets are trapped by ROM driver and parsed. That means the MSC state machine in ROM thought it is in data_input state but host had sent CBW packet.... In your case you can safely assume that if data_length is 31 it means it is non-data packet so don't write to the block device. We need to invesigate why the CBW packet is slipping through. Can you capture USB traffic during this error and post?

C. Yes you can set MSC_GetWriteBuf to null during init.

D. Yes. What is the length of the packet just before receiving 31 byte packet?
0 项奖励
回复

1,370 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by ehughes on Thu May 22 05:54:33 MST 2014
A:

Thank you for the clarification.   Things like this make me very nervous as I have seen compilers (including GCC) violate EABI.  

Can you clarify the intended use?   (other than 64-bit addressing)


B.


Thank you for the clarification on on that.   In this case the length was set to 31!       Let me take some time to get the project setup simpler (it is a LPC4357 Dual Core) to send you to show you the problem.

C.)   The other challenge is the API call    GetWrBr:

Here is the example from the MSC_RAM

/* USB device mass storage class get write buffer callback routine */
static void translate_GetWrBuf(uint32_t offset, uint8_t * *buff_adr, uint32_t length, uint32_t hi_offset)
{
*buff_adr =  &g_memDiskArea[(((uint64_t) offset) | (((uint64_t) hi_offset) << 32))];
}


Here is the documentation from page 799 of 1420 of Rev 1.8 of UM10503


Quote:
Optional callback function to optimize MSC_Write buffer transfer.
This function is provided by the application software. This function gets called when host
sends SCSI_WRITE10/SCSI_WRITE12 command. The callback function should update the



It appears the text gets cut off.         the example just just passes a pointer back from the RAM block used for the file system. Please advise on what this function should do.   For a block based device, do Ineed to have a cache?    It would be nice if we could see the source code for the ROM driver to get an idea of how these functions interact.

I noticed it said it is "optional".   Does this mean I can feed a null pointer to the function pointer in the setup struct?

D. 

What is weird is that 99% of the write callbacks work.    The file mostly shows up on disk but something seems to hang windows up towards the end.  it may have something to do with how I get a write callback with a length of 31


Thank you for the help.   It would be very nice if this could work as it would free up other code space.

0 项奖励
回复

1,370 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by nxpsupport on Wed May 21 13:55:00 MST 2014
Hi ehughes,

Thank you for posting. Please see below for each of your points:

Exhibit A
I am sorry our USB MSC documentation is both lacking and needs updating.
The 4th parameter was added in a newer version of ROM stack (LPC18xx Rev D silicon and onwards). Since ARM EABI calling convention specifies that r0-r3 (up to 4 parameters) are not preserved for a sub-routine call, the calling routine should not assume these registers will be intact after a sub-routine call. Since the original ROM code uses only first 3 params (r0-r2), even if you pass a fourth parameter to the old ROM USB lib it is ignored.  For newer ROM you need to pass the 4th param. Hence the example code is updated with 4 param signature to be compatible with both ROM versions. This should not corrupt the stack.

Exhibit B

Offset should always be a multiple of “param->BlockSize”, where param is USBD_MSC_INIT_PARAM_T* you pass to USBD_API->msc->init() routine. The only time it could be non-blocksize offset is if the BlockSize is greater than MAXP of the endpoint. If you are connected at full-speed then MAXP will be 64 bytes, so the write() function would be called with a multiple of 64 byte offset instead of BlockSize.

Exhibit C

As per USB Mass storage specification, when the total amount of data sent for command block is exactly a multiple of MAXP (512 for HS mode and 64 for FS mode), then the host should send a zero-length-packet to indicate end of transfer. So for this last transfer the translate_wr() would be called with length param set to zero.
Due to MAXP restriction and buffer management complexity we had to pass these kind of gotchas to the application layer and not abstract it out completely in ROM driver.

We agree that providing a MSC example using the ROM stack for a block based device such as SD card would be good to clarify the questions/issues you have. We will push it up priority-wise in our TODO list.
As an alternative you could use ROM stack to take care of Ch9 (USB enumeration etc) and in the application you could implement your own BulkEP handlers to take-care of MSC class CBW handling.

Exhibit D
We will investigate this.

Best regards,
-NXP Support
0 项奖励
回复