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 { 551001ff7aSBrian Norris loff_t addr = (loff_t)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; 671001ff7aSBrian Norris loff_t addr = (loff_t)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"); 1306396bb22SKees Cook pp1 = kcalloc(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 137a995c792SAkinobu Mita addr0 = 0; 138a995c792SAkinobu Mita for (i = 0; i < ebcnt && bbt[i]; ++i) 139a995c792SAkinobu Mita addr0 += mtd->erasesize; 140a995c792SAkinobu Mita 141a995c792SAkinobu Mita addrn = mtd->size; 142a995c792SAkinobu Mita for (i = 0; i < ebcnt && bbt[ebcnt - i - 1]; ++i) 143a995c792SAkinobu Mita addrn -= mtd->erasesize; 144a995c792SAkinobu Mita 145a995c792SAkinobu Mita /* Read 2nd-to-last page to pp1 */ 146a995c792SAkinobu Mita addr = addrn - pgsize - pgsize; 14766b28183SAkinobu Mita err = mtdtest_read(mtd, addr, pgsize, pp1); 14866b28183SAkinobu Mita if (err) { 149a995c792SAkinobu Mita kfree(pp1); 150a995c792SAkinobu Mita return err; 151a995c792SAkinobu Mita } 152a995c792SAkinobu Mita 153a995c792SAkinobu Mita /* Read 3rd-to-last page to pp1 */ 154a995c792SAkinobu Mita addr = addrn - pgsize - pgsize - pgsize; 15566b28183SAkinobu Mita err = mtdtest_read(mtd, addr, pgsize, pp1); 15666b28183SAkinobu Mita if (err) { 157a995c792SAkinobu Mita kfree(pp1); 158a995c792SAkinobu Mita return err; 159a995c792SAkinobu Mita } 160a995c792SAkinobu Mita 161a995c792SAkinobu Mita /* Read first page to pp2 */ 162a995c792SAkinobu Mita addr = addr0; 163a995c792SAkinobu Mita pr_info("reading page at %#llx\n", (long long)addr); 16466b28183SAkinobu Mita err = mtdtest_read(mtd, addr, pgsize, pp2); 16566b28183SAkinobu Mita if (err) { 166a995c792SAkinobu Mita kfree(pp1); 167a995c792SAkinobu Mita return err; 168a995c792SAkinobu Mita } 169a995c792SAkinobu Mita 170a995c792SAkinobu Mita /* Read last page to pp3 */ 171a995c792SAkinobu Mita addr = addrn - pgsize; 172a995c792SAkinobu Mita pr_info("reading page at %#llx\n", (long long)addr); 17366b28183SAkinobu Mita err = mtdtest_read(mtd, addr, pgsize, pp3); 17466b28183SAkinobu Mita if (err) { 175a995c792SAkinobu Mita kfree(pp1); 176a995c792SAkinobu Mita return err; 177a995c792SAkinobu Mita } 178a995c792SAkinobu Mita 179a995c792SAkinobu Mita /* Read first page again to pp4 */ 180a995c792SAkinobu Mita addr = addr0; 181a995c792SAkinobu Mita pr_info("reading page at %#llx\n", (long long)addr); 18266b28183SAkinobu Mita err = mtdtest_read(mtd, addr, pgsize, pp4); 18366b28183SAkinobu Mita if (err) { 184a995c792SAkinobu Mita kfree(pp1); 185a995c792SAkinobu Mita return err; 186a995c792SAkinobu Mita } 187a995c792SAkinobu Mita 188a995c792SAkinobu Mita /* pp2 and pp4 should be the same */ 189a995c792SAkinobu Mita pr_info("verifying pages read at %#llx match\n", 190a995c792SAkinobu Mita (long long)addr0); 191a995c792SAkinobu Mita if (memcmp(pp2, pp4, pgsize)) { 192a995c792SAkinobu Mita pr_err("verify failed!\n"); 193a995c792SAkinobu Mita errcnt += 1; 194a995c792SAkinobu Mita } else if (!err) 195a995c792SAkinobu Mita pr_info("crosstest ok\n"); 196a995c792SAkinobu Mita kfree(pp1); 197a995c792SAkinobu Mita return err; 198a995c792SAkinobu Mita } 199a995c792SAkinobu Mita 200a995c792SAkinobu Mita static int erasecrosstest(void) 201a995c792SAkinobu Mita { 202a995c792SAkinobu Mita int err = 0, i, ebnum, ebnum2; 203a995c792SAkinobu Mita loff_t addr0; 204a995c792SAkinobu Mita char *readbuf = twopages; 205a995c792SAkinobu Mita 206a995c792SAkinobu Mita pr_info("erasecrosstest\n"); 207a995c792SAkinobu Mita 208a995c792SAkinobu Mita ebnum = 0; 209a995c792SAkinobu Mita addr0 = 0; 210a995c792SAkinobu Mita for (i = 0; i < ebcnt && bbt[i]; ++i) { 211a995c792SAkinobu Mita addr0 += mtd->erasesize; 212a995c792SAkinobu Mita ebnum += 1; 213a995c792SAkinobu Mita } 214a995c792SAkinobu Mita 215a995c792SAkinobu Mita ebnum2 = ebcnt - 1; 216a995c792SAkinobu Mita while (ebnum2 && bbt[ebnum2]) 217a995c792SAkinobu Mita ebnum2 -= 1; 218a995c792SAkinobu Mita 219a995c792SAkinobu Mita pr_info("erasing block %d\n", ebnum); 22066b28183SAkinobu Mita err = mtdtest_erase_eraseblock(mtd, ebnum); 221a995c792SAkinobu Mita if (err) 222a995c792SAkinobu Mita return err; 223a995c792SAkinobu Mita 224a995c792SAkinobu Mita pr_info("writing 1st page of block %d\n", ebnum); 225a995c792SAkinobu Mita prandom_bytes_state(&rnd_state, writebuf, pgsize); 226a995c792SAkinobu Mita strcpy(writebuf, "There is no data like this!"); 22766b28183SAkinobu Mita err = mtdtest_write(mtd, addr0, pgsize, writebuf); 2288a9f4aa3SAkinobu Mita if (err) 22966b28183SAkinobu Mita return err; 230a995c792SAkinobu Mita 231a995c792SAkinobu Mita pr_info("reading 1st page of block %d\n", ebnum); 232a995c792SAkinobu Mita memset(readbuf, 0, pgsize); 23366b28183SAkinobu Mita err = mtdtest_read(mtd, addr0, pgsize, readbuf); 234abc173adSAkinobu Mita if (err) 23566b28183SAkinobu Mita return err; 236a995c792SAkinobu Mita 237a995c792SAkinobu Mita pr_info("verifying 1st page of block %d\n", ebnum); 238a995c792SAkinobu Mita if (memcmp(writebuf, readbuf, pgsize)) { 239a995c792SAkinobu Mita pr_err("verify failed!\n"); 240a995c792SAkinobu Mita errcnt += 1; 241a995c792SAkinobu Mita return -1; 242a995c792SAkinobu Mita } 243a995c792SAkinobu Mita 244a995c792SAkinobu Mita pr_info("erasing block %d\n", ebnum); 24566b28183SAkinobu Mita err = mtdtest_erase_eraseblock(mtd, ebnum); 246a995c792SAkinobu Mita if (err) 247a995c792SAkinobu Mita return err; 248a995c792SAkinobu Mita 249a995c792SAkinobu Mita pr_info("writing 1st page of block %d\n", ebnum); 250a995c792SAkinobu Mita prandom_bytes_state(&rnd_state, writebuf, pgsize); 251a995c792SAkinobu Mita strcpy(writebuf, "There is no data like this!"); 25266b28183SAkinobu Mita err = mtdtest_write(mtd, addr0, pgsize, writebuf); 2538a9f4aa3SAkinobu Mita if (err) 25466b28183SAkinobu Mita return err; 255a995c792SAkinobu Mita 256a995c792SAkinobu Mita pr_info("erasing block %d\n", ebnum2); 25766b28183SAkinobu Mita err = mtdtest_erase_eraseblock(mtd, ebnum2); 258a995c792SAkinobu Mita if (err) 259a995c792SAkinobu Mita return err; 260a995c792SAkinobu Mita 261a995c792SAkinobu Mita pr_info("reading 1st page of block %d\n", ebnum); 262a995c792SAkinobu Mita memset(readbuf, 0, pgsize); 26366b28183SAkinobu Mita err = mtdtest_read(mtd, addr0, pgsize, readbuf); 264abc173adSAkinobu Mita if (err) 26566b28183SAkinobu Mita return err; 266a995c792SAkinobu Mita 267a995c792SAkinobu Mita pr_info("verifying 1st page of block %d\n", ebnum); 268a995c792SAkinobu Mita if (memcmp(writebuf, readbuf, pgsize)) { 269a995c792SAkinobu Mita pr_err("verify failed!\n"); 270a995c792SAkinobu Mita errcnt += 1; 271a995c792SAkinobu Mita return -1; 272a995c792SAkinobu Mita } 273a995c792SAkinobu Mita 274a995c792SAkinobu Mita if (!err) 275a995c792SAkinobu Mita pr_info("erasecrosstest ok\n"); 276a995c792SAkinobu Mita return err; 277a995c792SAkinobu Mita } 278a995c792SAkinobu Mita 279a995c792SAkinobu Mita static int erasetest(void) 280a995c792SAkinobu Mita { 281a995c792SAkinobu Mita int err = 0, i, ebnum, ok = 1; 282a995c792SAkinobu Mita loff_t addr0; 283a995c792SAkinobu Mita 284a995c792SAkinobu Mita pr_info("erasetest\n"); 285a995c792SAkinobu Mita 286a995c792SAkinobu Mita ebnum = 0; 287a995c792SAkinobu Mita addr0 = 0; 288a995c792SAkinobu Mita for (i = 0; i < ebcnt && bbt[i]; ++i) { 289a995c792SAkinobu Mita addr0 += mtd->erasesize; 290a995c792SAkinobu Mita ebnum += 1; 291a995c792SAkinobu Mita } 292a995c792SAkinobu Mita 293a995c792SAkinobu Mita pr_info("erasing block %d\n", ebnum); 29466b28183SAkinobu Mita err = mtdtest_erase_eraseblock(mtd, ebnum); 295a995c792SAkinobu Mita if (err) 296a995c792SAkinobu Mita return err; 297a995c792SAkinobu Mita 298a995c792SAkinobu Mita pr_info("writing 1st page of block %d\n", ebnum); 299a995c792SAkinobu Mita prandom_bytes_state(&rnd_state, writebuf, pgsize); 30066b28183SAkinobu Mita err = mtdtest_write(mtd, addr0, pgsize, writebuf); 3018a9f4aa3SAkinobu Mita if (err) 30266b28183SAkinobu Mita return err; 303a995c792SAkinobu Mita 304a995c792SAkinobu Mita pr_info("erasing block %d\n", ebnum); 30566b28183SAkinobu Mita err = mtdtest_erase_eraseblock(mtd, ebnum); 306a995c792SAkinobu Mita if (err) 307a995c792SAkinobu Mita return err; 308a995c792SAkinobu Mita 309a995c792SAkinobu Mita pr_info("reading 1st page of block %d\n", ebnum); 31066b28183SAkinobu Mita err = mtdtest_read(mtd, addr0, pgsize, twopages); 311abc173adSAkinobu Mita if (err) 31266b28183SAkinobu Mita return err; 313a995c792SAkinobu Mita 314a995c792SAkinobu Mita pr_info("verifying 1st page of block %d is all 0xff\n", 315a995c792SAkinobu Mita ebnum); 316a995c792SAkinobu Mita for (i = 0; i < pgsize; ++i) 317a995c792SAkinobu Mita if (twopages[i] != 0xff) { 318a995c792SAkinobu Mita pr_err("verifying all 0xff failed at %d\n", 319a995c792SAkinobu Mita i); 320a995c792SAkinobu Mita errcnt += 1; 321a995c792SAkinobu Mita ok = 0; 322a995c792SAkinobu Mita break; 323a995c792SAkinobu Mita } 324a995c792SAkinobu Mita 325a995c792SAkinobu Mita if (ok && !err) 326a995c792SAkinobu Mita pr_info("erasetest ok\n"); 327a995c792SAkinobu Mita 328a995c792SAkinobu Mita return err; 329a995c792SAkinobu Mita } 330a995c792SAkinobu Mita 331a995c792SAkinobu Mita static int __init mtd_pagetest_init(void) 332a995c792SAkinobu Mita { 333a995c792SAkinobu Mita int err = 0; 334a995c792SAkinobu Mita uint64_t tmp; 335a995c792SAkinobu Mita uint32_t i; 336a995c792SAkinobu Mita 337a995c792SAkinobu Mita printk(KERN_INFO "\n"); 338a995c792SAkinobu Mita printk(KERN_INFO "=================================================\n"); 339a995c792SAkinobu Mita 340a995c792SAkinobu Mita if (dev < 0) { 341a995c792SAkinobu Mita pr_info("Please specify a valid mtd-device via module parameter\n"); 342a995c792SAkinobu Mita pr_crit("CAREFUL: This test wipes all data on the specified MTD device!\n"); 343a995c792SAkinobu Mita return -EINVAL; 344a995c792SAkinobu Mita } 345a995c792SAkinobu Mita 346a995c792SAkinobu Mita pr_info("MTD device: %d\n", dev); 347a995c792SAkinobu Mita 348a995c792SAkinobu Mita mtd = get_mtd_device(NULL, dev); 349a995c792SAkinobu Mita if (IS_ERR(mtd)) { 350a995c792SAkinobu Mita err = PTR_ERR(mtd); 351a995c792SAkinobu Mita pr_err("error: cannot get MTD device\n"); 352a995c792SAkinobu Mita return err; 353a995c792SAkinobu Mita } 354a995c792SAkinobu Mita 355818b9739SHuang Shijie if (!mtd_type_is_nand(mtd)) { 356a995c792SAkinobu Mita pr_info("this test requires NAND flash\n"); 357a995c792SAkinobu Mita goto out; 358a995c792SAkinobu Mita } 359a995c792SAkinobu Mita 360a995c792SAkinobu Mita tmp = mtd->size; 361a995c792SAkinobu Mita do_div(tmp, mtd->erasesize); 362a995c792SAkinobu Mita ebcnt = tmp; 363a995c792SAkinobu Mita pgcnt = mtd->erasesize / mtd->writesize; 364a995c792SAkinobu Mita pgsize = mtd->writesize; 365a995c792SAkinobu Mita 366a995c792SAkinobu Mita pr_info("MTD device size %llu, eraseblock size %u, " 367a995c792SAkinobu Mita "page size %u, count of eraseblocks %u, pages per " 368a995c792SAkinobu Mita "eraseblock %u, OOB size %u\n", 369a995c792SAkinobu Mita (unsigned long long)mtd->size, mtd->erasesize, 370a995c792SAkinobu Mita pgsize, ebcnt, pgcnt, mtd->oobsize); 371a995c792SAkinobu Mita 372a995c792SAkinobu Mita err = -ENOMEM; 373a995c792SAkinobu Mita bufsize = pgsize * 2; 374a995c792SAkinobu Mita writebuf = kmalloc(mtd->erasesize, GFP_KERNEL); 375a995c792SAkinobu Mita if (!writebuf) 376a995c792SAkinobu Mita goto out; 377a995c792SAkinobu Mita twopages = kmalloc(bufsize, GFP_KERNEL); 378a995c792SAkinobu Mita if (!twopages) 379a995c792SAkinobu Mita goto out; 380a995c792SAkinobu Mita boundary = kmalloc(bufsize, GFP_KERNEL); 381a995c792SAkinobu Mita if (!boundary) 382a995c792SAkinobu Mita goto out; 383a995c792SAkinobu Mita 38466b28183SAkinobu Mita bbt = kzalloc(ebcnt, GFP_KERNEL); 38566b28183SAkinobu Mita if (!bbt) 38666b28183SAkinobu Mita goto out; 38766b28183SAkinobu Mita err = mtdtest_scan_for_bad_eraseblocks(mtd, bbt, 0, ebcnt); 388a995c792SAkinobu Mita if (err) 389a995c792SAkinobu Mita goto out; 390a995c792SAkinobu Mita 391a995c792SAkinobu Mita /* Erase all eraseblocks */ 392a995c792SAkinobu Mita pr_info("erasing whole device\n"); 39366b28183SAkinobu Mita err = mtdtest_erase_good_eraseblocks(mtd, bbt, 0, ebcnt); 394a995c792SAkinobu Mita if (err) 395a995c792SAkinobu Mita goto out; 39666b28183SAkinobu Mita pr_info("erased %u eraseblocks\n", ebcnt); 397a995c792SAkinobu Mita 398a995c792SAkinobu Mita /* Write all eraseblocks */ 399a995c792SAkinobu Mita prandom_seed_state(&rnd_state, 1); 400a995c792SAkinobu Mita pr_info("writing whole device\n"); 401a995c792SAkinobu Mita for (i = 0; i < ebcnt; ++i) { 402a995c792SAkinobu Mita if (bbt[i]) 403a995c792SAkinobu Mita continue; 404a995c792SAkinobu Mita err = write_eraseblock(i); 405a995c792SAkinobu Mita if (err) 406a995c792SAkinobu Mita goto out; 407a995c792SAkinobu Mita if (i % 256 == 0) 408a995c792SAkinobu Mita pr_info("written up to eraseblock %u\n", i); 4092a6a28e7SRichard Weinberger 4102a6a28e7SRichard Weinberger err = mtdtest_relax(); 4112a6a28e7SRichard Weinberger if (err) 4122a6a28e7SRichard Weinberger goto out; 413a995c792SAkinobu Mita } 414a995c792SAkinobu Mita pr_info("written %u eraseblocks\n", i); 415a995c792SAkinobu Mita 416a995c792SAkinobu Mita /* Check all eraseblocks */ 417a995c792SAkinobu Mita prandom_seed_state(&rnd_state, 1); 418a995c792SAkinobu Mita pr_info("verifying all eraseblocks\n"); 419a995c792SAkinobu Mita for (i = 0; i < ebcnt; ++i) { 420a995c792SAkinobu Mita if (bbt[i]) 421a995c792SAkinobu Mita continue; 422a995c792SAkinobu Mita err = verify_eraseblock(i); 423a995c792SAkinobu Mita if (err) 424a995c792SAkinobu Mita goto out; 425a995c792SAkinobu Mita if (i % 256 == 0) 426a995c792SAkinobu Mita pr_info("verified up to eraseblock %u\n", i); 4272a6a28e7SRichard Weinberger 4282a6a28e7SRichard Weinberger err = mtdtest_relax(); 4292a6a28e7SRichard Weinberger if (err) 4302a6a28e7SRichard Weinberger goto out; 431a995c792SAkinobu Mita } 432a995c792SAkinobu Mita pr_info("verified %u eraseblocks\n", i); 433a995c792SAkinobu Mita 434a995c792SAkinobu Mita err = crosstest(); 435a995c792SAkinobu Mita if (err) 436a995c792SAkinobu Mita goto out; 437a995c792SAkinobu Mita 438148a1a5dSStefan Agner if (ebcnt > 1) { 439a995c792SAkinobu Mita err = erasecrosstest(); 440a995c792SAkinobu Mita if (err) 441a995c792SAkinobu Mita goto out; 442148a1a5dSStefan Agner } else { 443148a1a5dSStefan Agner pr_info("skipping erasecrosstest, 2 erase blocks needed\n"); 444148a1a5dSStefan Agner } 445a995c792SAkinobu Mita 446a995c792SAkinobu Mita err = erasetest(); 447a995c792SAkinobu Mita if (err) 448a995c792SAkinobu Mita goto out; 449a995c792SAkinobu Mita 450a995c792SAkinobu Mita pr_info("finished with %d errors\n", errcnt); 451a995c792SAkinobu Mita out: 452a995c792SAkinobu Mita 453a995c792SAkinobu Mita kfree(bbt); 454a995c792SAkinobu Mita kfree(boundary); 455a995c792SAkinobu Mita kfree(twopages); 456a995c792SAkinobu Mita kfree(writebuf); 457a995c792SAkinobu Mita put_mtd_device(mtd); 458a995c792SAkinobu Mita if (err) 459a995c792SAkinobu Mita pr_info("error %d occurred\n", err); 460a995c792SAkinobu Mita printk(KERN_INFO "=================================================\n"); 461a995c792SAkinobu Mita return err; 462a995c792SAkinobu Mita } 463a995c792SAkinobu Mita module_init(mtd_pagetest_init); 464a995c792SAkinobu Mita 465a995c792SAkinobu Mita static void __exit mtd_pagetest_exit(void) 466a995c792SAkinobu Mita { 467a995c792SAkinobu Mita return; 468a995c792SAkinobu Mita } 469a995c792SAkinobu Mita module_exit(mtd_pagetest_exit); 470a995c792SAkinobu Mita 471a995c792SAkinobu Mita MODULE_DESCRIPTION("NAND page test"); 472a995c792SAkinobu Mita MODULE_AUTHOR("Adrian Hunter"); 473a995c792SAkinobu Mita MODULE_LICENSE("GPL"); 474