mtd: core: expose ooblayout information via debugfs

Add two new debugfs files which allows to determine the OOB layout
used by a given MTD device. This can be useful to verify the current
layout during driver development without adding extra debug code.
The exposed information also makes it easier to analyze NAND dumps
without the need of crawling out the layout from the driver code.

The content of the new debugfs files is similar to this:

    # cat /sys/kernel/debug/mtd/mtd0/ooblayout_ecc
    0      0   49
    1     65   63
    # cat /sys/kernel/debug/mtd/mtd0/ooblayout_free
    0     49   16

Signed-off-by: Gabor Juhos <j4g8y7@gmail.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
This commit is contained in:
Gabor Juhos
2025-08-08 12:13:44 +02:00
committed by Miquel Raynal
parent 0ee8d7616b
commit e3d2faffdd

View File

@@ -384,14 +384,64 @@ EXPORT_SYMBOL_GPL(mtd_check_expert_analysis_mode);
static struct dentry *dfs_dir_mtd;
static int mtd_ooblayout_show(struct seq_file *s, void *p,
int (*iter)(struct mtd_info *, int section,
struct mtd_oob_region *region))
{
struct mtd_info *mtd = s->private;
int section;
for (section = 0;; section++) {
struct mtd_oob_region region;
int err;
err = iter(mtd, section, &region);
if (err) {
if (err == -ERANGE)
break;
return err;
}
seq_printf(s, "%-3d %4u %4u\n", section, region.offset,
region.length);
}
return 0;
}
static int mtd_ooblayout_ecc_show(struct seq_file *s, void *p)
{
return mtd_ooblayout_show(s, p, mtd_ooblayout_ecc);
}
DEFINE_SHOW_ATTRIBUTE(mtd_ooblayout_ecc);
static int mtd_ooblayout_free_show(struct seq_file *s, void *p)
{
return mtd_ooblayout_show(s, p, mtd_ooblayout_free);
}
DEFINE_SHOW_ATTRIBUTE(mtd_ooblayout_free);
static void mtd_debugfs_populate(struct mtd_info *mtd)
{
struct device *dev = &mtd->dev;
struct mtd_oob_region region;
if (IS_ERR_OR_NULL(dfs_dir_mtd))
return;
mtd->dbg.dfs_dir = debugfs_create_dir(dev_name(dev), dfs_dir_mtd);
if (IS_ERR_OR_NULL(mtd->dbg.dfs_dir))
return;
/* Create ooblayout files only if at least one region is present. */
if (mtd_ooblayout_ecc(mtd, 0, &region) == 0)
debugfs_create_file("ooblayout_ecc", 0444, mtd->dbg.dfs_dir,
mtd, &mtd_ooblayout_ecc_fops);
if (mtd_ooblayout_free(mtd, 0, &region) == 0)
debugfs_create_file("ooblayout_free", 0444, mtd->dbg.dfs_dir,
mtd, &mtd_ooblayout_free_fops);
}
#ifndef CONFIG_MMU