23 #include <linux/module.h>
27 #include <linux/slab.h>
28 #include <linux/sched.h>
30 #define PRINT_PREF KERN_INFO "mtd_subpagetest: "
37 static unsigned char *writebuf;
38 static unsigned char *readbuf;
39 static unsigned char *bbt;
46 static unsigned long next = 1;
48 static inline unsigned int simple_rand(
void)
51 return (
unsigned int)((
next / 65536) % 32768);
54 static inline void simple_srand(
unsigned long seed)
59 static void set_random_data(
unsigned char *
buf,
size_t len)
63 for (i = 0; i < len; ++
i)
64 buf[i] = simple_rand();
67 static inline void clear_data(
unsigned char *buf,
size_t len)
72 static int erase_eraseblock(
int ebnum)
98 static int erase_whole_device(
void)
104 for (i = 0; i < ebcnt; ++
i) {
107 err = erase_eraseblock(i);
116 static int write_eraseblock(
int ebnum)
122 set_random_data(writebuf, subpgsize);
123 err =
mtd_write(mtd, addr, subpgsize, &written, writebuf);
124 if (
unlikely(err || written != subpgsize)) {
127 if (written != subpgsize) {
131 return err ? err : -1;
136 set_random_data(writebuf, subpgsize);
137 err =
mtd_write(mtd, addr, subpgsize, &written, writebuf);
138 if (
unlikely(err || written != subpgsize)) {
141 if (written != subpgsize) {
145 return err ? err : -1;
151 static int write_eraseblock2(
int ebnum)
157 for (
k = 1;
k < 33; ++
k) {
158 if (addr + (subpgsize *
k) > (ebnum + 1) * mtd->
erasesize)
160 set_random_data(writebuf, subpgsize * k);
161 err =
mtd_write(mtd, addr, subpgsize * k, &written, writebuf);
162 if (
unlikely(err || written != subpgsize * k)) {
165 if (written != subpgsize) {
171 return err ? err : -1;
173 addr += subpgsize *
k;
179 static void print_subpage(
unsigned char *
p)
183 for (i = 0; i < subpgsize; ) {
184 for (j = 0; i < subpgsize && j < 32; ++
i, ++
j)
190 static int verify_eraseblock(
int ebnum)
196 set_random_data(writebuf, subpgsize);
197 clear_data(readbuf, subpgsize);
198 err =
mtd_read(mtd, addr, subpgsize, &read, readbuf);
199 if (
unlikely(err || read != subpgsize)) {
200 if (mtd_is_bitflip(err) && read == subpgsize) {
207 return err ? err : -1;
214 print_subpage(writebuf);
216 print_subpage(readbuf);
223 set_random_data(writebuf, subpgsize);
224 clear_data(readbuf, subpgsize);
225 err =
mtd_read(mtd, addr, subpgsize, &read, readbuf);
226 if (
unlikely(err || read != subpgsize)) {
227 if (mtd_is_bitflip(err) && read == subpgsize) {
234 return err ? err : -1;
241 print_subpage(writebuf);
243 print_subpage(readbuf);
251 static int verify_eraseblock2(
int ebnum)
257 for (k = 1; k < 33; ++
k) {
258 if (addr + (subpgsize * k) > (ebnum + 1) * mtd->
erasesize)
260 set_random_data(writebuf, subpgsize * k);
261 clear_data(readbuf, subpgsize * k);
262 err =
mtd_read(mtd, addr, subpgsize * k, &read, readbuf);
263 if (
unlikely(err || read != subpgsize * k)) {
264 if (mtd_is_bitflip(err) && read == subpgsize * k) {
270 "%#llx\n", (
long long)addr);
271 return err ? err : -1;
279 addr += subpgsize *
k;
285 static int verify_eraseblock_ff(
int ebnum)
292 memset(writebuf, 0xff, subpgsize);
293 for (j = 0; j < mtd->
erasesize / subpgsize; ++
j) {
294 clear_data(readbuf, subpgsize);
295 err =
mtd_read(mtd, addr, subpgsize, &read, readbuf);
296 if (
unlikely(err || read != subpgsize)) {
297 if (mtd_is_bitflip(err) && read == subpgsize) {
303 "%#llx\n", (
long long)addr);
304 return err ? err : -1;
309 "%#llx\n", (
long long)addr);
318 static int verify_all_eraseblocks_ff(
void)
324 for (i = 0; i < ebcnt; ++
i) {
327 err = verify_eraseblock_ff(i);
338 static int is_block_bad(
int ebnum)
349 static int scan_for_bad_eraseblocks(
void)
360 for (i = 0; i < ebcnt; ++
i) {
361 bbt[
i] = is_block_bad(i) ? 1 : 0;
370 static int __init mtd_subpagetest_init(
void)
377 printk(
KERN_INFO "=================================================\n");
380 printk(
PRINT_PREF "Please specify a valid mtd-device via module paramter\n");
381 printk(
KERN_CRIT "CAREFUL: This test wipes all data on the specified MTD device!\n");
406 "page size %u, subpage size %u, count of eraseblocks %u, "
407 "pages per eraseblock %u, OOB size %u\n",
424 err = scan_for_bad_eraseblocks();
428 err = erase_whole_device();
434 for (i = 0; i < ebcnt; ++
i) {
437 err = write_eraseblock(i);
448 for (i = 0; i < ebcnt; ++
i) {
451 err = verify_eraseblock(i);
460 err = erase_whole_device();
464 err = verify_all_eraseblocks_ff();
471 for (i = 0; i < ebcnt; ++
i) {
474 err = write_eraseblock2(i);
486 for (i = 0; i < ebcnt; ++
i) {
489 err = verify_eraseblock2(i);
498 err = erase_whole_device();
502 err = verify_all_eraseblocks_ff();
515 printk(
KERN_INFO "=================================================\n");
520 static void __exit mtd_subpagetest_exit(
void)