diff options
| -rw-r--r-- | drivers/mtd/nand/nandsim.c | 43 |
1 files changed, 42 insertions, 1 deletions
diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c index a5aa99f014b..213181be0d9 100644 --- a/drivers/mtd/nand/nandsim.c +++ b/drivers/mtd/nand/nandsim.c | |||
| @@ -34,6 +34,7 @@ | |||
| 34 | #include <linux/string.h> | 34 | #include <linux/string.h> |
| 35 | #include <linux/mtd/mtd.h> | 35 | #include <linux/mtd/mtd.h> |
| 36 | #include <linux/mtd/nand.h> | 36 | #include <linux/mtd/nand.h> |
| 37 | #include <linux/mtd/nand_bch.h> | ||
| 37 | #include <linux/mtd/partitions.h> | 38 | #include <linux/mtd/partitions.h> |
| 38 | #include <linux/delay.h> | 39 | #include <linux/delay.h> |
| 39 | #include <linux/list.h> | 40 | #include <linux/list.h> |
| @@ -108,6 +109,7 @@ static unsigned int rptwear = 0; | |||
| 108 | static unsigned int overridesize = 0; | 109 | static unsigned int overridesize = 0; |
| 109 | static char *cache_file = NULL; | 110 | static char *cache_file = NULL; |
| 110 | static unsigned int bbt; | 111 | static unsigned int bbt; |
| 112 | static unsigned int bch; | ||
| 111 | 113 | ||
| 112 | module_param(first_id_byte, uint, 0400); | 114 | module_param(first_id_byte, uint, 0400); |
| 113 | module_param(second_id_byte, uint, 0400); | 115 | module_param(second_id_byte, uint, 0400); |
| @@ -132,6 +134,7 @@ module_param(rptwear, uint, 0400); | |||
| 132 | module_param(overridesize, uint, 0400); | 134 | module_param(overridesize, uint, 0400); |
| 133 | module_param(cache_file, charp, 0400); | 135 | module_param(cache_file, charp, 0400); |
| 134 | module_param(bbt, uint, 0400); | 136 | module_param(bbt, uint, 0400); |
| 137 | module_param(bch, uint, 0400); | ||
| 135 | 138 | ||
| 136 | MODULE_PARM_DESC(first_id_byte, "The first byte returned by NAND Flash 'read ID' command (manufacturer ID)"); | 139 | MODULE_PARM_DESC(first_id_byte, "The first byte returned by NAND Flash 'read ID' command (manufacturer ID)"); |
| 137 | MODULE_PARM_DESC(second_id_byte, "The second byte returned by NAND Flash 'read ID' command (chip ID)"); | 140 | MODULE_PARM_DESC(second_id_byte, "The second byte returned by NAND Flash 'read ID' command (chip ID)"); |
| @@ -165,6 +168,8 @@ MODULE_PARM_DESC(overridesize, "Specifies the NAND Flash size overriding the I | |||
| 165 | " e.g. 5 means a size of 32 erase blocks"); | 168 | " e.g. 5 means a size of 32 erase blocks"); |
| 166 | MODULE_PARM_DESC(cache_file, "File to use to cache nand pages instead of memory"); | 169 | MODULE_PARM_DESC(cache_file, "File to use to cache nand pages instead of memory"); |
| 167 | MODULE_PARM_DESC(bbt, "0 OOB, 1 BBT with marker in OOB, 2 BBT with marker in data area"); | 170 | MODULE_PARM_DESC(bbt, "0 OOB, 1 BBT with marker in OOB, 2 BBT with marker in data area"); |
| 171 | MODULE_PARM_DESC(bch, "Enable BCH ecc and set how many bits should " | ||
| 172 | "be correctable in 512-byte blocks"); | ||
| 168 | 173 | ||
| 169 | /* The largest possible page size */ | 174 | /* The largest possible page size */ |
| 170 | #define NS_LARGEST_PAGE_SIZE 4096 | 175 | #define NS_LARGEST_PAGE_SIZE 4096 |
| @@ -2309,7 +2314,43 @@ static int __init ns_init_module(void) | |||
| 2309 | if ((retval = parse_gravepages()) != 0) | 2314 | if ((retval = parse_gravepages()) != 0) |
| 2310 | goto error; | 2315 | goto error; |
| 2311 | 2316 | ||
| 2312 | if ((retval = nand_scan(nsmtd, 1)) != 0) { | 2317 | retval = nand_scan_ident(nsmtd, 1, NULL); |
| 2318 | if (retval) { | ||
| 2319 | NS_ERR("cannot scan NAND Simulator device\n"); | ||
| 2320 | if (retval > 0) | ||
| 2321 | retval = -ENXIO; | ||
| 2322 | goto error; | ||
| 2323 | } | ||
| 2324 | |||
| 2325 | if (bch) { | ||
| 2326 | unsigned int eccsteps, eccbytes; | ||
| 2327 | if (!mtd_nand_has_bch()) { | ||
| 2328 | NS_ERR("BCH ECC support is disabled\n"); | ||
| 2329 | retval = -EINVAL; | ||
| 2330 | goto error; | ||
| 2331 | } | ||
| 2332 | /* use 512-byte ecc blocks */ | ||
| 2333 | eccsteps = nsmtd->writesize/512; | ||
| 2334 | eccbytes = (bch*13+7)/8; | ||
| 2335 | /* do not bother supporting small page devices */ | ||
| 2336 | if ((nsmtd->oobsize < 64) || !eccsteps) { | ||
| 2337 | NS_ERR("bch not available on small page devices\n"); | ||
| 2338 | retval = -EINVAL; | ||
| 2339 | goto error; | ||
| 2340 | } | ||
| 2341 | if ((eccbytes*eccsteps+2) > nsmtd->oobsize) { | ||
| 2342 | NS_ERR("invalid bch value %u\n", bch); | ||
| 2343 | retval = -EINVAL; | ||
| 2344 | goto error; | ||
| 2345 | } | ||
| 2346 | chip->ecc.mode = NAND_ECC_SOFT_BCH; | ||
| 2347 | chip->ecc.size = 512; | ||
| 2348 | chip->ecc.bytes = eccbytes; | ||
| 2349 | NS_INFO("using %u-bit/%u bytes BCH ECC\n", bch, chip->ecc.size); | ||
| 2350 | } | ||
| 2351 | |||
| 2352 | retval = nand_scan_tail(nsmtd); | ||
| 2353 | if (retval) { | ||
| 2313 | NS_ERR("can't register NAND Simulator\n"); | 2354 | NS_ERR("can't register NAND Simulator\n"); |
| 2314 | if (retval > 0) | 2355 | if (retval > 0) |
| 2315 | retval = -ENXIO; | 2356 | retval = -ENXIO; |
