aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/ubi/build.c
diff options
context:
space:
mode:
authorRichard Genoud <richard.genoud@gmail.com>2012-07-10 12:23:41 -0400
committerArtem Bityutskiy <artem.bityutskiy@linux.intel.com>2012-09-04 02:39:00 -0400
commitba4087e956d336488c6df9dfca65d1e70cf480f1 (patch)
tree25faa54edbfd08685e7b12e2715cda470159bd92 /drivers/mtd/ubi/build.c
parent62082e56cbb807cb325a8968f35dbd922432eb48 (diff)
UBI: use the whole MTD device size to get bad_peb_limit
On NAND flash devices, UBI reserves some physical erase blocks (PEB) for bad block handling. Today, the number of reserved PEB can only be set as a percentage of the total number of PEB in each MTD partition. For example, for a NAND flash with 128KiB PEB, 2 MTD partition of 20MiB (mtd0) and 100MiB (mtd1) and 2% reserved PEB: - the UBI device on mtd0 will have 2 PEB reserved - the UBI device on mtd1 will have 16 PEB reserved The problem with this behaviour is that NAND flash manufacturers give a minimum number of valid block (NVB) during the endurance life of the device, e.g.: Parameter Symbol Min Max Unit Notes -------------------------------------------------------------- Valid block number NVB 1004 1024 Blocks 1 From this number we can deduce the maximum number of bad PEB that a device will contain during its endurance life: a 128MiB NAND flash (1024 PEB) will not have less than 20 bad blocks during the flash endurance life. But the manufacturer doesn't tell where those bad block will appear. He doesn't say either if they will be equally disposed on the whole device (and I'm pretty sure they won't). So, according to the datasheets, we should reserve the maximum number of bad PEB for each UBI device (worst case scenario: 20 bad blocks appears on the smallest MTD partition). So this patch make UBI use the whole MTD device size to calculate the maximum bad expected eraseblocks. The Kconfig option is in per1024 blocks, thus it can have a default value of 20 which is *very* common for NAND devices. Signed-off-by: Richard Genoud <richard.genoud@gmail.com> Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
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 @@
36#include <linux/namei.h> 36#include <linux/namei.h>
37#include <linux/stat.h> 37#include <linux/stat.h>
38#include <linux/miscdevice.h> 38#include <linux/miscdevice.h>
39#include <linux/mtd/partitions.h>
39#include <linux/log2.h> 40#include <linux/log2.h>
40#include <linux/kthread.h> 41#include <linux/kthread.h>
41#include <linux/kernel.h> 42#include <linux/kernel.h>
@@ -610,11 +611,25 @@ static int io_init(struct ubi_device *ubi)
610 if (mtd_can_have_bb(ubi->mtd)) { 611 if (mtd_can_have_bb(ubi->mtd)) {
611 ubi->bad_allowed = 1; 612 ubi->bad_allowed = 1;
612 if (CONFIG_MTD_UBI_BEB_LIMIT > 0) { 613 if (CONFIG_MTD_UBI_BEB_LIMIT > 0) {
613 int percent = CONFIG_MTD_UBI_BEB_LIMIT; 614 int per1024 = CONFIG_MTD_UBI_BEB_LIMIT;
614 int limit = mult_frac(ubi->peb_count, percent, 100); 615 int limit, device_pebs;
616 uint64_t device_size;
617
618 /*
619 * Here we are using size of the entire flash chip and
620 * not just the MTD partition size because the maximum
621 * number of bad eraseblocks is a percentage of the
622 * whole device and bad eraseblocks are not fairly
623 * distributed over the flash chip. So the worst case
624 * is that all the bad eraseblocks of the chip are in
625 * the MTD partition we are attaching (ubi->mtd).
626 */
627 device_size = mtd_get_device_size(ubi->mtd);
628 device_pebs = mtd_div_by_eb(device_size, ubi->mtd);
629 limit = mult_frac(device_pebs, per1024, 1024);
615 630
616 /* Round it up */ 631 /* Round it up */
617 if (mult_frac(limit, 100, percent) < ubi->peb_count) 632 if (mult_frac(limit, 1024, per1024) < device_pebs)
618 limit += 1; 633 limit += 1;
619 ubi->bad_peb_limit = limit; 634 ubi->bad_peb_limit = limit;
620 } 635 }