drivers/mtd: Remove bad block management in FTL for devices not needing it

Bad block management and the logical->physical mapping is only needed
with raw NAND type memories, so we can compile that in conditionally,
saving ~600 bytes of flash on a 32-bit arm when NAND is not used.

Signed-off-by: Jukka Laitinen <jukka.laitinen@tii.ae>
This commit is contained in:
Jukka Laitinen 2026-06-02 09:18:13 +03:00 committed by Alin Jerpelea
parent 9e9926317d
commit 9c10bbd04a
2 changed files with 55 additions and 3 deletions

View file

@ -50,6 +50,15 @@ config FTL_READAHEAD
default n
depends on DRVR_READAHEAD
config FTL_BBM
bool "Enable bad block management in the FTL layer"
default y if MTD_NAND
---help---
Enable logical to physical erase-block mapping in the FTL layer for
MTD devices that expose bad blocks via the MTD isbad/markbad methods.
This is needed for devices that require software bad block management.
config MTD_SECT512
bool "512B sector conversion"
default n
@ -1442,6 +1451,7 @@ config MTD_GD5F
bool "SPI-based GD5F nand FLASH"
default n
select SPI
select FTL_BBM
if MTD_GD5F

View file

@ -80,10 +80,12 @@ struct ftl_struct_s
FAR uint8_t *eblock; /* One, in-memory erase block */
int oflags;
/* The nand block map between logic block and physical block */
#ifdef CONFIG_FTL_BBM
/* The block map between logic block and physical block */
FAR off_t *lptable;
off_t lpcount;
#endif
};
/****************************************************************************
@ -133,12 +135,14 @@ static const struct block_operations g_bops =
* Private Functions
****************************************************************************/
#ifdef CONFIG_FTL_BBM
/****************************************************************************
* Name: ftl_init_map
*
* Description: Allocate logical block and physical block mapping table
* space, and scan the entire nand flash device to establish
* the mapping relationship between logical block and physical
* space, and scan the entire MTD device to establish the
* mapping relationship between logical block and physical
* good block.
*
****************************************************************************/
@ -207,6 +211,7 @@ static size_t ftl_get_cblock(FAR struct ftl_struct_s *dev, off_t start,
return count;
}
#endif
/****************************************************************************
* Name: ftl_open
@ -273,11 +278,15 @@ static int ftl_close(FAR struct inode *inode)
static ssize_t ftl_mtd_bread(FAR struct ftl_struct_s *dev, off_t startblock,
size_t nblocks, FAR uint8_t *buffer)
{
#ifdef CONFIG_FTL_BBM
off_t mask = dev->blkper - 1;
size_t nread = nblocks;
#endif
ssize_t ret = OK;
#ifdef CONFIG_FTL_BBM
if (dev->lptable == NULL)
#endif
{
ret = MTD_BREAD(dev->mtd, startblock, nblocks, buffer);
if (ret != nblocks)
@ -289,6 +298,7 @@ static ssize_t ftl_mtd_bread(FAR struct ftl_struct_s *dev, off_t startblock,
return ret;
}
#ifdef CONFIG_FTL_BBM
while (nblocks > 0)
{
off_t startphysicalblock;
@ -324,6 +334,7 @@ static ssize_t ftl_mtd_bread(FAR struct ftl_struct_s *dev, off_t startblock,
}
return nblocks != nread ? nread - nblocks : ret;
#endif
}
/****************************************************************************
@ -339,10 +350,14 @@ static ssize_t ftl_mtd_bread(FAR struct ftl_struct_s *dev, off_t startblock,
static ssize_t ftl_mtd_bwrite(FAR struct ftl_struct_s *dev, off_t startblock,
FAR const uint8_t *buffer)
{
#ifdef CONFIG_FTL_BBM
off_t starteraseblock;
#endif
ssize_t ret;
#ifdef CONFIG_FTL_BBM
if (dev->lptable == NULL)
#endif
{
ret = MTD_BWRITE(dev->mtd, startblock, dev->blkper, buffer);
if (ret != dev->blkper)
@ -354,6 +369,7 @@ static ssize_t ftl_mtd_bwrite(FAR struct ftl_struct_s *dev, off_t startblock,
return ret;
}
#ifdef CONFIG_FTL_BBM
starteraseblock = startblock / dev->blkper;
while (1)
{
@ -372,6 +388,7 @@ static ssize_t ftl_mtd_bwrite(FAR struct ftl_struct_s *dev, off_t startblock,
MTD_MARKBAD(dev->mtd, dev->lptable[starteraseblock]);
ftl_update_map(dev, starteraseblock);
}
#endif
}
/****************************************************************************
@ -389,7 +406,9 @@ static ssize_t ftl_mtd_erase(FAR struct ftl_struct_s *dev, off_t startblock)
{
ssize_t ret;
#ifdef CONFIG_FTL_BBM
if (dev->lptable == NULL)
#endif
{
ret = MTD_ERASE(dev->mtd, startblock, 1);
if (ret < 0 && ret != -ENOSYS)
@ -402,6 +421,7 @@ static ssize_t ftl_mtd_erase(FAR struct ftl_struct_s *dev, off_t startblock)
return OK;
}
#ifdef CONFIG_FTL_BBM
while (1)
{
if (startblock >= dev->lpcount)
@ -418,6 +438,7 @@ static ssize_t ftl_mtd_erase(FAR struct ftl_struct_s *dev, off_t startblock)
MTD_MARKBAD(dev->mtd, dev->lptable[startblock]);
ftl_update_map(dev, startblock);
}
#endif
}
/****************************************************************************
@ -517,7 +538,9 @@ static ssize_t ftl_flush_direct(FAR struct ftl_struct_s *dev,
}
}
#ifdef CONFIG_FTL_BBM
if (dev->lptable == NULL)
#endif
{
ret = MTD_BWRITE(dev->mtd, startblock, count, buffer);
if (ret != count)
@ -527,6 +550,7 @@ static ssize_t ftl_flush_direct(FAR struct ftl_struct_s *dev,
return ret;
}
}
#ifdef CONFIG_FTL_BBM
else
{
if (starteraseblock >= dev->lpcount)
@ -544,6 +568,7 @@ static ssize_t ftl_flush_direct(FAR struct ftl_struct_s *dev,
continue;
}
}
#endif
nblocks -= count;
startblock += count;
@ -567,7 +592,11 @@ static ssize_t ftl_flush(FAR void *priv, FAR const uint8_t *buffer,
int nbytes;
int ret;
#ifdef CONFIG_FTL_BBM
if (dev->mtd->erase == NULL && dev->lptable == NULL)
#else
if (dev->mtd->erase == NULL)
#endif
{
ret = MTD_BWRITE(dev->mtd, startblock, nblocks, buffer);
if (ret != nblocks)
@ -922,6 +951,15 @@ int ftl_initialize_by_path(FAR const char *path, FAR struct mtd_dev_s *mtd,
finfo("path=\"%s\"\n", path);
#ifndef CONFIG_FTL_BBM
/* It is likely a configuration error if the mtd driver implements
* the bad block management, but it is still disabled by the
* configuration.
*/
DEBUGASSERT(mtd->isbad == NULL && mtd->markbad == NULL);
#endif
/* Allocate a FTL device structure */
dev = kmm_zalloc(sizeof(struct ftl_struct_s));
@ -978,6 +1016,7 @@ int ftl_initialize_by_path(FAR const char *path, FAR struct mtd_dev_s *mtd,
}
#endif
#ifdef CONFIG_FTL_BBM
if (MTD_ISBAD(dev->mtd, 0) != -ENOSYS)
{
ret = ftl_init_map(dev);
@ -986,6 +1025,7 @@ int ftl_initialize_by_path(FAR const char *path, FAR struct mtd_dev_s *mtd,
goto out;
}
}
#endif
/* Inode private data is a reference to the FTL device structure */
@ -993,8 +1033,10 @@ int ftl_initialize_by_path(FAR const char *path, FAR struct mtd_dev_s *mtd,
if (ret < 0)
{
ferr("ERROR: register_blockdriver failed: %d\n", -ret);
#ifdef CONFIG_FTL_BBM
kmm_free(dev->lptable);
out:
#endif
#ifdef FTL_HAVE_RWBUFFER
rwb_uninitialize(&dev->rwb);
#endif