aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/tests
diff options
context:
space:
mode:
authorAkinobu Mita <akinobu.mita@gmail.com>2013-08-03 05:52:12 -0400
committerDavid Woodhouse <David.Woodhouse@intel.com>2013-08-30 16:34:19 -0400
commit59b0816d7c7de3c14d6dd59da3baa3deffb973da (patch)
tree8a6c50fd8d9c316604bf25e52c780a79909f399f /drivers/mtd/tests
parentbf9c223664e6f5fdf538919c715c45c26dbb4268 (diff)
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>
Diffstat (limited to 'drivers/mtd/tests')
-rw-r--r--drivers/mtd/tests/speedtest.c180
1 files changed, 36 insertions, 144 deletions
diff --git a/drivers/mtd/tests/speedtest.c b/drivers/mtd/tests/speedtest.c
index 20b63d1ad494..457c45c6a704 100644
--- a/drivers/mtd/tests/speedtest.c
+++ b/drivers/mtd/tests/speedtest.c
@@ -30,6 +30,8 @@
30#include <linux/sched.h> 30#include <linux/sched.h>
31#include <linux/random.h> 31#include <linux/random.h>
32 32
33#include "mtd_test.h"
34
33static int dev = -EINVAL; 35static int dev = -EINVAL;
34module_param(dev, int, S_IRUGO); 36module_param(dev, int, S_IRUGO);
35MODULE_PARM_DESC(dev, "MTD device number to use"); 37MODULE_PARM_DESC(dev, "MTD device number to use");
@@ -49,33 +51,6 @@ static int pgcnt;
49static int goodebcnt; 51static int goodebcnt;
50static struct timeval start, finish; 52static struct timeval start, finish;
51 53
52
53static int erase_eraseblock(int ebnum)
54{
55 int err;
56 struct erase_info ei;
57 loff_t addr = ebnum * mtd->erasesize;
58
59 memset(&ei, 0, sizeof(struct erase_info));
60 ei.mtd = mtd;
61 ei.addr = addr;
62 ei.len = mtd->erasesize;
63
64 err = mtd_erase(mtd, &ei);
65 if (err) {
66 pr_err("error %d while erasing EB %d\n", err, ebnum);
67 return err;
68 }
69
70 if (ei.state == MTD_ERASE_FAILED) {
71 pr_err("some erase error occurred at EB %d\n",
72 ebnum);
73 return -EIO;
74 }
75
76 return 0;
77}
78
79static int multiblock_erase(int ebnum, int blocks) 54static int multiblock_erase(int ebnum, int blocks)
80{ 55{
81 int err; 56 int err;
@@ -103,52 +78,29 @@ static int multiblock_erase(int ebnum, int blocks)
103 return 0; 78 return 0;
104} 79}
105 80
106static int erase_whole_device(void)
107{
108 int err;
109 unsigned int i;
110
111 for (i = 0; i < ebcnt; ++i) {
112 if (bbt[i])
113 continue;
114 err = erase_eraseblock(i);
115 if (err)
116 return err;
117 cond_resched();
118 }
119 return 0;
120}
121
122static int write_eraseblock(int ebnum) 81static int write_eraseblock(int ebnum)
123{ 82{
124 size_t written; 83 int err;
125 int err = 0;
126 loff_t addr = ebnum * mtd->erasesize; 84 loff_t addr = ebnum * mtd->erasesize;
127 85
128 err = mtd_write(mtd, addr, mtd->erasesize, &written, iobuf); 86 err = mtdtest_write(mtd, addr, mtd->erasesize, iobuf);
129 if (err || written != mtd->erasesize) { 87 if (err)
130 pr_err("error: write failed at %#llx\n", addr); 88 pr_err("error: write failed at %#llx\n", addr);
131 if (!err)
132 err = -EINVAL;
133 }
134 89
135 return err; 90 return err;
136} 91}
137 92
138static int write_eraseblock_by_page(int ebnum) 93static int write_eraseblock_by_page(int ebnum)
139{ 94{
140 size_t written;
141 int i, err = 0; 95 int i, err = 0;
142 loff_t addr = ebnum * mtd->erasesize; 96 loff_t addr = ebnum * mtd->erasesize;
143 void *buf = iobuf; 97 void *buf = iobuf;
144 98
145 for (i = 0; i < pgcnt; i++) { 99 for (i = 0; i < pgcnt; i++) {
146 err = mtd_write(mtd, addr, pgsize, &written, buf); 100 err = mtdtest_write(mtd, addr, pgsize, buf);
147 if (err || written != pgsize) { 101 if (err) {
148 pr_err("error: write failed at %#llx\n", 102 pr_err("error: write failed at %#llx\n",
149 addr); 103 addr);
150 if (!err)
151 err = -EINVAL;
152 break; 104 break;
153 } 105 }
154 addr += pgsize; 106 addr += pgsize;
@@ -160,30 +112,26 @@ static int write_eraseblock_by_page(int ebnum)
160 112
161static int write_eraseblock_by_2pages(int ebnum) 113static int write_eraseblock_by_2pages(int ebnum)
162{ 114{
163 size_t written, sz = pgsize * 2; 115 size_t sz = pgsize * 2;
164 int i, n = pgcnt / 2, err = 0; 116 int i, n = pgcnt / 2, err = 0;
165 loff_t addr = ebnum * mtd->erasesize; 117 loff_t addr = ebnum * mtd->erasesize;
166 void *buf = iobuf; 118 void *buf = iobuf;
167 119
168 for (i = 0; i < n; i++) { 120 for (i = 0; i < n; i++) {
169 err = mtd_write(mtd, addr, sz, &written, buf); 121 err = mtdtest_write(mtd, addr, sz, buf);
170 if (err || written != sz) { 122 if (err) {
171 pr_err("error: write failed at %#llx\n", 123 pr_err("error: write failed at %#llx\n",
172 addr); 124 addr);
173 if (!err)
174 err = -EINVAL;
175 return err; 125 return err;
176 } 126 }
177 addr += sz; 127 addr += sz;
178 buf += sz; 128 buf += sz;
179 } 129 }
180 if (pgcnt % 2) { 130 if (pgcnt % 2) {
181 err = mtd_write(mtd, addr, pgsize, &written, buf); 131 err = mtdtest_write(mtd, addr, pgsize, buf);
182 if (err || written != pgsize) { 132 if (err) {
183 pr_err("error: write failed at %#llx\n", 133 pr_err("error: write failed at %#llx\n",
184 addr); 134 addr);
185 if (!err)
186 err = -EINVAL;
187 } 135 }
188 } 136 }
189 137
@@ -192,40 +140,27 @@ static int write_eraseblock_by_2pages(int ebnum)
192 140
193static int read_eraseblock(int ebnum) 141static int read_eraseblock(int ebnum)
194{ 142{
195 size_t read; 143 int err;
196 int err = 0;
197 loff_t addr = ebnum * mtd->erasesize; 144 loff_t addr = ebnum * mtd->erasesize;
198 145
199 err = mtd_read(mtd, addr, mtd->erasesize, &read, iobuf); 146 err = mtdtest_read(mtd, addr, mtd->erasesize, iobuf);
200 /* Ignore corrected ECC errors */ 147 if (err)
201 if (mtd_is_bitflip(err))
202 err = 0;
203 if (err || read != mtd->erasesize) {
204 pr_err("error: read failed at %#llx\n", addr); 148 pr_err("error: read failed at %#llx\n", addr);
205 if (!err)
206 err = -EINVAL;
207 }
208 149
209 return err; 150 return err;
210} 151}
211 152
212static int read_eraseblock_by_page(int ebnum) 153static int read_eraseblock_by_page(int ebnum)
213{ 154{
214 size_t read;
215 int i, err = 0; 155 int i, err = 0;
216 loff_t addr = ebnum * mtd->erasesize; 156 loff_t addr = ebnum * mtd->erasesize;
217 void *buf = iobuf; 157 void *buf = iobuf;
218 158
219 for (i = 0; i < pgcnt; i++) { 159 for (i = 0; i < pgcnt; i++) {
220 err = mtd_read(mtd, addr, pgsize, &read, buf); 160 err = mtdtest_read(mtd, addr, pgsize, buf);
221 /* Ignore corrected ECC errors */ 161 if (err) {
222 if (mtd_is_bitflip(err))
223 err = 0;
224 if (err || read != pgsize) {
225 pr_err("error: read failed at %#llx\n", 162 pr_err("error: read failed at %#llx\n",
226 addr); 163 addr);
227 if (!err)
228 err = -EINVAL;
229 break; 164 break;
230 } 165 }
231 addr += pgsize; 166 addr += pgsize;
@@ -237,53 +172,32 @@ static int read_eraseblock_by_page(int ebnum)
237 172
238static int read_eraseblock_by_2pages(int ebnum) 173static int read_eraseblock_by_2pages(int ebnum)
239{ 174{
240 size_t read, sz = pgsize * 2; 175 size_t sz = pgsize * 2;
241 int i, n = pgcnt / 2, err = 0; 176 int i, n = pgcnt / 2, err = 0;
242 loff_t addr = ebnum * mtd->erasesize; 177 loff_t addr = ebnum * mtd->erasesize;
243 void *buf = iobuf; 178 void *buf = iobuf;
244 179
245 for (i = 0; i < n; i++) { 180 for (i = 0; i < n; i++) {
246 err = mtd_read(mtd, addr, sz, &read, buf); 181 err = mtdtest_read(mtd, addr, sz, buf);
247 /* Ignore corrected ECC errors */ 182 if (err) {
248 if (mtd_is_bitflip(err))
249 err = 0;
250 if (err || read != sz) {
251 pr_err("error: read failed at %#llx\n", 183 pr_err("error: read failed at %#llx\n",
252 addr); 184 addr);
253 if (!err)
254 err = -EINVAL;
255 return err; 185 return err;
256 } 186 }
257 addr += sz; 187 addr += sz;
258 buf += sz; 188 buf += sz;
259 } 189 }
260 if (pgcnt % 2) { 190 if (pgcnt % 2) {
261 err = mtd_read(mtd, addr, pgsize, &read, buf); 191 err = mtdtest_read(mtd, addr, pgsize, buf);
262 /* Ignore corrected ECC errors */ 192 if (err) {
263 if (mtd_is_bitflip(err))
264 err = 0;
265 if (err || read != pgsize) {
266 pr_err("error: read failed at %#llx\n", 193 pr_err("error: read failed at %#llx\n",
267 addr); 194 addr);
268 if (!err)
269 err = -EINVAL;
270 } 195 }
271 } 196 }
272 197
273 return err; 198 return err;
274} 199}
275 200
276static int is_block_bad(int ebnum)
277{
278 loff_t addr = ebnum * mtd->erasesize;
279 int ret;
280
281 ret = mtd_block_isbad(mtd, addr);
282 if (ret)
283 pr_info("block %d is bad\n", ebnum);
284 return ret;
285}
286
287static inline void start_timing(void) 201static inline void start_timing(void)
288{ 202{
289 do_gettimeofday(&start); 203 do_gettimeofday(&start);
@@ -308,30 +222,6 @@ static long calc_speed(void)
308 return k; 222 return k;
309} 223}
310 224
311static int scan_for_bad_eraseblocks(void)
312{
313 int i, bad = 0;
314
315 bbt = kzalloc(ebcnt, GFP_KERNEL);
316 if (!bbt)
317 return -ENOMEM;
318
319 if (!mtd_can_have_bb(mtd))
320 goto out;
321
322 pr_info("scanning for bad eraseblocks\n");
323 for (i = 0; i < ebcnt; ++i) {
324 bbt[i] = is_block_bad(i) ? 1 : 0;
325 if (bbt[i])
326 bad += 1;
327 cond_resched();
328 }
329 pr_info("scanned %d eraseblocks, %d are bad\n", i, bad);
330out:
331 goodebcnt = ebcnt - bad;
332 return 0;
333}
334
335static int __init mtd_speedtest_init(void) 225static int __init mtd_speedtest_init(void)
336{ 226{
337 int err, i, blocks, j, k; 227 int err, i, blocks, j, k;
@@ -387,11 +277,18 @@ static int __init mtd_speedtest_init(void)
387 277
388 prandom_bytes(iobuf, mtd->erasesize); 278 prandom_bytes(iobuf, mtd->erasesize);
389 279
390 err = scan_for_bad_eraseblocks(); 280 bbt = kzalloc(ebcnt, GFP_KERNEL);
281 if (!bbt)
282 goto out;
283 err = mtdtest_scan_for_bad_eraseblocks(mtd, bbt, 0, ebcnt);
391 if (err) 284 if (err)
392 goto out; 285 goto out;
286 for (i = 0; i < ebcnt; i++) {
287 if (!bbt[i])
288 goodebcnt++;
289 }
393 290
394 err = erase_whole_device(); 291 err = mtdtest_erase_good_eraseblocks(mtd, bbt, 0, ebcnt);
395 if (err) 292 if (err)
396 goto out; 293 goto out;
397 294
@@ -425,7 +322,7 @@ static int __init mtd_speedtest_init(void)
425 speed = calc_speed(); 322 speed = calc_speed();
426 pr_info("eraseblock read speed is %ld KiB/s\n", speed); 323 pr_info("eraseblock read speed is %ld KiB/s\n", speed);
427 324
428 err = erase_whole_device(); 325 err = mtdtest_erase_good_eraseblocks(mtd, bbt, 0, ebcnt);
429 if (err) 326 if (err)
430 goto out; 327 goto out;
431 328
@@ -459,7 +356,7 @@ static int __init mtd_speedtest_init(void)
459 speed = calc_speed(); 356 speed = calc_speed();
460 pr_info("page read speed is %ld KiB/s\n", speed); 357 pr_info("page read speed is %ld KiB/s\n", speed);
461 358
462 err = erase_whole_device(); 359 err = mtdtest_erase_good_eraseblocks(mtd, bbt, 0, ebcnt);
463 if (err) 360 if (err)
464 goto out; 361 goto out;
465 362
@@ -496,14 +393,9 @@ static int __init mtd_speedtest_init(void)
496 /* Erase all eraseblocks */ 393 /* Erase all eraseblocks */
497 pr_info("Testing erase speed\n"); 394 pr_info("Testing erase speed\n");
498 start_timing(); 395 start_timing();
499 for (i = 0; i < ebcnt; ++i) { 396 err = mtdtest_erase_good_eraseblocks(mtd, bbt, 0, ebcnt);
500 if (bbt[i]) 397 if (err)
501 continue; 398 goto out;
502 err = erase_eraseblock(i);
503 if (err)
504 goto out;
505 cond_resched();
506 }
507 stop_timing(); 399 stop_timing();
508 speed = calc_speed(); 400 speed = calc_speed();
509 pr_info("erase speed is %ld KiB/s\n", speed); 401 pr_info("erase speed is %ld KiB/s\n", speed);