FS#12468 - Hotswap fails to recognize the card after it was removed in USB mode

Attached to Project: Rockbox
Opened by Andrej (rarog) - Monday, 19 December 2011, 03:55 GMT
Task Type Bugs
Category Operating System/Drivers
Status Unconfirmed
Assigned To No-one
Operating System All players
Severity Low
Priority Normal
Reported Version Release 3.9
Due in Version Undecided
Due Date Undecided
Percent Complete 0%
Votes 0
Private No


If Rockbox is connected via USB with no sd card inserted and it is inserted, it offers the OS to mount the new drive.
If the sd card is removed and reinsterted again, it fails to offer and recognize it.

I could locate the problem in firmware/usbstack/usb_storage.c in the line

if(inserted && check_disk_present(IF_MD(volume))) {

after reinserting the card, check_disk_present fails to return true, so this check fails and the card isn't recognized anymore.
This task depends upon

Comment by Andrej (rarog) - Monday, 19 December 2011, 04:01 GMT
Ok, further investigation reveals, that in the function fat_get_sector_buffer() called in check_disk_present() returns an empty string after reinserting the sd card.
Comment by Boris Gjenero (dreamlayers) - Tuesday, 20 December 2011, 04:33 GMT
If check_disk_present() returns false, that means the storage_read_sectors() call inside failed. It's just reading the very first sector. A failure probably means the sd driver is encountering problems.

The initial contents of memory pointed to by the return value of fat_get_sector_buffer() don't matter. That's just some free memory where storage_read_sectors() can write.

On what device is this happening? Is this on Fuze+ and related to  FS#12458 ?
Comment by Andrej (rarog) - Tuesday, 20 December 2011, 14:21 GMT
Ok, indeed I read the code wrong. It is on Fuze+, but as the other bug had other errors in description, I opened a new one, as I found these problems while investigating the other bug.

Further investigations on this bug reveals, that indeed storage_read_sectors returns a -1 instead of 0 when the sd card is reinserted.

storage_read_sectors calls sd_read_sectors which calls transfer_sectors. And this is indeed a fuze+ specific implementation.

I'll investigate this problem further to see, which part of transfer_sectors fails.
Comment by Andrej (rarog) - Tuesday, 20 December 2011, 14:37 GMT
Ok, the problem is that the following line:
ret = sd_wait_for_tran_state();

sets ret to -1.

Investigating further it seems to hint to a timeout during the following lines:
while(!send_cmd(SD_SEND_STATUS, card_info.rca, SSP_SHORT_RESP, &response) && cmd_retry > 0)

if(cmd_retry <= 0)
return -1;

cmd_retry is set to 10, but no values like 20 or 100 brought the desired result, so it seems that something in send_cmd(SD_SEND_STATUS... goes wrong.
Comment by Andrej (rarog) - Thursday, 22 December 2011, 04:09 GMT
When the thing fails, card_info.rca is set to -433847008 and response is set to 2816.
Comment by Andrej (rarog) - Thursday, 22 December 2011, 04:56 GMT
3861120288 is card_info.rca actually if read as unsigned int.

But other thing is, that SSP_SHORT_RESP has the value of 1 and MCI_ACMD is 4, so send_cmd automatically should have (flags & MCI_ACMD) checked to false as this should become 0, so send_cmd always returns false and won't read. Does this make any sense?