rk27xx: don't return from SD transfers with the lock held

sd_read_sectors() and sd_write_sectors() take sd_mtx and power the
controller, then check the requested range and return -1 on failure -
leaving the mutex held and the controller on. Check the range first.

With no card present numblocks is 0, so every request takes that path.
Rockbox mutexes are recursive for the owning thread, so the first thread
to touch the SD drive keeps working, and every other thread that does
blocks forever.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Change-Id: I16c2be3bde5c62946fdedaabe115b6c4bc330467
This commit is contained in:
Marcin Bukat 2026-09-24 00:30:51 +02:00
parent 330236911b
commit 79329c8f7c

View file

@ -464,12 +464,15 @@ int sd_read_sectors(IF_MD(int drive,) sector_t start, int count,
int cnt, ret = 0;
unsigned char *dst;
mutex_lock(&sd_mtx);
enable_controller(true);
/* Checked before taking the lock: returning from after it left sd_mtx
* held and the controller powered. With no card numblocks is 0, so
* that was every request. */
if (count <= 0 || start + count > card_info.numblocks)
return -1;
mutex_lock(&sd_mtx);
enable_controller(true);
if(!(card_info.ocr & (1<<30)))
start <<= 9; /* not SDHC */
@ -602,12 +605,15 @@ int sd_write_sectors(IF_MD(int drive,) sector_t start, int count,
unsigned char *src;
/* bool card_selected = false; */
mutex_lock(&sd_mtx);
enable_controller(true);
/* Checked before taking the lock: returning from after it left sd_mtx
* held and the controller powered. With no card numblocks is 0, so
* that was every request. */
if (count <= 0 || start + count > card_info.numblocks)
return -1;
mutex_lock(&sd_mtx);
enable_controller(true);
if(!(card_info.ocr & (1<<30)))
start <<= 9; /* not SDHC */