Loading drivers/mtd/ubi/io.c +10 −0 Original line number Diff line number Diff line Loading @@ -1101,6 +1101,16 @@ int ubi_io_write_vid_hdr(struct ubi_device *ubi, int pnum, dbg_io("write VID header to PEB %d", pnum); ubi_assert(pnum >= 0 && pnum < ubi->peb_count); /* * Re-erase the PEB before using it. This should minimize any issues * from decay of charge in this block. */ if (ubi->wl_is_inited) { err = ubi_wl_re_erase_peb(ubi, pnum); if (err) return err; } err = self_check_peb_ec_hdr(ubi, pnum); if (err) return err; Loading drivers/mtd/ubi/ubi.h +1 −0 Original line number Diff line number Diff line Loading @@ -871,6 +871,7 @@ ssize_t ubi_wl_scrub_all(struct ubi_device *ubi, void ubi_wl_update_peb_sqnum(struct ubi_device *ubi, int pnum, struct ubi_vid_hdr *vid_hdr); unsigned long long ubi_wl_scrub_get_min_sqnum(struct ubi_device *ubi); int ubi_wl_re_erase_peb(struct ubi_device *ubi, int pnum); /* io.c */ int ubi_io_read(const struct ubi_device *ubi, void *buf, int pnum, int offset, Loading drivers/mtd/ubi/wl.c +47 −0 Original line number Diff line number Diff line Loading @@ -488,6 +488,53 @@ out_free: return err; } /** * ubi_wl_re_erase_peb - synchronously re-erase a physical eraseblock without updating the EC of the PEB * @ubi: UBI device description object * @pnum: the the physical eraseblock number to erase * * This function returns zero in case of success and a negative error code in * case of failure. */ int ubi_wl_re_erase_peb(struct ubi_device *ubi, int pnum) { int err; struct ubi_wl_entry *e; struct ubi_ec_hdr *ec_hdr; spin_lock(&ubi->wl_lock); e = ubi->lookuptbl[pnum]; spin_unlock(&ubi->wl_lock); dbg_wl("Re-erase PEB %d, EC %u", e->pnum, e->ec); err = self_check_ec(ubi, e->pnum, e->ec); if (err) return -EINVAL; ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_NOFS); if (!ec_hdr) return -ENOMEM; err = ubi_io_sync_erase(ubi, e->pnum, 0); if (err < 0) goto out_free; dbg_wl("re-erased PEB %d, EC %u", e->pnum, e->ec); ec_hdr->ec = cpu_to_be64(e->ec); err = ubi_io_write_ec_hdr(ubi, e->pnum, ec_hdr); if (err) goto out_free; out_free: kfree(ec_hdr); return err; } /** * serve_prot_queue - check if it is time to stop protecting PEBs. * @ubi: UBI device description object Loading Loading
drivers/mtd/ubi/io.c +10 −0 Original line number Diff line number Diff line Loading @@ -1101,6 +1101,16 @@ int ubi_io_write_vid_hdr(struct ubi_device *ubi, int pnum, dbg_io("write VID header to PEB %d", pnum); ubi_assert(pnum >= 0 && pnum < ubi->peb_count); /* * Re-erase the PEB before using it. This should minimize any issues * from decay of charge in this block. */ if (ubi->wl_is_inited) { err = ubi_wl_re_erase_peb(ubi, pnum); if (err) return err; } err = self_check_peb_ec_hdr(ubi, pnum); if (err) return err; Loading
drivers/mtd/ubi/ubi.h +1 −0 Original line number Diff line number Diff line Loading @@ -871,6 +871,7 @@ ssize_t ubi_wl_scrub_all(struct ubi_device *ubi, void ubi_wl_update_peb_sqnum(struct ubi_device *ubi, int pnum, struct ubi_vid_hdr *vid_hdr); unsigned long long ubi_wl_scrub_get_min_sqnum(struct ubi_device *ubi); int ubi_wl_re_erase_peb(struct ubi_device *ubi, int pnum); /* io.c */ int ubi_io_read(const struct ubi_device *ubi, void *buf, int pnum, int offset, Loading
drivers/mtd/ubi/wl.c +47 −0 Original line number Diff line number Diff line Loading @@ -488,6 +488,53 @@ out_free: return err; } /** * ubi_wl_re_erase_peb - synchronously re-erase a physical eraseblock without updating the EC of the PEB * @ubi: UBI device description object * @pnum: the the physical eraseblock number to erase * * This function returns zero in case of success and a negative error code in * case of failure. */ int ubi_wl_re_erase_peb(struct ubi_device *ubi, int pnum) { int err; struct ubi_wl_entry *e; struct ubi_ec_hdr *ec_hdr; spin_lock(&ubi->wl_lock); e = ubi->lookuptbl[pnum]; spin_unlock(&ubi->wl_lock); dbg_wl("Re-erase PEB %d, EC %u", e->pnum, e->ec); err = self_check_ec(ubi, e->pnum, e->ec); if (err) return -EINVAL; ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_NOFS); if (!ec_hdr) return -ENOMEM; err = ubi_io_sync_erase(ubi, e->pnum, 0); if (err < 0) goto out_free; dbg_wl("re-erased PEB %d, EC %u", e->pnum, e->ec); ec_hdr->ec = cpu_to_be64(e->ec); err = ubi_io_write_ec_hdr(ubi, e->pnum, ec_hdr); if (err) goto out_free; out_free: kfree(ec_hdr); return err; } /** * serve_prot_queue - check if it is time to stop protecting PEBs. * @ubi: UBI device description object Loading