int erased_chunks;
int checkpt_block_adjust;
- if (dev->param.gc_control && (dev->param.gc_control(dev) & 1) == 0)
+ if (dev->param.gc_control_fn &&
+ (dev->param.gc_control_fn(dev) & 1) == 0)
return YAFFS_OK;
if (dev->gc_disable)
struct yaffs_param *param = &dev->param;
/* Common functions, gotta have */
- if (!param->drv_initialise_fn ||
- !param->drv_read_chunk_fn ||
+ if (!param->drv_read_chunk_fn ||
!param->drv_write_chunk_fn ||
!param->drv_erase_fn)
return 0;
+ if (param->is_yaffs2 &&
+ (!param->drv_mark_bad_fn || !param->drv_check_bad_fn))
+ return 0;
+
/* Install the default tags marshalling functions if needed. */
yaffs_tags_compat_install(dev);
yaffs_tags_marshall_install(dev);
dev->is_mounted = 0;
- if (dev->param.drv_deinitialise_fn)
- dev->param.drv_deinitialise_fn(dev);
+ yaffs_deinit_nand(dev);
}
}
void (*sb_dirty_fn) (struct yaffs_dev *dev);
/* Callback to control garbage collection. */
- unsigned (*gc_control) (struct yaffs_dev *dev);
+ unsigned (*gc_control_fn) (struct yaffs_dev *dev);
/* Debug control flags. Don't use unless you know what you're doing */
int use_header_file_size; /* Flag to determine if we should use
* at compile time so we have to allocate it.
*/
struct list_head search_contexts;
- void (*put_super_fn) (struct super_block *sb);
-
struct task_struct *readdir_process;
unsigned mount_id;
};
return dev->param.drv_initialise_fn(dev);
return YAFFS_OK;
}
+
+int yaffs_deinit_nand(struct yaffs_dev *dev)
+{
+ if (dev->param.drv_deinitialise_fn)
+ return dev->param.drv_deinitialise_fn(dev);
+ return YAFFS_OK;
+}
int yaffs_erase_block(struct yaffs_dev *dev, int flash_block);
int yaffs_init_nand(struct yaffs_dev *dev);
+int yaffs_deinit_nand(struct yaffs_dev *dev);
#endif
static void yaffs_put_super(struct super_block *sb)
{
struct yaffs_dev *dev = yaffs_super_to_dev(sb);
+ struct mtd_info *mtd = yaffs_dev_to_mtd(dev);
- yaffs_trace(YAFFS_TRACE_OS, "yaffs_put_super");
+ yaffs_trace(YAFFS_TRACE_OS | YAFFS_TRACE_ALWAYS,
+ "yaffs_put_super");
yaffs_trace(YAFFS_TRACE_OS | YAFFS_TRACE_BACKGROUND,
"Shutting down yaffs background thread");
yaffs_flush_super(sb, 1);
- if (yaffs_dev_to_lc(dev)->put_super_fn)
- yaffs_dev_to_lc(dev)->put_super_fn(sb);
-
yaffs_deinitialise(dev);
yaffs_gross_unlock(dev);
}
kfree(dev);
-}
-
-static void yaffs_mtd_put_super(struct super_block *sb)
-{
- struct mtd_info *mtd = yaffs_dev_to_mtd(yaffs_super_to_dev(sb));
- if (mtd->sync)
+ if (mtd && mtd->sync)
mtd->sync(mtd);
- put_mtd_device(mtd);
+ if(mtd)
+ put_mtd_device(mtd);
+
+ yaffs_trace(YAFFS_TRACE_OS | YAFFS_TRACE_ALWAYS,
+ "yaffs_put_super done");
}
+
static void yaffs_touch_super(struct yaffs_dev *dev)
{
struct super_block *sb = yaffs_dev_to_lc(dev)->super;
yaffs_mtd_drv_install(dev);
- yaffs_dev_to_lc(dev)->put_super_fn = yaffs_mtd_put_super;
-
param->sb_dirty_fn = yaffs_touch_super;
- param->gc_control = yaffs_gc_control_callback;
+ param->gc_control_fn = yaffs_gc_control_callback;
yaffs_dev_to_lc(dev)->super = sb;
static void yaffs_put_super(struct super_block *sb)
{
struct yaffs_dev *dev = yaffs_super_to_dev(sb);
+ struct mtd_info *mtd = yaffs_dev_to_mtd(dev);
yaffs_trace(YAFFS_TRACE_OS, "yaffs_put_super");
}
kfree(dev);
-}
-static void yaffs_mtd_put_super(struct super_block *sb)
-{
- struct mtd_info *mtd = yaffs_dev_to_mtd(yaffs_super_to_dev(sb));
- if (mtd->sync)
+
+ if (mtd && mtd->sync)
mtd->sync(mtd);
- put_mtd_device(mtd);
+ if (mtd)
+ put_mtd_device(mtd);
}
static const struct super_operations yaffs_super_ops = {
yaffs_dev_to_lc(dev)->put_super_fn = yaffs_mtd_put_super;
param->sb_dirty_fn = yaffs_touch_super;
- param->gc_control = yaffs_gc_control_callback;
+ param->gc_control_fn = yaffs_gc_control_callback;
yaffs_dev_to_lc(dev)->super = sb;