23 #include <linux/module.h>
27 #include <linux/slab.h>
28 #include <linux/sched.h>
29 #include <linux/random.h>
31 #define PRINT_PREF KERN_INFO "mtd_speedtest: "
43 static unsigned char *iobuf;
44 static unsigned char *bbt;
52 static void set_random_data(
unsigned char *
buf,
size_t len)
56 for (i = 0; i < len; ++
i)
60 static int erase_eraseblock(
int ebnum)
86 static int multiblock_erase(
int ebnum,
int blocks)
106 "blocks %d\n", ebnum, blocks);
113 static int erase_whole_device(
void)
118 for (i = 0; i < ebcnt; ++
i) {
121 err = erase_eraseblock(i);
129 static int write_eraseblock(
int ebnum)
145 static int write_eraseblock_by_page(
int ebnum)
152 for (i = 0; i < pgcnt; i++) {
153 err =
mtd_write(mtd, addr, pgsize, &written, buf);
154 if (err || written != pgsize) {
168 static int write_eraseblock_by_2pages(
int ebnum)
170 size_t written, sz = pgsize * 2;
171 int i,
n = pgcnt / 2, err = 0;
175 for (i = 0; i <
n; i++) {
176 err =
mtd_write(mtd, addr, sz, &written, buf);
177 if (err || written != sz) {
188 err =
mtd_write(mtd, addr, pgsize, &written, buf);
189 if (err || written != pgsize) {
200 static int read_eraseblock(
int ebnum)
208 if (mtd_is_bitflip(err))
219 static int read_eraseblock_by_page(
int ebnum)
226 for (i = 0; i < pgcnt; i++) {
227 err =
mtd_read(mtd, addr, pgsize, &read, buf);
229 if (mtd_is_bitflip(err))
231 if (err || read != pgsize) {
245 static int read_eraseblock_by_2pages(
int ebnum)
247 size_t read, sz = pgsize * 2;
248 int i, n = pgcnt / 2, err = 0;
252 for (i = 0; i <
n; i++) {
253 err =
mtd_read(mtd, addr, sz, &read, buf);
255 if (mtd_is_bitflip(err))
257 if (err || read != sz) {
268 err =
mtd_read(mtd, addr, pgsize, &read, buf);
270 if (mtd_is_bitflip(err))
272 if (err || read != pgsize) {
283 static int is_block_bad(
int ebnum)
294 static inline void start_timing(
void)
299 static inline void stop_timing(
void)
304 static long calc_speed(
void)
309 ms = (finish.tv_sec -
start.tv_sec) * 1000 +
310 (finish.tv_usec -
start.tv_usec) / 1000;
313 k = goodebcnt * (mtd->
erasesize / 1024) * 1000;
318 static int scan_for_bad_eraseblocks(
void)
328 if (!mtd_can_have_bb(mtd))
332 for (i = 0; i < ebcnt; ++
i) {
333 bbt[
i] = is_block_bad(i) ? 1 : 0;
340 goodebcnt = ebcnt -
bad;
344 static int __init mtd_speedtest_init(
void)
351 printk(
KERN_INFO "=================================================\n");
354 printk(
PRINT_PREF "Please specify a valid mtd-device via module paramter\n");
355 printk(
KERN_CRIT "CAREFUL: This test wipes all data on the specified MTD device!\n");
384 "page size %u, count of eraseblocks %u, pages per "
385 "eraseblock %u, OOB size %u\n",
387 pgsize, ebcnt, pgcnt, mtd->
oobsize);
401 err = scan_for_bad_eraseblocks();
405 err = erase_whole_device();
412 for (i = 0; i < ebcnt; ++
i) {
415 err = write_eraseblock(i);
421 speed = calc_speed();
427 for (i = 0; i < ebcnt; ++
i) {
430 err = read_eraseblock(i);
436 speed = calc_speed();
439 err = erase_whole_device();
446 for (i = 0; i < ebcnt; ++
i) {
449 err = write_eraseblock_by_page(i);
455 speed = calc_speed();
461 for (i = 0; i < ebcnt; ++
i) {
464 err = read_eraseblock_by_page(i);
470 speed = calc_speed();
473 err = erase_whole_device();
480 for (i = 0; i < ebcnt; ++
i) {
483 err = write_eraseblock_by_2pages(i);
489 speed = calc_speed();
495 for (i = 0; i < ebcnt; ++
i) {
498 err = read_eraseblock_by_2pages(i);
504 speed = calc_speed();
510 for (i = 0; i < ebcnt; ++
i) {
513 err = erase_eraseblock(i);
519 speed = calc_speed();
523 for (k = 1; k < 7; k++) {
528 for (i = 0; i < ebcnt; ) {
529 for (j = 0; j < blocks && (i +
j) < ebcnt; j++)
536 err = multiblock_erase(i, j);
543 speed = calc_speed();
554 printk(
KERN_INFO "=================================================\n");
559 static void __exit mtd_speedtest_exit(
void)