--- zzzz-none-000/linux-3.10.107/drivers/mtd/ubi/build.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/drivers/mtd/ubi/build.c 2021-02-04 17:41:59.000000000 +0000 @@ -41,13 +41,14 @@ #include #include #include +#include #include "ubi.h" /* 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 +#define MTD_PARAM_MAX_COUNT 4 /* Maximum value for the number of bad PEBs per 1024 PEBs */ #define MAX_MTD_UBI_BEB_LIMIT 768 @@ -67,6 +68,7 @@ */ struct mtd_dev_param { char name[MTD_PARAM_LEN_MAX]; + int ubi_num; int vid_hdr_offs; int max_beb_per1024; }; @@ -79,9 +81,8 @@ #ifdef CONFIG_MTD_UBI_FASTMAP /* UBI module parameter to enable fastmap automatically on non-fastmap images */ static bool fm_autoconvert; +static bool fm_debug; #endif -/* Root UBI "class" object (corresponds to '//class/ubi/') */ -struct class *ubi_class; /* Slab cache for wear-leveling entries */ struct kmem_cache *ubi_wl_entry_slab; @@ -110,8 +111,17 @@ } /* UBI version attribute ('//class/ubi/version') */ -static struct class_attribute ubi_version = - __ATTR(version, S_IRUGO, ubi_version_show, NULL); +static struct class_attribute ubi_class_attrs[] = { + __ATTR(version, S_IRUGO, ubi_version_show, NULL), + __ATTR_NULL +}; + +/* Root UBI "class" object (corresponds to '//class/ubi/') */ +struct class ubi_class = { + .name = UBI_NAME_STR, + .owner = THIS_MODULE, + .class_attrs = ubi_class_attrs, +}; static ssize_t dev_attribute_show(struct device *dev, struct device_attribute *attr, char *buf); @@ -152,23 +162,22 @@ */ int ubi_volume_notify(struct ubi_device *ubi, struct ubi_volume *vol, int ntype) { + int ret; struct ubi_notification nt; ubi_do_get_device_info(ubi, &nt.di); ubi_do_get_volume_info(ubi, vol, &nt.vi); -#ifdef CONFIG_MTD_UBI_FASTMAP switch (ntype) { case UBI_VOLUME_ADDED: case UBI_VOLUME_REMOVED: case UBI_VOLUME_RESIZED: case UBI_VOLUME_RENAMED: - if (ubi_update_fastmap(ubi)) { - ubi_err("Unable to update fastmap!"); - ubi_ro_mode(ubi); - } + ret = ubi_update_fastmap(ubi); + if (ret) + ubi_msg(ubi, "Unable to write a new fastmap: %i", ret); } -#endif + return blocking_notifier_call_chain(&ubi_notifiers, ntype, &nt); } @@ -383,6 +392,22 @@ return ret; } +static struct attribute *ubi_dev_attrs[] = { + &dev_eraseblock_size.attr, + &dev_avail_eraseblocks.attr, + &dev_total_eraseblocks.attr, + &dev_volumes_count.attr, + &dev_max_ec.attr, + &dev_reserved_for_bad.attr, + &dev_bad_peb_count.attr, + &dev_max_vol_count.attr, + &dev_min_io_size.attr, + &dev_bgt_enabled.attr, + &dev_mtd_num.attr, + NULL +}; +ATTRIBUTE_GROUPS(ubi_dev); + static void dev_release(struct device *dev) { struct ubi_device *ubi = container_of(dev, struct ubi_device, dev); @@ -405,45 +430,15 @@ ubi->dev.release = dev_release; ubi->dev.devt = ubi->cdev.dev; - ubi->dev.class = ubi_class; + ubi->dev.class = &ubi_class; + ubi->dev.groups = ubi_dev_groups; dev_set_name(&ubi->dev, UBI_NAME_STR"%d", ubi->ubi_num); err = device_register(&ubi->dev); if (err) return err; *ref = 1; - err = device_create_file(&ubi->dev, &dev_eraseblock_size); - if (err) - return err; - err = device_create_file(&ubi->dev, &dev_avail_eraseblocks); - if (err) - return err; - err = device_create_file(&ubi->dev, &dev_total_eraseblocks); - if (err) - return err; - err = device_create_file(&ubi->dev, &dev_volumes_count); - if (err) - return err; - err = device_create_file(&ubi->dev, &dev_max_ec); - if (err) - return err; - err = device_create_file(&ubi->dev, &dev_reserved_for_bad); - if (err) - return err; - err = device_create_file(&ubi->dev, &dev_bad_peb_count); - if (err) - return err; - err = device_create_file(&ubi->dev, &dev_max_vol_count); - if (err) - return err; - err = device_create_file(&ubi->dev, &dev_min_io_size); - if (err) - return err; - err = device_create_file(&ubi->dev, &dev_bgt_enabled); - if (err) - return err; - err = device_create_file(&ubi->dev, &dev_mtd_num); - return err; + return 0; } /** @@ -452,17 +447,6 @@ */ static void ubi_sysfs_close(struct ubi_device *ubi) { - device_remove_file(&ubi->dev, &dev_mtd_num); - device_remove_file(&ubi->dev, &dev_bgt_enabled); - device_remove_file(&ubi->dev, &dev_min_io_size); - device_remove_file(&ubi->dev, &dev_max_vol_count); - device_remove_file(&ubi->dev, &dev_bad_peb_count); - device_remove_file(&ubi->dev, &dev_reserved_for_bad); - device_remove_file(&ubi->dev, &dev_max_ec); - device_remove_file(&ubi->dev, &dev_volumes_count); - device_remove_file(&ubi->dev, &dev_total_eraseblocks); - device_remove_file(&ubi->dev, &dev_avail_eraseblocks); - device_remove_file(&ubi->dev, &dev_eraseblock_size); device_unregister(&ubi->dev); } @@ -515,7 +499,7 @@ */ err = alloc_chrdev_region(&dev, 0, ubi->vtbl_slots + 1, ubi->ubi_name); if (err) { - ubi_err("cannot register UBI character devices"); + ubi_err(ubi, "cannot register UBI character devices"); return err; } @@ -526,7 +510,7 @@ err = cdev_add(&ubi->cdev, dev, 1); if (err) { - ubi_err("cannot add character device"); + ubi_err(ubi, "cannot add character device"); goto out_unreg; } @@ -538,7 +522,7 @@ if (ubi->volumes[i]) { err = ubi_add_volume(ubi, ubi->volumes[i]); if (err) { - ubi_err("cannot add volume %d", i); + ubi_err(ubi, "cannot add volume %d", i); goto out_volumes; } } @@ -554,7 +538,8 @@ cdev_del(&ubi->cdev); out_unreg: unregister_chrdev_region(ubi->cdev.dev, ubi->vtbl_slots + 1); - ubi_err("cannot initialize UBI %s, error %d", ubi->ubi_name, err); + ubi_err(ubi, "cannot initialize UBI %s, error %d", + ubi->ubi_name, err); return err; } @@ -648,7 +633,7 @@ * guess we should just pick the largest region. But this is * not implemented. */ - ubi_err("multiple regions, not implemented"); + ubi_err(ubi, "multiple regions, not implemented"); return -EINVAL; } @@ -683,7 +668,7 @@ * which allows us to avoid costly division operations. */ if (!is_power_of_2(ubi->min_io_size)) { - ubi_err("min. I/O unit (%d) is not power of 2", + ubi_err(ubi, "min. I/O unit (%d) is not power of 2", ubi->min_io_size); return -EINVAL; } @@ -700,7 +685,7 @@ if (ubi->max_write_size < ubi->min_io_size || ubi->max_write_size % ubi->min_io_size || !is_power_of_2(ubi->max_write_size)) { - ubi_err("bad write buffer size %d for %d min. I/O unit", + ubi_err(ubi, "bad write buffer size %d for %d min. I/O unit", ubi->max_write_size, ubi->min_io_size); return -EINVAL; } @@ -737,7 +722,7 @@ /* The shift must be aligned to 32-bit boundary */ if (ubi->vid_hdr_shift % 4) { - ubi_err("unaligned VID header shift %d", + ubi_err(ubi, "unaligned VID header shift %d", ubi->vid_hdr_shift); return -EINVAL; } @@ -747,7 +732,7 @@ ubi->leb_start < ubi->vid_hdr_offset + UBI_VID_HDR_SIZE || ubi->leb_start > ubi->peb_size - UBI_VID_HDR_SIZE || ubi->leb_start & (ubi->min_io_size - 1)) { - ubi_err("bad VID header (%d) or data offsets (%d)", + ubi_err(ubi, "bad VID header (%d) or data offsets (%d)", ubi->vid_hdr_offset, ubi->leb_start); return -EINVAL; } @@ -767,14 +752,14 @@ * 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(ubi, "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_msg(ubi, "MTD device %d is write-protected, attach in read-only mode", ubi->mtd->index); ubi->ro_mode = 1; } @@ -807,7 +792,7 @@ int err, old_reserved_pebs = vol->reserved_pebs; if (ubi->ro_mode) { - ubi_warn("skip auto-resize because of R/O mode"); + ubi_warn(ubi, "skip auto-resize because of R/O mode"); return 0; } @@ -816,7 +801,8 @@ * volume table, and 'ubi_resize_volume()' will propagate this change * to the flash. */ - ubi->vtbl[vol_id].flags &= ~UBI_VTBL_AUTORESIZE_FLG; + ubi->vtbl[vol_id].flags &= ~(UBI_VTBL_AUTORESIZE_FLG | + UBI_VTBL_AUTORESIZE_FLG_LINUX); if (ubi->avail_pebs == 0) { struct ubi_vtbl_record vtbl_rec; @@ -828,21 +814,22 @@ vtbl_rec = ubi->vtbl[vol_id]; err = ubi_change_vtbl_record(ubi, vol_id, &vtbl_rec); if (err) - ubi_err("cannot clean auto-resize flag for volume %d", + ubi_err(ubi, "cannot clean auto-resize flag for volume %d", vol_id); } else { desc.vol = vol; err = ubi_resize_volume(&desc, old_reserved_pebs + ubi->avail_pebs); if (err) - ubi_err("cannot auto-resize volume %d", vol_id); + ubi_err(ubi, "cannot auto-resize volume %d", + vol_id); } if (err) return err; - ubi_msg("volume %d (\"%s\") re-sized from %d to %d LEBs", vol_id, - vol->name, old_reserved_pebs, vol->reserved_pebs); + ubi_msg(ubi, "volume %d (\"%s\") re-sized from %d to %d LEBs", + vol_id, vol->name, old_reserved_pebs, vol->reserved_pebs); return 0; } @@ -883,7 +870,7 @@ for (i = 0; i < UBI_MAX_DEVICES; i++) { ubi = ubi_devices[i]; if (ubi && mtd->index == ubi->mtd->index) { - ubi_err("mtd%d is already attached to ubi%d", + pr_err("ubi: mtd%d is already attached to ubi%d", mtd->index, i); return -EEXIST; } @@ -898,7 +885,7 @@ * 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", + pr_err("ubi: refuse attaching mtd%d - it is already emulated on top of UBI", mtd->index); return -EINVAL; } @@ -909,7 +896,7 @@ if (!ubi_devices[ubi_num]) break; if (ubi_num == UBI_MAX_DEVICES) { - ubi_err("only %d UBI devices may be created", + pr_err("ubi: only %d UBI devices may be created", UBI_MAX_DEVICES); return -ENFILE; } @@ -919,7 +906,7 @@ /* Make sure ubi_num is not busy */ if (ubi_devices[ubi_num]) { - ubi_err("ubi%d already exists", ubi_num); + pr_err("ubi: ubi%i already exists", ubi_num); return -EEXIST; } } @@ -943,21 +930,24 @@ */ ubi->fm_pool.max_size = min(((int)mtd_div_by_eb(ubi->mtd->size, ubi->mtd) / 100) * 5, UBI_FM_MAX_POOL_SIZE); - if (ubi->fm_pool.max_size < UBI_FM_MIN_POOL_SIZE) - ubi->fm_pool.max_size = UBI_FM_MIN_POOL_SIZE; + ubi->fm_pool.max_size = max(ubi->fm_pool.max_size, + UBI_FM_MIN_POOL_SIZE); - ubi->fm_wl_pool.max_size = UBI_FM_WL_POOL_SIZE; + ubi->fm_wl_pool.max_size = ubi->fm_pool.max_size / 2; ubi->fm_disabled = !fm_autoconvert; + if (fm_debug) + ubi_enable_dbg_chk_fastmap(ubi); if (!ubi->fm_disabled && (int)mtd_div_by_eb(ubi->mtd->size, ubi->mtd) <= UBI_FM_MAX_START) { - ubi_err("More than %i PEBs are needed for fastmap, sorry.", + ubi_err(ubi, "More than %i PEBs are needed for fastmap, sorry.", UBI_FM_MAX_START); ubi->fm_disabled = 1; } - ubi_msg("default fastmap pool size: %d", ubi->fm_pool.max_size); - ubi_msg("default fastmap WL pool size: %d", ubi->fm_wl_pool.max_size); + ubi_msg(ubi, "default fastmap pool size: %d", ubi->fm_pool.max_size); + ubi_msg(ubi, "default fastmap WL pool size: %d", + ubi->fm_wl_pool.max_size); #else ubi->fm_disabled = 1; #endif @@ -965,10 +955,10 @@ mutex_init(&ubi->ckvol_mutex); mutex_init(&ubi->device_mutex); spin_lock_init(&ubi->volumes_lock); - mutex_init(&ubi->fm_mutex); - init_rwsem(&ubi->fm_sem); + init_rwsem(&ubi->fm_protect); + init_rwsem(&ubi->fm_eba_sem); - ubi_msg("attaching mtd%d to ubi%d", mtd->index, ubi_num); + ubi_msg(ubi, "attaching mtd%d", mtd->index); err = io_init(ubi, max_beb_per1024); if (err) @@ -987,7 +977,8 @@ #endif err = ubi_attach(ubi, 0); if (err) { - ubi_err("failed to attach mtd%d, error %d", mtd->index, err); + ubi_err(ubi, "failed to attach mtd%d, error %d", + mtd->index, err); goto out_free; } @@ -1008,31 +999,31 @@ if (err) goto out_uif; - ubi->bgt_thread = kthread_create(ubi_thread, ubi, ubi->bgt_name); + ubi->bgt_thread = kthread_create(ubi_thread, ubi, "%s", ubi->bgt_name); if (IS_ERR(ubi->bgt_thread)) { err = PTR_ERR(ubi->bgt_thread); - ubi_err("cannot spawn \"%s\", error %d", ubi->bgt_name, - err); + ubi_err(ubi, "cannot spawn \"%s\", error %d", + ubi->bgt_name, err); goto out_debugfs; } - 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_msg(ubi, "attached mtd%d (name \"%s\", size %llu MiB)", + mtd->index, mtd->name, ubi->flash_size >> 20); + ubi_msg(ubi, "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_msg(ubi, "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_msg(ubi, "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_msg(ubi, "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_msg(ubi, "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_msg(ubi, "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_msg(ubi, "available PEBs: %d, total reserved PEBs: %d, PEBs reserved for bad PEB handling: %d", ubi->avail_pebs, ubi->rsvd_pebs, ubi->beb_rsvd_pebs); /* @@ -1101,7 +1092,7 @@ return -EBUSY; } /* This may only happen if there is a bug */ - ubi_err("%s reference count %d, destroy anyway", + ubi_err(ubi, "%s reference count %d, destroy anyway", ubi->ubi_name, ubi->ref_count); } ubi_devices[ubi_num] = NULL; @@ -1109,11 +1100,14 @@ ubi_assert(ubi_num == ubi->ubi_num); ubi_notify_all(ubi, UBI_VOLUME_REMOVED, NULL); - ubi_msg("detaching mtd%d from ubi%d", ubi->mtd->index, ubi_num); + ubi_msg(ubi, "detaching mtd%d", ubi->mtd->index); #ifdef CONFIG_MTD_UBI_FASTMAP /* If we don't write a new fastmap at detach time we lose all - * EC updates that have been made since the last written fastmap. */ - ubi_update_fastmap(ubi); + * EC updates that have been made since the last written fastmap. + * In case of fastmap debugging we omit the update to simulate an + * unclean shutdown. */ + if (!ubi_dbg_chk_fastmap(ubi)) + ubi_update_fastmap(ubi); #endif /* * Before freeing anything, we have to stop the background thread to @@ -1137,7 +1131,7 @@ put_mtd_device(ubi->mtd); vfree(ubi->peb_buf); vfree(ubi->fm_buf); - ubi_msg("mtd%d is detached from ubi%d", ubi->mtd->index, ubi->ubi_num); + ubi_msg(ubi, "mtd%d is detached", ubi->mtd->index); put_device(&ubi->dev); return 0; } @@ -1161,9 +1155,9 @@ return ERR_PTR(err); /* MTD device number is defined by the major / minor numbers */ - major = imajor(path.dentry->d_inode); - minor = iminor(path.dentry->d_inode); - mode = path.dentry->d_inode->i_mode; + major = imajor(d_backing_inode(path.dentry)); + minor = iminor(d_backing_inode(path.dentry)); + mode = d_backing_inode(path.dentry)->i_mode; path_put(&path); if (major != MTD_CHAR_MAJOR || !S_ISCHR(mode)) return ERR_PTR(-EINVAL); @@ -1210,6 +1204,49 @@ return mtd; } +/* + * This function tries attaching mtd partitions named either "ubi" or "data" + * during boot. + */ +static void __init ubi_auto_attach(void) +{ + int err; + struct mtd_info *mtd; + + /* try attaching mtd device named "ubi" or "data" */ + mtd = open_mtd_device("ubi"); + if (IS_ERR(mtd)) + mtd = open_mtd_device("data"); + + if (!IS_ERR(mtd)) { + size_t len; + char magic[4]; + + /* check for a valid ubi magic */ + err = mtd_read(mtd, 0, 4, &len, (void *) magic); + if (!err && len == 4 && strncmp(magic, "UBI#", 4)) { + pr_err("UBI error: no valid UBI magic found inside mtd%d", mtd->index); + put_mtd_device(mtd); + return; + } + + /* auto-add only media types where UBI makes sense */ + if (mtd->type == MTD_NANDFLASH || + mtd->type == MTD_NORFLASH || + mtd->type == MTD_DATAFLASH || + mtd->type == MTD_MLCNANDFLASH) { + mutex_lock(&ubi_devices_mutex); + pr_notice("UBI: auto-attach mtd%d", mtd->index); + err = ubi_attach_mtd_dev(mtd, UBI_DEV_NUM_AUTO, 0, 0); + mutex_unlock(&ubi_devices_mutex); + if (err < 0) { + pr_err("UBI error: cannot attach mtd%d", mtd->index); + put_mtd_device(mtd); + } + } + } +} + static int __init ubi_init(void) { int err, i, k; @@ -1219,35 +1256,29 @@ BUILD_BUG_ON(sizeof(struct ubi_vid_hdr) != 64); if (mtd_devs > UBI_MAX_DEVICES) { - ubi_err("too many MTD devices, maximum is %d", UBI_MAX_DEVICES); + pr_err("UBI error: too many MTD devices, maximum is %d", + UBI_MAX_DEVICES); return -EINVAL; } /* Create base sysfs directory and sysfs files */ - ubi_class = class_create(THIS_MODULE, UBI_NAME_STR); - if (IS_ERR(ubi_class)) { - err = PTR_ERR(ubi_class); - ubi_err("cannot create UBI class"); - goto out; - } - - err = class_create_file(ubi_class, &ubi_version); - if (err) { - ubi_err("cannot create sysfs file"); - goto out_class; - } + err = class_register(&ubi_class); + if (err < 0) + return err; err = misc_register(&ubi_ctrl_cdev); if (err) { - ubi_err("cannot register device"); - goto out_version; + pr_err("UBI error: cannot register device"); + goto out; } ubi_wl_entry_slab = kmem_cache_create("ubi_wl_entry_slab", sizeof(struct ubi_wl_entry), 0, 0, NULL); - if (!ubi_wl_entry_slab) + if (!ubi_wl_entry_slab) { + err = -ENOMEM; goto out_dev_unreg; + } err = ubi_debugfs_init(); if (err) @@ -1264,15 +1295,21 @@ mtd = open_mtd_device(p->name); if (IS_ERR(mtd)) { err = PTR_ERR(mtd); - goto out_detach; + pr_err("UBI error: cannot open mtd %s, error %d", + p->name, err); + /* See comment below re-ubi_is_module(). */ + if (ubi_is_module()) + goto out_detach; + continue; } mutex_lock(&ubi_devices_mutex); - err = ubi_attach_mtd_dev(mtd, UBI_DEV_NUM_AUTO, + err = ubi_attach_mtd_dev(mtd, p->ubi_num, p->vid_hdr_offs, p->max_beb_per1024); mutex_unlock(&ubi_devices_mutex); if (err < 0) { - ubi_err("cannot attach mtd%d", mtd->index); + pr_err("UBI error: cannot attach mtd%d", + mtd->index); put_mtd_device(mtd); /* @@ -1293,6 +1330,21 @@ } } + /* auto-attach mtd devices only if built-in to the kernel and no ubi.mtd + * parameter was given */ + if (config_enabled(CONFIG_MTD_ROOTFS_ROOT_DEV) && + !ubi_is_module() && !mtd_devs) + ubi_auto_attach(); + + err = ubiblock_init(); + if (err) { + pr_err("UBI error: block: cannot initialize, error %d", err); + + /* See comment above re-ubi_is_module(). */ + if (ubi_is_module()) + goto out_detach; + } + return 0; out_detach: @@ -1307,12 +1359,9 @@ kmem_cache_destroy(ubi_wl_entry_slab); out_dev_unreg: misc_deregister(&ubi_ctrl_cdev); -out_version: - class_remove_file(ubi_class, &ubi_version); -out_class: - class_destroy(ubi_class); out: - ubi_err("UBI error: cannot initialize UBI, error %d", err); + class_unregister(&ubi_class); + pr_err("UBI error: cannot initialize UBI, error %d", err); return err; } late_initcall(ubi_init); @@ -1321,6 +1370,8 @@ { int i; + ubiblock_exit(); + for (i = 0; i < UBI_MAX_DEVICES; i++) if (ubi_devices[i]) { mutex_lock(&ubi_devices_mutex); @@ -1330,8 +1381,7 @@ ubi_debugfs_exit(); kmem_cache_destroy(ubi_wl_entry_slab); misc_deregister(&ubi_ctrl_cdev); - class_remove_file(ubi_class, &ubi_version); - class_destroy(ubi_class); + class_unregister(&ubi_class); } module_exit(ubi_exit); @@ -1349,7 +1399,7 @@ result = simple_strtoul(str, &endp, 0); if (str == endp || result >= INT_MAX) { - ubi_err("UBI error: incorrect bytes count: \"%s\"\n", str); + pr_err("UBI error: incorrect bytes count: \"%s\"\n", str); return -EINVAL; } @@ -1365,7 +1415,7 @@ case '\0': break; default: - ubi_err("UBI error: incorrect bytes count: \"%s\"\n", str); + pr_err("UBI error: incorrect bytes count: \"%s\"\n", str); return -EINVAL; } @@ -1380,27 +1430,31 @@ * This function returns zero in case of success and a negative error code in * case of error. */ +#if ! defined(CONFIG_AVM_ENHANCED) static int __init ubi_mtd_param_parse(const char *val, struct kernel_param *kp) +#else +int __init ubi_mtd_param_parse(const char *val, struct kernel_param *kp) +#endif { int i, len; struct mtd_dev_param *p; char buf[MTD_PARAM_LEN_MAX]; char *pbuf = &buf[0]; - char *tokens[MTD_PARAM_MAX_COUNT]; + char *tokens[MTD_PARAM_MAX_COUNT], *token; if (!val) return -EINVAL; if (mtd_devs == UBI_MAX_DEVICES) { - ubi_err("UBI error: too many parameters, max. is %d\n", - UBI_MAX_DEVICES); + pr_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) { - ubi_err("UBI error: parameter \"%s\" is too long, max. is %d\n", - val, MTD_PARAM_LEN_MAX); + pr_err("UBI error: parameter \"%s\" is too long, max. is %d\n", + val, MTD_PARAM_LEN_MAX); return -EINVAL; } @@ -1419,48 +1473,67 @@ tokens[i] = strsep(&pbuf, ","); if (pbuf) { - ubi_err("UBI error: too many arguments at \"%s\"\n", val); + pr_err("UBI error: too many arguments at \"%s\"\n", val); return -EINVAL; } p = &mtd_dev_param[mtd_devs]; strcpy(&p->name[0], tokens[0]); - if (tokens[1]) - p->vid_hdr_offs = bytes_str_to_int(tokens[1]); + token = tokens[1]; + if (token) { + p->vid_hdr_offs = bytes_str_to_int(token); - if (p->vid_hdr_offs < 0) - return p->vid_hdr_offs; + if (p->vid_hdr_offs < 0) + return p->vid_hdr_offs; + } - if (tokens[2]) { - int err = kstrtoint(tokens[2], 10, &p->max_beb_per1024); + token = tokens[2]; + if (token) { + int err = kstrtoint(token, 10, &p->max_beb_per1024); if (err) { - ubi_err("UBI error: bad value for max_beb_per1024 parameter: %s", - tokens[2]); + pr_err("UBI error: bad value for max_beb_per1024 parameter: %s", + token); return -EINVAL; } } + token = tokens[3]; + if (token) { + int err = kstrtoint(token, 10, &p->ubi_num); + + if (err) { + pr_err("UBI error: bad value for ubi_num parameter: %s", + token); + return -EINVAL; + } + } else + p->ubi_num = UBI_DEV_NUM_AUTO; + 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=[,[,max_beb_per1024]].\n" +MODULE_PARM_DESC(mtd, "MTD devices to attach. Parameter format: mtd=[,[,max_beb_per1024[,ubi_num]]].\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. (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" + "Optional \"ubi_num\" parameter specifies UBI device number which have to be assigned to the newly created UBI device (assigned automatically by default)\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" + "Example 4: mtd=/dev/mtd1,0,0,5 - attach MTD device /dev/mtd1 to UBI 5 and using default values for the other fields.\n" "\t(e.g. if the NAND *chipset* has 4096 PEB, 100 will be reserved for this UBI device)."); #ifdef CONFIG_MTD_UBI_FASTMAP module_param(fm_autoconvert, bool, 0644); MODULE_PARM_DESC(fm_autoconvert, "Set this parameter to enable fastmap automatically on images without a fastmap."); +module_param(fm_debug, bool, 0); +MODULE_PARM_DESC(fm_debug, "Set this parameter to enable fastmap debugging by default. Warning, this will make fastmap slow!"); #endif MODULE_VERSION(__stringify(UBI_VERSION)); MODULE_DESCRIPTION("UBI - Unsorted Block Images");