summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mtd/ubi/Kconfig27
-rw-r--r--drivers/mtd/ubi/build.c21
2 files changed, 39 insertions, 9 deletions
diff --git a/drivers/mtd/ubi/Kconfig b/drivers/mtd/ubi/Kconfig
index b2f4f0f032f1..dcbaae3ead63 100644
--- a/drivers/mtd/ubi/Kconfig
+++ b/drivers/mtd/ubi/Kconfig
@@ -28,14 +28,29 @@ config MTD_UBI_WL_THRESHOLD
to 128 or 256, although it does not have to be power of 2).
config MTD_UBI_BEB_LIMIT
- int "Percentage of maximum expected bad eraseblocks"
- default 2
- range 0 25
+ int "Maximum expected bad eraseblock count per 1024 eraseblocks"
+ default 20
+ range 0 768
help
This option specifies the maximum bad physical eraseblocks UBI
- expects on the UBI device (percents of total number of physical
- eraseblocks on this MTD partition). If the underlying flash does not
- admit of bad eraseblocks (e.g. NOR flash), this value is ignored.
+ expects on the MTD device (per 1024 eraseblocks). If the underlying
+ flash does not admit of bad eraseblocks (e.g. NOR flash), this value
+ is ignored.
+
+ NAND datasheets often specify the minimum and maximum NVM (Number of
+ Valid Blocks) for the flashes' endurance lifetime. The maximum
+ expected bad eraseblocks per 1024 eraseblocks then can be calculated
+ as "1024 * (1 - MinNVB / MaxNVB)", which gives 20 for most NANDs
+ (MaxNVB is basically the total count of eraseblocks on the chip).
+
+ To put it differently, if this value is 20, UBI will try to reserve
+ about 1.9% of physical eraseblocks for bad blocks handling. And that
+ will be 1.9% of eraseblocks on the entire NAND chip, not just the MTD
+ partition UBI attaches. This means that if you have, say, a NAND
+ flash chip admits maximum 40 bad eraseblocks, and it is split on two
+ MTD partitions of the same size, UBI will reserve 40 eraseblocks when
+ attaching a partition.
+
Leave the default value if unsure.
config MTD_UBI_GLUEBI
diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c
index 0d14ae1f72dc..c77384cd4d46 100644
--- a/drivers/mtd/ubi/build.c
+++ b/drivers/mtd/ubi/build.c
@@ -36,6 +36,7 @@
#include <linux/namei.h>
#include <linux/stat.h>
#include <linux/miscdevice.h>
+#include <linux/mtd/partitions.h>
#include <linux/log2.h>
#include <linux/kthread.h>
#include <linux/kernel.h>
@@ -610,11 +611,25 @@ static int io_init(struct ubi_device *ubi)
if (ubi->mtd->block_isbad && ubi->mtd->block_markbad) {
ubi->bad_allowed = 1;
if (CONFIG_MTD_UBI_BEB_LIMIT > 0) {
- int percent = CONFIG_MTD_UBI_BEB_LIMIT;
- int limit = mult_frac(ubi->peb_count, percent, 100);
+ int per1024 = CONFIG_MTD_UBI_BEB_LIMIT;
+ int limit, device_pebs;
+ uint64_t device_size;
+
+ /*
+ * Here we are using size of the entire flash chip and
+ * not just the MTD partition size because the maximum
+ * number of bad eraseblocks is a percentage of the
+ * whole device and bad eraseblocks are not fairly
+ * distributed over the flash chip. So the worst case
+ * is that all the bad eraseblocks of the chip are in
+ * the MTD partition we are attaching (ubi->mtd).
+ */
+ device_size = mtd_get_device_size(ubi->mtd);
+ device_pebs = mtd_div_by_eb(device_size, ubi->mtd);
+ limit = mult_frac(device_pebs, per1024, 1024);
/* Round it up */
- if (mult_frac(limit, 100, percent) < ubi->peb_count)
+ if (mult_frac(limit, 1024, per1024) < device_pebs)
limit += 1;
ubi->bad_peb_limit = limit;
}