during ubi initialization we have a following calling sequence 1) ubi_attach() ---------------------------------------------------------------- err = ubi_wl_init(ubi, ai); if (err) goto out_vtbl; err = ubi_eba_init(ubi, ai); if (err) goto out_wl; ---------------------------------------------------------------- As we can see "eba" subsytem is NOT initialized at the moment of initializing of "wl" subsystem 2) ubi_wl_init() it call ensure_wear_leveling() at some moment 3) ensure_wear_leveling() --------------------------------------------------------------- e1 = rb_entry(rb_first(&ubi->used), struct ubi_wl_entry, u.rb); e2 = find_wl_entry(ubi, &ubi->free, WL_FREE_MAX_DIFF); if (!(e2->ec - e1->ec >= UBI_WL_THRESHOLD)) goto out_unlock; dbg_wl("schedule wear-leveling"); --------------------------------------------------------------- so, if no wear-leveling is scheduled than everything is OK and a little bit below --------------------------------------------------------------- wrk->anchor = 0; wrk->func = &wear_leveling_worker; if (nested) __schedule_ubi_work(ubi, wrk); else schedule_ubi_work(ubi, wrk); --------------------------------------------------------------- as result we enter to wear_leveling_worker() function 4) wear_leveling_worker() --------------------------------------------------------------- /* * Now pick the least worn-out used physical eraseblock and a * highly worn-out free physical eraseblock. If the erase * counters differ much enough, start wear-leveling. */ e1 = rb_entry(rb_first(&ubi->used), struct ubi_wl_entry, u.rb); e2 = get_peb_for_wl(ubi); if (!e2) goto out_cancel; if (!(e2->ec - e1->ec >= UBI_WL_THRESHOLD)) { dbg_wl("no WL needed: min used EC %d, max free EC %d", e1->ec, e2->ec); /* Give the unused PEB back */ wl_tree_add(e2, &ubi->free); ubi->free_count++; goto out_cancel; } --------------------------------------------------------------- so, if no WL needed than everything is OK and a little bit below --------------------------------------------------------------- err = ubi_eba_copy_leb(ubi, e1->pnum, e2->pnum, vid_hdr); --------------------------------------------------------------- OPS, eba sybsystem is not initialized yet (see (1)) >From the other side, it looks like eba sybsystem does not require wl sybsystem during initialization, so just fix ordering and proper handle error path. --- drivers/mtd/ubi/attach.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/mtd/ubi/attach.c b/drivers/mtd/ubi/attach.c index 10b2459f8951..8c1d629c0e1d 100644 --- a/drivers/mtd/ubi/attach.c +++ b/drivers/mtd/ubi/attach.c @@ -1602,13 +1602,13 @@ int ubi_attach(struct ubi_device *ubi, int force_scan) if (err) goto out_ai; - err = ubi_wl_init(ubi, ai); + err = ubi_eba_init(ubi, ai); if (err) goto out_vtbl; - err = ubi_eba_init(ubi, ai); + err = ubi_wl_init(ubi, ai); if (err) - goto out_wl; + goto out_vtbl; #ifdef CONFIG_MTD_UBI_FASTMAP if (ubi->fm && ubi_dbg_chk_fastmap(ubi)) { -- 2.20.1 ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/