14cd10358SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2a995c792SAkinobu Mita /*
3a995c792SAkinobu Mita * Copyright © 2012 NetCommWireless
4a995c792SAkinobu Mita * Iwo Mergler <Iwo.Mergler@netcommwireless.com.au>
5a995c792SAkinobu Mita *
6a995c792SAkinobu Mita * Test for multi-bit error recovery on a NAND page This mostly tests the
7a995c792SAkinobu Mita * ECC controller / driver.
8a995c792SAkinobu Mita *
9a995c792SAkinobu Mita * There are two test modes:
10a995c792SAkinobu Mita *
11a995c792SAkinobu Mita * 0 - artificially inserting bit errors until the ECC fails
12a995c792SAkinobu Mita * This is the default method and fairly quick. It should
13a995c792SAkinobu Mita * be independent of the quality of the FLASH.
14a995c792SAkinobu Mita *
15a995c792SAkinobu Mita * 1 - re-writing the same pattern repeatedly until the ECC fails.
16a995c792SAkinobu Mita * This method relies on the physics of NAND FLASH to eventually
17a995c792SAkinobu Mita * generate '0' bits if '1' has been written sufficient times.
18a995c792SAkinobu Mita * Depending on the NAND, the first bit errors will appear after
19a995c792SAkinobu Mita * 1000 or more writes and then will usually snowball, reaching the
20a995c792SAkinobu Mita * limits of the ECC quickly.
21a995c792SAkinobu Mita *
22a995c792SAkinobu Mita * The test stops after 10000 cycles, should your FLASH be
23a995c792SAkinobu Mita * exceptionally good and not generate bit errors before that. Try
24a995c792SAkinobu Mita * a different page in that case.
25a995c792SAkinobu Mita *
26a995c792SAkinobu Mita * Please note that neither of these tests will significantly 'use up' any
27a995c792SAkinobu Mita * FLASH endurance. Only a maximum of two erase operations will be performed.
28a995c792SAkinobu Mita */
29a995c792SAkinobu Mita
30a995c792SAkinobu Mita #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
31a995c792SAkinobu Mita
32a995c792SAkinobu Mita #include <linux/init.h>
33a995c792SAkinobu Mita #include <linux/module.h>
34a995c792SAkinobu Mita #include <linux/moduleparam.h>
35a995c792SAkinobu Mita #include <linux/mtd/mtd.h>
36a995c792SAkinobu Mita #include <linux/err.h>
37d4092d76SBoris Brezillon #include <linux/mtd/rawnand.h>
38a995c792SAkinobu Mita #include <linux/slab.h>
3956177516SAkinobu Mita #include "mtd_test.h"
40a995c792SAkinobu Mita
41a995c792SAkinobu Mita static int dev;
42a995c792SAkinobu Mita module_param(dev, int, S_IRUGO);
43a995c792SAkinobu Mita MODULE_PARM_DESC(dev, "MTD device number to use");
44a995c792SAkinobu Mita
45a995c792SAkinobu Mita static unsigned page_offset;
46a995c792SAkinobu Mita module_param(page_offset, uint, S_IRUGO);
47a995c792SAkinobu Mita MODULE_PARM_DESC(page_offset, "Page number relative to dev start");
48a995c792SAkinobu Mita
49a995c792SAkinobu Mita static unsigned seed;
50a995c792SAkinobu Mita module_param(seed, uint, S_IRUGO);
51a995c792SAkinobu Mita MODULE_PARM_DESC(seed, "Random seed");
52a995c792SAkinobu Mita
53a995c792SAkinobu Mita static int mode;
54a995c792SAkinobu Mita module_param(mode, int, S_IRUGO);
55a995c792SAkinobu Mita MODULE_PARM_DESC(mode, "0=incremental errors, 1=overwrite test");
56a995c792SAkinobu Mita
57a995c792SAkinobu Mita static unsigned max_overwrite = 10000;
58a995c792SAkinobu Mita
59a995c792SAkinobu Mita static loff_t offset; /* Offset of the page we're using. */
60a995c792SAkinobu Mita static unsigned eraseblock; /* Eraseblock number for our page. */
61a995c792SAkinobu Mita
62a995c792SAkinobu Mita /* We assume that the ECC can correct up to a certain number
63a995c792SAkinobu Mita * of biterrors per subpage. */
64a995c792SAkinobu Mita static unsigned subsize; /* Size of subpages */
65a995c792SAkinobu Mita static unsigned subcount; /* Number of subpages per page */
66a995c792SAkinobu Mita
67a995c792SAkinobu Mita static struct mtd_info *mtd; /* MTD device */
68a995c792SAkinobu Mita
69a995c792SAkinobu Mita static uint8_t *wbuffer; /* One page write / compare buffer */
70a995c792SAkinobu Mita static uint8_t *rbuffer; /* One page read buffer */
71a995c792SAkinobu Mita
72a995c792SAkinobu Mita /* 'random' bytes from known offsets */
hash(unsigned offset)73a995c792SAkinobu Mita static uint8_t hash(unsigned offset)
74a995c792SAkinobu Mita {
75a995c792SAkinobu Mita unsigned v = offset;
76a995c792SAkinobu Mita unsigned char c;
77a995c792SAkinobu Mita v ^= 0x7f7edfd3;
78a995c792SAkinobu Mita v = v ^ (v >> 3);
79a995c792SAkinobu Mita v = v ^ (v >> 5);
80a995c792SAkinobu Mita v = v ^ (v >> 13);
81a995c792SAkinobu Mita c = v & 0xFF;
82a995c792SAkinobu Mita /* Reverse bits of result. */
83a995c792SAkinobu Mita c = (c & 0x0F) << 4 | (c & 0xF0) >> 4;
84a995c792SAkinobu Mita c = (c & 0x33) << 2 | (c & 0xCC) >> 2;
85a995c792SAkinobu Mita c = (c & 0x55) << 1 | (c & 0xAA) >> 1;
86a995c792SAkinobu Mita return c;
87a995c792SAkinobu Mita }
88a995c792SAkinobu Mita
89a995c792SAkinobu Mita /* Writes wbuffer to page */
write_page(int log)90a995c792SAkinobu Mita static int write_page(int log)
91a995c792SAkinobu Mita {
92a995c792SAkinobu Mita if (log)
93a995c792SAkinobu Mita pr_info("write_page\n");
94a995c792SAkinobu Mita
958a9f4aa3SAkinobu Mita return mtdtest_write(mtd, offset, mtd->writesize, wbuffer);
96a995c792SAkinobu Mita }
97a995c792SAkinobu Mita
98a995c792SAkinobu Mita /* Re-writes the data area while leaving the OOB alone. */
rewrite_page(int log)99a995c792SAkinobu Mita static int rewrite_page(int log)
100a995c792SAkinobu Mita {
101a995c792SAkinobu Mita int err = 0;
102*745df179SMichał Kępień struct mtd_oob_ops ops = { };
103a995c792SAkinobu Mita
104a995c792SAkinobu Mita if (log)
105a995c792SAkinobu Mita pr_info("rewrite page\n");
106a995c792SAkinobu Mita
107a995c792SAkinobu Mita ops.mode = MTD_OPS_RAW; /* No ECC */
108a995c792SAkinobu Mita ops.len = mtd->writesize;
109a995c792SAkinobu Mita ops.retlen = 0;
110a995c792SAkinobu Mita ops.ooblen = 0;
111a995c792SAkinobu Mita ops.oobretlen = 0;
112a995c792SAkinobu Mita ops.ooboffs = 0;
113a995c792SAkinobu Mita ops.datbuf = wbuffer;
114a995c792SAkinobu Mita ops.oobbuf = NULL;
115a995c792SAkinobu Mita
116a995c792SAkinobu Mita err = mtd_write_oob(mtd, offset, &ops);
117a995c792SAkinobu Mita if (err || ops.retlen != mtd->writesize) {
118a995c792SAkinobu Mita pr_err("error: write_oob failed (%d)\n", err);
119a995c792SAkinobu Mita if (!err)
120a995c792SAkinobu Mita err = -EIO;
121a995c792SAkinobu Mita }
122a995c792SAkinobu Mita
123a995c792SAkinobu Mita return err;
124a995c792SAkinobu Mita }
125a995c792SAkinobu Mita
126a995c792SAkinobu Mita /* Reads page into rbuffer. Returns number of corrected bit errors (>=0)
127a995c792SAkinobu Mita * or error (<0) */
read_page(int log)128a995c792SAkinobu Mita static int read_page(int log)
129a995c792SAkinobu Mita {
130a995c792SAkinobu Mita int err = 0;
131a995c792SAkinobu Mita size_t read;
132a995c792SAkinobu Mita struct mtd_ecc_stats oldstats;
133a995c792SAkinobu Mita
134a995c792SAkinobu Mita if (log)
135a995c792SAkinobu Mita pr_info("read_page\n");
136a995c792SAkinobu Mita
137a995c792SAkinobu Mita /* Saving last mtd stats */
138a995c792SAkinobu Mita memcpy(&oldstats, &mtd->ecc_stats, sizeof(oldstats));
139a995c792SAkinobu Mita
140a995c792SAkinobu Mita err = mtd_read(mtd, offset, mtd->writesize, &read, rbuffer);
1416cbefbdcSSascha Hauer if (!err || err == -EUCLEAN)
142a995c792SAkinobu Mita err = mtd->ecc_stats.corrected - oldstats.corrected;
143a995c792SAkinobu Mita
144a995c792SAkinobu Mita if (err < 0 || read != mtd->writesize) {
145a995c792SAkinobu Mita pr_err("error: read failed at %#llx\n", (long long)offset);
146a995c792SAkinobu Mita if (err >= 0)
147a995c792SAkinobu Mita err = -EIO;
148a995c792SAkinobu Mita }
149a995c792SAkinobu Mita
150a995c792SAkinobu Mita return err;
151a995c792SAkinobu Mita }
152a995c792SAkinobu Mita
153a995c792SAkinobu Mita /* Verifies rbuffer against random sequence */
verify_page(int log)154a995c792SAkinobu Mita static int verify_page(int log)
155a995c792SAkinobu Mita {
156a995c792SAkinobu Mita unsigned i, errs = 0;
157a995c792SAkinobu Mita
158a995c792SAkinobu Mita if (log)
159a995c792SAkinobu Mita pr_info("verify_page\n");
160a995c792SAkinobu Mita
161a995c792SAkinobu Mita for (i = 0; i < mtd->writesize; i++) {
162a995c792SAkinobu Mita if (rbuffer[i] != hash(i+seed)) {
163a995c792SAkinobu Mita pr_err("Error: page offset %u, expected %02x, got %02x\n",
164a995c792SAkinobu Mita i, hash(i+seed), rbuffer[i]);
165a995c792SAkinobu Mita errs++;
166a995c792SAkinobu Mita }
167a995c792SAkinobu Mita }
168a995c792SAkinobu Mita
169a995c792SAkinobu Mita if (errs)
170a995c792SAkinobu Mita return -EIO;
171a995c792SAkinobu Mita else
172a995c792SAkinobu Mita return 0;
173a995c792SAkinobu Mita }
174a995c792SAkinobu Mita
175a995c792SAkinobu Mita #define CBIT(v, n) ((v) & (1 << (n)))
176a995c792SAkinobu Mita #define BCLR(v, n) ((v) = (v) & ~(1 << (n)))
177a995c792SAkinobu Mita
178a995c792SAkinobu Mita /* Finds the first '1' bit in wbuffer starting at offset 'byte'
179a995c792SAkinobu Mita * and sets it to '0'. */
insert_biterror(unsigned byte)180a995c792SAkinobu Mita static int insert_biterror(unsigned byte)
181a995c792SAkinobu Mita {
182a995c792SAkinobu Mita int bit;
183a995c792SAkinobu Mita
184a995c792SAkinobu Mita while (byte < mtd->writesize) {
185a995c792SAkinobu Mita for (bit = 7; bit >= 0; bit--) {
186a995c792SAkinobu Mita if (CBIT(wbuffer[byte], bit)) {
187a995c792SAkinobu Mita BCLR(wbuffer[byte], bit);
188a995c792SAkinobu Mita pr_info("Inserted biterror @ %u/%u\n", byte, bit);
189a995c792SAkinobu Mita return 0;
190a995c792SAkinobu Mita }
191a995c792SAkinobu Mita }
192a995c792SAkinobu Mita byte++;
193a995c792SAkinobu Mita }
194a995c792SAkinobu Mita pr_err("biterror: Failed to find a '1' bit\n");
195a995c792SAkinobu Mita return -EIO;
196a995c792SAkinobu Mita }
197a995c792SAkinobu Mita
198a995c792SAkinobu Mita /* Writes 'random' data to page and then introduces deliberate bit
199a995c792SAkinobu Mita * errors into the page, while verifying each step. */
incremental_errors_test(void)200a995c792SAkinobu Mita static int incremental_errors_test(void)
201a995c792SAkinobu Mita {
202a995c792SAkinobu Mita int err = 0;
203a995c792SAkinobu Mita unsigned i;
204a995c792SAkinobu Mita unsigned errs_per_subpage = 0;
205a995c792SAkinobu Mita
206a995c792SAkinobu Mita pr_info("incremental biterrors test\n");
207a995c792SAkinobu Mita
208a995c792SAkinobu Mita for (i = 0; i < mtd->writesize; i++)
209a995c792SAkinobu Mita wbuffer[i] = hash(i+seed);
210a995c792SAkinobu Mita
211a995c792SAkinobu Mita err = write_page(1);
212a995c792SAkinobu Mita if (err)
213a995c792SAkinobu Mita goto exit;
214a995c792SAkinobu Mita
215a995c792SAkinobu Mita while (1) {
216a995c792SAkinobu Mita
217a995c792SAkinobu Mita err = rewrite_page(1);
218a995c792SAkinobu Mita if (err)
219a995c792SAkinobu Mita goto exit;
220a995c792SAkinobu Mita
221a995c792SAkinobu Mita err = read_page(1);
222a995c792SAkinobu Mita if (err > 0)
223a995c792SAkinobu Mita pr_info("Read reported %d corrected bit errors\n", err);
224a995c792SAkinobu Mita if (err < 0) {
225a995c792SAkinobu Mita pr_err("After %d biterrors per subpage, read reported error %d\n",
226a995c792SAkinobu Mita errs_per_subpage, err);
227a995c792SAkinobu Mita err = 0;
228a995c792SAkinobu Mita goto exit;
229a995c792SAkinobu Mita }
230a995c792SAkinobu Mita
231a995c792SAkinobu Mita err = verify_page(1);
232a995c792SAkinobu Mita if (err) {
233a995c792SAkinobu Mita pr_err("ECC failure, read data is incorrect despite read success\n");
234a995c792SAkinobu Mita goto exit;
235a995c792SAkinobu Mita }
236a995c792SAkinobu Mita
237a995c792SAkinobu Mita pr_info("Successfully corrected %d bit errors per subpage\n",
238a995c792SAkinobu Mita errs_per_subpage);
239a995c792SAkinobu Mita
240a995c792SAkinobu Mita for (i = 0; i < subcount; i++) {
241a995c792SAkinobu Mita err = insert_biterror(i * subsize);
242a995c792SAkinobu Mita if (err < 0)
243a995c792SAkinobu Mita goto exit;
244a995c792SAkinobu Mita }
245a995c792SAkinobu Mita errs_per_subpage++;
246a995c792SAkinobu Mita }
247a995c792SAkinobu Mita
248a995c792SAkinobu Mita exit:
249a995c792SAkinobu Mita return err;
250a995c792SAkinobu Mita }
251a995c792SAkinobu Mita
252a995c792SAkinobu Mita
253a995c792SAkinobu Mita /* Writes 'random' data to page and then re-writes that same data repeatedly.
254a995c792SAkinobu Mita This eventually develops bit errors (bits written as '1' will slowly become
255a995c792SAkinobu Mita '0'), which are corrected as far as the ECC is capable of. */
overwrite_test(void)256a995c792SAkinobu Mita static int overwrite_test(void)
257a995c792SAkinobu Mita {
258a995c792SAkinobu Mita int err = 0;
259a995c792SAkinobu Mita unsigned i;
260a995c792SAkinobu Mita unsigned max_corrected = 0;
261a995c792SAkinobu Mita unsigned opno = 0;
262a995c792SAkinobu Mita /* We don't expect more than this many correctable bit errors per
263a995c792SAkinobu Mita * page. */
264a995c792SAkinobu Mita #define MAXBITS 512
265a995c792SAkinobu Mita static unsigned bitstats[MAXBITS]; /* bit error histogram. */
266a995c792SAkinobu Mita
267a995c792SAkinobu Mita memset(bitstats, 0, sizeof(bitstats));
268a995c792SAkinobu Mita
269a995c792SAkinobu Mita pr_info("overwrite biterrors test\n");
270a995c792SAkinobu Mita
271a995c792SAkinobu Mita for (i = 0; i < mtd->writesize; i++)
272a995c792SAkinobu Mita wbuffer[i] = hash(i+seed);
273a995c792SAkinobu Mita
274a995c792SAkinobu Mita err = write_page(1);
275a995c792SAkinobu Mita if (err)
276a995c792SAkinobu Mita goto exit;
277a995c792SAkinobu Mita
278a995c792SAkinobu Mita while (opno < max_overwrite) {
279a995c792SAkinobu Mita
28097b67131SIwo Mergler err = write_page(0);
281a995c792SAkinobu Mita if (err)
282a995c792SAkinobu Mita break;
283a995c792SAkinobu Mita
284a995c792SAkinobu Mita err = read_page(0);
285a995c792SAkinobu Mita if (err >= 0) {
286a995c792SAkinobu Mita if (err >= MAXBITS) {
287a995c792SAkinobu Mita pr_info("Implausible number of bit errors corrected\n");
288a995c792SAkinobu Mita err = -EIO;
289a995c792SAkinobu Mita break;
290a995c792SAkinobu Mita }
291a995c792SAkinobu Mita bitstats[err]++;
292a995c792SAkinobu Mita if (err > max_corrected) {
293a995c792SAkinobu Mita max_corrected = err;
294a995c792SAkinobu Mita pr_info("Read reported %d corrected bit errors\n",
295a995c792SAkinobu Mita err);
296a995c792SAkinobu Mita }
297a995c792SAkinobu Mita } else { /* err < 0 */
298a995c792SAkinobu Mita pr_info("Read reported error %d\n", err);
299a995c792SAkinobu Mita err = 0;
300a995c792SAkinobu Mita break;
301a995c792SAkinobu Mita }
302a995c792SAkinobu Mita
303a995c792SAkinobu Mita err = verify_page(0);
304a995c792SAkinobu Mita if (err) {
305a995c792SAkinobu Mita bitstats[max_corrected] = opno;
306a995c792SAkinobu Mita pr_info("ECC failure, read data is incorrect despite read success\n");
307a995c792SAkinobu Mita break;
308a995c792SAkinobu Mita }
309a995c792SAkinobu Mita
3102a6a28e7SRichard Weinberger err = mtdtest_relax();
3112a6a28e7SRichard Weinberger if (err)
3122a6a28e7SRichard Weinberger break;
3132a6a28e7SRichard Weinberger
314a995c792SAkinobu Mita opno++;
315a995c792SAkinobu Mita }
316a995c792SAkinobu Mita
317a995c792SAkinobu Mita /* At this point bitstats[0] contains the number of ops with no bit
318a995c792SAkinobu Mita * errors, bitstats[1] the number of ops with 1 bit error, etc. */
319a995c792SAkinobu Mita pr_info("Bit error histogram (%d operations total):\n", opno);
320a995c792SAkinobu Mita for (i = 0; i < max_corrected; i++)
321a995c792SAkinobu Mita pr_info("Page reads with %3d corrected bit errors: %d\n",
322a995c792SAkinobu Mita i, bitstats[i]);
323a995c792SAkinobu Mita
324a995c792SAkinobu Mita exit:
325a995c792SAkinobu Mita return err;
326a995c792SAkinobu Mita }
327a995c792SAkinobu Mita
mtd_nandbiterrs_init(void)328a995c792SAkinobu Mita static int __init mtd_nandbiterrs_init(void)
329a995c792SAkinobu Mita {
330a995c792SAkinobu Mita int err = 0;
331a995c792SAkinobu Mita
332a995c792SAkinobu Mita printk("\n");
333a995c792SAkinobu Mita printk(KERN_INFO "==================================================\n");
334a995c792SAkinobu Mita pr_info("MTD device: %d\n", dev);
335a995c792SAkinobu Mita
336a995c792SAkinobu Mita mtd = get_mtd_device(NULL, dev);
337a995c792SAkinobu Mita if (IS_ERR(mtd)) {
338a995c792SAkinobu Mita err = PTR_ERR(mtd);
339a995c792SAkinobu Mita pr_err("error: cannot get MTD device\n");
340a995c792SAkinobu Mita goto exit_mtddev;
341a995c792SAkinobu Mita }
342a995c792SAkinobu Mita
343818b9739SHuang Shijie if (!mtd_type_is_nand(mtd)) {
344a995c792SAkinobu Mita pr_info("this test requires NAND flash\n");
345a995c792SAkinobu Mita err = -ENODEV;
346a995c792SAkinobu Mita goto exit_nand;
347a995c792SAkinobu Mita }
348a995c792SAkinobu Mita
349a995c792SAkinobu Mita pr_info("MTD device size %llu, eraseblock=%u, page=%u, oob=%u\n",
350a995c792SAkinobu Mita (unsigned long long)mtd->size, mtd->erasesize,
351a995c792SAkinobu Mita mtd->writesize, mtd->oobsize);
352a995c792SAkinobu Mita
353a995c792SAkinobu Mita subsize = mtd->writesize >> mtd->subpage_sft;
354a995c792SAkinobu Mita subcount = mtd->writesize / subsize;
355a995c792SAkinobu Mita
356a995c792SAkinobu Mita pr_info("Device uses %d subpages of %d bytes\n", subcount, subsize);
357a995c792SAkinobu Mita
3581001ff7aSBrian Norris offset = (loff_t)page_offset * mtd->writesize;
359a995c792SAkinobu Mita eraseblock = mtd_div_by_eb(offset, mtd);
360a995c792SAkinobu Mita
361a995c792SAkinobu Mita pr_info("Using page=%u, offset=%llu, eraseblock=%u\n",
362a995c792SAkinobu Mita page_offset, offset, eraseblock);
363a995c792SAkinobu Mita
364a995c792SAkinobu Mita wbuffer = kmalloc(mtd->writesize, GFP_KERNEL);
365a995c792SAkinobu Mita if (!wbuffer) {
366a995c792SAkinobu Mita err = -ENOMEM;
367a995c792SAkinobu Mita goto exit_wbuffer;
368a995c792SAkinobu Mita }
369a995c792SAkinobu Mita
370a995c792SAkinobu Mita rbuffer = kmalloc(mtd->writesize, GFP_KERNEL);
371a995c792SAkinobu Mita if (!rbuffer) {
372a995c792SAkinobu Mita err = -ENOMEM;
373a995c792SAkinobu Mita goto exit_rbuffer;
374a995c792SAkinobu Mita }
375a995c792SAkinobu Mita
37656177516SAkinobu Mita err = mtdtest_erase_eraseblock(mtd, eraseblock);
377a995c792SAkinobu Mita if (err)
378a995c792SAkinobu Mita goto exit_error;
379a995c792SAkinobu Mita
380a995c792SAkinobu Mita if (mode == 0)
381a995c792SAkinobu Mita err = incremental_errors_test();
382a995c792SAkinobu Mita else
383a995c792SAkinobu Mita err = overwrite_test();
384a995c792SAkinobu Mita
385a995c792SAkinobu Mita if (err)
386a995c792SAkinobu Mita goto exit_error;
387a995c792SAkinobu Mita
388a995c792SAkinobu Mita /* We leave the block un-erased in case of test failure. */
38956177516SAkinobu Mita err = mtdtest_erase_eraseblock(mtd, eraseblock);
390a995c792SAkinobu Mita if (err)
391a995c792SAkinobu Mita goto exit_error;
392a995c792SAkinobu Mita
393a995c792SAkinobu Mita err = -EIO;
394a995c792SAkinobu Mita pr_info("finished successfully.\n");
395a995c792SAkinobu Mita printk(KERN_INFO "==================================================\n");
396a995c792SAkinobu Mita
397a995c792SAkinobu Mita exit_error:
398a995c792SAkinobu Mita kfree(rbuffer);
399a995c792SAkinobu Mita exit_rbuffer:
400a995c792SAkinobu Mita kfree(wbuffer);
401a995c792SAkinobu Mita exit_wbuffer:
402a995c792SAkinobu Mita /* Nothing */
403a995c792SAkinobu Mita exit_nand:
404a995c792SAkinobu Mita put_mtd_device(mtd);
405a995c792SAkinobu Mita exit_mtddev:
406a995c792SAkinobu Mita return err;
407a995c792SAkinobu Mita }
408a995c792SAkinobu Mita
mtd_nandbiterrs_exit(void)409a995c792SAkinobu Mita static void __exit mtd_nandbiterrs_exit(void)
410a995c792SAkinobu Mita {
411a995c792SAkinobu Mita return;
412a995c792SAkinobu Mita }
413a995c792SAkinobu Mita
414a995c792SAkinobu Mita module_init(mtd_nandbiterrs_init);
415a995c792SAkinobu Mita module_exit(mtd_nandbiterrs_exit);
416a995c792SAkinobu Mita
417a995c792SAkinobu Mita MODULE_DESCRIPTION("NAND bit error recovery test");
418a995c792SAkinobu Mita MODULE_AUTHOR("Iwo Mergler");
419a995c792SAkinobu Mita MODULE_LICENSE("GPL");
420