diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-02 20:49:15 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-02 20:49:15 -0700 |
commit | 65b99c74fdd325d1ffa2e5663295888704712604 (patch) | |
tree | 6ccec0803316bbefc1ea82add70245a9586c5fff /drivers/mtd/ubi | |
parent | 782c3fb22baa103abbcd30dfc99cad24bb09f1df (diff) | |
parent | 55393ba1bdedc5ded79b34b4cc08898a7776cddb (diff) |
Merge tag 'upstream-3.7-rc1' of git://git.infradead.org/linux-ubi
Pull UBI changes from Artem Bityutskiy:
"The main change is the way we reserve eraseblocks for bad blocks
handling. We used to reserve 2% of the partition, but now we are more
aggressive and we reserve 2% of the entire chip, which is what
actually manufacturers specify in data sheets. We introduced an
option to users to override the default, though.
There are a couple of fixes as well, and a number of cleanups."
* tag 'upstream-3.7-rc1' of git://git.infradead.org/linux-ubi: (24 commits)
UBI: fix trivial typo 'it' => 'is'
UBI: load after mtd device drivers
UBI: print less
UBI: use pr_ helper instead of printk
UBI: comply with coding style
UBI: erase free PEB with bitflip in EC header
UBI: fix autoresize handling in R/O mode
UBI: add max_beb_per1024 to attach ioctl
UBI: allow specifying bad PEBs limit using module parameter
UBI: check max_beb_per1024 value in ubi_attach_mtd_dev
UBI: prepare for max_beb_per1024 module parameter addition
UBI: introduce MTD_PARAM_MAX_COUNT
UBI: separate bad_peb_limit in a function
arm: sam9_l9260_defconfig: correct CONFIG_MTD_UBI_BEB_LIMIT
UBI: use the whole MTD device size to get bad_peb_limit
mtd: mtdparts: introduce mtd_get_device_size
mtd: mark mtd_is_partition argument as constant
arm: sam9_l9260_defconfig: remove non-existing config option
UBI: kill CONFIG_MTD_UBI_BEB_RESERVE
UBI: limit amount of reserved eraseblocks for bad PEB handling
...
Diffstat (limited to 'drivers/mtd/ubi')
-rw-r--r-- | drivers/mtd/ubi/Kconfig | 40 | ||||
-rw-r--r-- | drivers/mtd/ubi/attach.c | 46 | ||||
-rw-r--r-- | drivers/mtd/ubi/build.c | 204 | ||||
-rw-r--r-- | drivers/mtd/ubi/cdev.c | 18 | ||||
-rw-r--r-- | drivers/mtd/ubi/debug.c | 153 | ||||
-rw-r--r-- | drivers/mtd/ubi/debug.h | 12 | ||||
-rw-r--r-- | drivers/mtd/ubi/eba.c | 33 | ||||
-rw-r--r-- | drivers/mtd/ubi/gluebi.c | 30 | ||||
-rw-r--r-- | drivers/mtd/ubi/io.c | 80 | ||||
-rw-r--r-- | drivers/mtd/ubi/misc.c | 14 | ||||
-rw-r--r-- | drivers/mtd/ubi/ubi.h | 16 | ||||
-rw-r--r-- | drivers/mtd/ubi/vtbl.c | 10 | ||||
-rw-r--r-- | drivers/mtd/ubi/wl.c | 48 |
13 files changed, 383 insertions, 321 deletions
diff --git a/drivers/mtd/ubi/Kconfig b/drivers/mtd/ubi/Kconfig index ea4b95b5451c..271a842f8c39 100644 --- a/drivers/mtd/ubi/Kconfig +++ b/drivers/mtd/ubi/Kconfig @@ -27,20 +27,34 @@ config MTD_UBI_WL_THRESHOLD life-cycle less than 10000, the threshold should be lessened (e.g., to 128 or 256, although it does not have to be power of 2). -config MTD_UBI_BEB_RESERVE - int "Percentage of reserved eraseblocks for bad eraseblocks handling" - default 2 - range 0 25 +config MTD_UBI_BEB_LIMIT + int "Maximum expected bad eraseblock count per 1024 eraseblocks" + default 20 + range 0 768 help - If the MTD device admits of bad eraseblocks (e.g. NAND flash), UBI - reserves some amount of physical eraseblocks to handle new bad - eraseblocks. For example, if a flash physical eraseblock becomes bad, - UBI uses these reserved physical eraseblocks to relocate the bad one. - This option specifies how many physical eraseblocks will be reserved - for bad eraseblock handling (percents of total number of good flash - eraseblocks). If the underlying flash does not admit of bad - eraseblocks (e.g. NOR flash), this value is ignored and nothing is - reserved. Leave the default value if unsure. + This option specifies the maximum bad physical eraseblocks UBI + 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. + + This option can be overridden by the "mtd=" UBI module parameter or + by the "attach" ioctl. + + Leave the default value if unsure. config MTD_UBI_GLUEBI tristate "MTD devices emulation driver (gluebi)" diff --git a/drivers/mtd/ubi/attach.c b/drivers/mtd/ubi/attach.c index bd27cbbb4066..f7adf53e4f45 100644 --- a/drivers/mtd/ubi/attach.c +++ b/drivers/mtd/ubi/attach.c @@ -79,7 +79,7 @@ * NAND), it is probably a PEB which was being erased when power cut * happened, so this is corruption type 1. However, this is just a guess, * which might be wrong. - * o Otherwise this it corruption type 2. + * o Otherwise this is corruption type 2. */ #include <linux/err.h> @@ -378,8 +378,8 @@ static int compare_lebs(struct ubi_device *ubi, const struct ubi_ainf_peb *aeb, if (err == UBI_IO_BITFLIPS) bitflips = 1; else { - ubi_err("VID of PEB %d header is bad, but it " - "was OK earlier, err %d", pnum, err); + ubi_err("VID of PEB %d header is bad, but it was OK earlier, err %d", + pnum, err); if (err > 0) err = -EIO; @@ -790,12 +790,12 @@ static int check_corruption(struct ubi_device *ubi, struct ubi_vid_hdr *vid_hdr, if (ubi_check_pattern(ubi->peb_buf, 0xFF, ubi->leb_size)) goto out_unlock; - ubi_err("PEB %d contains corrupted VID header, and the data does not " - "contain all 0xFF, this may be a non-UBI PEB or a severe VID " - "header corruption which requires manual inspection", pnum); + ubi_err("PEB %d contains corrupted VID header, and the data does not contain all 0xFF", + pnum); + ubi_err("this may be a non-UBI PEB or a severe VID header corruption which requires manual inspection"); ubi_dump_vid_hdr(vid_hdr); - dbg_msg("hexdump of PEB %d offset %d, length %d", - pnum, ubi->leb_start, ubi->leb_size); + pr_err("hexdump of PEB %d offset %d, length %d", + pnum, ubi->leb_start, ubi->leb_size); ubi_dbg_print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, ubi->peb_buf, ubi->leb_size, 1); err = 1; @@ -907,8 +907,8 @@ static int scan_peb(struct ubi_device *ubi, struct ubi_attach_info *ai, ubi->image_seq = image_seq; if (ubi->image_seq && image_seq && ubi->image_seq != image_seq) { - ubi_err("bad image sequence number %d in PEB %d, " - "expected %d", image_seq, pnum, ubi->image_seq); + ubi_err("bad image sequence number %d in PEB %d, expected %d", + image_seq, pnum, ubi->image_seq); ubi_dump_ec_hdr(ech); return -EINVAL; } @@ -975,7 +975,7 @@ static int scan_peb(struct ubi_device *ubi, struct ubi_attach_info *ai, return err; goto adjust_mean_ec; case UBI_IO_FF: - if (ec_err) + if (ec_err || bitflips) err = add_to_list(ai, pnum, UBI_UNKNOWN, UBI_UNKNOWN, ec, 1, &ai->erase); else @@ -997,8 +997,8 @@ static int scan_peb(struct ubi_device *ubi, struct ubi_attach_info *ai, /* Unsupported internal volume */ switch (vidh->compat) { case UBI_COMPAT_DELETE: - ubi_msg("\"delete\" compatible internal volume %d:%d" - " found, will remove it", vol_id, lnum); + ubi_msg("\"delete\" compatible internal volume %d:%d found, will remove it", + vol_id, lnum); err = add_to_list(ai, pnum, vol_id, lnum, ec, 1, &ai->erase); if (err) @@ -1006,15 +1006,14 @@ static int scan_peb(struct ubi_device *ubi, struct ubi_attach_info *ai, return 0; case UBI_COMPAT_RO: - ubi_msg("read-only compatible internal volume %d:%d" - " found, switch to read-only mode", + ubi_msg("read-only compatible internal volume %d:%d found, switch to read-only mode", vol_id, lnum); ubi->ro_mode = 1; break; case UBI_COMPAT_PRESERVE: - ubi_msg("\"preserve\" compatible internal volume %d:%d" - " found", vol_id, lnum); + ubi_msg("\"preserve\" compatible internal volume %d:%d found", + vol_id, lnum); err = add_to_list(ai, pnum, vol_id, lnum, ec, 0, &ai->alien); if (err) @@ -1075,10 +1074,10 @@ static int late_analysis(struct ubi_device *ubi, struct ubi_attach_info *ai) if (ai->corr_peb_count) { ubi_err("%d PEBs are corrupted and preserved", ai->corr_peb_count); - printk(KERN_ERR "Corrupted PEBs are:"); + pr_err("Corrupted PEBs are:"); list_for_each_entry(aeb, &ai->corr, u.list) - printk(KERN_CONT " %d", aeb->pnum); - printk(KERN_CONT "\n"); + pr_cont(" %d", aeb->pnum); + pr_cont("\n"); /* * If too many PEBs are corrupted, we refuse attaching, @@ -1112,8 +1111,7 @@ static int late_analysis(struct ubi_device *ubi, struct ubi_attach_info *ai) get_random_bytes(&ubi->image_seq, sizeof(ubi->image_seq)); } else { - ubi_err("MTD device is not UBI-formatted and possibly " - "contains non-UBI data - refusing it"); + ubi_err("MTD device is not UBI-formatted and possibly contains non-UBI data - refusing it"); return -EINVAL; } @@ -1172,7 +1170,7 @@ static struct ubi_attach_info *scan_all(struct ubi_device *ubi) goto out_vidh; } - dbg_msg("scanning is finished"); + ubi_msg("scanning is finished"); /* Calculate mean erase counter */ if (ai->ec_count) @@ -1244,7 +1242,7 @@ int ubi_attach(struct ubi_device *ubi) ubi->corr_peb_count = ai->corr_peb_count; ubi->max_ec = ai->max_ec; ubi->mean_ec = ai->mean_ec; - ubi_msg("max. sequence number: %llu", ai->max_sqnum); + dbg_gen("max. sequence number: %llu", ai->max_sqnum); err = ubi_read_volume_table(ubi, ai); if (err) diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index 2c5ed5ca9c33..34977039850c 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> @@ -45,6 +46,12 @@ /* Maximum length of the 'mtd=' parameter */ #define MTD_PARAM_LEN_MAX 64 +/* Maximum number of comma-separated items in the 'mtd=' parameter */ +#define MTD_PARAM_MAX_COUNT 3 + +/* Maximum value for the number of bad PEBs per 1024 PEBs */ +#define MAX_MTD_UBI_BEB_LIMIT 768 + #ifdef CONFIG_MTD_UBI_MODULE #define ubi_is_module() 1 #else @@ -56,10 +63,12 @@ * @name: MTD character device node path, MTD device name, or MTD device number * string * @vid_hdr_offs: VID header offset + * @max_beb_per1024: maximum expected number of bad PEBs per 1024 PEBs */ struct mtd_dev_param { char name[MTD_PARAM_LEN_MAX]; int vid_hdr_offs; + int max_beb_per1024; }; /* Numbers of elements set in the @mtd_dev_param array */ @@ -564,9 +573,38 @@ void ubi_free_internal_volumes(struct ubi_device *ubi) } } +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; + + /* + * 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, max_beb_per1024, 1024); + + /* Round it up */ + if (mult_frac(limit, 1024, max_beb_per1024) < device_pebs) + limit += 1; + + return limit; +} + /** * io_init - initialize I/O sub-system for a given UBI device. * @ubi: UBI device description object + * @max_beb_per1024: maximum expected number of bad PEB per 1024 PEBs * * If @ubi->vid_hdr_offset or @ubi->leb_start is zero, default offsets are * assumed: @@ -579,8 +617,11 @@ void ubi_free_internal_volumes(struct ubi_device *ubi) * This function returns zero in case of success and a negative error code in * case of failure. */ -static int io_init(struct ubi_device *ubi) +static int io_init(struct ubi_device *ubi, int max_beb_per1024) { + dbg_gen("sizeof(struct ubi_ainf_peb) %zu", sizeof(struct ubi_ainf_peb)); + dbg_gen("sizeof(struct ubi_wl_entry) %zu", sizeof(struct ubi_wl_entry)); + if (ubi->mtd->numeraseregions != 0) { /* * Some flashes have several erase regions. Different regions @@ -607,8 +648,10 @@ static int io_init(struct ubi_device *ubi) ubi->peb_count = mtd_div_by_eb(ubi->mtd->size, ubi->mtd); ubi->flash_size = ubi->mtd->size; - if (mtd_can_have_bb(ubi->mtd)) + if (mtd_can_have_bb(ubi->mtd)) { ubi->bad_allowed = 1; + ubi->bad_peb_limit = get_bad_peb_limit(ubi, max_beb_per1024); + } if (ubi->mtd->type == MTD_NORFLASH) { ubi_assert(ubi->mtd->writesize == 1); @@ -650,11 +693,11 @@ static int io_init(struct ubi_device *ubi) ubi->ec_hdr_alsize = ALIGN(UBI_EC_HDR_SIZE, ubi->hdrs_min_io_size); ubi->vid_hdr_alsize = ALIGN(UBI_VID_HDR_SIZE, ubi->hdrs_min_io_size); - dbg_msg("min_io_size %d", ubi->min_io_size); - dbg_msg("max_write_size %d", ubi->max_write_size); - dbg_msg("hdrs_min_io_size %d", ubi->hdrs_min_io_size); - dbg_msg("ec_hdr_alsize %d", ubi->ec_hdr_alsize); - dbg_msg("vid_hdr_alsize %d", ubi->vid_hdr_alsize); + dbg_gen("min_io_size %d", ubi->min_io_size); + dbg_gen("max_write_size %d", ubi->max_write_size); + dbg_gen("hdrs_min_io_size %d", ubi->hdrs_min_io_size); + dbg_gen("ec_hdr_alsize %d", ubi->ec_hdr_alsize); + dbg_gen("vid_hdr_alsize %d", ubi->vid_hdr_alsize); if (ubi->vid_hdr_offset == 0) /* Default offset */ @@ -671,10 +714,10 @@ static int io_init(struct ubi_device *ubi) ubi->leb_start = ubi->vid_hdr_offset + UBI_VID_HDR_SIZE; ubi->leb_start = ALIGN(ubi->leb_start, ubi->min_io_size); - dbg_msg("vid_hdr_offset %d", ubi->vid_hdr_offset); - dbg_msg("vid_hdr_aloffset %d", ubi->vid_hdr_aloffset); - dbg_msg("vid_hdr_shift %d", ubi->vid_hdr_shift); - dbg_msg("leb_start %d", ubi->leb_start); + dbg_gen("vid_hdr_offset %d", ubi->vid_hdr_offset); + dbg_gen("vid_hdr_aloffset %d", ubi->vid_hdr_aloffset); + dbg_gen("vid_hdr_shift %d", ubi->vid_hdr_shift); + dbg_gen("leb_start %d", ubi->leb_start); /* The shift must be aligned to 32-bit boundary */ if (ubi->vid_hdr_shift % 4) { @@ -700,7 +743,7 @@ static int io_init(struct ubi_device *ubi) ubi->max_erroneous = ubi->peb_count / 10; if (ubi->max_erroneous < 16) ubi->max_erroneous = 16; - dbg_msg("max_erroneous %d", ubi->max_erroneous); + dbg_gen("max_erroneous %d", ubi->max_erroneous); /* * It may happen that EC and VID headers are situated in one minimal @@ -708,30 +751,18 @@ static int io_init(struct ubi_device *ubi) * read-only mode. */ if (ubi->vid_hdr_offset + UBI_VID_HDR_SIZE <= ubi->hdrs_min_io_size) { - ubi_warn("EC and VID headers are in the same minimal I/O unit, " - "switch to read-only mode"); + ubi_warn("EC and VID headers are in the same minimal I/O unit, switch to read-only mode"); ubi->ro_mode = 1; } ubi->leb_size = ubi->peb_size - ubi->leb_start; if (!(ubi->mtd->flags & MTD_WRITEABLE)) { - ubi_msg("MTD device %d is write-protected, attach in " - "read-only mode", ubi->mtd->index); + ubi_msg("MTD device %d is write-protected, attach in read-only mode", + ubi->mtd->index); ubi->ro_mode = 1; } - ubi_msg("physical eraseblock size: %d bytes (%d KiB)", - ubi->peb_size, ubi->peb_size >> 10); - ubi_msg("logical eraseblock size: %d bytes", ubi->leb_size); - ubi_msg("smallest flash I/O unit: %d", ubi->min_io_size); - if (ubi->hdrs_min_io_size != ubi->min_io_size) - ubi_msg("sub-page size: %d", - ubi->hdrs_min_io_size); - ubi_msg("VID header offset: %d (aligned %d)", - ubi->vid_hdr_offset, ubi->vid_hdr_aloffset); - ubi_msg("data offset: %d", ubi->leb_start); - /* * Note, ideally, we have to initialize @ubi->bad_peb_count here. But * unfortunately, MTD does not provide this information. We should loop @@ -759,6 +790,11 @@ static int autoresize(struct ubi_device *ubi, int vol_id) struct ubi_volume *vol = ubi->volumes[vol_id]; int err, old_reserved_pebs = vol->reserved_pebs; + if (ubi->ro_mode) { + ubi_warn("skip auto-resize because of R/O mode"); + return 0; + } + /* * Clear the auto-resize flag in the volume in-memory copy of the * volume table, and 'ubi_resize_volume()' will propagate this change @@ -800,6 +836,7 @@ static int autoresize(struct ubi_device *ubi, int vol_id) * @mtd: MTD device description object * @ubi_num: number to assign to the new UBI device * @vid_hdr_offset: VID header offset + * @max_beb_per1024: maximum expected number of bad PEB per 1024 PEBs * * This function attaches MTD device @mtd_dev to UBI and assign @ubi_num number * to the newly created UBI device, unless @ubi_num is %UBI_DEV_NUM_AUTO, in @@ -810,11 +847,18 @@ static int autoresize(struct ubi_device *ubi, int vol_id) * Note, the invocations of this function has to be serialized by the * @ubi_devices_mutex. */ -int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset) +int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, + int vid_hdr_offset, int max_beb_per1024) { struct ubi_device *ubi; int i, err, ref = 0; + if (max_beb_per1024 < 0 || max_beb_per1024 > MAX_MTD_UBI_BEB_LIMIT) + return -EINVAL; + + if (!max_beb_per1024) + max_beb_per1024 = CONFIG_MTD_UBI_BEB_LIMIT; + /* * Check if we already have the same MTD device attached. * @@ -839,8 +883,8 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset) * no sense to attach emulated MTD devices, so we prohibit this. */ if (mtd->type == MTD_UBIVOLUME) { - ubi_err("refuse attaching mtd%d - it is already emulated on " - "top of UBI", mtd->index); + ubi_err("refuse attaching mtd%d - it is already emulated on top of UBI", + mtd->index); return -EINVAL; } @@ -880,10 +924,8 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset) spin_lock_init(&ubi->volumes_lock); ubi_msg("attaching mtd%d to ubi%d", mtd->index, ubi_num); - dbg_msg("sizeof(struct ubi_ainf_peb) %zu", sizeof(struct ubi_ainf_peb)); - dbg_msg("sizeof(struct ubi_wl_entry) %zu", sizeof(struct ubi_wl_entry)); - err = io_init(ubi); + err = io_init(ubi, max_beb_per1024); if (err) goto out_free; @@ -924,23 +966,24 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset) goto out_debugfs; } - ubi_msg("attached mtd%d to ubi%d", mtd->index, ubi_num); - ubi_msg("MTD device name: \"%s\"", mtd->name); - ubi_msg("MTD device size: %llu MiB", ubi->flash_size >> 20); - ubi_msg("number of good PEBs: %d", ubi->good_peb_count); - ubi_msg("number of bad PEBs: %d", ubi->bad_peb_count); - ubi_msg("number of corrupted PEBs: %d", ubi->corr_peb_count); - ubi_msg("max. allowed volumes: %d", ubi->vtbl_slots); - ubi_msg("wear-leveling threshold: %d", CONFIG_MTD_UBI_WL_THRESHOLD); - ubi_msg("number of internal volumes: %d", UBI_INT_VOL_COUNT); - ubi_msg("number of user volumes: %d", - ubi->vol_count - UBI_INT_VOL_COUNT); - ubi_msg("available PEBs: %d", ubi->avail_pebs); - ubi_msg("total number of reserved PEBs: %d", ubi->rsvd_pebs); - ubi_msg("number of PEBs reserved for bad PEB handling: %d", - ubi->beb_rsvd_pebs); - ubi_msg("max/mean erase counter: %d/%d", ubi->max_ec, ubi->mean_ec); - ubi_msg("image sequence number: %d", ubi->image_seq); + ubi_msg("attached mtd%d (name \"%s\", size %llu MiB) to ubi%d", + mtd->index, mtd->name, ubi->flash_size >> 20, ubi_num); + ubi_msg("PEB size: %d bytes (%d KiB), LEB size: %d bytes", + ubi->peb_size, ubi->peb_size >> 10, ubi->leb_size); + ubi_msg("min./max. I/O unit sizes: %d/%d, sub-page size %d", + ubi->min_io_size, ubi->max_write_size, ubi->hdrs_min_io_size); + ubi_msg("VID header offset: %d (aligned %d), data offset: %d", + ubi->vid_hdr_offset, ubi->vid_hdr_aloffset, ubi->leb_start); + ubi_msg("good PEBs: %d, bad PEBs: %d, corrupted PEBs: %d", + ubi->good_peb_count, ubi->bad_peb_count, ubi->corr_peb_count); + ubi_msg("user volume: %d, internal volumes: %d, max. volumes count: %d", + ubi->vol_count - UBI_INT_VOL_COUNT, UBI_INT_VOL_COUNT, + ubi->vtbl_slots); + ubi_msg("max/mean erase counter: %d/%d, WL threshold: %d, image sequence number: %u", + ubi->max_ec, ubi->mean_ec, CONFIG_MTD_UBI_WL_THRESHOLD, + ubi->image_seq); + ubi_msg("available PEBs: %d, total reserved PEBs: %d, PEBs reserved for bad PEB handling: %d", + ubi->avail_pebs, ubi->rsvd_pebs, ubi->beb_rsvd_pebs); /* * The below lock makes sure we do not race with 'ubi_thread()' which @@ -1017,7 +1060,7 @@ int ubi_detach_mtd_dev(int ubi_num, int anyway) ubi_assert(ubi_num == ubi->ubi_num); ubi_notify_all(ubi, UBI_VOLUME_REMOVED, NULL); - dbg_msg("detaching mtd%d from ubi%d", ubi->mtd->index, ubi_num); + ubi_msg("detaching mtd%d from ubi%d", ubi->mtd->index, ubi_num); /* * Before freeing anything, we have to stop the background thread to @@ -1172,7 +1215,7 @@ static int __init ubi_init(void) mutex_lock(&ubi_devices_mutex); err = ubi_attach_mtd_dev(mtd, UBI_DEV_NUM_AUTO, - p->vid_hdr_offs); + p->vid_hdr_offs, p->max_beb_per1024); mutex_unlock(&ubi_devices_mutex); if (err < 0) { ubi_err("cannot attach mtd%d", mtd->index); @@ -1218,7 +1261,7 @@ out: ubi_err("UBI error: cannot initialize UBI, error %d", err); return err; } -module_init(ubi_init); +late_initcall(ubi_init); static void __exit ubi_exit(void) { @@ -1252,8 +1295,7 @@ static int __init bytes_str_to_int(const char *str) result = simple_strtoul(str, &endp, 0); if (str == endp || result >= INT_MAX) { - printk(KERN_ERR "UBI error: incorrect bytes count: \"%s\"\n", - str); + ubi_err("UBI error: incorrect bytes count: \"%s\"\n", str); return -EINVAL; } @@ -1269,8 +1311,7 @@ static int __init bytes_str_to_int(const char *str) case '\0': break; default: - printk(KERN_ERR "UBI error: incorrect bytes count: \"%s\"\n", - str); + ubi_err("UBI error: incorrect bytes count: \"%s\"\n", str); return -EINVAL; } @@ -1291,27 +1332,26 @@ static int __init ubi_mtd_param_parse(const char *val, struct kernel_param *kp) struct mtd_dev_param *p; char buf[MTD_PARAM_LEN_MAX]; char *pbuf = &buf[0]; - char *tokens[2] = {NULL, NULL}; + char *tokens[MTD_PARAM_MAX_COUNT]; if (!val) return -EINVAL; if (mtd_devs == UBI_MAX_DEVICES) { - printk(KERN_ERR "UBI error: too many parameters, max. is %d\n", - UBI_MAX_DEVICES); + ubi_err("UBI error: too many parameters, max. is %d\n", + UBI_MAX_DEVICES); return -EINVAL; } len = strnlen(val, MTD_PARAM_LEN_MAX); if (len == MTD_PARAM_LEN_MAX) { - printk(KERN_ERR "UBI error: parameter \"%s\" is too long, " - "max. is %d\n", val, MTD_PARAM_LEN_MAX); + ubi_err("UBI error: parameter \"%s\" is too long, max. is %d\n", + val, MTD_PARAM_LEN_MAX); return -EINVAL; } if (len == 0) { - printk(KERN_WARNING "UBI warning: empty 'mtd=' parameter - " - "ignored\n"); + pr_warn("UBI warning: empty 'mtd=' parameter - ignored\n"); return 0; } @@ -1321,12 +1361,11 @@ static int __init ubi_mtd_param_parse(const char *val, struct kernel_param *kp) if (buf[len - 1] == '\n') buf[len - 1] = '\0'; - for (i = 0; i < 2; i++) + for (i = 0; i < MTD_PARAM_MAX_COUNT; i++) tokens[i] = strsep(&pbuf, ","); if (pbuf) { - printk(KERN_ERR "UBI error: too many arguments at \"%s\"\n", - val); + ubi_err("UBI error: too many arguments at \"%s\"\n", val); return -EINVAL; } @@ -1339,23 +1378,32 @@ static int __init ubi_mtd_param_parse(const char *val, struct kernel_param *kp) if (p->vid_hdr_offs < 0) return p->vid_hdr_offs; + if (tokens[2]) { + int err = kstrtoint(tokens[2], 10, &p->max_beb_per1024); + + if (err) { + ubi_err("UBI error: bad value for max_beb_per1024 parameter: %s", + tokens[2]); + return -EINVAL; + } + } + mtd_devs += 1; return 0; } module_param_call(mtd, ubi_mtd_param_parse, NULL, NULL, 000); -MODULE_PARM_DESC(mtd, "MTD devices to attach. Parameter format: " - "mtd=<name|num|path>[,<vid_hdr_offs>].\n" +MODULE_PARM_DESC(mtd, "MTD devices to attach. Parameter format: mtd=<name|num|path>[,<vid_hdr_offs>[,max_beb_per1024]].\n" "Multiple \"mtd\" parameters may be specified.\n" - "MTD devices may be specified by their number, name, or " - "path to the MTD character device node.\n" - "Optional \"vid_hdr_offs\" parameter specifies UBI VID " - "header position to be used by UBI.\n" - "Example 1: mtd=/dev/mtd0 - attach MTD device " - "/dev/mtd0.\n" - "Example 2: mtd=content,1984 mtd=4 - attach MTD device " - "with name \"content\" using VID header offset 1984, and " - "MTD device number 4 with default VID header offset."); + "MTD devices may be specified by their number, name, or path to the MTD character device node.\n" + "Optional \"vid_hdr_offs\" parameter specifies UBI VID header position to be used by UBI. (default value if 0)\n" + "Optional \"max_beb_per1024\" parameter specifies the maximum expected bad eraseblock per 1024 eraseblocks. (default value (" + __stringify(CONFIG_MTD_UBI_BEB_LIMIT) ") if 0)\n" + "\n" + "Example 1: mtd=/dev/mtd0 - attach MTD device /dev/mtd0.\n" + "Example 2: mtd=content,1984 mtd=4 - attach MTD device with name \"content\" using VID header offset 1984, and MTD device number 4 with default VID header offset.\n" + "Example 3: mtd=/dev/mtd1,0,25 - attach MTD device /dev/mtd1 using default VID header offset and reserve 25*nand_size_in_blocks/1024 erase blocks for bad block handling.\n" + "\t(e.g. if the NAND *chipset* has 4096 PEB, 100 will be reserved for this UBI device)."); MODULE_VERSION(__stringify(UBI_VERSION)); MODULE_DESCRIPTION("UBI - Unsorted Block Images"); diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c index fb5567878181..dfcc65b33e99 100644 --- a/drivers/mtd/ubi/cdev.c +++ b/drivers/mtd/ubi/cdev.c @@ -140,9 +140,9 @@ static int vol_cdev_release(struct inode *inode, struct file *file) vol->updating = 0; vfree(vol->upd_buf); } else if (vol->changing_leb) { - dbg_gen("only %lld of %lld bytes received for atomic LEB change" - " for volume %d:%d, cancel", vol->upd_received, - vol->upd_bytes, vol->ubi->ubi_num, vol->vol_id); + dbg_gen("only %lld of %lld bytes received for atomic LEB change for volume %d:%d, cancel", + vol->upd_received, vol->upd_bytes, vol->ubi->ubi_num, + vol->vol_id); vol->changing_leb = 0; vfree(vol->upd_buf); } @@ -189,7 +189,8 @@ static loff_t vol_cdev_llseek(struct file *file, loff_t offset, int origin) return new_offset; } -static int vol_cdev_fsync(struct file *file, loff_t start, loff_t end, int datasync) +static int vol_cdev_fsync(struct file *file, loff_t start, loff_t end, + int datasync) { struct ubi_volume_desc *desc = file->private_data; struct ubi_device *ubi = desc->vol->ubi; @@ -753,7 +754,7 @@ static int rename_volumes(struct ubi_device *ubi, re->new_name_len = name_len; memcpy(re->new_name, name, name_len); list_add_tail(&re->list, &rename_list); - dbg_msg("will rename volume %d from \"%s\" to \"%s\"", + dbg_gen("will rename volume %d from \"%s\" to \"%s\"", vol_id, re->desc->vol->name, name); } @@ -811,7 +812,7 @@ static int rename_volumes(struct ubi_device *ubi, re1->remove = 1; re1->desc = desc; list_add(&re1->list, &rename_list); - dbg_msg("will remove volume %d, name \"%s\"", + dbg_gen("will remove volume %d, name \"%s\"", re1->desc->vol->vol_id, re1->desc->vol->name); } @@ -942,7 +943,7 @@ static long ubi_cdev_ioctl(struct file *file, unsigned int cmd, { struct ubi_rnvol_req *req; - dbg_msg("re-name volumes"); + dbg_gen("re-name volumes"); req = kmalloc(sizeof(struct ubi_rnvol_req), GFP_KERNEL); if (!req) { err = -ENOMEM; @@ -1010,7 +1011,8 @@ static long ctrl_cdev_ioctl(struct file *file, unsigned int cmd, * 'ubi_attach_mtd_dev()'. */ mutex_lock(&ubi_devices_mutex); - err = ubi_attach_mtd_dev(mtd, req.ubi_num, req.vid_hdr_offset); + err = ubi_attach_mtd_dev(mtd, req.ubi_num, req.vid_hdr_offset, + req.max_beb_per1024); mutex_unlock(&ubi_devices_mutex); if (err < 0) put_mtd_device(mtd); diff --git a/drivers/mtd/ubi/debug.c b/drivers/mtd/ubi/debug.c index 7c1380305219..26908a59506b 100644 --- a/drivers/mtd/ubi/debug.c +++ b/drivers/mtd/ubi/debug.c @@ -43,8 +43,8 @@ void ubi_dump_flash(struct ubi_device *ubi, int pnum, int offset, int len) return; err = mtd_read(ubi->mtd, addr, len, &read, buf); if (err && err != -EUCLEAN) { - ubi_err("error %d while reading %d bytes from PEB %d:%d, " - "read %zd bytes", err, len, pnum, offset, read); + ubi_err("error %d while reading %d bytes from PEB %d:%d, read %zd bytes", + err, len, pnum, offset, read); goto out; } @@ -62,21 +62,15 @@ out: */ void ubi_dump_ec_hdr(const struct ubi_ec_hdr *ec_hdr) { - printk(KERN_DEBUG "Erase counter header dump:\n"); - printk(KERN_DEBUG "\tmagic %#08x\n", - be32_to_cpu(ec_hdr->magic)); - printk(KERN_DEBUG "\tversion %d\n", (int)ec_hdr->version); - printk(KERN_DEBUG "\tec %llu\n", - (long long)be64_to_cpu(ec_hdr->ec)); - printk(KERN_DEBUG "\tvid_hdr_offset %d\n", - be32_to_cpu(ec_hdr->vid_hdr_offset)); - printk(KERN_DEBUG "\tdata_offset %d\n", - be32_to_cpu(ec_hdr->data_offset)); - printk(KERN_DEBUG "\timage_seq %d\n", - be32_to_cpu(ec_hdr->image_seq)); - printk(KERN_DEBUG "\thdr_crc %#08x\n", - be32_to_cpu(ec_hdr->hdr_crc)); - printk(KERN_DEBUG "erase counter header hexdump:\n"); + pr_err("Erase counter header dump:\n"); + pr_err("\tmagic %#08x\n", be32_to_cpu(ec_hdr->magic)); + pr_err("\tversion %d\n", (int)ec_hdr->version); + pr_err("\tec %llu\n", (long long)be64_to_cpu(ec_hdr->ec)); + pr_err("\tvid_hdr_offset %d\n", be32_to_cpu(ec_hdr->vid_hdr_offset)); + pr_err("\tdata_offset %d\n", be32_to_cpu(ec_hdr->data_offset)); + pr_err("\timage_seq %d\n", be32_to_cpu(ec_hdr->image_seq)); + pr_err("\thdr_crc %#08x\n", be32_to_cpu(ec_hdr->hdr_crc)); + pr_err("erase counter header hexdump:\n"); print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, ec_hdr, UBI_EC_HDR_SIZE, 1); } @@ -87,21 +81,21 @@ void ubi_dump_ec_hdr(const struct ubi_ec_hdr *ec_hdr) */ void ubi_dump_vid_hdr(const struct ubi_vid_hdr *vid_hdr) { - printk(KERN_DEBUG "Volume identifier header dump:\n"); - printk(KERN_DEBUG "\tmagic %08x\n", be32_to_cpu(vid_hdr->magic)); - printk(KERN_DEBUG "\tversion %d\n", (int)vid_hdr->version); - printk(KERN_DEBUG "\tvol_type %d\n", (int)vid_hdr->vol_type); - printk(KERN_DEBUG "\tcopy_flag %d\n", (int)vid_hdr->copy_flag); - printk(KERN_DEBUG "\tcompat %d\n", (int)vid_hdr->compat); - printk(KERN_DEBUG "\tvol_id %d\n", be32_to_cpu(vid_hdr->vol_id)); - printk(KERN_DEBUG "\tlnum %d\n", be32_to_cpu(vid_hdr->lnum)); - printk(KERN_DEBUG "\tdata_size %d\n", be32_to_cpu(vid_hdr->data_size)); - printk(KERN_DEBUG "\tused_ebs %d\n", be32_to_cpu(vid_hdr->used_ebs)); - printk(KERN_DEBUG "\tdata_pad %d\n", be32_to_cpu(vid_hdr->data_pad)); - printk(KERN_DEBUG "\tsqnum %llu\n", + pr_err("Volume identifier header dump:\n"); + pr_err("\tmagic %08x\n", be32_to_cpu(vid_hdr->magic)); + pr_err("\tversion %d\n", (int)vid_hdr->version); + pr_err("\tvol_type %d\n", (int)vid_hdr->vol_type); + pr_err("\tcopy_flag %d\n", (int)vid_hdr->copy_flag); + pr_err("\tcompat %d\n", (int)vid_hdr->compat); + pr_err("\tvol_id %d\n", be32_to_cpu(vid_hdr->vol_id)); + pr_err("\tlnum %d\n", be32_to_cpu(vid_hdr->lnum)); + pr_err("\tdata_size %d\n", be32_to_cpu(vid_hdr->data_size)); + pr_err("\tused_ebs %d\n", be32_to_cpu(vid_hdr->used_ebs)); + pr_err("\tdata_pad %d\n", be32_to_cpu(vid_hdr->data_pad)); + pr_err("\tsqnum %llu\n", (unsigned long long)be64_to_cpu(vid_hdr->sqnum)); - printk(KERN_DEBUG "\thdr_crc %08x\n", be32_to_cpu(vid_hdr->hdr_crc)); - printk(KERN_DEBUG "Volume identifier header hexdump:\n"); + pr_err("\thdr_crc %08x\n", be32_to_cpu(vid_hdr->hdr_crc)); + pr_err("Volume identifier header hexdump:\n"); print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, vid_hdr, UBI_VID_HDR_SIZE, 1); } @@ -112,25 +106,25 @@ void ubi_dump_vid_hdr(const struct ubi_vid_hdr *vid_hdr) */ void ubi_dump_vol_info(const struct ubi_volume *vol) { - printk(KERN_DEBUG "Volume information dump:\n"); - printk(KERN_DEBUG "\tvol_id %d\n", vol->vol_id); - printk(KERN_DEBUG "\treserved_pebs %d\n", vol->reserved_pebs); - printk(KERN_DEBUG "\talignment %d\n", vol->alignment); - printk(KERN_DEBUG "\tdata_pad %d\n", vol->data_pad); - printk(KERN_DEBUG "\tvol_type %d\n", vol->vol_type); - printk(KERN_DEBUG "\tname_len %d\n", vol->name_len); - printk(KERN_DEBUG "\tusable_leb_size %d\n", vol->usable_leb_size); - printk(KERN_DEBUG "\tused_ebs %d\n", vol->used_ebs); - printk(KERN_DEBUG "\tused_bytes %lld\n", vol->used_bytes); - printk(KERN_DEBUG "\tlast_eb_bytes %d\n", vol->last_eb_bytes); - printk(KERN_DEBUG "\tcorrupted %d\n", vol->corrupted); - printk(KERN_DEBUG "\tupd_marker %d\n", vol->upd_marker); + pr_err("Volume information dump:\n"); + pr_err("\tvol_id %d\n", vol->vol_id); + pr_err("\treserved_pebs %d\n", vol->reserved_pebs); + pr_err("\talignment %d\n", vol->alignment); + pr_err("\tdata_pad %d\n", vol->data_pad); + pr_err("\tvol_type %d\n", vol->vol_type); + pr_err("\tname_len %d\n", vol->name_len); + pr_err("\tusable_leb_size %d\n", vol->usable_leb_size); + pr_err("\tused_ebs %d\n", vol->used_ebs); + pr_err("\tused_bytes %lld\n", vol->used_bytes); + pr_err("\tlast_eb_bytes %d\n", vol->last_eb_bytes); + pr_err("\tcorrupted %d\n", vol->corrupted); + pr_err("\tupd_marker %d\n", vol->upd_marker); if (vol->name_len <= UBI_VOL_NAME_MAX && strnlen(vol->name, vol->name_len + 1) == vol->name_len) { - printk(KERN_DEBUG "\tname %s\n", vol->name); + pr_err("\tname %s\n", vol->name); } else { - printk(KERN_DEBUG "\t1st 5 characters of name: %c%c%c%c%c\n", + pr_err("\t1st 5 characters of name: %c%c%c%c%c\n", vol->name[0], vol->name[1], vol->name[2], vol->name[3], vol->name[4]); } @@ -145,29 +139,28 @@ void ubi_dump_vtbl_record(const struct ubi_vtbl_record *r, int idx) { int name_len = be16_to_cpu(r->name_len); - printk(KERN_DEBUG "Volume table reco |