Commit cdfa788a authored by Artem Bityutskiy's avatar Artem Bityutskiy

UBI: prepare attach and detach functions

Prepare the attach and detach functions to by used outside of
module initialization:

* detach function checks reference count before detaching
* it kills the background thread as well
Signed-off-by: default avatarArtem Bityutskiy <Artem.Bityutskiy@nokia.com>
parent e73f4459
This diff is collapsed.
...@@ -404,6 +404,7 @@ extern struct file_operations ubi_ctrl_cdev_operations; ...@@ -404,6 +404,7 @@ extern struct file_operations ubi_ctrl_cdev_operations;
extern struct file_operations ubi_cdev_operations; extern struct file_operations ubi_cdev_operations;
extern struct file_operations ubi_vol_cdev_operations; extern struct file_operations ubi_vol_cdev_operations;
extern struct class *ubi_class; extern struct class *ubi_class;
extern struct mutex ubi_devices_mutex;
/* vtbl.c */ /* vtbl.c */
int ubi_change_vtbl_record(struct ubi_device *ubi, int idx, int ubi_change_vtbl_record(struct ubi_device *ubi, int idx,
...@@ -462,6 +463,7 @@ int ubi_wl_flush(struct ubi_device *ubi); ...@@ -462,6 +463,7 @@ int ubi_wl_flush(struct ubi_device *ubi);
int ubi_wl_scrub_peb(struct ubi_device *ubi, int pnum); int ubi_wl_scrub_peb(struct ubi_device *ubi, int pnum);
int ubi_wl_init_scan(struct ubi_device *ubi, struct ubi_scan_info *si); int ubi_wl_init_scan(struct ubi_device *ubi, struct ubi_scan_info *si);
void ubi_wl_close(struct ubi_device *ubi); void ubi_wl_close(struct ubi_device *ubi);
int ubi_thread(void *u);
/* io.c */ /* io.c */
int ubi_io_read(const struct ubi_device *ubi, void *buf, int pnum, int offset, int ubi_io_read(const struct ubi_device *ubi, void *buf, int pnum, int offset,
...@@ -481,6 +483,9 @@ int ubi_io_write_vid_hdr(struct ubi_device *ubi, int pnum, ...@@ -481,6 +483,9 @@ int ubi_io_write_vid_hdr(struct ubi_device *ubi, int pnum,
struct ubi_vid_hdr *vid_hdr); struct ubi_vid_hdr *vid_hdr);
/* build.c */ /* build.c */
int ubi_attach_mtd_dev(struct mtd_info *mtd, int vid_hdr_offset,
int data_offset);
int ubi_detach_mtd_dev(int ubi_num, int anyway);
struct ubi_device *ubi_get_device(int ubi_num); struct ubi_device *ubi_get_device(int ubi_num);
void ubi_put_device(struct ubi_device *ubi); void ubi_put_device(struct ubi_device *ubi);
struct ubi_device *ubi_get_by_major(int major); struct ubi_device *ubi_get_by_major(int major);
......
...@@ -1356,7 +1356,7 @@ static void tree_destroy(struct rb_root *root) ...@@ -1356,7 +1356,7 @@ static void tree_destroy(struct rb_root *root)
* ubi_thread - UBI background thread. * ubi_thread - UBI background thread.
* @u: the UBI device description object pointer * @u: the UBI device description object pointer
*/ */
static int ubi_thread(void *u) int ubi_thread(void *u)
{ {
int failures = 0; int failures = 0;
struct ubi_device *ubi = u; struct ubi_device *ubi = u;
...@@ -1454,18 +1454,10 @@ int ubi_wl_init_scan(struct ubi_device *ubi, struct ubi_scan_info *si) ...@@ -1454,18 +1454,10 @@ int ubi_wl_init_scan(struct ubi_device *ubi, struct ubi_scan_info *si)
sprintf(ubi->bgt_name, UBI_BGT_NAME_PATTERN, ubi->ubi_num); sprintf(ubi->bgt_name, UBI_BGT_NAME_PATTERN, ubi->ubi_num);
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);
return err;
}
err = -ENOMEM; err = -ENOMEM;
ubi->lookuptbl = kzalloc(ubi->peb_count * sizeof(void *), GFP_KERNEL); ubi->lookuptbl = kzalloc(ubi->peb_count * sizeof(void *), GFP_KERNEL);
if (!ubi->lookuptbl) if (!ubi->lookuptbl)
goto out_free; return err;
list_for_each_entry_safe(seb, tmp, &si->erase, u.list) { list_for_each_entry_safe(seb, tmp, &si->erase, u.list) {
cond_resched(); cond_resched();
...@@ -1598,10 +1590,6 @@ static void protection_trees_destroy(struct ubi_device *ubi) ...@@ -1598,10 +1590,6 @@ static void protection_trees_destroy(struct ubi_device *ubi)
*/ */
void ubi_wl_close(struct ubi_device *ubi) void ubi_wl_close(struct ubi_device *ubi)
{ {
dbg_wl("disable \"%s\"", ubi->bgt_name);
if (ubi->bgt_thread)
kthread_stop(ubi->bgt_thread);
dbg_wl("close the UBI wear-leveling unit"); dbg_wl("close the UBI wear-leveling unit");
cancel_pending(ubi); cancel_pending(ubi);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment