summaryrefslogtreecommitdiffstats
path: root/drivers/mtd/ubi/build.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd/ubi/build.c')
-rw-r--r--drivers/mtd/ubi/build.c21
1 files changed, 18 insertions, 3 deletions
diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c
index ce311aa75a75..9980441a8886 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 (mtd_can_have_bb(ubi->mtd)) {
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;
}