Linux Audio

Check our new training course

Linux BSP development engineering services

Need help to port Linux and bootloaders to your hardware?
Loading...
v6.8
  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}
 28
 29static int is_block_bad(struct mtd_info *mtd, unsigned int ebnum)
 30{
 31	int ret;
 32	loff_t addr = (loff_t)ebnum * mtd->erasesize;
 33
 34	ret = mtd_block_isbad(mtd, addr);
 35	if (ret)
 36		pr_info("block %d is bad\n", ebnum);
 37
 38	return ret;
 39}
 40
 41int mtdtest_scan_for_bad_eraseblocks(struct mtd_info *mtd, unsigned char *bbt,
 42					unsigned int eb, int ebcnt)
 43{
 44	int i, bad = 0;
 45
 46	if (!mtd_can_have_bb(mtd))
 47		return 0;
 48
 49	pr_info("scanning for bad eraseblocks\n");
 50	for (i = 0; i < ebcnt; ++i) {
 51		bbt[i] = is_block_bad(mtd, eb + i) ? 1 : 0;
 52		if (bbt[i])
 53			bad += 1;
 54		cond_resched();
 55	}
 56	pr_info("scanned %d eraseblocks, %d are bad\n", i, bad);
 57
 58	return 0;
 59}
 60
 61int mtdtest_erase_good_eraseblocks(struct mtd_info *mtd, unsigned char *bbt,
 62				unsigned int eb, int ebcnt)
 63{
 64	int err;
 65	unsigned int i;
 66
 67	for (i = 0; i < ebcnt; ++i) {
 68		if (bbt[i])
 69			continue;
 70		err = mtdtest_erase_eraseblock(mtd, eb + i);
 71		if (err)
 72			return err;
 73		cond_resched();
 74	}
 75
 76	return 0;
 77}
 78
 79int mtdtest_read(struct mtd_info *mtd, loff_t addr, size_t size, void *buf)
 80{
 81	size_t read;
 82	int err;
 83
 84	err = mtd_read(mtd, addr, size, &read, buf);
 85	/* Ignore corrected ECC errors */
 86	if (mtd_is_bitflip(err))
 87		err = 0;
 88	if (!err && read != size)
 89		err = -EIO;
 90	if (err)
 91		pr_err("error: read failed at %#llx\n", addr);
 92
 93	return err;
 94}
 95
 96int mtdtest_write(struct mtd_info *mtd, loff_t addr, size_t size,
 97		const void *buf)
 98{
 99	size_t written;
100	int err;
101
102	err = mtd_write(mtd, addr, size, &written, buf);
103	if (!err && written != size)
104		err = -EIO;
105	if (err)
106		pr_err("error: write failed at %#llx\n", addr);
107
108	return err;
109}
v5.4
  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}
 28
 29static int is_block_bad(struct mtd_info *mtd, unsigned int ebnum)
 30{
 31	int ret;
 32	loff_t addr = (loff_t)ebnum * mtd->erasesize;
 33
 34	ret = mtd_block_isbad(mtd, addr);
 35	if (ret)
 36		pr_info("block %d is bad\n", ebnum);
 37
 38	return ret;
 39}
 40
 41int mtdtest_scan_for_bad_eraseblocks(struct mtd_info *mtd, unsigned char *bbt,
 42					unsigned int eb, int ebcnt)
 43{
 44	int i, bad = 0;
 45
 46	if (!mtd_can_have_bb(mtd))
 47		return 0;
 48
 49	pr_info("scanning for bad eraseblocks\n");
 50	for (i = 0; i < ebcnt; ++i) {
 51		bbt[i] = is_block_bad(mtd, eb + i) ? 1 : 0;
 52		if (bbt[i])
 53			bad += 1;
 54		cond_resched();
 55	}
 56	pr_info("scanned %d eraseblocks, %d are bad\n", i, bad);
 57
 58	return 0;
 59}
 60
 61int mtdtest_erase_good_eraseblocks(struct mtd_info *mtd, unsigned char *bbt,
 62				unsigned int eb, int ebcnt)
 63{
 64	int err;
 65	unsigned int i;
 66
 67	for (i = 0; i < ebcnt; ++i) {
 68		if (bbt[i])
 69			continue;
 70		err = mtdtest_erase_eraseblock(mtd, eb + i);
 71		if (err)
 72			return err;
 73		cond_resched();
 74	}
 75
 76	return 0;
 77}
 78
 79int mtdtest_read(struct mtd_info *mtd, loff_t addr, size_t size, void *buf)
 80{
 81	size_t read;
 82	int err;
 83
 84	err = mtd_read(mtd, addr, size, &read, buf);
 85	/* Ignore corrected ECC errors */
 86	if (mtd_is_bitflip(err))
 87		err = 0;
 88	if (!err && read != size)
 89		err = -EIO;
 90	if (err)
 91		pr_err("error: read failed at %#llx\n", addr);
 92
 93	return err;
 94}
 95
 96int mtdtest_write(struct mtd_info *mtd, loff_t addr, size_t size,
 97		const void *buf)
 98{
 99	size_t written;
100	int err;
101
102	err = mtd_write(mtd, addr, size, &written, buf);
103	if (!err && written != size)
104		err = -EIO;
105	if (err)
106		pr_err("error: write failed at %#llx\n", addr);
107
108	return err;
109}