Merge branch 'devicetree/next' of git://git.secretlab.ca/git/linux-2.6
[pandora-kernel.git] / drivers / mtd / ubi / build.c
index 5ebe280..6c3fb5a 100644 (file)
@@ -690,11 +690,25 @@ static int io_init(struct ubi_device *ubi)
        ubi_assert(ubi->hdrs_min_io_size <= ubi->min_io_size);
        ubi_assert(ubi->min_io_size % ubi->hdrs_min_io_size == 0);
 
+       ubi->max_write_size = ubi->mtd->writebufsize;
+       /*
+        * Maximum write size has to be greater or equivalent to min. I/O
+        * size, and be multiple of min. I/O size.
+        */
+       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->max_write_size, ubi->min_io_size);
+               return -EINVAL;
+       }
+
        /* Calculate default aligned sizes of EC and VID headers */
        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);
@@ -711,7 +725,7 @@ static int io_init(struct ubi_device *ubi)
        }
 
        /* Similar for the data offset */
-       ubi->leb_start = ubi->vid_hdr_offset + UBI_EC_HDR_SIZE;
+       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);
@@ -923,6 +937,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_scan_leb) %zu", sizeof(struct ubi_scan_leb));
+       dbg_msg("sizeof(struct ubi_wl_entry) %zu", sizeof(struct ubi_wl_entry));
 
        err = io_init(ubi);
        if (err)
@@ -937,17 +953,14 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset)
        if (!ubi->peb_buf2)
                goto out_free;
 
-#ifdef CONFIG_MTD_UBI_DEBUG_PARANOID
-       mutex_init(&ubi->dbg_buf_mutex);
-       ubi->dbg_peb_buf = vmalloc(ubi->peb_size);
-       if (!ubi->dbg_peb_buf)
+       err = ubi_debugging_init_dev(ubi);
+       if (err)
                goto out_free;
-#endif
 
        err = attach_by_scanning(ubi);
        if (err) {
                dbg_err("failed to attach by scanning, error %d", err);
-               goto out_free;
+               goto out_debugging;
        }
 
        if (ubi->autoresize_vol_id != -1) {
@@ -960,12 +973,16 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset)
        if (err)
                goto out_detach;
 
+       err = ubi_debugfs_init_dev(ubi);
+       if (err)
+               goto out_uif;
+
        ubi->bgt_thread = kthread_create(ubi_thread, ubi, 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);
-               goto out_uif;
+               goto out_debugfs;
        }
 
        ubi_msg("attached mtd%d to ubi%d", mtd->index, ubi_num);
@@ -991,8 +1008,7 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset)
         * checks @ubi->thread_enabled. Otherwise we may fail to wake it up.
         */
        spin_lock(&ubi->wl_lock);
-       if (!DBG_DISABLE_BGT)
-               ubi->thread_enabled = 1;
+       ubi->thread_enabled = 1;
        wake_up_process(ubi->bgt_thread);
        spin_unlock(&ubi->wl_lock);
 
@@ -1000,18 +1016,21 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset)
        ubi_notify_all(ubi, UBI_VOLUME_ADDED, NULL);
        return ubi_num;
 
+out_debugfs:
+       ubi_debugfs_exit_dev(ubi);
 out_uif:
+       get_device(&ubi->dev);
+       ubi_assert(ref);
        uif_close(ubi);
 out_detach:
        ubi_wl_close(ubi);
        free_internal_volumes(ubi);
        vfree(ubi->vtbl);
+out_debugging:
+       ubi_debugging_exit_dev(ubi);
 out_free:
        vfree(ubi->peb_buf1);
        vfree(ubi->peb_buf2);
-#ifdef CONFIG_MTD_UBI_DEBUG_PARANOID
-       vfree(ubi->dbg_peb_buf);
-#endif
        if (ref)
                put_device(&ubi->dev);
        else
@@ -1075,16 +1094,15 @@ int ubi_detach_mtd_dev(int ubi_num, int anyway)
         */
        get_device(&ubi->dev);
 
+       ubi_debugfs_exit_dev(ubi);
        uif_close(ubi);
        ubi_wl_close(ubi);
        free_internal_volumes(ubi);
        vfree(ubi->vtbl);
        put_mtd_device(ubi->mtd);
+       ubi_debugging_exit_dev(ubi);
        vfree(ubi->peb_buf1);
        vfree(ubi->peb_buf2);
-#ifdef CONFIG_MTD_UBI_DEBUG_PARANOID
-       vfree(ubi->dbg_peb_buf);
-#endif
        ubi_msg("mtd%d is detached from ubi%d", ubi->mtd->index, ubi->ubi_num);
        put_device(&ubi->dev);
        return 0;
@@ -1197,6 +1215,11 @@ static int __init ubi_init(void)
        if (!ubi_wl_entry_slab)
                goto out_dev_unreg;
 
+       err = ubi_debugfs_init();
+       if (err)
+               goto out_slab;
+
+
        /* Attach MTD devices */
        for (i = 0; i < mtd_devs; i++) {
                struct mtd_dev_param *p = &mtd_dev_param[i];
@@ -1245,6 +1268,8 @@ out_detach:
                        ubi_detach_mtd_dev(ubi_devices[k]->ubi_num, 1);
                        mutex_unlock(&ubi_devices_mutex);
                }
+       ubi_debugfs_exit();
+out_slab:
        kmem_cache_destroy(ubi_wl_entry_slab);
 out_dev_unreg:
        misc_deregister(&ubi_ctrl_cdev);
@@ -1268,6 +1293,7 @@ static void __exit ubi_exit(void)
                        ubi_detach_mtd_dev(ubi_devices[i]->ubi_num, 1);
                        mutex_unlock(&ubi_devices_mutex);
                }
+       ubi_debugfs_exit();
        kmem_cache_destroy(ubi_wl_entry_slab);
        misc_deregister(&ubi_ctrl_cdev);
        class_remove_file(ubi_class, &ubi_version);