summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
authorAidan MacDonald <amachronic@protonmail.com>2021-03-08 11:29:05 +0000
committerSolomon Peachy <pizza@shaftnet.org>2021-03-27 14:43:17 -0400
commitea1aef9b82c91f93eb0bacccab7b213c374f18f5 (patch)
treef5b95b575a66f9988ddbcb1036d90d59cdbf0fe4 /firmware
parentf00eea4434ab5c30df48c60aaa215754f6833c5d (diff)
downloadrockbox-ea1aef9b82c91f93eb0bacccab7b213c374f18f5.tar.gz
rockbox-ea1aef9b82c91f93eb0bacccab7b213c374f18f5.zip
Have FAT filesystem respect storage buffer alignment on reads
This is just a minor cleanup of Solomon Peachy's code, and using per-filesystem buffers instead of a single static buffer. Tested and working on the FiiO M3K. Change-Id: I3c19e8cc24e2f8aa07668c9d1c6d63364815050a
Diffstat (limited to 'firmware')
-rw-r--r--firmware/drivers/fat.c38
1 files changed, 36 insertions, 2 deletions
diff --git a/firmware/drivers/fat.c b/firmware/drivers/fat.c
index c0e84a2f61..61bf9051f2 100644
--- a/firmware/drivers/fat.c
+++ b/firmware/drivers/fat.c
@@ -266,6 +266,13 @@ static struct bpb
266 266
267} fat_bpbs[NUM_VOLUMES]; /* mounted partition info */ 267} fat_bpbs[NUM_VOLUMES]; /* mounted partition info */
268 268
269#ifdef STORAGE_WANTS_ALIGN
270#define FAT_BOUNCE_SECTORS 10
271static uint8_t fat_bounce_buffers[NUM_VOLUMES][SECTOR_SIZE*FAT_BOUNCE_SECTORS] STORAGE_ALIGN_ATTR;
272#define FAT_BOUNCE_BUFFER(bpb) \
273 (fat_bounce_buffers[IF_MV_VOL((bpb)->volume)])
274#endif
275
269#define IS_FAT_SECTOR(bpb, sector) \ 276#define IS_FAT_SECTOR(bpb, sector) \
270 (!((sector) >= (bpb)->fatrgnend || (sector) < (bpb)->fatrgnstart)) 277 (!((sector) >= (bpb)->fatrgnend || (sector) < (bpb)->fatrgnstart))
271 278
@@ -2385,8 +2392,35 @@ static long transfer(struct bpb *fat_bpb, unsigned long start, long count,
2385 } 2392 }
2386 else 2393 else
2387 { 2394 {
2388 rc = storage_read_sectors(IF_MD(fat_bpb->drive,) 2395 void* xferbuf = buf;
2389 start + fat_bpb->startsector, count, buf); 2396#ifdef STORAGE_WANTS_ALIGN
2397 int remain = count;
2398 int xferred = 0;
2399 int aligned = 1;
2400 if(STORAGE_OVERLAP((uintptr_t)buf)) {
2401 xferbuf = FAT_BOUNCE_BUFFER(fat_bpb);
2402 aligned = 0;
2403 count = MIN(remain, FAT_BOUNCE_SECTORS);
2404 }
2405
2406 while(remain > 0) {
2407#endif
2408 rc = storage_read_sectors(IF_MD(fat_bpb->drive,)
2409 start + fat_bpb->startsector, count, xferbuf);
2410#ifdef STORAGE_WANTS_ALIGN
2411 if(rc < 0)
2412 break;
2413 if(LIKELY(aligned))
2414 break;
2415
2416 memcpy(buf, xferbuf, count * SECTOR_SIZE);
2417 buf += count * SECTOR_SIZE;
2418 xferred += count;
2419 start += count;
2420 remain -= count;
2421 count = MIN(remain, FAT_BOUNCE_SECTORS);
2422 }
2423#endif
2390 } 2424 }
2391 2425
2392 if (rc < 0) 2426 if (rc < 0)