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 { 5566b28183SAkinobu Mita int err; 56a995c792SAkinobu Mita loff_t addr = ebnum * mtd->erasesize; 57a995c792SAkinobu Mita 58a995c792SAkinobu Mita prandom_bytes_state(&rnd_state, writebuf, mtd->erasesize); 59a995c792SAkinobu Mita cond_resched(); 6066b28183SAkinobu Mita err = mtdtest_write(mtd, addr, mtd->erasesize, writebuf); 6166b28183SAkinobu Mita if (err) 62a995c792SAkinobu Mita pr_err("error: write failed at %#llx\n", 63a995c792SAkinobu Mita (long long)addr); 64a995c792SAkinobu Mita 65a995c792SAkinobu Mita return err; 66a995c792SAkinobu Mita } 67a995c792SAkinobu Mita 68a995c792SAkinobu Mita static int verify_eraseblock(int ebnum) 69a995c792SAkinobu Mita { 70a995c792SAkinobu Mita uint32_t j; 71a995c792SAkinobu Mita int err = 0, i; 72a995c792SAkinobu Mita loff_t addr0, addrn; 73a995c792SAkinobu Mita loff_t addr = ebnum * mtd->erasesize; 74a995c792SAkinobu Mita 75a995c792SAkinobu Mita addr0 = 0; 76a995c792SAkinobu Mita for (i = 0; i < ebcnt && bbt[i]; ++i) 77a995c792SAkinobu Mita addr0 += mtd->erasesize; 78a995c792SAkinobu Mita 79a995c792SAkinobu Mita addrn = mtd->size; 80a995c792SAkinobu Mita for (i = 0; i < ebcnt && bbt[ebcnt - i - 1]; ++i) 81a995c792SAkinobu Mita addrn -= mtd->erasesize; 82a995c792SAkinobu Mita 83a995c792SAkinobu Mita prandom_bytes_state(&rnd_state, writebuf, mtd->erasesize); 84a995c792SAkinobu Mita for (j = 0; j < pgcnt - 1; ++j, addr += pgsize) { 85a995c792SAkinobu Mita /* Do a read to set the internal dataRAMs to different data */ 8666b28183SAkinobu Mita err = mtdtest_read(mtd, addr0, bufsize, twopages); 87abc173adSAkinobu Mita if (err) 88a995c792SAkinobu Mita return err; 8966b28183SAkinobu Mita err = mtdtest_read(mtd, addrn - bufsize, bufsize, twopages); 90abc173adSAkinobu Mita if (err) 91a995c792SAkinobu Mita return err; 92a995c792SAkinobu Mita memset(twopages, 0, bufsize); 9366b28183SAkinobu Mita err = mtdtest_read(mtd, addr, bufsize, twopages); 94abc173adSAkinobu Mita if (err) 95a995c792SAkinobu Mita break; 96a995c792SAkinobu Mita if (memcmp(twopages, writebuf + (j * pgsize), bufsize)) { 97a995c792SAkinobu Mita pr_err("error: verify failed at %#llx\n", 98a995c792SAkinobu Mita (long long)addr); 99a995c792SAkinobu Mita errcnt += 1; 100a995c792SAkinobu Mita } 101a995c792SAkinobu Mita } 102a995c792SAkinobu Mita /* Check boundary between eraseblocks */ 103a995c792SAkinobu Mita if (addr <= addrn - pgsize - pgsize && !bbt[ebnum + 1]) { 104a995c792SAkinobu Mita struct rnd_state old_state = rnd_state; 105a995c792SAkinobu Mita 106a995c792SAkinobu Mita /* Do a read to set the internal dataRAMs to different data */ 10766b28183SAkinobu Mita err = mtdtest_read(mtd, addr0, bufsize, twopages); 108abc173adSAkinobu Mita if (err) 109a995c792SAkinobu Mita return err; 11066b28183SAkinobu Mita err = mtdtest_read(mtd, addrn - bufsize, bufsize, twopages); 111abc173adSAkinobu Mita if (err) 112a995c792SAkinobu Mita return err; 113a995c792SAkinobu Mita memset(twopages, 0, bufsize); 11466b28183SAkinobu Mita err = mtdtest_read(mtd, addr, bufsize, twopages); 115abc173adSAkinobu Mita if (err) 116a995c792SAkinobu Mita return err; 117a995c792SAkinobu Mita memcpy(boundary, writebuf + mtd->erasesize - pgsize, pgsize); 118a995c792SAkinobu Mita prandom_bytes_state(&rnd_state, boundary + pgsize, pgsize); 119a995c792SAkinobu Mita if (memcmp(twopages, boundary, bufsize)) { 120a995c792SAkinobu Mita pr_err("error: verify failed at %#llx\n", 121a995c792SAkinobu Mita (long long)addr); 122a995c792SAkinobu Mita errcnt += 1; 123a995c792SAkinobu Mita } 124a995c792SAkinobu Mita rnd_state = old_state; 125a995c792SAkinobu Mita } 126a995c792SAkinobu Mita return err; 127a995c792SAkinobu Mita } 128a995c792SAkinobu Mita 129a995c792SAkinobu Mita static int crosstest(void) 130a995c792SAkinobu Mita { 131a995c792SAkinobu Mita int err = 0, i; 132a995c792SAkinobu Mita loff_t addr, addr0, addrn; 133a995c792SAkinobu Mita unsigned char *pp1, *pp2, *pp3, *pp4; 134a995c792SAkinobu Mita 135a995c792SAkinobu Mita pr_info("crosstest\n"); 136a995c792SAkinobu Mita pp1 = kmalloc(pgsize * 4, GFP_KERNEL); 137a995c792SAkinobu Mita if (!pp1) 138a995c792SAkinobu Mita return -ENOMEM; 139a995c792SAkinobu Mita pp2 = pp1 + pgsize; 140a995c792SAkinobu Mita pp3 = pp2 + pgsize; 141a995c792SAkinobu Mita pp4 = pp3 + pgsize; 142a995c792SAkinobu Mita memset(pp1, 0, pgsize * 4); 143a995c792SAkinobu Mita 144a995c792SAkinobu Mita addr0 = 0; 145a995c792SAkinobu Mita for (i = 0; i < ebcnt && bbt[i]; ++i) 146a995c792SAkinobu Mita addr0 += mtd->erasesize; 147a995c792SAkinobu Mita 148a995c792SAkinobu Mita addrn = mtd->size; 149a995c792SAkinobu Mita for (i = 0; i < ebcnt && bbt[ebcnt - i - 1]; ++i) 150a995c792SAkinobu Mita addrn -= mtd->erasesize; 151a995c792SAkinobu Mita 152a995c792SAkinobu Mita /* Read 2nd-to-last page to pp1 */ 153a995c792SAkinobu Mita addr = addrn - pgsize - pgsize; 15466b28183SAkinobu Mita err = mtdtest_read(mtd, addr, pgsize, pp1); 15566b28183SAkinobu Mita if (err) { 156a995c792SAkinobu Mita kfree(pp1); 157a995c792SAkinobu Mita return err; 158a995c792SAkinobu Mita } 159a995c792SAkinobu Mita 160a995c792SAkinobu Mita /* Read 3rd-to-last page to pp1 */ 161a995c792SAkinobu Mita addr = addrn - pgsize - pgsize - pgsize; 16266b28183SAkinobu Mita err = mtdtest_read(mtd, addr, pgsize, pp1); 16366b28183SAkinobu Mita if (err) { 164a995c792SAkinobu Mita kfree(pp1); 165a995c792SAkinobu Mita return err; 166a995c792SAkinobu Mita } 167a995c792SAkinobu Mita 168a995c792SAkinobu Mita /* Read first page to pp2 */ 169a995c792SAkinobu Mita addr = addr0; 170a995c792SAkinobu Mita pr_info("reading page at %#llx\n", (long long)addr); 17166b28183SAkinobu Mita err = mtdtest_read(mtd, addr, pgsize, pp2); 17266b28183SAkinobu Mita if (err) { 173a995c792SAkinobu Mita kfree(pp1); 174a995c792SAkinobu Mita return err; 175a995c792SAkinobu Mita } 176a995c792SAkinobu Mita 177a995c792SAkinobu Mita /* Read last page to pp3 */ 178a995c792SAkinobu Mita addr = addrn - pgsize; 179a995c792SAkinobu Mita pr_info("reading page at %#llx\n", (long long)addr); 18066b28183SAkinobu Mita err = mtdtest_read(mtd, addr, pgsize, pp3); 18166b28183SAkinobu Mita if (err) { 182a995c792SAkinobu Mita kfree(pp1); 183a995c792SAkinobu Mita return err; 184a995c792SAkinobu Mita } 185a995c792SAkinobu Mita 186a995c792SAkinobu Mita /* Read first page again to pp4 */ 187a995c792SAkinobu Mita addr = addr0; 188a995c792SAkinobu Mita pr_info("reading page at %#llx\n", (long long)addr); 18966b28183SAkinobu Mita err = mtdtest_read(mtd, addr, pgsize, pp4); 19066b28183SAkinobu Mita if (err) { 191a995c792SAkinobu Mita kfree(pp1); 192a995c792SAkinobu Mita return err; 193a995c792SAkinobu Mita } 194a995c792SAkinobu Mita 195a995c792SAkinobu Mita /* pp2 and pp4 should be the same */ 196a995c792SAkinobu Mita pr_info("verifying pages read at %#llx match\n", 197a995c792SAkinobu Mita (long long)addr0); 198a995c792SAkinobu Mita if (memcmp(pp2, pp4, pgsize)) { 199a995c792SAkinobu Mita pr_err("verify failed!\n"); 200a995c792SAkinobu Mita errcnt += 1; 201a995c792SAkinobu Mita } else if (!err) 202a995c792SAkinobu Mita pr_info("crosstest ok\n"); 203a995c792SAkinobu Mita kfree(pp1); 204a995c792SAkinobu Mita return err; 205a995c792SAkinobu Mita } 206a995c792SAkinobu Mita 207a995c792SAkinobu Mita static int erasecrosstest(void) 208a995c792SAkinobu Mita { 209a995c792SAkinobu Mita int err = 0, i, ebnum, ebnum2; 210a995c792SAkinobu Mita loff_t addr0; 211a995c792SAkinobu Mita char *readbuf = twopages; 212a995c792SAkinobu Mita 213a995c792SAkinobu Mita pr_info("erasecrosstest\n"); 214a995c792SAkinobu Mita 215a995c792SAkinobu Mita ebnum = 0; 216a995c792SAkinobu Mita addr0 = 0; 217a995c792SAkinobu Mita for (i = 0; i < ebcnt && bbt[i]; ++i) { 218a995c792SAkinobu Mita addr0 += mtd->erasesize; 219a995c792SAkinobu Mita ebnum += 1; 220a995c792SAkinobu Mita } 221a995c792SAkinobu Mita 222a995c792SAkinobu Mita ebnum2 = ebcnt - 1; 223a995c792SAkinobu Mita while (ebnum2 && bbt[ebnum2]) 224a995c792SAkinobu Mita ebnum2 -= 1; 225a995c792SAkinobu Mita 226a995c792SAkinobu Mita pr_info("erasing block %d\n", ebnum); 22766b28183SAkinobu Mita err = mtdtest_erase_eraseblock(mtd, ebnum); 228a995c792SAkinobu Mita if (err) 229a995c792SAkinobu Mita return err; 230a995c792SAkinobu Mita 231a995c792SAkinobu Mita pr_info("writing 1st page of block %d\n", ebnum); 232a995c792SAkinobu Mita prandom_bytes_state(&rnd_state, writebuf, pgsize); 233a995c792SAkinobu Mita strcpy(writebuf, "There is no data like this!"); 23466b28183SAkinobu Mita err = mtdtest_write(mtd, addr0, pgsize, writebuf); 23566b28183SAkinobu Mita if (err) { 236a995c792SAkinobu Mita pr_info("error: write failed at %#llx\n", 237a995c792SAkinobu Mita (long long)addr0); 23866b28183SAkinobu Mita return err; 239a995c792SAkinobu Mita } 240a995c792SAkinobu Mita 241a995c792SAkinobu Mita pr_info("reading 1st page of block %d\n", ebnum); 242a995c792SAkinobu Mita memset(readbuf, 0, pgsize); 24366b28183SAkinobu Mita err = mtdtest_read(mtd, addr0, pgsize, readbuf); 244abc173adSAkinobu Mita if (err) 24566b28183SAkinobu Mita return err; 246a995c792SAkinobu Mita 247a995c792SAkinobu Mita pr_info("verifying 1st page of block %d\n", ebnum); 248a995c792SAkinobu Mita if (memcmp(writebuf, readbuf, pgsize)) { 249a995c792SAkinobu Mita pr_err("verify failed!\n"); 250a995c792SAkinobu Mita errcnt += 1; 251a995c792SAkinobu Mita return -1; 252a995c792SAkinobu Mita } 253a995c792SAkinobu Mita 254a995c792SAkinobu Mita pr_info("erasing block %d\n", ebnum); 25566b28183SAkinobu Mita err = mtdtest_erase_eraseblock(mtd, ebnum); 256a995c792SAkinobu Mita if (err) 257a995c792SAkinobu Mita return err; 258a995c792SAkinobu Mita 259a995c792SAkinobu Mita pr_info("writing 1st page of block %d\n", ebnum); 260a995c792SAkinobu Mita prandom_bytes_state(&rnd_state, writebuf, pgsize); 261a995c792SAkinobu Mita strcpy(writebuf, "There is no data like this!"); 26266b28183SAkinobu Mita err = mtdtest_write(mtd, addr0, pgsize, writebuf); 26366b28183SAkinobu Mita if (err) { 264a995c792SAkinobu Mita pr_err("error: write failed at %#llx\n", 265a995c792SAkinobu Mita (long long)addr0); 26666b28183SAkinobu Mita return err; 267a995c792SAkinobu Mita } 268a995c792SAkinobu Mita 269a995c792SAkinobu Mita pr_info("erasing block %d\n", ebnum2); 27066b28183SAkinobu Mita err = mtdtest_erase_eraseblock(mtd, ebnum2); 271a995c792SAkinobu Mita if (err) 272a995c792SAkinobu Mita return err; 273a995c792SAkinobu Mita 274a995c792SAkinobu Mita pr_info("reading 1st page of block %d\n", ebnum); 275a995c792SAkinobu Mita memset(readbuf, 0, pgsize); 27666b28183SAkinobu Mita err = mtdtest_read(mtd, addr0, pgsize, readbuf); 277abc173adSAkinobu Mita if (err) 27866b28183SAkinobu Mita return err; 279a995c792SAkinobu Mita 280a995c792SAkinobu Mita pr_info("verifying 1st page of block %d\n", ebnum); 281a995c792SAkinobu Mita if (memcmp(writebuf, readbuf, pgsize)) { 282a995c792SAkinobu Mita pr_err("verify failed!\n"); 283a995c792SAkinobu Mita errcnt += 1; 284a995c792SAkinobu Mita return -1; 285a995c792SAkinobu Mita } 286a995c792SAkinobu Mita 287a995c792SAkinobu Mita if (!err) 288a995c792SAkinobu Mita pr_info("erasecrosstest ok\n"); 289a995c792SAkinobu Mita return err; 290a995c792SAkinobu Mita } 291a995c792SAkinobu Mita 292a995c792SAkinobu Mita static int erasetest(void) 293a995c792SAkinobu Mita { 294a995c792SAkinobu Mita int err = 0, i, ebnum, ok = 1; 295a995c792SAkinobu Mita loff_t addr0; 296a995c792SAkinobu Mita 297a995c792SAkinobu Mita pr_info("erasetest\n"); 298a995c792SAkinobu Mita 299a995c792SAkinobu Mita ebnum = 0; 300a995c792SAkinobu Mita addr0 = 0; 301a995c792SAkinobu Mita for (i = 0; i < ebcnt && bbt[i]; ++i) { 302a995c792SAkinobu Mita addr0 += mtd->erasesize; 303a995c792SAkinobu Mita ebnum += 1; 304a995c792SAkinobu Mita } 305a995c792SAkinobu Mita 306a995c792SAkinobu Mita pr_info("erasing block %d\n", ebnum); 30766b28183SAkinobu Mita err = mtdtest_erase_eraseblock(mtd, ebnum); 308a995c792SAkinobu Mita if (err) 309a995c792SAkinobu Mita return err; 310a995c792SAkinobu Mita 311a995c792SAkinobu Mita pr_info("writing 1st page of block %d\n", ebnum); 312a995c792SAkinobu Mita prandom_bytes_state(&rnd_state, writebuf, pgsize); 31366b28183SAkinobu Mita err = mtdtest_write(mtd, addr0, pgsize, writebuf); 31466b28183SAkinobu Mita if (err) { 315a995c792SAkinobu Mita pr_err("error: write failed at %#llx\n", 316a995c792SAkinobu Mita (long long)addr0); 31766b28183SAkinobu Mita return err; 318a995c792SAkinobu Mita } 319a995c792SAkinobu Mita 320a995c792SAkinobu Mita pr_info("erasing block %d\n", ebnum); 32166b28183SAkinobu Mita err = mtdtest_erase_eraseblock(mtd, ebnum); 322a995c792SAkinobu Mita if (err) 323a995c792SAkinobu Mita return err; 324a995c792SAkinobu Mita 325a995c792SAkinobu Mita pr_info("reading 1st page of block %d\n", ebnum); 32666b28183SAkinobu Mita err = mtdtest_read(mtd, addr0, pgsize, twopages); 327abc173adSAkinobu Mita if (err) 32866b28183SAkinobu Mita return err; 329a995c792SAkinobu Mita 330a995c792SAkinobu Mita pr_info("verifying 1st page of block %d is all 0xff\n", 331a995c792SAkinobu Mita ebnum); 332a995c792SAkinobu Mita for (i = 0; i < pgsize; ++i) 333a995c792SAkinobu Mita if (twopages[i] != 0xff) { 334a995c792SAkinobu Mita pr_err("verifying all 0xff failed at %d\n", 335a995c792SAkinobu Mita i); 336a995c792SAkinobu Mita errcnt += 1; 337a995c792SAkinobu Mita ok = 0; 338a995c792SAkinobu Mita break; 339a995c792SAkinobu Mita } 340a995c792SAkinobu Mita 341a995c792SAkinobu Mita if (ok && !err) 342a995c792SAkinobu Mita pr_info("erasetest ok\n"); 343a995c792SAkinobu Mita 344a995c792SAkinobu Mita return err; 345a995c792SAkinobu Mita } 346a995c792SAkinobu Mita 347a995c792SAkinobu Mita static int __init mtd_pagetest_init(void) 348a995c792SAkinobu Mita { 349a995c792SAkinobu Mita int err = 0; 350a995c792SAkinobu Mita uint64_t tmp; 351a995c792SAkinobu Mita uint32_t i; 352a995c792SAkinobu Mita 353a995c792SAkinobu Mita printk(KERN_INFO "\n"); 354a995c792SAkinobu Mita printk(KERN_INFO "=================================================\n"); 355a995c792SAkinobu Mita 356a995c792SAkinobu Mita if (dev < 0) { 357a995c792SAkinobu Mita pr_info("Please specify a valid mtd-device via module parameter\n"); 358a995c792SAkinobu Mita pr_crit("CAREFUL: This test wipes all data on the specified MTD device!\n"); 359a995c792SAkinobu Mita return -EINVAL; 360a995c792SAkinobu Mita } 361a995c792SAkinobu Mita 362a995c792SAkinobu Mita pr_info("MTD device: %d\n", dev); 363a995c792SAkinobu Mita 364a995c792SAkinobu Mita mtd = get_mtd_device(NULL, dev); 365a995c792SAkinobu Mita if (IS_ERR(mtd)) { 366a995c792SAkinobu Mita err = PTR_ERR(mtd); 367a995c792SAkinobu Mita pr_err("error: cannot get MTD device\n"); 368a995c792SAkinobu Mita return err; 369a995c792SAkinobu Mita } 370a995c792SAkinobu Mita 371a995c792SAkinobu Mita if (mtd->type != MTD_NANDFLASH) { 372a995c792SAkinobu Mita pr_info("this test requires NAND flash\n"); 373a995c792SAkinobu Mita goto out; 374a995c792SAkinobu Mita } 375a995c792SAkinobu Mita 376a995c792SAkinobu Mita tmp = mtd->size; 377a995c792SAkinobu Mita do_div(tmp, mtd->erasesize); 378a995c792SAkinobu Mita ebcnt = tmp; 379a995c792SAkinobu Mita pgcnt = mtd->erasesize / mtd->writesize; 380a995c792SAkinobu Mita pgsize = mtd->writesize; 381a995c792SAkinobu Mita 382a995c792SAkinobu Mita pr_info("MTD device size %llu, eraseblock size %u, " 383a995c792SAkinobu Mita "page size %u, count of eraseblocks %u, pages per " 384a995c792SAkinobu Mita "eraseblock %u, OOB size %u\n", 385a995c792SAkinobu Mita (unsigned long long)mtd->size, mtd->erasesize, 386a995c792SAkinobu Mita pgsize, ebcnt, pgcnt, mtd->oobsize); 387a995c792SAkinobu Mita 388a995c792SAkinobu Mita err = -ENOMEM; 389a995c792SAkinobu Mita bufsize = pgsize * 2; 390a995c792SAkinobu Mita writebuf = kmalloc(mtd->erasesize, GFP_KERNEL); 391a995c792SAkinobu Mita if (!writebuf) 392a995c792SAkinobu Mita goto out; 393a995c792SAkinobu Mita twopages = kmalloc(bufsize, GFP_KERNEL); 394a995c792SAkinobu Mita if (!twopages) 395a995c792SAkinobu Mita goto out; 396a995c792SAkinobu Mita boundary = kmalloc(bufsize, GFP_KERNEL); 397a995c792SAkinobu Mita if (!boundary) 398a995c792SAkinobu Mita goto out; 399a995c792SAkinobu Mita 40066b28183SAkinobu Mita bbt = kzalloc(ebcnt, GFP_KERNEL); 40166b28183SAkinobu Mita if (!bbt) 40266b28183SAkinobu Mita goto out; 40366b28183SAkinobu Mita err = mtdtest_scan_for_bad_eraseblocks(mtd, bbt, 0, ebcnt); 404a995c792SAkinobu Mita if (err) 405a995c792SAkinobu Mita goto out; 406a995c792SAkinobu Mita 407a995c792SAkinobu Mita /* Erase all eraseblocks */ 408a995c792SAkinobu Mita pr_info("erasing whole device\n"); 40966b28183SAkinobu Mita err = mtdtest_erase_good_eraseblocks(mtd, bbt, 0, ebcnt); 410a995c792SAkinobu Mita if (err) 411a995c792SAkinobu Mita goto out; 41266b28183SAkinobu Mita pr_info("erased %u eraseblocks\n", ebcnt); 413a995c792SAkinobu Mita 414a995c792SAkinobu Mita /* Write all eraseblocks */ 415a995c792SAkinobu Mita prandom_seed_state(&rnd_state, 1); 416a995c792SAkinobu Mita pr_info("writing whole device\n"); 417a995c792SAkinobu Mita for (i = 0; i < ebcnt; ++i) { 418a995c792SAkinobu Mita if (bbt[i]) 419a995c792SAkinobu Mita continue; 420a995c792SAkinobu Mita err = write_eraseblock(i); 421a995c792SAkinobu Mita if (err) 422a995c792SAkinobu Mita goto out; 423a995c792SAkinobu Mita if (i % 256 == 0) 424a995c792SAkinobu Mita pr_info("written up to eraseblock %u\n", i); 425a995c792SAkinobu Mita cond_resched(); 426a995c792SAkinobu Mita } 427a995c792SAkinobu Mita pr_info("written %u eraseblocks\n", i); 428a995c792SAkinobu Mita 429a995c792SAkinobu Mita /* Check all eraseblocks */ 430a995c792SAkinobu Mita prandom_seed_state(&rnd_state, 1); 431a995c792SAkinobu Mita pr_info("verifying all eraseblocks\n"); 432a995c792SAkinobu Mita for (i = 0; i < ebcnt; ++i) { 433a995c792SAkinobu Mita if (bbt[i]) 434a995c792SAkinobu Mita continue; 435a995c792SAkinobu Mita err = verify_eraseblock(i); 436a995c792SAkinobu Mita if (err) 437a995c792SAkinobu Mita goto out; 438a995c792SAkinobu Mita if (i % 256 == 0) 439a995c792SAkinobu Mita pr_info("verified up to eraseblock %u\n", i); 440a995c792SAkinobu Mita cond_resched(); 441a995c792SAkinobu Mita } 442a995c792SAkinobu Mita pr_info("verified %u eraseblocks\n", i); 443a995c792SAkinobu Mita 444a995c792SAkinobu Mita err = crosstest(); 445a995c792SAkinobu Mita if (err) 446a995c792SAkinobu Mita goto out; 447a995c792SAkinobu Mita 448a995c792SAkinobu Mita err = erasecrosstest(); 449a995c792SAkinobu Mita if (err) 450a995c792SAkinobu Mita goto out; 451a995c792SAkinobu Mita 452a995c792SAkinobu Mita err = erasetest(); 453a995c792SAkinobu Mita if (err) 454a995c792SAkinobu Mita goto out; 455a995c792SAkinobu Mita 456a995c792SAkinobu Mita pr_info("finished with %d errors\n", errcnt); 457a995c792SAkinobu Mita out: 458a995c792SAkinobu Mita 459a995c792SAkinobu Mita kfree(bbt); 460a995c792SAkinobu Mita kfree(boundary); 461a995c792SAkinobu Mita kfree(twopages); 462a995c792SAkinobu Mita kfree(writebuf); 463a995c792SAkinobu Mita put_mtd_device(mtd); 464a995c792SAkinobu Mita if (err) 465a995c792SAkinobu Mita pr_info("error %d occurred\n", err); 466a995c792SAkinobu Mita printk(KERN_INFO "=================================================\n"); 467a995c792SAkinobu Mita return err; 468a995c792SAkinobu Mita } 469a995c792SAkinobu Mita module_init(mtd_pagetest_init); 470a995c792SAkinobu Mita 471a995c792SAkinobu Mita static void __exit mtd_pagetest_exit(void) 472a995c792SAkinobu Mita { 473a995c792SAkinobu Mita return; 474a995c792SAkinobu Mita } 475a995c792SAkinobu Mita module_exit(mtd_pagetest_exit); 476a995c792SAkinobu Mita 477a995c792SAkinobu Mita MODULE_DESCRIPTION("NAND page test"); 478a995c792SAkinobu Mita MODULE_AUTHOR("Adrian Hunter"); 479a995c792SAkinobu Mita MODULE_LICENSE("GPL"); 480