1a995c792SAkinobu Mita /* 2a995c792SAkinobu Mita * Copyright (C) 2006-2008 Nokia Corporation 3a995c792SAkinobu Mita * 4a995c792SAkinobu Mita * This program is free software; you can redistribute it and/or modify it 5a995c792SAkinobu Mita * under the terms of the GNU General Public License version 2 as published by 6a995c792SAkinobu Mita * the Free Software Foundation. 7a995c792SAkinobu Mita * 8a995c792SAkinobu Mita * This program is distributed in the hope that it will be useful, but WITHOUT 9a995c792SAkinobu Mita * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10a995c792SAkinobu Mita * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 11a995c792SAkinobu Mita * more details. 12a995c792SAkinobu Mita * 13a995c792SAkinobu Mita * You should have received a copy of the GNU General Public License along with 14a995c792SAkinobu Mita * this program; see the file COPYING. If not, write to the Free Software 15a995c792SAkinobu Mita * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 16a995c792SAkinobu Mita * 17a995c792SAkinobu Mita * Test page read and write on MTD device. 18a995c792SAkinobu Mita * 19a995c792SAkinobu Mita * Author: Adrian Hunter <ext-adrian.hunter@nokia.com> 20a995c792SAkinobu Mita */ 21a995c792SAkinobu Mita 22a995c792SAkinobu Mita #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 23a995c792SAkinobu Mita 24a995c792SAkinobu Mita #include <asm/div64.h> 25a995c792SAkinobu Mita #include <linux/init.h> 26a995c792SAkinobu Mita #include <linux/module.h> 27a995c792SAkinobu Mita #include <linux/moduleparam.h> 28a995c792SAkinobu Mita #include <linux/err.h> 29a995c792SAkinobu Mita #include <linux/mtd/mtd.h> 30a995c792SAkinobu Mita #include <linux/slab.h> 31a995c792SAkinobu Mita #include <linux/sched.h> 32a995c792SAkinobu Mita #include <linux/random.h> 33a995c792SAkinobu Mita 3466b28183SAkinobu Mita #include "mtd_test.h" 3566b28183SAkinobu Mita 36a995c792SAkinobu Mita static int dev = -EINVAL; 37a995c792SAkinobu Mita module_param(dev, int, S_IRUGO); 38a995c792SAkinobu Mita MODULE_PARM_DESC(dev, "MTD device number to use"); 39a995c792SAkinobu Mita 40a995c792SAkinobu Mita static struct mtd_info *mtd; 41a995c792SAkinobu Mita static unsigned char *twopages; 42a995c792SAkinobu Mita static unsigned char *writebuf; 43a995c792SAkinobu Mita static unsigned char *boundary; 44a995c792SAkinobu Mita static unsigned char *bbt; 45a995c792SAkinobu Mita 46a995c792SAkinobu Mita static int pgsize; 47a995c792SAkinobu Mita static int bufsize; 48a995c792SAkinobu Mita static int ebcnt; 49a995c792SAkinobu Mita static int pgcnt; 50a995c792SAkinobu Mita static int errcnt; 51a995c792SAkinobu Mita static struct rnd_state rnd_state; 52a995c792SAkinobu Mita 53a995c792SAkinobu Mita static int write_eraseblock(int ebnum) 54a995c792SAkinobu Mita { 55a995c792SAkinobu Mita loff_t addr = ebnum * mtd->erasesize; 56a995c792SAkinobu Mita 57a995c792SAkinobu Mita prandom_bytes_state(&rnd_state, writebuf, mtd->erasesize); 58a995c792SAkinobu Mita cond_resched(); 598a9f4aa3SAkinobu Mita return mtdtest_write(mtd, addr, mtd->erasesize, writebuf); 60a995c792SAkinobu Mita } 61a995c792SAkinobu Mita 62a995c792SAkinobu Mita static int verify_eraseblock(int ebnum) 63a995c792SAkinobu Mita { 64a995c792SAkinobu Mita uint32_t j; 65a995c792SAkinobu Mita int err = 0, i; 66a995c792SAkinobu Mita loff_t addr0, addrn; 67a995c792SAkinobu Mita loff_t addr = ebnum * mtd->erasesize; 68a995c792SAkinobu Mita 69a995c792SAkinobu Mita addr0 = 0; 70a995c792SAkinobu Mita for (i = 0; i < ebcnt && bbt[i]; ++i) 71a995c792SAkinobu Mita addr0 += mtd->erasesize; 72a995c792SAkinobu Mita 73a995c792SAkinobu Mita addrn = mtd->size; 74a995c792SAkinobu Mita for (i = 0; i < ebcnt && bbt[ebcnt - i - 1]; ++i) 75a995c792SAkinobu Mita addrn -= mtd->erasesize; 76a995c792SAkinobu Mita 77a995c792SAkinobu Mita prandom_bytes_state(&rnd_state, writebuf, mtd->erasesize); 78a995c792SAkinobu Mita for (j = 0; j < pgcnt - 1; ++j, addr += pgsize) { 79a995c792SAkinobu Mita /* Do a read to set the internal dataRAMs to different data */ 8066b28183SAkinobu Mita err = mtdtest_read(mtd, addr0, bufsize, twopages); 81abc173adSAkinobu Mita if (err) 82a995c792SAkinobu Mita return err; 8366b28183SAkinobu Mita err = mtdtest_read(mtd, addrn - bufsize, bufsize, twopages); 84abc173adSAkinobu Mita if (err) 85a995c792SAkinobu Mita return err; 86a995c792SAkinobu Mita memset(twopages, 0, bufsize); 8766b28183SAkinobu Mita err = mtdtest_read(mtd, addr, bufsize, twopages); 88abc173adSAkinobu Mita if (err) 89a995c792SAkinobu Mita break; 90a995c792SAkinobu Mita if (memcmp(twopages, writebuf + (j * pgsize), bufsize)) { 91a995c792SAkinobu Mita pr_err("error: verify failed at %#llx\n", 92a995c792SAkinobu Mita (long long)addr); 93a995c792SAkinobu Mita errcnt += 1; 94a995c792SAkinobu Mita } 95a995c792SAkinobu Mita } 96a995c792SAkinobu Mita /* Check boundary between eraseblocks */ 97a995c792SAkinobu Mita if (addr <= addrn - pgsize - pgsize && !bbt[ebnum + 1]) { 98a995c792SAkinobu Mita struct rnd_state old_state = rnd_state; 99a995c792SAkinobu Mita 100a995c792SAkinobu Mita /* Do a read to set the internal dataRAMs to different data */ 10166b28183SAkinobu Mita err = mtdtest_read(mtd, addr0, bufsize, twopages); 102abc173adSAkinobu Mita if (err) 103a995c792SAkinobu Mita return err; 10466b28183SAkinobu Mita err = mtdtest_read(mtd, addrn - bufsize, bufsize, twopages); 105abc173adSAkinobu Mita if (err) 106a995c792SAkinobu Mita return err; 107a995c792SAkinobu Mita memset(twopages, 0, bufsize); 10866b28183SAkinobu Mita err = mtdtest_read(mtd, addr, bufsize, twopages); 109abc173adSAkinobu Mita if (err) 110a995c792SAkinobu Mita return err; 111a995c792SAkinobu Mita memcpy(boundary, writebuf + mtd->erasesize - pgsize, pgsize); 112a995c792SAkinobu Mita prandom_bytes_state(&rnd_state, boundary + pgsize, pgsize); 113a995c792SAkinobu Mita if (memcmp(twopages, boundary, bufsize)) { 114a995c792SAkinobu Mita pr_err("error: verify failed at %#llx\n", 115a995c792SAkinobu Mita (long long)addr); 116a995c792SAkinobu Mita errcnt += 1; 117a995c792SAkinobu Mita } 118a995c792SAkinobu Mita rnd_state = old_state; 119a995c792SAkinobu Mita } 120a995c792SAkinobu Mita return err; 121a995c792SAkinobu Mita } 122a995c792SAkinobu Mita 123a995c792SAkinobu Mita static int crosstest(void) 124a995c792SAkinobu Mita { 125a995c792SAkinobu Mita int err = 0, i; 126a995c792SAkinobu Mita loff_t addr, addr0, addrn; 127a995c792SAkinobu Mita unsigned char *pp1, *pp2, *pp3, *pp4; 128a995c792SAkinobu Mita 129a995c792SAkinobu Mita pr_info("crosstest\n"); 130a995c792SAkinobu Mita pp1 = kmalloc(pgsize * 4, GFP_KERNEL); 131a995c792SAkinobu Mita if (!pp1) 132a995c792SAkinobu Mita return -ENOMEM; 133a995c792SAkinobu Mita pp2 = pp1 + pgsize; 134a995c792SAkinobu Mita pp3 = pp2 + pgsize; 135a995c792SAkinobu Mita pp4 = pp3 + pgsize; 136a995c792SAkinobu Mita memset(pp1, 0, pgsize * 4); 137a995c792SAkinobu Mita 138a995c792SAkinobu Mita addr0 = 0; 139a995c792SAkinobu Mita for (i = 0; i < ebcnt && bbt[i]; ++i) 140a995c792SAkinobu Mita addr0 += mtd->erasesize; 141a995c792SAkinobu Mita 142a995c792SAkinobu Mita addrn = mtd->size; 143a995c792SAkinobu Mita for (i = 0; i < ebcnt && bbt[ebcnt - i - 1]; ++i) 144a995c792SAkinobu Mita addrn -= mtd->erasesize; 145a995c792SAkinobu Mita 146a995c792SAkinobu Mita /* Read 2nd-to-last page to pp1 */ 147a995c792SAkinobu Mita addr = addrn - pgsize - pgsize; 14866b28183SAkinobu Mita err = mtdtest_read(mtd, addr, pgsize, pp1); 14966b28183SAkinobu Mita if (err) { 150a995c792SAkinobu Mita kfree(pp1); 151a995c792SAkinobu Mita return err; 152a995c792SAkinobu Mita } 153a995c792SAkinobu Mita 154a995c792SAkinobu Mita /* Read 3rd-to-last page to pp1 */ 155a995c792SAkinobu Mita addr = addrn - pgsize - pgsize - pgsize; 15666b28183SAkinobu Mita err = mtdtest_read(mtd, addr, pgsize, pp1); 15766b28183SAkinobu Mita if (err) { 158a995c792SAkinobu Mita kfree(pp1); 159a995c792SAkinobu Mita return err; 160a995c792SAkinobu Mita } 161a995c792SAkinobu Mita 162a995c792SAkinobu Mita /* Read first page to pp2 */ 163a995c792SAkinobu Mita addr = addr0; 164a995c792SAkinobu Mita pr_info("reading page at %#llx\n", (long long)addr); 16566b28183SAkinobu Mita err = mtdtest_read(mtd, addr, pgsize, pp2); 16666b28183SAkinobu Mita if (err) { 167a995c792SAkinobu Mita kfree(pp1); 168a995c792SAkinobu Mita return err; 169a995c792SAkinobu Mita } 170a995c792SAkinobu Mita 171a995c792SAkinobu Mita /* Read last page to pp3 */ 172a995c792SAkinobu Mita addr = addrn - pgsize; 173a995c792SAkinobu Mita pr_info("reading page at %#llx\n", (long long)addr); 17466b28183SAkinobu Mita err = mtdtest_read(mtd, addr, pgsize, pp3); 17566b28183SAkinobu Mita if (err) { 176a995c792SAkinobu Mita kfree(pp1); 177a995c792SAkinobu Mita return err; 178a995c792SAkinobu Mita } 179a995c792SAkinobu Mita 180a995c792SAkinobu Mita /* Read first page again to pp4 */ 181a995c792SAkinobu Mita addr = addr0; 182a995c792SAkinobu Mita pr_info("reading page at %#llx\n", (long long)addr); 18366b28183SAkinobu Mita err = mtdtest_read(mtd, addr, pgsize, pp4); 18466b28183SAkinobu Mita if (err) { 185a995c792SAkinobu Mita kfree(pp1); 186a995c792SAkinobu Mita return err; 187a995c792SAkinobu Mita } 188a995c792SAkinobu Mita 189a995c792SAkinobu Mita /* pp2 and pp4 should be the same */ 190a995c792SAkinobu Mita pr_info("verifying pages read at %#llx match\n", 191a995c792SAkinobu Mita (long long)addr0); 192a995c792SAkinobu Mita if (memcmp(pp2, pp4, pgsize)) { 193a995c792SAkinobu Mita pr_err("verify failed!\n"); 194a995c792SAkinobu Mita errcnt += 1; 195a995c792SAkinobu Mita } else if (!err) 196a995c792SAkinobu Mita pr_info("crosstest ok\n"); 197a995c792SAkinobu Mita kfree(pp1); 198a995c792SAkinobu Mita return err; 199a995c792SAkinobu Mita } 200a995c792SAkinobu Mita 201a995c792SAkinobu Mita static int erasecrosstest(void) 202a995c792SAkinobu Mita { 203a995c792SAkinobu Mita int err = 0, i, ebnum, ebnum2; 204a995c792SAkinobu Mita loff_t addr0; 205a995c792SAkinobu Mita char *readbuf = twopages; 206a995c792SAkinobu Mita 207a995c792SAkinobu Mita pr_info("erasecrosstest\n"); 208a995c792SAkinobu Mita 209a995c792SAkinobu Mita ebnum = 0; 210a995c792SAkinobu Mita addr0 = 0; 211a995c792SAkinobu Mita for (i = 0; i < ebcnt && bbt[i]; ++i) { 212a995c792SAkinobu Mita addr0 += mtd->erasesize; 213a995c792SAkinobu Mita ebnum += 1; 214a995c792SAkinobu Mita } 215a995c792SAkinobu Mita 216a995c792SAkinobu Mita ebnum2 = ebcnt - 1; 217a995c792SAkinobu Mita while (ebnum2 && bbt[ebnum2]) 218a995c792SAkinobu Mita ebnum2 -= 1; 219a995c792SAkinobu Mita 220a995c792SAkinobu Mita pr_info("erasing block %d\n", ebnum); 22166b28183SAkinobu Mita err = mtdtest_erase_eraseblock(mtd, ebnum); 222a995c792SAkinobu Mita if (err) 223a995c792SAkinobu Mita return err; 224a995c792SAkinobu Mita 225a995c792SAkinobu Mita pr_info("writing 1st page of block %d\n", ebnum); 226a995c792SAkinobu Mita prandom_bytes_state(&rnd_state, writebuf, pgsize); 227a995c792SAkinobu Mita strcpy(writebuf, "There is no data like this!"); 22866b28183SAkinobu Mita err = mtdtest_write(mtd, addr0, pgsize, writebuf); 2298a9f4aa3SAkinobu Mita if (err) 23066b28183SAkinobu Mita return err; 231a995c792SAkinobu Mita 232a995c792SAkinobu Mita pr_info("reading 1st page of block %d\n", ebnum); 233a995c792SAkinobu Mita memset(readbuf, 0, pgsize); 23466b28183SAkinobu Mita err = mtdtest_read(mtd, addr0, pgsize, readbuf); 235abc173adSAkinobu Mita if (err) 23666b28183SAkinobu Mita return err; 237a995c792SAkinobu Mita 238a995c792SAkinobu Mita pr_info("verifying 1st page of block %d\n", ebnum); 239a995c792SAkinobu Mita if (memcmp(writebuf, readbuf, pgsize)) { 240a995c792SAkinobu Mita pr_err("verify failed!\n"); 241a995c792SAkinobu Mita errcnt += 1; 242a995c792SAkinobu Mita return -1; 243a995c792SAkinobu Mita } 244a995c792SAkinobu Mita 245a995c792SAkinobu Mita pr_info("erasing block %d\n", ebnum); 24666b28183SAkinobu Mita err = mtdtest_erase_eraseblock(mtd, ebnum); 247a995c792SAkinobu Mita if (err) 248a995c792SAkinobu Mita return err; 249a995c792SAkinobu Mita 250a995c792SAkinobu Mita pr_info("writing 1st page of block %d\n", ebnum); 251a995c792SAkinobu Mita prandom_bytes_state(&rnd_state, writebuf, pgsize); 252a995c792SAkinobu Mita strcpy(writebuf, "There is no data like this!"); 25366b28183SAkinobu Mita err = mtdtest_write(mtd, addr0, pgsize, writebuf); 2548a9f4aa3SAkinobu Mita if (err) 25566b28183SAkinobu Mita return err; 256a995c792SAkinobu Mita 257a995c792SAkinobu Mita pr_info("erasing block %d\n", ebnum2); 25866b28183SAkinobu Mita err = mtdtest_erase_eraseblock(mtd, ebnum2); 259a995c792SAkinobu Mita if (err) 260a995c792SAkinobu Mita return err; 261a995c792SAkinobu Mita 262a995c792SAkinobu Mita pr_info("reading 1st page of block %d\n", ebnum); 263a995c792SAkinobu Mita memset(readbuf, 0, pgsize); 26466b28183SAkinobu Mita err = mtdtest_read(mtd, addr0, pgsize, readbuf); 265abc173adSAkinobu Mita if (err) 26666b28183SAkinobu Mita return err; 267a995c792SAkinobu Mita 268a995c792SAkinobu Mita pr_info("verifying 1st page of block %d\n", ebnum); 269a995c792SAkinobu Mita if (memcmp(writebuf, readbuf, pgsize)) { 270a995c792SAkinobu Mita pr_err("verify failed!\n"); 271a995c792SAkinobu Mita errcnt += 1; 272a995c792SAkinobu Mita return -1; 273a995c792SAkinobu Mita } 274a995c792SAkinobu Mita 275a995c792SAkinobu Mita if (!err) 276a995c792SAkinobu Mita pr_info("erasecrosstest ok\n"); 277a995c792SAkinobu Mita return err; 278a995c792SAkinobu Mita } 279a995c792SAkinobu Mita 280a995c792SAkinobu Mita static int erasetest(void) 281a995c792SAkinobu Mita { 282a995c792SAkinobu Mita int err = 0, i, ebnum, ok = 1; 283a995c792SAkinobu Mita loff_t addr0; 284a995c792SAkinobu Mita 285a995c792SAkinobu Mita pr_info("erasetest\n"); 286a995c792SAkinobu Mita 287a995c792SAkinobu Mita ebnum = 0; 288a995c792SAkinobu Mita addr0 = 0; 289a995c792SAkinobu Mita for (i = 0; i < ebcnt && bbt[i]; ++i) { 290a995c792SAkinobu Mita addr0 += mtd->erasesize; 291a995c792SAkinobu Mita ebnum += 1; 292a995c792SAkinobu Mita } 293a995c792SAkinobu Mita 294a995c792SAkinobu Mita pr_info("erasing block %d\n", ebnum); 29566b28183SAkinobu Mita err = mtdtest_erase_eraseblock(mtd, ebnum); 296a995c792SAkinobu Mita if (err) 297a995c792SAkinobu Mita return err; 298a995c792SAkinobu Mita 299a995c792SAkinobu Mita pr_info("writing 1st page of block %d\n", ebnum); 300a995c792SAkinobu Mita prandom_bytes_state(&rnd_state, writebuf, pgsize); 30166b28183SAkinobu Mita err = mtdtest_write(mtd, addr0, pgsize, writebuf); 3028a9f4aa3SAkinobu Mita if (err) 30366b28183SAkinobu Mita return err; 304a995c792SAkinobu Mita 305a995c792SAkinobu Mita pr_info("erasing block %d\n", ebnum); 30666b28183SAkinobu Mita err = mtdtest_erase_eraseblock(mtd, ebnum); 307a995c792SAkinobu Mita if (err) 308a995c792SAkinobu Mita return err; 309a995c792SAkinobu Mita 310a995c792SAkinobu Mita pr_info("reading 1st page of block %d\n", ebnum); 31166b28183SAkinobu Mita err = mtdtest_read(mtd, addr0, pgsize, twopages); 312abc173adSAkinobu Mita if (err) 31366b28183SAkinobu Mita return err; 314a995c792SAkinobu Mita 315a995c792SAkinobu Mita pr_info("verifying 1st page of block %d is all 0xff\n", 316a995c792SAkinobu Mita ebnum); 317a995c792SAkinobu Mita for (i = 0; i < pgsize; ++i) 318a995c792SAkinobu Mita if (twopages[i] != 0xff) { 319a995c792SAkinobu Mita pr_err("verifying all 0xff failed at %d\n", 320a995c792SAkinobu Mita i); 321a995c792SAkinobu Mita errcnt += 1; 322a995c792SAkinobu Mita ok = 0; 323a995c792SAkinobu Mita break; 324a995c792SAkinobu Mita } 325a995c792SAkinobu Mita 326a995c792SAkinobu Mita if (ok && !err) 327a995c792SAkinobu Mita pr_info("erasetest ok\n"); 328a995c792SAkinobu Mita 329a995c792SAkinobu Mita return err; 330a995c792SAkinobu Mita } 331a995c792SAkinobu Mita 332a995c792SAkinobu Mita static int __init mtd_pagetest_init(void) 333a995c792SAkinobu Mita { 334a995c792SAkinobu Mita int err = 0; 335a995c792SAkinobu Mita uint64_t tmp; 336a995c792SAkinobu Mita uint32_t i; 337a995c792SAkinobu Mita 338a995c792SAkinobu Mita printk(KERN_INFO "\n"); 339a995c792SAkinobu Mita printk(KERN_INFO "=================================================\n"); 340a995c792SAkinobu Mita 341a995c792SAkinobu Mita if (dev < 0) { 342a995c792SAkinobu Mita pr_info("Please specify a valid mtd-device via module parameter\n"); 343a995c792SAkinobu Mita pr_crit("CAREFUL: This test wipes all data on the specified MTD device!\n"); 344a995c792SAkinobu Mita return -EINVAL; 345a995c792SAkinobu Mita } 346a995c792SAkinobu Mita 347a995c792SAkinobu Mita pr_info("MTD device: %d\n", dev); 348a995c792SAkinobu Mita 349a995c792SAkinobu Mita mtd = get_mtd_device(NULL, dev); 350a995c792SAkinobu Mita if (IS_ERR(mtd)) { 351a995c792SAkinobu Mita err = PTR_ERR(mtd); 352a995c792SAkinobu Mita pr_err("error: cannot get MTD device\n"); 353a995c792SAkinobu Mita return err; 354a995c792SAkinobu Mita } 355a995c792SAkinobu Mita 356818b9739SHuang Shijie if (!mtd_type_is_nand(mtd)) { 357a995c792SAkinobu Mita pr_info("this test requires NAND flash\n"); 358a995c792SAkinobu Mita goto out; 359a995c792SAkinobu Mita } 360a995c792SAkinobu Mita 361a995c792SAkinobu Mita tmp = mtd->size; 362a995c792SAkinobu Mita do_div(tmp, mtd->erasesize); 363a995c792SAkinobu Mita ebcnt = tmp; 364a995c792SAkinobu Mita pgcnt = mtd->erasesize / mtd->writesize; 365a995c792SAkinobu Mita pgsize = mtd->writesize; 366a995c792SAkinobu Mita 367a995c792SAkinobu Mita pr_info("MTD device size %llu, eraseblock size %u, " 368a995c792SAkinobu Mita "page size %u, count of eraseblocks %u, pages per " 369a995c792SAkinobu Mita "eraseblock %u, OOB size %u\n", 370a995c792SAkinobu Mita (unsigned long long)mtd->size, mtd->erasesize, 371a995c792SAkinobu Mita pgsize, ebcnt, pgcnt, mtd->oobsize); 372a995c792SAkinobu Mita 373a995c792SAkinobu Mita err = -ENOMEM; 374a995c792SAkinobu Mita bufsize = pgsize * 2; 375a995c792SAkinobu Mita writebuf = kmalloc(mtd->erasesize, GFP_KERNEL); 376a995c792SAkinobu Mita if (!writebuf) 377a995c792SAkinobu Mita goto out; 378a995c792SAkinobu Mita twopages = kmalloc(bufsize, GFP_KERNEL); 379a995c792SAkinobu Mita if (!twopages) 380a995c792SAkinobu Mita goto out; 381a995c792SAkinobu Mita boundary = kmalloc(bufsize, GFP_KERNEL); 382a995c792SAkinobu Mita if (!boundary) 383a995c792SAkinobu Mita goto out; 384a995c792SAkinobu Mita 38566b28183SAkinobu Mita bbt = kzalloc(ebcnt, GFP_KERNEL); 38666b28183SAkinobu Mita if (!bbt) 38766b28183SAkinobu Mita goto out; 38866b28183SAkinobu Mita err = mtdtest_scan_for_bad_eraseblocks(mtd, bbt, 0, ebcnt); 389a995c792SAkinobu Mita if (err) 390a995c792SAkinobu Mita goto out; 391a995c792SAkinobu Mita 392a995c792SAkinobu Mita /* Erase all eraseblocks */ 393a995c792SAkinobu Mita pr_info("erasing whole device\n"); 39466b28183SAkinobu Mita err = mtdtest_erase_good_eraseblocks(mtd, bbt, 0, ebcnt); 395a995c792SAkinobu Mita if (err) 396a995c792SAkinobu Mita goto out; 39766b28183SAkinobu Mita pr_info("erased %u eraseblocks\n", ebcnt); 398a995c792SAkinobu Mita 399a995c792SAkinobu Mita /* Write all eraseblocks */ 400a995c792SAkinobu Mita prandom_seed_state(&rnd_state, 1); 401a995c792SAkinobu Mita pr_info("writing whole device\n"); 402a995c792SAkinobu Mita for (i = 0; i < ebcnt; ++i) { 403a995c792SAkinobu Mita if (bbt[i]) 404a995c792SAkinobu Mita continue; 405a995c792SAkinobu Mita err = write_eraseblock(i); 406a995c792SAkinobu Mita if (err) 407a995c792SAkinobu Mita goto out; 408a995c792SAkinobu Mita if (i % 256 == 0) 409a995c792SAkinobu Mita pr_info("written up to eraseblock %u\n", i); 410a995c792SAkinobu Mita cond_resched(); 411a995c792SAkinobu Mita } 412a995c792SAkinobu Mita pr_info("written %u eraseblocks\n", i); 413a995c792SAkinobu Mita 414a995c792SAkinobu Mita /* Check all eraseblocks */ 415a995c792SAkinobu Mita prandom_seed_state(&rnd_state, 1); 416a995c792SAkinobu Mita pr_info("verifying all eraseblocks\n"); 417a995c792SAkinobu Mita for (i = 0; i < ebcnt; ++i) { 418a995c792SAkinobu Mita if (bbt[i]) 419a995c792SAkinobu Mita continue; 420a995c792SAkinobu Mita err = verify_eraseblock(i); 421a995c792SAkinobu Mita if (err) 422a995c792SAkinobu Mita goto out; 423a995c792SAkinobu Mita if (i % 256 == 0) 424a995c792SAkinobu Mita pr_info("verified up to eraseblock %u\n", i); 425a995c792SAkinobu Mita cond_resched(); 426a995c792SAkinobu Mita } 427a995c792SAkinobu Mita pr_info("verified %u eraseblocks\n", i); 428a995c792SAkinobu Mita 429a995c792SAkinobu Mita err = crosstest(); 430a995c792SAkinobu Mita if (err) 431a995c792SAkinobu Mita goto out; 432a995c792SAkinobu Mita 433a995c792SAkinobu Mita err = erasecrosstest(); 434a995c792SAkinobu Mita if (err) 435a995c792SAkinobu Mita goto out; 436a995c792SAkinobu Mita 437a995c792SAkinobu Mita err = erasetest(); 438a995c792SAkinobu Mita if (err) 439a995c792SAkinobu Mita goto out; 440a995c792SAkinobu Mita 441a995c792SAkinobu Mita pr_info("finished with %d errors\n", errcnt); 442a995c792SAkinobu Mita out: 443a995c792SAkinobu Mita 444a995c792SAkinobu Mita kfree(bbt); 445a995c792SAkinobu Mita kfree(boundary); 446a995c792SAkinobu Mita kfree(twopages); 447a995c792SAkinobu Mita kfree(writebuf); 448a995c792SAkinobu Mita put_mtd_device(mtd); 449a995c792SAkinobu Mita if (err) 450a995c792SAkinobu Mita pr_info("error %d occurred\n", err); 451a995c792SAkinobu Mita printk(KERN_INFO "=================================================\n"); 452a995c792SAkinobu Mita return err; 453a995c792SAkinobu Mita } 454a995c792SAkinobu Mita module_init(mtd_pagetest_init); 455a995c792SAkinobu Mita 456a995c792SAkinobu Mita static void __exit mtd_pagetest_exit(void) 457a995c792SAkinobu Mita { 458a995c792SAkinobu Mita return; 459a995c792SAkinobu Mita } 460a995c792SAkinobu Mita module_exit(mtd_pagetest_exit); 461a995c792SAkinobu Mita 462a995c792SAkinobu Mita MODULE_DESCRIPTION("NAND page test"); 463a995c792SAkinobu Mita MODULE_AUTHOR("Adrian Hunter"); 464a995c792SAkinobu Mita MODULE_LICENSE("GPL"); 465