From c453f4fa8fa01451a472e7005c57ed241b439e45 Mon Sep 17 00:00:00 2001 From: Marcin Bukat Date: Thu, 1 Oct 2026 09:28:09 +0200 Subject: [PATCH] rk27xx: name the NAND's FTL scheme in each target's config CONFIG_RK27XX_FTL selects the FTL a target's NAND uses, RK27XX_FTL_SCHEME_A or RK27XX_FTL_SCHEME_B. rk27generic and the YP-CP3 are Scheme A, the HM-60x Scheme B. ftl-rk27xx.c mounts the one named; for Scheme B it maps the drives onto the volumes ID block 1 records: the system disk from LBA 0, the user volume after the system data area. The other rk27xx targets with NAND - HM-801, MA8, MA8C, MA9, MA9C and iHiFi 760, 770, 770C, 800, 960 - have no confirmed scheme. They drop the NAND from storage and build only the FTL scheme finder, so users can report what their device holds and the scheme can then be set. Only Scheme A flushes at shutdown: Scheme B holds nothing in RAM. Co-Authored-By: Claude Opus 5.5 Change-Id: I484217b82c6de7316b90b354c012bfbaa263b3dd --- firmware/SOURCES | 18 +- firmware/export/config.h | 13 +- firmware/export/config/hifietma8.h | 8 +- firmware/export/config/hifietma8c.h | 8 +- firmware/export/config/hifietma9.h | 8 +- firmware/export/config/hifietma9c.h | 8 +- firmware/export/config/hifimanhm60x.h | 1 + firmware/export/config/hifimanhm801.h | 8 +- firmware/export/config/ihifi760.h | 8 +- firmware/export/config/ihifi770.h | 8 +- firmware/export/config/ihifi770c.h | 8 +- firmware/export/config/ihifi800.h | 8 +- firmware/export/config/ihifi960.h | 8 +- firmware/export/config/rk27generic.h | 1 + firmware/export/config/samsungypcp3.h | 1 + firmware/target/arm/rk27xx/ftl-rk27xx.c | 242 +++++++++++++++++++----- 16 files changed, 278 insertions(+), 78 deletions(-) diff --git a/firmware/SOURCES b/firmware/SOURCES index 46966bb507..cd1c3f201a 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES @@ -1710,15 +1710,23 @@ target/arm/rk27xx/system-rk27xx.c target/arm/rk27xx/backlight-rk27xx.c target/arm/rk27xx/adc-rk27xx.c target/arm/rk27xx/sd-rk27xx.c -target/arm/rk27xx/ftl-rk27xx.c -target/arm/rk27xx/ftl-scheme-a.c +#if CONFIG_NAND == NAND_RK27XX +#if (CONFIG_STORAGE & STORAGE_NAND) +target/arm/rk27xx/flash-rk27xx.c +target/arm/rk27xx/nand-rk27xx.c +target/arm/rk27xx/ftl-rk27xx.c +#if CONFIG_RK27XX_FTL == RK27XX_FTL_SCHEME_A +target/arm/rk27xx/ftl-scheme-a.c +#elif CONFIG_RK27XX_FTL == RK27XX_FTL_SCHEME_B +target/arm/rk27xx/ftl-scheme-b.c +#endif +#elif !defined(BOOTLOADER) +/* no FTL scheme configured: only the finder (debug menu) */ target/arm/rk27xx/flash-rk27xx.c target/arm/rk27xx/nand-rk27xx.c -#if (CONFIG_NAND == NAND_RK27XX) && !(CONFIG_STORAGE & STORAGE_NAND) \ - && !defined(BOOTLOADER) -/* no FTL scheme configured: the finder (debug menu) */ target/arm/rk27xx/ftl-probe-rk27xx.c #endif +#endif target/arm/rk27xx/usb-rk27xx.c target/arm/rk27xx/lcdif-rk27xx.c target/arm/rk27xx/rkw-loader.c diff --git a/firmware/export/config.h b/firmware/export/config.h index 508caf5e40..786ca1e3a8 100644 --- a/firmware/export/config.h +++ b/firmware/export/config.h @@ -325,6 +325,11 @@ Lyre prototype 1 */ #define NAND_RK27XX 5 #define NAND_IMX233 6 +/* CONFIG_RK27XX_FTL: the on-flash format of an rk27xx target's NAND. A + * target that does not define it builds only the FTL scheme finder. */ +#define RK27XX_FTL_SCHEME_A 1 /* ftl-scheme-a.c: zone tables, remap logs */ +#define RK27XX_FTL_SCHEME_B 2 /* ftl-scheme-b.c: self-describing blocks */ + /* CONFIG_RTC */ #define RTC_HOSTED 1 /* Generic hosted */ #define RTC_PCF50605 2 /* iPod 3G, 4G & Mini */ @@ -893,10 +898,12 @@ Lyre prototype 1 */ /* Storage related config handling */ -/* The rk27xx NAND's flash translation layer holds part-written pages in RAM - * (ftl-scheme-a.c) until a later write completes them; storage_flush() - * commits them at shutdown, ROLO and wherever else it is called. */ +/* The rk27xx NAND's Scheme A flash translation layer holds part-written + * pages in RAM (ftl-scheme-a.c) until a later write completes them; + * storage_flush() commits them at shutdown, ROLO and wherever else it is + * called. */ #if (CONFIG_STORAGE & STORAGE_NAND) && (CONFIG_NAND == NAND_RK27XX) \ + && (CONFIG_RK27XX_FTL == RK27XX_FTL_SCHEME_A) \ && !defined(HAVE_STORAGE_FLUSH) #define HAVE_STORAGE_FLUSH #endif diff --git a/firmware/export/config/hifietma8.h b/firmware/export/config/hifietma8.h index 80f6be3b9e..b40c22a4c0 100644 --- a/firmware/export/config/hifietma8.h +++ b/firmware/export/config/hifietma8.h @@ -45,7 +45,11 @@ /* define this if you have a flash memory storage */ #define HAVE_FLASH_STORAGE -#define CONFIG_STORAGE (STORAGE_SD | STORAGE_NAND) +/* The NAND's FTL scheme is not known yet, so the NAND is not storage here: + * only the FTL scheme finder is built (Debug > View FTL scheme). Once a + * report confirms the scheme, define CONFIG_RK27XX_FTL and add STORAGE_NAND, + * as config/hifimanhm60x.h does. */ +#define CONFIG_STORAGE STORAGE_SD #define CONFIG_NAND NAND_RK27XX #define HAVE_SW_TONE_CONTROLS @@ -53,7 +57,7 @@ /* commented for now */ /* #define HAVE_HOTSWAP */ -#define NUM_DRIVES 2 +#define NUM_DRIVES 1 #define SECTOR_SIZE 512 /* for small(ish) SD cards */ diff --git a/firmware/export/config/hifietma8c.h b/firmware/export/config/hifietma8c.h index 8504fa1e55..1006d8721b 100644 --- a/firmware/export/config/hifietma8c.h +++ b/firmware/export/config/hifietma8c.h @@ -45,7 +45,11 @@ /* define this if you have a flash memory storage */ #define HAVE_FLASH_STORAGE -#define CONFIG_STORAGE (STORAGE_SD | STORAGE_NAND) +/* The NAND's FTL scheme is not known yet, so the NAND is not storage here: + * only the FTL scheme finder is built (Debug > View FTL scheme). Once a + * report confirms the scheme, define CONFIG_RK27XX_FTL and add STORAGE_NAND, + * as config/hifimanhm60x.h does. */ +#define CONFIG_STORAGE STORAGE_SD #define CONFIG_NAND NAND_RK27XX #define HAVE_SW_TONE_CONTROLS @@ -53,7 +57,7 @@ /* commented for now */ /* #define HAVE_HOTSWAP */ -#define NUM_DRIVES 2 +#define NUM_DRIVES 1 #define SECTOR_SIZE 512 /* for small(ish) SD cards */ diff --git a/firmware/export/config/hifietma9.h b/firmware/export/config/hifietma9.h index 4c9eea2594..123a549f99 100644 --- a/firmware/export/config/hifietma9.h +++ b/firmware/export/config/hifietma9.h @@ -45,7 +45,11 @@ /* define this if you have a flash memory storage */ #define HAVE_FLASH_STORAGE -#define CONFIG_STORAGE (STORAGE_SD | STORAGE_NAND) +/* The NAND's FTL scheme is not known yet, so the NAND is not storage here: + * only the FTL scheme finder is built (Debug > View FTL scheme). Once a + * report confirms the scheme, define CONFIG_RK27XX_FTL and add STORAGE_NAND, + * as config/hifimanhm60x.h does. */ +#define CONFIG_STORAGE STORAGE_SD #define CONFIG_NAND NAND_RK27XX #define HAVE_SW_TONE_CONTROLS @@ -53,7 +57,7 @@ /* commented for now */ /* #define HAVE_HOTSWAP */ -#define NUM_DRIVES 2 +#define NUM_DRIVES 1 #define SECTOR_SIZE 512 /* for small(ish) SD cards */ diff --git a/firmware/export/config/hifietma9c.h b/firmware/export/config/hifietma9c.h index bcc4505d54..b40d9bd4e9 100644 --- a/firmware/export/config/hifietma9c.h +++ b/firmware/export/config/hifietma9c.h @@ -45,7 +45,11 @@ /* define this if you have a flash memory storage */ #define HAVE_FLASH_STORAGE -#define CONFIG_STORAGE (STORAGE_SD | STORAGE_NAND) +/* The NAND's FTL scheme is not known yet, so the NAND is not storage here: + * only the FTL scheme finder is built (Debug > View FTL scheme). Once a + * report confirms the scheme, define CONFIG_RK27XX_FTL and add STORAGE_NAND, + * as config/hifimanhm60x.h does. */ +#define CONFIG_STORAGE STORAGE_SD #define CONFIG_NAND NAND_RK27XX #define HAVE_SW_TONE_CONTROLS @@ -53,7 +57,7 @@ /* commented for now */ /* #define HAVE_HOTSWAP */ -#define NUM_DRIVES 2 +#define NUM_DRIVES 1 #define SECTOR_SIZE 512 /* for small(ish) SD cards */ diff --git a/firmware/export/config/hifimanhm60x.h b/firmware/export/config/hifimanhm60x.h index 51de435467..e26ff271fe 100644 --- a/firmware/export/config/hifimanhm60x.h +++ b/firmware/export/config/hifimanhm60x.h @@ -51,6 +51,7 @@ #define CONFIG_STORAGE (STORAGE_SD | STORAGE_NAND) #define CONFIG_NAND NAND_RK27XX +#define CONFIG_RK27XX_FTL RK27XX_FTL_SCHEME_B #define HAVE_SW_TONE_CONTROLS #define HAVE_SW_VOLUME_CONTROL diff --git a/firmware/export/config/hifimanhm801.h b/firmware/export/config/hifimanhm801.h index d420a1f714..c604725de1 100644 --- a/firmware/export/config/hifimanhm801.h +++ b/firmware/export/config/hifimanhm801.h @@ -45,7 +45,11 @@ /* define this if you have a flash memory storage */ #define HAVE_FLASH_STORAGE -#define CONFIG_STORAGE (STORAGE_SD | STORAGE_NAND) +/* The NAND's FTL scheme is not known yet, so the NAND is not storage here: + * only the FTL scheme finder is built (Debug > View FTL scheme). Once a + * report confirms the scheme, define CONFIG_RK27XX_FTL and add STORAGE_NAND, + * as config/hifimanhm60x.h does. */ +#define CONFIG_STORAGE STORAGE_SD #define CONFIG_NAND NAND_RK27XX #define HAVE_SW_TONE_CONTROLS @@ -55,7 +59,7 @@ /* commented for now */ /* #define HAVE_HOTSWAP */ -#define NUM_DRIVES 2 +#define NUM_DRIVES 1 #define SECTOR_SIZE 512 /* for small(ish) SD cards */ diff --git a/firmware/export/config/ihifi760.h b/firmware/export/config/ihifi760.h index b3057daaaf..e64b5403f8 100644 --- a/firmware/export/config/ihifi760.h +++ b/firmware/export/config/ihifi760.h @@ -48,8 +48,12 @@ /* define this if you have a flash memory storage */ #define HAVE_FLASH_STORAGE -#define CONFIG_STORAGE (STORAGE_SD | STORAGE_NAND) -#define NUM_DRIVES 1 /* NAND doesn't work yet */ +/* The NAND's FTL scheme is not known yet, so the NAND is not storage here: + * only the FTL scheme finder is built (Debug > View FTL scheme). Once a + * report confirms the scheme, define CONFIG_RK27XX_FTL and add STORAGE_NAND, + * as config/hifimanhm60x.h does. */ +#define CONFIG_STORAGE STORAGE_SD +#define NUM_DRIVES 1 #define CONFIG_NAND NAND_RK27XX #define HAVE_SW_TONE_CONTROLS diff --git a/firmware/export/config/ihifi770.h b/firmware/export/config/ihifi770.h index d6ca563339..0c8ddae90d 100644 --- a/firmware/export/config/ihifi770.h +++ b/firmware/export/config/ihifi770.h @@ -49,8 +49,12 @@ /* define this if you have a flash memory storage */ #define HAVE_FLASH_STORAGE -#define CONFIG_STORAGE (STORAGE_SD | STORAGE_NAND) -#define NUM_DRIVES 1 /* NAND doesn't work yet */ +/* The NAND's FTL scheme is not known yet, so the NAND is not storage here: + * only the FTL scheme finder is built (Debug > View FTL scheme). Once a + * report confirms the scheme, define CONFIG_RK27XX_FTL and add STORAGE_NAND, + * as config/hifimanhm60x.h does. */ +#define CONFIG_STORAGE STORAGE_SD +#define NUM_DRIVES 1 #define CONFIG_NAND NAND_RK27XX #define HAVE_SW_TONE_CONTROLS diff --git a/firmware/export/config/ihifi770c.h b/firmware/export/config/ihifi770c.h index c305a3a3d0..f55f120712 100644 --- a/firmware/export/config/ihifi770c.h +++ b/firmware/export/config/ihifi770c.h @@ -49,8 +49,12 @@ /* define this if you have a flash memory storage */ #define HAVE_FLASH_STORAGE -#define CONFIG_STORAGE (STORAGE_SD | STORAGE_NAND) -#define NUM_DRIVES 1 /* NAND doesn't work yet */ +/* The NAND's FTL scheme is not known yet, so the NAND is not storage here: + * only the FTL scheme finder is built (Debug > View FTL scheme). Once a + * report confirms the scheme, define CONFIG_RK27XX_FTL and add STORAGE_NAND, + * as config/hifimanhm60x.h does. */ +#define CONFIG_STORAGE STORAGE_SD +#define NUM_DRIVES 1 #define CONFIG_NAND NAND_RK27XX #define HAVE_SW_TONE_CONTROLS diff --git a/firmware/export/config/ihifi800.h b/firmware/export/config/ihifi800.h index c6e8652111..d70c259c59 100644 --- a/firmware/export/config/ihifi800.h +++ b/firmware/export/config/ihifi800.h @@ -49,8 +49,12 @@ /* define this if you have a flash memory storage */ #define HAVE_FLASH_STORAGE -#define CONFIG_STORAGE (STORAGE_SD | STORAGE_NAND) -#define NUM_DRIVES 1 /* NAND doesn't work yet */ +/* The NAND's FTL scheme is not known yet, so the NAND is not storage here: + * only the FTL scheme finder is built (Debug > View FTL scheme). Once a + * report confirms the scheme, define CONFIG_RK27XX_FTL and add STORAGE_NAND, + * as config/hifimanhm60x.h does. */ +#define CONFIG_STORAGE STORAGE_SD +#define NUM_DRIVES 1 #define CONFIG_NAND NAND_RK27XX #define HAVE_SW_TONE_CONTROLS diff --git a/firmware/export/config/ihifi960.h b/firmware/export/config/ihifi960.h index f1506f59df..a3af5d7354 100644 --- a/firmware/export/config/ihifi960.h +++ b/firmware/export/config/ihifi960.h @@ -48,8 +48,12 @@ /* define this if you have a flash memory storage */ #define HAVE_FLASH_STORAGE -#define CONFIG_STORAGE (STORAGE_SD | STORAGE_NAND) -#define NUM_DRIVES 1 /* NAND doesn't work yet */ +/* The NAND's FTL scheme is not known yet, so the NAND is not storage here: + * only the FTL scheme finder is built (Debug > View FTL scheme). Once a + * report confirms the scheme, define CONFIG_RK27XX_FTL and add STORAGE_NAND, + * as config/hifimanhm60x.h does. */ +#define CONFIG_STORAGE STORAGE_SD +#define NUM_DRIVES 1 #define CONFIG_NAND NAND_RK27XX #define HAVE_SW_TONE_CONTROLS diff --git a/firmware/export/config/rk27generic.h b/firmware/export/config/rk27generic.h index 8c1eaa3975..a61f0400ac 100644 --- a/firmware/export/config/rk27generic.h +++ b/firmware/export/config/rk27generic.h @@ -58,6 +58,7 @@ #define CONFIG_STORAGE (STORAGE_SD | STORAGE_NAND) #define CONFIG_NAND NAND_RK27XX +#define CONFIG_RK27XX_FTL RK27XX_FTL_SCHEME_A #define HAVE_SW_TONE_CONTROLS /* commented for now */ diff --git a/firmware/export/config/samsungypcp3.h b/firmware/export/config/samsungypcp3.h index 61b80f5477..658b327165 100644 --- a/firmware/export/config/samsungypcp3.h +++ b/firmware/export/config/samsungypcp3.h @@ -44,6 +44,7 @@ #define CONFIG_STORAGE (STORAGE_SD | STORAGE_NAND) #define CONFIG_NAND NAND_RK27XX +#define CONFIG_RK27XX_FTL RK27XX_FTL_SCHEME_A /* commented for now */ /* #define HAVE_HOTSWAP */ diff --git a/firmware/target/arm/rk27xx/ftl-rk27xx.c b/firmware/target/arm/rk27xx/ftl-rk27xx.c index e5e50a8cf6..1f5de9ca3f 100644 --- a/firmware/target/arm/rk27xx/ftl-rk27xx.c +++ b/firmware/target/arm/rk27xx/ftl-rk27xx.c @@ -19,7 +19,8 @@ * ****************************************************************************/ -/* Rockbox storage on the rk27xx Scheme A FTL (ftl-scheme-a.c). +/* Rockbox storage on the rk27xx NAND, through the FTL scheme the target's + * config names in CONFIG_RK27XX_FTL: ftl-scheme-a.c or ftl-scheme-b.c. * * Writing is opt-in: a build without FTL_ALLOW_WRITE mounts read-only and * never writes the flash, not even the repairs a mount can make. */ @@ -29,7 +30,14 @@ #include "ftl-target.h" #include "nand-target.h" #include "flash-rk27xx.h" + +#if CONFIG_RK27XX_FTL == RK27XX_FTL_SCHEME_A #include "ftl-scheme-a.h" +#elif CONFIG_RK27XX_FTL == RK27XX_FTL_SCHEME_B +#include "ftl-scheme-b.h" +#else +#error "NAND storage needs CONFIG_RK27XX_FTL in the target config" +#endif /* The boot ROM looks for ID blocks at every 512th raw sector of the boot * area, up to 50 positions, by metadata type 0x69. */ @@ -39,26 +47,49 @@ #define IDB_TYPE 0x69 #define IDB_MAX_BOOT_BLOCKS 64 +#define SECTORS_PER_MB 2048 + +#if CONFIG_RK27XX_FTL == RK27XX_FTL_SCHEME_B +/* Scheme B's original firmware keeps its open exchange blocks to 8, and its + * mount recovers no more (ftl-scheme-b.h) */ +#define SCHEME_B_EXCH_BLOCKS 8 +#endif + +/* What ID block 1 records */ +struct idb_info +{ + uint32_t boot_blocks; /* raw blocks of the boot area */ + uint32_t sys_sectors; /* the SYS volume (code disk) */ + uint32_t data_sectors; /* Scheme B: the system data area after it */ +}; + static bool ftl_mounted = false; -/* The size of the SYS volume, from ID block 1. +#if CONFIG_RK27XX_FTL == RK27XX_FTL_SCHEME_B +/* Scheme B's logical space holds the volumes back to back: SYS, the system + * data area, then USER to the end */ +static uint32_t vol_base[FTL_NUM_DRIVES]; +static uint32_t vol_size[FTL_NUM_DRIVES]; +#endif + +/* ID block 1, the sector after ID block 0: * - * ID block 0 is scrambled; ID block 1, the sector after it, is plain: - * - * +0 uint16_t LE blocks of bootloader + * +0 uint16_t LE raw blocks of the boot area * +2 uint16_t LE SYS volume size, MB + * +4 uint16_t LE system data area size, MB (Scheme B) * - * A sector marked 0x69 whose ID block 1 gives a sane block count and a SYS - * volume smaller than the chip is taken; descrambling ID block 0 to check its - * signature would buy little over that. Returns 0 if none is found. */ -static uint32_t idb_sys_sectors(void) + * ID block 0 is scrambled; ID block 1 is plain. A sector marked 0x69 whose + * ID block 1 gives a sane block count and a SYS volume smaller than the + * chip is taken; descrambling ID block 0 to check its signature would buy + * little over that. Returns false if none is found. */ +static bool idb_read(struct idb_info *idb) { const struct flash_geometry *geo = flash_get_geometry(); uint8_t data[FLASH_SECTOR_SIZE], meta[FLASH_META_SIZE]; - uint32_t sectors = 0; + bool found = false; uint32_t pos; - for (pos = 0; pos < IDB_POSITIONS && sectors == 0; pos++) + for (pos = 0; pos < IDB_POSITIONS && !found; pos++) { uint32_t raw = pos * IDB_STRIDE; uint32_t blocks, mb; @@ -82,17 +113,86 @@ static uint32_t idb_sys_sectors(void) mb = data[2] | (data[3] << 8); if (blocks > 0 && blocks <= IDB_MAX_BOOT_BLOCKS && mb > 0 && - mb * 2048 < geo->total_sectors) + mb * SECTORS_PER_MB < geo->total_sectors) { - sectors = mb * 2048; + idb->boot_blocks = blocks; + idb->sys_sectors = mb * SECTORS_PER_MB; + idb->data_sectors = (data[4] | (data[5] << 8)) * SECTORS_PER_MB; + found = true; } } - return sectors; + return found; } +#if CONFIG_RK27XX_FTL == RK27XX_FTL_SCHEME_A +static uint32_t mount_scheme(const struct idb_info *idb) +{ + struct ftl_a_config config; + uint32_t ret = 0; + + config.sys_sectors = idb->sys_sectors; +#ifdef FTL_ALLOW_WRITE + config.read_only = false; + /* the rk2705 NAND bootloader's generation formats with flag 1; its + * write logic is the same as the standard one's */ + config.alt_format_flag = 1; + config.alt_format_writable = true; +#else + config.read_only = true; + config.alt_format_flag = 1; + config.alt_format_writable = false; +#endif + + if (ftl_a_mount(&config) != FTL_A_OK) + { + ret = 3; + } + else if (ftl_a_capacity(FTL_A_VOL_USER) == 0) + { + ret = 4; + } + return ret; +} +#else +static uint32_t mount_scheme(const struct idb_info *idb) +{ + const struct flash_geometry *geo = flash_get_geometry(); + struct ftl_b_config config; + uint32_t user_base = idb->sys_sectors + idb->data_sectors; + uint32_t ret = 0; + + config.first_block = (uint16_t)(idb->boot_blocks / geo->planes); + config.exch_blocks = SCHEME_B_EXCH_BLOCKS; +#ifdef FTL_ALLOW_WRITE + config.read_only = false; +#else + config.read_only = true; +#endif + + if (ftl_b_mount(&config) != FTL_B_OK) + { + ret = 3; + } + else if (ftl_b_capacity() <= user_base) + { + ret = 4; + } + else + { +#ifdef HAVE_RK27XX_NAND_SYS + vol_base[FTL_DRIVE_SYS] = 0; + vol_size[FTL_DRIVE_SYS] = idb->sys_sectors; +#endif + vol_base[FTL_DRIVE_USER] = user_base; + vol_size[FTL_DRIVE_USER] = ftl_b_capacity() - user_base; + } + return ret; +} +#endif + uint32_t ftl_init(void) { - struct ftl_a_config config; + struct idb_info idb; uint32_t ret = 0; flash_init(); @@ -101,41 +201,24 @@ uint32_t ftl_init(void) { ret = 1; } + else if (!idb_read(&idb)) + { + ret = 2; /* without it USER cannot be told from SYS */ + } else { - config.sys_sectors = idb_sys_sectors(); -#ifdef FTL_ALLOW_WRITE - config.read_only = false; - /* the rk2705 NAND bootloader's generation formats with flag 1; its - * write logic is the same as the standard one's */ - config.alt_format_flag = 1; - config.alt_format_writable = true; -#else - config.read_only = true; - config.alt_format_flag = 1; - config.alt_format_writable = false; -#endif - - if (config.sys_sectors == 0) - { - ret = 2; /* without it USER cannot be told from SYS */ - } - else if (ftl_a_mount(&config) != FTL_A_OK) - { - ret = 3; - } - else if (ftl_a_capacity(FTL_A_VOL_USER) == 0) - { - ret = 4; - } - else - { - ftl_mounted = true; - } + ret = mount_scheme(&idb); + ftl_mounted = ret == 0; } return ret; } +static bool drive_valid(int drive) +{ + return ftl_mounted && drive >= 0 && drive < FTL_NUM_DRIVES; +} + +#if CONFIG_RK27XX_FTL == RK27XX_FTL_SCHEME_A /* The FTL volume behind a drive. SYS is reachable only when exposed. */ static int ftl_volume(int drive) { @@ -152,18 +235,77 @@ static int ftl_volume(int drive) return volume; } -static bool drive_valid(int drive) +static uint32_t drive_sectors(int drive) { - return ftl_mounted && drive >= 0 && drive < FTL_NUM_DRIVES; + return ftl_a_capacity(ftl_volume(drive)); } +static int drive_read(int drive, uint32_t sector, uint32_t count, void *buffer) +{ + return ftl_a_read(ftl_volume(drive), sector, buffer, count); +} + +#ifdef FTL_ALLOW_WRITE +static int drive_write(int drive, uint32_t sector, uint32_t count, + const void *buffer) +{ + return ftl_a_write(ftl_volume(drive), sector, buffer, count); +} +#endif + +static void drive_sync(void) +{ + ftl_a_sync(); +} +#else +static uint32_t drive_sectors(int drive) +{ + return vol_size[drive]; +} + +static bool in_volume(int drive, uint32_t sector, uint32_t count) +{ + return sector < vol_size[drive] && count <= vol_size[drive] - sector; +} + +static int drive_read(int drive, uint32_t sector, uint32_t count, void *buffer) +{ + int ret = 1; + + if (in_volume(drive, sector, count)) + { + ret = ftl_b_read(vol_base[drive] + sector, buffer, count); + } + return ret; +} + +#ifdef FTL_ALLOW_WRITE +static int drive_write(int drive, uint32_t sector, uint32_t count, + const void *buffer) +{ + int ret = 1; + + if (in_volume(drive, sector, count)) + { + ret = ftl_b_write(vol_base[drive] + sector, buffer, count); + } + return ret; +} +#endif + +static void drive_sync(void) +{ + ftl_b_sync(); +} +#endif + uint32_t ftl_get_sectors(int drive) { uint32_t sectors = 0; if (drive_valid(drive)) { - sectors = ftl_a_capacity(ftl_volume(drive)); + sectors = drive_sectors(drive); } return sectors; } @@ -174,7 +316,7 @@ uint32_t ftl_read(int drive, uint32_t sector, uint32_t count, void *buffer) if (drive_valid(drive)) { - ret = ftl_a_read(ftl_volume(drive), sector, buffer, count) ? 2 : 0; + ret = drive_read(drive, sector, count, buffer) ? 2 : 0; } return ret; } @@ -187,7 +329,7 @@ uint32_t ftl_write(int drive, uint32_t sector, uint32_t count, #ifdef FTL_ALLOW_WRITE if (drive_valid(drive)) { - ret = ftl_a_write(ftl_volume(drive), sector, buffer, count) ? 2 : 0; + ret = drive_write(drive, sector, count, buffer) ? 2 : 0; } #else /* refuse rather than pretend: a silent success would let the filesystem @@ -201,7 +343,7 @@ uint32_t ftl_sync(void) { if (ftl_mounted) { - ftl_a_sync(); + drive_sync(); } return 0; }