File Index
Files and directories
Sign in
FILE

mtd_test.c

File preview with syntax highlighting.

linux-6.19.14/drivers/mtd/tests/mtd_test.c C
  1// SPDX-License-Identifier: GPL-2.0
  2#define pr_fmt(fmt) "mtd_test: " fmt
  3
  4#include <linux/module.h>
  5#include <linux/sched.h>
  6#include <linux/printk.h>
  7
  8#include "mtd_test.h"
  9
 10int mtdtest_erase_eraseblock(struct mtd_info *mtd, unsigned int ebnum)
 11{
 12	int err;
 13	struct erase_info ei;
 14	loff_t addr = (loff_t)ebnum * mtd->erasesize;
 15
 16	memset(&ei, 0, sizeof(struct erase_info));
 17	ei.addr = addr;
 18	ei.len  = mtd->erasesize;
 19
 20	err = mtd_erase(mtd, &ei);
 21	if (err) {
 22		pr_info("error %d while erasing EB %d\n", err, ebnum);
 23		return err;
 24	}
 25
 26	return 0;
 27}
 28EXPORT_SYMBOL_GPL(mtdtest_erase_eraseblock);
 29
 30static int is_block_bad(struct mtd_info *mtd, unsigned int ebnum)
 31{
 32	int ret;
 33	loff_t addr = (loff_t)ebnum * mtd->erasesize;
 34
 35	ret = mtd_block_isbad(mtd, addr);
 36	if (ret)
 37		pr_info("block %d is bad\n", ebnum);
 38
 39	return ret;
 40}
 41
 42int mtdtest_scan_for_bad_eraseblocks(struct mtd_info *mtd, unsigned char *bbt,
 43					unsigned int eb, int ebcnt)
 44{
 45	int i, bad = 0;
 46
 47	if (!mtd_can_have_bb(mtd))
 48		return 0;
 49
 50	pr_info("scanning for bad eraseblocks\n");
 51	for (i = 0; i < ebcnt; ++i) {
 52		bbt[i] = is_block_bad(mtd, eb + i) ? 1 : 0;
 53		if (bbt[i])
 54			bad += 1;
 55		cond_resched();
 56	}
 57	pr_info("scanned %d eraseblocks, %d are bad\n", i, bad);
 58
 59	return 0;
 60}
 61EXPORT_SYMBOL_GPL(mtdtest_scan_for_bad_eraseblocks);
 62
 63int mtdtest_erase_good_eraseblocks(struct mtd_info *mtd, unsigned char *bbt,
 64				unsigned int eb, int ebcnt)
 65{
 66	int err;
 67	unsigned int i;
 68
 69	for (i = 0; i < ebcnt; ++i) {
 70		if (bbt[i])
 71			continue;
 72		err = mtdtest_erase_eraseblock(mtd, eb + i);
 73		if (err)
 74			return err;
 75		cond_resched();
 76	}
 77
 78	return 0;
 79}
 80EXPORT_SYMBOL_GPL(mtdtest_erase_good_eraseblocks);
 81
 82int mtdtest_read(struct mtd_info *mtd, loff_t addr, size_t size, void *buf)
 83{
 84	size_t read;
 85	int err;
 86
 87	err = mtd_read(mtd, addr, size, &read, buf);
 88	/* Ignore corrected ECC errors */
 89	if (mtd_is_bitflip(err))
 90		err = 0;
 91	if (!err && read != size)
 92		err = -EIO;
 93	if (err)
 94		pr_err("error: read failed at %#llx\n", addr);
 95
 96	return err;
 97}
 98EXPORT_SYMBOL_GPL(mtdtest_read);
 99
100int mtdtest_write(struct mtd_info *mtd, loff_t addr, size_t size,
101		const void *buf)
102{
103	size_t written;
104	int err;
105
106	err = mtd_write(mtd, addr, size, &written, buf);
107	if (!err && written != size)
108		err = -EIO;
109	if (err)
110		pr_err("error: write failed at %#llx\n", addr);
111
112	return err;
113}
114EXPORT_SYMBOL_GPL(mtdtest_write);
115
116MODULE_LICENSE("GPL");
117MODULE_DESCRIPTION("MTD function test helpers");
118MODULE_AUTHOR("Akinobu Mita");
~/ Read-only file preview.