Linux Audio

Check our new training course

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}
v3.15
 
  1#define pr_fmt(fmt) "mtd_test: " fmt
  2
  3#include <linux/module.h>
  4#include <linux/sched.h>
  5#include <linux/printk.h>
  6
  7#include "mtd_test.h"
  8
  9int mtdtest_erase_eraseblock(struct mtd_info *mtd, unsigned int ebnum)
 10{
 11	int err;
 12	struct erase_info ei;
 13	loff_t addr = ebnum * mtd->erasesize;
 14
 15	memset(&ei, 0, sizeof(struct erase_info));
 16	ei.mtd  = mtd;
 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	if (ei.state == MTD_ERASE_FAILED) {
 27		pr_info("some erase error occurred at EB %d\n", ebnum);
 28		return -EIO;
 29	}
 30	return 0;
 31}
 32
 33static int is_block_bad(struct mtd_info *mtd, unsigned int ebnum)
 34{
 35	int ret;
 36	loff_t addr = ebnum * mtd->erasesize;
 37
 38	ret = mtd_block_isbad(mtd, addr);
 39	if (ret)
 40		pr_info("block %d is bad\n", ebnum);
 41
 42	return ret;
 43}
 44
 45int mtdtest_scan_for_bad_eraseblocks(struct mtd_info *mtd, unsigned char *bbt,
 46					unsigned int eb, int ebcnt)
 47{
 48	int i, bad = 0;
 49
 50	if (!mtd_can_have_bb(mtd))
 51		return 0;
 52
 53	pr_info("scanning for bad eraseblocks\n");
 54	for (i = 0; i < ebcnt; ++i) {
 55		bbt[i] = is_block_bad(mtd, eb + i) ? 1 : 0;
 56		if (bbt[i])
 57			bad += 1;
 58		cond_resched();
 59	}
 60	pr_info("scanned %d eraseblocks, %d are bad\n", i, bad);
 61
 62	return 0;
 63}
 64
 65int mtdtest_erase_good_eraseblocks(struct mtd_info *mtd, unsigned char *bbt,
 66				unsigned int eb, int ebcnt)
 67{
 68	int err;
 69	unsigned int i;
 70
 71	for (i = 0; i < ebcnt; ++i) {
 72		if (bbt[i])
 73			continue;
 74		err = mtdtest_erase_eraseblock(mtd, eb + i);
 75		if (err)
 76			return err;
 77		cond_resched();
 78	}
 79
 80	return 0;
 81}
 82
 83int mtdtest_read(struct mtd_info *mtd, loff_t addr, size_t size, void *buf)
 84{
 85	size_t read;
 86	int err;
 87
 88	err = mtd_read(mtd, addr, size, &read, buf);
 89	/* Ignore corrected ECC errors */
 90	if (mtd_is_bitflip(err))
 91		err = 0;
 92	if (!err && read != size)
 93		err = -EIO;
 94	if (err)
 95		pr_err("error: read failed at %#llx\n", addr);
 96
 97	return err;
 98}
 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}