Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1553045 > unrolled thread

[PATCH v7 0/5] mtd: use ONFI bad blocks per LUN to calculate UBI bad PEB limit

Started byZach Brown <zach.brown@ni.com>
First post2017-01-06 20:20 +0100
Last post2017-01-06 20:20 +0100
Articles 4 — 1 participant

Back to article view | Back to linux.kernel


Contents

  [PATCH v7 0/5] mtd: use ONFI bad blocks per LUN to calculate UBI bad PEB limit Zach Brown <zach.brown@ni.com> - 2017-01-06 20:20 +0100
    [PATCH v7 5/5] mtd: nand: set max_bb_per_die and blocks_per_die for ONFI compliant chips Zach Brown <zach.brown@ni.com> - 2017-01-06 20:20 +0100
    [PATCH v7 1/5] mtd: introduce function max_bad_blocks Zach Brown <zach.brown@ni.com> - 2017-01-06 20:20 +0100
    [PATCH v7 2/5] mtd: ubi: use 'max_bad_blocks' to compute bad_peb_limit if available Zach Brown <zach.brown@ni.com> - 2017-01-06 20:20 +0100

#1553045 — [PATCH v7 0/5] mtd: use ONFI bad blocks per LUN to calculate UBI bad PEB limit

FromZach Brown <zach.brown@ni.com>
Date2017-01-06 20:20 +0100
Subject[PATCH v7 0/5] mtd: use ONFI bad blocks per LUN to calculate UBI bad PEB limit
Message-ID<sWIdr-6kw-7@gated-at.bofh.it>
For ONFI-compliant NAND devices, the ONFI parameters report the maximum number
of bad blocks per LUN that will be encountered over the lifetime of the device,
so we can use that information to get a more accurate (and smaller) value for
the UBI bad PEB limit.

The ONFI parameter "maxiumum number of bad blocks per LUN" is the max number of
bad blocks that each individual LUN will ever ecounter. It is not the number of
bad blocks to reserve for the nand device per LUN in the device.

This means that in the worst case a UBI device spanning X LUNs will encounter
"maximum number of bad blocks per LUN" * X bad blocks. The implementation in
this patch assumes this worst case and allocates bad block accordingly.

These patches are ordered in terms of their dependencies, but ideally, all 5
would need to be applied for this to work as intended.

v2:
 * Changed commit message to address concerns from v1[1] about this patch set
   making best case assumptions.
v3:
 * Provided helper function for _max_bad_blocks
 * Two new patches
 * First new patch adds bb_per_lun and blocks_per_lun to nand_chip struct
 * Second new patch sets the new fields during nand_flash_detect_onfi
 * Max bad blocks calculation now uses the new nand_chip fields
v4:
 * Changed bb_per_lun and blocks_per_lun to bb_per_die and blocks_per_die
 * Corrected type of bb_per_die and blocks_per_die from little endian to host
   unsigned int
v5:
 * Changed bb_per_die to max_bb_per_die
 * Fixed spacing style issue
v6:
 * Moved bounds checking from "part_max_bad_blocks" to "mtd_max_bad_blocks"
 * Added check for 'ofs < 0' to bounds checking mentioned in change above.
 * Moved assignment of slave->mtd._max_bad_blocks up to be next to the other
   bad-block-related assignments
 * s/lun/die in "nand_max_bad_blocks"
 * Fixed comment style in "nand_max_bad_blocks"
 * In "get_bad_peb_limit" made call to "mtd_max_bad_blocks" occurr only if
   !max_beb_per1024. This makes the ordering the three different ways to set
   the bad_peb_limit: cmdline > Kconfig > automatic with mtd_max_bad_blocks
v7:
 * Moved mtd_max_bad_blocks function to be with other static inline functions
   so it would not look like the odd man out.


Jeff Westfahl (2):
  mtd: introduce function max_bad_blocks
  mtd: ubi: use 'max_bad_blocks' to compute bad_peb_limit if available

Zach Brown (3):
  mtd: nand: Add max_bb_per_die and blocks_per_die fields to nand_chip
  mtd: nand: implement 'max_bad_blocks' mtd function
  mtd: nand: set max_bb_per_die and blocks_per_die for ONFI compliant
    chips

 drivers/mtd/mtdpart.c        | 10 ++++++++++
 drivers/mtd/nand/nand_base.c | 40 ++++++++++++++++++++++++++++++++++++++++
 drivers/mtd/ubi/build.c      | 13 +++++++++++--
 include/linux/mtd/mtd.h      | 13 +++++++++++++
 include/linux/mtd/nand.h     |  5 +++++
 5 files changed, 79 insertions(+), 2 deletions(-)

-- 
2.7.4

[toc] | [next] | [standalone]


#1553046 — [PATCH v7 5/5] mtd: nand: set max_bb_per_die and blocks_per_die for ONFI compliant chips

FromZach Brown <zach.brown@ni.com>
Date2017-01-06 20:20 +0100
Subject[PATCH v7 5/5] mtd: nand: set max_bb_per_die and blocks_per_die for ONFI compliant chips
Message-ID<sWIdr-6kw-21@gated-at.bofh.it>
In reply to#1553045
ONFI compliant chips contain the values for the max_bb_per_die and
blocks_per_die fields in the parameter page. When the ONFI paged is
retrieved/parsed the chip's fields are set by the corresponding fields
in the param page.

Signed-off-by: Zach Brown <zach.brown@ni.com>
Acked-by: Boris Brezillon <boris.brezillon@free-electron.com>
Acked-by: Brian Norris <computersforpeace@gmail.com>
---
 drivers/mtd/nand/nand_base.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 587cd42..11bc2c4 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -3628,6 +3628,9 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip,
 	chip->chipsize *= (uint64_t)mtd->erasesize * p->lun_count;
 	chip->bits_per_cell = p->bits_per_cell;
 
+	chip->max_bb_per_die = le16_to_cpu(p->bb_per_lun);
+	chip->blocks_per_die = le32_to_cpu(p->blocks_per_lun);
+
 	if (onfi_feature(chip) & ONFI_FEATURE_16_BIT_BUS)
 		*busw = NAND_BUSWIDTH_16;
 	else
-- 
2.7.4

[toc] | [prev] | [next] | [standalone]


#1553047 — [PATCH v7 1/5] mtd: introduce function max_bad_blocks

FromZach Brown <zach.brown@ni.com>
Date2017-01-06 20:20 +0100
Subject[PATCH v7 1/5] mtd: introduce function max_bad_blocks
Message-ID<sWIds-6kw-41@gated-at.bofh.it>
In reply to#1553045
From: Jeff Westfahl <jeff.westfahl@ni.com>

If implemented, 'max_bad_blocks' returns the maximum number of bad
blocks to reserve for a MTD. An implementation for NAND is coming soon.

Signed-off-by: Jeff Westfahl <jeff.westfahl@ni.com>
Signed-off-by: Zach Brown <zach.brown@ni.com>
Acked-by: Boris Brezillon <boris.brezillon@free-electron.com>
Acked-by: Brian Norris <computersforpeace@gmail.com>
---
 drivers/mtd/mtdpart.c   | 10 ++++++++++
 include/linux/mtd/mtd.h | 13 +++++++++++++
 2 files changed, 23 insertions(+)

diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index fccdd49..08925bb 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -349,6 +349,14 @@ static const struct mtd_ooblayout_ops part_ooblayout_ops = {
 	.free = part_ooblayout_free,
 };
 
+static int part_max_bad_blocks(struct mtd_info *mtd, loff_t ofs, size_t len)
+{
+	struct mtd_part *part = mtd_to_part(mtd);
+
+	return part->master->_max_bad_blocks(part->master,
+					     ofs + part->offset, len);
+}
+
 static inline void free_partition(struct mtd_part *p)
 {
 	kfree(p->mtd.name);
@@ -475,6 +483,8 @@ static struct mtd_part *allocate_partition(struct mtd_info *master,
 		slave->mtd._block_isbad = part_block_isbad;
 	if (master->_block_markbad)
 		slave->mtd._block_markbad = part_block_markbad;
+	if (master->_max_bad_blocks)
+		slave->mtd._max_bad_blocks = part_max_bad_blocks;
 
 	if (master->_get_device)
 		slave->mtd._get_device = part_get_device;
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
index 13f8052..5bb42c6 100644
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -322,6 +322,7 @@ struct mtd_info {
 	int (*_block_isreserved) (struct mtd_info *mtd, loff_t ofs);
 	int (*_block_isbad) (struct mtd_info *mtd, loff_t ofs);
 	int (*_block_markbad) (struct mtd_info *mtd, loff_t ofs);
+	int (*_max_bad_blocks) (struct mtd_info *mtd, loff_t ofs, size_t len);
 	int (*_suspend) (struct mtd_info *mtd);
 	void (*_resume) (struct mtd_info *mtd);
 	void (*_reboot) (struct mtd_info *mtd);
@@ -397,6 +398,18 @@ static inline int mtd_oobavail(struct mtd_info *mtd, struct mtd_oob_ops *ops)
 	return ops->mode == MTD_OPS_AUTO_OOB ? mtd->oobavail : mtd->oobsize;
 }
 
+static inline int mtd_max_bad_blocks(struct mtd_info *mtd,
+				     loff_t ofs, size_t len)
+{
+	if (!mtd->_max_bad_blocks)
+		return -ENOTSUPP;
+
+	if (mtd->size < (len + ofs) || ofs < 0)
+		return -EINVAL;
+
+	return mtd->_max_bad_blocks(mtd, ofs, len);
+}
+
 int mtd_wunit_to_pairing_info(struct mtd_info *mtd, int wunit,
 			      struct mtd_pairing_info *info);
 int mtd_pairing_info_to_wunit(struct mtd_info *mtd,
-- 
2.7.4

[toc] | [prev] | [next] | [standalone]


#1553049 — [PATCH v7 2/5] mtd: ubi: use 'max_bad_blocks' to compute bad_peb_limit if available

FromZach Brown <zach.brown@ni.com>
Date2017-01-06 20:20 +0100
Subject[PATCH v7 2/5] mtd: ubi: use 'max_bad_blocks' to compute bad_peb_limit if available
Message-ID<sWIdr-6kw-25@gated-at.bofh.it>
In reply to#1553045
From: Jeff Westfahl <jeff.westfahl@ni.com>

If the user has not set max_beb_per1024 using either the cmdline or
Kconfig options for doing so, use the MTD function 'max_bad_blocks' to
compute the UBI bad_peb_limit.

Signed-off-by: Jeff Westfahl <jeff.westfahl@ni.com>
Signed-off-by: Zach Brown <zach.brown@ni.com>
Acked-by: Boris Brezillon <boris.brezillon@free-electron.com>
---
 drivers/mtd/ubi/build.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c
index 85d54f3..3029219 100644
--- a/drivers/mtd/ubi/build.c
+++ b/drivers/mtd/ubi/build.c
@@ -584,8 +584,17 @@ static int get_bad_peb_limit(const struct ubi_device *ubi, int max_beb_per1024)
 	int limit, device_pebs;
 	uint64_t device_size;
 
-	if (!max_beb_per1024)
-		return 0;
+	if (!max_beb_per1024) {
+		/*
+		 * Since max_beb_per1024 has not been set by the user in either
+		 * the cmdline or Kconfig, use mtd_max_bad_blocks to set the
+		 * limit if it is supported by the device.
+		 */
+		limit = mtd_max_bad_blocks(ubi->mtd, 0, ubi->mtd->size);
+		if (limit < 0)
+			return 0;
+		return limit;
+	}
 
 	/*
 	 * Here we are using size of the entire flash chip and
-- 
2.7.4

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web