aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdrian Hunter <ext-adrian.hunter@nokia.com>2008-05-30 08:56:26 -0400
committerDavid Woodhouse <dwmw2@infradead.org>2008-06-04 12:47:52 -0400
commit6eda7a55f786b75e7d3d636a9431e6c850b20d72 (patch)
tree04d762f049315d0173230ecf89d86f912d9adce9
parent07293b20083cb66df35bf2041f0c554eaac43e8c (diff)
[MTD] [NAND] nandsim: allow for 64-bit size
Amend nandsim so that it does not assume 32-bit flash size. Signed-off-by: Adrian Hunter <ext-adrian.hunter@nokia.com> Signed-off-by: David Woodhouse <dwmw2@infradead.org>
-rw-r--r--drivers/mtd/nand/nandsim.c35
1 files changed, 21 insertions, 14 deletions
diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c
index b48051684733..68c150c8ff9d 100644
--- a/drivers/mtd/nand/nandsim.c
+++ b/drivers/mtd/nand/nandsim.c
@@ -298,11 +298,11 @@ struct nandsim {
298 298
299 /* NAND flash "geometry" */ 299 /* NAND flash "geometry" */
300 struct nandsin_geometry { 300 struct nandsin_geometry {
301 uint32_t totsz; /* total flash size, bytes */ 301 uint64_t totsz; /* total flash size, bytes */
302 uint32_t secsz; /* flash sector (erase block) size, bytes */ 302 uint32_t secsz; /* flash sector (erase block) size, bytes */
303 uint pgsz; /* NAND flash page size, bytes */ 303 uint pgsz; /* NAND flash page size, bytes */
304 uint oobsz; /* page OOB area size, bytes */ 304 uint oobsz; /* page OOB area size, bytes */
305 uint32_t totszoob; /* total flash size including OOB, bytes */ 305 uint64_t totszoob; /* total flash size including OOB, bytes */
306 uint pgszoob; /* page size including OOB , bytes*/ 306 uint pgszoob; /* page size including OOB , bytes*/
307 uint secszoob; /* sector size including OOB, bytes */ 307 uint secszoob; /* sector size including OOB, bytes */
308 uint pgnum; /* total number of pages */ 308 uint pgnum; /* total number of pages */
@@ -459,6 +459,12 @@ static char *get_partition_name(int i)
459 return kstrdup(buf, GFP_KERNEL); 459 return kstrdup(buf, GFP_KERNEL);
460} 460}
461 461
462static u_int64_t divide(u_int64_t n, u_int32_t d)
463{
464 do_div(n, d);
465 return n;
466}
467
462/* 468/*
463 * Initialize the nandsim structure. 469 * Initialize the nandsim structure.
464 * 470 *
@@ -469,8 +475,8 @@ static int init_nandsim(struct mtd_info *mtd)
469 struct nand_chip *chip = (struct nand_chip *)mtd->priv; 475 struct nand_chip *chip = (struct nand_chip *)mtd->priv;
470 struct nandsim *ns = (struct nandsim *)(chip->priv); 476 struct nandsim *ns = (struct nandsim *)(chip->priv);
471 int i, ret = 0; 477 int i, ret = 0;
472 u_int32_t remains; 478 u_int64_t remains;
473 u_int32_t next_offset; 479 u_int64_t next_offset;
474 480
475 if (NS_IS_INITIALIZED(ns)) { 481 if (NS_IS_INITIALIZED(ns)) {
476 NS_ERR("init_nandsim: nandsim is already initialized\n"); 482 NS_ERR("init_nandsim: nandsim is already initialized\n");
@@ -487,8 +493,8 @@ static int init_nandsim(struct mtd_info *mtd)
487 ns->geom.oobsz = mtd->oobsize; 493 ns->geom.oobsz = mtd->oobsize;
488 ns->geom.secsz = mtd->erasesize; 494 ns->geom.secsz = mtd->erasesize;
489 ns->geom.pgszoob = ns->geom.pgsz + ns->geom.oobsz; 495 ns->geom.pgszoob = ns->geom.pgsz + ns->geom.oobsz;
490 ns->geom.pgnum = ns->geom.totsz / ns->geom.pgsz; 496 ns->geom.pgnum = divide(ns->geom.totsz, ns->geom.pgsz);
491 ns->geom.totszoob = ns->geom.totsz + ns->geom.pgnum * ns->geom.oobsz; 497 ns->geom.totszoob = ns->geom.totsz + (uint64_t)ns->geom.pgnum * ns->geom.oobsz;
492 ns->geom.secshift = ffs(ns->geom.secsz) - 1; 498 ns->geom.secshift = ffs(ns->geom.secsz) - 1;
493 ns->geom.pgshift = chip->page_shift; 499 ns->geom.pgshift = chip->page_shift;
494 ns->geom.oobshift = ffs(ns->geom.oobsz) - 1; 500 ns->geom.oobshift = ffs(ns->geom.oobsz) - 1;
@@ -537,15 +543,16 @@ static int init_nandsim(struct mtd_info *mtd)
537 remains = ns->geom.totsz; 543 remains = ns->geom.totsz;
538 next_offset = 0; 544 next_offset = 0;
539 for (i = 0; i < parts_num; ++i) { 545 for (i = 0; i < parts_num; ++i) {
540 unsigned long part = parts[i]; 546 u_int64_t part_sz = (u_int64_t)parts[i] * ns->geom.secsz;
541 if (!part || part > remains / ns->geom.secsz) { 547
548 if (!part_sz || part_sz > remains) {
542 NS_ERR("bad partition size.\n"); 549 NS_ERR("bad partition size.\n");
543 ret = -EINVAL; 550 ret = -EINVAL;
544 goto error; 551 goto error;
545 } 552 }
546 ns->partitions[i].name = get_partition_name(i); 553 ns->partitions[i].name = get_partition_name(i);
547 ns->partitions[i].offset = next_offset; 554 ns->partitions[i].offset = next_offset;
548 ns->partitions[i].size = part * ns->geom.secsz; 555 ns->partitions[i].size = part_sz;
549 next_offset += ns->partitions[i].size; 556 next_offset += ns->partitions[i].size;
550 remains -= ns->partitions[i].size; 557 remains -= ns->partitions[i].size;
551 } 558 }
@@ -573,7 +580,7 @@ static int init_nandsim(struct mtd_info *mtd)
573 if (ns->busw == 16) 580 if (ns->busw == 16)
574 NS_WARN("16-bit flashes support wasn't tested\n"); 581 NS_WARN("16-bit flashes support wasn't tested\n");
575 582
576 printk("flash size: %u MiB\n", ns->geom.totsz >> 20); 583 printk("flash size: %llu MiB\n", ns->geom.totsz >> 20);
577 printk("page size: %u bytes\n", ns->geom.pgsz); 584 printk("page size: %u bytes\n", ns->geom.pgsz);
578 printk("OOB area size: %u bytes\n", ns->geom.oobsz); 585 printk("OOB area size: %u bytes\n", ns->geom.oobsz);
579 printk("sector size: %u KiB\n", ns->geom.secsz >> 10); 586 printk("sector size: %u KiB\n", ns->geom.secsz >> 10);
@@ -583,7 +590,7 @@ static int init_nandsim(struct mtd_info *mtd)
583 printk("bits in sector size: %u\n", ns->geom.secshift); 590 printk("bits in sector size: %u\n", ns->geom.secshift);
584 printk("bits in page size: %u\n", ns->geom.pgshift); 591 printk("bits in page size: %u\n", ns->geom.pgshift);
585 printk("bits in OOB size: %u\n", ns->geom.oobshift); 592 printk("bits in OOB size: %u\n", ns->geom.oobshift);
586 printk("flash size with OOB: %u KiB\n", ns->geom.totszoob >> 10); 593 printk("flash size with OOB: %llu KiB\n", ns->geom.totszoob >> 10);
587 printk("page address bytes: %u\n", ns->geom.pgaddrbytes); 594 printk("page address bytes: %u\n", ns->geom.pgaddrbytes);
588 printk("sector address bytes: %u\n", ns->geom.secaddrbytes); 595 printk("sector address bytes: %u\n", ns->geom.secaddrbytes);
589 printk("options: %#x\n", ns->options); 596 printk("options: %#x\n", ns->options);
@@ -825,7 +832,7 @@ static int setup_wear_reporting(struct mtd_info *mtd)
825 832
826 if (!rptwear) 833 if (!rptwear)
827 return 0; 834 return 0;
828 wear_eb_count = mtd->size / mtd->erasesize; 835 wear_eb_count = divide(mtd->size, mtd->erasesize);
829 mem = wear_eb_count * sizeof(unsigned long); 836 mem = wear_eb_count * sizeof(unsigned long);
830 if (mem / sizeof(unsigned long) != wear_eb_count) { 837 if (mem / sizeof(unsigned long) != wear_eb_count) {
831 NS_ERR("Too many erase blocks for wear reporting\n"); 838 NS_ERR("Too many erase blocks for wear reporting\n");
@@ -2013,7 +2020,7 @@ static int __init ns_init_module(void)
2013 } 2020 }
2014 2021
2015 if (overridesize) { 2022 if (overridesize) {
2016 u_int32_t new_size = nsmtd->erasesize << overridesize; 2023 u_int64_t new_size = (u_int64_t)nsmtd->erasesize << overridesize;
2017 if (new_size >> overridesize != nsmtd->erasesize) { 2024 if (new_size >> overridesize != nsmtd->erasesize) {
2018 NS_ERR("overridesize is too big\n"); 2025 NS_ERR("overridesize is too big\n");
2019 goto err_exit; 2026 goto err_exit;
@@ -2021,7 +2028,7 @@ static int __init ns_init_module(void)
2021 /* N.B. This relies on nand_scan not doing anything with the size before we change it */ 2028 /* N.B. This relies on nand_scan not doing anything with the size before we change it */
2022 nsmtd->size = new_size; 2029 nsmtd->size = new_size;
2023 chip->chipsize = new_size; 2030 chip->chipsize = new_size;
2024 chip->chip_shift = ffs(new_size) - 1; 2031 chip->chip_shift = ffs(nsmtd->erasesize) + overridesize - 1;
2025 chip->pagemask = (chip->chipsize >> chip->page_shift) - 1; 2032 chip->pagemask = (chip->chipsize >> chip->page_shift) - 1;
2026 } 2033 }
2027 2034