diff options
author | Aidan MacDonald <amachronic@protonmail.com> | 2021-03-08 11:29:05 +0000 |
---|---|---|
committer | Solomon Peachy <pizza@shaftnet.org> | 2021-03-27 14:43:17 -0400 |
commit | ea1aef9b82c91f93eb0bacccab7b213c374f18f5 (patch) | |
tree | f5b95b575a66f9988ddbcb1036d90d59cdbf0fe4 /firmware | |
parent | f00eea4434ab5c30df48c60aaa215754f6833c5d (diff) | |
download | rockbox-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.c | 38 |
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 | ||
271 | static 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) |