Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mtd: mtd_speedtest: use mtd_test helpers

Use mtdtest_write(), mtdtest_read(), mtdtest_scan_for_bad_eraseblocks(),
mtdtest_erase_good_eraseblocks() in mtd_test helpers.

Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com>
Cc: Brian Norris <computersforpeace@gmail.com>
Cc: Vikram Narayanan <vikram186@gmail.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>

authored by

Akinobu Mita and committed by
David Woodhouse
59b0816d bf9c2236

+36 -144
+36 -144
drivers/mtd/tests/speedtest.c
··· 30 30 #include <linux/sched.h> 31 31 #include <linux/random.h> 32 32 33 + #include "mtd_test.h" 34 + 33 35 static int dev = -EINVAL; 34 36 module_param(dev, int, S_IRUGO); 35 37 MODULE_PARM_DESC(dev, "MTD device number to use"); ··· 50 48 static int pgcnt; 51 49 static int goodebcnt; 52 50 static struct timeval start, finish; 53 - 54 - 55 - static int erase_eraseblock(int ebnum) 56 - { 57 - int err; 58 - struct erase_info ei; 59 - loff_t addr = ebnum * mtd->erasesize; 60 - 61 - memset(&ei, 0, sizeof(struct erase_info)); 62 - ei.mtd = mtd; 63 - ei.addr = addr; 64 - ei.len = mtd->erasesize; 65 - 66 - err = mtd_erase(mtd, &ei); 67 - if (err) { 68 - pr_err("error %d while erasing EB %d\n", err, ebnum); 69 - return err; 70 - } 71 - 72 - if (ei.state == MTD_ERASE_FAILED) { 73 - pr_err("some erase error occurred at EB %d\n", 74 - ebnum); 75 - return -EIO; 76 - } 77 - 78 - return 0; 79 - } 80 51 81 52 static int multiblock_erase(int ebnum, int blocks) 82 53 { ··· 78 103 return 0; 79 104 } 80 105 81 - static int erase_whole_device(void) 82 - { 83 - int err; 84 - unsigned int i; 85 - 86 - for (i = 0; i < ebcnt; ++i) { 87 - if (bbt[i]) 88 - continue; 89 - err = erase_eraseblock(i); 90 - if (err) 91 - return err; 92 - cond_resched(); 93 - } 94 - return 0; 95 - } 96 - 97 106 static int write_eraseblock(int ebnum) 98 107 { 99 - size_t written; 100 - int err = 0; 108 + int err; 101 109 loff_t addr = ebnum * mtd->erasesize; 102 110 103 - err = mtd_write(mtd, addr, mtd->erasesize, &written, iobuf); 104 - if (err || written != mtd->erasesize) { 111 + err = mtdtest_write(mtd, addr, mtd->erasesize, iobuf); 112 + if (err) 105 113 pr_err("error: write failed at %#llx\n", addr); 106 - if (!err) 107 - err = -EINVAL; 108 - } 109 114 110 115 return err; 111 116 } 112 117 113 118 static int write_eraseblock_by_page(int ebnum) 114 119 { 115 - size_t written; 116 120 int i, err = 0; 117 121 loff_t addr = ebnum * mtd->erasesize; 118 122 void *buf = iobuf; 119 123 120 124 for (i = 0; i < pgcnt; i++) { 121 - err = mtd_write(mtd, addr, pgsize, &written, buf); 122 - if (err || written != pgsize) { 125 + err = mtdtest_write(mtd, addr, pgsize, buf); 126 + if (err) { 123 127 pr_err("error: write failed at %#llx\n", 124 128 addr); 125 - if (!err) 126 - err = -EINVAL; 127 129 break; 128 130 } 129 131 addr += pgsize; ··· 112 160 113 161 static int write_eraseblock_by_2pages(int ebnum) 114 162 { 115 - size_t written, sz = pgsize * 2; 163 + size_t sz = pgsize * 2; 116 164 int i, n = pgcnt / 2, err = 0; 117 165 loff_t addr = ebnum * mtd->erasesize; 118 166 void *buf = iobuf; 119 167 120 168 for (i = 0; i < n; i++) { 121 - err = mtd_write(mtd, addr, sz, &written, buf); 122 - if (err || written != sz) { 169 + err = mtdtest_write(mtd, addr, sz, buf); 170 + if (err) { 123 171 pr_err("error: write failed at %#llx\n", 124 172 addr); 125 - if (!err) 126 - err = -EINVAL; 127 173 return err; 128 174 } 129 175 addr += sz; 130 176 buf += sz; 131 177 } 132 178 if (pgcnt % 2) { 133 - err = mtd_write(mtd, addr, pgsize, &written, buf); 134 - if (err || written != pgsize) { 179 + err = mtdtest_write(mtd, addr, pgsize, buf); 180 + if (err) { 135 181 pr_err("error: write failed at %#llx\n", 136 182 addr); 137 - if (!err) 138 - err = -EINVAL; 139 183 } 140 184 } 141 185 ··· 140 192 141 193 static int read_eraseblock(int ebnum) 142 194 { 143 - size_t read; 144 - int err = 0; 195 + int err; 145 196 loff_t addr = ebnum * mtd->erasesize; 146 197 147 - err = mtd_read(mtd, addr, mtd->erasesize, &read, iobuf); 148 - /* Ignore corrected ECC errors */ 149 - if (mtd_is_bitflip(err)) 150 - err = 0; 151 - if (err || read != mtd->erasesize) { 198 + err = mtdtest_read(mtd, addr, mtd->erasesize, iobuf); 199 + if (err) 152 200 pr_err("error: read failed at %#llx\n", addr); 153 - if (!err) 154 - err = -EINVAL; 155 - } 156 201 157 202 return err; 158 203 } 159 204 160 205 static int read_eraseblock_by_page(int ebnum) 161 206 { 162 - size_t read; 163 207 int i, err = 0; 164 208 loff_t addr = ebnum * mtd->erasesize; 165 209 void *buf = iobuf; 166 210 167 211 for (i = 0; i < pgcnt; i++) { 168 - err = mtd_read(mtd, addr, pgsize, &read, buf); 169 - /* Ignore corrected ECC errors */ 170 - if (mtd_is_bitflip(err)) 171 - err = 0; 172 - if (err || read != pgsize) { 212 + err = mtdtest_read(mtd, addr, pgsize, buf); 213 + if (err) { 173 214 pr_err("error: read failed at %#llx\n", 174 215 addr); 175 - if (!err) 176 - err = -EINVAL; 177 216 break; 178 217 } 179 218 addr += pgsize; ··· 172 237 173 238 static int read_eraseblock_by_2pages(int ebnum) 174 239 { 175 - size_t read, sz = pgsize * 2; 240 + size_t sz = pgsize * 2; 176 241 int i, n = pgcnt / 2, err = 0; 177 242 loff_t addr = ebnum * mtd->erasesize; 178 243 void *buf = iobuf; 179 244 180 245 for (i = 0; i < n; i++) { 181 - err = mtd_read(mtd, addr, sz, &read, buf); 182 - /* Ignore corrected ECC errors */ 183 - if (mtd_is_bitflip(err)) 184 - err = 0; 185 - if (err || read != sz) { 246 + err = mtdtest_read(mtd, addr, sz, buf); 247 + if (err) { 186 248 pr_err("error: read failed at %#llx\n", 187 249 addr); 188 - if (!err) 189 - err = -EINVAL; 190 250 return err; 191 251 } 192 252 addr += sz; 193 253 buf += sz; 194 254 } 195 255 if (pgcnt % 2) { 196 - err = mtd_read(mtd, addr, pgsize, &read, buf); 197 - /* Ignore corrected ECC errors */ 198 - if (mtd_is_bitflip(err)) 199 - err = 0; 200 - if (err || read != pgsize) { 256 + err = mtdtest_read(mtd, addr, pgsize, buf); 257 + if (err) { 201 258 pr_err("error: read failed at %#llx\n", 202 259 addr); 203 - if (!err) 204 - err = -EINVAL; 205 260 } 206 261 } 207 262 208 263 return err; 209 - } 210 - 211 - static int is_block_bad(int ebnum) 212 - { 213 - loff_t addr = ebnum * mtd->erasesize; 214 - int ret; 215 - 216 - ret = mtd_block_isbad(mtd, addr); 217 - if (ret) 218 - pr_info("block %d is bad\n", ebnum); 219 - return ret; 220 264 } 221 265 222 266 static inline void start_timing(void) ··· 220 306 k = goodebcnt * (mtd->erasesize / 1024) * 1000; 221 307 do_div(k, ms); 222 308 return k; 223 - } 224 - 225 - static int scan_for_bad_eraseblocks(void) 226 - { 227 - int i, bad = 0; 228 - 229 - bbt = kzalloc(ebcnt, GFP_KERNEL); 230 - if (!bbt) 231 - return -ENOMEM; 232 - 233 - if (!mtd_can_have_bb(mtd)) 234 - goto out; 235 - 236 - pr_info("scanning for bad eraseblocks\n"); 237 - for (i = 0; i < ebcnt; ++i) { 238 - bbt[i] = is_block_bad(i) ? 1 : 0; 239 - if (bbt[i]) 240 - bad += 1; 241 - cond_resched(); 242 - } 243 - pr_info("scanned %d eraseblocks, %d are bad\n", i, bad); 244 - out: 245 - goodebcnt = ebcnt - bad; 246 - return 0; 247 309 } 248 310 249 311 static int __init mtd_speedtest_init(void) ··· 277 387 278 388 prandom_bytes(iobuf, mtd->erasesize); 279 389 280 - err = scan_for_bad_eraseblocks(); 390 + bbt = kzalloc(ebcnt, GFP_KERNEL); 391 + if (!bbt) 392 + goto out; 393 + err = mtdtest_scan_for_bad_eraseblocks(mtd, bbt, 0, ebcnt); 281 394 if (err) 282 395 goto out; 396 + for (i = 0; i < ebcnt; i++) { 397 + if (!bbt[i]) 398 + goodebcnt++; 399 + } 283 400 284 - err = erase_whole_device(); 401 + err = mtdtest_erase_good_eraseblocks(mtd, bbt, 0, ebcnt); 285 402 if (err) 286 403 goto out; 287 404 ··· 322 425 speed = calc_speed(); 323 426 pr_info("eraseblock read speed is %ld KiB/s\n", speed); 324 427 325 - err = erase_whole_device(); 428 + err = mtdtest_erase_good_eraseblocks(mtd, bbt, 0, ebcnt); 326 429 if (err) 327 430 goto out; 328 431 ··· 356 459 speed = calc_speed(); 357 460 pr_info("page read speed is %ld KiB/s\n", speed); 358 461 359 - err = erase_whole_device(); 462 + err = mtdtest_erase_good_eraseblocks(mtd, bbt, 0, ebcnt); 360 463 if (err) 361 464 goto out; 362 465 ··· 393 496 /* Erase all eraseblocks */ 394 497 pr_info("Testing erase speed\n"); 395 498 start_timing(); 396 - for (i = 0; i < ebcnt; ++i) { 397 - if (bbt[i]) 398 - continue; 399 - err = erase_eraseblock(i); 400 - if (err) 401 - goto out; 402 - cond_resched(); 403 - } 499 + err = mtdtest_erase_good_eraseblocks(mtd, bbt, 0, ebcnt); 500 + if (err) 501 + goto out; 404 502 stop_timing(); 405 503 speed = calc_speed(); 406 504 pr_info("erase speed is %ld KiB/s\n", speed);