Loading drivers/mtd/ubi/build.c +27 −1 Original line number Diff line number Diff line Loading @@ -583,6 +583,22 @@ static int attach_mtd_dev(const char *mtd_dev, int vid_hdr_offset, if (err) goto out_free; mutex_init(&ubi->buf_mutex); ubi->peb_buf1 = vmalloc(ubi->peb_size); if (!ubi->peb_buf1) goto out_free; ubi->peb_buf2 = vmalloc(ubi->peb_size); if (!ubi->peb_buf2) goto out_free; #ifdef CONFIG_MTD_UBI_DEBUG mutex_init(&ubi->dbg_buf_mutex); ubi->dbg_peb_buf = vmalloc(ubi->peb_size); if (!ubi->dbg_peb_buf) goto out_free; #endif err = attach_by_scanning(ubi); if (err) { dbg_err("failed to attach by scanning, error %d", err); Loading Loading @@ -630,6 +646,11 @@ static int attach_mtd_dev(const char *mtd_dev, int vid_hdr_offset, ubi_wl_close(ubi); vfree(ubi->vtbl); out_free: vfree(ubi->peb_buf1); vfree(ubi->peb_buf2); #ifdef CONFIG_MTD_UBI_DEBUG vfree(ubi->dbg_peb_buf); #endif kfree(ubi); out_mtd: put_mtd_device(mtd); Loading @@ -651,6 +672,11 @@ static void detach_mtd_dev(struct ubi_device *ubi) ubi_wl_close(ubi); vfree(ubi->vtbl); put_mtd_device(ubi->mtd); vfree(ubi->peb_buf1); vfree(ubi->peb_buf2); #ifdef CONFIG_MTD_UBI_DEBUG vfree(ubi->dbg_peb_buf); #endif kfree(ubi_devices[ubi_num]); ubi_devices[ubi_num] = NULL; ubi_devices_cnt -= 1; Loading drivers/mtd/ubi/debug.c +2 −35 Original line number Diff line number Diff line Loading @@ -42,7 +42,8 @@ void ubi_dbg_dump_ec_hdr(const struct ubi_ec_hdr *ec_hdr) dbg_msg("data_offset %d", be32_to_cpu(ec_hdr->data_offset)); dbg_msg("hdr_crc %#08x", be32_to_cpu(ec_hdr->hdr_crc)); dbg_msg("erase counter header hexdump:"); ubi_dbg_hexdump(ec_hdr, UBI_EC_HDR_SIZE); print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, ec_hdr, UBI_EC_HDR_SIZE, 1); } /** Loading Loading @@ -187,38 +188,4 @@ void ubi_dbg_dump_mkvol_req(const struct ubi_mkvol_req *req) dbg_msg("the 1st 16 characters of the name: %s", nm); } #define BYTES_PER_LINE 32 /** * ubi_dbg_hexdump - dump a buffer. * @ptr: the buffer to dump * @size: buffer size which must be multiple of 4 bytes */ void ubi_dbg_hexdump(const void *ptr, int size) { int i, k = 0, rows, columns; const uint8_t *p = ptr; size = ALIGN(size, 4); rows = size/BYTES_PER_LINE + size % BYTES_PER_LINE; for (i = 0; i < rows; i++) { int j; cond_resched(); columns = min(size - k, BYTES_PER_LINE) / 4; if (columns == 0) break; printk(KERN_DEBUG "%5d: ", i * BYTES_PER_LINE); for (j = 0; j < columns; j++) { int n, N; N = size - k > 4 ? 4 : size - k; for (n = 0; n < N; n++) printk("%02x", p[k++]); printk(" "); } printk("\n"); } } #endif /* CONFIG_MTD_UBI_DEBUG_MSG */ drivers/mtd/ubi/debug.h +0 −2 Original line number Diff line number Diff line Loading @@ -59,7 +59,6 @@ void ubi_dbg_dump_vtbl_record(const struct ubi_vtbl_record *r, int idx); void ubi_dbg_dump_sv(const struct ubi_scan_volume *sv); void ubi_dbg_dump_seb(const struct ubi_scan_leb *seb, int type); void ubi_dbg_dump_mkvol_req(const struct ubi_mkvol_req *req); void ubi_dbg_hexdump(const void *buf, int size); #else Loading @@ -72,7 +71,6 @@ void ubi_dbg_hexdump(const void *buf, int size); #define ubi_dbg_dump_sv(sv) ({}) #define ubi_dbg_dump_seb(seb, type) ({}) #define ubi_dbg_dump_mkvol_req(req) ({}) #define ubi_dbg_hexdump(buf, size) ({}) #endif /* CONFIG_MTD_UBI_DEBUG_MSG */ Loading drivers/mtd/ubi/eba.c +60 −71 Original line number Diff line number Diff line Loading @@ -46,6 +46,9 @@ #include <linux/err.h> #include "ubi.h" /* Number of physical eraseblocks reserved for atomic LEB change operation */ #define EBA_RESERVED_PEBS 1 /** * struct ltree_entry - an entry in the lock tree. * @rb: links RB-tree nodes Loading Loading @@ -157,7 +160,7 @@ static struct ltree_entry *ltree_add_entry(struct ubi_device *ubi, int vol_id, { struct ltree_entry *le, *le1, *le_free; le = kmem_cache_alloc(ltree_slab, GFP_KERNEL); le = kmem_cache_alloc(ltree_slab, GFP_NOFS); if (!le) return ERR_PTR(-ENOMEM); Loading Loading @@ -397,7 +400,7 @@ int ubi_eba_read_leb(struct ubi_device *ubi, int vol_id, int lnum, void *buf, retry: if (check) { vid_hdr = ubi_zalloc_vid_hdr(ubi); vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); if (!vid_hdr) { err = -ENOMEM; goto out_unlock; Loading Loading @@ -495,16 +498,18 @@ static int recover_peb(struct ubi_device *ubi, int pnum, int vol_id, int lnum, int err, idx = vol_id2idx(ubi, vol_id), new_pnum, data_size, tries = 0; struct ubi_volume *vol = ubi->volumes[idx]; struct ubi_vid_hdr *vid_hdr; unsigned char *new_buf; vid_hdr = ubi_zalloc_vid_hdr(ubi); vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); if (!vid_hdr) { return -ENOMEM; } mutex_lock(&ubi->buf_mutex); retry: new_pnum = ubi_wl_get_peb(ubi, UBI_UNKNOWN); if (new_pnum < 0) { mutex_unlock(&ubi->buf_mutex); ubi_free_vid_hdr(ubi, vid_hdr); return new_pnum; } Loading @@ -524,31 +529,22 @@ static int recover_peb(struct ubi_device *ubi, int pnum, int vol_id, int lnum, goto write_error; data_size = offset + len; new_buf = vmalloc(data_size); if (!new_buf) { err = -ENOMEM; goto out_put; } memset(new_buf + offset, 0xFF, len); memset(ubi->peb_buf1 + offset, 0xFF, len); /* Read everything before the area where the write failure happened */ if (offset > 0) { err = ubi_io_read_data(ubi, new_buf, pnum, 0, offset); if (err && err != UBI_IO_BITFLIPS) { vfree(new_buf); err = ubi_io_read_data(ubi, ubi->peb_buf1, pnum, 0, offset); if (err && err != UBI_IO_BITFLIPS) goto out_put; } } memcpy(new_buf + offset, buf, len); memcpy(ubi->peb_buf1 + offset, buf, len); err = ubi_io_write_data(ubi, new_buf, new_pnum, 0, data_size); if (err) { vfree(new_buf); err = ubi_io_write_data(ubi, ubi->peb_buf1, new_pnum, 0, data_size); if (err) goto write_error; } vfree(new_buf); mutex_unlock(&ubi->buf_mutex); ubi_free_vid_hdr(ubi, vid_hdr); vol->eba_tbl[lnum] = new_pnum; Loading @@ -558,6 +554,7 @@ static int recover_peb(struct ubi_device *ubi, int pnum, int vol_id, int lnum, return 0; out_put: mutex_unlock(&ubi->buf_mutex); ubi_wl_put_peb(ubi, new_pnum, 1); ubi_free_vid_hdr(ubi, vid_hdr); return err; Loading @@ -570,6 +567,7 @@ static int recover_peb(struct ubi_device *ubi, int pnum, int vol_id, int lnum, ubi_warn("failed to write to PEB %d", new_pnum); ubi_wl_put_peb(ubi, new_pnum, 1); if (++tries > UBI_IO_RETRIES) { mutex_unlock(&ubi->buf_mutex); ubi_free_vid_hdr(ubi, vid_hdr); return err; } Loading Loading @@ -627,7 +625,7 @@ int ubi_eba_write_leb(struct ubi_device *ubi, int vol_id, int lnum, * The logical eraseblock is not mapped. We have to get a free physical * eraseblock and write the volume identifier header there first. */ vid_hdr = ubi_zalloc_vid_hdr(ubi); vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); if (!vid_hdr) { leb_write_unlock(ubi, vol_id, lnum); return -ENOMEM; Loading Loading @@ -738,7 +736,7 @@ int ubi_eba_write_leb_st(struct ubi_device *ubi, int vol_id, int lnum, else ubi_assert(len % ubi->min_io_size == 0); vid_hdr = ubi_zalloc_vid_hdr(ubi); vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); if (!vid_hdr) return -ENOMEM; Loading Loading @@ -832,6 +830,9 @@ int ubi_eba_write_leb_st(struct ubi_device *ubi, int vol_id, int lnum, * data, which has to be aligned. This function guarantees that in case of an * unclean reboot the old contents is preserved. Returns zero in case of * success and a negative error code in case of failure. * * UBI reserves one LEB for the "atomic LEB change" operation, so only one * LEB change may be done at a time. This is ensured by @ubi->alc_mutex. */ int ubi_eba_atomic_leb_change(struct ubi_device *ubi, int vol_id, int lnum, const void *buf, int len, int dtype) Loading @@ -844,15 +845,14 @@ int ubi_eba_atomic_leb_change(struct ubi_device *ubi, int vol_id, int lnum, if (ubi->ro_mode) return -EROFS; vid_hdr = ubi_zalloc_vid_hdr(ubi); vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); if (!vid_hdr) return -ENOMEM; mutex_lock(&ubi->alc_mutex); err = leb_write_lock(ubi, vol_id, lnum); if (err) { ubi_free_vid_hdr(ubi, vid_hdr); return err; } if (err) goto out_mutex; vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi)); vid_hdr->vol_id = cpu_to_be32(vol_id); Loading @@ -869,9 +869,8 @@ int ubi_eba_atomic_leb_change(struct ubi_device *ubi, int vol_id, int lnum, retry: pnum = ubi_wl_get_peb(ubi, dtype); if (pnum < 0) { ubi_free_vid_hdr(ubi, vid_hdr); leb_write_unlock(ubi, vol_id, lnum); return pnum; err = pnum; goto out_leb_unlock; } dbg_eba("change LEB %d:%d, PEB %d, write VID hdr to PEB %d", Loading @@ -893,17 +892,18 @@ int ubi_eba_atomic_leb_change(struct ubi_device *ubi, int vol_id, int lnum, if (vol->eba_tbl[lnum] >= 0) { err = ubi_wl_put_peb(ubi, vol->eba_tbl[lnum], 1); if (err) { ubi_free_vid_hdr(ubi, vid_hdr); leb_write_unlock(ubi, vol_id, lnum); return err; } if (err) goto out_leb_unlock; } vol->eba_tbl[lnum] = pnum; out_leb_unlock: leb_write_unlock(ubi, vol_id, lnum); out_mutex: mutex_unlock(&ubi->alc_mutex); ubi_free_vid_hdr(ubi, vid_hdr); return 0; return err; write_error: if (err != -EIO || !ubi->bad_allowed) { Loading @@ -913,17 +913,13 @@ int ubi_eba_atomic_leb_change(struct ubi_device *ubi, int vol_id, int lnum, * mode just in case. */ ubi_ro_mode(ubi); leb_write_unlock(ubi, vol_id, lnum); ubi_free_vid_hdr(ubi, vid_hdr); return err; goto out_leb_unlock; } err = ubi_wl_put_peb(ubi, pnum, 1); if (err || ++tries > UBI_IO_RETRIES) { ubi_ro_mode(ubi); leb_write_unlock(ubi, vol_id, lnum); ubi_free_vid_hdr(ubi, vid_hdr); return err; goto out_leb_unlock; } vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi)); Loading Loading @@ -965,7 +961,6 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, int err, vol_id, lnum, data_size, aldata_size, pnum, idx; struct ubi_volume *vol; uint32_t crc; void *buf, *buf1 = NULL; vol_id = be32_to_cpu(vid_hdr->vol_id); lnum = be32_to_cpu(vid_hdr->lnum); Loading @@ -979,19 +974,15 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, data_size = aldata_size = ubi->leb_size - be32_to_cpu(vid_hdr->data_pad); buf = vmalloc(aldata_size); if (!buf) return -ENOMEM; /* * We do not want anybody to write to this logical eraseblock while we * are moving it, so we lock it. */ err = leb_write_lock(ubi, vol_id, lnum); if (err) { vfree(buf); if (err) return err; } mutex_lock(&ubi->buf_mutex); /* * But the logical eraseblock might have been put by this time. Loading Loading @@ -1023,7 +1014,7 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, /* OK, now the LEB is locked and we can safely start moving it */ dbg_eba("read %d bytes of data", aldata_size); err = ubi_io_read_data(ubi, buf, from, 0, aldata_size); err = ubi_io_read_data(ubi, ubi->peb_buf1, from, 0, aldata_size); if (err && err != UBI_IO_BITFLIPS) { ubi_warn("error %d while reading data from PEB %d", err, from); Loading @@ -1042,10 +1033,10 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, */ if (vid_hdr->vol_type == UBI_VID_DYNAMIC) aldata_size = data_size = ubi_calc_data_len(ubi, buf, data_size); ubi_calc_data_len(ubi, ubi->peb_buf1, data_size); cond_resched(); crc = crc32(UBI_CRC32_INIT, buf, data_size); crc = crc32(UBI_CRC32_INIT, ubi->peb_buf1, data_size); cond_resched(); /* Loading Loading @@ -1076,23 +1067,18 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, } if (data_size > 0) { err = ubi_io_write_data(ubi, buf, to, 0, aldata_size); err = ubi_io_write_data(ubi, ubi->peb_buf1, to, 0, aldata_size); if (err) goto out_unlock; cond_resched(); /* * We've written the data and are going to read it back to make * sure it was written correctly. */ buf1 = vmalloc(aldata_size); if (!buf1) { err = -ENOMEM; goto out_unlock; } cond_resched(); err = ubi_io_read_data(ubi, buf1, to, 0, aldata_size); err = ubi_io_read_data(ubi, ubi->peb_buf2, to, 0, aldata_size); if (err) { if (err != UBI_IO_BITFLIPS) ubi_warn("cannot read data back from PEB %d", Loading @@ -1102,7 +1088,7 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, cond_resched(); if (memcmp(buf, buf1, aldata_size)) { if (memcmp(ubi->peb_buf1, ubi->peb_buf2, aldata_size)) { ubi_warn("read data back from PEB %d - it is different", to); goto out_unlock; Loading @@ -1112,16 +1098,9 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, ubi_assert(vol->eba_tbl[lnum] == from); vol->eba_tbl[lnum] = to; leb_write_unlock(ubi, vol_id, lnum); vfree(buf); vfree(buf1); return 0; out_unlock: mutex_unlock(&ubi->buf_mutex); leb_write_unlock(ubi, vol_id, lnum); vfree(buf); vfree(buf1); return err; } Loading @@ -1144,6 +1123,7 @@ int ubi_eba_init_scan(struct ubi_device *ubi, struct ubi_scan_info *si) dbg_eba("initialize EBA unit"); spin_lock_init(&ubi->ltree_lock); mutex_init(&ubi->alc_mutex); ubi->ltree = RB_ROOT; if (ubi_devices_cnt == 0) { Loading Loading @@ -1205,6 +1185,15 @@ int ubi_eba_init_scan(struct ubi_device *ubi, struct ubi_scan_info *si) ubi->rsvd_pebs += ubi->beb_rsvd_pebs; } if (ubi->avail_pebs < EBA_RESERVED_PEBS) { ubi_err("no enough physical eraseblocks (%d, need %d)", ubi->avail_pebs, EBA_RESERVED_PEBS); err = -ENOSPC; goto out_free; } ubi->avail_pebs -= EBA_RESERVED_PEBS; ubi->rsvd_pebs += EBA_RESERVED_PEBS; dbg_eba("EBA unit is initialized"); return 0; Loading drivers/mtd/ubi/io.c +35 −40 Original line number Diff line number Diff line Loading @@ -98,8 +98,8 @@ static int paranoid_check_ec_hdr(const struct ubi_device *ubi, int pnum, static int paranoid_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum); static int paranoid_check_vid_hdr(const struct ubi_device *ubi, int pnum, const struct ubi_vid_hdr *vid_hdr); static int paranoid_check_all_ff(const struct ubi_device *ubi, int pnum, int offset, int len); static int paranoid_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len); #else #define paranoid_check_not_bad(ubi, pnum) 0 #define paranoid_check_peb_ec_hdr(ubi, pnum) 0 Loading Loading @@ -202,8 +202,8 @@ int ubi_io_read(const struct ubi_device *ubi, void *buf, int pnum, int offset, * Note, in case of an error, it is possible that something was still written * to the flash media, but may be some garbage. */ int ubi_io_write(const struct ubi_device *ubi, const void *buf, int pnum, int offset, int len) int ubi_io_write(struct ubi_device *ubi, const void *buf, int pnum, int offset, int len) { int err; size_t written; Loading Loading @@ -285,7 +285,7 @@ static void erase_callback(struct erase_info *ei) * zero in case of success and a negative error code in case of failure. If * %-EIO is returned, the physical eraseblock most probably went bad. */ static int do_sync_erase(const struct ubi_device *ubi, int pnum) static int do_sync_erase(struct ubi_device *ubi, int pnum) { int err, retries = 0; struct erase_info ei; Loading Loading @@ -377,29 +377,25 @@ static uint8_t patterns[] = {0xa5, 0x5a, 0x0}; * test, a positive number of erase operations done if the test was * successfully passed, and other negative error codes in case of other errors. */ static int torture_peb(const struct ubi_device *ubi, int pnum) static int torture_peb(struct ubi_device *ubi, int pnum) { void *buf; int err, i, patt_count; buf = vmalloc(ubi->peb_size); if (!buf) return -ENOMEM; patt_count = ARRAY_SIZE(patterns); ubi_assert(patt_count > 0); mutex_lock(&ubi->buf_mutex); for (i = 0; i < patt_count; i++) { err = do_sync_erase(ubi, pnum); if (err) goto out; /* Make sure the PEB contains only 0xFF bytes */ err = ubi_io_read(ubi, buf, pnum, 0, ubi->peb_size); err = ubi_io_read(ubi, ubi->peb_buf1, pnum, 0, ubi->peb_size); if (err) goto out; err = check_pattern(buf, 0xFF, ubi->peb_size); err = check_pattern(ubi->peb_buf1, 0xFF, ubi->peb_size); if (err == 0) { ubi_err("erased PEB %d, but a non-0xFF byte found", pnum); Loading @@ -408,17 +404,17 @@ static int torture_peb(const struct ubi_device *ubi, int pnum) } /* Write a pattern and check it */ memset(buf, patterns[i], ubi->peb_size); err = ubi_io_write(ubi, buf, pnum, 0, ubi->peb_size); memset(ubi->peb_buf1, patterns[i], ubi->peb_size); err = ubi_io_write(ubi, ubi->peb_buf1, pnum, 0, ubi->peb_size); if (err) goto out; memset(buf, ~patterns[i], ubi->peb_size); err = ubi_io_read(ubi, buf, pnum, 0, ubi->peb_size); memset(ubi->peb_buf1, ~patterns[i], ubi->peb_size); err = ubi_io_read(ubi, ubi->peb_buf1, pnum, 0, ubi->peb_size); if (err) goto out; err = check_pattern(buf, patterns[i], ubi->peb_size); err = check_pattern(ubi->peb_buf1, patterns[i], ubi->peb_size); if (err == 0) { ubi_err("pattern %x checking failed for PEB %d", patterns[i], pnum); Loading @@ -430,14 +426,17 @@ static int torture_peb(const struct ubi_device *ubi, int pnum) err = patt_count; out: if (err == UBI_IO_BITFLIPS || err == -EBADMSG) mutex_unlock(&ubi->buf_mutex); if (err == UBI_IO_BITFLIPS || err == -EBADMSG) { /* * If a bit-flip or data integrity error was detected, the test * has not passed because it happened on a freshly erased * physical eraseblock which means something is wrong with it. */ ubi_err("read problems on freshly erased PEB %d, must be bad", pnum); err = -EIO; vfree(buf); } return err; } Loading @@ -457,7 +456,7 @@ static int torture_peb(const struct ubi_device *ubi, int pnum) * codes in case of other errors. Note, %-EIO means that the physical * eraseblock is bad. */ int ubi_io_sync_erase(const struct ubi_device *ubi, int pnum, int torture) int ubi_io_sync_erase(struct ubi_device *ubi, int pnum, int torture) { int err, ret = 0; Loading Loading @@ -614,7 +613,7 @@ static int validate_ec_hdr(const struct ubi_device *ubi, * o %UBI_IO_PEB_EMPTY if the physical eraseblock is empty; * o a negative error code in case of failure. */ int ubi_io_read_ec_hdr(const struct ubi_device *ubi, int pnum, int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum, struct ubi_ec_hdr *ec_hdr, int verbose) { int err, read_err = 0; Loading Loading @@ -720,7 +719,7 @@ int ubi_io_read_ec_hdr(const struct ubi_device *ubi, int pnum, * case of failure. If %-EIO is returned, the physical eraseblock most probably * went bad. */ int ubi_io_write_ec_hdr(const struct ubi_device *ubi, int pnum, int ubi_io_write_ec_hdr(struct ubi_device *ubi, int pnum, struct ubi_ec_hdr *ec_hdr) { int err; Loading Loading @@ -886,7 +885,7 @@ static int validate_vid_hdr(const struct ubi_device *ubi, * header there); * o a negative error code in case of failure. */ int ubi_io_read_vid_hdr(const struct ubi_device *ubi, int pnum, int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum, struct ubi_vid_hdr *vid_hdr, int verbose) { int err, read_err = 0; Loading Loading @@ -993,7 +992,7 @@ int ubi_io_read_vid_hdr(const struct ubi_device *ubi, int pnum, * case of failure. If %-EIO is returned, the physical eraseblock probably went * bad. */ int ubi_io_write_vid_hdr(const struct ubi_device *ubi, int pnum, int ubi_io_write_vid_hdr(struct ubi_device *ubi, int pnum, struct ubi_vid_hdr *vid_hdr) { int err; Loading Loading @@ -1096,7 +1095,7 @@ static int paranoid_check_peb_ec_hdr(const struct ubi_device *ubi, int pnum) uint32_t crc, hdr_crc; struct ubi_ec_hdr *ec_hdr; ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL); ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_NOFS); if (!ec_hdr) return -ENOMEM; Loading Loading @@ -1176,7 +1175,7 @@ static int paranoid_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum) struct ubi_vid_hdr *vid_hdr; void *p; vid_hdr = ubi_zalloc_vid_hdr(ubi); vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); if (!vid_hdr) return -ENOMEM; Loading Loading @@ -1216,44 +1215,40 @@ static int paranoid_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum) * @offset of the physical eraseblock @pnum, %1 if not, and a negative error * code if an error occurred. */ static int paranoid_check_all_ff(const struct ubi_device *ubi, int pnum, int offset, int len) static int paranoid_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len) { size_t read; int err; void *buf; loff_t addr = (loff_t)pnum * ubi->peb_size + offset; buf = vmalloc(len); if (!buf) return -ENOMEM; memset(buf, 0, len); err = ubi->mtd->read(ubi->mtd, addr, len, &read, buf); mutex_lock(&ubi->dbg_buf_mutex); err = ubi->mtd->read(ubi->mtd, addr, len, &read, ubi->dbg_peb_buf); if (err && err != -EUCLEAN) { ubi_err("error %d while reading %d bytes from PEB %d:%d, " "read %zd bytes", err, len, pnum, offset, read); goto error; } err = check_pattern(buf, 0xFF, len); err = check_pattern(ubi->dbg_peb_buf, 0xFF, len); if (err == 0) { ubi_err("flash region at PEB %d:%d, length %d does not " "contain all 0xFF bytes", pnum, offset, len); goto fail; } mutex_unlock(&ubi->dbg_buf_mutex); vfree(buf); return 0; fail: ubi_err("paranoid check failed for PEB %d", pnum); dbg_msg("hex dump of the %d-%d region", offset, offset + len); ubi_dbg_hexdump(buf, len); print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, ubi->dbg_peb_buf, len, 1); err = 1; error: ubi_dbg_dump_stack(); vfree(buf); mutex_unlock(&ubi->dbg_buf_mutex); return err; } Loading Loading
drivers/mtd/ubi/build.c +27 −1 Original line number Diff line number Diff line Loading @@ -583,6 +583,22 @@ static int attach_mtd_dev(const char *mtd_dev, int vid_hdr_offset, if (err) goto out_free; mutex_init(&ubi->buf_mutex); ubi->peb_buf1 = vmalloc(ubi->peb_size); if (!ubi->peb_buf1) goto out_free; ubi->peb_buf2 = vmalloc(ubi->peb_size); if (!ubi->peb_buf2) goto out_free; #ifdef CONFIG_MTD_UBI_DEBUG mutex_init(&ubi->dbg_buf_mutex); ubi->dbg_peb_buf = vmalloc(ubi->peb_size); if (!ubi->dbg_peb_buf) goto out_free; #endif err = attach_by_scanning(ubi); if (err) { dbg_err("failed to attach by scanning, error %d", err); Loading Loading @@ -630,6 +646,11 @@ static int attach_mtd_dev(const char *mtd_dev, int vid_hdr_offset, ubi_wl_close(ubi); vfree(ubi->vtbl); out_free: vfree(ubi->peb_buf1); vfree(ubi->peb_buf2); #ifdef CONFIG_MTD_UBI_DEBUG vfree(ubi->dbg_peb_buf); #endif kfree(ubi); out_mtd: put_mtd_device(mtd); Loading @@ -651,6 +672,11 @@ static void detach_mtd_dev(struct ubi_device *ubi) ubi_wl_close(ubi); vfree(ubi->vtbl); put_mtd_device(ubi->mtd); vfree(ubi->peb_buf1); vfree(ubi->peb_buf2); #ifdef CONFIG_MTD_UBI_DEBUG vfree(ubi->dbg_peb_buf); #endif kfree(ubi_devices[ubi_num]); ubi_devices[ubi_num] = NULL; ubi_devices_cnt -= 1; Loading
drivers/mtd/ubi/debug.c +2 −35 Original line number Diff line number Diff line Loading @@ -42,7 +42,8 @@ void ubi_dbg_dump_ec_hdr(const struct ubi_ec_hdr *ec_hdr) dbg_msg("data_offset %d", be32_to_cpu(ec_hdr->data_offset)); dbg_msg("hdr_crc %#08x", be32_to_cpu(ec_hdr->hdr_crc)); dbg_msg("erase counter header hexdump:"); ubi_dbg_hexdump(ec_hdr, UBI_EC_HDR_SIZE); print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, ec_hdr, UBI_EC_HDR_SIZE, 1); } /** Loading Loading @@ -187,38 +188,4 @@ void ubi_dbg_dump_mkvol_req(const struct ubi_mkvol_req *req) dbg_msg("the 1st 16 characters of the name: %s", nm); } #define BYTES_PER_LINE 32 /** * ubi_dbg_hexdump - dump a buffer. * @ptr: the buffer to dump * @size: buffer size which must be multiple of 4 bytes */ void ubi_dbg_hexdump(const void *ptr, int size) { int i, k = 0, rows, columns; const uint8_t *p = ptr; size = ALIGN(size, 4); rows = size/BYTES_PER_LINE + size % BYTES_PER_LINE; for (i = 0; i < rows; i++) { int j; cond_resched(); columns = min(size - k, BYTES_PER_LINE) / 4; if (columns == 0) break; printk(KERN_DEBUG "%5d: ", i * BYTES_PER_LINE); for (j = 0; j < columns; j++) { int n, N; N = size - k > 4 ? 4 : size - k; for (n = 0; n < N; n++) printk("%02x", p[k++]); printk(" "); } printk("\n"); } } #endif /* CONFIG_MTD_UBI_DEBUG_MSG */
drivers/mtd/ubi/debug.h +0 −2 Original line number Diff line number Diff line Loading @@ -59,7 +59,6 @@ void ubi_dbg_dump_vtbl_record(const struct ubi_vtbl_record *r, int idx); void ubi_dbg_dump_sv(const struct ubi_scan_volume *sv); void ubi_dbg_dump_seb(const struct ubi_scan_leb *seb, int type); void ubi_dbg_dump_mkvol_req(const struct ubi_mkvol_req *req); void ubi_dbg_hexdump(const void *buf, int size); #else Loading @@ -72,7 +71,6 @@ void ubi_dbg_hexdump(const void *buf, int size); #define ubi_dbg_dump_sv(sv) ({}) #define ubi_dbg_dump_seb(seb, type) ({}) #define ubi_dbg_dump_mkvol_req(req) ({}) #define ubi_dbg_hexdump(buf, size) ({}) #endif /* CONFIG_MTD_UBI_DEBUG_MSG */ Loading
drivers/mtd/ubi/eba.c +60 −71 Original line number Diff line number Diff line Loading @@ -46,6 +46,9 @@ #include <linux/err.h> #include "ubi.h" /* Number of physical eraseblocks reserved for atomic LEB change operation */ #define EBA_RESERVED_PEBS 1 /** * struct ltree_entry - an entry in the lock tree. * @rb: links RB-tree nodes Loading Loading @@ -157,7 +160,7 @@ static struct ltree_entry *ltree_add_entry(struct ubi_device *ubi, int vol_id, { struct ltree_entry *le, *le1, *le_free; le = kmem_cache_alloc(ltree_slab, GFP_KERNEL); le = kmem_cache_alloc(ltree_slab, GFP_NOFS); if (!le) return ERR_PTR(-ENOMEM); Loading Loading @@ -397,7 +400,7 @@ int ubi_eba_read_leb(struct ubi_device *ubi, int vol_id, int lnum, void *buf, retry: if (check) { vid_hdr = ubi_zalloc_vid_hdr(ubi); vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); if (!vid_hdr) { err = -ENOMEM; goto out_unlock; Loading Loading @@ -495,16 +498,18 @@ static int recover_peb(struct ubi_device *ubi, int pnum, int vol_id, int lnum, int err, idx = vol_id2idx(ubi, vol_id), new_pnum, data_size, tries = 0; struct ubi_volume *vol = ubi->volumes[idx]; struct ubi_vid_hdr *vid_hdr; unsigned char *new_buf; vid_hdr = ubi_zalloc_vid_hdr(ubi); vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); if (!vid_hdr) { return -ENOMEM; } mutex_lock(&ubi->buf_mutex); retry: new_pnum = ubi_wl_get_peb(ubi, UBI_UNKNOWN); if (new_pnum < 0) { mutex_unlock(&ubi->buf_mutex); ubi_free_vid_hdr(ubi, vid_hdr); return new_pnum; } Loading @@ -524,31 +529,22 @@ static int recover_peb(struct ubi_device *ubi, int pnum, int vol_id, int lnum, goto write_error; data_size = offset + len; new_buf = vmalloc(data_size); if (!new_buf) { err = -ENOMEM; goto out_put; } memset(new_buf + offset, 0xFF, len); memset(ubi->peb_buf1 + offset, 0xFF, len); /* Read everything before the area where the write failure happened */ if (offset > 0) { err = ubi_io_read_data(ubi, new_buf, pnum, 0, offset); if (err && err != UBI_IO_BITFLIPS) { vfree(new_buf); err = ubi_io_read_data(ubi, ubi->peb_buf1, pnum, 0, offset); if (err && err != UBI_IO_BITFLIPS) goto out_put; } } memcpy(new_buf + offset, buf, len); memcpy(ubi->peb_buf1 + offset, buf, len); err = ubi_io_write_data(ubi, new_buf, new_pnum, 0, data_size); if (err) { vfree(new_buf); err = ubi_io_write_data(ubi, ubi->peb_buf1, new_pnum, 0, data_size); if (err) goto write_error; } vfree(new_buf); mutex_unlock(&ubi->buf_mutex); ubi_free_vid_hdr(ubi, vid_hdr); vol->eba_tbl[lnum] = new_pnum; Loading @@ -558,6 +554,7 @@ static int recover_peb(struct ubi_device *ubi, int pnum, int vol_id, int lnum, return 0; out_put: mutex_unlock(&ubi->buf_mutex); ubi_wl_put_peb(ubi, new_pnum, 1); ubi_free_vid_hdr(ubi, vid_hdr); return err; Loading @@ -570,6 +567,7 @@ static int recover_peb(struct ubi_device *ubi, int pnum, int vol_id, int lnum, ubi_warn("failed to write to PEB %d", new_pnum); ubi_wl_put_peb(ubi, new_pnum, 1); if (++tries > UBI_IO_RETRIES) { mutex_unlock(&ubi->buf_mutex); ubi_free_vid_hdr(ubi, vid_hdr); return err; } Loading Loading @@ -627,7 +625,7 @@ int ubi_eba_write_leb(struct ubi_device *ubi, int vol_id, int lnum, * The logical eraseblock is not mapped. We have to get a free physical * eraseblock and write the volume identifier header there first. */ vid_hdr = ubi_zalloc_vid_hdr(ubi); vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); if (!vid_hdr) { leb_write_unlock(ubi, vol_id, lnum); return -ENOMEM; Loading Loading @@ -738,7 +736,7 @@ int ubi_eba_write_leb_st(struct ubi_device *ubi, int vol_id, int lnum, else ubi_assert(len % ubi->min_io_size == 0); vid_hdr = ubi_zalloc_vid_hdr(ubi); vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); if (!vid_hdr) return -ENOMEM; Loading Loading @@ -832,6 +830,9 @@ int ubi_eba_write_leb_st(struct ubi_device *ubi, int vol_id, int lnum, * data, which has to be aligned. This function guarantees that in case of an * unclean reboot the old contents is preserved. Returns zero in case of * success and a negative error code in case of failure. * * UBI reserves one LEB for the "atomic LEB change" operation, so only one * LEB change may be done at a time. This is ensured by @ubi->alc_mutex. */ int ubi_eba_atomic_leb_change(struct ubi_device *ubi, int vol_id, int lnum, const void *buf, int len, int dtype) Loading @@ -844,15 +845,14 @@ int ubi_eba_atomic_leb_change(struct ubi_device *ubi, int vol_id, int lnum, if (ubi->ro_mode) return -EROFS; vid_hdr = ubi_zalloc_vid_hdr(ubi); vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); if (!vid_hdr) return -ENOMEM; mutex_lock(&ubi->alc_mutex); err = leb_write_lock(ubi, vol_id, lnum); if (err) { ubi_free_vid_hdr(ubi, vid_hdr); return err; } if (err) goto out_mutex; vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi)); vid_hdr->vol_id = cpu_to_be32(vol_id); Loading @@ -869,9 +869,8 @@ int ubi_eba_atomic_leb_change(struct ubi_device *ubi, int vol_id, int lnum, retry: pnum = ubi_wl_get_peb(ubi, dtype); if (pnum < 0) { ubi_free_vid_hdr(ubi, vid_hdr); leb_write_unlock(ubi, vol_id, lnum); return pnum; err = pnum; goto out_leb_unlock; } dbg_eba("change LEB %d:%d, PEB %d, write VID hdr to PEB %d", Loading @@ -893,17 +892,18 @@ int ubi_eba_atomic_leb_change(struct ubi_device *ubi, int vol_id, int lnum, if (vol->eba_tbl[lnum] >= 0) { err = ubi_wl_put_peb(ubi, vol->eba_tbl[lnum], 1); if (err) { ubi_free_vid_hdr(ubi, vid_hdr); leb_write_unlock(ubi, vol_id, lnum); return err; } if (err) goto out_leb_unlock; } vol->eba_tbl[lnum] = pnum; out_leb_unlock: leb_write_unlock(ubi, vol_id, lnum); out_mutex: mutex_unlock(&ubi->alc_mutex); ubi_free_vid_hdr(ubi, vid_hdr); return 0; return err; write_error: if (err != -EIO || !ubi->bad_allowed) { Loading @@ -913,17 +913,13 @@ int ubi_eba_atomic_leb_change(struct ubi_device *ubi, int vol_id, int lnum, * mode just in case. */ ubi_ro_mode(ubi); leb_write_unlock(ubi, vol_id, lnum); ubi_free_vid_hdr(ubi, vid_hdr); return err; goto out_leb_unlock; } err = ubi_wl_put_peb(ubi, pnum, 1); if (err || ++tries > UBI_IO_RETRIES) { ubi_ro_mode(ubi); leb_write_unlock(ubi, vol_id, lnum); ubi_free_vid_hdr(ubi, vid_hdr); return err; goto out_leb_unlock; } vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi)); Loading Loading @@ -965,7 +961,6 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, int err, vol_id, lnum, data_size, aldata_size, pnum, idx; struct ubi_volume *vol; uint32_t crc; void *buf, *buf1 = NULL; vol_id = be32_to_cpu(vid_hdr->vol_id); lnum = be32_to_cpu(vid_hdr->lnum); Loading @@ -979,19 +974,15 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, data_size = aldata_size = ubi->leb_size - be32_to_cpu(vid_hdr->data_pad); buf = vmalloc(aldata_size); if (!buf) return -ENOMEM; /* * We do not want anybody to write to this logical eraseblock while we * are moving it, so we lock it. */ err = leb_write_lock(ubi, vol_id, lnum); if (err) { vfree(buf); if (err) return err; } mutex_lock(&ubi->buf_mutex); /* * But the logical eraseblock might have been put by this time. Loading Loading @@ -1023,7 +1014,7 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, /* OK, now the LEB is locked and we can safely start moving it */ dbg_eba("read %d bytes of data", aldata_size); err = ubi_io_read_data(ubi, buf, from, 0, aldata_size); err = ubi_io_read_data(ubi, ubi->peb_buf1, from, 0, aldata_size); if (err && err != UBI_IO_BITFLIPS) { ubi_warn("error %d while reading data from PEB %d", err, from); Loading @@ -1042,10 +1033,10 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, */ if (vid_hdr->vol_type == UBI_VID_DYNAMIC) aldata_size = data_size = ubi_calc_data_len(ubi, buf, data_size); ubi_calc_data_len(ubi, ubi->peb_buf1, data_size); cond_resched(); crc = crc32(UBI_CRC32_INIT, buf, data_size); crc = crc32(UBI_CRC32_INIT, ubi->peb_buf1, data_size); cond_resched(); /* Loading Loading @@ -1076,23 +1067,18 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, } if (data_size > 0) { err = ubi_io_write_data(ubi, buf, to, 0, aldata_size); err = ubi_io_write_data(ubi, ubi->peb_buf1, to, 0, aldata_size); if (err) goto out_unlock; cond_resched(); /* * We've written the data and are going to read it back to make * sure it was written correctly. */ buf1 = vmalloc(aldata_size); if (!buf1) { err = -ENOMEM; goto out_unlock; } cond_resched(); err = ubi_io_read_data(ubi, buf1, to, 0, aldata_size); err = ubi_io_read_data(ubi, ubi->peb_buf2, to, 0, aldata_size); if (err) { if (err != UBI_IO_BITFLIPS) ubi_warn("cannot read data back from PEB %d", Loading @@ -1102,7 +1088,7 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, cond_resched(); if (memcmp(buf, buf1, aldata_size)) { if (memcmp(ubi->peb_buf1, ubi->peb_buf2, aldata_size)) { ubi_warn("read data back from PEB %d - it is different", to); goto out_unlock; Loading @@ -1112,16 +1098,9 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, ubi_assert(vol->eba_tbl[lnum] == from); vol->eba_tbl[lnum] = to; leb_write_unlock(ubi, vol_id, lnum); vfree(buf); vfree(buf1); return 0; out_unlock: mutex_unlock(&ubi->buf_mutex); leb_write_unlock(ubi, vol_id, lnum); vfree(buf); vfree(buf1); return err; } Loading @@ -1144,6 +1123,7 @@ int ubi_eba_init_scan(struct ubi_device *ubi, struct ubi_scan_info *si) dbg_eba("initialize EBA unit"); spin_lock_init(&ubi->ltree_lock); mutex_init(&ubi->alc_mutex); ubi->ltree = RB_ROOT; if (ubi_devices_cnt == 0) { Loading Loading @@ -1205,6 +1185,15 @@ int ubi_eba_init_scan(struct ubi_device *ubi, struct ubi_scan_info *si) ubi->rsvd_pebs += ubi->beb_rsvd_pebs; } if (ubi->avail_pebs < EBA_RESERVED_PEBS) { ubi_err("no enough physical eraseblocks (%d, need %d)", ubi->avail_pebs, EBA_RESERVED_PEBS); err = -ENOSPC; goto out_free; } ubi->avail_pebs -= EBA_RESERVED_PEBS; ubi->rsvd_pebs += EBA_RESERVED_PEBS; dbg_eba("EBA unit is initialized"); return 0; Loading
drivers/mtd/ubi/io.c +35 −40 Original line number Diff line number Diff line Loading @@ -98,8 +98,8 @@ static int paranoid_check_ec_hdr(const struct ubi_device *ubi, int pnum, static int paranoid_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum); static int paranoid_check_vid_hdr(const struct ubi_device *ubi, int pnum, const struct ubi_vid_hdr *vid_hdr); static int paranoid_check_all_ff(const struct ubi_device *ubi, int pnum, int offset, int len); static int paranoid_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len); #else #define paranoid_check_not_bad(ubi, pnum) 0 #define paranoid_check_peb_ec_hdr(ubi, pnum) 0 Loading Loading @@ -202,8 +202,8 @@ int ubi_io_read(const struct ubi_device *ubi, void *buf, int pnum, int offset, * Note, in case of an error, it is possible that something was still written * to the flash media, but may be some garbage. */ int ubi_io_write(const struct ubi_device *ubi, const void *buf, int pnum, int offset, int len) int ubi_io_write(struct ubi_device *ubi, const void *buf, int pnum, int offset, int len) { int err; size_t written; Loading Loading @@ -285,7 +285,7 @@ static void erase_callback(struct erase_info *ei) * zero in case of success and a negative error code in case of failure. If * %-EIO is returned, the physical eraseblock most probably went bad. */ static int do_sync_erase(const struct ubi_device *ubi, int pnum) static int do_sync_erase(struct ubi_device *ubi, int pnum) { int err, retries = 0; struct erase_info ei; Loading Loading @@ -377,29 +377,25 @@ static uint8_t patterns[] = {0xa5, 0x5a, 0x0}; * test, a positive number of erase operations done if the test was * successfully passed, and other negative error codes in case of other errors. */ static int torture_peb(const struct ubi_device *ubi, int pnum) static int torture_peb(struct ubi_device *ubi, int pnum) { void *buf; int err, i, patt_count; buf = vmalloc(ubi->peb_size); if (!buf) return -ENOMEM; patt_count = ARRAY_SIZE(patterns); ubi_assert(patt_count > 0); mutex_lock(&ubi->buf_mutex); for (i = 0; i < patt_count; i++) { err = do_sync_erase(ubi, pnum); if (err) goto out; /* Make sure the PEB contains only 0xFF bytes */ err = ubi_io_read(ubi, buf, pnum, 0, ubi->peb_size); err = ubi_io_read(ubi, ubi->peb_buf1, pnum, 0, ubi->peb_size); if (err) goto out; err = check_pattern(buf, 0xFF, ubi->peb_size); err = check_pattern(ubi->peb_buf1, 0xFF, ubi->peb_size); if (err == 0) { ubi_err("erased PEB %d, but a non-0xFF byte found", pnum); Loading @@ -408,17 +404,17 @@ static int torture_peb(const struct ubi_device *ubi, int pnum) } /* Write a pattern and check it */ memset(buf, patterns[i], ubi->peb_size); err = ubi_io_write(ubi, buf, pnum, 0, ubi->peb_size); memset(ubi->peb_buf1, patterns[i], ubi->peb_size); err = ubi_io_write(ubi, ubi->peb_buf1, pnum, 0, ubi->peb_size); if (err) goto out; memset(buf, ~patterns[i], ubi->peb_size); err = ubi_io_read(ubi, buf, pnum, 0, ubi->peb_size); memset(ubi->peb_buf1, ~patterns[i], ubi->peb_size); err = ubi_io_read(ubi, ubi->peb_buf1, pnum, 0, ubi->peb_size); if (err) goto out; err = check_pattern(buf, patterns[i], ubi->peb_size); err = check_pattern(ubi->peb_buf1, patterns[i], ubi->peb_size); if (err == 0) { ubi_err("pattern %x checking failed for PEB %d", patterns[i], pnum); Loading @@ -430,14 +426,17 @@ static int torture_peb(const struct ubi_device *ubi, int pnum) err = patt_count; out: if (err == UBI_IO_BITFLIPS || err == -EBADMSG) mutex_unlock(&ubi->buf_mutex); if (err == UBI_IO_BITFLIPS || err == -EBADMSG) { /* * If a bit-flip or data integrity error was detected, the test * has not passed because it happened on a freshly erased * physical eraseblock which means something is wrong with it. */ ubi_err("read problems on freshly erased PEB %d, must be bad", pnum); err = -EIO; vfree(buf); } return err; } Loading @@ -457,7 +456,7 @@ static int torture_peb(const struct ubi_device *ubi, int pnum) * codes in case of other errors. Note, %-EIO means that the physical * eraseblock is bad. */ int ubi_io_sync_erase(const struct ubi_device *ubi, int pnum, int torture) int ubi_io_sync_erase(struct ubi_device *ubi, int pnum, int torture) { int err, ret = 0; Loading Loading @@ -614,7 +613,7 @@ static int validate_ec_hdr(const struct ubi_device *ubi, * o %UBI_IO_PEB_EMPTY if the physical eraseblock is empty; * o a negative error code in case of failure. */ int ubi_io_read_ec_hdr(const struct ubi_device *ubi, int pnum, int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum, struct ubi_ec_hdr *ec_hdr, int verbose) { int err, read_err = 0; Loading Loading @@ -720,7 +719,7 @@ int ubi_io_read_ec_hdr(const struct ubi_device *ubi, int pnum, * case of failure. If %-EIO is returned, the physical eraseblock most probably * went bad. */ int ubi_io_write_ec_hdr(const struct ubi_device *ubi, int pnum, int ubi_io_write_ec_hdr(struct ubi_device *ubi, int pnum, struct ubi_ec_hdr *ec_hdr) { int err; Loading Loading @@ -886,7 +885,7 @@ static int validate_vid_hdr(const struct ubi_device *ubi, * header there); * o a negative error code in case of failure. */ int ubi_io_read_vid_hdr(const struct ubi_device *ubi, int pnum, int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum, struct ubi_vid_hdr *vid_hdr, int verbose) { int err, read_err = 0; Loading Loading @@ -993,7 +992,7 @@ int ubi_io_read_vid_hdr(const struct ubi_device *ubi, int pnum, * case of failure. If %-EIO is returned, the physical eraseblock probably went * bad. */ int ubi_io_write_vid_hdr(const struct ubi_device *ubi, int pnum, int ubi_io_write_vid_hdr(struct ubi_device *ubi, int pnum, struct ubi_vid_hdr *vid_hdr) { int err; Loading Loading @@ -1096,7 +1095,7 @@ static int paranoid_check_peb_ec_hdr(const struct ubi_device *ubi, int pnum) uint32_t crc, hdr_crc; struct ubi_ec_hdr *ec_hdr; ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL); ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_NOFS); if (!ec_hdr) return -ENOMEM; Loading Loading @@ -1176,7 +1175,7 @@ static int paranoid_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum) struct ubi_vid_hdr *vid_hdr; void *p; vid_hdr = ubi_zalloc_vid_hdr(ubi); vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); if (!vid_hdr) return -ENOMEM; Loading Loading @@ -1216,44 +1215,40 @@ static int paranoid_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum) * @offset of the physical eraseblock @pnum, %1 if not, and a negative error * code if an error occurred. */ static int paranoid_check_all_ff(const struct ubi_device *ubi, int pnum, int offset, int len) static int paranoid_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len) { size_t read; int err; void *buf; loff_t addr = (loff_t)pnum * ubi->peb_size + offset; buf = vmalloc(len); if (!buf) return -ENOMEM; memset(buf, 0, len); err = ubi->mtd->read(ubi->mtd, addr, len, &read, buf); mutex_lock(&ubi->dbg_buf_mutex); err = ubi->mtd->read(ubi->mtd, addr, len, &read, ubi->dbg_peb_buf); if (err && err != -EUCLEAN) { ubi_err("error %d while reading %d bytes from PEB %d:%d, " "read %zd bytes", err, len, pnum, offset, read); goto error; } err = check_pattern(buf, 0xFF, len); err = check_pattern(ubi->dbg_peb_buf, 0xFF, len); if (err == 0) { ubi_err("flash region at PEB %d:%d, length %d does not " "contain all 0xFF bytes", pnum, offset, len); goto fail; } mutex_unlock(&ubi->dbg_buf_mutex); vfree(buf); return 0; fail: ubi_err("paranoid check failed for PEB %d", pnum); dbg_msg("hex dump of the %d-%d region", offset, offset + len); ubi_dbg_hexdump(buf, len); print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, ubi->dbg_peb_buf, len, 1); err = 1; error: ubi_dbg_dump_stack(); vfree(buf); mutex_unlock(&ubi->dbg_buf_mutex); return err; } Loading