1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (C) 2006-2008 Nokia Corporation 4 * 5 * Test OOB read and write on MTD device. 6 * 7 * Author: Adrian Hunter <ext-adrian.hunter@nokia.com> 8 */ 9 10 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 11 12 #include <asm/div64.h> 13 #include <linux/init.h> 14 #include <linux/module.h> 15 #include <linux/moduleparam.h> 16 #include <linux/err.h> 17 #include <linux/mtd/mtd.h> 18 #include <linux/slab.h> 19 #include <linux/sched.h> 20 #include <linux/random.h> 21 22 #include "mtd_test.h" 23 24 static int dev = -EINVAL; 25 static int bitflip_limit; 26 module_param(dev, int, S_IRUGO); 27 MODULE_PARM_DESC(dev, "MTD device number to use"); 28 module_param(bitflip_limit, int, S_IRUGO); 29 MODULE_PARM_DESC(bitflip_limit, "Max. allowed bitflips per page"); 30 31 static struct mtd_info *mtd; 32 static unsigned char *readbuf; 33 static unsigned char *writebuf; 34 static unsigned char *bbt; 35 36 static int ebcnt; 37 static int pgcnt; 38 static int errcnt; 39 static int use_offset; 40 static int use_len; 41 static int use_len_max; 42 static int vary_offset; 43 static struct rnd_state rnd_state; 44 45 static void do_vary_offset(void) 46 { 47 use_len -= 1; 48 if (use_len < 1) { 49 use_offset += 1; 50 if (use_offset >= use_len_max) 51 use_offset = 0; 52 use_len = use_len_max - use_offset; 53 } 54 } 55 56 static int write_eraseblock(int ebnum) 57 { 58 int i; 59 struct mtd_oob_ops ops; 60 int err = 0; 61 loff_t addr = (loff_t)ebnum * mtd->erasesize; 62 63 prandom_bytes_state(&rnd_state, writebuf, use_len_max * pgcnt); 64 for (i = 0; i < pgcnt; ++i, addr += mtd->writesize) { 65 ops.mode = MTD_OPS_AUTO_OOB; 66 ops.len = 0; 67 ops.retlen = 0; 68 ops.ooblen = use_len; 69 ops.oobretlen = 0; 70 ops.ooboffs = use_offset; 71 ops.datbuf = NULL; 72 ops.oobbuf = writebuf + (use_len_max * i) + use_offset; 73 err = mtd_write_oob(mtd, addr, &ops); 74 if (err || ops.oobretlen != use_len) { 75 pr_err("error: writeoob failed at %#llx\n", 76 (long long)addr); 77 pr_err("error: use_len %d, use_offset %d\n", 78 use_len, use_offset); 79 errcnt += 1; 80 return err ? err : -1; 81 } 82 if (vary_offset) 83 do_vary_offset(); 84 } 85 86 return err; 87 } 88 89 static int write_whole_device(void) 90 { 91 int err; 92 unsigned int i; 93 94 pr_info("writing OOBs of whole device\n"); 95 for (i = 0; i < ebcnt; ++i) { 96 if (bbt[i]) 97 continue; 98 err = write_eraseblock(i); 99 if (err) 100 return err; 101 if (i % 256 == 0) 102 pr_info("written up to eraseblock %u\n", i); 103 104 err = mtdtest_relax(); 105 if (err) 106 return err; 107 } 108 pr_info("written %u eraseblocks\n", i); 109 return 0; 110 } 111 112 /* 113 * Display the address, offset and data bytes at comparison failure. 114 * Return number of bitflips encountered. 115 */ 116 static size_t memcmpshowoffset(loff_t addr, loff_t offset, const void *cs, 117 const void *ct, size_t count) 118 { 119 const unsigned char *su1, *su2; 120 int res; 121 size_t i = 0; 122 size_t bitflips = 0; 123 124 for (su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--, i++) { 125 res = *su1 ^ *su2; 126 if (res) { 127 pr_info("error @addr[0x%lx:0x%lx] 0x%x -> 0x%x diff 0x%x\n", 128 (unsigned long)addr, (unsigned long)offset + i, 129 *su1, *su2, res); 130 bitflips += hweight8(res); 131 } 132 } 133 134 return bitflips; 135 } 136 137 #define memcmpshow(addr, cs, ct, count) memcmpshowoffset((addr), 0, (cs), (ct),\ 138 (count)) 139 140 /* 141 * Compare with 0xff and show the address, offset and data bytes at 142 * comparison failure. Return number of bitflips encountered. 143 */ 144 static size_t memffshow(loff_t addr, loff_t offset, const void *cs, 145 size_t count) 146 { 147 const unsigned char *su1; 148 int res; 149 size_t i = 0; 150 size_t bitflips = 0; 151 152 for (su1 = cs; 0 < count; ++su1, count--, i++) { 153 res = *su1 ^ 0xff; 154 if (res) { 155 pr_info("error @addr[0x%lx:0x%lx] 0x%x -> 0xff diff 0x%x\n", 156 (unsigned long)addr, (unsigned long)offset + i, 157 *su1, res); 158 bitflips += hweight8(res); 159 } 160 } 161 162 return bitflips; 163 } 164 165 static int verify_eraseblock(int ebnum) 166 { 167 int i; 168 struct mtd_oob_ops ops; 169 int err = 0; 170 loff_t addr = (loff_t)ebnum * mtd->erasesize; 171 size_t bitflips; 172 173 prandom_bytes_state(&rnd_state, writebuf, use_len_max * pgcnt); 174 for (i = 0; i < pgcnt; ++i, addr += mtd->writesize) { 175 ops.mode = MTD_OPS_AUTO_OOB; 176 ops.len = 0; 177 ops.retlen = 0; 178 ops.ooblen = use_len; 179 ops.oobretlen = 0; 180 ops.ooboffs = use_offset; 181 ops.datbuf = NULL; 182 ops.oobbuf = readbuf; 183 err = mtd_read_oob(mtd, addr, &ops); 184 if (mtd_is_bitflip(err)) 185 err = 0; 186 187 if (err || ops.oobretlen != use_len) { 188 pr_err("error: readoob failed at %#llx\n", 189 (long long)addr); 190 errcnt += 1; 191 return err ? err : -1; 192 } 193 194 bitflips = memcmpshow(addr, readbuf, 195 writebuf + (use_len_max * i) + use_offset, 196 use_len); 197 if (bitflips > bitflip_limit) { 198 pr_err("error: verify failed at %#llx\n", 199 (long long)addr); 200 errcnt += 1; 201 if (errcnt > 1000) { 202 pr_err("error: too many errors\n"); 203 return -1; 204 } 205 } else if (bitflips) { 206 pr_info("ignoring error as within bitflip_limit\n"); 207 } 208 209 if (use_offset != 0 || use_len < mtd->oobavail) { 210 int k; 211 212 ops.mode = MTD_OPS_AUTO_OOB; 213 ops.len = 0; 214 ops.retlen = 0; 215 ops.ooblen = mtd->oobavail; 216 ops.oobretlen = 0; 217 ops.ooboffs = 0; 218 ops.datbuf = NULL; 219 ops.oobbuf = readbuf; 220 err = mtd_read_oob(mtd, addr, &ops); 221 if (mtd_is_bitflip(err)) 222 err = 0; 223 224 if (err || ops.oobretlen != mtd->oobavail) { 225 pr_err("error: readoob failed at %#llx\n", 226 (long long)addr); 227 errcnt += 1; 228 return err ? err : -1; 229 } 230 bitflips = memcmpshowoffset(addr, use_offset, 231 readbuf + use_offset, 232 writebuf + (use_len_max * i) + use_offset, 233 use_len); 234 235 /* verify pre-offset area for 0xff */ 236 bitflips += memffshow(addr, 0, readbuf, use_offset); 237 238 /* verify post-(use_offset + use_len) area for 0xff */ 239 k = use_offset + use_len; 240 bitflips += memffshow(addr, k, readbuf + k, 241 mtd->oobavail - k); 242 243 if (bitflips > bitflip_limit) { 244 pr_err("error: verify failed at %#llx\n", 245 (long long)addr); 246 errcnt += 1; 247 if (errcnt > 1000) { 248 pr_err("error: too many errors\n"); 249 return -1; 250 } 251 } else if (bitflips) { 252 pr_info("ignoring errors as within bitflip limit\n"); 253 } 254 } 255 if (vary_offset) 256 do_vary_offset(); 257 } 258 return err; 259 } 260 261 static int verify_eraseblock_in_one_go(int ebnum) 262 { 263 struct mtd_oob_ops ops; 264 int err = 0; 265 loff_t addr = (loff_t)ebnum * mtd->erasesize; 266 size_t len = mtd->oobavail * pgcnt; 267 size_t oobavail = mtd->oobavail; 268 size_t bitflips; 269 int i; 270 271 prandom_bytes_state(&rnd_state, writebuf, len); 272 ops.mode = MTD_OPS_AUTO_OOB; 273 ops.len = 0; 274 ops.retlen = 0; 275 ops.ooblen = len; 276 ops.oobretlen = 0; 277 ops.ooboffs = 0; 278 ops.datbuf = NULL; 279 ops.oobbuf = readbuf; 280 281 /* read entire block's OOB at one go */ 282 err = mtd_read_oob(mtd, addr, &ops); 283 if (mtd_is_bitflip(err)) 284 err = 0; 285 286 if (err || ops.oobretlen != len) { 287 pr_err("error: readoob failed at %#llx\n", 288 (long long)addr); 289 errcnt += 1; 290 return err ? err : -1; 291 } 292 293 /* verify one page OOB at a time for bitflip per page limit check */ 294 for (i = 0; i < pgcnt; ++i, addr += mtd->writesize) { 295 bitflips = memcmpshow(addr, readbuf + (i * oobavail), 296 writebuf + (i * oobavail), oobavail); 297 if (bitflips > bitflip_limit) { 298 pr_err("error: verify failed at %#llx\n", 299 (long long)addr); 300 errcnt += 1; 301 if (errcnt > 1000) { 302 pr_err("error: too many errors\n"); 303 return -1; 304 } 305 } else if (bitflips) { 306 pr_info("ignoring error as within bitflip_limit\n"); 307 } 308 } 309 310 return err; 311 } 312 313 static int verify_all_eraseblocks(void) 314 { 315 int err; 316 unsigned int i; 317 318 pr_info("verifying all eraseblocks\n"); 319 for (i = 0; i < ebcnt; ++i) { 320 if (bbt[i]) 321 continue; 322 err = verify_eraseblock(i); 323 if (err) 324 return err; 325 if (i % 256 == 0) 326 pr_info("verified up to eraseblock %u\n", i); 327 328 err = mtdtest_relax(); 329 if (err) 330 return err; 331 } 332 pr_info("verified %u eraseblocks\n", i); 333 return 0; 334 } 335 336 static int __init mtd_oobtest_init(void) 337 { 338 int err = 0; 339 unsigned int i; 340 uint64_t tmp; 341 struct mtd_oob_ops ops; 342 loff_t addr = 0, addr0; 343 344 printk(KERN_INFO "\n"); 345 printk(KERN_INFO "=================================================\n"); 346 347 if (dev < 0) { 348 pr_info("Please specify a valid mtd-device via module parameter\n"); 349 pr_crit("CAREFUL: This test wipes all data on the specified MTD device!\n"); 350 return -EINVAL; 351 } 352 353 pr_info("MTD device: %d\n", dev); 354 355 mtd = get_mtd_device(NULL, dev); 356 if (IS_ERR(mtd)) { 357 err = PTR_ERR(mtd); 358 pr_err("error: cannot get MTD device\n"); 359 return err; 360 } 361 362 if (!mtd_type_is_nand(mtd)) { 363 pr_info("this test requires NAND flash\n"); 364 goto out; 365 } 366 367 tmp = mtd->size; 368 do_div(tmp, mtd->erasesize); 369 ebcnt = tmp; 370 pgcnt = mtd->erasesize / mtd->writesize; 371 372 pr_info("MTD device size %llu, eraseblock size %u, " 373 "page size %u, count of eraseblocks %u, pages per " 374 "eraseblock %u, OOB size %u\n", 375 (unsigned long long)mtd->size, mtd->erasesize, 376 mtd->writesize, ebcnt, pgcnt, mtd->oobsize); 377 378 err = -ENOMEM; 379 readbuf = kmalloc(mtd->erasesize, GFP_KERNEL); 380 if (!readbuf) 381 goto out; 382 writebuf = kmalloc(mtd->erasesize, GFP_KERNEL); 383 if (!writebuf) 384 goto out; 385 bbt = kzalloc(ebcnt, GFP_KERNEL); 386 if (!bbt) 387 goto out; 388 389 err = mtdtest_scan_for_bad_eraseblocks(mtd, bbt, 0, ebcnt); 390 if (err) 391 goto out; 392 393 use_offset = 0; 394 use_len = mtd->oobavail; 395 use_len_max = mtd->oobavail; 396 vary_offset = 0; 397 398 /* First test: write all OOB, read it back and verify */ 399 pr_info("test 1 of 5\n"); 400 401 err = mtdtest_erase_good_eraseblocks(mtd, bbt, 0, ebcnt); 402 if (err) 403 goto out; 404 405 prandom_seed_state(&rnd_state, 1); 406 err = write_whole_device(); 407 if (err) 408 goto out; 409 410 prandom_seed_state(&rnd_state, 1); 411 err = verify_all_eraseblocks(); 412 if (err) 413 goto out; 414 415 /* 416 * Second test: write all OOB, a block at a time, read it back and 417 * verify. 418 */ 419 pr_info("test 2 of 5\n"); 420 421 err = mtdtest_erase_good_eraseblocks(mtd, bbt, 0, ebcnt); 422 if (err) 423 goto out; 424 425 prandom_seed_state(&rnd_state, 3); 426 err = write_whole_device(); 427 if (err) 428 goto out; 429 430 /* Check all eraseblocks */ 431 prandom_seed_state(&rnd_state, 3); 432 pr_info("verifying all eraseblocks\n"); 433 for (i = 0; i < ebcnt; ++i) { 434 if (bbt[i]) 435 continue; 436 err = verify_eraseblock_in_one_go(i); 437 if (err) 438 goto out; 439 if (i % 256 == 0) 440 pr_info("verified up to eraseblock %u\n", i); 441 442 err = mtdtest_relax(); 443 if (err) 444 goto out; 445 } 446 pr_info("verified %u eraseblocks\n", i); 447 448 /* 449 * Third test: write OOB at varying offsets and lengths, read it back 450 * and verify. 451 */ 452 pr_info("test 3 of 5\n"); 453 454 err = mtdtest_erase_good_eraseblocks(mtd, bbt, 0, ebcnt); 455 if (err) 456 goto out; 457 458 /* Write all eraseblocks */ 459 use_offset = 0; 460 use_len = mtd->oobavail; 461 use_len_max = mtd->oobavail; 462 vary_offset = 1; 463 prandom_seed_state(&rnd_state, 5); 464 465 err = write_whole_device(); 466 if (err) 467 goto out; 468 469 /* Check all eraseblocks */ 470 use_offset = 0; 471 use_len = mtd->oobavail; 472 use_len_max = mtd->oobavail; 473 vary_offset = 1; 474 prandom_seed_state(&rnd_state, 5); 475 err = verify_all_eraseblocks(); 476 if (err) 477 goto out; 478 479 use_offset = 0; 480 use_len = mtd->oobavail; 481 use_len_max = mtd->oobavail; 482 vary_offset = 0; 483 484 /* Fourth test: try to write off end of device */ 485 pr_info("test 4 of 5\n"); 486 487 err = mtdtest_erase_good_eraseblocks(mtd, bbt, 0, ebcnt); 488 if (err) 489 goto out; 490 491 addr0 = 0; 492 for (i = 0; i < ebcnt && bbt[i]; ++i) 493 addr0 += mtd->erasesize; 494 495 /* Attempt to write off end of OOB */ 496 ops.mode = MTD_OPS_AUTO_OOB; 497 ops.len = 0; 498 ops.retlen = 0; 499 ops.ooblen = 1; 500 ops.oobretlen = 0; 501 ops.ooboffs = mtd->oobavail; 502 ops.datbuf = NULL; 503 ops.oobbuf = writebuf; 504 pr_info("attempting to start write past end of OOB\n"); 505 pr_info("an error is expected...\n"); 506 err = mtd_write_oob(mtd, addr0, &ops); 507 if (err) { 508 pr_info("error occurred as expected\n"); 509 err = 0; 510 } else { 511 pr_err("error: can write past end of OOB\n"); 512 errcnt += 1; 513 } 514 515 /* Attempt to read off end of OOB */ 516 ops.mode = MTD_OPS_AUTO_OOB; 517 ops.len = 0; 518 ops.retlen = 0; 519 ops.ooblen = 1; 520 ops.oobretlen = 0; 521 ops.ooboffs = mtd->oobavail; 522 ops.datbuf = NULL; 523 ops.oobbuf = readbuf; 524 pr_info("attempting to start read past end of OOB\n"); 525 pr_info("an error is expected...\n"); 526 err = mtd_read_oob(mtd, addr0, &ops); 527 if (mtd_is_bitflip(err)) 528 err = 0; 529 530 if (err) { 531 pr_info("error occurred as expected\n"); 532 err = 0; 533 } else { 534 pr_err("error: can read past end of OOB\n"); 535 errcnt += 1; 536 } 537 538 if (bbt[ebcnt - 1]) 539 pr_info("skipping end of device tests because last " 540 "block is bad\n"); 541 else { 542 /* Attempt to write off end of device */ 543 ops.mode = MTD_OPS_AUTO_OOB; 544 ops.len = 0; 545 ops.retlen = 0; 546 ops.ooblen = mtd->oobavail + 1; 547 ops.oobretlen = 0; 548 ops.ooboffs = 0; 549 ops.datbuf = NULL; 550 ops.oobbuf = writebuf; 551 pr_info("attempting to write past end of device\n"); 552 pr_info("an error is expected...\n"); 553 err = mtd_write_oob(mtd, mtd->size - mtd->writesize, &ops); 554 if (err) { 555 pr_info("error occurred as expected\n"); 556 err = 0; 557 } else { 558 pr_err("error: wrote past end of device\n"); 559 errcnt += 1; 560 } 561 562 /* Attempt to read off end of device */ 563 ops.mode = MTD_OPS_AUTO_OOB; 564 ops.len = 0; 565 ops.retlen = 0; 566 ops.ooblen = mtd->oobavail + 1; 567 ops.oobretlen = 0; 568 ops.ooboffs = 0; 569 ops.datbuf = NULL; 570 ops.oobbuf = readbuf; 571 pr_info("attempting to read past end of device\n"); 572 pr_info("an error is expected...\n"); 573 err = mtd_read_oob(mtd, mtd->size - mtd->writesize, &ops); 574 if (mtd_is_bitflip(err)) 575 err = 0; 576 577 if (err) { 578 pr_info("error occurred as expected\n"); 579 err = 0; 580 } else { 581 pr_err("error: read past end of device\n"); 582 errcnt += 1; 583 } 584 585 err = mtdtest_erase_eraseblock(mtd, ebcnt - 1); 586 if (err) 587 goto out; 588 589 /* Attempt to write off end of device */ 590 ops.mode = MTD_OPS_AUTO_OOB; 591 ops.len = 0; 592 ops.retlen = 0; 593 ops.ooblen = mtd->oobavail; 594 ops.oobretlen = 0; 595 ops.ooboffs = 1; 596 ops.datbuf = NULL; 597 ops.oobbuf = writebuf; 598 pr_info("attempting to write past end of device\n"); 599 pr_info("an error is expected...\n"); 600 err = mtd_write_oob(mtd, mtd->size - mtd->writesize, &ops); 601 if (err) { 602 pr_info("error occurred as expected\n"); 603 err = 0; 604 } else { 605 pr_err("error: wrote past end of device\n"); 606 errcnt += 1; 607 } 608 609 /* Attempt to read off end of device */ 610 ops.mode = MTD_OPS_AUTO_OOB; 611 ops.len = 0; 612 ops.retlen = 0; 613 ops.ooblen = mtd->oobavail; 614 ops.oobretlen = 0; 615 ops.ooboffs = 1; 616 ops.datbuf = NULL; 617 ops.oobbuf = readbuf; 618 pr_info("attempting to read past end of device\n"); 619 pr_info("an error is expected...\n"); 620 err = mtd_read_oob(mtd, mtd->size - mtd->writesize, &ops); 621 if (mtd_is_bitflip(err)) 622 err = 0; 623 624 if (err) { 625 pr_info("error occurred as expected\n"); 626 err = 0; 627 } else { 628 pr_err("error: read past end of device\n"); 629 errcnt += 1; 630 } 631 } 632 633 /* Fifth test: write / read across block boundaries */ 634 pr_info("test 5 of 5\n"); 635 636 /* Erase all eraseblocks */ 637 err = mtdtest_erase_good_eraseblocks(mtd, bbt, 0, ebcnt); 638 if (err) 639 goto out; 640 641 /* Write all eraseblocks */ 642 prandom_seed_state(&rnd_state, 11); 643 pr_info("writing OOBs of whole device\n"); 644 for (i = 0; i < ebcnt - 1; ++i) { 645 int cnt = 2; 646 int pg; 647 size_t sz = mtd->oobavail; 648 if (bbt[i] || bbt[i + 1]) 649 continue; 650 addr = (loff_t)(i + 1) * mtd->erasesize - mtd->writesize; 651 prandom_bytes_state(&rnd_state, writebuf, sz * cnt); 652 for (pg = 0; pg < cnt; ++pg) { 653 ops.mode = MTD_OPS_AUTO_OOB; 654 ops.len = 0; 655 ops.retlen = 0; 656 ops.ooblen = sz; 657 ops.oobretlen = 0; 658 ops.ooboffs = 0; 659 ops.datbuf = NULL; 660 ops.oobbuf = writebuf + pg * sz; 661 err = mtd_write_oob(mtd, addr, &ops); 662 if (err) 663 goto out; 664 if (i % 256 == 0) 665 pr_info("written up to eraseblock %u\n", i); 666 667 err = mtdtest_relax(); 668 if (err) 669 goto out; 670 671 addr += mtd->writesize; 672 } 673 } 674 pr_info("written %u eraseblocks\n", i); 675 676 /* Check all eraseblocks */ 677 prandom_seed_state(&rnd_state, 11); 678 pr_info("verifying all eraseblocks\n"); 679 for (i = 0; i < ebcnt - 1; ++i) { 680 if (bbt[i] || bbt[i + 1]) 681 continue; 682 prandom_bytes_state(&rnd_state, writebuf, mtd->oobavail * 2); 683 addr = (loff_t)(i + 1) * mtd->erasesize - mtd->writesize; 684 ops.mode = MTD_OPS_AUTO_OOB; 685 ops.len = 0; 686 ops.retlen = 0; 687 ops.ooblen = mtd->oobavail * 2; 688 ops.oobretlen = 0; 689 ops.ooboffs = 0; 690 ops.datbuf = NULL; 691 ops.oobbuf = readbuf; 692 err = mtd_read_oob(mtd, addr, &ops); 693 if (mtd_is_bitflip(err)) 694 err = 0; 695 696 if (err) 697 goto out; 698 if (memcmpshow(addr, readbuf, writebuf, 699 mtd->oobavail * 2)) { 700 pr_err("error: verify failed at %#llx\n", 701 (long long)addr); 702 errcnt += 1; 703 if (errcnt > 1000) { 704 pr_err("error: too many errors\n"); 705 goto out; 706 } 707 } 708 if (i % 256 == 0) 709 pr_info("verified up to eraseblock %u\n", i); 710 711 err = mtdtest_relax(); 712 if (err) 713 goto out; 714 } 715 pr_info("verified %u eraseblocks\n", i); 716 717 pr_info("finished with %d errors\n", errcnt); 718 out: 719 kfree(bbt); 720 kfree(writebuf); 721 kfree(readbuf); 722 put_mtd_device(mtd); 723 if (err) 724 pr_info("error %d occurred\n", err); 725 printk(KERN_INFO "=================================================\n"); 726 return err; 727 } 728 module_init(mtd_oobtest_init); 729 730 static void __exit mtd_oobtest_exit(void) 731 { 732 return; 733 } 734 module_exit(mtd_oobtest_exit); 735 736 MODULE_DESCRIPTION("Out-of-band test module"); 737 MODULE_AUTHOR("Adrian Hunter"); 738 MODULE_LICENSE("GPL"); 739