ubi_free_volume(ubi, ubi->volumes[i]);
}
+/**
+ * free_user_volumes - free all user volumes.
+ * @ubi: UBI device description object
+ *
+ * Normally the volumes are freed at the release function of the volume device
+ * objects. However, on error paths the volumes have to be freed before the
+ * device objects have been initialized.
+ */
+static void free_user_volumes(struct ubi_device *ubi)
+{
+ int i;
+
+ for (i = 0; i < ubi->vtbl_slots; i++)
+ if (ubi->volumes[i]) {
+ kfree(ubi->volumes[i]->eba_tbl);
+ kfree(ubi->volumes[i]);
+ }
+}
+
/**
* uif_init - initialize user interfaces for an UBI device.
* @ubi: UBI device description object
*
* This function returns zero in case of success and a negative error code in
- * case of failure.
+ * case of failure. Note, this function destroys all volumes if it failes.
*/
static int uif_init(struct ubi_device *ubi)
{
- int i, err;
+ int i, err, do_free = 0;
dev_t dev;
sprintf(ubi->ubi_name, UBI_NAME_STR "%d", ubi->ubi_num);
out_volumes:
kill_volumes(ubi);
+ do_free = 0;
out_sysfs:
ubi_sysfs_close(ubi);
cdev_del(&ubi->cdev);
out_unreg:
+ if (do_free)
+ free_user_volumes(ubi);
unregister_chrdev_region(ubi->cdev.dev, ubi->vtbl_slots + 1);
ubi_err("cannot initialize UBI %s, error %d", ubi->ubi_name, err);
return err;
/**
* uif_close - close user interfaces for an UBI device.
* @ubi: UBI device description object
+ *
+ * Note, since this function un-registers UBI volume device objects (@vol->dev),
+ * the memory allocated voe the volumes is freed as well (in the release
+ * function).
*/
static void uif_close(struct ubi_device *ubi)
{
unregister_chrdev_region(ubi->cdev.dev, ubi->vtbl_slots + 1);
}
+/**
+ * free_internal_volumes - free internal volumes.
+ * @ubi: UBI device description object
+ */
+static void free_internal_volumes(struct ubi_device *ubi)
+{
+ int i;
+
+ for (i = ubi->vtbl_slots;
+ i < ubi->vtbl_slots + UBI_INT_VOL_COUNT; i++) {
+ kfree(ubi->volumes[i]->eba_tbl);
+ kfree(ubi->volumes[i]);
+ }
+}
+
/**
* attach_by_scanning - attach an MTD device using scanning method.
* @ubi: UBI device descriptor
out_wl:
ubi_wl_close(ubi);
out_vtbl:
+ free_internal_volumes(ubi);
vfree(ubi->vtbl);
out_si:
ubi_scan_destroy_si(si);
ubi->min_io_size = ubi->mtd->writesize;
ubi->hdrs_min_io_size = ubi->mtd->writesize >> ubi->mtd->subpage_sft;
- /* Make sure minimal I/O unit is power of 2 */
+ /*
+ * Make sure minimal I/O unit is power of 2. Note, there is no
+ * fundamental reason for this assumption. It is just an optimization
+ * 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->min_io_size);
if (ubi->vid_hdr_offset < UBI_EC_HDR_SIZE ||
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) {
+ ubi->leb_start & (ubi->min_io_size - 1)) {
ubi_err("bad VID header (%d) or data offsets (%d)",
ubi->vid_hdr_offset, ubi->leb_start);
return -EINVAL;
ubi->ro_mode = 1;
}
- dbg_msg("leb_size %d", ubi->leb_size);
- dbg_msg("ro_mode %d", ubi->ro_mode);
+ 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
/*
* Clear the auto-resize flag in the volume in-memory copy of the
- * volume table, and 'ubi_resize_volume()' will propogate this change
+ * volume table, and 'ubi_resize_volume()' will propagate this change
* to the flash.
*/
ubi->vtbl[vol_id].flags &= ~UBI_VTBL_AUTORESIZE_FLG;
struct ubi_vtbl_record vtbl_rec;
/*
- * No avalilable PEBs to re-size the volume, clear the flag on
+ * No available PEBs to re-size the volume, clear the flag on
* flash and exit.
*/
memcpy(&vtbl_rec, &ubi->vtbl[vol_id],
*
* 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
- * which case this function finds a vacant device nubert and assings it
+ * which case this function finds a vacant device number and assigns it
* automatically. Returns the new UBI device number in case of success and a
* negative error code in case of failure.
*
int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset)
{
struct ubi_device *ubi;
- int i, err;
+ int i, err, do_free = 1;
/*
* Check if we already have the same MTD device attached.
mutex_init(&ubi->volumes_mutex);
spin_lock_init(&ubi->volumes_lock);
- dbg_msg("attaching mtd%d to ubi%d: VID header offset %d",
- mtd->index, ubi_num, vid_hdr_offset);
+ ubi_msg("attaching mtd%d to ubi%d", mtd->index, ubi_num);
err = io_init(ubi);
if (err)
err = uif_init(ubi);
if (err)
- goto out_detach;
+ goto out_nofree;
ubi->bgt_thread = kthread_create(ubi_thread, ubi, ubi->bgt_name);
if (IS_ERR(ubi->bgt_thread)) {
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("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("number of good PEBs: %d", ubi->good_peb_count);
ubi_msg("number of bad PEBs: %d", ubi->bad_peb_count);
- ubi_msg("smallest flash I/O unit: %d", ubi->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);
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);
out_uif:
uif_close(ubi);
+out_nofree:
+ do_free = 0;
out_detach:
- ubi_eba_close(ubi);
ubi_wl_close(ubi);
+ if (do_free)
+ free_user_volumes(ubi);
+ free_internal_volumes(ubi);
vfree(ubi->vtbl);
out_free:
vfree(ubi->peb_buf1);
kthread_stop(ubi->bgt_thread);
uif_close(ubi);
- ubi_eba_close(ubi);
ubi_wl_close(ubi);
+ free_internal_volumes(ubi);
vfree(ubi->vtbl);
put_mtd_device(ubi->mtd);
vfree(ubi->peb_buf1);
BUILD_BUG_ON(sizeof(struct ubi_vid_hdr) != 64);
if (mtd_devs > UBI_MAX_DEVICES) {
- printk(KERN_ERR "UBI error: too many MTD devices, "
- "maximum is %d\n", UBI_MAX_DEVICES);
+ ubi_err("too many MTD devices, maximum is %d", UBI_MAX_DEVICES);
return -EINVAL;
}
ubi_class = class_create(THIS_MODULE, UBI_NAME_STR);
if (IS_ERR(ubi_class)) {
err = PTR_ERR(ubi_class);
- printk(KERN_ERR "UBI error: cannot create UBI class\n");
+ ubi_err("cannot create UBI class");
goto out;
}
err = class_create_file(ubi_class, &ubi_version);
if (err) {
- printk(KERN_ERR "UBI error: cannot create sysfs file\n");
+ ubi_err("cannot create sysfs file");
goto out_class;
}
err = misc_register(&ubi_ctrl_cdev);
if (err) {
- printk(KERN_ERR "UBI error: cannot register device\n");
+ ubi_err("cannot register device");
goto out_version;
}
ubi_wl_entry_slab = kmem_cache_create("ubi_wl_entry_slab",
- sizeof(struct ubi_wl_entry),
- 0, 0, NULL);
+ sizeof(struct ubi_wl_entry),
+ 0, 0, NULL);
if (!ubi_wl_entry_slab)
goto out_dev_unreg;
mutex_unlock(&ubi_devices_mutex);
if (err < 0) {
put_mtd_device(mtd);
- printk(KERN_ERR "UBI error: cannot attach mtd%d\n",
- mtd->index);
+ ubi_err("cannot attach mtd%d", mtd->index);
goto out_detach;
}
}
out_class:
class_destroy(ubi_class);
out:
- printk(KERN_ERR "UBI error: cannot initialize UBI, error %d\n", err);
+ ubi_err("UBI error: cannot initialize UBI, error %d", err);
return err;
}
module_init(ubi_init);