--- zzzz-none-000/linux-5.4.213/drivers/mtd/mtdcore.c 2022-09-15 10:04:56.000000000 +0000 +++ miami-7690-761/linux-5.4.213/drivers/mtd/mtdcore.c 2024-05-29 11:19:52.000000000 +0000 @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -35,7 +36,9 @@ #include "mtdcore.h" struct backing_dev_info *mtd_bdi; - +#ifdef CONFIG_KASAN +bool nand_device_suspended = false; +#endif #ifdef CONFIG_PM_SLEEP static int mtd_cls_suspend(struct device *dev) @@ -432,9 +435,12 @@ void *cmd) { struct mtd_info *mtd; - mtd = container_of(n, struct mtd_info, reboot_notifier); mtd->_reboot(mtd); +#ifdef CONFIG_KASAN + nand_device_suspended = true; + pr_info("NAND device suspended. Ignoring further read/write requests\n"); +#endif return NOTIFY_DONE; } @@ -543,6 +549,7 @@ } EXPORT_SYMBOL_GPL(mtd_pairing_groups); +#ifdef CONFIG_MTD_SUPPORTS_NVMEM static int mtd_nvmem_reg_read(void *priv, unsigned int offset, void *val, size_t bytes) { @@ -587,6 +594,7 @@ return 0; } +#endif /** * add_mtd_device - register an MTD device @@ -676,10 +684,12 @@ if (error) goto fail_added; +#ifdef CONFIG_MTD_SUPPORTS_NVMEM /* Add the nvmem provider */ error = mtd_nvmem_add(mtd); if (error) goto fail_nvmem_add; +#endif mtd_debugfs_populate(mtd); @@ -698,10 +708,21 @@ of this try_ nonsense, and no bitching about it either. :) */ __module_get(THIS_MODULE); + + if (!strcmp(mtd->name, "rootfs") && + IS_ENABLED(CONFIG_MTD_ROOTFS_ROOT_DEV) && + ROOT_DEV == 0) { + pr_notice("mtd: device %d (%s) set to be root filesystem\n", + mtd->index, mtd->name); + ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, mtd->index); + } + return 0; +#ifdef CONFIG_MTD_SUPPORTS_NVMEM fail_nvmem_add: device_unregister(&mtd->dev); +#endif fail_added: of_node_put(mtd_get_of_node(mtd)); idr_remove(&mtd_idr, i); @@ -744,9 +765,11 @@ } else { debugfs_remove_recursive(mtd->dbg.dfs_dir); +#ifdef CONFIG_MTD_SUPPORTS_NVMEM /* Try to remove the NVMEM provider */ if (mtd->nvmem) nvmem_unregister(mtd->nvmem); +#endif device_unregister(&mtd->dev); @@ -1042,6 +1065,44 @@ } EXPORT_SYMBOL_GPL(get_mtd_device_nm); +/** + * get_mtd_device_by_node - obtain a validated handle for an MTD device + * by of_node + * @of_node: OF node of MTD device to open + * + * This function returns MTD device description structure in case of + * success and an error code in case of failure. + */ +struct mtd_info *get_mtd_device_by_node(const struct device_node *of_node) +{ + int err = -ENODEV; + struct mtd_info *mtd = NULL, *other; + + mutex_lock(&mtd_table_mutex); + + mtd_for_each_device(other) { + if (of_node == other->dev.of_node) { + mtd = other; + break; + } + } + + if (!mtd) + goto out_unlock; + + err = __get_mtd_device(mtd); + if (err) + goto out_unlock; + + mutex_unlock(&mtd_table_mutex); + return mtd; + +out_unlock: + mutex_unlock(&mtd_table_mutex); + return ERR_PTR(err); +} +EXPORT_SYMBOL_GPL(get_mtd_device_by_node); + void put_mtd_device(struct mtd_info *mtd) { mutex_lock(&mtd_table_mutex); @@ -1933,6 +1994,42 @@ mutex_unlock(&mtd_table_mutex); return 0; } + +#if defined(CONFIG_AVM_ENHANCED) +static struct proc_dir_entry *proc_bbt_mtd; +static int mtd_bbt_proc_show(struct seq_file *m, void *v) +{ + struct mtd_info *mtd; + + mutex_lock(&mtd_table_mutex); + mtd_for_each_device(mtd) { + if (mtd->_block_isbad) { + uint64_t i; + unsigned int badblocks=0; + for (i = 0; i < mtd->size; i += mtd->erasesize) { + if (mtd->_block_isbad(mtd, i) && ((badblocks+1)>badblocks) ) + badblocks++; + } + seq_printf(m, "mtd%d: %u bad blocks\n", mtd->index, badblocks); + } + } + mutex_unlock(&mtd_table_mutex); + return 0; +} + +static int mtd_bbt_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, mtd_bbt_proc_show, NULL); +} + +static const struct file_operations mtd_bbt_proc_ops = { + .open = mtd_bbt_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; +#endif /*--- #if #defined(CONFIG_AVM_ENHANCED) ---*/ + #endif /* CONFIG_PROC_FS */ /*====================================================================*/ @@ -1977,6 +2074,10 @@ proc_mtd = proc_create_single("mtd", 0, NULL, mtd_proc_show); +#if defined(CONFIG_AVM_ENHANCED) + proc_bbt_mtd = proc_create("avm/mtd_bbt", 0, NULL, &mtd_bbt_proc_ops); +#endif + ret = init_mtdchar(); if (ret) goto out_procfs; @@ -1988,6 +2089,12 @@ out_procfs: if (proc_mtd) remove_proc_entry("mtd", NULL); + +#if defined(CONFIG_AVM_ENHANCED) + if (proc_bbt_mtd) + remove_proc_entry("mtd_bbt", NULL); +#endif + bdi_put(mtd_bdi); err_bdi: class_unregister(&mtd_class); @@ -2002,6 +2109,12 @@ cleanup_mtdchar(); if (proc_mtd) remove_proc_entry("mtd", NULL); + +#if defined(CONFIG_AVM_ENHANCED) + if (proc_bbt_mtd) + remove_proc_entry("mtd_bbt", NULL); +#endif + class_unregister(&mtd_class); bdi_put(mtd_bdi); idr_destroy(&mtd_idr);