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 34a995c792SAkinobu Mita static int dev = -EINVAL; 35a995c792SAkinobu Mita module_param(dev, int, S_IRUGO); 36a995c792SAkinobu Mita MODULE_PARM_DESC(dev, "MTD device number to use"); 37a995c792SAkinobu Mita 38a995c792SAkinobu Mita static struct mtd_info *mtd; 39a995c792SAkinobu Mita static unsigned char *twopages; 40a995c792SAkinobu Mita static unsigned char *writebuf; 41a995c792SAkinobu Mita static unsigned char *boundary; 42a995c792SAkinobu Mita static unsigned char *bbt; 43a995c792SAkinobu Mita 44a995c792SAkinobu Mita static int pgsize; 45a995c792SAkinobu Mita static int bufsize; 46a995c792SAkinobu Mita static int ebcnt; 47a995c792SAkinobu Mita static int pgcnt; 48a995c792SAkinobu Mita static int errcnt; 49a995c792SAkinobu Mita static struct rnd_state rnd_state; 50a995c792SAkinobu Mita 51a995c792SAkinobu Mita static int erase_eraseblock(int ebnum) 52a995c792SAkinobu Mita { 53a995c792SAkinobu Mita int err; 54a995c792SAkinobu Mita struct erase_info ei; 55a995c792SAkinobu Mita loff_t addr = ebnum * mtd->erasesize; 56a995c792SAkinobu Mita 57a995c792SAkinobu Mita memset(&ei, 0, sizeof(struct erase_info)); 58a995c792SAkinobu Mita ei.mtd = mtd; 59a995c792SAkinobu Mita ei.addr = addr; 60a995c792SAkinobu Mita ei.len = mtd->erasesize; 61a995c792SAkinobu Mita 62a995c792SAkinobu Mita err = mtd_erase(mtd, &ei); 63a995c792SAkinobu Mita if (err) { 64a995c792SAkinobu Mita pr_err("error %d while erasing EB %d\n", err, ebnum); 65a995c792SAkinobu Mita return err; 66a995c792SAkinobu Mita } 67a995c792SAkinobu Mita 68a995c792SAkinobu Mita if (ei.state == MTD_ERASE_FAILED) { 69a995c792SAkinobu Mita pr_err("some erase error occurred at EB %d\n", 70a995c792SAkinobu Mita ebnum); 71a995c792SAkinobu Mita return -EIO; 72a995c792SAkinobu Mita } 73a995c792SAkinobu Mita 74a995c792SAkinobu Mita return 0; 75a995c792SAkinobu Mita } 76a995c792SAkinobu Mita 77a995c792SAkinobu Mita static int write_eraseblock(int ebnum) 78a995c792SAkinobu Mita { 79a995c792SAkinobu Mita int err = 0; 80a995c792SAkinobu Mita size_t written; 81a995c792SAkinobu Mita loff_t addr = ebnum * mtd->erasesize; 82a995c792SAkinobu Mita 83a995c792SAkinobu Mita prandom_bytes_state(&rnd_state, writebuf, mtd->erasesize); 84a995c792SAkinobu Mita cond_resched(); 85a995c792SAkinobu Mita err = mtd_write(mtd, addr, mtd->erasesize, &written, writebuf); 86a995c792SAkinobu Mita if (err || written != mtd->erasesize) 87a995c792SAkinobu Mita pr_err("error: write failed at %#llx\n", 88a995c792SAkinobu Mita (long long)addr); 89a995c792SAkinobu Mita 90a995c792SAkinobu Mita return err; 91a995c792SAkinobu Mita } 92a995c792SAkinobu Mita 93a995c792SAkinobu Mita static int verify_eraseblock(int ebnum) 94a995c792SAkinobu Mita { 95a995c792SAkinobu Mita uint32_t j; 96a995c792SAkinobu Mita size_t read; 97a995c792SAkinobu Mita int err = 0, i; 98a995c792SAkinobu Mita loff_t addr0, addrn; 99a995c792SAkinobu Mita loff_t addr = ebnum * mtd->erasesize; 100a995c792SAkinobu Mita 101a995c792SAkinobu Mita addr0 = 0; 102a995c792SAkinobu Mita for (i = 0; i < ebcnt && bbt[i]; ++i) 103a995c792SAkinobu Mita addr0 += mtd->erasesize; 104a995c792SAkinobu Mita 105a995c792SAkinobu Mita addrn = mtd->size; 106a995c792SAkinobu Mita for (i = 0; i < ebcnt && bbt[ebcnt - i - 1]; ++i) 107a995c792SAkinobu Mita addrn -= mtd->erasesize; 108a995c792SAkinobu Mita 109a995c792SAkinobu Mita prandom_bytes_state(&rnd_state, writebuf, mtd->erasesize); 110a995c792SAkinobu Mita for (j = 0; j < pgcnt - 1; ++j, addr += pgsize) { 111a995c792SAkinobu Mita /* Do a read to set the internal dataRAMs to different data */ 112a995c792SAkinobu Mita err = mtd_read(mtd, addr0, bufsize, &read, twopages); 113a995c792SAkinobu Mita if (mtd_is_bitflip(err)) 114a995c792SAkinobu Mita err = 0; 115a995c792SAkinobu Mita if (err || read != bufsize) { 116a995c792SAkinobu Mita pr_err("error: read failed at %#llx\n", 117a995c792SAkinobu Mita (long long)addr0); 118a995c792SAkinobu Mita return err; 119a995c792SAkinobu Mita } 120a995c792SAkinobu Mita err = mtd_read(mtd, addrn - bufsize, bufsize, &read, twopages); 121a995c792SAkinobu Mita if (mtd_is_bitflip(err)) 122a995c792SAkinobu Mita err = 0; 123a995c792SAkinobu Mita if (err || read != bufsize) { 124a995c792SAkinobu Mita pr_err("error: read failed at %#llx\n", 125a995c792SAkinobu Mita (long long)(addrn - bufsize)); 126a995c792SAkinobu Mita return err; 127a995c792SAkinobu Mita } 128a995c792SAkinobu Mita memset(twopages, 0, bufsize); 129a995c792SAkinobu Mita err = mtd_read(mtd, addr, bufsize, &read, twopages); 130a995c792SAkinobu Mita if (mtd_is_bitflip(err)) 131a995c792SAkinobu Mita err = 0; 132a995c792SAkinobu Mita if (err || read != bufsize) { 133a995c792SAkinobu Mita pr_err("error: read failed at %#llx\n", 134a995c792SAkinobu Mita (long long)addr); 135a995c792SAkinobu Mita break; 136a995c792SAkinobu Mita } 137a995c792SAkinobu Mita if (memcmp(twopages, writebuf + (j * pgsize), bufsize)) { 138a995c792SAkinobu Mita pr_err("error: verify failed at %#llx\n", 139a995c792SAkinobu Mita (long long)addr); 140a995c792SAkinobu Mita errcnt += 1; 141a995c792SAkinobu Mita } 142a995c792SAkinobu Mita } 143a995c792SAkinobu Mita /* Check boundary between eraseblocks */ 144a995c792SAkinobu Mita if (addr <= addrn - pgsize - pgsize && !bbt[ebnum + 1]) { 145a995c792SAkinobu Mita struct rnd_state old_state = rnd_state; 146a995c792SAkinobu Mita 147a995c792SAkinobu Mita /* Do a read to set the internal dataRAMs to different data */ 148a995c792SAkinobu Mita err = mtd_read(mtd, addr0, bufsize, &read, twopages); 149a995c792SAkinobu Mita if (mtd_is_bitflip(err)) 150a995c792SAkinobu Mita err = 0; 151a995c792SAkinobu Mita if (err || read != bufsize) { 152a995c792SAkinobu Mita pr_err("error: read failed at %#llx\n", 153a995c792SAkinobu Mita (long long)addr0); 154a995c792SAkinobu Mita return err; 155a995c792SAkinobu Mita } 156a995c792SAkinobu Mita err = mtd_read(mtd, addrn - bufsize, bufsize, &read, twopages); 157a995c792SAkinobu Mita if (mtd_is_bitflip(err)) 158a995c792SAkinobu Mita err = 0; 159a995c792SAkinobu Mita if (err || read != bufsize) { 160a995c792SAkinobu Mita pr_err("error: read failed at %#llx\n", 161a995c792SAkinobu Mita (long long)(addrn - bufsize)); 162a995c792SAkinobu Mita return err; 163a995c792SAkinobu Mita } 164a995c792SAkinobu Mita memset(twopages, 0, bufsize); 165a995c792SAkinobu Mita err = mtd_read(mtd, addr, bufsize, &read, twopages); 166a995c792SAkinobu Mita if (mtd_is_bitflip(err)) 167a995c792SAkinobu Mita err = 0; 168a995c792SAkinobu Mita if (err || read != bufsize) { 169a995c792SAkinobu Mita pr_err("error: read failed at %#llx\n", 170a995c792SAkinobu Mita (long long)addr); 171a995c792SAkinobu Mita return err; 172a995c792SAkinobu Mita } 173a995c792SAkinobu Mita memcpy(boundary, writebuf + mtd->erasesize - pgsize, pgsize); 174a995c792SAkinobu Mita prandom_bytes_state(&rnd_state, boundary + pgsize, pgsize); 175a995c792SAkinobu Mita if (memcmp(twopages, boundary, bufsize)) { 176a995c792SAkinobu Mita pr_err("error: verify failed at %#llx\n", 177a995c792SAkinobu Mita (long long)addr); 178a995c792SAkinobu Mita errcnt += 1; 179a995c792SAkinobu Mita } 180a995c792SAkinobu Mita rnd_state = old_state; 181a995c792SAkinobu Mita } 182a995c792SAkinobu Mita return err; 183a995c792SAkinobu Mita } 184a995c792SAkinobu Mita 185a995c792SAkinobu Mita static int crosstest(void) 186a995c792SAkinobu Mita { 187a995c792SAkinobu Mita size_t read; 188a995c792SAkinobu Mita int err = 0, i; 189a995c792SAkinobu Mita loff_t addr, addr0, addrn; 190a995c792SAkinobu Mita unsigned char *pp1, *pp2, *pp3, *pp4; 191a995c792SAkinobu Mita 192a995c792SAkinobu Mita pr_info("crosstest\n"); 193a995c792SAkinobu Mita pp1 = kmalloc(pgsize * 4, GFP_KERNEL); 194a995c792SAkinobu Mita if (!pp1) 195a995c792SAkinobu Mita return -ENOMEM; 196a995c792SAkinobu Mita pp2 = pp1 + pgsize; 197a995c792SAkinobu Mita pp3 = pp2 + pgsize; 198a995c792SAkinobu Mita pp4 = pp3 + pgsize; 199a995c792SAkinobu Mita memset(pp1, 0, pgsize * 4); 200a995c792SAkinobu Mita 201a995c792SAkinobu Mita addr0 = 0; 202a995c792SAkinobu Mita for (i = 0; i < ebcnt && bbt[i]; ++i) 203a995c792SAkinobu Mita addr0 += mtd->erasesize; 204a995c792SAkinobu Mita 205a995c792SAkinobu Mita addrn = mtd->size; 206a995c792SAkinobu Mita for (i = 0; i < ebcnt && bbt[ebcnt - i - 1]; ++i) 207a995c792SAkinobu Mita addrn -= mtd->erasesize; 208a995c792SAkinobu Mita 209a995c792SAkinobu Mita /* Read 2nd-to-last page to pp1 */ 210a995c792SAkinobu Mita addr = addrn - pgsize - pgsize; 211a995c792SAkinobu Mita err = mtd_read(mtd, addr, pgsize, &read, pp1); 212a995c792SAkinobu Mita if (mtd_is_bitflip(err)) 213a995c792SAkinobu Mita err = 0; 214a995c792SAkinobu Mita if (err || read != pgsize) { 215a995c792SAkinobu Mita pr_err("error: read failed at %#llx\n", 216a995c792SAkinobu Mita (long long)addr); 217a995c792SAkinobu Mita kfree(pp1); 218a995c792SAkinobu Mita return err; 219a995c792SAkinobu Mita } 220a995c792SAkinobu Mita 221a995c792SAkinobu Mita /* Read 3rd-to-last page to pp1 */ 222a995c792SAkinobu Mita addr = addrn - pgsize - pgsize - pgsize; 223a995c792SAkinobu Mita err = mtd_read(mtd, addr, pgsize, &read, pp1); 224a995c792SAkinobu Mita if (mtd_is_bitflip(err)) 225a995c792SAkinobu Mita err = 0; 226a995c792SAkinobu Mita if (err || read != pgsize) { 227a995c792SAkinobu Mita pr_err("error: read failed at %#llx\n", 228a995c792SAkinobu Mita (long long)addr); 229a995c792SAkinobu Mita kfree(pp1); 230a995c792SAkinobu Mita return err; 231a995c792SAkinobu Mita } 232a995c792SAkinobu Mita 233a995c792SAkinobu Mita /* Read first page to pp2 */ 234a995c792SAkinobu Mita addr = addr0; 235a995c792SAkinobu Mita pr_info("reading page at %#llx\n", (long long)addr); 236a995c792SAkinobu Mita err = mtd_read(mtd, addr, pgsize, &read, pp2); 237a995c792SAkinobu Mita if (mtd_is_bitflip(err)) 238a995c792SAkinobu Mita err = 0; 239a995c792SAkinobu Mita if (err || read != pgsize) { 240a995c792SAkinobu Mita pr_err("error: read failed at %#llx\n", 241a995c792SAkinobu Mita (long long)addr); 242a995c792SAkinobu Mita kfree(pp1); 243a995c792SAkinobu Mita return err; 244a995c792SAkinobu Mita } 245a995c792SAkinobu Mita 246a995c792SAkinobu Mita /* Read last page to pp3 */ 247a995c792SAkinobu Mita addr = addrn - pgsize; 248a995c792SAkinobu Mita pr_info("reading page at %#llx\n", (long long)addr); 249a995c792SAkinobu Mita err = mtd_read(mtd, addr, pgsize, &read, pp3); 250a995c792SAkinobu Mita if (mtd_is_bitflip(err)) 251a995c792SAkinobu Mita err = 0; 252a995c792SAkinobu Mita if (err || read != pgsize) { 253a995c792SAkinobu Mita pr_err("error: read failed at %#llx\n", 254a995c792SAkinobu Mita (long long)addr); 255a995c792SAkinobu Mita kfree(pp1); 256a995c792SAkinobu Mita return err; 257a995c792SAkinobu Mita } 258a995c792SAkinobu Mita 259a995c792SAkinobu Mita /* Read first page again to pp4 */ 260a995c792SAkinobu Mita addr = addr0; 261a995c792SAkinobu Mita pr_info("reading page at %#llx\n", (long long)addr); 262a995c792SAkinobu Mita err = mtd_read(mtd, addr, pgsize, &read, pp4); 263a995c792SAkinobu Mita if (mtd_is_bitflip(err)) 264a995c792SAkinobu Mita err = 0; 265a995c792SAkinobu Mita if (err || read != pgsize) { 266a995c792SAkinobu Mita pr_err("error: read failed at %#llx\n", 267a995c792SAkinobu Mita (long long)addr); 268a995c792SAkinobu Mita kfree(pp1); 269a995c792SAkinobu Mita return err; 270a995c792SAkinobu Mita } 271a995c792SAkinobu Mita 272a995c792SAkinobu Mita /* pp2 and pp4 should be the same */ 273a995c792SAkinobu Mita pr_info("verifying pages read at %#llx match\n", 274a995c792SAkinobu Mita (long long)addr0); 275a995c792SAkinobu Mita if (memcmp(pp2, pp4, pgsize)) { 276a995c792SAkinobu Mita pr_err("verify failed!\n"); 277a995c792SAkinobu Mita errcnt += 1; 278a995c792SAkinobu Mita } else if (!err) 279a995c792SAkinobu Mita pr_info("crosstest ok\n"); 280a995c792SAkinobu Mita kfree(pp1); 281a995c792SAkinobu Mita return err; 282a995c792SAkinobu Mita } 283a995c792SAkinobu Mita 284a995c792SAkinobu Mita static int erasecrosstest(void) 285a995c792SAkinobu Mita { 286a995c792SAkinobu Mita size_t read, written; 287a995c792SAkinobu Mita int err = 0, i, ebnum, ebnum2; 288a995c792SAkinobu Mita loff_t addr0; 289a995c792SAkinobu Mita char *readbuf = twopages; 290a995c792SAkinobu Mita 291a995c792SAkinobu Mita pr_info("erasecrosstest\n"); 292a995c792SAkinobu Mita 293a995c792SAkinobu Mita ebnum = 0; 294a995c792SAkinobu Mita addr0 = 0; 295a995c792SAkinobu Mita for (i = 0; i < ebcnt && bbt[i]; ++i) { 296a995c792SAkinobu Mita addr0 += mtd->erasesize; 297a995c792SAkinobu Mita ebnum += 1; 298a995c792SAkinobu Mita } 299a995c792SAkinobu Mita 300a995c792SAkinobu Mita ebnum2 = ebcnt - 1; 301a995c792SAkinobu Mita while (ebnum2 && bbt[ebnum2]) 302a995c792SAkinobu Mita ebnum2 -= 1; 303a995c792SAkinobu Mita 304a995c792SAkinobu Mita pr_info("erasing block %d\n", ebnum); 305a995c792SAkinobu Mita err = erase_eraseblock(ebnum); 306a995c792SAkinobu Mita if (err) 307a995c792SAkinobu Mita return err; 308a995c792SAkinobu Mita 309a995c792SAkinobu Mita pr_info("writing 1st page of block %d\n", ebnum); 310a995c792SAkinobu Mita prandom_bytes_state(&rnd_state, writebuf, pgsize); 311a995c792SAkinobu Mita strcpy(writebuf, "There is no data like this!"); 312a995c792SAkinobu Mita err = mtd_write(mtd, addr0, pgsize, &written, writebuf); 313a995c792SAkinobu Mita if (err || written != pgsize) { 314a995c792SAkinobu Mita pr_info("error: write failed at %#llx\n", 315a995c792SAkinobu Mita (long long)addr0); 316a995c792SAkinobu Mita return err ? err : -1; 317a995c792SAkinobu Mita } 318a995c792SAkinobu Mita 319a995c792SAkinobu Mita pr_info("reading 1st page of block %d\n", ebnum); 320a995c792SAkinobu Mita memset(readbuf, 0, pgsize); 321a995c792SAkinobu Mita err = mtd_read(mtd, addr0, pgsize, &read, readbuf); 322a995c792SAkinobu Mita if (mtd_is_bitflip(err)) 323a995c792SAkinobu Mita err = 0; 324a995c792SAkinobu Mita if (err || read != pgsize) { 325a995c792SAkinobu Mita pr_err("error: read failed at %#llx\n", 326a995c792SAkinobu Mita (long long)addr0); 327a995c792SAkinobu Mita return err ? err : -1; 328a995c792SAkinobu Mita } 329a995c792SAkinobu Mita 330a995c792SAkinobu Mita pr_info("verifying 1st page of block %d\n", ebnum); 331a995c792SAkinobu Mita if (memcmp(writebuf, readbuf, pgsize)) { 332a995c792SAkinobu Mita pr_err("verify failed!\n"); 333a995c792SAkinobu Mita errcnt += 1; 334a995c792SAkinobu Mita return -1; 335a995c792SAkinobu Mita } 336a995c792SAkinobu Mita 337a995c792SAkinobu Mita pr_info("erasing block %d\n", ebnum); 338a995c792SAkinobu Mita err = erase_eraseblock(ebnum); 339a995c792SAkinobu Mita if (err) 340a995c792SAkinobu Mita return err; 341a995c792SAkinobu Mita 342a995c792SAkinobu Mita pr_info("writing 1st page of block %d\n", ebnum); 343a995c792SAkinobu Mita prandom_bytes_state(&rnd_state, writebuf, pgsize); 344a995c792SAkinobu Mita strcpy(writebuf, "There is no data like this!"); 345a995c792SAkinobu Mita err = mtd_write(mtd, addr0, pgsize, &written, writebuf); 346a995c792SAkinobu Mita if (err || written != pgsize) { 347a995c792SAkinobu Mita pr_err("error: write failed at %#llx\n", 348a995c792SAkinobu Mita (long long)addr0); 349a995c792SAkinobu Mita return err ? err : -1; 350a995c792SAkinobu Mita } 351a995c792SAkinobu Mita 352a995c792SAkinobu Mita pr_info("erasing block %d\n", ebnum2); 353a995c792SAkinobu Mita err = erase_eraseblock(ebnum2); 354a995c792SAkinobu Mita if (err) 355a995c792SAkinobu Mita return err; 356a995c792SAkinobu Mita 357a995c792SAkinobu Mita pr_info("reading 1st page of block %d\n", ebnum); 358a995c792SAkinobu Mita memset(readbuf, 0, pgsize); 359a995c792SAkinobu Mita err = mtd_read(mtd, addr0, pgsize, &read, readbuf); 360a995c792SAkinobu Mita if (mtd_is_bitflip(err)) 361a995c792SAkinobu Mita err = 0; 362a995c792SAkinobu Mita if (err || read != pgsize) { 363a995c792SAkinobu Mita pr_err("error: read failed at %#llx\n", 364a995c792SAkinobu Mita (long long)addr0); 365a995c792SAkinobu Mita return err ? err : -1; 366a995c792SAkinobu Mita } 367a995c792SAkinobu Mita 368a995c792SAkinobu Mita pr_info("verifying 1st page of block %d\n", ebnum); 369a995c792SAkinobu Mita if (memcmp(writebuf, readbuf, pgsize)) { 370a995c792SAkinobu Mita pr_err("verify failed!\n"); 371a995c792SAkinobu Mita errcnt += 1; 372a995c792SAkinobu Mita return -1; 373a995c792SAkinobu Mita } 374a995c792SAkinobu Mita 375a995c792SAkinobu Mita if (!err) 376a995c792SAkinobu Mita pr_info("erasecrosstest ok\n"); 377a995c792SAkinobu Mita return err; 378a995c792SAkinobu Mita } 379a995c792SAkinobu Mita 380a995c792SAkinobu Mita static int erasetest(void) 381a995c792SAkinobu Mita { 382a995c792SAkinobu Mita size_t read, written; 383a995c792SAkinobu Mita int err = 0, i, ebnum, ok = 1; 384a995c792SAkinobu Mita loff_t addr0; 385a995c792SAkinobu Mita 386a995c792SAkinobu Mita pr_info("erasetest\n"); 387a995c792SAkinobu Mita 388a995c792SAkinobu Mita ebnum = 0; 389a995c792SAkinobu Mita addr0 = 0; 390a995c792SAkinobu Mita for (i = 0; i < ebcnt && bbt[i]; ++i) { 391a995c792SAkinobu Mita addr0 += mtd->erasesize; 392a995c792SAkinobu Mita ebnum += 1; 393a995c792SAkinobu Mita } 394a995c792SAkinobu Mita 395a995c792SAkinobu Mita pr_info("erasing block %d\n", ebnum); 396a995c792SAkinobu Mita err = erase_eraseblock(ebnum); 397a995c792SAkinobu Mita if (err) 398a995c792SAkinobu Mita return err; 399a995c792SAkinobu Mita 400a995c792SAkinobu Mita pr_info("writing 1st page of block %d\n", ebnum); 401a995c792SAkinobu Mita prandom_bytes_state(&rnd_state, writebuf, pgsize); 402a995c792SAkinobu Mita err = mtd_write(mtd, addr0, pgsize, &written, writebuf); 403a995c792SAkinobu Mita if (err || written != pgsize) { 404a995c792SAkinobu Mita pr_err("error: write failed at %#llx\n", 405a995c792SAkinobu Mita (long long)addr0); 406a995c792SAkinobu Mita return err ? err : -1; 407a995c792SAkinobu Mita } 408a995c792SAkinobu Mita 409a995c792SAkinobu Mita pr_info("erasing block %d\n", ebnum); 410a995c792SAkinobu Mita err = erase_eraseblock(ebnum); 411a995c792SAkinobu Mita if (err) 412a995c792SAkinobu Mita return err; 413a995c792SAkinobu Mita 414a995c792SAkinobu Mita pr_info("reading 1st page of block %d\n", ebnum); 415a995c792SAkinobu Mita err = mtd_read(mtd, addr0, pgsize, &read, twopages); 416a995c792SAkinobu Mita if (mtd_is_bitflip(err)) 417a995c792SAkinobu Mita err = 0; 418a995c792SAkinobu Mita if (err || read != pgsize) { 419a995c792SAkinobu Mita pr_err("error: read failed at %#llx\n", 420a995c792SAkinobu Mita (long long)addr0); 421a995c792SAkinobu Mita return err ? err : -1; 422a995c792SAkinobu Mita } 423a995c792SAkinobu Mita 424a995c792SAkinobu Mita pr_info("verifying 1st page of block %d is all 0xff\n", 425a995c792SAkinobu Mita ebnum); 426a995c792SAkinobu Mita for (i = 0; i < pgsize; ++i) 427a995c792SAkinobu Mita if (twopages[i] != 0xff) { 428a995c792SAkinobu Mita pr_err("verifying all 0xff failed at %d\n", 429a995c792SAkinobu Mita i); 430a995c792SAkinobu Mita errcnt += 1; 431a995c792SAkinobu Mita ok = 0; 432a995c792SAkinobu Mita break; 433a995c792SAkinobu Mita } 434a995c792SAkinobu Mita 435a995c792SAkinobu Mita if (ok && !err) 436a995c792SAkinobu Mita pr_info("erasetest ok\n"); 437a995c792SAkinobu Mita 438a995c792SAkinobu Mita return err; 439a995c792SAkinobu Mita } 440a995c792SAkinobu Mita 441a995c792SAkinobu Mita static int is_block_bad(int ebnum) 442a995c792SAkinobu Mita { 443a995c792SAkinobu Mita loff_t addr = ebnum * mtd->erasesize; 444a995c792SAkinobu Mita int ret; 445a995c792SAkinobu Mita 446a995c792SAkinobu Mita ret = mtd_block_isbad(mtd, addr); 447a995c792SAkinobu Mita if (ret) 448a995c792SAkinobu Mita pr_info("block %d is bad\n", ebnum); 449a995c792SAkinobu Mita return ret; 450a995c792SAkinobu Mita } 451a995c792SAkinobu Mita 452a995c792SAkinobu Mita static int scan_for_bad_eraseblocks(void) 453a995c792SAkinobu Mita { 454a995c792SAkinobu Mita int i, bad = 0; 455a995c792SAkinobu Mita 456a995c792SAkinobu Mita bbt = kzalloc(ebcnt, GFP_KERNEL); 457a995c792SAkinobu Mita if (!bbt) 458a995c792SAkinobu Mita return -ENOMEM; 459a995c792SAkinobu Mita 460a995c792SAkinobu Mita pr_info("scanning for bad eraseblocks\n"); 461a995c792SAkinobu Mita for (i = 0; i < ebcnt; ++i) { 462a995c792SAkinobu Mita bbt[i] = is_block_bad(i) ? 1 : 0; 463a995c792SAkinobu Mita if (bbt[i]) 464a995c792SAkinobu Mita bad += 1; 465a995c792SAkinobu Mita cond_resched(); 466a995c792SAkinobu Mita } 467a995c792SAkinobu Mita pr_info("scanned %d eraseblocks, %d are bad\n", i, bad); 468a995c792SAkinobu Mita return 0; 469a995c792SAkinobu Mita } 470a995c792SAkinobu Mita 471a995c792SAkinobu Mita static int __init mtd_pagetest_init(void) 472a995c792SAkinobu Mita { 473a995c792SAkinobu Mita int err = 0; 474a995c792SAkinobu Mita uint64_t tmp; 475a995c792SAkinobu Mita uint32_t i; 476a995c792SAkinobu Mita 477a995c792SAkinobu Mita printk(KERN_INFO "\n"); 478a995c792SAkinobu Mita printk(KERN_INFO "=================================================\n"); 479a995c792SAkinobu Mita 480a995c792SAkinobu Mita if (dev < 0) { 481a995c792SAkinobu Mita pr_info("Please specify a valid mtd-device via module parameter\n"); 482a995c792SAkinobu Mita pr_crit("CAREFUL: This test wipes all data on the specified MTD device!\n"); 483a995c792SAkinobu Mita return -EINVAL; 484a995c792SAkinobu Mita } 485a995c792SAkinobu Mita 486a995c792SAkinobu Mita pr_info("MTD device: %d\n", dev); 487a995c792SAkinobu Mita 488a995c792SAkinobu Mita mtd = get_mtd_device(NULL, dev); 489a995c792SAkinobu Mita if (IS_ERR(mtd)) { 490a995c792SAkinobu Mita err = PTR_ERR(mtd); 491a995c792SAkinobu Mita pr_err("error: cannot get MTD device\n"); 492a995c792SAkinobu Mita return err; 493a995c792SAkinobu Mita } 494a995c792SAkinobu Mita 495a995c792SAkinobu Mita if (mtd->type != MTD_NANDFLASH) { 496a995c792SAkinobu Mita pr_info("this test requires NAND flash\n"); 497a995c792SAkinobu Mita goto out; 498a995c792SAkinobu Mita } 499a995c792SAkinobu Mita 500a995c792SAkinobu Mita tmp = mtd->size; 501a995c792SAkinobu Mita do_div(tmp, mtd->erasesize); 502a995c792SAkinobu Mita ebcnt = tmp; 503a995c792SAkinobu Mita pgcnt = mtd->erasesize / mtd->writesize; 504a995c792SAkinobu Mita pgsize = mtd->writesize; 505a995c792SAkinobu Mita 506a995c792SAkinobu Mita pr_info("MTD device size %llu, eraseblock size %u, " 507a995c792SAkinobu Mita "page size %u, count of eraseblocks %u, pages per " 508a995c792SAkinobu Mita "eraseblock %u, OOB size %u\n", 509a995c792SAkinobu Mita (unsigned long long)mtd->size, mtd->erasesize, 510a995c792SAkinobu Mita pgsize, ebcnt, pgcnt, mtd->oobsize); 511a995c792SAkinobu Mita 512a995c792SAkinobu Mita err = -ENOMEM; 513a995c792SAkinobu Mita bufsize = pgsize * 2; 514a995c792SAkinobu Mita writebuf = kmalloc(mtd->erasesize, GFP_KERNEL); 515a995c792SAkinobu Mita if (!writebuf) 516a995c792SAkinobu Mita goto out; 517a995c792SAkinobu Mita twopages = kmalloc(bufsize, GFP_KERNEL); 518a995c792SAkinobu Mita if (!twopages) 519a995c792SAkinobu Mita goto out; 520a995c792SAkinobu Mita boundary = kmalloc(bufsize, GFP_KERNEL); 521a995c792SAkinobu Mita if (!boundary) 522a995c792SAkinobu Mita goto out; 523a995c792SAkinobu Mita 524a995c792SAkinobu Mita err = scan_for_bad_eraseblocks(); 525a995c792SAkinobu Mita if (err) 526a995c792SAkinobu Mita goto out; 527a995c792SAkinobu Mita 528a995c792SAkinobu Mita /* Erase all eraseblocks */ 529a995c792SAkinobu Mita pr_info("erasing whole device\n"); 530a995c792SAkinobu Mita for (i = 0; i < ebcnt; ++i) { 531a995c792SAkinobu Mita if (bbt[i]) 532a995c792SAkinobu Mita continue; 533a995c792SAkinobu Mita err = erase_eraseblock(i); 534a995c792SAkinobu Mita if (err) 535a995c792SAkinobu Mita goto out; 536a995c792SAkinobu Mita cond_resched(); 537a995c792SAkinobu Mita } 538a995c792SAkinobu Mita pr_info("erased %u eraseblocks\n", i); 539a995c792SAkinobu Mita 540a995c792SAkinobu Mita /* Write all eraseblocks */ 541a995c792SAkinobu Mita prandom_seed_state(&rnd_state, 1); 542a995c792SAkinobu Mita pr_info("writing whole device\n"); 543a995c792SAkinobu Mita for (i = 0; i < ebcnt; ++i) { 544a995c792SAkinobu Mita if (bbt[i]) 545a995c792SAkinobu Mita continue; 546a995c792SAkinobu Mita err = write_eraseblock(i); 547a995c792SAkinobu Mita if (err) 548a995c792SAkinobu Mita goto out; 549a995c792SAkinobu Mita if (i % 256 == 0) 550a995c792SAkinobu Mita pr_info("written up to eraseblock %u\n", i); 551a995c792SAkinobu Mita cond_resched(); 552a995c792SAkinobu Mita } 553a995c792SAkinobu Mita pr_info("written %u eraseblocks\n", i); 554a995c792SAkinobu Mita 555a995c792SAkinobu Mita /* Check all eraseblocks */ 556a995c792SAkinobu Mita prandom_seed_state(&rnd_state, 1); 557a995c792SAkinobu Mita pr_info("verifying all eraseblocks\n"); 558a995c792SAkinobu Mita for (i = 0; i < ebcnt; ++i) { 559a995c792SAkinobu Mita if (bbt[i]) 560a995c792SAkinobu Mita continue; 561a995c792SAkinobu Mita err = verify_eraseblock(i); 562a995c792SAkinobu Mita if (err) 563a995c792SAkinobu Mita goto out; 564a995c792SAkinobu Mita if (i % 256 == 0) 565a995c792SAkinobu Mita pr_info("verified up to eraseblock %u\n", i); 566a995c792SAkinobu Mita cond_resched(); 567a995c792SAkinobu Mita } 568a995c792SAkinobu Mita pr_info("verified %u eraseblocks\n", i); 569a995c792SAkinobu Mita 570a995c792SAkinobu Mita err = crosstest(); 571a995c792SAkinobu Mita if (err) 572a995c792SAkinobu Mita goto out; 573a995c792SAkinobu Mita 574a995c792SAkinobu Mita err = erasecrosstest(); 575a995c792SAkinobu Mita if (err) 576a995c792SAkinobu Mita goto out; 577a995c792SAkinobu Mita 578a995c792SAkinobu Mita err = erasetest(); 579a995c792SAkinobu Mita if (err) 580a995c792SAkinobu Mita goto out; 581a995c792SAkinobu Mita 582a995c792SAkinobu Mita pr_info("finished with %d errors\n", errcnt); 583a995c792SAkinobu Mita out: 584a995c792SAkinobu Mita 585a995c792SAkinobu Mita kfree(bbt); 586a995c792SAkinobu Mita kfree(boundary); 587a995c792SAkinobu Mita kfree(twopages); 588a995c792SAkinobu Mita kfree(writebuf); 589a995c792SAkinobu Mita put_mtd_device(mtd); 590a995c792SAkinobu Mita if (err) 591a995c792SAkinobu Mita pr_info("error %d occurred\n", err); 592a995c792SAkinobu Mita printk(KERN_INFO "=================================================\n"); 593a995c792SAkinobu Mita return err; 594a995c792SAkinobu Mita } 595a995c792SAkinobu Mita module_init(mtd_pagetest_init); 596a995c792SAkinobu Mita 597a995c792SAkinobu Mita static void __exit mtd_pagetest_exit(void) 598a995c792SAkinobu Mita { 599a995c792SAkinobu Mita return; 600a995c792SAkinobu Mita } 601a995c792SAkinobu Mita module_exit(mtd_pagetest_exit); 602a995c792SAkinobu Mita 603a995c792SAkinobu Mita MODULE_DESCRIPTION("NAND page test"); 604a995c792SAkinobu Mita MODULE_AUTHOR("Adrian Hunter"); 605a995c792SAkinobu Mita MODULE_LICENSE("GPL"); 606