diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
commit | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch) | |
tree | a8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /drivers/mtd/tests | |
parent | 406089d01562f1e2bf9f089fd7637009ebaad589 (diff) |
Patched in Tegra support.
Diffstat (limited to 'drivers/mtd/tests')
-rw-r--r-- | drivers/mtd/tests/Makefile | 1 | ||||
-rw-r--r-- | drivers/mtd/tests/mtd_nandbiterrs.c | 461 | ||||
-rw-r--r-- | drivers/mtd/tests/mtd_nandecctest.c | 296 | ||||
-rw-r--r-- | drivers/mtd/tests/mtd_oobtest.c | 228 | ||||
-rw-r--r-- | drivers/mtd/tests/mtd_pagetest.c | 242 | ||||
-rw-r--r-- | drivers/mtd/tests/mtd_readtest.c | 66 | ||||
-rw-r--r-- | drivers/mtd/tests/mtd_speedtest.c | 154 | ||||
-rw-r--r-- | drivers/mtd/tests/mtd_stresstest.c | 105 | ||||
-rw-r--r-- | drivers/mtd/tests/mtd_subpagetest.c | 169 | ||||
-rw-r--r-- | drivers/mtd/tests/mtd_torturetest.c | 95 |
10 files changed, 563 insertions, 1254 deletions
diff --git a/drivers/mtd/tests/Makefile b/drivers/mtd/tests/Makefile index bd0065c0d35..b44dcab940d 100644 --- a/drivers/mtd/tests/Makefile +++ b/drivers/mtd/tests/Makefile | |||
@@ -6,4 +6,3 @@ obj-$(CONFIG_MTD_TESTS) += mtd_stresstest.o | |||
6 | obj-$(CONFIG_MTD_TESTS) += mtd_subpagetest.o | 6 | obj-$(CONFIG_MTD_TESTS) += mtd_subpagetest.o |
7 | obj-$(CONFIG_MTD_TESTS) += mtd_torturetest.o | 7 | obj-$(CONFIG_MTD_TESTS) += mtd_torturetest.o |
8 | obj-$(CONFIG_MTD_TESTS) += mtd_nandecctest.o | 8 | obj-$(CONFIG_MTD_TESTS) += mtd_nandecctest.o |
9 | obj-$(CONFIG_MTD_TESTS) += mtd_nandbiterrs.o | ||
diff --git a/drivers/mtd/tests/mtd_nandbiterrs.c b/drivers/mtd/tests/mtd_nandbiterrs.c deleted file mode 100644 index 207bf9a9972..00000000000 --- a/drivers/mtd/tests/mtd_nandbiterrs.c +++ /dev/null | |||
@@ -1,461 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright © 2012 NetCommWireless | ||
3 | * Iwo Mergler <Iwo.Mergler@netcommwireless.com.au> | ||
4 | * | ||
5 | * Test for multi-bit error recovery on a NAND page This mostly tests the | ||
6 | * ECC controller / driver. | ||
7 | * | ||
8 | * There are two test modes: | ||
9 | * | ||
10 | * 0 - artificially inserting bit errors until the ECC fails | ||
11 | * This is the default method and fairly quick. It should | ||
12 | * be independent of the quality of the FLASH. | ||
13 | * | ||
14 | * 1 - re-writing the same pattern repeatedly until the ECC fails. | ||
15 | * This method relies on the physics of NAND FLASH to eventually | ||
16 | * generate '0' bits if '1' has been written sufficient times. | ||
17 | * Depending on the NAND, the first bit errors will appear after | ||
18 | * 1000 or more writes and then will usually snowball, reaching the | ||
19 | * limits of the ECC quickly. | ||
20 | * | ||
21 | * The test stops after 10000 cycles, should your FLASH be | ||
22 | * exceptionally good and not generate bit errors before that. Try | ||
23 | * a different page in that case. | ||
24 | * | ||
25 | * Please note that neither of these tests will significantly 'use up' any | ||
26 | * FLASH endurance. Only a maximum of two erase operations will be performed. | ||
27 | * | ||
28 | * | ||
29 | * This program is free software; you can redistribute it and/or modify it | ||
30 | * under the terms of the GNU General Public License version 2 as published by | ||
31 | * the Free Software Foundation. | ||
32 | * | ||
33 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
34 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
35 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
36 | * more details. | ||
37 | * | ||
38 | * You should have received a copy of the GNU General Public License along with | ||
39 | * this program; see the file COPYING. If not, write to the Free Software | ||
40 | * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
41 | */ | ||
42 | |||
43 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
44 | |||
45 | #include <linux/init.h> | ||
46 | #include <linux/module.h> | ||
47 | #include <linux/moduleparam.h> | ||
48 | #include <linux/mtd/mtd.h> | ||
49 | #include <linux/err.h> | ||
50 | #include <linux/mtd/nand.h> | ||
51 | #include <linux/slab.h> | ||
52 | |||
53 | static int dev; | ||
54 | module_param(dev, int, S_IRUGO); | ||
55 | MODULE_PARM_DESC(dev, "MTD device number to use"); | ||
56 | |||
57 | static unsigned page_offset; | ||
58 | module_param(page_offset, uint, S_IRUGO); | ||
59 | MODULE_PARM_DESC(page_offset, "Page number relative to dev start"); | ||
60 | |||
61 | static unsigned seed; | ||
62 | module_param(seed, uint, S_IRUGO); | ||
63 | MODULE_PARM_DESC(seed, "Random seed"); | ||
64 | |||
65 | static int mode; | ||
66 | module_param(mode, int, S_IRUGO); | ||
67 | MODULE_PARM_DESC(mode, "0=incremental errors, 1=overwrite test"); | ||
68 | |||
69 | static unsigned max_overwrite = 10000; | ||
70 | |||
71 | static loff_t offset; /* Offset of the page we're using. */ | ||
72 | static unsigned eraseblock; /* Eraseblock number for our page. */ | ||
73 | |||
74 | /* We assume that the ECC can correct up to a certain number | ||
75 | * of biterrors per subpage. */ | ||
76 | static unsigned subsize; /* Size of subpages */ | ||
77 | static unsigned subcount; /* Number of subpages per page */ | ||
78 | |||
79 | static struct mtd_info *mtd; /* MTD device */ | ||
80 | |||
81 | static uint8_t *wbuffer; /* One page write / compare buffer */ | ||
82 | static uint8_t *rbuffer; /* One page read buffer */ | ||
83 | |||
84 | /* 'random' bytes from known offsets */ | ||
85 | static uint8_t hash(unsigned offset) | ||
86 | { | ||
87 | unsigned v = offset; | ||
88 | unsigned char c; | ||
89 | v ^= 0x7f7edfd3; | ||
90 | v = v ^ (v >> 3); | ||
91 | v = v ^ (v >> 5); | ||
92 | v = v ^ (v >> 13); | ||
93 | c = v & 0xFF; | ||
94 | /* Reverse bits of result. */ | ||
95 | c = (c & 0x0F) << 4 | (c & 0xF0) >> 4; | ||
96 | c = (c & 0x33) << 2 | (c & 0xCC) >> 2; | ||
97 | c = (c & 0x55) << 1 | (c & 0xAA) >> 1; | ||
98 | return c; | ||
99 | } | ||
100 | |||
101 | static int erase_block(void) | ||
102 | { | ||
103 | int err; | ||
104 | struct erase_info ei; | ||
105 | loff_t addr = eraseblock * mtd->erasesize; | ||
106 | |||
107 | pr_info("erase_block\n"); | ||
108 | |||
109 | memset(&ei, 0, sizeof(struct erase_info)); | ||
110 | ei.mtd = mtd; | ||
111 | ei.addr = addr; | ||
112 | ei.len = mtd->erasesize; | ||
113 | |||
114 | err = mtd_erase(mtd, &ei); | ||
115 | if (err || ei.state == MTD_ERASE_FAILED) { | ||
116 | pr_err("error %d while erasing\n", err); | ||
117 | if (!err) | ||
118 | err = -EIO; | ||
119 | return err; | ||
120 | } | ||
121 | |||
122 | return 0; | ||
123 | } | ||
124 | |||
125 | /* Writes wbuffer to page */ | ||
126 | static int write_page(int log) | ||
127 | { | ||
128 | int err = 0; | ||
129 | size_t written; | ||
130 | |||
131 | if (log) | ||
132 | pr_info("write_page\n"); | ||
133 | |||
134 | err = mtd_write(mtd, offset, mtd->writesize, &written, wbuffer); | ||
135 | if (err || written != mtd->writesize) { | ||
136 | pr_err("error: write failed at %#llx\n", (long long)offset); | ||
137 | if (!err) | ||
138 | err = -EIO; | ||
139 | } | ||
140 | |||
141 | return err; | ||
142 | } | ||
143 | |||
144 | /* Re-writes the data area while leaving the OOB alone. */ | ||
145 | static int rewrite_page(int log) | ||
146 | { | ||
147 | int err = 0; | ||
148 | struct mtd_oob_ops ops; | ||
149 | |||
150 | if (log) | ||
151 | pr_info("rewrite page\n"); | ||
152 | |||
153 | ops.mode = MTD_OPS_RAW; /* No ECC */ | ||
154 | ops.len = mtd->writesize; | ||
155 | ops.retlen = 0; | ||
156 | ops.ooblen = 0; | ||
157 | ops.oobretlen = 0; | ||
158 | ops.ooboffs = 0; | ||
159 | ops.datbuf = wbuffer; | ||
160 | ops.oobbuf = NULL; | ||
161 | |||
162 | err = mtd_write_oob(mtd, offset, &ops); | ||
163 | if (err || ops.retlen != mtd->writesize) { | ||
164 | pr_err("error: write_oob failed (%d)\n", err); | ||
165 | if (!err) | ||
166 | err = -EIO; | ||
167 | } | ||
168 | |||
169 | return err; | ||
170 | } | ||
171 | |||
172 | /* Reads page into rbuffer. Returns number of corrected bit errors (>=0) | ||
173 | * or error (<0) */ | ||
174 | static int read_page(int log) | ||
175 | { | ||
176 | int err = 0; | ||
177 | size_t read; | ||
178 | struct mtd_ecc_stats oldstats; | ||
179 | |||
180 | if (log) | ||
181 | pr_info("read_page\n"); | ||
182 | |||
183 | /* Saving last mtd stats */ | ||
184 | memcpy(&oldstats, &mtd->ecc_stats, sizeof(oldstats)); | ||
185 | |||
186 | err = mtd_read(mtd, offset, mtd->writesize, &read, rbuffer); | ||
187 | if (err == -EUCLEAN) | ||
188 | err = mtd->ecc_stats.corrected - oldstats.corrected; | ||
189 | |||
190 | if (err < 0 || read != mtd->writesize) { | ||
191 | pr_err("error: read failed at %#llx\n", (long long)offset); | ||
192 | if (err >= 0) | ||
193 | err = -EIO; | ||
194 | } | ||
195 | |||
196 | return err; | ||
197 | } | ||
198 | |||
199 | /* Verifies rbuffer against random sequence */ | ||
200 | static int verify_page(int log) | ||
201 | { | ||
202 | unsigned i, errs = 0; | ||
203 | |||
204 | if (log) | ||
205 | pr_info("verify_page\n"); | ||
206 | |||
207 | for (i = 0; i < mtd->writesize; i++) { | ||
208 | if (rbuffer[i] != hash(i+seed)) { | ||
209 | pr_err("Error: page offset %u, expected %02x, got %02x\n", | ||
210 | i, hash(i+seed), rbuffer[i]); | ||
211 | errs++; | ||
212 | } | ||
213 | } | ||
214 | |||
215 | if (errs) | ||
216 | return -EIO; | ||
217 | else | ||
218 | return 0; | ||
219 | } | ||
220 | |||
221 | #define CBIT(v, n) ((v) & (1 << (n))) | ||
222 | #define BCLR(v, n) ((v) = (v) & ~(1 << (n))) | ||
223 | |||
224 | /* Finds the first '1' bit in wbuffer starting at offset 'byte' | ||
225 | * and sets it to '0'. */ | ||
226 | static int insert_biterror(unsigned byte) | ||
227 | { | ||
228 | int bit; | ||
229 | |||
230 | while (byte < mtd->writesize) { | ||
231 | for (bit = 7; bit >= 0; bit--) { | ||
232 | if (CBIT(wbuffer[byte], bit)) { | ||
233 | BCLR(wbuffer[byte], bit); | ||
234 | pr_info("Inserted biterror @ %u/%u\n", byte, bit); | ||
235 | return 0; | ||
236 | } | ||
237 | } | ||
238 | byte++; | ||
239 | } | ||
240 | pr_err("biterror: Failed to find a '1' bit\n"); | ||
241 | return -EIO; | ||
242 | } | ||
243 | |||
244 | /* Writes 'random' data to page and then introduces deliberate bit | ||
245 | * errors into the page, while verifying each step. */ | ||
246 | static int incremental_errors_test(void) | ||
247 | { | ||
248 | int err = 0; | ||
249 | unsigned i; | ||
250 | unsigned errs_per_subpage = 0; | ||
251 | |||
252 | pr_info("incremental biterrors test\n"); | ||
253 | |||
254 | for (i = 0; i < mtd->writesize; i++) | ||
255 | wbuffer[i] = hash(i+seed); | ||
256 | |||
257 | err = write_page(1); | ||
258 | if (err) | ||
259 | goto exit; | ||
260 | |||
261 | while (1) { | ||
262 | |||
263 | err = rewrite_page(1); | ||
264 | if (err) | ||
265 | goto exit; | ||
266 | |||
267 | err = read_page(1); | ||
268 | if (err > 0) | ||
269 | pr_info("Read reported %d corrected bit errors\n", err); | ||
270 | if (err < 0) { | ||
271 | pr_err("After %d biterrors per subpage, read reported error %d\n", | ||
272 | errs_per_subpage, err); | ||
273 | err = 0; | ||
274 | goto exit; | ||
275 | } | ||
276 | |||
277 | err = verify_page(1); | ||
278 | if (err) { | ||
279 | pr_err("ECC failure, read data is incorrect despite read success\n"); | ||
280 | goto exit; | ||
281 | } | ||
282 | |||
283 | pr_info("Successfully corrected %d bit errors per subpage\n", | ||
284 | errs_per_subpage); | ||
285 | |||
286 | for (i = 0; i < subcount; i++) { | ||
287 | err = insert_biterror(i * subsize); | ||
288 | if (err < 0) | ||
289 | goto exit; | ||
290 | } | ||
291 | errs_per_subpage++; | ||
292 | } | ||
293 | |||
294 | exit: | ||
295 | return err; | ||
296 | } | ||
297 | |||
298 | |||
299 | /* Writes 'random' data to page and then re-writes that same data repeatedly. | ||
300 | This eventually develops bit errors (bits written as '1' will slowly become | ||
301 | '0'), which are corrected as far as the ECC is capable of. */ | ||
302 | static int overwrite_test(void) | ||
303 | { | ||
304 | int err = 0; | ||
305 | unsigned i; | ||
306 | unsigned max_corrected = 0; | ||
307 | unsigned opno = 0; | ||
308 | /* We don't expect more than this many correctable bit errors per | ||
309 | * page. */ | ||
310 | #define MAXBITS 512 | ||
311 | static unsigned bitstats[MAXBITS]; /* bit error histogram. */ | ||
312 | |||
313 | memset(bitstats, 0, sizeof(bitstats)); | ||
314 | |||
315 | pr_info("overwrite biterrors test\n"); | ||
316 | |||
317 | for (i = 0; i < mtd->writesize; i++) | ||
318 | wbuffer[i] = hash(i+seed); | ||
319 | |||
320 | err = write_page(1); | ||
321 | if (err) | ||
322 | goto exit; | ||
323 | |||
324 | while (opno < max_overwrite) { | ||
325 | |||
326 | err = rewrite_page(0); | ||
327 | if (err) | ||
328 | break; | ||
329 | |||
330 | err = read_page(0); | ||
331 | if (err >= 0) { | ||
332 | if (err >= MAXBITS) { | ||
333 | pr_info("Implausible number of bit errors corrected\n"); | ||
334 | err = -EIO; | ||
335 | break; | ||
336 | } | ||
337 | bitstats[err]++; | ||
338 | if (err > max_corrected) { | ||
339 | max_corrected = err; | ||
340 | pr_info("Read reported %d corrected bit errors\n", | ||
341 | err); | ||
342 | } | ||
343 | } else { /* err < 0 */ | ||
344 | pr_info("Read reported error %d\n", err); | ||
345 | err = 0; | ||
346 | break; | ||
347 | } | ||
348 | |||
349 | err = verify_page(0); | ||
350 | if (err) { | ||
351 | bitstats[max_corrected] = opno; | ||
352 | pr_info("ECC failure, read data is incorrect despite read success\n"); | ||
353 | break; | ||
354 | } | ||
355 | |||
356 | opno++; | ||
357 | } | ||
358 | |||
359 | /* At this point bitstats[0] contains the number of ops with no bit | ||
360 | * errors, bitstats[1] the number of ops with 1 bit error, etc. */ | ||
361 | pr_info("Bit error histogram (%d operations total):\n", opno); | ||
362 | for (i = 0; i < max_corrected; i++) | ||
363 | pr_info("Page reads with %3d corrected bit errors: %d\n", | ||
364 | i, bitstats[i]); | ||
365 | |||
366 | exit: | ||
367 | return err; | ||
368 | } | ||
369 | |||
370 | static int __init mtd_nandbiterrs_init(void) | ||
371 | { | ||
372 | int err = 0; | ||
373 | |||
374 | printk("\n"); | ||
375 | printk(KERN_INFO "==================================================\n"); | ||
376 | pr_info("MTD device: %d\n", dev); | ||
377 | |||
378 | mtd = get_mtd_device(NULL, dev); | ||
379 | if (IS_ERR(mtd)) { | ||
380 | err = PTR_ERR(mtd); | ||
381 | pr_err("error: cannot get MTD device\n"); | ||
382 | goto exit_mtddev; | ||
383 | } | ||
384 | |||
385 | if (mtd->type != MTD_NANDFLASH) { | ||
386 | pr_info("this test requires NAND flash\n"); | ||
387 | err = -ENODEV; | ||
388 | goto exit_nand; | ||
389 | } | ||
390 | |||
391 | pr_info("MTD device size %llu, eraseblock=%u, page=%u, oob=%u\n", | ||
392 | (unsigned long long)mtd->size, mtd->erasesize, | ||
393 | mtd->writesize, mtd->oobsize); | ||
394 | |||
395 | subsize = mtd->writesize >> mtd->subpage_sft; | ||
396 | subcount = mtd->writesize / subsize; | ||
397 | |||
398 | pr_info("Device uses %d subpages of %d bytes\n", subcount, subsize); | ||
399 | |||
400 | offset = page_offset * mtd->writesize; | ||
401 | eraseblock = mtd_div_by_eb(offset, mtd); | ||
402 | |||
403 | pr_info("Using page=%u, offset=%llu, eraseblock=%u\n", | ||
404 | page_offset, offset, eraseblock); | ||
405 | |||
406 | wbuffer = kmalloc(mtd->writesize, GFP_KERNEL); | ||
407 | if (!wbuffer) { | ||
408 | err = -ENOMEM; | ||
409 | goto exit_wbuffer; | ||
410 | } | ||
411 | |||
412 | rbuffer = kmalloc(mtd->writesize, GFP_KERNEL); | ||
413 | if (!rbuffer) { | ||
414 | err = -ENOMEM; | ||
415 | goto exit_rbuffer; | ||
416 | } | ||
417 | |||
418 | err = erase_block(); | ||
419 | if (err) | ||
420 | goto exit_error; | ||
421 | |||
422 | if (mode == 0) | ||
423 | err = incremental_errors_test(); | ||
424 | else | ||
425 | err = overwrite_test(); | ||
426 | |||
427 | if (err) | ||
428 | goto exit_error; | ||
429 | |||
430 | /* We leave the block un-erased in case of test failure. */ | ||
431 | err = erase_block(); | ||
432 | if (err) | ||
433 | goto exit_error; | ||
434 | |||
435 | err = -EIO; | ||
436 | pr_info("finished successfully.\n"); | ||
437 | printk(KERN_INFO "==================================================\n"); | ||
438 | |||
439 | exit_error: | ||
440 | kfree(rbuffer); | ||
441 | exit_rbuffer: | ||
442 | kfree(wbuffer); | ||
443 | exit_wbuffer: | ||
444 | /* Nothing */ | ||
445 | exit_nand: | ||
446 | put_mtd_device(mtd); | ||
447 | exit_mtddev: | ||
448 | return err; | ||
449 | } | ||
450 | |||
451 | static void __exit mtd_nandbiterrs_exit(void) | ||
452 | { | ||
453 | return; | ||
454 | } | ||
455 | |||
456 | module_init(mtd_nandbiterrs_init); | ||
457 | module_exit(mtd_nandbiterrs_exit); | ||
458 | |||
459 | MODULE_DESCRIPTION("NAND bit error recovery test"); | ||
460 | MODULE_AUTHOR("Iwo Mergler"); | ||
461 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/mtd/tests/mtd_nandecctest.c b/drivers/mtd/tests/mtd_nandecctest.c index 1eee264509a..70d6d7d0d65 100644 --- a/drivers/mtd/tests/mtd_nandecctest.c +++ b/drivers/mtd/tests/mtd_nandecctest.c | |||
@@ -1,292 +1,63 @@ | |||
1 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
2 | |||
3 | #include <linux/kernel.h> | 1 | #include <linux/kernel.h> |
4 | #include <linux/module.h> | 2 | #include <linux/module.h> |
5 | #include <linux/list.h> | 3 | #include <linux/list.h> |
6 | #include <linux/random.h> | 4 | #include <linux/random.h> |
7 | #include <linux/string.h> | 5 | #include <linux/string.h> |
8 | #include <linux/bitops.h> | 6 | #include <linux/bitops.h> |
9 | #include <linux/slab.h> | 7 | #include <linux/jiffies.h> |
10 | #include <linux/mtd/nand_ecc.h> | 8 | #include <linux/mtd/nand_ecc.h> |
11 | 9 | ||
12 | /* | ||
13 | * Test the implementation for software ECC | ||
14 | * | ||
15 | * No actual MTD device is needed, So we don't need to warry about losing | ||
16 | * important data by human error. | ||
17 | * | ||
18 | * This covers possible patterns of corruption which can be reliably corrected | ||
19 | * or detected. | ||
20 | */ | ||
21 | |||
22 | #if defined(CONFIG_MTD_NAND) || defined(CONFIG_MTD_NAND_MODULE) | 10 | #if defined(CONFIG_MTD_NAND) || defined(CONFIG_MTD_NAND_MODULE) |
23 | 11 | ||
24 | struct nand_ecc_test { | 12 | static void inject_single_bit_error(void *data, size_t size) |
25 | const char *name; | ||
26 | void (*prepare)(void *, void *, void *, void *, const size_t); | ||
27 | int (*verify)(void *, void *, void *, const size_t); | ||
28 | }; | ||
29 | |||
30 | /* | ||
31 | * The reason for this __change_bit_le() instead of __change_bit() is to inject | ||
32 | * bit error properly within the region which is not a multiple of | ||
33 | * sizeof(unsigned long) on big-endian systems | ||
34 | */ | ||
35 | #ifdef __LITTLE_ENDIAN | ||
36 | #define __change_bit_le(nr, addr) __change_bit(nr, addr) | ||
37 | #elif defined(__BIG_ENDIAN) | ||
38 | #define __change_bit_le(nr, addr) \ | ||
39 | __change_bit((nr) ^ ((BITS_PER_LONG - 1) & ~0x7), addr) | ||
40 | #else | ||
41 | #error "Unknown byte order" | ||
42 | #endif | ||
43 | |||
44 | static void single_bit_error_data(void *error_data, void *correct_data, | ||
45 | size_t size) | ||
46 | { | 13 | { |
47 | unsigned int offset = random32() % (size * BITS_PER_BYTE); | 14 | unsigned long offset = random32() % (size * BITS_PER_BYTE); |
48 | 15 | ||
49 | memcpy(error_data, correct_data, size); | 16 | __change_bit(offset, data); |
50 | __change_bit_le(offset, error_data); | ||
51 | } | 17 | } |
52 | 18 | ||
53 | static void double_bit_error_data(void *error_data, void *correct_data, | 19 | static unsigned char data[512]; |
54 | size_t size) | 20 | static unsigned char error_data[512]; |
55 | { | ||
56 | unsigned int offset[2]; | ||
57 | |||
58 | offset[0] = random32() % (size * BITS_PER_BYTE); | ||
59 | do { | ||
60 | offset[1] = random32() % (size * BITS_PER_BYTE); | ||
61 | } while (offset[0] == offset[1]); | ||
62 | |||
63 | memcpy(error_data, correct_data, size); | ||
64 | 21 | ||
65 | __change_bit_le(offset[0], error_data); | 22 | static int nand_ecc_test(const size_t size) |
66 | __change_bit_le(offset[1], error_data); | ||
67 | } | ||
68 | |||
69 | static unsigned int random_ecc_bit(size_t size) | ||
70 | { | 23 | { |
71 | unsigned int offset = random32() % (3 * BITS_PER_BYTE); | 24 | unsigned char code[3]; |
72 | 25 | unsigned char error_code[3]; | |
73 | if (size == 256) { | 26 | char testname[30]; |
74 | /* | ||
75 | * Don't inject a bit error into the insignificant bits (16th | ||
76 | * and 17th bit) in ECC code for 256 byte data block | ||
77 | */ | ||
78 | while (offset == 16 || offset == 17) | ||
79 | offset = random32() % (3 * BITS_PER_BYTE); | ||
80 | } | ||
81 | 27 | ||
82 | return offset; | 28 | BUG_ON(sizeof(data) < size); |
83 | } | ||
84 | |||
85 | static void single_bit_error_ecc(void *error_ecc, void *correct_ecc, | ||
86 | size_t size) | ||
87 | { | ||
88 | unsigned int offset = random_ecc_bit(size); | ||
89 | 29 | ||
90 | memcpy(error_ecc, correct_ecc, 3); | 30 | sprintf(testname, "nand-ecc-%zu", size); |
91 | __change_bit_le(offset, error_ecc); | ||
92 | } | ||
93 | 31 | ||
94 | static void double_bit_error_ecc(void *error_ecc, void *correct_ecc, | 32 | get_random_bytes(data, size); |
95 | size_t size) | ||
96 | { | ||
97 | unsigned int offset[2]; | ||
98 | |||
99 | offset[0] = random_ecc_bit(size); | ||
100 | do { | ||
101 | offset[1] = random_ecc_bit(size); | ||
102 | } while (offset[0] == offset[1]); | ||
103 | |||
104 | memcpy(error_ecc, correct_ecc, 3); | ||
105 | __change_bit_le(offset[0], error_ecc); | ||
106 | __change_bit_le(offset[1], error_ecc); | ||
107 | } | ||
108 | |||
109 | static void no_bit_error(void *error_data, void *error_ecc, | ||
110 | void *correct_data, void *correct_ecc, const size_t size) | ||
111 | { | ||
112 | memcpy(error_data, correct_data, size); | ||
113 | memcpy(error_ecc, correct_ecc, 3); | ||
114 | } | ||
115 | |||
116 | static int no_bit_error_verify(void *error_data, void *error_ecc, | ||
117 | void *correct_data, const size_t size) | ||
118 | { | ||
119 | unsigned char calc_ecc[3]; | ||
120 | int ret; | ||
121 | |||
122 | __nand_calculate_ecc(error_data, size, calc_ecc); | ||
123 | ret = __nand_correct_data(error_data, error_ecc, calc_ecc, size); | ||
124 | if (ret == 0 && !memcmp(correct_data, error_data, size)) | ||
125 | return 0; | ||
126 | |||
127 | return -EINVAL; | ||
128 | } | ||
129 | |||
130 | static void single_bit_error_in_data(void *error_data, void *error_ecc, | ||
131 | void *correct_data, void *correct_ecc, const size_t size) | ||
132 | { | ||
133 | single_bit_error_data(error_data, correct_data, size); | ||
134 | memcpy(error_ecc, correct_ecc, 3); | ||
135 | } | ||
136 | 33 | ||
137 | static void single_bit_error_in_ecc(void *error_data, void *error_ecc, | 34 | memcpy(error_data, data, size); |
138 | void *correct_data, void *correct_ecc, const size_t size) | 35 | inject_single_bit_error(error_data, size); |
139 | { | ||
140 | memcpy(error_data, correct_data, size); | ||
141 | single_bit_error_ecc(error_ecc, correct_ecc, size); | ||
142 | } | ||
143 | 36 | ||
144 | static int single_bit_error_correct(void *error_data, void *error_ecc, | 37 | __nand_calculate_ecc(data, size, code); |
145 | void *correct_data, const size_t size) | 38 | __nand_calculate_ecc(error_data, size, error_code); |
146 | { | 39 | __nand_correct_data(error_data, code, error_code, size); |
147 | unsigned char calc_ecc[3]; | ||
148 | int ret; | ||
149 | 40 | ||
150 | __nand_calculate_ecc(error_data, size, calc_ecc); | 41 | if (!memcmp(data, error_data, size)) { |
151 | ret = __nand_correct_data(error_data, error_ecc, calc_ecc, size); | 42 | printk(KERN_INFO "mtd_nandecctest: ok - %s\n", testname); |
152 | if (ret == 1 && !memcmp(correct_data, error_data, size)) | ||
153 | return 0; | 43 | return 0; |
154 | |||
155 | return -EINVAL; | ||
156 | } | ||
157 | |||
158 | static void double_bit_error_in_data(void *error_data, void *error_ecc, | ||
159 | void *correct_data, void *correct_ecc, const size_t size) | ||
160 | { | ||
161 | double_bit_error_data(error_data, correct_data, size); | ||
162 | memcpy(error_ecc, correct_ecc, 3); | ||
163 | } | ||
164 | |||
165 | static void single_bit_error_in_data_and_ecc(void *error_data, void *error_ecc, | ||
166 | void *correct_data, void *correct_ecc, const size_t size) | ||
167 | { | ||
168 | single_bit_error_data(error_data, correct_data, size); | ||
169 | single_bit_error_ecc(error_ecc, correct_ecc, size); | ||
170 | } | ||
171 | |||
172 | static void double_bit_error_in_ecc(void *error_data, void *error_ecc, | ||
173 | void *correct_data, void *correct_ecc, const size_t size) | ||
174 | { | ||
175 | memcpy(error_data, correct_data, size); | ||
176 | double_bit_error_ecc(error_ecc, correct_ecc, size); | ||
177 | } | ||
178 | |||
179 | static int double_bit_error_detect(void *error_data, void *error_ecc, | ||
180 | void *correct_data, const size_t size) | ||
181 | { | ||
182 | unsigned char calc_ecc[3]; | ||
183 | int ret; | ||
184 | |||
185 | __nand_calculate_ecc(error_data, size, calc_ecc); | ||
186 | ret = __nand_correct_data(error_data, error_ecc, calc_ecc, size); | ||
187 | |||
188 | return (ret == -1) ? 0 : -EINVAL; | ||
189 | } | ||
190 | |||
191 | static const struct nand_ecc_test nand_ecc_test[] = { | ||
192 | { | ||
193 | .name = "no-bit-error", | ||
194 | .prepare = no_bit_error, | ||
195 | .verify = no_bit_error_verify, | ||
196 | }, | ||
197 | { | ||
198 | .name = "single-bit-error-in-data-correct", | ||
199 | .prepare = single_bit_error_in_data, | ||
200 | .verify = single_bit_error_correct, | ||
201 | }, | ||
202 | { | ||
203 | .name = "single-bit-error-in-ecc-correct", | ||
204 | .prepare = single_bit_error_in_ecc, | ||
205 | .verify = single_bit_error_correct, | ||
206 | }, | ||
207 | { | ||
208 | .name = "double-bit-error-in-data-detect", | ||
209 | .prepare = double_bit_error_in_data, | ||
210 | .verify = double_bit_error_detect, | ||
211 | }, | ||
212 | { | ||
213 | .name = "single-bit-error-in-data-and-ecc-detect", | ||
214 | .prepare = single_bit_error_in_data_and_ecc, | ||
215 | .verify = double_bit_error_detect, | ||
216 | }, | ||
217 | { | ||
218 | .name = "double-bit-error-in-ecc-detect", | ||
219 | .prepare = double_bit_error_in_ecc, | ||
220 | .verify = double_bit_error_detect, | ||
221 | }, | ||
222 | }; | ||
223 | |||
224 | static void dump_data_ecc(void *error_data, void *error_ecc, void *correct_data, | ||
225 | void *correct_ecc, const size_t size) | ||
226 | { | ||
227 | pr_info("hexdump of error data:\n"); | ||
228 | print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 4, | ||
229 | error_data, size, false); | ||
230 | print_hex_dump(KERN_INFO, "hexdump of error ecc: ", | ||
231 | DUMP_PREFIX_NONE, 16, 1, error_ecc, 3, false); | ||
232 | |||
233 | pr_info("hexdump of correct data:\n"); | ||
234 | print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 4, | ||
235 | correct_data, size, false); | ||
236 | print_hex_dump(KERN_INFO, "hexdump of correct ecc: ", | ||
237 | DUMP_PREFIX_NONE, 16, 1, correct_ecc, 3, false); | ||
238 | } | ||
239 | |||
240 | static int nand_ecc_test_run(const size_t size) | ||
241 | { | ||
242 | int i; | ||
243 | int err = 0; | ||
244 | void *error_data; | ||
245 | void *error_ecc; | ||
246 | void *correct_data; | ||
247 | void *correct_ecc; | ||
248 | |||
249 | error_data = kmalloc(size, GFP_KERNEL); | ||
250 | error_ecc = kmalloc(3, GFP_KERNEL); | ||
251 | correct_data = kmalloc(size, GFP_KERNEL); | ||
252 | correct_ecc = kmalloc(3, GFP_KERNEL); | ||
253 | |||
254 | if (!error_data || !error_ecc || !correct_data || !correct_ecc) { | ||
255 | err = -ENOMEM; | ||
256 | goto error; | ||
257 | } | 44 | } |
258 | 45 | ||
259 | get_random_bytes(correct_data, size); | 46 | printk(KERN_ERR "mtd_nandecctest: not ok - %s\n", testname); |
260 | __nand_calculate_ecc(correct_data, size, correct_ecc); | ||
261 | 47 | ||
262 | for (i = 0; i < ARRAY_SIZE(nand_ecc_test); i++) { | 48 | printk(KERN_DEBUG "hexdump of data:\n"); |
263 | nand_ecc_test[i].prepare(error_data, error_ecc, | 49 | print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 16, 4, |
264 | correct_data, correct_ecc, size); | 50 | data, size, false); |
265 | err = nand_ecc_test[i].verify(error_data, error_ecc, | 51 | printk(KERN_DEBUG "hexdump of error data:\n"); |
266 | correct_data, size); | 52 | print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 16, 4, |
267 | 53 | error_data, size, false); | |
268 | if (err) { | ||
269 | pr_err("not ok - %s-%zd\n", | ||
270 | nand_ecc_test[i].name, size); | ||
271 | dump_data_ecc(error_data, error_ecc, | ||
272 | correct_data, correct_ecc, size); | ||
273 | break; | ||
274 | } | ||
275 | pr_info("ok - %s-%zd\n", | ||
276 | nand_ecc_test[i].name, size); | ||
277 | } | ||
278 | error: | ||
279 | kfree(error_data); | ||
280 | kfree(error_ecc); | ||
281 | kfree(correct_data); | ||
282 | kfree(correct_ecc); | ||
283 | 54 | ||
284 | return err; | 55 | return -1; |
285 | } | 56 | } |
286 | 57 | ||
287 | #else | 58 | #else |
288 | 59 | ||
289 | static int nand_ecc_test_run(const size_t size) | 60 | static int nand_ecc_test(const size_t size) |
290 | { | 61 | { |
291 | return 0; | 62 | return 0; |
292 | } | 63 | } |
@@ -295,13 +66,12 @@ static int nand_ecc_test_run(const size_t size) | |||
295 | 66 | ||
296 | static int __init ecc_test_init(void) | 67 | static int __init ecc_test_init(void) |
297 | { | 68 | { |
298 | int err; | 69 | srandom32(jiffies); |
299 | 70 | ||
300 | err = nand_ecc_test_run(256); | 71 | nand_ecc_test(256); |
301 | if (err) | 72 | nand_ecc_test(512); |
302 | return err; | ||
303 | 73 | ||
304 | return nand_ecc_test_run(512); | 74 | return 0; |
305 | } | 75 | } |
306 | 76 | ||
307 | static void __exit ecc_test_exit(void) | 77 | static void __exit ecc_test_exit(void) |
diff --git a/drivers/mtd/tests/mtd_oobtest.c b/drivers/mtd/tests/mtd_oobtest.c index e827fa8cd84..dec92ae6111 100644 --- a/drivers/mtd/tests/mtd_oobtest.c +++ b/drivers/mtd/tests/mtd_oobtest.c | |||
@@ -19,8 +19,6 @@ | |||
19 | * Author: Adrian Hunter <ext-adrian.hunter@nokia.com> | 19 | * Author: Adrian Hunter <ext-adrian.hunter@nokia.com> |
20 | */ | 20 | */ |
21 | 21 | ||
22 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
23 | |||
24 | #include <asm/div64.h> | 22 | #include <asm/div64.h> |
25 | #include <linux/init.h> | 23 | #include <linux/init.h> |
26 | #include <linux/module.h> | 24 | #include <linux/module.h> |
@@ -30,7 +28,9 @@ | |||
30 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
31 | #include <linux/sched.h> | 29 | #include <linux/sched.h> |
32 | 30 | ||
33 | static int dev = -EINVAL; | 31 | #define PRINT_PREF KERN_INFO "mtd_oobtest: " |
32 | |||
33 | static int dev; | ||
34 | module_param(dev, int, S_IRUGO); | 34 | module_param(dev, int, S_IRUGO); |
35 | MODULE_PARM_DESC(dev, "MTD device number to use"); | 35 | MODULE_PARM_DESC(dev, "MTD device number to use"); |
36 | 36 | ||
@@ -78,14 +78,15 @@ static int erase_eraseblock(int ebnum) | |||
78 | ei.addr = addr; | 78 | ei.addr = addr; |
79 | ei.len = mtd->erasesize; | 79 | ei.len = mtd->erasesize; |
80 | 80 | ||
81 | err = mtd_erase(mtd, &ei); | 81 | err = mtd->erase(mtd, &ei); |
82 | if (err) { | 82 | if (err) { |
83 | pr_err("error %d while erasing EB %d\n", err, ebnum); | 83 | printk(PRINT_PREF "error %d while erasing EB %d\n", err, ebnum); |
84 | return err; | 84 | return err; |
85 | } | 85 | } |
86 | 86 | ||
87 | if (ei.state == MTD_ERASE_FAILED) { | 87 | if (ei.state == MTD_ERASE_FAILED) { |
88 | pr_err("some erase error occurred at EB %d\n", ebnum); | 88 | printk(PRINT_PREF "some erase error occurred at EB %d\n", |
89 | ebnum); | ||
89 | return -EIO; | 90 | return -EIO; |
90 | } | 91 | } |
91 | 92 | ||
@@ -97,7 +98,7 @@ static int erase_whole_device(void) | |||
97 | int err; | 98 | int err; |
98 | unsigned int i; | 99 | unsigned int i; |
99 | 100 | ||
100 | pr_info("erasing whole device\n"); | 101 | printk(PRINT_PREF "erasing whole device\n"); |
101 | for (i = 0; i < ebcnt; ++i) { | 102 | for (i = 0; i < ebcnt; ++i) { |
102 | if (bbt[i]) | 103 | if (bbt[i]) |
103 | continue; | 104 | continue; |
@@ -106,7 +107,7 @@ static int erase_whole_device(void) | |||
106 | return err; | 107 | return err; |
107 | cond_resched(); | 108 | cond_resched(); |
108 | } | 109 | } |
109 | pr_info("erased %u eraseblocks\n", i); | 110 | printk(PRINT_PREF "erased %u eraseblocks\n", i); |
110 | return 0; | 111 | return 0; |
111 | } | 112 | } |
112 | 113 | ||
@@ -130,7 +131,7 @@ static int write_eraseblock(int ebnum) | |||
130 | 131 | ||
131 | for (i = 0; i < pgcnt; ++i, addr += mtd->writesize) { | 132 | for (i = 0; i < pgcnt; ++i, addr += mtd->writesize) { |
132 | set_random_data(writebuf, use_len); | 133 | set_random_data(writebuf, use_len); |
133 | ops.mode = MTD_OPS_AUTO_OOB; | 134 | ops.mode = MTD_OOB_AUTO; |
134 | ops.len = 0; | 135 | ops.len = 0; |
135 | ops.retlen = 0; | 136 | ops.retlen = 0; |
136 | ops.ooblen = use_len; | 137 | ops.ooblen = use_len; |
@@ -138,11 +139,11 @@ static int write_eraseblock(int ebnum) | |||
138 | ops.ooboffs = use_offset; | 139 | ops.ooboffs = use_offset; |
139 | ops.datbuf = NULL; | 140 | ops.datbuf = NULL; |
140 | ops.oobbuf = writebuf; | 141 | ops.oobbuf = writebuf; |
141 | err = mtd_write_oob(mtd, addr, &ops); | 142 | err = mtd->write_oob(mtd, addr, &ops); |
142 | if (err || ops.oobretlen != use_len) { | 143 | if (err || ops.oobretlen != use_len) { |
143 | pr_err("error: writeoob failed at %#llx\n", | 144 | printk(PRINT_PREF "error: writeoob failed at %#llx\n", |
144 | (long long)addr); | 145 | (long long)addr); |
145 | pr_err("error: use_len %d, use_offset %d\n", | 146 | printk(PRINT_PREF "error: use_len %d, use_offset %d\n", |
146 | use_len, use_offset); | 147 | use_len, use_offset); |
147 | errcnt += 1; | 148 | errcnt += 1; |
148 | return err ? err : -1; | 149 | return err ? err : -1; |
@@ -159,7 +160,7 @@ static int write_whole_device(void) | |||
159 | int err; | 160 | int err; |
160 | unsigned int i; | 161 | unsigned int i; |
161 | 162 | ||
162 | pr_info("writing OOBs of whole device\n"); | 163 | printk(PRINT_PREF "writing OOBs of whole device\n"); |
163 | for (i = 0; i < ebcnt; ++i) { | 164 | for (i = 0; i < ebcnt; ++i) { |
164 | if (bbt[i]) | 165 | if (bbt[i]) |
165 | continue; | 166 | continue; |
@@ -167,10 +168,10 @@ static int write_whole_device(void) | |||
167 | if (err) | 168 | if (err) |
168 | return err; | 169 | return err; |
169 | if (i % 256 == 0) | 170 | if (i % 256 == 0) |
170 | pr_info("written up to eraseblock %u\n", i); | 171 | printk(PRINT_PREF "written up to eraseblock %u\n", i); |
171 | cond_resched(); | 172 | cond_resched(); |
172 | } | 173 | } |
173 | pr_info("written %u eraseblocks\n", i); | 174 | printk(PRINT_PREF "written %u eraseblocks\n", i); |
174 | return 0; | 175 | return 0; |
175 | } | 176 | } |
176 | 177 | ||
@@ -183,7 +184,7 @@ static int verify_eraseblock(int ebnum) | |||
183 | 184 | ||
184 | for (i = 0; i < pgcnt; ++i, addr += mtd->writesize) { | 185 | for (i = 0; i < pgcnt; ++i, addr += mtd->writesize) { |
185 | set_random_data(writebuf, use_len); | 186 | set_random_data(writebuf, use_len); |
186 | ops.mode = MTD_OPS_AUTO_OOB; | 187 | ops.mode = MTD_OOB_AUTO; |
187 | ops.len = 0; | 188 | ops.len = 0; |
188 | ops.retlen = 0; | 189 | ops.retlen = 0; |
189 | ops.ooblen = use_len; | 190 | ops.ooblen = use_len; |
@@ -191,26 +192,26 @@ static int verify_eraseblock(int ebnum) | |||
191 | ops.ooboffs = use_offset; | 192 | ops.ooboffs = use_offset; |
192 | ops.datbuf = NULL; | 193 | ops.datbuf = NULL; |
193 | ops.oobbuf = readbuf; | 194 | ops.oobbuf = readbuf; |
194 | err = mtd_read_oob(mtd, addr, &ops); | 195 | err = mtd->read_oob(mtd, addr, &ops); |
195 | if (err || ops.oobretlen != use_len) { | 196 | if (err || ops.oobretlen != use_len) { |
196 | pr_err("error: readoob failed at %#llx\n", | 197 | printk(PRINT_PREF "error: readoob failed at %#llx\n", |
197 | (long long)addr); | 198 | (long long)addr); |
198 | errcnt += 1; | 199 | errcnt += 1; |
199 | return err ? err : -1; | 200 | return err ? err : -1; |
200 | } | 201 | } |
201 | if (memcmp(readbuf, writebuf, use_len)) { | 202 | if (memcmp(readbuf, writebuf, use_len)) { |
202 | pr_err("error: verify failed at %#llx\n", | 203 | printk(PRINT_PREF "error: verify failed at %#llx\n", |
203 | (long long)addr); | 204 | (long long)addr); |
204 | errcnt += 1; | 205 | errcnt += 1; |
205 | if (errcnt > 1000) { | 206 | if (errcnt > 1000) { |
206 | pr_err("error: too many errors\n"); | 207 | printk(PRINT_PREF "error: too many errors\n"); |
207 | return -1; | 208 | return -1; |
208 | } | 209 | } |
209 | } | 210 | } |
210 | if (use_offset != 0 || use_len < mtd->ecclayout->oobavail) { | 211 | if (use_offset != 0 || use_len < mtd->ecclayout->oobavail) { |
211 | int k; | 212 | int k; |
212 | 213 | ||
213 | ops.mode = MTD_OPS_AUTO_OOB; | 214 | ops.mode = MTD_OOB_AUTO; |
214 | ops.len = 0; | 215 | ops.len = 0; |
215 | ops.retlen = 0; | 216 | ops.retlen = 0; |
216 | ops.ooblen = mtd->ecclayout->oobavail; | 217 | ops.ooblen = mtd->ecclayout->oobavail; |
@@ -218,30 +219,31 @@ static int verify_eraseblock(int ebnum) | |||
218 | ops.ooboffs = 0; | 219 | ops.ooboffs = 0; |
219 | ops.datbuf = NULL; | 220 | ops.datbuf = NULL; |
220 | ops.oobbuf = readbuf; | 221 | ops.oobbuf = readbuf; |
221 | err = mtd_read_oob(mtd, addr, &ops); | 222 | err = mtd->read_oob(mtd, addr, &ops); |
222 | if (err || ops.oobretlen != mtd->ecclayout->oobavail) { | 223 | if (err || ops.oobretlen != mtd->ecclayout->oobavail) { |
223 | pr_err("error: readoob failed at %#llx\n", | 224 | printk(PRINT_PREF "error: readoob failed at " |
224 | (long long)addr); | 225 | "%#llx\n", (long long)addr); |
225 | errcnt += 1; | 226 | errcnt += 1; |
226 | return err ? err : -1; | 227 | return err ? err : -1; |
227 | } | 228 | } |
228 | if (memcmp(readbuf + use_offset, writebuf, use_len)) { | 229 | if (memcmp(readbuf + use_offset, writebuf, use_len)) { |
229 | pr_err("error: verify failed at %#llx\n", | 230 | printk(PRINT_PREF "error: verify failed at " |
230 | (long long)addr); | 231 | "%#llx\n", (long long)addr); |
231 | errcnt += 1; | 232 | errcnt += 1; |
232 | if (errcnt > 1000) { | 233 | if (errcnt > 1000) { |
233 | pr_err("error: too many errors\n"); | 234 | printk(PRINT_PREF "error: too many " |
235 | "errors\n"); | ||
234 | return -1; | 236 | return -1; |
235 | } | 237 | } |
236 | } | 238 | } |
237 | for (k = 0; k < use_offset; ++k) | 239 | for (k = 0; k < use_offset; ++k) |
238 | if (readbuf[k] != 0xff) { | 240 | if (readbuf[k] != 0xff) { |
239 | pr_err("error: verify 0xff " | 241 | printk(PRINT_PREF "error: verify 0xff " |
240 | "failed at %#llx\n", | 242 | "failed at %#llx\n", |
241 | (long long)addr); | 243 | (long long)addr); |
242 | errcnt += 1; | 244 | errcnt += 1; |
243 | if (errcnt > 1000) { | 245 | if (errcnt > 1000) { |
244 | pr_err("error: too " | 246 | printk(PRINT_PREF "error: too " |
245 | "many errors\n"); | 247 | "many errors\n"); |
246 | return -1; | 248 | return -1; |
247 | } | 249 | } |
@@ -249,12 +251,12 @@ static int verify_eraseblock(int ebnum) | |||
249 | for (k = use_offset + use_len; | 251 | for (k = use_offset + use_len; |
250 | k < mtd->ecclayout->oobavail; ++k) | 252 | k < mtd->ecclayout->oobavail; ++k) |
251 | if (readbuf[k] != 0xff) { | 253 | if (readbuf[k] != 0xff) { |
252 | pr_err("error: verify 0xff " | 254 | printk(PRINT_PREF "error: verify 0xff " |
253 | "failed at %#llx\n", | 255 | "failed at %#llx\n", |
254 | (long long)addr); | 256 | (long long)addr); |
255 | errcnt += 1; | 257 | errcnt += 1; |
256 | if (errcnt > 1000) { | 258 | if (errcnt > 1000) { |
257 | pr_err("error: too " | 259 | printk(PRINT_PREF "error: too " |
258 | "many errors\n"); | 260 | "many errors\n"); |
259 | return -1; | 261 | return -1; |
260 | } | 262 | } |
@@ -274,7 +276,7 @@ static int verify_eraseblock_in_one_go(int ebnum) | |||
274 | size_t len = mtd->ecclayout->oobavail * pgcnt; | 276 | size_t len = mtd->ecclayout->oobavail * pgcnt; |
275 | 277 | ||
276 | set_random_data(writebuf, len); | 278 | set_random_data(writebuf, len); |
277 | ops.mode = MTD_OPS_AUTO_OOB; | 279 | ops.mode = MTD_OOB_AUTO; |
278 | ops.len = 0; | 280 | ops.len = 0; |
279 | ops.retlen = 0; | 281 | ops.retlen = 0; |
280 | ops.ooblen = len; | 282 | ops.ooblen = len; |
@@ -282,19 +284,19 @@ static int verify_eraseblock_in_one_go(int ebnum) | |||
282 | ops.ooboffs = 0; | 284 | ops.ooboffs = 0; |
283 | ops.datbuf = NULL; | 285 | ops.datbuf = NULL; |
284 | ops.oobbuf = readbuf; | 286 | ops.oobbuf = readbuf; |
285 | err = mtd_read_oob(mtd, addr, &ops); | 287 | err = mtd->read_oob(mtd, addr, &ops); |
286 | if (err || ops.oobretlen != len) { | 288 | if (err || ops.oobretlen != len) { |
287 | pr_err("error: readoob failed at %#llx\n", | 289 | printk(PRINT_PREF "error: readoob failed at %#llx\n", |
288 | (long long)addr); | 290 | (long long)addr); |
289 | errcnt += 1; | 291 | errcnt += 1; |
290 | return err ? err : -1; | 292 | return err ? err : -1; |
291 | } | 293 | } |
292 | if (memcmp(readbuf, writebuf, len)) { | 294 | if (memcmp(readbuf, writebuf, len)) { |
293 | pr_err("error: verify failed at %#llx\n", | 295 | printk(PRINT_PREF "error: verify failed at %#llx\n", |
294 | (long long)addr); | 296 | (long long)addr); |
295 | errcnt += 1; | 297 | errcnt += 1; |
296 | if (errcnt > 1000) { | 298 | if (errcnt > 1000) { |
297 | pr_err("error: too many errors\n"); | 299 | printk(PRINT_PREF "error: too many errors\n"); |
298 | return -1; | 300 | return -1; |
299 | } | 301 | } |
300 | } | 302 | } |
@@ -307,7 +309,7 @@ static int verify_all_eraseblocks(void) | |||
307 | int err; | 309 | int err; |
308 | unsigned int i; | 310 | unsigned int i; |
309 | 311 | ||
310 | pr_info("verifying all eraseblocks\n"); | 312 | printk(PRINT_PREF "verifying all eraseblocks\n"); |
311 | for (i = 0; i < ebcnt; ++i) { | 313 | for (i = 0; i < ebcnt; ++i) { |
312 | if (bbt[i]) | 314 | if (bbt[i]) |
313 | continue; | 315 | continue; |
@@ -315,10 +317,10 @@ static int verify_all_eraseblocks(void) | |||
315 | if (err) | 317 | if (err) |
316 | return err; | 318 | return err; |
317 | if (i % 256 == 0) | 319 | if (i % 256 == 0) |
318 | pr_info("verified up to eraseblock %u\n", i); | 320 | printk(PRINT_PREF "verified up to eraseblock %u\n", i); |
319 | cond_resched(); | 321 | cond_resched(); |
320 | } | 322 | } |
321 | pr_info("verified %u eraseblocks\n", i); | 323 | printk(PRINT_PREF "verified %u eraseblocks\n", i); |
322 | return 0; | 324 | return 0; |
323 | } | 325 | } |
324 | 326 | ||
@@ -327,9 +329,9 @@ static int is_block_bad(int ebnum) | |||
327 | int ret; | 329 | int ret; |
328 | loff_t addr = ebnum * mtd->erasesize; | 330 | loff_t addr = ebnum * mtd->erasesize; |
329 | 331 | ||
330 | ret = mtd_block_isbad(mtd, addr); | 332 | ret = mtd->block_isbad(mtd, addr); |
331 | if (ret) | 333 | if (ret) |
332 | pr_info("block %d is bad\n", ebnum); | 334 | printk(PRINT_PREF "block %d is bad\n", ebnum); |
333 | return ret; | 335 | return ret; |
334 | } | 336 | } |
335 | 337 | ||
@@ -339,18 +341,18 @@ static int scan_for_bad_eraseblocks(void) | |||
339 | 341 | ||
340 | bbt = kmalloc(ebcnt, GFP_KERNEL); | 342 | bbt = kmalloc(ebcnt, GFP_KERNEL); |
341 | if (!bbt) { | 343 | if (!bbt) { |
342 | pr_err("error: cannot allocate memory\n"); | 344 | printk(PRINT_PREF "error: cannot allocate memory\n"); |
343 | return -ENOMEM; | 345 | return -ENOMEM; |
344 | } | 346 | } |
345 | 347 | ||
346 | pr_info("scanning for bad eraseblocks\n"); | 348 | printk(PRINT_PREF "scanning for bad eraseblocks\n"); |
347 | for (i = 0; i < ebcnt; ++i) { | 349 | for (i = 0; i < ebcnt; ++i) { |
348 | bbt[i] = is_block_bad(i) ? 1 : 0; | 350 | bbt[i] = is_block_bad(i) ? 1 : 0; |
349 | if (bbt[i]) | 351 | if (bbt[i]) |
350 | bad += 1; | 352 | bad += 1; |
351 | cond_resched(); | 353 | cond_resched(); |
352 | } | 354 | } |
353 | pr_info("scanned %d eraseblocks, %d are bad\n", i, bad); | 355 | printk(PRINT_PREF "scanned %d eraseblocks, %d are bad\n", i, bad); |
354 | return 0; | 356 | return 0; |
355 | } | 357 | } |
356 | 358 | ||
@@ -364,24 +366,17 @@ static int __init mtd_oobtest_init(void) | |||
364 | 366 | ||
365 | printk(KERN_INFO "\n"); | 367 | printk(KERN_INFO "\n"); |
366 | printk(KERN_INFO "=================================================\n"); | 368 | printk(KERN_INFO "=================================================\n"); |
367 | 369 | printk(PRINT_PREF "MTD device: %d\n", dev); | |
368 | if (dev < 0) { | ||
369 | pr_info("Please specify a valid mtd-device via module parameter\n"); | ||
370 | pr_crit("CAREFUL: This test wipes all data on the specified MTD device!\n"); | ||
371 | return -EINVAL; | ||
372 | } | ||
373 | |||
374 | pr_info("MTD device: %d\n", dev); | ||
375 | 370 | ||
376 | mtd = get_mtd_device(NULL, dev); | 371 | mtd = get_mtd_device(NULL, dev); |
377 | if (IS_ERR(mtd)) { | 372 | if (IS_ERR(mtd)) { |
378 | err = PTR_ERR(mtd); | 373 | err = PTR_ERR(mtd); |
379 | pr_err("error: cannot get MTD device\n"); | 374 | printk(PRINT_PREF "error: cannot get MTD device\n"); |
380 | return err; | 375 | return err; |
381 | } | 376 | } |
382 | 377 | ||
383 | if (mtd->type != MTD_NANDFLASH) { | 378 | if (mtd->type != MTD_NANDFLASH) { |
384 | pr_info("this test requires NAND flash\n"); | 379 | printk(PRINT_PREF "this test requires NAND flash\n"); |
385 | goto out; | 380 | goto out; |
386 | } | 381 | } |
387 | 382 | ||
@@ -390,7 +385,7 @@ static int __init mtd_oobtest_init(void) | |||
390 | ebcnt = tmp; | 385 | ebcnt = tmp; |
391 | pgcnt = mtd->erasesize / mtd->writesize; | 386 | pgcnt = mtd->erasesize / mtd->writesize; |
392 | 387 | ||
393 | pr_info("MTD device size %llu, eraseblock size %u, " | 388 | printk(PRINT_PREF "MTD device size %llu, eraseblock size %u, " |
394 | "page size %u, count of eraseblocks %u, pages per " | 389 | "page size %u, count of eraseblocks %u, pages per " |
395 | "eraseblock %u, OOB size %u\n", | 390 | "eraseblock %u, OOB size %u\n", |
396 | (unsigned long long)mtd->size, mtd->erasesize, | 391 | (unsigned long long)mtd->size, mtd->erasesize, |
@@ -399,12 +394,12 @@ static int __init mtd_oobtest_init(void) | |||
399 | err = -ENOMEM; | 394 | err = -ENOMEM; |
400 | readbuf = kmalloc(mtd->erasesize, GFP_KERNEL); | 395 | readbuf = kmalloc(mtd->erasesize, GFP_KERNEL); |
401 | if (!readbuf) { | 396 | if (!readbuf) { |
402 | pr_err("error: cannot allocate memory\n"); | 397 | printk(PRINT_PREF "error: cannot allocate memory\n"); |
403 | goto out; | 398 | goto out; |
404 | } | 399 | } |
405 | writebuf = kmalloc(mtd->erasesize, GFP_KERNEL); | 400 | writebuf = kmalloc(mtd->erasesize, GFP_KERNEL); |
406 | if (!writebuf) { | 401 | if (!writebuf) { |
407 | pr_err("error: cannot allocate memory\n"); | 402 | printk(PRINT_PREF "error: cannot allocate memory\n"); |
408 | goto out; | 403 | goto out; |
409 | } | 404 | } |
410 | 405 | ||
@@ -418,7 +413,7 @@ static int __init mtd_oobtest_init(void) | |||
418 | vary_offset = 0; | 413 | vary_offset = 0; |
419 | 414 | ||
420 | /* First test: write all OOB, read it back and verify */ | 415 | /* First test: write all OOB, read it back and verify */ |
421 | pr_info("test 1 of 5\n"); | 416 | printk(PRINT_PREF "test 1 of 5\n"); |
422 | 417 | ||
423 | err = erase_whole_device(); | 418 | err = erase_whole_device(); |
424 | if (err) | 419 | if (err) |
@@ -438,7 +433,7 @@ static int __init mtd_oobtest_init(void) | |||
438 | * Second test: write all OOB, a block at a time, read it back and | 433 | * Second test: write all OOB, a block at a time, read it back and |
439 | * verify. | 434 | * verify. |
440 | */ | 435 | */ |
441 | pr_info("test 2 of 5\n"); | 436 | printk(PRINT_PREF "test 2 of 5\n"); |
442 | 437 | ||
443 | err = erase_whole_device(); | 438 | err = erase_whole_device(); |
444 | if (err) | 439 | if (err) |
@@ -451,7 +446,7 @@ static int __init mtd_oobtest_init(void) | |||
451 | 446 | ||
452 | /* Check all eraseblocks */ | 447 | /* Check all eraseblocks */ |
453 | simple_srand(3); | 448 | simple_srand(3); |
454 | pr_info("verifying all eraseblocks\n"); | 449 | printk(PRINT_PREF "verifying all eraseblocks\n"); |
455 | for (i = 0; i < ebcnt; ++i) { | 450 | for (i = 0; i < ebcnt; ++i) { |
456 | if (bbt[i]) | 451 | if (bbt[i]) |
457 | continue; | 452 | continue; |
@@ -459,16 +454,16 @@ static int __init mtd_oobtest_init(void) | |||
459 | if (err) | 454 | if (err) |
460 | goto out; | 455 | goto out; |
461 | if (i % 256 == 0) | 456 | if (i % 256 == 0) |
462 | pr_info("verified up to eraseblock %u\n", i); | 457 | printk(PRINT_PREF "verified up to eraseblock %u\n", i); |
463 | cond_resched(); | 458 | cond_resched(); |
464 | } | 459 | } |
465 | pr_info("verified %u eraseblocks\n", i); | 460 | printk(PRINT_PREF "verified %u eraseblocks\n", i); |
466 | 461 | ||
467 | /* | 462 | /* |
468 | * Third test: write OOB at varying offsets and lengths, read it back | 463 | * Third test: write OOB at varying offsets and lengths, read it back |
469 | * and verify. | 464 | * and verify. |
470 | */ | 465 | */ |
471 | pr_info("test 3 of 5\n"); | 466 | printk(PRINT_PREF "test 3 of 5\n"); |
472 | 467 | ||
473 | err = erase_whole_device(); | 468 | err = erase_whole_device(); |
474 | if (err) | 469 | if (err) |
@@ -501,7 +496,7 @@ static int __init mtd_oobtest_init(void) | |||
501 | vary_offset = 0; | 496 | vary_offset = 0; |
502 | 497 | ||
503 | /* Fourth test: try to write off end of device */ | 498 | /* Fourth test: try to write off end of device */ |
504 | pr_info("test 4 of 5\n"); | 499 | printk(PRINT_PREF "test 4 of 5\n"); |
505 | 500 | ||
506 | err = erase_whole_device(); | 501 | err = erase_whole_device(); |
507 | if (err) | 502 | if (err) |
@@ -512,7 +507,7 @@ static int __init mtd_oobtest_init(void) | |||
512 | addr0 += mtd->erasesize; | 507 | addr0 += mtd->erasesize; |
513 | 508 | ||
514 | /* Attempt to write off end of OOB */ | 509 | /* Attempt to write off end of OOB */ |
515 | ops.mode = MTD_OPS_AUTO_OOB; | 510 | ops.mode = MTD_OOB_AUTO; |
516 | ops.len = 0; | 511 | ops.len = 0; |
517 | ops.retlen = 0; | 512 | ops.retlen = 0; |
518 | ops.ooblen = 1; | 513 | ops.ooblen = 1; |
@@ -520,19 +515,19 @@ static int __init mtd_oobtest_init(void) | |||
520 | ops.ooboffs = mtd->ecclayout->oobavail; | 515 | ops.ooboffs = mtd->ecclayout->oobavail; |
521 | ops.datbuf = NULL; | 516 | ops.datbuf = NULL; |
522 | ops.oobbuf = writebuf; | 517 | ops.oobbuf = writebuf; |
523 | pr_info("attempting to start write past end of OOB\n"); | 518 | printk(PRINT_PREF "attempting to start write past end of OOB\n"); |
524 | pr_info("an error is expected...\n"); | 519 | printk(PRINT_PREF "an error is expected...\n"); |
525 | err = mtd_write_oob(mtd, addr0, &ops); | 520 | err = mtd->write_oob(mtd, addr0, &ops); |
526 | if (err) { | 521 | if (err) { |
527 | pr_info("error occurred as expected\n"); | 522 | printk(PRINT_PREF "error occurred as expected\n"); |
528 | err = 0; | 523 | err = 0; |
529 | } else { | 524 | } else { |
530 | pr_err("error: can write past end of OOB\n"); | 525 | printk(PRINT_PREF "error: can write past end of OOB\n"); |
531 | errcnt += 1; | 526 | errcnt += 1; |
532 | } | 527 | } |
533 | 528 | ||
534 | /* Attempt to read off end of OOB */ | 529 | /* Attempt to read off end of OOB */ |
535 | ops.mode = MTD_OPS_AUTO_OOB; | 530 | ops.mode = MTD_OOB_AUTO; |
536 | ops.len = 0; | 531 | ops.len = 0; |
537 | ops.retlen = 0; | 532 | ops.retlen = 0; |
538 | ops.ooblen = 1; | 533 | ops.ooblen = 1; |
@@ -540,23 +535,23 @@ static int __init mtd_oobtest_init(void) | |||
540 | ops.ooboffs = mtd->ecclayout->oobavail; | 535 | ops.ooboffs = mtd->ecclayout->oobavail; |
541 | ops.datbuf = NULL; | 536 | ops.datbuf = NULL; |
542 | ops.oobbuf = readbuf; | 537 | ops.oobbuf = readbuf; |
543 | pr_info("attempting to start read past end of OOB\n"); | 538 | printk(PRINT_PREF "attempting to start read past end of OOB\n"); |
544 | pr_info("an error is expected...\n"); | 539 | printk(PRINT_PREF "an error is expected...\n"); |
545 | err = mtd_read_oob(mtd, addr0, &ops); | 540 | err = mtd->read_oob(mtd, addr0, &ops); |
546 | if (err) { | 541 | if (err) { |
547 | pr_info("error occurred as expected\n"); | 542 | printk(PRINT_PREF "error occurred as expected\n"); |
548 | err = 0; | 543 | err = 0; |
549 | } else { | 544 | } else { |
550 | pr_err("error: can read past end of OOB\n"); | 545 | printk(PRINT_PREF "error: can read past end of OOB\n"); |
551 | errcnt += 1; | 546 | errcnt += 1; |
552 | } | 547 | } |
553 | 548 | ||
554 | if (bbt[ebcnt - 1]) | 549 | if (bbt[ebcnt - 1]) |
555 | pr_info("skipping end of device tests because last " | 550 | printk(PRINT_PREF "skipping end of device tests because last " |
556 | "block is bad\n"); | 551 | "block is bad\n"); |
557 | else { | 552 | else { |
558 | /* Attempt to write off end of device */ | 553 | /* Attempt to write off end of device */ |
559 | ops.mode = MTD_OPS_AUTO_OOB; | 554 | ops.mode = MTD_OOB_AUTO; |
560 | ops.len = 0; | 555 | ops.len = 0; |
561 | ops.retlen = 0; | 556 | ops.retlen = 0; |
562 | ops.ooblen = mtd->ecclayout->oobavail + 1; | 557 | ops.ooblen = mtd->ecclayout->oobavail + 1; |
@@ -564,19 +559,19 @@ static int __init mtd_oobtest_init(void) | |||
564 | ops.ooboffs = 0; | 559 | ops.ooboffs = 0; |
565 | ops.datbuf = NULL; | 560 | ops.datbuf = NULL; |
566 | ops.oobbuf = writebuf; | 561 | ops.oobbuf = writebuf; |
567 | pr_info("attempting to write past end of device\n"); | 562 | printk(PRINT_PREF "attempting to write past end of device\n"); |
568 | pr_info("an error is expected...\n"); | 563 | printk(PRINT_PREF "an error is expected...\n"); |
569 | err = mtd_write_oob(mtd, mtd->size - mtd->writesize, &ops); | 564 | err = mtd->write_oob(mtd, mtd->size - mtd->writesize, &ops); |
570 | if (err) { | 565 | if (err) { |
571 | pr_info("error occurred as expected\n"); | 566 | printk(PRINT_PREF "error occurred as expected\n"); |
572 | err = 0; | 567 | err = 0; |
573 | } else { | 568 | } else { |
574 | pr_err("error: wrote past end of device\n"); | 569 | printk(PRINT_PREF "error: wrote past end of device\n"); |
575 | errcnt += 1; | 570 | errcnt += 1; |
576 | } | 571 | } |
577 | 572 | ||
578 | /* Attempt to read off end of device */ | 573 | /* Attempt to read off end of device */ |
579 | ops.mode = MTD_OPS_AUTO_OOB; | 574 | ops.mode = MTD_OOB_AUTO; |
580 | ops.len = 0; | 575 | ops.len = 0; |
581 | ops.retlen = 0; | 576 | ops.retlen = 0; |
582 | ops.ooblen = mtd->ecclayout->oobavail + 1; | 577 | ops.ooblen = mtd->ecclayout->oobavail + 1; |
@@ -584,14 +579,14 @@ static int __init mtd_oobtest_init(void) | |||
584 | ops.ooboffs = 0; | 579 | ops.ooboffs = 0; |
585 | ops.datbuf = NULL; | 580 | ops.datbuf = NULL; |
586 | ops.oobbuf = readbuf; | 581 | ops.oobbuf = readbuf; |
587 | pr_info("attempting to read past end of device\n"); | 582 | printk(PRINT_PREF "attempting to read past end of device\n"); |
588 | pr_info("an error is expected...\n"); | 583 | printk(PRINT_PREF "an error is expected...\n"); |
589 | err = mtd_read_oob(mtd, mtd->size - mtd->writesize, &ops); | 584 | err = mtd->read_oob(mtd, mtd->size - mtd->writesize, &ops); |
590 | if (err) { | 585 | if (err) { |
591 | pr_info("error occurred as expected\n"); | 586 | printk(PRINT_PREF "error occurred as expected\n"); |
592 | err = 0; | 587 | err = 0; |
593 | } else { | 588 | } else { |
594 | pr_err("error: read past end of device\n"); | 589 | printk(PRINT_PREF "error: read past end of device\n"); |
595 | errcnt += 1; | 590 | errcnt += 1; |
596 | } | 591 | } |
597 | 592 | ||
@@ -600,7 +595,7 @@ static int __init mtd_oobtest_init(void) | |||
600 | goto out; | 595 | goto out; |
601 | 596 | ||
602 | /* Attempt to write off end of device */ | 597 | /* Attempt to write off end of device */ |
603 | ops.mode = MTD_OPS_AUTO_OOB; | 598 | ops.mode = MTD_OOB_AUTO; |
604 | ops.len = 0; | 599 | ops.len = 0; |
605 | ops.retlen = 0; | 600 | ops.retlen = 0; |
606 | ops.ooblen = mtd->ecclayout->oobavail; | 601 | ops.ooblen = mtd->ecclayout->oobavail; |
@@ -608,19 +603,19 @@ static int __init mtd_oobtest_init(void) | |||
608 | ops.ooboffs = 1; | 603 | ops.ooboffs = 1; |
609 | ops.datbuf = NULL; | 604 | ops.datbuf = NULL; |
610 | ops.oobbuf = writebuf; | 605 | ops.oobbuf = writebuf; |
611 | pr_info("attempting to write past end of device\n"); | 606 | printk(PRINT_PREF "attempting to write past end of device\n"); |
612 | pr_info("an error is expected...\n"); | 607 | printk(PRINT_PREF "an error is expected...\n"); |
613 | err = mtd_write_oob(mtd, mtd->size - mtd->writesize, &ops); | 608 | err = mtd->write_oob(mtd, mtd->size - mtd->writesize, &ops); |
614 | if (err) { | 609 | if (err) { |
615 | pr_info("error occurred as expected\n"); | 610 | printk(PRINT_PREF "error occurred as expected\n"); |
616 | err = 0; | 611 | err = 0; |
617 | } else { | 612 | } else { |
618 | pr_err("error: wrote past end of device\n"); | 613 | printk(PRINT_PREF "error: wrote past end of device\n"); |
619 | errcnt += 1; | 614 | errcnt += 1; |
620 | } | 615 | } |
621 | 616 | ||
622 | /* Attempt to read off end of device */ | 617 | /* Attempt to read off end of device */ |
623 | ops.mode = MTD_OPS_AUTO_OOB; | 618 | ops.mode = MTD_OOB_AUTO; |
624 | ops.len = 0; | 619 | ops.len = 0; |
625 | ops.retlen = 0; | 620 | ops.retlen = 0; |
626 | ops.ooblen = mtd->ecclayout->oobavail; | 621 | ops.ooblen = mtd->ecclayout->oobavail; |
@@ -628,20 +623,20 @@ static int __init mtd_oobtest_init(void) | |||
628 | ops.ooboffs = 1; | 623 | ops.ooboffs = 1; |
629 | ops.datbuf = NULL; | 624 | ops.datbuf = NULL; |
630 | ops.oobbuf = readbuf; | 625 | ops.oobbuf = readbuf; |
631 | pr_info("attempting to read past end of device\n"); | 626 | printk(PRINT_PREF "attempting to read past end of device\n"); |
632 | pr_info("an error is expected...\n"); | 627 | printk(PRINT_PREF "an error is expected...\n"); |
633 | err = mtd_read_oob(mtd, mtd->size - mtd->writesize, &ops); | 628 | err = mtd->read_oob(mtd, mtd->size - mtd->writesize, &ops); |
634 | if (err) { | 629 | if (err) { |
635 | pr_info("error occurred as expected\n"); | 630 | printk(PRINT_PREF "error occurred as expected\n"); |
636 | err = 0; | 631 | err = 0; |
637 | } else { | 632 | } else { |
638 | pr_err("error: read past end of device\n"); | 633 | printk(PRINT_PREF "error: read past end of device\n"); |
639 | errcnt += 1; | 634 | errcnt += 1; |
640 | } | 635 | } |
641 | } | 636 | } |
642 | 637 | ||
643 | /* Fifth test: write / read across block boundaries */ | 638 | /* Fifth test: write / read across block boundaries */ |
644 | pr_info("test 5 of 5\n"); | 639 | printk(PRINT_PREF "test 5 of 5\n"); |
645 | 640 | ||
646 | /* Erase all eraseblocks */ | 641 | /* Erase all eraseblocks */ |
647 | err = erase_whole_device(); | 642 | err = erase_whole_device(); |
@@ -650,7 +645,7 @@ static int __init mtd_oobtest_init(void) | |||
650 | 645 | ||
651 | /* Write all eraseblocks */ | 646 | /* Write all eraseblocks */ |
652 | simple_srand(11); | 647 | simple_srand(11); |
653 | pr_info("writing OOBs of whole device\n"); | 648 | printk(PRINT_PREF "writing OOBs of whole device\n"); |
654 | for (i = 0; i < ebcnt - 1; ++i) { | 649 | for (i = 0; i < ebcnt - 1; ++i) { |
655 | int cnt = 2; | 650 | int cnt = 2; |
656 | int pg; | 651 | int pg; |
@@ -660,7 +655,7 @@ static int __init mtd_oobtest_init(void) | |||
660 | addr = (i + 1) * mtd->erasesize - mtd->writesize; | 655 | addr = (i + 1) * mtd->erasesize - mtd->writesize; |
661 | for (pg = 0; pg < cnt; ++pg) { | 656 | for (pg = 0; pg < cnt; ++pg) { |
662 | set_random_data(writebuf, sz); | 657 | set_random_data(writebuf, sz); |
663 | ops.mode = MTD_OPS_AUTO_OOB; | 658 | ops.mode = MTD_OOB_AUTO; |
664 | ops.len = 0; | 659 | ops.len = 0; |
665 | ops.retlen = 0; | 660 | ops.retlen = 0; |
666 | ops.ooblen = sz; | 661 | ops.ooblen = sz; |
@@ -668,26 +663,27 @@ static int __init mtd_oobtest_init(void) | |||
668 | ops.ooboffs = 0; | 663 | ops.ooboffs = 0; |
669 | ops.datbuf = NULL; | 664 | ops.datbuf = NULL; |
670 | ops.oobbuf = writebuf; | 665 | ops.oobbuf = writebuf; |
671 | err = mtd_write_oob(mtd, addr, &ops); | 666 | err = mtd->write_oob(mtd, addr, &ops); |
672 | if (err) | 667 | if (err) |
673 | goto out; | 668 | goto out; |
674 | if (i % 256 == 0) | 669 | if (i % 256 == 0) |
675 | pr_info("written up to eraseblock %u\n", i); | 670 | printk(PRINT_PREF "written up to eraseblock " |
671 | "%u\n", i); | ||
676 | cond_resched(); | 672 | cond_resched(); |
677 | addr += mtd->writesize; | 673 | addr += mtd->writesize; |
678 | } | 674 | } |
679 | } | 675 | } |
680 | pr_info("written %u eraseblocks\n", i); | 676 | printk(PRINT_PREF "written %u eraseblocks\n", i); |
681 | 677 | ||
682 | /* Check all eraseblocks */ | 678 | /* Check all eraseblocks */ |
683 | simple_srand(11); | 679 | simple_srand(11); |
684 | pr_info("verifying all eraseblocks\n"); | 680 | printk(PRINT_PREF "verifying all eraseblocks\n"); |
685 | for (i = 0; i < ebcnt - 1; ++i) { | 681 | for (i = 0; i < ebcnt - 1; ++i) { |
686 | if (bbt[i] || bbt[i + 1]) | 682 | if (bbt[i] || bbt[i + 1]) |
687 | continue; | 683 | continue; |
688 | set_random_data(writebuf, mtd->ecclayout->oobavail * 2); | 684 | set_random_data(writebuf, mtd->ecclayout->oobavail * 2); |
689 | addr = (i + 1) * mtd->erasesize - mtd->writesize; | 685 | addr = (i + 1) * mtd->erasesize - mtd->writesize; |
690 | ops.mode = MTD_OPS_AUTO_OOB; | 686 | ops.mode = MTD_OOB_AUTO; |
691 | ops.len = 0; | 687 | ops.len = 0; |
692 | ops.retlen = 0; | 688 | ops.retlen = 0; |
693 | ops.ooblen = mtd->ecclayout->oobavail * 2; | 689 | ops.ooblen = mtd->ecclayout->oobavail * 2; |
@@ -695,32 +691,32 @@ static int __init mtd_oobtest_init(void) | |||
695 | ops.ooboffs = 0; | 691 | ops.ooboffs = 0; |
696 | ops.datbuf = NULL; | 692 | ops.datbuf = NULL; |
697 | ops.oobbuf = readbuf; | 693 | ops.oobbuf = readbuf; |
698 | err = mtd_read_oob(mtd, addr, &ops); | 694 | err = mtd->read_oob(mtd, addr, &ops); |
699 | if (err) | 695 | if (err) |
700 | goto out; | 696 | goto out; |
701 | if (memcmp(readbuf, writebuf, mtd->ecclayout->oobavail * 2)) { | 697 | if (memcmp(readbuf, writebuf, mtd->ecclayout->oobavail * 2)) { |
702 | pr_err("error: verify failed at %#llx\n", | 698 | printk(PRINT_PREF "error: verify failed at %#llx\n", |
703 | (long long)addr); | 699 | (long long)addr); |
704 | errcnt += 1; | 700 | errcnt += 1; |
705 | if (errcnt > 1000) { | 701 | if (errcnt > 1000) { |
706 | pr_err("error: too many errors\n"); | 702 | printk(PRINT_PREF "error: too many errors\n"); |
707 | goto out; | 703 | goto out; |
708 | } | 704 | } |
709 | } | 705 | } |
710 | if (i % 256 == 0) | 706 | if (i % 256 == 0) |
711 | pr_info("verified up to eraseblock %u\n", i); | 707 | printk(PRINT_PREF "verified up to eraseblock %u\n", i); |
712 | cond_resched(); | 708 | cond_resched(); |
713 | } | 709 | } |
714 | pr_info("verified %u eraseblocks\n", i); | 710 | printk(PRINT_PREF "verified %u eraseblocks\n", i); |
715 | 711 | ||
716 | pr_info("finished with %d errors\n", errcnt); | 712 | printk(PRINT_PREF "finished with %d errors\n", errcnt); |
717 | out: | 713 | out: |
718 | kfree(bbt); | 714 | kfree(bbt); |
719 | kfree(writebuf); | 715 | kfree(writebuf); |
720 | kfree(readbuf); | 716 | kfree(readbuf); |
721 | put_mtd_device(mtd); | 717 | put_mtd_device(mtd); |
722 | if (err) | 718 | if (err) |
723 | pr_info("error %d occurred\n", err); | 719 | printk(PRINT_PREF "error %d occurred\n", err); |
724 | printk(KERN_INFO "=================================================\n"); | 720 | printk(KERN_INFO "=================================================\n"); |
725 | return err; | 721 | return err; |
726 | } | 722 | } |
diff --git a/drivers/mtd/tests/mtd_pagetest.c b/drivers/mtd/tests/mtd_pagetest.c index f93a76f8811..00b937e38c1 100644 --- a/drivers/mtd/tests/mtd_pagetest.c +++ b/drivers/mtd/tests/mtd_pagetest.c | |||
@@ -19,8 +19,6 @@ | |||
19 | * Author: Adrian Hunter <ext-adrian.hunter@nokia.com> | 19 | * Author: Adrian Hunter <ext-adrian.hunter@nokia.com> |
20 | */ | 20 | */ |
21 | 21 | ||
22 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
23 | |||
24 | #include <asm/div64.h> | 22 | #include <asm/div64.h> |
25 | #include <linux/init.h> | 23 | #include <linux/init.h> |
26 | #include <linux/module.h> | 24 | #include <linux/module.h> |
@@ -30,7 +28,9 @@ | |||
30 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
31 | #include <linux/sched.h> | 29 | #include <linux/sched.h> |
32 | 30 | ||
33 | static int dev = -EINVAL; | 31 | #define PRINT_PREF KERN_INFO "mtd_pagetest: " |
32 | |||
33 | static int dev; | ||
34 | module_param(dev, int, S_IRUGO); | 34 | module_param(dev, int, S_IRUGO); |
35 | MODULE_PARM_DESC(dev, "MTD device number to use"); | 35 | MODULE_PARM_DESC(dev, "MTD device number to use"); |
36 | 36 | ||
@@ -77,14 +77,14 @@ static int erase_eraseblock(int ebnum) | |||
77 | ei.addr = addr; | 77 | ei.addr = addr; |
78 | ei.len = mtd->erasesize; | 78 | ei.len = mtd->erasesize; |
79 | 79 | ||
80 | err = mtd_erase(mtd, &ei); | 80 | err = mtd->erase(mtd, &ei); |
81 | if (err) { | 81 | if (err) { |
82 | pr_err("error %d while erasing EB %d\n", err, ebnum); | 82 | printk(PRINT_PREF "error %d while erasing EB %d\n", err, ebnum); |
83 | return err; | 83 | return err; |
84 | } | 84 | } |
85 | 85 | ||
86 | if (ei.state == MTD_ERASE_FAILED) { | 86 | if (ei.state == MTD_ERASE_FAILED) { |
87 | pr_err("some erase error occurred at EB %d\n", | 87 | printk(PRINT_PREF "some erase error occurred at EB %d\n", |
88 | ebnum); | 88 | ebnum); |
89 | return -EIO; | 89 | return -EIO; |
90 | } | 90 | } |
@@ -95,14 +95,14 @@ static int erase_eraseblock(int ebnum) | |||
95 | static int write_eraseblock(int ebnum) | 95 | static int write_eraseblock(int ebnum) |
96 | { | 96 | { |
97 | int err = 0; | 97 | int err = 0; |
98 | size_t written; | 98 | size_t written = 0; |
99 | loff_t addr = ebnum * mtd->erasesize; | 99 | loff_t addr = ebnum * mtd->erasesize; |
100 | 100 | ||
101 | set_random_data(writebuf, mtd->erasesize); | 101 | set_random_data(writebuf, mtd->erasesize); |
102 | cond_resched(); | 102 | cond_resched(); |
103 | err = mtd_write(mtd, addr, mtd->erasesize, &written, writebuf); | 103 | err = mtd->write(mtd, addr, mtd->erasesize, &written, writebuf); |
104 | if (err || written != mtd->erasesize) | 104 | if (err || written != mtd->erasesize) |
105 | pr_err("error: write failed at %#llx\n", | 105 | printk(PRINT_PREF "error: write failed at %#llx\n", |
106 | (long long)addr); | 106 | (long long)addr); |
107 | 107 | ||
108 | return err; | 108 | return err; |
@@ -111,7 +111,7 @@ static int write_eraseblock(int ebnum) | |||
111 | static int verify_eraseblock(int ebnum) | 111 | static int verify_eraseblock(int ebnum) |
112 | { | 112 | { |
113 | uint32_t j; | 113 | uint32_t j; |
114 | size_t read; | 114 | size_t read = 0; |
115 | int err = 0, i; | 115 | int err = 0, i; |
116 | loff_t addr0, addrn; | 116 | loff_t addr0, addrn; |
117 | loff_t addr = ebnum * mtd->erasesize; | 117 | loff_t addr = ebnum * mtd->erasesize; |
@@ -127,33 +127,34 @@ static int verify_eraseblock(int ebnum) | |||
127 | set_random_data(writebuf, mtd->erasesize); | 127 | set_random_data(writebuf, mtd->erasesize); |
128 | for (j = 0; j < pgcnt - 1; ++j, addr += pgsize) { | 128 | for (j = 0; j < pgcnt - 1; ++j, addr += pgsize) { |
129 | /* Do a read to set the internal dataRAMs to different data */ | 129 | /* Do a read to set the internal dataRAMs to different data */ |
130 | err = mtd_read(mtd, addr0, bufsize, &read, twopages); | 130 | err = mtd->read(mtd, addr0, bufsize, &read, twopages); |
131 | if (mtd_is_bitflip(err)) | 131 | if (err == -EUCLEAN) |
132 | err = 0; | 132 | err = 0; |
133 | if (err || read != bufsize) { | 133 | if (err || read != bufsize) { |
134 | pr_err("error: read failed at %#llx\n", | 134 | printk(PRINT_PREF "error: read failed at %#llx\n", |
135 | (long long)addr0); | 135 | (long long)addr0); |
136 | return err; | 136 | return err; |
137 | } | 137 | } |
138 | err = mtd_read(mtd, addrn - bufsize, bufsize, &read, twopages); | 138 | err = mtd->read(mtd, addrn - bufsize, bufsize, &read, twopages); |
139 | if (mtd_is_bitflip(err)) | 139 | if (err == -EUCLEAN) |
140 | err = 0; | 140 | err = 0; |
141 | if (err || read != bufsize) { | 141 | if (err || read != bufsize) { |
142 | pr_err("error: read failed at %#llx\n", | 142 | printk(PRINT_PREF "error: read failed at %#llx\n", |
143 | (long long)(addrn - bufsize)); | 143 | (long long)(addrn - bufsize)); |
144 | return err; | 144 | return err; |
145 | } | 145 | } |
146 | memset(twopages, 0, bufsize); | 146 | memset(twopages, 0, bufsize); |
147 | err = mtd_read(mtd, addr, bufsize, &read, twopages); | 147 | read = 0; |
148 | if (mtd_is_bitflip(err)) | 148 | err = mtd->read(mtd, addr, bufsize, &read, twopages); |
149 | if (err == -EUCLEAN) | ||
149 | err = 0; | 150 | err = 0; |
150 | if (err || read != bufsize) { | 151 | if (err || read != bufsize) { |
151 | pr_err("error: read failed at %#llx\n", | 152 | printk(PRINT_PREF "error: read failed at %#llx\n", |
152 | (long long)addr); | 153 | (long long)addr); |
153 | break; | 154 | break; |
154 | } | 155 | } |
155 | if (memcmp(twopages, writebuf + (j * pgsize), bufsize)) { | 156 | if (memcmp(twopages, writebuf + (j * pgsize), bufsize)) { |
156 | pr_err("error: verify failed at %#llx\n", | 157 | printk(PRINT_PREF "error: verify failed at %#llx\n", |
157 | (long long)addr); | 158 | (long long)addr); |
158 | errcnt += 1; | 159 | errcnt += 1; |
159 | } | 160 | } |
@@ -162,35 +163,36 @@ static int verify_eraseblock(int ebnum) | |||
162 | if (addr <= addrn - pgsize - pgsize && !bbt[ebnum + 1]) { | 163 | if (addr <= addrn - pgsize - pgsize && !bbt[ebnum + 1]) { |
163 | unsigned long oldnext = next; | 164 | unsigned long oldnext = next; |
164 | /* Do a read to set the internal dataRAMs to different data */ | 165 | /* Do a read to set the internal dataRAMs to different data */ |
165 | err = mtd_read(mtd, addr0, bufsize, &read, twopages); | 166 | err = mtd->read(mtd, addr0, bufsize, &read, twopages); |
166 | if (mtd_is_bitflip(err)) | 167 | if (err == -EUCLEAN) |
167 | err = 0; | 168 | err = 0; |
168 | if (err || read != bufsize) { | 169 | if (err || read != bufsize) { |
169 | pr_err("error: read failed at %#llx\n", | 170 | printk(PRINT_PREF "error: read failed at %#llx\n", |
170 | (long long)addr0); | 171 | (long long)addr0); |
171 | return err; | 172 | return err; |
172 | } | 173 | } |
173 | err = mtd_read(mtd, addrn - bufsize, bufsize, &read, twopages); | 174 | err = mtd->read(mtd, addrn - bufsize, bufsize, &read, twopages); |
174 | if (mtd_is_bitflip(err)) | 175 | if (err == -EUCLEAN) |
175 | err = 0; | 176 | err = 0; |
176 | if (err || read != bufsize) { | 177 | if (err || read != bufsize) { |
177 | pr_err("error: read failed at %#llx\n", | 178 | printk(PRINT_PREF "error: read failed at %#llx\n", |
178 | (long long)(addrn - bufsize)); | 179 | (long long)(addrn - bufsize)); |
179 | return err; | 180 | return err; |
180 | } | 181 | } |
181 | memset(twopages, 0, bufsize); | 182 | memset(twopages, 0, bufsize); |
182 | err = mtd_read(mtd, addr, bufsize, &read, twopages); | 183 | read = 0; |
183 | if (mtd_is_bitflip(err)) | 184 | err = mtd->read(mtd, addr, bufsize, &read, twopages); |
185 | if (err == -EUCLEAN) | ||
184 | err = 0; | 186 | err = 0; |
185 | if (err || read != bufsize) { | 187 | if (err || read != bufsize) { |
186 | pr_err("error: read failed at %#llx\n", | 188 | printk(PRINT_PREF "error: read failed at %#llx\n", |
187 | (long long)addr); | 189 | (long long)addr); |
188 | return err; | 190 | return err; |
189 | } | 191 | } |
190 | memcpy(boundary, writebuf + mtd->erasesize - pgsize, pgsize); | 192 | memcpy(boundary, writebuf + mtd->erasesize - pgsize, pgsize); |
191 | set_random_data(boundary + pgsize, pgsize); | 193 | set_random_data(boundary + pgsize, pgsize); |
192 | if (memcmp(twopages, boundary, bufsize)) { | 194 | if (memcmp(twopages, boundary, bufsize)) { |
193 | pr_err("error: verify failed at %#llx\n", | 195 | printk(PRINT_PREF "error: verify failed at %#llx\n", |
194 | (long long)addr); | 196 | (long long)addr); |
195 | errcnt += 1; | 197 | errcnt += 1; |
196 | } | 198 | } |
@@ -201,15 +203,15 @@ static int verify_eraseblock(int ebnum) | |||
201 | 203 | ||
202 | static int crosstest(void) | 204 | static int crosstest(void) |
203 | { | 205 | { |
204 | size_t read; | 206 | size_t read = 0; |
205 | int err = 0, i; | 207 | int err = 0, i; |
206 | loff_t addr, addr0, addrn; | 208 | loff_t addr, addr0, addrn; |
207 | unsigned char *pp1, *pp2, *pp3, *pp4; | 209 | unsigned char *pp1, *pp2, *pp3, *pp4; |
208 | 210 | ||
209 | pr_info("crosstest\n"); | 211 | printk(PRINT_PREF "crosstest\n"); |
210 | pp1 = kmalloc(pgsize * 4, GFP_KERNEL); | 212 | pp1 = kmalloc(pgsize * 4, GFP_KERNEL); |
211 | if (!pp1) { | 213 | if (!pp1) { |
212 | pr_err("error: cannot allocate memory\n"); | 214 | printk(PRINT_PREF "error: cannot allocate memory\n"); |
213 | return -ENOMEM; | 215 | return -ENOMEM; |
214 | } | 216 | } |
215 | pp2 = pp1 + pgsize; | 217 | pp2 = pp1 + pgsize; |
@@ -226,88 +228,93 @@ static int crosstest(void) | |||
226 | addrn -= mtd->erasesize; | 228 | addrn -= mtd->erasesize; |
227 | 229 | ||
228 | /* Read 2nd-to-last page to pp1 */ | 230 | /* Read 2nd-to-last page to pp1 */ |
231 | read = 0; | ||
229 | addr = addrn - pgsize - pgsize; | 232 | addr = addrn - pgsize - pgsize; |
230 | err = mtd_read(mtd, addr, pgsize, &read, pp1); | 233 | err = mtd->read(mtd, addr, pgsize, &read, pp1); |
231 | if (mtd_is_bitflip(err)) | 234 | if (err == -EUCLEAN) |
232 | err = 0; | 235 | err = 0; |
233 | if (err || read != pgsize) { | 236 | if (err || read != pgsize) { |
234 | pr_err("error: read failed at %#llx\n", | 237 | printk(PRINT_PREF "error: read failed at %#llx\n", |
235 | (long long)addr); | 238 | (long long)addr); |
236 | kfree(pp1); | 239 | kfree(pp1); |
237 | return err; | 240 | return err; |
238 | } | 241 | } |
239 | 242 | ||
240 | /* Read 3rd-to-last page to pp1 */ | 243 | /* Read 3rd-to-last page to pp1 */ |
244 | read = 0; | ||
241 | addr = addrn - pgsize - pgsize - pgsize; | 245 | addr = addrn - pgsize - pgsize - pgsize; |
242 | err = mtd_read(mtd, addr, pgsize, &read, pp1); | 246 | err = mtd->read(mtd, addr, pgsize, &read, pp1); |
243 | if (mtd_is_bitflip(err)) | 247 | if (err == -EUCLEAN) |
244 | err = 0; | 248 | err = 0; |
245 | if (err || read != pgsize) { | 249 | if (err || read != pgsize) { |
246 | pr_err("error: read failed at %#llx\n", | 250 | printk(PRINT_PREF "error: read failed at %#llx\n", |
247 | (long long)addr); | 251 | (long long)addr); |
248 | kfree(pp1); | 252 | kfree(pp1); |
249 | return err; | 253 | return err; |
250 | } | 254 | } |
251 | 255 | ||
252 | /* Read first page to pp2 */ | 256 | /* Read first page to pp2 */ |
257 | read = 0; | ||
253 | addr = addr0; | 258 | addr = addr0; |
254 | pr_info("reading page at %#llx\n", (long long)addr); | 259 | printk(PRINT_PREF "reading page at %#llx\n", (long long)addr); |
255 | err = mtd_read(mtd, addr, pgsize, &read, pp2); | 260 | err = mtd->read(mtd, addr, pgsize, &read, pp2); |
256 | if (mtd_is_bitflip(err)) | 261 | if (err == -EUCLEAN) |
257 | err = 0; | 262 | err = 0; |
258 | if (err || read != pgsize) { | 263 | if (err || read != pgsize) { |
259 | pr_err("error: read failed at %#llx\n", | 264 | printk(PRINT_PREF "error: read failed at %#llx\n", |
260 | (long long)addr); | 265 | (long long)addr); |
261 | kfree(pp1); | 266 | kfree(pp1); |
262 | return err; | 267 | return err; |
263 | } | 268 | } |
264 | 269 | ||
265 | /* Read last page to pp3 */ | 270 | /* Read last page to pp3 */ |
271 | read = 0; | ||
266 | addr = addrn - pgsize; | 272 | addr = addrn - pgsize; |
267 | pr_info("reading page at %#llx\n", (long long)addr); | 273 | printk(PRINT_PREF "reading page at %#llx\n", (long long)addr); |
268 | err = mtd_read(mtd, addr, pgsize, &read, pp3); | 274 | err = mtd->read(mtd, addr, pgsize, &read, pp3); |
269 | if (mtd_is_bitflip(err)) | 275 | if (err == -EUCLEAN) |
270 | err = 0; | 276 | err = 0; |
271 | if (err || read != pgsize) { | 277 | if (err || read != pgsize) { |
272 | pr_err("error: read failed at %#llx\n", | 278 | printk(PRINT_PREF "error: read failed at %#llx\n", |
273 | (long long)addr); | 279 | (long long)addr); |
274 | kfree(pp1); | 280 | kfree(pp1); |
275 | return err; | 281 | return err; |
276 | } | 282 | } |
277 | 283 | ||
278 | /* Read first page again to pp4 */ | 284 | /* Read first page again to pp4 */ |
285 | read = 0; | ||
279 | addr = addr0; | 286 | addr = addr0; |
280 | pr_info("reading page at %#llx\n", (long long)addr); | 287 | printk(PRINT_PREF "reading page at %#llx\n", (long long)addr); |
281 | err = mtd_read(mtd, addr, pgsize, &read, pp4); | 288 | err = mtd->read(mtd, addr, pgsize, &read, pp4); |
282 | if (mtd_is_bitflip(err)) | 289 | if (err == -EUCLEAN) |
283 | err = 0; | 290 | err = 0; |
284 | if (err || read != pgsize) { | 291 | if (err || read != pgsize) { |
285 | pr_err("error: read failed at %#llx\n", | 292 | printk(PRINT_PREF "error: read failed at %#llx\n", |
286 | (long long)addr); | 293 | (long long)addr); |
287 | kfree(pp1); | 294 | kfree(pp1); |
288 | return err; | 295 | return err; |
289 | } | 296 | } |
290 | 297 | ||
291 | /* pp2 and pp4 should be the same */ | 298 | /* pp2 and pp4 should be the same */ |
292 | pr_info("verifying pages read at %#llx match\n", | 299 | printk(PRINT_PREF "verifying pages read at %#llx match\n", |
293 | (long long)addr0); | 300 | (long long)addr0); |
294 | if (memcmp(pp2, pp4, pgsize)) { | 301 | if (memcmp(pp2, pp4, pgsize)) { |
295 | pr_err("verify failed!\n"); | 302 | printk(PRINT_PREF "verify failed!\n"); |
296 | errcnt += 1; | 303 | errcnt += 1; |
297 | } else if (!err) | 304 | } else if (!err) |
298 | pr_info("crosstest ok\n"); | 305 | printk(PRINT_PREF "crosstest ok\n"); |
299 | kfree(pp1); | 306 | kfree(pp1); |
300 | return err; | 307 | return err; |
301 | } | 308 | } |
302 | 309 | ||
303 | static int erasecrosstest(void) | 310 | static int erasecrosstest(void) |
304 | { | 311 | { |
305 | size_t read, written; | 312 | size_t read = 0, written = 0; |
306 | int err = 0, i, ebnum, ebnum2; | 313 | int err = 0, i, ebnum, ebnum2; |
307 | loff_t addr0; | 314 | loff_t addr0; |
308 | char *readbuf = twopages; | 315 | char *readbuf = twopages; |
309 | 316 | ||
310 | pr_info("erasecrosstest\n"); | 317 | printk(PRINT_PREF "erasecrosstest\n"); |
311 | 318 | ||
312 | ebnum = 0; | 319 | ebnum = 0; |
313 | addr0 = 0; | 320 | addr0 = 0; |
@@ -320,89 +327,89 @@ static int erasecrosstest(void) | |||
320 | while (ebnum2 && bbt[ebnum2]) | 327 | while (ebnum2 && bbt[ebnum2]) |
321 | ebnum2 -= 1; | 328 | ebnum2 -= 1; |
322 | 329 | ||
323 | pr_info("erasing block %d\n", ebnum); | 330 | printk(PRINT_PREF "erasing block %d\n", ebnum); |
324 | err = erase_eraseblock(ebnum); | 331 | err = erase_eraseblock(ebnum); |
325 | if (err) | 332 | if (err) |
326 | return err; | 333 | return err; |
327 | 334 | ||
328 | pr_info("writing 1st page of block %d\n", ebnum); | 335 | printk(PRINT_PREF "writing 1st page of block %d\n", ebnum); |
329 | set_random_data(writebuf, pgsize); | 336 | set_random_data(writebuf, pgsize); |
330 | strcpy(writebuf, "There is no data like this!"); | 337 | strcpy(writebuf, "There is no data like this!"); |
331 | err = mtd_write(mtd, addr0, pgsize, &written, writebuf); | 338 | err = mtd->write(mtd, addr0, pgsize, &written, writebuf); |
332 | if (err || written != pgsize) { | 339 | if (err || written != pgsize) { |
333 | pr_info("error: write failed at %#llx\n", | 340 | printk(PRINT_PREF "error: write failed at %#llx\n", |
334 | (long long)addr0); | 341 | (long long)addr0); |
335 | return err ? err : -1; | 342 | return err ? err : -1; |
336 | } | 343 | } |
337 | 344 | ||
338 | pr_info("reading 1st page of block %d\n", ebnum); | 345 | printk(PRINT_PREF "reading 1st page of block %d\n", ebnum); |
339 | memset(readbuf, 0, pgsize); | 346 | memset(readbuf, 0, pgsize); |
340 | err = mtd_read(mtd, addr0, pgsize, &read, readbuf); | 347 | err = mtd->read(mtd, addr0, pgsize, &read, readbuf); |
341 | if (mtd_is_bitflip(err)) | 348 | if (err == -EUCLEAN) |
342 | err = 0; | 349 | err = 0; |
343 | if (err || read != pgsize) { | 350 | if (err || read != pgsize) { |
344 | pr_err("error: read failed at %#llx\n", | 351 | printk(PRINT_PREF "error: read failed at %#llx\n", |
345 | (long long)addr0); | 352 | (long long)addr0); |
346 | return err ? err : -1; | 353 | return err ? err : -1; |
347 | } | 354 | } |
348 | 355 | ||
349 | pr_info("verifying 1st page of block %d\n", ebnum); | 356 | printk(PRINT_PREF "verifying 1st page of block %d\n", ebnum); |
350 | if (memcmp(writebuf, readbuf, pgsize)) { | 357 | if (memcmp(writebuf, readbuf, pgsize)) { |
351 | pr_err("verify failed!\n"); | 358 | printk(PRINT_PREF "verify failed!\n"); |
352 | errcnt += 1; | 359 | errcnt += 1; |
353 | return -1; | 360 | return -1; |
354 | } | 361 | } |
355 | 362 | ||
356 | pr_info("erasing block %d\n", ebnum); | 363 | printk(PRINT_PREF "erasing block %d\n", ebnum); |
357 | err = erase_eraseblock(ebnum); | 364 | err = erase_eraseblock(ebnum); |
358 | if (err) | 365 | if (err) |
359 | return err; | 366 | return err; |
360 | 367 | ||
361 | pr_info("writing 1st page of block %d\n", ebnum); | 368 | printk(PRINT_PREF "writing 1st page of block %d\n", ebnum); |
362 | set_random_data(writebuf, pgsize); | 369 | set_random_data(writebuf, pgsize); |
363 | strcpy(writebuf, "There is no data like this!"); | 370 | strcpy(writebuf, "There is no data like this!"); |
364 | err = mtd_write(mtd, addr0, pgsize, &written, writebuf); | 371 | err = mtd->write(mtd, addr0, pgsize, &written, writebuf); |
365 | if (err || written != pgsize) { | 372 | if (err || written != pgsize) { |
366 | pr_err("error: write failed at %#llx\n", | 373 | printk(PRINT_PREF "error: write failed at %#llx\n", |
367 | (long long)addr0); | 374 | (long long)addr0); |
368 | return err ? err : -1; | 375 | return err ? err : -1; |
369 | } | 376 | } |
370 | 377 | ||
371 | pr_info("erasing block %d\n", ebnum2); | 378 | printk(PRINT_PREF "erasing block %d\n", ebnum2); |
372 | err = erase_eraseblock(ebnum2); | 379 | err = erase_eraseblock(ebnum2); |
373 | if (err) | 380 | if (err) |
374 | return err; | 381 | return err; |
375 | 382 | ||
376 | pr_info("reading 1st page of block %d\n", ebnum); | 383 | printk(PRINT_PREF "reading 1st page of block %d\n", ebnum); |
377 | memset(readbuf, 0, pgsize); | 384 | memset(readbuf, 0, pgsize); |
378 | err = mtd_read(mtd, addr0, pgsize, &read, readbuf); | 385 | err = mtd->read(mtd, addr0, pgsize, &read, readbuf); |
379 | if (mtd_is_bitflip(err)) | 386 | if (err == -EUCLEAN) |
380 | err = 0; | 387 | err = 0; |
381 | if (err || read != pgsize) { | 388 | if (err || read != pgsize) { |
382 | pr_err("error: read failed at %#llx\n", | 389 | printk(PRINT_PREF "error: read failed at %#llx\n", |
383 | (long long)addr0); | 390 | (long long)addr0); |
384 | return err ? err : -1; | 391 | return err ? err : -1; |
385 | } | 392 | } |
386 | 393 | ||
387 | pr_info("verifying 1st page of block %d\n", ebnum); | 394 | printk(PRINT_PREF "verifying 1st page of block %d\n", ebnum); |
388 | if (memcmp(writebuf, readbuf, pgsize)) { | 395 | if (memcmp(writebuf, readbuf, pgsize)) { |
389 | pr_err("verify failed!\n"); | 396 | printk(PRINT_PREF "verify failed!\n"); |
390 | errcnt += 1; | 397 | errcnt += 1; |
391 | return -1; | 398 | return -1; |
392 | } | 399 | } |
393 | 400 | ||
394 | if (!err) | 401 | if (!err) |
395 | pr_info("erasecrosstest ok\n"); | 402 | printk(PRINT_PREF "erasecrosstest ok\n"); |
396 | return err; | 403 | return err; |
397 | } | 404 | } |
398 | 405 | ||
399 | static int erasetest(void) | 406 | static int erasetest(void) |
400 | { | 407 | { |
401 | size_t read, written; | 408 | size_t read = 0, written = 0; |
402 | int err = 0, i, ebnum, ok = 1; | 409 | int err = 0, i, ebnum, ok = 1; |
403 | loff_t addr0; | 410 | loff_t addr0; |
404 | 411 | ||
405 | pr_info("erasetest\n"); | 412 | printk(PRINT_PREF "erasetest\n"); |
406 | 413 | ||
407 | ebnum = 0; | 414 | ebnum = 0; |
408 | addr0 = 0; | 415 | addr0 = 0; |
@@ -411,40 +418,40 @@ static int erasetest(void) | |||
411 | ebnum += 1; | 418 | ebnum += 1; |
412 | } | 419 | } |
413 | 420 | ||
414 | pr_info("erasing block %d\n", ebnum); | 421 | printk(PRINT_PREF "erasing block %d\n", ebnum); |
415 | err = erase_eraseblock(ebnum); | 422 | err = erase_eraseblock(ebnum); |
416 | if (err) | 423 | if (err) |
417 | return err; | 424 | return err; |
418 | 425 | ||
419 | pr_info("writing 1st page of block %d\n", ebnum); | 426 | printk(PRINT_PREF "writing 1st page of block %d\n", ebnum); |
420 | set_random_data(writebuf, pgsize); | 427 | set_random_data(writebuf, pgsize); |
421 | err = mtd_write(mtd, addr0, pgsize, &written, writebuf); | 428 | err = mtd->write(mtd, addr0, pgsize, &written, writebuf); |
422 | if (err || written != pgsize) { | 429 | if (err || written != pgsize) { |
423 | pr_err("error: write failed at %#llx\n", | 430 | printk(PRINT_PREF "error: write failed at %#llx\n", |
424 | (long long)addr0); | 431 | (long long)addr0); |
425 | return err ? err : -1; | 432 | return err ? err : -1; |
426 | } | 433 | } |
427 | 434 | ||
428 | pr_info("erasing block %d\n", ebnum); | 435 | printk(PRINT_PREF "erasing block %d\n", ebnum); |
429 | err = erase_eraseblock(ebnum); | 436 | err = erase_eraseblock(ebnum); |
430 | if (err) | 437 | if (err) |
431 | return err; | 438 | return err; |
432 | 439 | ||
433 | pr_info("reading 1st page of block %d\n", ebnum); | 440 | printk(PRINT_PREF "reading 1st page of block %d\n", ebnum); |
434 | err = mtd_read(mtd, addr0, pgsize, &read, twopages); | 441 | err = mtd->read(mtd, addr0, pgsize, &read, twopages); |
435 | if (mtd_is_bitflip(err)) | 442 | if (err == -EUCLEAN) |
436 | err = 0; | 443 | err = 0; |
437 | if (err || read != pgsize) { | 444 | if (err || read != pgsize) { |
438 | pr_err("error: read failed at %#llx\n", | 445 | printk(PRINT_PREF "error: read failed at %#llx\n", |
439 | (long long)addr0); | 446 | (long long)addr0); |
440 | return err ? err : -1; | 447 | return err ? err : -1; |
441 | } | 448 | } |
442 | 449 | ||
443 | pr_info("verifying 1st page of block %d is all 0xff\n", | 450 | printk(PRINT_PREF "verifying 1st page of block %d is all 0xff\n", |
444 | ebnum); | 451 | ebnum); |
445 | for (i = 0; i < pgsize; ++i) | 452 | for (i = 0; i < pgsize; ++i) |
446 | if (twopages[i] != 0xff) { | 453 | if (twopages[i] != 0xff) { |
447 | pr_err("verifying all 0xff failed at %d\n", | 454 | printk(PRINT_PREF "verifying all 0xff failed at %d\n", |
448 | i); | 455 | i); |
449 | errcnt += 1; | 456 | errcnt += 1; |
450 | ok = 0; | 457 | ok = 0; |
@@ -452,7 +459,7 @@ static int erasetest(void) | |||
452 | } | 459 | } |
453 | 460 | ||
454 | if (ok && !err) | 461 | if (ok && !err) |
455 | pr_info("erasetest ok\n"); | 462 | printk(PRINT_PREF "erasetest ok\n"); |
456 | 463 | ||
457 | return err; | 464 | return err; |
458 | } | 465 | } |
@@ -462,9 +469,9 @@ static int is_block_bad(int ebnum) | |||
462 | loff_t addr = ebnum * mtd->erasesize; | 469 | loff_t addr = ebnum * mtd->erasesize; |
463 | int ret; | 470 | int ret; |
464 | 471 | ||
465 | ret = mtd_block_isbad(mtd, addr); | 472 | ret = mtd->block_isbad(mtd, addr); |
466 | if (ret) | 473 | if (ret) |
467 | pr_info("block %d is bad\n", ebnum); | 474 | printk(PRINT_PREF "block %d is bad\n", ebnum); |
468 | return ret; | 475 | return ret; |
469 | } | 476 | } |
470 | 477 | ||
@@ -474,18 +481,18 @@ static int scan_for_bad_eraseblocks(void) | |||
474 | 481 | ||
475 | bbt = kzalloc(ebcnt, GFP_KERNEL); | 482 | bbt = kzalloc(ebcnt, GFP_KERNEL); |
476 | if (!bbt) { | 483 | if (!bbt) { |
477 | pr_err("error: cannot allocate memory\n"); | 484 | printk(PRINT_PREF "error: cannot allocate memory\n"); |
478 | return -ENOMEM; | 485 | return -ENOMEM; |
479 | } | 486 | } |
480 | 487 | ||
481 | pr_info("scanning for bad eraseblocks\n"); | 488 | printk(PRINT_PREF "scanning for bad eraseblocks\n"); |
482 | for (i = 0; i < ebcnt; ++i) { | 489 | for (i = 0; i < ebcnt; ++i) { |
483 | bbt[i] = is_block_bad(i) ? 1 : 0; | 490 | bbt[i] = is_block_bad(i) ? 1 : 0; |
484 | if (bbt[i]) | 491 | if (bbt[i]) |
485 | bad += 1; | 492 | bad += 1; |
486 | cond_resched(); | 493 | cond_resched(); |
487 | } | 494 | } |
488 | pr_info("scanned %d eraseblocks, %d are bad\n", i, bad); | 495 | printk(PRINT_PREF "scanned %d eraseblocks, %d are bad\n", i, bad); |
489 | return 0; | 496 | return 0; |
490 | } | 497 | } |
491 | 498 | ||
@@ -497,24 +504,17 @@ static int __init mtd_pagetest_init(void) | |||
497 | 504 | ||
498 | printk(KERN_INFO "\n"); | 505 | printk(KERN_INFO "\n"); |
499 | printk(KERN_INFO "=================================================\n"); | 506 | printk(KERN_INFO "=================================================\n"); |
500 | 507 | printk(PRINT_PREF "MTD device: %d\n", dev); | |
501 | if (dev < 0) { | ||
502 | pr_info("Please specify a valid mtd-device via module parameter\n"); | ||
503 | pr_crit("CAREFUL: This test wipes all data on the specified MTD device!\n"); | ||
504 | return -EINVAL; | ||
505 | } | ||
506 | |||
507 | pr_info("MTD device: %d\n", dev); | ||
508 | 508 | ||
509 | mtd = get_mtd_device(NULL, dev); | 509 | mtd = get_mtd_device(NULL, dev); |
510 | if (IS_ERR(mtd)) { | 510 | if (IS_ERR(mtd)) { |
511 | err = PTR_ERR(mtd); | 511 | err = PTR_ERR(mtd); |
512 | pr_err("error: cannot get MTD device\n"); | 512 | printk(PRINT_PREF "error: cannot get MTD device\n"); |
513 | return err; | 513 | return err; |
514 | } | 514 | } |
515 | 515 | ||
516 | if (mtd->type != MTD_NANDFLASH) { | 516 | if (mtd->type != MTD_NANDFLASH) { |
517 | pr_info("this test requires NAND flash\n"); | 517 | printk(PRINT_PREF "this test requires NAND flash\n"); |
518 | goto out; | 518 | goto out; |
519 | } | 519 | } |
520 | 520 | ||
@@ -524,7 +524,7 @@ static int __init mtd_pagetest_init(void) | |||
524 | pgcnt = mtd->erasesize / mtd->writesize; | 524 | pgcnt = mtd->erasesize / mtd->writesize; |
525 | pgsize = mtd->writesize; | 525 | pgsize = mtd->writesize; |
526 | 526 | ||
527 | pr_info("MTD device size %llu, eraseblock size %u, " | 527 | printk(PRINT_PREF "MTD device size %llu, eraseblock size %u, " |
528 | "page size %u, count of eraseblocks %u, pages per " | 528 | "page size %u, count of eraseblocks %u, pages per " |
529 | "eraseblock %u, OOB size %u\n", | 529 | "eraseblock %u, OOB size %u\n", |
530 | (unsigned long long)mtd->size, mtd->erasesize, | 530 | (unsigned long long)mtd->size, mtd->erasesize, |
@@ -534,17 +534,17 @@ static int __init mtd_pagetest_init(void) | |||
534 | bufsize = pgsize * 2; | 534 | bufsize = pgsize * 2; |
535 | writebuf = kmalloc(mtd->erasesize, GFP_KERNEL); | 535 | writebuf = kmalloc(mtd->erasesize, GFP_KERNEL); |
536 | if (!writebuf) { | 536 | if (!writebuf) { |
537 | pr_err("error: cannot allocate memory\n"); | 537 | printk(PRINT_PREF "error: cannot allocate memory\n"); |
538 | goto out; | 538 | goto out; |
539 | } | 539 | } |
540 | twopages = kmalloc(bufsize, GFP_KERNEL); | 540 | twopages = kmalloc(bufsize, GFP_KERNEL); |
541 | if (!twopages) { | 541 | if (!twopages) { |
542 | pr_err("error: cannot allocate memory\n"); | 542 | printk(PRINT_PREF "error: cannot allocate memory\n"); |
543 | goto out; | 543 | goto out; |
544 | } | 544 | } |
545 | boundary = kmalloc(bufsize, GFP_KERNEL); | 545 | boundary = kmalloc(bufsize, GFP_KERNEL); |
546 | if (!boundary) { | 546 | if (!boundary) { |
547 | pr_err("error: cannot allocate memory\n"); | 547 | printk(PRINT_PREF "error: cannot allocate memory\n"); |
548 | goto out; | 548 | goto out; |
549 | } | 549 | } |
550 | 550 | ||
@@ -553,7 +553,7 @@ static int __init mtd_pagetest_init(void) | |||
553 | goto out; | 553 | goto out; |
554 | 554 | ||
555 | /* Erase all eraseblocks */ | 555 | /* Erase all eraseblocks */ |
556 | pr_info("erasing whole device\n"); | 556 | printk(PRINT_PREF "erasing whole device\n"); |
557 | for (i = 0; i < ebcnt; ++i) { | 557 | for (i = 0; i < ebcnt; ++i) { |
558 | if (bbt[i]) | 558 | if (bbt[i]) |
559 | continue; | 559 | continue; |
@@ -562,11 +562,11 @@ static int __init mtd_pagetest_init(void) | |||
562 | goto out; | 562 | goto out; |
563 | cond_resched(); | 563 | cond_resched(); |
564 | } | 564 | } |
565 | pr_info("erased %u eraseblocks\n", i); | 565 | printk(PRINT_PREF "erased %u eraseblocks\n", i); |
566 | 566 | ||
567 | /* Write all eraseblocks */ | 567 | /* Write all eraseblocks */ |
568 | simple_srand(1); | 568 | simple_srand(1); |
569 | pr_info("writing whole device\n"); | 569 | printk(PRINT_PREF "writing whole device\n"); |
570 | for (i = 0; i < ebcnt; ++i) { | 570 | for (i = 0; i < ebcnt; ++i) { |
571 | if (bbt[i]) | 571 | if (bbt[i]) |
572 | continue; | 572 | continue; |
@@ -574,14 +574,14 @@ static int __init mtd_pagetest_init(void) | |||
574 | if (err) | 574 | if (err) |
575 | goto out; | 575 | goto out; |
576 | if (i % 256 == 0) | 576 | if (i % 256 == 0) |
577 | pr_info("written up to eraseblock %u\n", i); | 577 | printk(PRINT_PREF "written up to eraseblock %u\n", i); |
578 | cond_resched(); | 578 | cond_resched(); |
579 | } | 579 | } |
580 | pr_info("written %u eraseblocks\n", i); | 580 | printk(PRINT_PREF "written %u eraseblocks\n", i); |
581 | 581 | ||
582 | /* Check all eraseblocks */ | 582 | /* Check all eraseblocks */ |
583 | simple_srand(1); | 583 | simple_srand(1); |
584 | pr_info("verifying all eraseblocks\n"); | 584 | printk(PRINT_PREF "verifying all eraseblocks\n"); |
585 | for (i = 0; i < ebcnt; ++i) { | 585 | for (i = 0; i < ebcnt; ++i) { |
586 | if (bbt[i]) | 586 | if (bbt[i]) |
587 | continue; | 587 | continue; |
@@ -589,10 +589,10 @@ static int __init mtd_pagetest_init(void) | |||
589 | if (err) | 589 | if (err) |
590 | goto out; | 590 | goto out; |
591 | if (i % 256 == 0) | 591 | if (i % 256 == 0) |
592 | pr_info("verified up to eraseblock %u\n", i); | 592 | printk(PRINT_PREF "verified up to eraseblock %u\n", i); |
593 | cond_resched(); | 593 | cond_resched(); |
594 | } | 594 | } |
595 | pr_info("verified %u eraseblocks\n", i); | 595 | printk(PRINT_PREF "verified %u eraseblocks\n", i); |
596 | 596 | ||
597 | err = crosstest(); | 597 | err = crosstest(); |
598 | if (err) | 598 | if (err) |
@@ -606,7 +606,7 @@ static int __init mtd_pagetest_init(void) | |||
606 | if (err) | 606 | if (err) |
607 | goto out; | 607 | goto out; |
608 | 608 | ||
609 | pr_info("finished with %d errors\n", errcnt); | 609 | printk(PRINT_PREF "finished with %d errors\n", errcnt); |
610 | out: | 610 | out: |
611 | 611 | ||
612 | kfree(bbt); | 612 | kfree(bbt); |
@@ -615,7 +615,7 @@ out: | |||
615 | kfree(writebuf); | 615 | kfree(writebuf); |
616 | put_mtd_device(mtd); | 616 | put_mtd_device(mtd); |
617 | if (err) | 617 | if (err) |
618 | pr_info("error %d occurred\n", err); | 618 | printk(PRINT_PREF "error %d occurred\n", err); |
619 | printk(KERN_INFO "=================================================\n"); | 619 | printk(KERN_INFO "=================================================\n"); |
620 | return err; | 620 | return err; |
621 | } | 621 | } |
diff --git a/drivers/mtd/tests/mtd_readtest.c b/drivers/mtd/tests/mtd_readtest.c index 266de04b6d2..afe71aa15c4 100644 --- a/drivers/mtd/tests/mtd_readtest.c +++ b/drivers/mtd/tests/mtd_readtest.c | |||
@@ -19,8 +19,6 @@ | |||
19 | * Author: Adrian Hunter <ext-adrian.hunter@nokia.com> | 19 | * Author: Adrian Hunter <ext-adrian.hunter@nokia.com> |
20 | */ | 20 | */ |
21 | 21 | ||
22 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
23 | |||
24 | #include <linux/init.h> | 22 | #include <linux/init.h> |
25 | #include <linux/module.h> | 23 | #include <linux/module.h> |
26 | #include <linux/moduleparam.h> | 24 | #include <linux/moduleparam.h> |
@@ -29,7 +27,9 @@ | |||
29 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
30 | #include <linux/sched.h> | 28 | #include <linux/sched.h> |
31 | 29 | ||
32 | static int dev = -EINVAL; | 30 | #define PRINT_PREF KERN_INFO "mtd_readtest: " |
31 | |||
32 | static int dev; | ||
33 | module_param(dev, int, S_IRUGO); | 33 | module_param(dev, int, S_IRUGO); |
34 | MODULE_PARM_DESC(dev, "MTD device number to use"); | 34 | MODULE_PARM_DESC(dev, "MTD device number to use"); |
35 | 35 | ||
@@ -44,19 +44,19 @@ static int pgcnt; | |||
44 | 44 | ||
45 | static int read_eraseblock_by_page(int ebnum) | 45 | static int read_eraseblock_by_page(int ebnum) |
46 | { | 46 | { |
47 | size_t read; | 47 | size_t read = 0; |
48 | int i, ret, err = 0; | 48 | int i, ret, err = 0; |
49 | loff_t addr = ebnum * mtd->erasesize; | 49 | loff_t addr = ebnum * mtd->erasesize; |
50 | void *buf = iobuf; | 50 | void *buf = iobuf; |
51 | void *oobbuf = iobuf1; | 51 | void *oobbuf = iobuf1; |
52 | 52 | ||
53 | for (i = 0; i < pgcnt; i++) { | 53 | for (i = 0; i < pgcnt; i++) { |
54 | memset(buf, 0 , pgsize); | 54 | memset(buf, 0 , pgcnt); |
55 | ret = mtd_read(mtd, addr, pgsize, &read, buf); | 55 | ret = mtd->read(mtd, addr, pgsize, &read, buf); |
56 | if (ret == -EUCLEAN) | 56 | if (ret == -EUCLEAN) |
57 | ret = 0; | 57 | ret = 0; |
58 | if (ret || read != pgsize) { | 58 | if (ret || read != pgsize) { |
59 | pr_err("error: read failed at %#llx\n", | 59 | printk(PRINT_PREF "error: read failed at %#llx\n", |
60 | (long long)addr); | 60 | (long long)addr); |
61 | if (!err) | 61 | if (!err) |
62 | err = ret; | 62 | err = ret; |
@@ -66,7 +66,7 @@ static int read_eraseblock_by_page(int ebnum) | |||
66 | if (mtd->oobsize) { | 66 | if (mtd->oobsize) { |
67 | struct mtd_oob_ops ops; | 67 | struct mtd_oob_ops ops; |
68 | 68 | ||
69 | ops.mode = MTD_OPS_PLACE_OOB; | 69 | ops.mode = MTD_OOB_PLACE; |
70 | ops.len = 0; | 70 | ops.len = 0; |
71 | ops.retlen = 0; | 71 | ops.retlen = 0; |
72 | ops.ooblen = mtd->oobsize; | 72 | ops.ooblen = mtd->oobsize; |
@@ -74,10 +74,9 @@ static int read_eraseblock_by_page(int ebnum) | |||
74 | ops.ooboffs = 0; | 74 | ops.ooboffs = 0; |
75 | ops.datbuf = NULL; | 75 | ops.datbuf = NULL; |
76 | ops.oobbuf = oobbuf; | 76 | ops.oobbuf = oobbuf; |
77 | ret = mtd_read_oob(mtd, addr, &ops); | 77 | ret = mtd->read_oob(mtd, addr, &ops); |
78 | if ((ret && !mtd_is_bitflip(ret)) || | 78 | if (ret || ops.oobretlen != mtd->oobsize) { |
79 | ops.oobretlen != mtd->oobsize) { | 79 | printk(PRINT_PREF "error: read oob failed at " |
80 | pr_err("error: read oob failed at " | ||
81 | "%#llx\n", (long long)addr); | 80 | "%#llx\n", (long long)addr); |
82 | if (!err) | 81 | if (!err) |
83 | err = ret; | 82 | err = ret; |
@@ -99,7 +98,7 @@ static void dump_eraseblock(int ebnum) | |||
99 | char line[128]; | 98 | char line[128]; |
100 | int pg, oob; | 99 | int pg, oob; |
101 | 100 | ||
102 | pr_info("dumping eraseblock %d\n", ebnum); | 101 | printk(PRINT_PREF "dumping eraseblock %d\n", ebnum); |
103 | n = mtd->erasesize; | 102 | n = mtd->erasesize; |
104 | for (i = 0; i < n;) { | 103 | for (i = 0; i < n;) { |
105 | char *p = line; | 104 | char *p = line; |
@@ -112,7 +111,7 @@ static void dump_eraseblock(int ebnum) | |||
112 | } | 111 | } |
113 | if (!mtd->oobsize) | 112 | if (!mtd->oobsize) |
114 | return; | 113 | return; |
115 | pr_info("dumping oob from eraseblock %d\n", ebnum); | 114 | printk(PRINT_PREF "dumping oob from eraseblock %d\n", ebnum); |
116 | n = mtd->oobsize; | 115 | n = mtd->oobsize; |
117 | for (pg = 0, i = 0; pg < pgcnt; pg++) | 116 | for (pg = 0, i = 0; pg < pgcnt; pg++) |
118 | for (oob = 0; oob < n;) { | 117 | for (oob = 0; oob < n;) { |
@@ -132,9 +131,9 @@ static int is_block_bad(int ebnum) | |||
132 | loff_t addr = ebnum * mtd->erasesize; | 131 | loff_t addr = ebnum * mtd->erasesize; |
133 | int ret; | 132 | int ret; |
134 | 133 | ||
135 | ret = mtd_block_isbad(mtd, addr); | 134 | ret = mtd->block_isbad(mtd, addr); |
136 | if (ret) | 135 | if (ret) |
137 | pr_info("block %d is bad\n", ebnum); | 136 | printk(PRINT_PREF "block %d is bad\n", ebnum); |
138 | return ret; | 137 | return ret; |
139 | } | 138 | } |
140 | 139 | ||
@@ -144,21 +143,22 @@ static int scan_for_bad_eraseblocks(void) | |||
144 | 143 | ||
145 | bbt = kzalloc(ebcnt, GFP_KERNEL); | 144 | bbt = kzalloc(ebcnt, GFP_KERNEL); |
146 | if (!bbt) { | 145 | if (!bbt) { |
147 | pr_err("error: cannot allocate memory\n"); | 146 | printk(PRINT_PREF "error: cannot allocate memory\n"); |
148 | return -ENOMEM; | 147 | return -ENOMEM; |
149 | } | 148 | } |
150 | 149 | ||
151 | if (!mtd_can_have_bb(mtd)) | 150 | /* NOR flash does not implement block_isbad */ |
151 | if (mtd->block_isbad == NULL) | ||
152 | return 0; | 152 | return 0; |
153 | 153 | ||
154 | pr_info("scanning for bad eraseblocks\n"); | 154 | printk(PRINT_PREF "scanning for bad eraseblocks\n"); |
155 | for (i = 0; i < ebcnt; ++i) { | 155 | for (i = 0; i < ebcnt; ++i) { |
156 | bbt[i] = is_block_bad(i) ? 1 : 0; | 156 | bbt[i] = is_block_bad(i) ? 1 : 0; |
157 | if (bbt[i]) | 157 | if (bbt[i]) |
158 | bad += 1; | 158 | bad += 1; |
159 | cond_resched(); | 159 | cond_resched(); |
160 | } | 160 | } |
161 | pr_info("scanned %d eraseblocks, %d are bad\n", i, bad); | 161 | printk(PRINT_PREF "scanned %d eraseblocks, %d are bad\n", i, bad); |
162 | return 0; | 162 | return 0; |
163 | } | 163 | } |
164 | 164 | ||
@@ -169,23 +169,17 @@ static int __init mtd_readtest_init(void) | |||
169 | 169 | ||
170 | printk(KERN_INFO "\n"); | 170 | printk(KERN_INFO "\n"); |
171 | printk(KERN_INFO "=================================================\n"); | 171 | printk(KERN_INFO "=================================================\n"); |
172 | 172 | printk(PRINT_PREF "MTD device: %d\n", dev); | |
173 | if (dev < 0) { | ||
174 | pr_info("Please specify a valid mtd-device via module parameter\n"); | ||
175 | return -EINVAL; | ||
176 | } | ||
177 | |||
178 | pr_info("MTD device: %d\n", dev); | ||
179 | 173 | ||
180 | mtd = get_mtd_device(NULL, dev); | 174 | mtd = get_mtd_device(NULL, dev); |
181 | if (IS_ERR(mtd)) { | 175 | if (IS_ERR(mtd)) { |
182 | err = PTR_ERR(mtd); | 176 | err = PTR_ERR(mtd); |
183 | pr_err("error: Cannot get MTD device\n"); | 177 | printk(PRINT_PREF "error: Cannot get MTD device\n"); |
184 | return err; | 178 | return err; |
185 | } | 179 | } |
186 | 180 | ||
187 | if (mtd->writesize == 1) { | 181 | if (mtd->writesize == 1) { |
188 | pr_info("not NAND flash, assume page size is 512 " | 182 | printk(PRINT_PREF "not NAND flash, assume page size is 512 " |
189 | "bytes.\n"); | 183 | "bytes.\n"); |
190 | pgsize = 512; | 184 | pgsize = 512; |
191 | } else | 185 | } else |
@@ -196,7 +190,7 @@ static int __init mtd_readtest_init(void) | |||
196 | ebcnt = tmp; | 190 | ebcnt = tmp; |
197 | pgcnt = mtd->erasesize / pgsize; | 191 | pgcnt = mtd->erasesize / pgsize; |
198 | 192 | ||
199 | pr_info("MTD device size %llu, eraseblock size %u, " | 193 | printk(PRINT_PREF "MTD device size %llu, eraseblock size %u, " |
200 | "page size %u, count of eraseblocks %u, pages per " | 194 | "page size %u, count of eraseblocks %u, pages per " |
201 | "eraseblock %u, OOB size %u\n", | 195 | "eraseblock %u, OOB size %u\n", |
202 | (unsigned long long)mtd->size, mtd->erasesize, | 196 | (unsigned long long)mtd->size, mtd->erasesize, |
@@ -205,12 +199,12 @@ static int __init mtd_readtest_init(void) | |||
205 | err = -ENOMEM; | 199 | err = -ENOMEM; |
206 | iobuf = kmalloc(mtd->erasesize, GFP_KERNEL); | 200 | iobuf = kmalloc(mtd->erasesize, GFP_KERNEL); |
207 | if (!iobuf) { | 201 | if (!iobuf) { |
208 | pr_err("error: cannot allocate memory\n"); | 202 | printk(PRINT_PREF "error: cannot allocate memory\n"); |
209 | goto out; | 203 | goto out; |
210 | } | 204 | } |
211 | iobuf1 = kmalloc(mtd->erasesize, GFP_KERNEL); | 205 | iobuf1 = kmalloc(mtd->erasesize, GFP_KERNEL); |
212 | if (!iobuf1) { | 206 | if (!iobuf1) { |
213 | pr_err("error: cannot allocate memory\n"); | 207 | printk(PRINT_PREF "error: cannot allocate memory\n"); |
214 | goto out; | 208 | goto out; |
215 | } | 209 | } |
216 | 210 | ||
@@ -219,7 +213,7 @@ static int __init mtd_readtest_init(void) | |||
219 | goto out; | 213 | goto out; |
220 | 214 | ||
221 | /* Read all eraseblocks 1 page at a time */ | 215 | /* Read all eraseblocks 1 page at a time */ |
222 | pr_info("testing page read\n"); | 216 | printk(PRINT_PREF "testing page read\n"); |
223 | for (i = 0; i < ebcnt; ++i) { | 217 | for (i = 0; i < ebcnt; ++i) { |
224 | int ret; | 218 | int ret; |
225 | 219 | ||
@@ -235,9 +229,9 @@ static int __init mtd_readtest_init(void) | |||
235 | } | 229 | } |
236 | 230 | ||
237 | if (err) | 231 | if (err) |
238 | pr_info("finished with errors\n"); | 232 | printk(PRINT_PREF "finished with errors\n"); |
239 | else | 233 | else |
240 | pr_info("finished\n"); | 234 | printk(PRINT_PREF "finished\n"); |
241 | 235 | ||
242 | out: | 236 | out: |
243 | 237 | ||
@@ -246,7 +240,7 @@ out: | |||
246 | kfree(bbt); | 240 | kfree(bbt); |
247 | put_mtd_device(mtd); | 241 | put_mtd_device(mtd); |
248 | if (err) | 242 | if (err) |
249 | pr_info("error %d occurred\n", err); | 243 | printk(PRINT_PREF "error %d occurred\n", err); |
250 | printk(KERN_INFO "=================================================\n"); | 244 | printk(KERN_INFO "=================================================\n"); |
251 | return err; | 245 | return err; |
252 | } | 246 | } |
diff --git a/drivers/mtd/tests/mtd_speedtest.c b/drivers/mtd/tests/mtd_speedtest.c index 596cbea8df4..627d4e2466a 100644 --- a/drivers/mtd/tests/mtd_speedtest.c +++ b/drivers/mtd/tests/mtd_speedtest.c | |||
@@ -19,8 +19,6 @@ | |||
19 | * Author: Adrian Hunter <adrian.hunter@nokia.com> | 19 | * Author: Adrian Hunter <adrian.hunter@nokia.com> |
20 | */ | 20 | */ |
21 | 21 | ||
22 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
23 | |||
24 | #include <linux/init.h> | 22 | #include <linux/init.h> |
25 | #include <linux/module.h> | 23 | #include <linux/module.h> |
26 | #include <linux/moduleparam.h> | 24 | #include <linux/moduleparam.h> |
@@ -28,9 +26,10 @@ | |||
28 | #include <linux/mtd/mtd.h> | 26 | #include <linux/mtd/mtd.h> |
29 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
30 | #include <linux/sched.h> | 28 | #include <linux/sched.h> |
31 | #include <linux/random.h> | ||
32 | 29 | ||
33 | static int dev = -EINVAL; | 30 | #define PRINT_PREF KERN_INFO "mtd_speedtest: " |
31 | |||
32 | static int dev; | ||
34 | module_param(dev, int, S_IRUGO); | 33 | module_param(dev, int, S_IRUGO); |
35 | MODULE_PARM_DESC(dev, "MTD device number to use"); | 34 | MODULE_PARM_DESC(dev, "MTD device number to use"); |
36 | 35 | ||
@@ -48,13 +47,25 @@ static int ebcnt; | |||
48 | static int pgcnt; | 47 | static int pgcnt; |
49 | static int goodebcnt; | 48 | static int goodebcnt; |
50 | static struct timeval start, finish; | 49 | static struct timeval start, finish; |
50 | static unsigned long next = 1; | ||
51 | |||
52 | static inline unsigned int simple_rand(void) | ||
53 | { | ||
54 | next = next * 1103515245 + 12345; | ||
55 | return (unsigned int)((next / 65536) % 32768); | ||
56 | } | ||
57 | |||
58 | static inline void simple_srand(unsigned long seed) | ||
59 | { | ||
60 | next = seed; | ||
61 | } | ||
51 | 62 | ||
52 | static void set_random_data(unsigned char *buf, size_t len) | 63 | static void set_random_data(unsigned char *buf, size_t len) |
53 | { | 64 | { |
54 | size_t i; | 65 | size_t i; |
55 | 66 | ||
56 | for (i = 0; i < len; ++i) | 67 | for (i = 0; i < len; ++i) |
57 | buf[i] = random32(); | 68 | buf[i] = simple_rand(); |
58 | } | 69 | } |
59 | 70 | ||
60 | static int erase_eraseblock(int ebnum) | 71 | static int erase_eraseblock(int ebnum) |
@@ -68,14 +79,14 @@ static int erase_eraseblock(int ebnum) | |||
68 | ei.addr = addr; | 79 | ei.addr = addr; |
69 | ei.len = mtd->erasesize; | 80 | ei.len = mtd->erasesize; |
70 | 81 | ||
71 | err = mtd_erase(mtd, &ei); | 82 | err = mtd->erase(mtd, &ei); |
72 | if (err) { | 83 | if (err) { |
73 | pr_err("error %d while erasing EB %d\n", err, ebnum); | 84 | printk(PRINT_PREF "error %d while erasing EB %d\n", err, ebnum); |
74 | return err; | 85 | return err; |
75 | } | 86 | } |
76 | 87 | ||
77 | if (ei.state == MTD_ERASE_FAILED) { | 88 | if (ei.state == MTD_ERASE_FAILED) { |
78 | pr_err("some erase error occurred at EB %d\n", | 89 | printk(PRINT_PREF "some erase error occurred at EB %d\n", |
79 | ebnum); | 90 | ebnum); |
80 | return -EIO; | 91 | return -EIO; |
81 | } | 92 | } |
@@ -94,15 +105,15 @@ static int multiblock_erase(int ebnum, int blocks) | |||
94 | ei.addr = addr; | 105 | ei.addr = addr; |
95 | ei.len = mtd->erasesize * blocks; | 106 | ei.len = mtd->erasesize * blocks; |
96 | 107 | ||
97 | err = mtd_erase(mtd, &ei); | 108 | err = mtd->erase(mtd, &ei); |
98 | if (err) { | 109 | if (err) { |
99 | pr_err("error %d while erasing EB %d, blocks %d\n", | 110 | printk(PRINT_PREF "error %d while erasing EB %d, blocks %d\n", |
100 | err, ebnum, blocks); | 111 | err, ebnum, blocks); |
101 | return err; | 112 | return err; |
102 | } | 113 | } |
103 | 114 | ||
104 | if (ei.state == MTD_ERASE_FAILED) { | 115 | if (ei.state == MTD_ERASE_FAILED) { |
105 | pr_err("some erase error occurred at EB %d," | 116 | printk(PRINT_PREF "some erase error occurred at EB %d," |
106 | "blocks %d\n", ebnum, blocks); | 117 | "blocks %d\n", ebnum, blocks); |
107 | return -EIO; | 118 | return -EIO; |
108 | } | 119 | } |
@@ -128,13 +139,13 @@ static int erase_whole_device(void) | |||
128 | 139 | ||
129 | static int write_eraseblock(int ebnum) | 140 | static int write_eraseblock(int ebnum) |
130 | { | 141 | { |
131 | size_t written; | 142 | size_t written = 0; |
132 | int err = 0; | 143 | int err = 0; |
133 | loff_t addr = ebnum * mtd->erasesize; | 144 | loff_t addr = ebnum * mtd->erasesize; |
134 | 145 | ||
135 | err = mtd_write(mtd, addr, mtd->erasesize, &written, iobuf); | 146 | err = mtd->write(mtd, addr, mtd->erasesize, &written, iobuf); |
136 | if (err || written != mtd->erasesize) { | 147 | if (err || written != mtd->erasesize) { |
137 | pr_err("error: write failed at %#llx\n", addr); | 148 | printk(PRINT_PREF "error: write failed at %#llx\n", addr); |
138 | if (!err) | 149 | if (!err) |
139 | err = -EINVAL; | 150 | err = -EINVAL; |
140 | } | 151 | } |
@@ -144,15 +155,15 @@ static int write_eraseblock(int ebnum) | |||
144 | 155 | ||
145 | static int write_eraseblock_by_page(int ebnum) | 156 | static int write_eraseblock_by_page(int ebnum) |
146 | { | 157 | { |
147 | size_t written; | 158 | size_t written = 0; |
148 | int i, err = 0; | 159 | int i, err = 0; |
149 | loff_t addr = ebnum * mtd->erasesize; | 160 | loff_t addr = ebnum * mtd->erasesize; |
150 | void *buf = iobuf; | 161 | void *buf = iobuf; |
151 | 162 | ||
152 | for (i = 0; i < pgcnt; i++) { | 163 | for (i = 0; i < pgcnt; i++) { |
153 | err = mtd_write(mtd, addr, pgsize, &written, buf); | 164 | err = mtd->write(mtd, addr, pgsize, &written, buf); |
154 | if (err || written != pgsize) { | 165 | if (err || written != pgsize) { |
155 | pr_err("error: write failed at %#llx\n", | 166 | printk(PRINT_PREF "error: write failed at %#llx\n", |
156 | addr); | 167 | addr); |
157 | if (!err) | 168 | if (!err) |
158 | err = -EINVAL; | 169 | err = -EINVAL; |
@@ -167,15 +178,15 @@ static int write_eraseblock_by_page(int ebnum) | |||
167 | 178 | ||
168 | static int write_eraseblock_by_2pages(int ebnum) | 179 | static int write_eraseblock_by_2pages(int ebnum) |
169 | { | 180 | { |
170 | size_t written, sz = pgsize * 2; | 181 | size_t written = 0, sz = pgsize * 2; |
171 | int i, n = pgcnt / 2, err = 0; | 182 | int i, n = pgcnt / 2, err = 0; |
172 | loff_t addr = ebnum * mtd->erasesize; | 183 | loff_t addr = ebnum * mtd->erasesize; |
173 | void *buf = iobuf; | 184 | void *buf = iobuf; |
174 | 185 | ||
175 | for (i = 0; i < n; i++) { | 186 | for (i = 0; i < n; i++) { |
176 | err = mtd_write(mtd, addr, sz, &written, buf); | 187 | err = mtd->write(mtd, addr, sz, &written, buf); |
177 | if (err || written != sz) { | 188 | if (err || written != sz) { |
178 | pr_err("error: write failed at %#llx\n", | 189 | printk(PRINT_PREF "error: write failed at %#llx\n", |
179 | addr); | 190 | addr); |
180 | if (!err) | 191 | if (!err) |
181 | err = -EINVAL; | 192 | err = -EINVAL; |
@@ -185,9 +196,9 @@ static int write_eraseblock_by_2pages(int ebnum) | |||
185 | buf += sz; | 196 | buf += sz; |
186 | } | 197 | } |
187 | if (pgcnt % 2) { | 198 | if (pgcnt % 2) { |
188 | err = mtd_write(mtd, addr, pgsize, &written, buf); | 199 | err = mtd->write(mtd, addr, pgsize, &written, buf); |
189 | if (err || written != pgsize) { | 200 | if (err || written != pgsize) { |
190 | pr_err("error: write failed at %#llx\n", | 201 | printk(PRINT_PREF "error: write failed at %#llx\n", |
191 | addr); | 202 | addr); |
192 | if (!err) | 203 | if (!err) |
193 | err = -EINVAL; | 204 | err = -EINVAL; |
@@ -199,16 +210,16 @@ static int write_eraseblock_by_2pages(int ebnum) | |||
199 | 210 | ||
200 | static int read_eraseblock(int ebnum) | 211 | static int read_eraseblock(int ebnum) |
201 | { | 212 | { |
202 | size_t read; | 213 | size_t read = 0; |
203 | int err = 0; | 214 | int err = 0; |
204 | loff_t addr = ebnum * mtd->erasesize; | 215 | loff_t addr = ebnum * mtd->erasesize; |
205 | 216 | ||
206 | err = mtd_read(mtd, addr, mtd->erasesize, &read, iobuf); | 217 | err = mtd->read(mtd, addr, mtd->erasesize, &read, iobuf); |
207 | /* Ignore corrected ECC errors */ | 218 | /* Ignore corrected ECC errors */ |
208 | if (mtd_is_bitflip(err)) | 219 | if (err == -EUCLEAN) |
209 | err = 0; | 220 | err = 0; |
210 | if (err || read != mtd->erasesize) { | 221 | if (err || read != mtd->erasesize) { |
211 | pr_err("error: read failed at %#llx\n", addr); | 222 | printk(PRINT_PREF "error: read failed at %#llx\n", addr); |
212 | if (!err) | 223 | if (!err) |
213 | err = -EINVAL; | 224 | err = -EINVAL; |
214 | } | 225 | } |
@@ -218,18 +229,18 @@ static int read_eraseblock(int ebnum) | |||
218 | 229 | ||
219 | static int read_eraseblock_by_page(int ebnum) | 230 | static int read_eraseblock_by_page(int ebnum) |
220 | { | 231 | { |
221 | size_t read; | 232 | size_t read = 0; |
222 | int i, err = 0; | 233 | int i, err = 0; |
223 | loff_t addr = ebnum * mtd->erasesize; | 234 | loff_t addr = ebnum * mtd->erasesize; |
224 | void *buf = iobuf; | 235 | void *buf = iobuf; |
225 | 236 | ||
226 | for (i = 0; i < pgcnt; i++) { | 237 | for (i = 0; i < pgcnt; i++) { |
227 | err = mtd_read(mtd, addr, pgsize, &read, buf); | 238 | err = mtd->read(mtd, addr, pgsize, &read, buf); |
228 | /* Ignore corrected ECC errors */ | 239 | /* Ignore corrected ECC errors */ |
229 | if (mtd_is_bitflip(err)) | 240 | if (err == -EUCLEAN) |
230 | err = 0; | 241 | err = 0; |
231 | if (err || read != pgsize) { | 242 | if (err || read != pgsize) { |
232 | pr_err("error: read failed at %#llx\n", | 243 | printk(PRINT_PREF "error: read failed at %#llx\n", |
233 | addr); | 244 | addr); |
234 | if (!err) | 245 | if (!err) |
235 | err = -EINVAL; | 246 | err = -EINVAL; |
@@ -244,18 +255,18 @@ static int read_eraseblock_by_page(int ebnum) | |||
244 | 255 | ||
245 | static int read_eraseblock_by_2pages(int ebnum) | 256 | static int read_eraseblock_by_2pages(int ebnum) |
246 | { | 257 | { |
247 | size_t read, sz = pgsize * 2; | 258 | size_t read = 0, sz = pgsize * 2; |
248 | int i, n = pgcnt / 2, err = 0; | 259 | int i, n = pgcnt / 2, err = 0; |
249 | loff_t addr = ebnum * mtd->erasesize; | 260 | loff_t addr = ebnum * mtd->erasesize; |
250 | void *buf = iobuf; | 261 | void *buf = iobuf; |
251 | 262 | ||
252 | for (i = 0; i < n; i++) { | 263 | for (i = 0; i < n; i++) { |
253 | err = mtd_read(mtd, addr, sz, &read, buf); | 264 | err = mtd->read(mtd, addr, sz, &read, buf); |
254 | /* Ignore corrected ECC errors */ | 265 | /* Ignore corrected ECC errors */ |
255 | if (mtd_is_bitflip(err)) | 266 | if (err == -EUCLEAN) |
256 | err = 0; | 267 | err = 0; |
257 | if (err || read != sz) { | 268 | if (err || read != sz) { |
258 | pr_err("error: read failed at %#llx\n", | 269 | printk(PRINT_PREF "error: read failed at %#llx\n", |
259 | addr); | 270 | addr); |
260 | if (!err) | 271 | if (!err) |
261 | err = -EINVAL; | 272 | err = -EINVAL; |
@@ -265,12 +276,12 @@ static int read_eraseblock_by_2pages(int ebnum) | |||
265 | buf += sz; | 276 | buf += sz; |
266 | } | 277 | } |
267 | if (pgcnt % 2) { | 278 | if (pgcnt % 2) { |
268 | err = mtd_read(mtd, addr, pgsize, &read, buf); | 279 | err = mtd->read(mtd, addr, pgsize, &read, buf); |
269 | /* Ignore corrected ECC errors */ | 280 | /* Ignore corrected ECC errors */ |
270 | if (mtd_is_bitflip(err)) | 281 | if (err == -EUCLEAN) |
271 | err = 0; | 282 | err = 0; |
272 | if (err || read != pgsize) { | 283 | if (err || read != pgsize) { |
273 | pr_err("error: read failed at %#llx\n", | 284 | printk(PRINT_PREF "error: read failed at %#llx\n", |
274 | addr); | 285 | addr); |
275 | if (!err) | 286 | if (!err) |
276 | err = -EINVAL; | 287 | err = -EINVAL; |
@@ -285,9 +296,9 @@ static int is_block_bad(int ebnum) | |||
285 | loff_t addr = ebnum * mtd->erasesize; | 296 | loff_t addr = ebnum * mtd->erasesize; |
286 | int ret; | 297 | int ret; |
287 | 298 | ||
288 | ret = mtd_block_isbad(mtd, addr); | 299 | ret = mtd->block_isbad(mtd, addr); |
289 | if (ret) | 300 | if (ret) |
290 | pr_info("block %d is bad\n", ebnum); | 301 | printk(PRINT_PREF "block %d is bad\n", ebnum); |
291 | return ret; | 302 | return ret; |
292 | } | 303 | } |
293 | 304 | ||
@@ -321,21 +332,22 @@ static int scan_for_bad_eraseblocks(void) | |||
321 | 332 | ||
322 | bbt = kzalloc(ebcnt, GFP_KERNEL); | 333 | bbt = kzalloc(ebcnt, GFP_KERNEL); |
323 | if (!bbt) { | 334 | if (!bbt) { |
324 | pr_err("error: cannot allocate memory\n"); | 335 | printk(PRINT_PREF "error: cannot allocate memory\n"); |
325 | return -ENOMEM; | 336 | return -ENOMEM; |
326 | } | 337 | } |
327 | 338 | ||
328 | if (!mtd_can_have_bb(mtd)) | 339 | /* NOR flash does not implement block_isbad */ |
340 | if (mtd->block_isbad == NULL) | ||
329 | goto out; | 341 | goto out; |
330 | 342 | ||
331 | pr_info("scanning for bad eraseblocks\n"); | 343 | printk(PRINT_PREF "scanning for bad eraseblocks\n"); |
332 | for (i = 0; i < ebcnt; ++i) { | 344 | for (i = 0; i < ebcnt; ++i) { |
333 | bbt[i] = is_block_bad(i) ? 1 : 0; | 345 | bbt[i] = is_block_bad(i) ? 1 : 0; |
334 | if (bbt[i]) | 346 | if (bbt[i]) |
335 | bad += 1; | 347 | bad += 1; |
336 | cond_resched(); | 348 | cond_resched(); |
337 | } | 349 | } |
338 | pr_info("scanned %d eraseblocks, %d are bad\n", i, bad); | 350 | printk(PRINT_PREF "scanned %d eraseblocks, %d are bad\n", i, bad); |
339 | out: | 351 | out: |
340 | goodebcnt = ebcnt - bad; | 352 | goodebcnt = ebcnt - bad; |
341 | return 0; | 353 | return 0; |
@@ -349,27 +361,20 @@ static int __init mtd_speedtest_init(void) | |||
349 | 361 | ||
350 | printk(KERN_INFO "\n"); | 362 | printk(KERN_INFO "\n"); |
351 | printk(KERN_INFO "=================================================\n"); | 363 | printk(KERN_INFO "=================================================\n"); |
352 | |||
353 | if (dev < 0) { | ||
354 | pr_info("Please specify a valid mtd-device via module parameter\n"); | ||
355 | pr_crit("CAREFUL: This test wipes all data on the specified MTD device!\n"); | ||
356 | return -EINVAL; | ||
357 | } | ||
358 | |||
359 | if (count) | 364 | if (count) |
360 | pr_info("MTD device: %d count: %d\n", dev, count); | 365 | printk(PRINT_PREF "MTD device: %d count: %d\n", dev, count); |
361 | else | 366 | else |
362 | pr_info("MTD device: %d\n", dev); | 367 | printk(PRINT_PREF "MTD device: %d\n", dev); |
363 | 368 | ||
364 | mtd = get_mtd_device(NULL, dev); | 369 | mtd = get_mtd_device(NULL, dev); |
365 | if (IS_ERR(mtd)) { | 370 | if (IS_ERR(mtd)) { |
366 | err = PTR_ERR(mtd); | 371 | err = PTR_ERR(mtd); |
367 | pr_err("error: cannot get MTD device\n"); | 372 | printk(PRINT_PREF "error: cannot get MTD device\n"); |
368 | return err; | 373 | return err; |
369 | } | 374 | } |
370 | 375 | ||
371 | if (mtd->writesize == 1) { | 376 | if (mtd->writesize == 1) { |
372 | pr_info("not NAND flash, assume page size is 512 " | 377 | printk(PRINT_PREF "not NAND flash, assume page size is 512 " |
373 | "bytes.\n"); | 378 | "bytes.\n"); |
374 | pgsize = 512; | 379 | pgsize = 512; |
375 | } else | 380 | } else |
@@ -380,7 +385,7 @@ static int __init mtd_speedtest_init(void) | |||
380 | ebcnt = tmp; | 385 | ebcnt = tmp; |
381 | pgcnt = mtd->erasesize / pgsize; | 386 | pgcnt = mtd->erasesize / pgsize; |
382 | 387 | ||
383 | pr_info("MTD device size %llu, eraseblock size %u, " | 388 | printk(PRINT_PREF "MTD device size %llu, eraseblock size %u, " |
384 | "page size %u, count of eraseblocks %u, pages per " | 389 | "page size %u, count of eraseblocks %u, pages per " |
385 | "eraseblock %u, OOB size %u\n", | 390 | "eraseblock %u, OOB size %u\n", |
386 | (unsigned long long)mtd->size, mtd->erasesize, | 391 | (unsigned long long)mtd->size, mtd->erasesize, |
@@ -392,10 +397,11 @@ static int __init mtd_speedtest_init(void) | |||
392 | err = -ENOMEM; | 397 | err = -ENOMEM; |
393 | iobuf = kmalloc(mtd->erasesize, GFP_KERNEL); | 398 | iobuf = kmalloc(mtd->erasesize, GFP_KERNEL); |
394 | if (!iobuf) { | 399 | if (!iobuf) { |
395 | pr_err("error: cannot allocate memory\n"); | 400 | printk(PRINT_PREF "error: cannot allocate memory\n"); |
396 | goto out; | 401 | goto out; |
397 | } | 402 | } |
398 | 403 | ||
404 | simple_srand(1); | ||
399 | set_random_data(iobuf, mtd->erasesize); | 405 | set_random_data(iobuf, mtd->erasesize); |
400 | 406 | ||
401 | err = scan_for_bad_eraseblocks(); | 407 | err = scan_for_bad_eraseblocks(); |
@@ -407,7 +413,7 @@ static int __init mtd_speedtest_init(void) | |||
407 | goto out; | 413 | goto out; |
408 | 414 | ||
409 | /* Write all eraseblocks, 1 eraseblock at a time */ | 415 | /* Write all eraseblocks, 1 eraseblock at a time */ |
410 | pr_info("testing eraseblock write speed\n"); | 416 | printk(PRINT_PREF "testing eraseblock write speed\n"); |
411 | start_timing(); | 417 | start_timing(); |
412 | for (i = 0; i < ebcnt; ++i) { | 418 | for (i = 0; i < ebcnt; ++i) { |
413 | if (bbt[i]) | 419 | if (bbt[i]) |
@@ -419,10 +425,10 @@ static int __init mtd_speedtest_init(void) | |||
419 | } | 425 | } |
420 | stop_timing(); | 426 | stop_timing(); |
421 | speed = calc_speed(); | 427 | speed = calc_speed(); |
422 | pr_info("eraseblock write speed is %ld KiB/s\n", speed); | 428 | printk(PRINT_PREF "eraseblock write speed is %ld KiB/s\n", speed); |
423 | 429 | ||
424 | /* Read all eraseblocks, 1 eraseblock at a time */ | 430 | /* Read all eraseblocks, 1 eraseblock at a time */ |
425 | pr_info("testing eraseblock read speed\n"); | 431 | printk(PRINT_PREF "testing eraseblock read speed\n"); |
426 | start_timing(); | 432 | start_timing(); |
427 | for (i = 0; i < ebcnt; ++i) { | 433 | for (i = 0; i < ebcnt; ++i) { |
428 | if (bbt[i]) | 434 | if (bbt[i]) |
@@ -434,14 +440,14 @@ static int __init mtd_speedtest_init(void) | |||
434 | } | 440 | } |
435 | stop_timing(); | 441 | stop_timing(); |
436 | speed = calc_speed(); | 442 | speed = calc_speed(); |
437 | pr_info("eraseblock read speed is %ld KiB/s\n", speed); | 443 | printk(PRINT_PREF "eraseblock read speed is %ld KiB/s\n", speed); |
438 | 444 | ||
439 | err = erase_whole_device(); | 445 | err = erase_whole_device(); |
440 | if (err) | 446 | if (err) |
441 | goto out; | 447 | goto out; |
442 | 448 | ||
443 | /* Write all eraseblocks, 1 page at a time */ | 449 | /* Write all eraseblocks, 1 page at a time */ |
444 | pr_info("testing page write speed\n"); | 450 | printk(PRINT_PREF "testing page write speed\n"); |
445 | start_timing(); | 451 | start_timing(); |
446 | for (i = 0; i < ebcnt; ++i) { | 452 | for (i = 0; i < ebcnt; ++i) { |
447 | if (bbt[i]) | 453 | if (bbt[i]) |
@@ -453,10 +459,10 @@ static int __init mtd_speedtest_init(void) | |||
453 | } | 459 | } |
454 | stop_timing(); | 460 | stop_timing(); |
455 | speed = calc_speed(); | 461 | speed = calc_speed(); |
456 | pr_info("page write speed is %ld KiB/s\n", speed); | 462 | printk(PRINT_PREF "page write speed is %ld KiB/s\n", speed); |
457 | 463 | ||
458 | /* Read all eraseblocks, 1 page at a time */ | 464 | /* Read all eraseblocks, 1 page at a time */ |
459 | pr_info("testing page read speed\n"); | 465 | printk(PRINT_PREF "testing page read speed\n"); |
460 | start_timing(); | 466 | start_timing(); |
461 | for (i = 0; i < ebcnt; ++i) { | 467 | for (i = 0; i < ebcnt; ++i) { |
462 | if (bbt[i]) | 468 | if (bbt[i]) |
@@ -468,14 +474,14 @@ static int __init mtd_speedtest_init(void) | |||
468 | } | 474 | } |
469 | stop_timing(); | 475 | stop_timing(); |
470 | speed = calc_speed(); | 476 | speed = calc_speed(); |
471 | pr_info("page read speed is %ld KiB/s\n", speed); | 477 | printk(PRINT_PREF "page read speed is %ld KiB/s\n", speed); |
472 | 478 | ||
473 | err = erase_whole_device(); | 479 | err = erase_whole_device(); |
474 | if (err) | 480 | if (err) |
475 | goto out; | 481 | goto out; |
476 | 482 | ||
477 | /* Write all eraseblocks, 2 pages at a time */ | 483 | /* Write all eraseblocks, 2 pages at a time */ |
478 | pr_info("testing 2 page write speed\n"); | 484 | printk(PRINT_PREF "testing 2 page write speed\n"); |
479 | start_timing(); | 485 | start_timing(); |
480 | for (i = 0; i < ebcnt; ++i) { | 486 | for (i = 0; i < ebcnt; ++i) { |
481 | if (bbt[i]) | 487 | if (bbt[i]) |
@@ -487,10 +493,10 @@ static int __init mtd_speedtest_init(void) | |||
487 | } | 493 | } |
488 | stop_timing(); | 494 | stop_timing(); |
489 | speed = calc_speed(); | 495 | speed = calc_speed(); |
490 | pr_info("2 page write speed is %ld KiB/s\n", speed); | 496 | printk(PRINT_PREF "2 page write speed is %ld KiB/s\n", speed); |
491 | 497 | ||
492 | /* Read all eraseblocks, 2 pages at a time */ | 498 | /* Read all eraseblocks, 2 pages at a time */ |
493 | pr_info("testing 2 page read speed\n"); | 499 | printk(PRINT_PREF "testing 2 page read speed\n"); |
494 | start_timing(); | 500 | start_timing(); |
495 | for (i = 0; i < ebcnt; ++i) { | 501 | for (i = 0; i < ebcnt; ++i) { |
496 | if (bbt[i]) | 502 | if (bbt[i]) |
@@ -502,10 +508,10 @@ static int __init mtd_speedtest_init(void) | |||
502 | } | 508 | } |
503 | stop_timing(); | 509 | stop_timing(); |
504 | speed = calc_speed(); | 510 | speed = calc_speed(); |
505 | pr_info("2 page read speed is %ld KiB/s\n", speed); | 511 | printk(PRINT_PREF "2 page read speed is %ld KiB/s\n", speed); |
506 | 512 | ||
507 | /* Erase all eraseblocks */ | 513 | /* Erase all eraseblocks */ |
508 | pr_info("Testing erase speed\n"); | 514 | printk(PRINT_PREF "Testing erase speed\n"); |
509 | start_timing(); | 515 | start_timing(); |
510 | for (i = 0; i < ebcnt; ++i) { | 516 | for (i = 0; i < ebcnt; ++i) { |
511 | if (bbt[i]) | 517 | if (bbt[i]) |
@@ -517,12 +523,12 @@ static int __init mtd_speedtest_init(void) | |||
517 | } | 523 | } |
518 | stop_timing(); | 524 | stop_timing(); |
519 | speed = calc_speed(); | 525 | speed = calc_speed(); |
520 | pr_info("erase speed is %ld KiB/s\n", speed); | 526 | printk(PRINT_PREF "erase speed is %ld KiB/s\n", speed); |
521 | 527 | ||
522 | /* Multi-block erase all eraseblocks */ | 528 | /* Multi-block erase all eraseblocks */ |
523 | for (k = 1; k < 7; k++) { | 529 | for (k = 1; k < 7; k++) { |
524 | blocks = 1 << k; | 530 | blocks = 1 << k; |
525 | pr_info("Testing %dx multi-block erase speed\n", | 531 | printk(PRINT_PREF "Testing %dx multi-block erase speed\n", |
526 | blocks); | 532 | blocks); |
527 | start_timing(); | 533 | start_timing(); |
528 | for (i = 0; i < ebcnt; ) { | 534 | for (i = 0; i < ebcnt; ) { |
@@ -541,16 +547,16 @@ static int __init mtd_speedtest_init(void) | |||
541 | } | 547 | } |
542 | stop_timing(); | 548 | stop_timing(); |
543 | speed = calc_speed(); | 549 | speed = calc_speed(); |
544 | pr_info("%dx multi-block erase speed is %ld KiB/s\n", | 550 | printk(PRINT_PREF "%dx multi-block erase speed is %ld KiB/s\n", |
545 | blocks, speed); | 551 | blocks, speed); |
546 | } | 552 | } |
547 | pr_info("finished\n"); | 553 | printk(PRINT_PREF "finished\n"); |
548 | out: | 554 | out: |
549 | kfree(iobuf); | 555 | kfree(iobuf); |
550 | kfree(bbt); | 556 | kfree(bbt); |
551 | put_mtd_device(mtd); | 557 | put_mtd_device(mtd); |
552 | if (err) | 558 | if (err) |
553 | pr_info("error %d occurred\n", err); | 559 | printk(PRINT_PREF "error %d occurred\n", err); |
554 | printk(KERN_INFO "=================================================\n"); | 560 | printk(KERN_INFO "=================================================\n"); |
555 | return err; | 561 | return err; |
556 | } | 562 | } |
diff --git a/drivers/mtd/tests/mtd_stresstest.c b/drivers/mtd/tests/mtd_stresstest.c index 3729f679ae5..129bad2e408 100644 --- a/drivers/mtd/tests/mtd_stresstest.c +++ b/drivers/mtd/tests/mtd_stresstest.c | |||
@@ -19,8 +19,6 @@ | |||
19 | * Author: Adrian Hunter <ext-adrian.hunter@nokia.com> | 19 | * Author: Adrian Hunter <ext-adrian.hunter@nokia.com> |
20 | */ | 20 | */ |
21 | 21 | ||
22 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
23 | |||
24 | #include <linux/init.h> | 22 | #include <linux/init.h> |
25 | #include <linux/module.h> | 23 | #include <linux/module.h> |
26 | #include <linux/moduleparam.h> | 24 | #include <linux/moduleparam.h> |
@@ -29,9 +27,10 @@ | |||
29 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
30 | #include <linux/sched.h> | 28 | #include <linux/sched.h> |
31 | #include <linux/vmalloc.h> | 29 | #include <linux/vmalloc.h> |
32 | #include <linux/random.h> | ||
33 | 30 | ||
34 | static int dev = -EINVAL; | 31 | #define PRINT_PREF KERN_INFO "mtd_stresstest: " |
32 | |||
33 | static int dev; | ||
35 | module_param(dev, int, S_IRUGO); | 34 | module_param(dev, int, S_IRUGO); |
36 | MODULE_PARM_DESC(dev, "MTD device number to use"); | 35 | MODULE_PARM_DESC(dev, "MTD device number to use"); |
37 | 36 | ||
@@ -49,13 +48,28 @@ static int pgsize; | |||
49 | static int bufsize; | 48 | static int bufsize; |
50 | static int ebcnt; | 49 | static int ebcnt; |
51 | static int pgcnt; | 50 | static int pgcnt; |
51 | static unsigned long next = 1; | ||
52 | |||
53 | static inline unsigned int simple_rand(void) | ||
54 | { | ||
55 | next = next * 1103515245 + 12345; | ||
56 | return (unsigned int)((next / 65536) % 32768); | ||
57 | } | ||
58 | |||
59 | static inline void simple_srand(unsigned long seed) | ||
60 | { | ||
61 | next = seed; | ||
62 | } | ||
52 | 63 | ||
53 | static int rand_eb(void) | 64 | static int rand_eb(void) |
54 | { | 65 | { |
55 | unsigned int eb; | 66 | int eb; |
56 | 67 | ||
57 | again: | 68 | again: |
58 | eb = random32(); | 69 | if (ebcnt < 32768) |
70 | eb = simple_rand(); | ||
71 | else | ||
72 | eb = (simple_rand() << 15) | simple_rand(); | ||
59 | /* Read or write up 2 eraseblocks at a time - hence 'ebcnt - 1' */ | 73 | /* Read or write up 2 eraseblocks at a time - hence 'ebcnt - 1' */ |
60 | eb %= (ebcnt - 1); | 74 | eb %= (ebcnt - 1); |
61 | if (bbt[eb]) | 75 | if (bbt[eb]) |
@@ -65,18 +79,24 @@ again: | |||
65 | 79 | ||
66 | static int rand_offs(void) | 80 | static int rand_offs(void) |
67 | { | 81 | { |
68 | unsigned int offs; | 82 | int offs; |
69 | 83 | ||
70 | offs = random32(); | 84 | if (bufsize < 32768) |
85 | offs = simple_rand(); | ||
86 | else | ||
87 | offs = (simple_rand() << 15) | simple_rand(); | ||
71 | offs %= bufsize; | 88 | offs %= bufsize; |
72 | return offs; | 89 | return offs; |
73 | } | 90 | } |
74 | 91 | ||
75 | static int rand_len(int offs) | 92 | static int rand_len(int offs) |
76 | { | 93 | { |
77 | unsigned int len; | 94 | int len; |
78 | 95 | ||
79 | len = random32(); | 96 | if (bufsize < 32768) |
97 | len = simple_rand(); | ||
98 | else | ||
99 | len = (simple_rand() << 15) | simple_rand(); | ||
80 | len %= (bufsize - offs); | 100 | len %= (bufsize - offs); |
81 | return len; | 101 | return len; |
82 | } | 102 | } |
@@ -92,14 +112,14 @@ static int erase_eraseblock(int ebnum) | |||
92 | ei.addr = addr; | 112 | ei.addr = addr; |
93 | ei.len = mtd->erasesize; | 113 | ei.len = mtd->erasesize; |
94 | 114 | ||
95 | err = mtd_erase(mtd, &ei); | 115 | err = mtd->erase(mtd, &ei); |
96 | if (unlikely(err)) { | 116 | if (unlikely(err)) { |
97 | pr_err("error %d while erasing EB %d\n", err, ebnum); | 117 | printk(PRINT_PREF "error %d while erasing EB %d\n", err, ebnum); |
98 | return err; | 118 | return err; |
99 | } | 119 | } |
100 | 120 | ||
101 | if (unlikely(ei.state == MTD_ERASE_FAILED)) { | 121 | if (unlikely(ei.state == MTD_ERASE_FAILED)) { |
102 | pr_err("some erase error occurred at EB %d\n", | 122 | printk(PRINT_PREF "some erase error occurred at EB %d\n", |
103 | ebnum); | 123 | ebnum); |
104 | return -EIO; | 124 | return -EIO; |
105 | } | 125 | } |
@@ -112,15 +132,15 @@ static int is_block_bad(int ebnum) | |||
112 | loff_t addr = ebnum * mtd->erasesize; | 132 | loff_t addr = ebnum * mtd->erasesize; |
113 | int ret; | 133 | int ret; |
114 | 134 | ||
115 | ret = mtd_block_isbad(mtd, addr); | 135 | ret = mtd->block_isbad(mtd, addr); |
116 | if (ret) | 136 | if (ret) |
117 | pr_info("block %d is bad\n", ebnum); | 137 | printk(PRINT_PREF "block %d is bad\n", ebnum); |
118 | return ret; | 138 | return ret; |
119 | } | 139 | } |
120 | 140 | ||
121 | static int do_read(void) | 141 | static int do_read(void) |
122 | { | 142 | { |
123 | size_t read; | 143 | size_t read = 0; |
124 | int eb = rand_eb(); | 144 | int eb = rand_eb(); |
125 | int offs = rand_offs(); | 145 | int offs = rand_offs(); |
126 | int len = rand_len(offs), err; | 146 | int len = rand_len(offs), err; |
@@ -133,11 +153,11 @@ static int do_read(void) | |||
133 | len = mtd->erasesize - offs; | 153 | len = mtd->erasesize - offs; |
134 | } | 154 | } |
135 | addr = eb * mtd->erasesize + offs; | 155 | addr = eb * mtd->erasesize + offs; |
136 | err = mtd_read(mtd, addr, len, &read, readbuf); | 156 | err = mtd->read(mtd, addr, len, &read, readbuf); |
137 | if (mtd_is_bitflip(err)) | 157 | if (err == -EUCLEAN) |
138 | err = 0; | 158 | err = 0; |
139 | if (unlikely(err || read != len)) { | 159 | if (unlikely(err || read != len)) { |
140 | pr_err("error: read failed at 0x%llx\n", | 160 | printk(PRINT_PREF "error: read failed at 0x%llx\n", |
141 | (long long)addr); | 161 | (long long)addr); |
142 | if (!err) | 162 | if (!err) |
143 | err = -EINVAL; | 163 | err = -EINVAL; |
@@ -149,7 +169,7 @@ static int do_read(void) | |||
149 | static int do_write(void) | 169 | static int do_write(void) |
150 | { | 170 | { |
151 | int eb = rand_eb(), offs, err, len; | 171 | int eb = rand_eb(), offs, err, len; |
152 | size_t written; | 172 | size_t written = 0; |
153 | loff_t addr; | 173 | loff_t addr; |
154 | 174 | ||
155 | offs = offsets[eb]; | 175 | offs = offsets[eb]; |
@@ -172,9 +192,9 @@ static int do_write(void) | |||
172 | } | 192 | } |
173 | } | 193 | } |
174 | addr = eb * mtd->erasesize + offs; | 194 | addr = eb * mtd->erasesize + offs; |
175 | err = mtd_write(mtd, addr, len, &written, writebuf); | 195 | err = mtd->write(mtd, addr, len, &written, writebuf); |
176 | if (unlikely(err || written != len)) { | 196 | if (unlikely(err || written != len)) { |
177 | pr_err("error: write failed at 0x%llx\n", | 197 | printk(PRINT_PREF "error: write failed at 0x%llx\n", |
178 | (long long)addr); | 198 | (long long)addr); |
179 | if (!err) | 199 | if (!err) |
180 | err = -EINVAL; | 200 | err = -EINVAL; |
@@ -191,7 +211,7 @@ static int do_write(void) | |||
191 | 211 | ||
192 | static int do_operation(void) | 212 | static int do_operation(void) |
193 | { | 213 | { |
194 | if (random32() & 1) | 214 | if (simple_rand() & 1) |
195 | return do_read(); | 215 | return do_read(); |
196 | else | 216 | else |
197 | return do_write(); | 217 | return do_write(); |
@@ -203,21 +223,22 @@ static int scan_for_bad_eraseblocks(void) | |||
203 | 223 | ||
204 | bbt = kzalloc(ebcnt, GFP_KERNEL); | 224 | bbt = kzalloc(ebcnt, GFP_KERNEL); |
205 | if (!bbt) { | 225 | if (!bbt) { |
206 | pr_err("error: cannot allocate memory\n"); | 226 | printk(PRINT_PREF "error: cannot allocate memory\n"); |
207 | return -ENOMEM; | 227 | return -ENOMEM; |
208 | } | 228 | } |
209 | 229 | ||
210 | if (!mtd_can_have_bb(mtd)) | 230 | /* NOR flash does not implement block_isbad */ |
231 | if (mtd->block_isbad == NULL) | ||
211 | return 0; | 232 | return 0; |
212 | 233 | ||
213 | pr_info("scanning for bad eraseblocks\n"); | 234 | printk(PRINT_PREF "scanning for bad eraseblocks\n"); |
214 | for (i = 0; i < ebcnt; ++i) { | 235 | for (i = 0; i < ebcnt; ++i) { |
215 | bbt[i] = is_block_bad(i) ? 1 : 0; | 236 | bbt[i] = is_block_bad(i) ? 1 : 0; |
216 | if (bbt[i]) | 237 | if (bbt[i]) |
217 | bad += 1; | 238 | bad += 1; |
218 | cond_resched(); | 239 | cond_resched(); |
219 | } | 240 | } |
220 | pr_info("scanned %d eraseblocks, %d are bad\n", i, bad); | 241 | printk(PRINT_PREF "scanned %d eraseblocks, %d are bad\n", i, bad); |
221 | return 0; | 242 | return 0; |
222 | } | 243 | } |
223 | 244 | ||
@@ -229,24 +250,17 @@ static int __init mtd_stresstest_init(void) | |||
229 | 250 | ||
230 | printk(KERN_INFO "\n"); | 251 | printk(KERN_INFO "\n"); |
231 | printk(KERN_INFO "=================================================\n"); | 252 | printk(KERN_INFO "=================================================\n"); |
232 | 253 | printk(PRINT_PREF "MTD device: %d\n", dev); | |
233 | if (dev < 0) { | ||
234 | pr_info("Please specify a valid mtd-device via module parameter\n"); | ||
235 | pr_crit("CAREFUL: This test wipes all data on the specified MTD device!\n"); | ||
236 | return -EINVAL; | ||
237 | } | ||
238 | |||
239 | pr_info("MTD device: %d\n", dev); | ||
240 | 254 | ||
241 | mtd = get_mtd_device(NULL, dev); | 255 | mtd = get_mtd_device(NULL, dev); |
242 | if (IS_ERR(mtd)) { | 256 | if (IS_ERR(mtd)) { |
243 | err = PTR_ERR(mtd); | 257 | err = PTR_ERR(mtd); |
244 | pr_err("error: cannot get MTD device\n"); | 258 | printk(PRINT_PREF "error: cannot get MTD device\n"); |
245 | return err; | 259 | return err; |
246 | } | 260 | } |
247 | 261 | ||
248 | if (mtd->writesize == 1) { | 262 | if (mtd->writesize == 1) { |
249 | pr_info("not NAND flash, assume page size is 512 " | 263 | printk(PRINT_PREF "not NAND flash, assume page size is 512 " |
250 | "bytes.\n"); | 264 | "bytes.\n"); |
251 | pgsize = 512; | 265 | pgsize = 512; |
252 | } else | 266 | } else |
@@ -257,14 +271,14 @@ static int __init mtd_stresstest_init(void) | |||
257 | ebcnt = tmp; | 271 | ebcnt = tmp; |
258 | pgcnt = mtd->erasesize / pgsize; | 272 | pgcnt = mtd->erasesize / pgsize; |
259 | 273 | ||
260 | pr_info("MTD device size %llu, eraseblock size %u, " | 274 | printk(PRINT_PREF "MTD device size %llu, eraseblock size %u, " |
261 | "page size %u, count of eraseblocks %u, pages per " | 275 | "page size %u, count of eraseblocks %u, pages per " |
262 | "eraseblock %u, OOB size %u\n", | 276 | "eraseblock %u, OOB size %u\n", |
263 | (unsigned long long)mtd->size, mtd->erasesize, | 277 | (unsigned long long)mtd->size, mtd->erasesize, |
264 | pgsize, ebcnt, pgcnt, mtd->oobsize); | 278 | pgsize, ebcnt, pgcnt, mtd->oobsize); |
265 | 279 | ||
266 | if (ebcnt < 2) { | 280 | if (ebcnt < 2) { |
267 | pr_err("error: need at least 2 eraseblocks\n"); | 281 | printk(PRINT_PREF "error: need at least 2 eraseblocks\n"); |
268 | err = -ENOSPC; | 282 | err = -ENOSPC; |
269 | goto out_put_mtd; | 283 | goto out_put_mtd; |
270 | } | 284 | } |
@@ -277,29 +291,30 @@ static int __init mtd_stresstest_init(void) | |||
277 | writebuf = vmalloc(bufsize); | 291 | writebuf = vmalloc(bufsize); |
278 | offsets = kmalloc(ebcnt * sizeof(int), GFP_KERNEL); | 292 | offsets = kmalloc(ebcnt * sizeof(int), GFP_KERNEL); |
279 | if (!readbuf || !writebuf || !offsets) { | 293 | if (!readbuf || !writebuf || !offsets) { |
280 | pr_err("error: cannot allocate memory\n"); | 294 | printk(PRINT_PREF "error: cannot allocate memory\n"); |
281 | goto out; | 295 | goto out; |
282 | } | 296 | } |
283 | for (i = 0; i < ebcnt; i++) | 297 | for (i = 0; i < ebcnt; i++) |
284 | offsets[i] = mtd->erasesize; | 298 | offsets[i] = mtd->erasesize; |
299 | simple_srand(current->pid); | ||
285 | for (i = 0; i < bufsize; i++) | 300 | for (i = 0; i < bufsize; i++) |
286 | writebuf[i] = random32(); | 301 | writebuf[i] = simple_rand(); |
287 | 302 | ||
288 | err = scan_for_bad_eraseblocks(); | 303 | err = scan_for_bad_eraseblocks(); |
289 | if (err) | 304 | if (err) |
290 | goto out; | 305 | goto out; |
291 | 306 | ||
292 | /* Do operations */ | 307 | /* Do operations */ |
293 | pr_info("doing operations\n"); | 308 | printk(PRINT_PREF "doing operations\n"); |
294 | for (op = 0; op < count; op++) { | 309 | for (op = 0; op < count; op++) { |
295 | if ((op & 1023) == 0) | 310 | if ((op & 1023) == 0) |
296 | pr_info("%d operations done\n", op); | 311 | printk(PRINT_PREF "%d operations done\n", op); |
297 | err = do_operation(); | 312 | err = do_operation(); |
298 | if (err) | 313 | if (err) |
299 | goto out; | 314 | goto out; |
300 | cond_resched(); | 315 | cond_resched(); |
301 | } | 316 | } |
302 | pr_info("finished, %d operations done\n", op); | 317 | printk(PRINT_PREF "finished, %d operations done\n", op); |
303 | 318 | ||
304 | out: | 319 | out: |
305 | kfree(offsets); | 320 | kfree(offsets); |
@@ -309,7 +324,7 @@ out: | |||
309 | out_put_mtd: | 324 | out_put_mtd: |
310 | put_mtd_device(mtd); | 325 | put_mtd_device(mtd); |
311 | if (err) | 326 | if (err) |
312 | pr_info("error %d occurred\n", err); | 327 | printk(PRINT_PREF "error %d occurred\n", err); |
313 | printk(KERN_INFO "=================================================\n"); | 328 | printk(KERN_INFO "=================================================\n"); |
314 | return err; | 329 | return err; |
315 | } | 330 | } |
diff --git a/drivers/mtd/tests/mtd_subpagetest.c b/drivers/mtd/tests/mtd_subpagetest.c index c880c2229c5..334eae53a3d 100644 --- a/drivers/mtd/tests/mtd_subpagetest.c +++ b/drivers/mtd/tests/mtd_subpagetest.c | |||
@@ -19,8 +19,6 @@ | |||
19 | * | 19 | * |
20 | */ | 20 | */ |
21 | 21 | ||
22 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
23 | |||
24 | #include <linux/init.h> | 22 | #include <linux/init.h> |
25 | #include <linux/module.h> | 23 | #include <linux/module.h> |
26 | #include <linux/moduleparam.h> | 24 | #include <linux/moduleparam.h> |
@@ -29,7 +27,9 @@ | |||
29 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
30 | #include <linux/sched.h> | 28 | #include <linux/sched.h> |
31 | 29 | ||
32 | static int dev = -EINVAL; | 30 | #define PRINT_PREF KERN_INFO "mtd_subpagetest: " |
31 | |||
32 | static int dev; | ||
33 | module_param(dev, int, S_IRUGO); | 33 | module_param(dev, int, S_IRUGO); |
34 | MODULE_PARM_DESC(dev, "MTD device number to use"); | 34 | MODULE_PARM_DESC(dev, "MTD device number to use"); |
35 | 35 | ||
@@ -80,14 +80,14 @@ static int erase_eraseblock(int ebnum) | |||
80 | ei.addr = addr; | 80 | ei.addr = addr; |
81 | ei.len = mtd->erasesize; | 81 | ei.len = mtd->erasesize; |
82 | 82 | ||
83 | err = mtd_erase(mtd, &ei); | 83 | err = mtd->erase(mtd, &ei); |
84 | if (err) { | 84 | if (err) { |
85 | pr_err("error %d while erasing EB %d\n", err, ebnum); | 85 | printk(PRINT_PREF "error %d while erasing EB %d\n", err, ebnum); |
86 | return err; | 86 | return err; |
87 | } | 87 | } |
88 | 88 | ||
89 | if (ei.state == MTD_ERASE_FAILED) { | 89 | if (ei.state == MTD_ERASE_FAILED) { |
90 | pr_err("some erase error occurred at EB %d\n", | 90 | printk(PRINT_PREF "some erase error occurred at EB %d\n", |
91 | ebnum); | 91 | ebnum); |
92 | return -EIO; | 92 | return -EIO; |
93 | } | 93 | } |
@@ -100,7 +100,7 @@ static int erase_whole_device(void) | |||
100 | int err; | 100 | int err; |
101 | unsigned int i; | 101 | unsigned int i; |
102 | 102 | ||
103 | pr_info("erasing whole device\n"); | 103 | printk(PRINT_PREF "erasing whole device\n"); |
104 | for (i = 0; i < ebcnt; ++i) { | 104 | for (i = 0; i < ebcnt; ++i) { |
105 | if (bbt[i]) | 105 | if (bbt[i]) |
106 | continue; | 106 | continue; |
@@ -109,24 +109,24 @@ static int erase_whole_device(void) | |||
109 | return err; | 109 | return err; |
110 | cond_resched(); | 110 | cond_resched(); |
111 | } | 111 | } |
112 | pr_info("erased %u eraseblocks\n", i); | 112 | printk(PRINT_PREF "erased %u eraseblocks\n", i); |
113 | return 0; | 113 | return 0; |
114 | } | 114 | } |
115 | 115 | ||
116 | static int write_eraseblock(int ebnum) | 116 | static int write_eraseblock(int ebnum) |
117 | { | 117 | { |
118 | size_t written; | 118 | size_t written = 0; |
119 | int err = 0; | 119 | int err = 0; |
120 | loff_t addr = ebnum * mtd->erasesize; | 120 | loff_t addr = ebnum * mtd->erasesize; |
121 | 121 | ||
122 | set_random_data(writebuf, subpgsize); | 122 | set_random_data(writebuf, subpgsize); |
123 | err = mtd_write(mtd, addr, subpgsize, &written, writebuf); | 123 | err = mtd->write(mtd, addr, subpgsize, &written, writebuf); |
124 | if (unlikely(err || written != subpgsize)) { | 124 | if (unlikely(err || written != subpgsize)) { |
125 | pr_err("error: write failed at %#llx\n", | 125 | printk(PRINT_PREF "error: write failed at %#llx\n", |
126 | (long long)addr); | 126 | (long long)addr); |
127 | if (written != subpgsize) { | 127 | if (written != subpgsize) { |
128 | pr_err(" write size: %#x\n", subpgsize); | 128 | printk(PRINT_PREF " write size: %#x\n", subpgsize); |
129 | pr_err(" written: %#zx\n", written); | 129 | printk(PRINT_PREF " written: %#zx\n", written); |
130 | } | 130 | } |
131 | return err ? err : -1; | 131 | return err ? err : -1; |
132 | } | 132 | } |
@@ -134,13 +134,13 @@ static int write_eraseblock(int ebnum) | |||
134 | addr += subpgsize; | 134 | addr += subpgsize; |
135 | 135 | ||
136 | set_random_data(writebuf, subpgsize); | 136 | set_random_data(writebuf, subpgsize); |
137 | err = mtd_write(mtd, addr, subpgsize, &written, writebuf); | 137 | err = mtd->write(mtd, addr, subpgsize, &written, writebuf); |
138 | if (unlikely(err || written != subpgsize)) { | 138 | if (unlikely(err || written != subpgsize)) { |
139 | pr_err("error: write failed at %#llx\n", | 139 | printk(PRINT_PREF "error: write failed at %#llx\n", |
140 | (long long)addr); | 140 | (long long)addr); |
141 | if (written != subpgsize) { | 141 | if (written != subpgsize) { |
142 | pr_err(" write size: %#x\n", subpgsize); | 142 | printk(PRINT_PREF " write size: %#x\n", subpgsize); |
143 | pr_err(" written: %#zx\n", written); | 143 | printk(PRINT_PREF " written: %#zx\n", written); |
144 | } | 144 | } |
145 | return err ? err : -1; | 145 | return err ? err : -1; |
146 | } | 146 | } |
@@ -150,7 +150,7 @@ static int write_eraseblock(int ebnum) | |||
150 | 150 | ||
151 | static int write_eraseblock2(int ebnum) | 151 | static int write_eraseblock2(int ebnum) |
152 | { | 152 | { |
153 | size_t written; | 153 | size_t written = 0; |
154 | int err = 0, k; | 154 | int err = 0, k; |
155 | loff_t addr = ebnum * mtd->erasesize; | 155 | loff_t addr = ebnum * mtd->erasesize; |
156 | 156 | ||
@@ -158,14 +158,14 @@ static int write_eraseblock2(int ebnum) | |||
158 | if (addr + (subpgsize * k) > (ebnum + 1) * mtd->erasesize) | 158 | if (addr + (subpgsize * k) > (ebnum + 1) * mtd->erasesize) |
159 | break; | 159 | break; |
160 | set_random_data(writebuf, subpgsize * k); | 160 | set_random_data(writebuf, subpgsize * k); |
161 | err = mtd_write(mtd, addr, subpgsize * k, &written, writebuf); | 161 | err = mtd->write(mtd, addr, subpgsize * k, &written, writebuf); |
162 | if (unlikely(err || written != subpgsize * k)) { | 162 | if (unlikely(err || written != subpgsize * k)) { |
163 | pr_err("error: write failed at %#llx\n", | 163 | printk(PRINT_PREF "error: write failed at %#llx\n", |
164 | (long long)addr); | 164 | (long long)addr); |
165 | if (written != subpgsize) { | 165 | if (written != subpgsize) { |
166 | pr_err(" write size: %#x\n", | 166 | printk(PRINT_PREF " write size: %#x\n", |
167 | subpgsize * k); | 167 | subpgsize * k); |
168 | pr_err(" written: %#08zx\n", | 168 | printk(PRINT_PREF " written: %#08zx\n", |
169 | written); | 169 | written); |
170 | } | 170 | } |
171 | return err ? err : -1; | 171 | return err ? err : -1; |
@@ -189,32 +189,33 @@ static void print_subpage(unsigned char *p) | |||
189 | 189 | ||
190 | static int verify_eraseblock(int ebnum) | 190 | static int verify_eraseblock(int ebnum) |
191 | { | 191 | { |
192 | size_t read; | 192 | size_t read = 0; |
193 | int err = 0; | 193 | int err = 0; |
194 | loff_t addr = ebnum * mtd->erasesize; | 194 | loff_t addr = ebnum * mtd->erasesize; |
195 | 195 | ||
196 | set_random_data(writebuf, subpgsize); | 196 | set_random_data(writebuf, subpgsize); |
197 | clear_data(readbuf, subpgsize); | 197 | clear_data(readbuf, subpgsize); |
198 | err = mtd_read(mtd, addr, subpgsize, &read, readbuf); | 198 | read = 0; |
199 | err = mtd->read(mtd, addr, subpgsize, &read, readbuf); | ||
199 | if (unlikely(err || read != subpgsize)) { | 200 | if (unlikely(err || read != subpgsize)) { |
200 | if (mtd_is_bitflip(err) && read == subpgsize) { | 201 | if (err == -EUCLEAN && read == subpgsize) { |
201 | pr_info("ECC correction at %#llx\n", | 202 | printk(PRINT_PREF "ECC correction at %#llx\n", |
202 | (long long)addr); | 203 | (long long)addr); |
203 | err = 0; | 204 | err = 0; |
204 | } else { | 205 | } else { |
205 | pr_err("error: read failed at %#llx\n", | 206 | printk(PRINT_PREF "error: read failed at %#llx\n", |
206 | (long long)addr); | 207 | (long long)addr); |
207 | return err ? err : -1; | 208 | return err ? err : -1; |
208 | } | 209 | } |
209 | } | 210 | } |
210 | if (unlikely(memcmp(readbuf, writebuf, subpgsize))) { | 211 | if (unlikely(memcmp(readbuf, writebuf, subpgsize))) { |
211 | pr_err("error: verify failed at %#llx\n", | 212 | printk(PRINT_PREF "error: verify failed at %#llx\n", |
212 | (long long)addr); | 213 | (long long)addr); |
213 | pr_info("------------- written----------------\n"); | 214 | printk(PRINT_PREF "------------- written----------------\n"); |
214 | print_subpage(writebuf); | 215 | print_subpage(writebuf); |
215 | pr_info("------------- read ------------------\n"); | 216 | printk(PRINT_PREF "------------- read ------------------\n"); |
216 | print_subpage(readbuf); | 217 | print_subpage(readbuf); |
217 | pr_info("-------------------------------------\n"); | 218 | printk(PRINT_PREF "-------------------------------------\n"); |
218 | errcnt += 1; | 219 | errcnt += 1; |
219 | } | 220 | } |
220 | 221 | ||
@@ -222,26 +223,27 @@ static int verify_eraseblock(int ebnum) | |||
222 | 223 | ||
223 | set_random_data(writebuf, subpgsize); | 224 | set_random_data(writebuf, subpgsize); |
224 | clear_data(readbuf, subpgsize); | 225 | clear_data(readbuf, subpgsize); |
225 | err = mtd_read(mtd, addr, subpgsize, &read, readbuf); | 226 | read = 0; |
227 | err = mtd->read(mtd, addr, subpgsize, &read, readbuf); | ||
226 | if (unlikely(err || read != subpgsize)) { | 228 | if (unlikely(err || read != subpgsize)) { |
227 | if (mtd_is_bitflip(err) && read == subpgsize) { | 229 | if (err == -EUCLEAN && read == subpgsize) { |
228 | pr_info("ECC correction at %#llx\n", | 230 | printk(PRINT_PREF "ECC correction at %#llx\n", |
229 | (long long)addr); | 231 | (long long)addr); |
230 | err = 0; | 232 | err = 0; |
231 | } else { | 233 | } else { |
232 | pr_err("error: read failed at %#llx\n", | 234 | printk(PRINT_PREF "error: read failed at %#llx\n", |
233 | (long long)addr); | 235 | (long long)addr); |
234 | return err ? err : -1; | 236 | return err ? err : -1; |
235 | } | 237 | } |
236 | } | 238 | } |
237 | if (unlikely(memcmp(readbuf, writebuf, subpgsize))) { | 239 | if (unlikely(memcmp(readbuf, writebuf, subpgsize))) { |
238 | pr_info("error: verify failed at %#llx\n", | 240 | printk(PRINT_PREF "error: verify failed at %#llx\n", |
239 | (long long)addr); | 241 | (long long)addr); |
240 | pr_info("------------- written----------------\n"); | 242 | printk(PRINT_PREF "------------- written----------------\n"); |
241 | print_subpage(writebuf); | 243 | print_subpage(writebuf); |
242 | pr_info("------------- read ------------------\n"); | 244 | printk(PRINT_PREF "------------- read ------------------\n"); |
243 | print_subpage(readbuf); | 245 | print_subpage(readbuf); |
244 | pr_info("-------------------------------------\n"); | 246 | printk(PRINT_PREF "-------------------------------------\n"); |
245 | errcnt += 1; | 247 | errcnt += 1; |
246 | } | 248 | } |
247 | 249 | ||
@@ -250,7 +252,7 @@ static int verify_eraseblock(int ebnum) | |||
250 | 252 | ||
251 | static int verify_eraseblock2(int ebnum) | 253 | static int verify_eraseblock2(int ebnum) |
252 | { | 254 | { |
253 | size_t read; | 255 | size_t read = 0; |
254 | int err = 0, k; | 256 | int err = 0, k; |
255 | loff_t addr = ebnum * mtd->erasesize; | 257 | loff_t addr = ebnum * mtd->erasesize; |
256 | 258 | ||
@@ -259,20 +261,21 @@ static int verify_eraseblock2(int ebnum) | |||
259 | break; | 261 | break; |
260 | set_random_data(writebuf, subpgsize * k); | 262 | set_random_data(writebuf, subpgsize * k); |
261 | clear_data(readbuf, subpgsize * k); | 263 | clear_data(readbuf, subpgsize * k); |
262 | err = mtd_read(mtd, addr, subpgsize * k, &read, readbuf); | 264 | read = 0; |
265 | err = mtd->read(mtd, addr, subpgsize * k, &read, readbuf); | ||
263 | if (unlikely(err || read != subpgsize * k)) { | 266 | if (unlikely(err || read != subpgsize * k)) { |
264 | if (mtd_is_bitflip(err) && read == subpgsize * k) { | 267 | if (err == -EUCLEAN && read == subpgsize * k) { |
265 | pr_info("ECC correction at %#llx\n", | 268 | printk(PRINT_PREF "ECC correction at %#llx\n", |
266 | (long long)addr); | 269 | (long long)addr); |
267 | err = 0; | 270 | err = 0; |
268 | } else { | 271 | } else { |
269 | pr_err("error: read failed at " | 272 | printk(PRINT_PREF "error: read failed at " |
270 | "%#llx\n", (long long)addr); | 273 | "%#llx\n", (long long)addr); |
271 | return err ? err : -1; | 274 | return err ? err : -1; |
272 | } | 275 | } |
273 | } | 276 | } |
274 | if (unlikely(memcmp(readbuf, writebuf, subpgsize * k))) { | 277 | if (unlikely(memcmp(readbuf, writebuf, subpgsize * k))) { |
275 | pr_err("error: verify failed at %#llx\n", | 278 | printk(PRINT_PREF "error: verify failed at %#llx\n", |
276 | (long long)addr); | 279 | (long long)addr); |
277 | errcnt += 1; | 280 | errcnt += 1; |
278 | } | 281 | } |
@@ -285,27 +288,28 @@ static int verify_eraseblock2(int ebnum) | |||
285 | static int verify_eraseblock_ff(int ebnum) | 288 | static int verify_eraseblock_ff(int ebnum) |
286 | { | 289 | { |
287 | uint32_t j; | 290 | uint32_t j; |
288 | size_t read; | 291 | size_t read = 0; |
289 | int err = 0; | 292 | int err = 0; |
290 | loff_t addr = ebnum * mtd->erasesize; | 293 | loff_t addr = ebnum * mtd->erasesize; |
291 | 294 | ||
292 | memset(writebuf, 0xff, subpgsize); | 295 | memset(writebuf, 0xff, subpgsize); |
293 | for (j = 0; j < mtd->erasesize / subpgsize; ++j) { | 296 | for (j = 0; j < mtd->erasesize / subpgsize; ++j) { |
294 | clear_data(readbuf, subpgsize); | 297 | clear_data(readbuf, subpgsize); |
295 | err = mtd_read(mtd, addr, subpgsize, &read, readbuf); | 298 | read = 0; |
299 | err = mtd->read(mtd, addr, subpgsize, &read, readbuf); | ||
296 | if (unlikely(err || read != subpgsize)) { | 300 | if (unlikely(err || read != subpgsize)) { |
297 | if (mtd_is_bitflip(err) && read == subpgsize) { | 301 | if (err == -EUCLEAN && read == subpgsize) { |
298 | pr_info("ECC correction at %#llx\n", | 302 | printk(PRINT_PREF "ECC correction at %#llx\n", |
299 | (long long)addr); | 303 | (long long)addr); |
300 | err = 0; | 304 | err = 0; |
301 | } else { | 305 | } else { |
302 | pr_err("error: read failed at " | 306 | printk(PRINT_PREF "error: read failed at " |
303 | "%#llx\n", (long long)addr); | 307 | "%#llx\n", (long long)addr); |
304 | return err ? err : -1; | 308 | return err ? err : -1; |
305 | } | 309 | } |
306 | } | 310 | } |
307 | if (unlikely(memcmp(readbuf, writebuf, subpgsize))) { | 311 | if (unlikely(memcmp(readbuf, writebuf, subpgsize))) { |
308 | pr_err("error: verify 0xff failed at " | 312 | printk(PRINT_PREF "error: verify 0xff failed at " |
309 | "%#llx\n", (long long)addr); | 313 | "%#llx\n", (long long)addr); |
310 | errcnt += 1; | 314 | errcnt += 1; |
311 | } | 315 | } |
@@ -320,7 +324,7 @@ static int verify_all_eraseblocks_ff(void) | |||
320 | int err; | 324 | int err; |
321 | unsigned int i; | 325 | unsigned int i; |
322 | 326 | ||
323 | pr_info("verifying all eraseblocks for 0xff\n"); | 327 | printk(PRINT_PREF "verifying all eraseblocks for 0xff\n"); |
324 | for (i = 0; i < ebcnt; ++i) { | 328 | for (i = 0; i < ebcnt; ++i) { |
325 | if (bbt[i]) | 329 | if (bbt[i]) |
326 | continue; | 330 | continue; |
@@ -328,10 +332,10 @@ static int verify_all_eraseblocks_ff(void) | |||
328 | if (err) | 332 | if (err) |
329 | return err; | 333 | return err; |
330 | if (i % 256 == 0) | 334 | if (i % 256 == 0) |
331 | pr_info("verified up to eraseblock %u\n", i); | 335 | printk(PRINT_PREF "verified up to eraseblock %u\n", i); |
332 | cond_resched(); | 336 | cond_resched(); |
333 | } | 337 | } |
334 | pr_info("verified %u eraseblocks\n", i); | 338 | printk(PRINT_PREF "verified %u eraseblocks\n", i); |
335 | return 0; | 339 | return 0; |
336 | } | 340 | } |
337 | 341 | ||
@@ -340,9 +344,9 @@ static int is_block_bad(int ebnum) | |||
340 | loff_t addr = ebnum * mtd->erasesize; | 344 | loff_t addr = ebnum * mtd->erasesize; |
341 | int ret; | 345 | int ret; |
342 | 346 | ||
343 | ret = mtd_block_isbad(mtd, addr); | 347 | ret = mtd->block_isbad(mtd, addr); |
344 | if (ret) | 348 | if (ret) |
345 | pr_info("block %d is bad\n", ebnum); | 349 | printk(PRINT_PREF "block %d is bad\n", ebnum); |
346 | return ret; | 350 | return ret; |
347 | } | 351 | } |
348 | 352 | ||
@@ -352,18 +356,18 @@ static int scan_for_bad_eraseblocks(void) | |||
352 | 356 | ||
353 | bbt = kzalloc(ebcnt, GFP_KERNEL); | 357 | bbt = kzalloc(ebcnt, GFP_KERNEL); |
354 | if (!bbt) { | 358 | if (!bbt) { |
355 | pr_err("error: cannot allocate memory\n"); | 359 | printk(PRINT_PREF "error: cannot allocate memory\n"); |
356 | return -ENOMEM; | 360 | return -ENOMEM; |
357 | } | 361 | } |
358 | 362 | ||
359 | pr_info("scanning for bad eraseblocks\n"); | 363 | printk(PRINT_PREF "scanning for bad eraseblocks\n"); |
360 | for (i = 0; i < ebcnt; ++i) { | 364 | for (i = 0; i < ebcnt; ++i) { |
361 | bbt[i] = is_block_bad(i) ? 1 : 0; | 365 | bbt[i] = is_block_bad(i) ? 1 : 0; |
362 | if (bbt[i]) | 366 | if (bbt[i]) |
363 | bad += 1; | 367 | bad += 1; |
364 | cond_resched(); | 368 | cond_resched(); |
365 | } | 369 | } |
366 | pr_info("scanned %d eraseblocks, %d are bad\n", i, bad); | 370 | printk(PRINT_PREF "scanned %d eraseblocks, %d are bad\n", i, bad); |
367 | return 0; | 371 | return 0; |
368 | } | 372 | } |
369 | 373 | ||
@@ -375,24 +379,17 @@ static int __init mtd_subpagetest_init(void) | |||
375 | 379 | ||
376 | printk(KERN_INFO "\n"); | 380 | printk(KERN_INFO "\n"); |
377 | printk(KERN_INFO "=================================================\n"); | 381 | printk(KERN_INFO "=================================================\n"); |
378 | 382 | printk(PRINT_PREF "MTD device: %d\n", dev); | |
379 | if (dev < 0) { | ||
380 | pr_info("Please specify a valid mtd-device via module parameter\n"); | ||
381 | pr_crit("CAREFUL: This test wipes all data on the specified MTD device!\n"); | ||
382 | return -EINVAL; | ||
383 | } | ||
384 | |||
385 | pr_info("MTD device: %d\n", dev); | ||
386 | 383 | ||
387 | mtd = get_mtd_device(NULL, dev); | 384 | mtd = get_mtd_device(NULL, dev); |
388 | if (IS_ERR(mtd)) { | 385 | if (IS_ERR(mtd)) { |
389 | err = PTR_ERR(mtd); | 386 | err = PTR_ERR(mtd); |
390 | pr_err("error: cannot get MTD device\n"); | 387 | printk(PRINT_PREF "error: cannot get MTD device\n"); |
391 | return err; | 388 | return err; |
392 | } | 389 | } |
393 | 390 | ||
394 | if (mtd->type != MTD_NANDFLASH) { | 391 | if (mtd->type != MTD_NANDFLASH) { |
395 | pr_info("this test requires NAND flash\n"); | 392 | printk(PRINT_PREF "this test requires NAND flash\n"); |
396 | goto out; | 393 | goto out; |
397 | } | 394 | } |
398 | 395 | ||
@@ -402,7 +399,7 @@ static int __init mtd_subpagetest_init(void) | |||
402 | ebcnt = tmp; | 399 | ebcnt = tmp; |
403 | pgcnt = mtd->erasesize / mtd->writesize; | 400 | pgcnt = mtd->erasesize / mtd->writesize; |
404 | 401 | ||
405 | pr_info("MTD device size %llu, eraseblock size %u, " | 402 | printk(PRINT_PREF "MTD device size %llu, eraseblock size %u, " |
406 | "page size %u, subpage size %u, count of eraseblocks %u, " | 403 | "page size %u, subpage size %u, count of eraseblocks %u, " |
407 | "pages per eraseblock %u, OOB size %u\n", | 404 | "pages per eraseblock %u, OOB size %u\n", |
408 | (unsigned long long)mtd->size, mtd->erasesize, | 405 | (unsigned long long)mtd->size, mtd->erasesize, |
@@ -412,12 +409,12 @@ static int __init mtd_subpagetest_init(void) | |||
412 | bufsize = subpgsize * 32; | 409 | bufsize = subpgsize * 32; |
413 | writebuf = kmalloc(bufsize, GFP_KERNEL); | 410 | writebuf = kmalloc(bufsize, GFP_KERNEL); |
414 | if (!writebuf) { | 411 | if (!writebuf) { |
415 | pr_info("error: cannot allocate memory\n"); | 412 | printk(PRINT_PREF "error: cannot allocate memory\n"); |
416 | goto out; | 413 | goto out; |
417 | } | 414 | } |
418 | readbuf = kmalloc(bufsize, GFP_KERNEL); | 415 | readbuf = kmalloc(bufsize, GFP_KERNEL); |
419 | if (!readbuf) { | 416 | if (!readbuf) { |
420 | pr_info("error: cannot allocate memory\n"); | 417 | printk(PRINT_PREF "error: cannot allocate memory\n"); |
421 | goto out; | 418 | goto out; |
422 | } | 419 | } |
423 | 420 | ||
@@ -429,7 +426,7 @@ static int __init mtd_subpagetest_init(void) | |||
429 | if (err) | 426 | if (err) |
430 | goto out; | 427 | goto out; |
431 | 428 | ||
432 | pr_info("writing whole device\n"); | 429 | printk(PRINT_PREF "writing whole device\n"); |
433 | simple_srand(1); | 430 | simple_srand(1); |
434 | for (i = 0; i < ebcnt; ++i) { | 431 | for (i = 0; i < ebcnt; ++i) { |
435 | if (bbt[i]) | 432 | if (bbt[i]) |
@@ -438,13 +435,13 @@ static int __init mtd_subpagetest_init(void) | |||
438 | if (unlikely(err)) | 435 | if (unlikely(err)) |
439 | goto out; | 436 | goto out; |
440 | if (i % 256 == 0) | 437 | if (i % 256 == 0) |
441 | pr_info("written up to eraseblock %u\n", i); | 438 | printk(PRINT_PREF "written up to eraseblock %u\n", i); |
442 | cond_resched(); | 439 | cond_resched(); |
443 | } | 440 | } |
444 | pr_info("written %u eraseblocks\n", i); | 441 | printk(PRINT_PREF "written %u eraseblocks\n", i); |
445 | 442 | ||
446 | simple_srand(1); | 443 | simple_srand(1); |
447 | pr_info("verifying all eraseblocks\n"); | 444 | printk(PRINT_PREF "verifying all eraseblocks\n"); |
448 | for (i = 0; i < ebcnt; ++i) { | 445 | for (i = 0; i < ebcnt; ++i) { |
449 | if (bbt[i]) | 446 | if (bbt[i]) |
450 | continue; | 447 | continue; |
@@ -452,10 +449,10 @@ static int __init mtd_subpagetest_init(void) | |||
452 | if (unlikely(err)) | 449 | if (unlikely(err)) |
453 | goto out; | 450 | goto out; |
454 | if (i % 256 == 0) | 451 | if (i % 256 == 0) |
455 | pr_info("verified up to eraseblock %u\n", i); | 452 | printk(PRINT_PREF "verified up to eraseblock %u\n", i); |
456 | cond_resched(); | 453 | cond_resched(); |
457 | } | 454 | } |
458 | pr_info("verified %u eraseblocks\n", i); | 455 | printk(PRINT_PREF "verified %u eraseblocks\n", i); |
459 | 456 | ||
460 | err = erase_whole_device(); | 457 | err = erase_whole_device(); |
461 | if (err) | 458 | if (err) |
@@ -467,7 +464,7 @@ static int __init mtd_subpagetest_init(void) | |||
467 | 464 | ||
468 | /* Write all eraseblocks */ | 465 | /* Write all eraseblocks */ |
469 | simple_srand(3); | 466 | simple_srand(3); |
470 | pr_info("writing whole device\n"); | 467 | printk(PRINT_PREF "writing whole device\n"); |
471 | for (i = 0; i < ebcnt; ++i) { | 468 | for (i = 0; i < ebcnt; ++i) { |
472 | if (bbt[i]) | 469 | if (bbt[i]) |
473 | continue; | 470 | continue; |
@@ -475,14 +472,14 @@ static int __init mtd_subpagetest_init(void) | |||
475 | if (unlikely(err)) | 472 | if (unlikely(err)) |
476 | goto out; | 473 | goto out; |
477 | if (i % 256 == 0) | 474 | if (i % 256 == 0) |
478 | pr_info("written up to eraseblock %u\n", i); | 475 | printk(PRINT_PREF "written up to eraseblock %u\n", i); |
479 | cond_resched(); | 476 | cond_resched(); |
480 | } | 477 | } |
481 | pr_info("written %u eraseblocks\n", i); | 478 | printk(PRINT_PREF "written %u eraseblocks\n", i); |
482 | 479 | ||
483 | /* Check all eraseblocks */ | 480 | /* Check all eraseblocks */ |
484 | simple_srand(3); | 481 | simple_srand(3); |
485 | pr_info("verifying all eraseblocks\n"); | 482 | printk(PRINT_PREF "verifying all eraseblocks\n"); |
486 | for (i = 0; i < ebcnt; ++i) { | 483 | for (i = 0; i < ebcnt; ++i) { |
487 | if (bbt[i]) | 484 | if (bbt[i]) |
488 | continue; | 485 | continue; |
@@ -490,10 +487,10 @@ static int __init mtd_subpagetest_init(void) | |||
490 | if (unlikely(err)) | 487 | if (unlikely(err)) |
491 | goto out; | 488 | goto out; |
492 | if (i % 256 == 0) | 489 | if (i % 256 == 0) |
493 | pr_info("verified up to eraseblock %u\n", i); | 490 | printk(PRINT_PREF "verified up to eraseblock %u\n", i); |
494 | cond_resched(); | 491 | cond_resched(); |
495 | } | 492 | } |
496 | pr_info("verified %u eraseblocks\n", i); | 493 | printk(PRINT_PREF "verified %u eraseblocks\n", i); |
497 | 494 | ||
498 | err = erase_whole_device(); | 495 | err = erase_whole_device(); |
499 | if (err) | 496 | if (err) |
@@ -503,7 +500,7 @@ static int __init mtd_subpagetest_init(void) | |||
503 | if (err) | 500 | if (err) |
504 | goto out; | 501 | goto out; |
505 | 502 | ||
506 | pr_info("finished with %d errors\n", errcnt); | 503 | printk(PRINT_PREF "finished with %d errors\n", errcnt); |
507 | 504 | ||
508 | out: | 505 | out: |
509 | kfree(bbt); | 506 | kfree(bbt); |
@@ -511,7 +508,7 @@ out: | |||
511 | kfree(writebuf); | 508 | kfree(writebuf); |
512 | put_mtd_device(mtd); | 509 | put_mtd_device(mtd); |
513 | if (err) | 510 | if (err) |
514 | pr_info("error %d occurred\n", err); | 511 | printk(PRINT_PREF "error %d occurred\n", err); |
515 | printk(KERN_INFO "=================================================\n"); | 512 | printk(KERN_INFO "=================================================\n"); |
516 | return err; | 513 | return err; |
517 | } | 514 | } |
diff --git a/drivers/mtd/tests/mtd_torturetest.c b/drivers/mtd/tests/mtd_torturetest.c index c4cde1e9edd..5c6c3d24890 100644 --- a/drivers/mtd/tests/mtd_torturetest.c +++ b/drivers/mtd/tests/mtd_torturetest.c | |||
@@ -23,8 +23,6 @@ | |||
23 | * damage caused by this program. | 23 | * damage caused by this program. |
24 | */ | 24 | */ |
25 | 25 | ||
26 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
27 | |||
28 | #include <linux/init.h> | 26 | #include <linux/init.h> |
29 | #include <linux/module.h> | 27 | #include <linux/module.h> |
30 | #include <linux/moduleparam.h> | 28 | #include <linux/moduleparam.h> |
@@ -33,6 +31,7 @@ | |||
33 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
34 | #include <linux/sched.h> | 32 | #include <linux/sched.h> |
35 | 33 | ||
34 | #define PRINT_PREF KERN_INFO "mtd_torturetest: " | ||
36 | #define RETRIES 3 | 35 | #define RETRIES 3 |
37 | 36 | ||
38 | static int eb = 8; | 37 | static int eb = 8; |
@@ -47,7 +46,7 @@ static int pgcnt; | |||
47 | module_param(pgcnt, int, S_IRUGO); | 46 | module_param(pgcnt, int, S_IRUGO); |
48 | MODULE_PARM_DESC(pgcnt, "number of pages per eraseblock to torture (0 => all)"); | 47 | MODULE_PARM_DESC(pgcnt, "number of pages per eraseblock to torture (0 => all)"); |
49 | 48 | ||
50 | static int dev = -EINVAL; | 49 | static int dev; |
51 | module_param(dev, int, S_IRUGO); | 50 | module_param(dev, int, S_IRUGO); |
52 | MODULE_PARM_DESC(dev, "MTD device number to use"); | 51 | MODULE_PARM_DESC(dev, "MTD device number to use"); |
53 | 52 | ||
@@ -106,14 +105,14 @@ static inline int erase_eraseblock(int ebnum) | |||
106 | ei.addr = addr; | 105 | ei.addr = addr; |
107 | ei.len = mtd->erasesize; | 106 | ei.len = mtd->erasesize; |
108 | 107 | ||
109 | err = mtd_erase(mtd, &ei); | 108 | err = mtd->erase(mtd, &ei); |
110 | if (err) { | 109 | if (err) { |
111 | pr_err("error %d while erasing EB %d\n", err, ebnum); | 110 | printk(PRINT_PREF "error %d while erasing EB %d\n", err, ebnum); |
112 | return err; | 111 | return err; |
113 | } | 112 | } |
114 | 113 | ||
115 | if (ei.state == MTD_ERASE_FAILED) { | 114 | if (ei.state == MTD_ERASE_FAILED) { |
116 | pr_err("some erase error occurred at EB %d\n", | 115 | printk(PRINT_PREF "some erase error occurred at EB %d\n", |
117 | ebnum); | 116 | ebnum); |
118 | return -EIO; | 117 | return -EIO; |
119 | } | 118 | } |
@@ -128,7 +127,7 @@ static inline int erase_eraseblock(int ebnum) | |||
128 | static inline int check_eraseblock(int ebnum, unsigned char *buf) | 127 | static inline int check_eraseblock(int ebnum, unsigned char *buf) |
129 | { | 128 | { |
130 | int err, retries = 0; | 129 | int err, retries = 0; |
131 | size_t read; | 130 | size_t read = 0; |
132 | loff_t addr = ebnum * mtd->erasesize; | 131 | loff_t addr = ebnum * mtd->erasesize; |
133 | size_t len = mtd->erasesize; | 132 | size_t len = mtd->erasesize; |
134 | 133 | ||
@@ -138,42 +137,42 @@ static inline int check_eraseblock(int ebnum, unsigned char *buf) | |||
138 | } | 137 | } |
139 | 138 | ||
140 | retry: | 139 | retry: |
141 | err = mtd_read(mtd, addr, len, &read, check_buf); | 140 | err = mtd->read(mtd, addr, len, &read, check_buf); |
142 | if (mtd_is_bitflip(err)) | 141 | if (err == -EUCLEAN) |
143 | pr_err("single bit flip occurred at EB %d " | 142 | printk(PRINT_PREF "single bit flip occurred at EB %d " |
144 | "MTD reported that it was fixed.\n", ebnum); | 143 | "MTD reported that it was fixed.\n", ebnum); |
145 | else if (err) { | 144 | else if (err) { |
146 | pr_err("error %d while reading EB %d, " | 145 | printk(PRINT_PREF "error %d while reading EB %d, " |
147 | "read %zd\n", err, ebnum, read); | 146 | "read %zd\n", err, ebnum, read); |
148 | return err; | 147 | return err; |
149 | } | 148 | } |
150 | 149 | ||
151 | if (read != len) { | 150 | if (read != len) { |
152 | pr_err("failed to read %zd bytes from EB %d, " | 151 | printk(PRINT_PREF "failed to read %zd bytes from EB %d, " |
153 | "read only %zd, but no error reported\n", | 152 | "read only %zd, but no error reported\n", |
154 | len, ebnum, read); | 153 | len, ebnum, read); |
155 | return -EIO; | 154 | return -EIO; |
156 | } | 155 | } |
157 | 156 | ||
158 | if (memcmp(buf, check_buf, len)) { | 157 | if (memcmp(buf, check_buf, len)) { |
159 | pr_err("read wrong data from EB %d\n", ebnum); | 158 | printk(PRINT_PREF "read wrong data from EB %d\n", ebnum); |
160 | report_corrupt(check_buf, buf); | 159 | report_corrupt(check_buf, buf); |
161 | 160 | ||
162 | if (retries++ < RETRIES) { | 161 | if (retries++ < RETRIES) { |
163 | /* Try read again */ | 162 | /* Try read again */ |
164 | yield(); | 163 | yield(); |
165 | pr_info("re-try reading data from EB %d\n", | 164 | printk(PRINT_PREF "re-try reading data from EB %d\n", |
166 | ebnum); | 165 | ebnum); |
167 | goto retry; | 166 | goto retry; |
168 | } else { | 167 | } else { |
169 | pr_info("retried %d times, still errors, " | 168 | printk(PRINT_PREF "retried %d times, still errors, " |
170 | "give-up\n", RETRIES); | 169 | "give-up\n", RETRIES); |
171 | return -EINVAL; | 170 | return -EINVAL; |
172 | } | 171 | } |
173 | } | 172 | } |
174 | 173 | ||
175 | if (retries != 0) | 174 | if (retries != 0) |
176 | pr_info("only attempt number %d was OK (!!!)\n", | 175 | printk(PRINT_PREF "only attempt number %d was OK (!!!)\n", |
177 | retries); | 176 | retries); |
178 | 177 | ||
179 | return 0; | 178 | return 0; |
@@ -182,7 +181,7 @@ retry: | |||
182 | static inline int write_pattern(int ebnum, void *buf) | 181 | static inline int write_pattern(int ebnum, void *buf) |
183 | { | 182 | { |
184 | int err; | 183 | int err; |
185 | size_t written; | 184 | size_t written = 0; |
186 | loff_t addr = ebnum * mtd->erasesize; | 185 | loff_t addr = ebnum * mtd->erasesize; |
187 | size_t len = mtd->erasesize; | 186 | size_t len = mtd->erasesize; |
188 | 187 | ||
@@ -190,14 +189,14 @@ static inline int write_pattern(int ebnum, void *buf) | |||
190 | addr = (ebnum + 1) * mtd->erasesize - pgcnt * pgsize; | 189 | addr = (ebnum + 1) * mtd->erasesize - pgcnt * pgsize; |
191 | len = pgcnt * pgsize; | 190 | len = pgcnt * pgsize; |
192 | } | 191 | } |
193 | err = mtd_write(mtd, addr, len, &written, buf); | 192 | err = mtd->write(mtd, addr, len, &written, buf); |
194 | if (err) { | 193 | if (err) { |
195 | pr_err("error %d while writing EB %d, written %zd" | 194 | printk(PRINT_PREF "error %d while writing EB %d, written %zd" |
196 | " bytes\n", err, ebnum, written); | 195 | " bytes\n", err, ebnum, written); |
197 | return err; | 196 | return err; |
198 | } | 197 | } |
199 | if (written != len) { | 198 | if (written != len) { |
200 | pr_info("written only %zd bytes of %zd, but no error" | 199 | printk(PRINT_PREF "written only %zd bytes of %zd, but no error" |
201 | " reported\n", written, len); | 200 | " reported\n", written, len); |
202 | return -EIO; | 201 | return -EIO; |
203 | } | 202 | } |
@@ -212,64 +211,57 @@ static int __init tort_init(void) | |||
212 | 211 | ||
213 | printk(KERN_INFO "\n"); | 212 | printk(KERN_INFO "\n"); |
214 | printk(KERN_INFO "=================================================\n"); | 213 | printk(KERN_INFO "=================================================\n"); |
215 | pr_info("Warning: this program is trying to wear out your " | 214 | printk(PRINT_PREF "Warning: this program is trying to wear out your " |
216 | "flash, stop it if this is not wanted.\n"); | 215 | "flash, stop it if this is not wanted.\n"); |
217 | 216 | printk(PRINT_PREF "MTD device: %d\n", dev); | |
218 | if (dev < 0) { | 217 | printk(PRINT_PREF "torture %d eraseblocks (%d-%d) of mtd%d\n", |
219 | pr_info("Please specify a valid mtd-device via module parameter\n"); | ||
220 | pr_crit("CAREFUL: This test wipes all data on the specified MTD device!\n"); | ||
221 | return -EINVAL; | ||
222 | } | ||
223 | |||
224 | pr_info("MTD device: %d\n", dev); | ||
225 | pr_info("torture %d eraseblocks (%d-%d) of mtd%d\n", | ||
226 | ebcnt, eb, eb + ebcnt - 1, dev); | 218 | ebcnt, eb, eb + ebcnt - 1, dev); |
227 | if (pgcnt) | 219 | if (pgcnt) |
228 | pr_info("torturing just %d pages per eraseblock\n", | 220 | printk(PRINT_PREF "torturing just %d pages per eraseblock\n", |
229 | pgcnt); | 221 | pgcnt); |
230 | pr_info("write verify %s\n", check ? "enabled" : "disabled"); | 222 | printk(PRINT_PREF "write verify %s\n", check ? "enabled" : "disabled"); |
231 | 223 | ||
232 | mtd = get_mtd_device(NULL, dev); | 224 | mtd = get_mtd_device(NULL, dev); |
233 | if (IS_ERR(mtd)) { | 225 | if (IS_ERR(mtd)) { |
234 | err = PTR_ERR(mtd); | 226 | err = PTR_ERR(mtd); |
235 | pr_err("error: cannot get MTD device\n"); | 227 | printk(PRINT_PREF "error: cannot get MTD device\n"); |
236 | return err; | 228 | return err; |
237 | } | 229 | } |
238 | 230 | ||
239 | if (mtd->writesize == 1) { | 231 | if (mtd->writesize == 1) { |
240 | pr_info("not NAND flash, assume page size is 512 " | 232 | printk(PRINT_PREF "not NAND flash, assume page size is 512 " |
241 | "bytes.\n"); | 233 | "bytes.\n"); |
242 | pgsize = 512; | 234 | pgsize = 512; |
243 | } else | 235 | } else |
244 | pgsize = mtd->writesize; | 236 | pgsize = mtd->writesize; |
245 | 237 | ||
246 | if (pgcnt && (pgcnt > mtd->erasesize / pgsize || pgcnt < 0)) { | 238 | if (pgcnt && (pgcnt > mtd->erasesize / pgsize || pgcnt < 0)) { |
247 | pr_err("error: invalid pgcnt value %d\n", pgcnt); | 239 | printk(PRINT_PREF "error: invalid pgcnt value %d\n", pgcnt); |
248 | goto out_mtd; | 240 | goto out_mtd; |
249 | } | 241 | } |
250 | 242 | ||
251 | err = -ENOMEM; | 243 | err = -ENOMEM; |
252 | patt_5A5 = kmalloc(mtd->erasesize, GFP_KERNEL); | 244 | patt_5A5 = kmalloc(mtd->erasesize, GFP_KERNEL); |
253 | if (!patt_5A5) { | 245 | if (!patt_5A5) { |
254 | pr_err("error: cannot allocate memory\n"); | 246 | printk(PRINT_PREF "error: cannot allocate memory\n"); |
255 | goto out_mtd; | 247 | goto out_mtd; |
256 | } | 248 | } |
257 | 249 | ||
258 | patt_A5A = kmalloc(mtd->erasesize, GFP_KERNEL); | 250 | patt_A5A = kmalloc(mtd->erasesize, GFP_KERNEL); |
259 | if (!patt_A5A) { | 251 | if (!patt_A5A) { |
260 | pr_err("error: cannot allocate memory\n"); | 252 | printk(PRINT_PREF "error: cannot allocate memory\n"); |
261 | goto out_patt_5A5; | 253 | goto out_patt_5A5; |
262 | } | 254 | } |
263 | 255 | ||
264 | patt_FF = kmalloc(mtd->erasesize, GFP_KERNEL); | 256 | patt_FF = kmalloc(mtd->erasesize, GFP_KERNEL); |
265 | if (!patt_FF) { | 257 | if (!patt_FF) { |
266 | pr_err("error: cannot allocate memory\n"); | 258 | printk(PRINT_PREF "error: cannot allocate memory\n"); |
267 | goto out_patt_A5A; | 259 | goto out_patt_A5A; |
268 | } | 260 | } |
269 | 261 | ||
270 | check_buf = kmalloc(mtd->erasesize, GFP_KERNEL); | 262 | check_buf = kmalloc(mtd->erasesize, GFP_KERNEL); |
271 | if (!check_buf) { | 263 | if (!check_buf) { |
272 | pr_err("error: cannot allocate memory\n"); | 264 | printk(PRINT_PREF "error: cannot allocate memory\n"); |
273 | goto out_patt_FF; | 265 | goto out_patt_FF; |
274 | } | 266 | } |
275 | 267 | ||
@@ -291,18 +283,19 @@ static int __init tort_init(void) | |||
291 | * Check if there is a bad eraseblock among those we are going to test. | 283 | * Check if there is a bad eraseblock among those we are going to test. |
292 | */ | 284 | */ |
293 | memset(&bad_ebs[0], 0, sizeof(int) * ebcnt); | 285 | memset(&bad_ebs[0], 0, sizeof(int) * ebcnt); |
294 | if (mtd_can_have_bb(mtd)) { | 286 | if (mtd->block_isbad) { |
295 | for (i = eb; i < eb + ebcnt; i++) { | 287 | for (i = eb; i < eb + ebcnt; i++) { |
296 | err = mtd_block_isbad(mtd, (loff_t)i * mtd->erasesize); | 288 | err = mtd->block_isbad(mtd, |
289 | (loff_t)i * mtd->erasesize); | ||
297 | 290 | ||
298 | if (err < 0) { | 291 | if (err < 0) { |
299 | pr_info("block_isbad() returned %d " | 292 | printk(PRINT_PREF "block_isbad() returned %d " |
300 | "for EB %d\n", err, i); | 293 | "for EB %d\n", err, i); |
301 | goto out; | 294 | goto out; |
302 | } | 295 | } |
303 | 296 | ||
304 | if (err) { | 297 | if (err) { |
305 | pr_err("EB %d is bad. Skip it.\n", i); | 298 | printk("EB %d is bad. Skip it.\n", i); |
306 | bad_ebs[i - eb] = 1; | 299 | bad_ebs[i - eb] = 1; |
307 | } | 300 | } |
308 | } | 301 | } |
@@ -330,7 +323,7 @@ static int __init tort_init(void) | |||
330 | continue; | 323 | continue; |
331 | err = check_eraseblock(i, patt_FF); | 324 | err = check_eraseblock(i, patt_FF); |
332 | if (err) { | 325 | if (err) { |
333 | pr_info("verify failed" | 326 | printk(PRINT_PREF "verify failed" |
334 | " for 0xFF... pattern\n"); | 327 | " for 0xFF... pattern\n"); |
335 | goto out; | 328 | goto out; |
336 | } | 329 | } |
@@ -363,7 +356,7 @@ static int __init tort_init(void) | |||
363 | patt = patt_A5A; | 356 | patt = patt_A5A; |
364 | err = check_eraseblock(i, patt); | 357 | err = check_eraseblock(i, patt); |
365 | if (err) { | 358 | if (err) { |
366 | pr_info("verify failed for %s" | 359 | printk(PRINT_PREF "verify failed for %s" |
367 | " pattern\n", | 360 | " pattern\n", |
368 | ((eb + erase_cycles) & 1) ? | 361 | ((eb + erase_cycles) & 1) ? |
369 | "0x55AA55..." : "0xAA55AA..."); | 362 | "0x55AA55..." : "0xAA55AA..."); |
@@ -381,7 +374,7 @@ static int __init tort_init(void) | |||
381 | stop_timing(); | 374 | stop_timing(); |
382 | ms = (finish.tv_sec - start.tv_sec) * 1000 + | 375 | ms = (finish.tv_sec - start.tv_sec) * 1000 + |
383 | (finish.tv_usec - start.tv_usec) / 1000; | 376 | (finish.tv_usec - start.tv_usec) / 1000; |
384 | pr_info("%08u erase cycles done, took %lu " | 377 | printk(PRINT_PREF "%08u erase cycles done, took %lu " |
385 | "milliseconds (%lu seconds)\n", | 378 | "milliseconds (%lu seconds)\n", |
386 | erase_cycles, ms, ms / 1000); | 379 | erase_cycles, ms, ms / 1000); |
387 | start_timing(); | 380 | start_timing(); |
@@ -392,7 +385,7 @@ static int __init tort_init(void) | |||
392 | } | 385 | } |
393 | out: | 386 | out: |
394 | 387 | ||
395 | pr_info("finished after %u erase cycles\n", | 388 | printk(PRINT_PREF "finished after %u erase cycles\n", |
396 | erase_cycles); | 389 | erase_cycles); |
397 | kfree(check_buf); | 390 | kfree(check_buf); |
398 | out_patt_FF: | 391 | out_patt_FF: |
@@ -404,7 +397,7 @@ out_patt_5A5: | |||
404 | out_mtd: | 397 | out_mtd: |
405 | put_mtd_device(mtd); | 398 | put_mtd_device(mtd); |
406 | if (err) | 399 | if (err) |
407 | pr_info("error %d occurred during torturing\n", err); | 400 | printk(PRINT_PREF "error %d occurred during torturing\n", err); |
408 | printk(KERN_INFO "=================================================\n"); | 401 | printk(KERN_INFO "=================================================\n"); |
409 | return err; | 402 | return err; |
410 | } | 403 | } |
@@ -442,9 +435,9 @@ static void report_corrupt(unsigned char *read, unsigned char *written) | |||
442 | &bits) >= 0) | 435 | &bits) >= 0) |
443 | pages++; | 436 | pages++; |
444 | 437 | ||
445 | pr_info("verify fails on %d pages, %d bytes/%d bits\n", | 438 | printk(PRINT_PREF "verify fails on %d pages, %d bytes/%d bits\n", |
446 | pages, bytes, bits); | 439 | pages, bytes, bits); |
447 | pr_info("The following is a list of all differences between" | 440 | printk(PRINT_PREF "The following is a list of all differences between" |
448 | " what was read from flash and what was expected\n"); | 441 | " what was read from flash and what was expected\n"); |
449 | 442 | ||
450 | for (i = 0; i < check_len; i += pgsize) { | 443 | for (i = 0; i < check_len; i += pgsize) { |
@@ -458,7 +451,7 @@ static void report_corrupt(unsigned char *read, unsigned char *written) | |||
458 | printk("-------------------------------------------------------" | 451 | printk("-------------------------------------------------------" |
459 | "----------------------------------\n"); | 452 | "----------------------------------\n"); |
460 | 453 | ||
461 | pr_info("Page %zd has %d bytes/%d bits failing verify," | 454 | printk(PRINT_PREF "Page %zd has %d bytes/%d bits failing verify," |
462 | " starting at offset 0x%x\n", | 455 | " starting at offset 0x%x\n", |
463 | (mtd->erasesize - check_len + i) / pgsize, | 456 | (mtd->erasesize - check_len + i) / pgsize, |
464 | bytes, bits, first); | 457 | bytes, bits, first); |