/** * self_check_write - make sure write succeeded. * @ubi: UBI device description object * @buf: buffer with data which were written * @pnum: physical eraseblock number the data were written to * @offset: offset within the physical eraseblock the data were written to * @len: how many bytes were written * * This functions reads data which were recently written and compares it with * the original data buffer - the data have to match. Returns zero if the data * match and a negative error code if not or in case of failure. */ static int self_check_write(struct ubi_device *ubi, const void *buf, int pnum, int offset, int len) { int err, i; size_t read; void *buf1; loff_t addr = (loff_t)pnum * ubi->peb_size + offset; if (!ubi_dbg_chk_io(ubi)) return 0; buf1 = __vmalloc(len, GFP_NOFS, PAGE_KERNEL); if (!buf1) { ubi_err("cannot allocate memory to check writes"); return 0; } err = mtd_read(ubi->mtd, addr, len, &read, buf1); if (err && !mtd_is_bitflip(err)) goto out_free; for (i = 0; i < len; i++) { uint8_t c = ((uint8_t *)buf)[i]; uint8_t c1 = ((uint8_t *)buf1)[i]; #if !defined(CONFIG_UBI_SILENCE_MSG) int dump_len = max_t(int, 128, len - i); #endif if (c == c1) continue; ubi_err("self-check failed for PEB %d:%d, len %d", pnum, offset, len); ubi_msg("data differ at position %d", i); ubi_msg("hex dump of the original buffer from %d to %d", i, i + dump_len); print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, buf + i, dump_len, 1); ubi_msg("hex dump of the read buffer from %d to %d", i, i + dump_len); print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, buf1 + i, dump_len, 1); dump_stack(); err = -EINVAL; goto out_free; } vfree(buf1); return 0; out_free: vfree(buf1); return err; }
static int ubi_io_read_vid_hdr(struct ubi_scan_info *ubi, int pnum, struct ubi_vid_hdr *vh, int unused) { u32 magic; int res; /* No point in rescanning a corrupt block */ if (test_bit(pnum, ubi->corrupt)) return UBI_IO_BAD_HDR; /* * If the block has been scanned already, no need to rescan */ if (test_and_set_bit(pnum, ubi->scanned)) return 0; res = ubi_io_read(ubi, vh, pnum, ubi->vid_offset, sizeof(*vh)); /* * Bad block, unrecoverable ECC error, skip the block */ if (res) { ubi_dbg("Skipping bad or unreadable block %d", pnum); vh->magic = 0; generic_set_bit(pnum, ubi->corrupt); return res; } /* Magic number available ? */ magic = be32_to_cpu(vh->magic); if (magic != UBI_VID_HDR_MAGIC) { generic_set_bit(pnum, ubi->corrupt); if (magic == 0xffffffff) return UBI_IO_FF; ubi_msg("Bad magic in block 0%d %08x", pnum, magic); return UBI_IO_BAD_HDR; } /* Header CRC correct ? */ if (crc32(UBI_CRC32_INIT, vh, UBI_VID_HDR_SIZE_CRC) != be32_to_cpu(vh->hdr_crc)) { ubi_msg("Bad CRC in block 0%d", pnum); generic_set_bit(pnum, ubi->corrupt); return UBI_IO_BAD_HDR; } ubi_dbg("RV: pnum: %i sqnum %llu", pnum, be64_to_cpu(vh->sqnum)); return 0; }
/* Read one page with oob one time */ int ubi_io_read_oob(const struct ubi_device *ubi, void *databuf, void *oobbuf, int pnum, int offset) { int err; loff_t addr; struct mtd_oob_ops ops; dbg_io("read from PEB %d:%d", pnum, offset); ubi_assert(pnum >= 0 && pnum < ubi->peb_count); ubi_assert(offset >= 0 && offset + ubi->mtd->writesize <= ubi->peb_size); addr = (loff_t)pnum * ubi->peb_size + offset; ops.mode = MTD_OPS_AUTO_OOB; ops.ooblen = ubi->mtd->oobavail; ops.oobbuf = oobbuf; ops.ooboffs = 0; ops.len = ubi->mtd->writesize; ops.datbuf = databuf; ops.retlen = ops.oobretlen = 0; err = mtd_read_oob(ubi->mtd, addr, &ops); if (err) { if (err == -EUCLEAN) { /* * -EUCLEAN is reported if there was a bit-flip which * was corrected, so this is harmless. * * We do not report about it here unless debugging is * enabled. A corresponding message will be printed * later, when it is has been scrubbed. */ ubi_msg("fixable bit-flip detected at addr %lld", addr); if(oobbuf) ubi_assert(ops.oobretlen == ops.ooblen); return UBI_IO_BITFLIPS; } if (ops.retlen != ops.len && err == -EBADMSG) { ubi_err("err(%d), retlen(%zu), len(%zu)", err, ops.retlen, ops.len); dump_stack(); err = -EIO; } ubi_msg("mtd_read_oob err %d\n", err); } return err; }
/** * ubi_dbg_check_all_ff - check that a region of flash is empty. * @ubi: UBI device description object * @pnum: the physical eraseblock number to check * @offset: the starting offset within the physical eraseblock to check * @len: the length of the region to check * * This function returns zero if only 0xFF bytes are present at offset * @offset of the physical eraseblock @pnum, and a negative error code if not * or if an error occurred. */ int ubi_dbg_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len) { size_t read; int err; loff_t addr = (loff_t)pnum * ubi->peb_size + offset; 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(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); return 0; fail: ubi_err("paranoid check failed for PEB %d", pnum); ubi_msg("hex dump of the %d-%d region", offset, offset + len); print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, ubi->dbg_peb_buf, len, 1); err = -EINVAL; error: ubi_dbg_dump_stack(); mutex_unlock(&ubi->dbg_buf_mutex); return err; }
int ubi_volume_cdev_add(struct ubi_device *ubi, struct ubi_volume *vol) { struct cdev *cdev = &vol->cdev; struct ubi_volume_cdev_priv *priv; int ret; priv = kzalloc(sizeof(*priv), GFP_KERNEL); priv->vol = vol; priv->ubi = ubi; cdev->ops = &ubi_volume_fops; cdev->name = asprintf("ubi%d.%s", ubi->ubi_num, vol->name); cdev->priv = priv; cdev->size = vol->used_bytes; cdev->dev = &vol->dev; ubi_msg("registering %s as /dev/%s\n", vol->name, cdev->name); ret = devfs_create(cdev); if (ret) { kfree(priv); free(cdev->name); } list_add_tail(&vol->list, &ubi_volumes_list); return 0; }
static void ubi_dump_vol_info_wide(const struct ubi_volume *vol) { char name[UBI_VOL_NAME_MAX+1], type[] = "UNKNOWN (%d)XXX"; memset(name, 0, sizeof(name)); if (vol->name_len <= UBI_VOL_NAME_MAX && strnlen(vol->name, vol->name_len + 1) == vol->name_len) { strcpy(name, vol->name); } else { strncpy(name, vol->name, 5); } if (vol->vol_type == UBI_DYNAMIC_VOLUME) strcpy(type, "dynamic"); else if (vol->vol_type == UBI_STATIC_VOLUME) strcpy(type, "static"); else sprintf(type, "Unknown (%d)", vol->vol_type); ubi_msg(UBI_LAYOUT_DATA_FMT, vol->vol_id, vol->reserved_pebs, vol->alignment, vol->data_pad, type, vol->usable_leb_size, vol->used_ebs, (long)vol->used_bytes, vol->last_eb_bytes, vol->corrupted, vol->upd_marker, vol->name_len, name); }
int ubi_volume_cdev_add(struct ubi_device *ubi, struct ubi_volume *vol) { struct cdev *cdev = &vol->cdev; struct ubi_volume_cdev_priv *priv; int ret; priv = kzalloc(sizeof(*priv), GFP_KERNEL); priv->vol = vol; priv->ubi = ubi; cdev->ops = &ubi_volume_fops; cdev->name = basprintf("%s.%s", ubi->cdev.name, vol->name); cdev->priv = priv; cdev->size = vol->used_bytes; if (vol->vol_type == UBI_STATIC_VOLUME) cdev->flags = DEVFS_IS_CHARACTER_DEV; cdev->dev = &vol->dev; ubi_msg(ubi, "registering %s as /dev/%s", vol->name, cdev->name); ret = devfs_create(cdev); if (ret) { kfree(priv); free(cdev->name); } list_add_tail(&vol->list, &ubi_volumes_list); return 0; }
/** * ubi_dump_flash - dump a region of flash. * @ubi: UBI device description object * @pnum: the physical eraseblock number to dump * @offset: the starting offset within the physical eraseblock to dump * @len: the length of the region to dump */ void ubi_dump_flash(struct ubi_device *ubi, int pnum, int offset, int len) { int err; size_t read; void *buf; loff_t addr = (loff_t)pnum * ubi->peb_size + offset; buf = vmalloc(len); if (!buf) return; err = mtd_read(ubi->mtd, addr, len, &read, buf); if (err && err != -EUCLEAN) { ubi_err(ubi->ubi_num, "err %d while reading %d bytes from PEB %d:%d, read %zd bytes", err, len, pnum, offset, read); goto out; } if (ubi->lookuptbl) { if (ubi->lookuptbl[pnum]->rc < UBI_MAX_READCOUNTER) ubi->lookuptbl[pnum]->rc++; else ubi_err(ubi->ubi_num, "read counter overflow at PEB %d, RC %d", pnum, ubi->lookuptbl[pnum]->rc); } else ubi_err(ubi->ubi_num, "Can't update RC. No lookuptbl"); ubi_msg(ubi->ubi_num, "dumping %d bytes of data from PEB %d, offset %d", len, pnum, offset); print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, buf, len, 1); out: vfree(buf); return; }
static int ubi_remove_vol(char *volume) { int err, reserved_pebs, i; struct ubi_volume *vol; vol = ubi_find_volume(volume); if (vol == NULL) return ENODEV; if (!strncmp(vol->name, "Factory", 7)) { printf("Remove volume %s is inhibited\n", vol->name); return EROFS; } printf("Remove UBI volume %s (id %d)\n", vol->name, vol->vol_id); if (ubi->ro_mode) { printf("It's read-only mode\n"); err = EROFS; goto out_err; } err = ubi_change_vtbl_record(ubi, vol->vol_id, NULL); if (err) { printf("Error changing Vol tabel record err=%x\n", err); goto out_err; } reserved_pebs = vol->reserved_pebs; for (i = 0; i < vol->reserved_pebs; i++) { err = ubi_eba_unmap_leb(ubi, vol, i); if (err) goto out_err; } kfree(vol->eba_tbl); ubi->volumes[vol->vol_id]->eba_tbl = NULL; ubi->volumes[vol->vol_id] = NULL; ubi->rsvd_pebs -= reserved_pebs; ubi->avail_pebs += reserved_pebs; i = ubi->beb_rsvd_level - ubi->beb_rsvd_pebs; if (i > 0) { i = ubi->avail_pebs >= i ? i : ubi->avail_pebs; ubi->avail_pebs -= i; ubi->rsvd_pebs += i; ubi->beb_rsvd_pebs += i; if (i > 0) ubi_msg("reserve more %d PEBs", i); } ubi->vol_count -= 1; return 0; out_err: ubi_err("cannot remove volume %s, error %d", volume, err); if (err < 0) err = -err; return err; }
void ubi_cdev_remove(struct ubi_device *ubi) { struct cdev *cdev = &ubi->cdev; ubi_msg(ubi, "removing %s", cdev->name); devfs_remove(cdev); kfree(cdev->name); }
/** * ubi_dbg_check_write - make sure write succeeded. * @ubi: UBI device description object * @buf: buffer with data which were written * @pnum: physical eraseblock number the data were written to * @offset: offset within the physical eraseblock the data were written to * @len: how many bytes were written * * This functions reads data which were recently written and compares it with * the original data buffer - the data have to match. Returns zero if the data * match and a negative error code if not or in case of failure. */ int ubi_dbg_check_write(struct ubi_device *ubi, const void *buf, int pnum, int offset, int len) { int err, i; mutex_lock(&ubi->dbg_buf_mutex); err = ubi_io_read(ubi, ubi->dbg_peb_buf, pnum, offset, len); if (err) goto out_unlock; for (i = 0; i < len; i++) { uint8_t c = ((uint8_t *)buf)[i]; uint8_t c1 = ((uint8_t *)ubi->dbg_peb_buf)[i]; int dump_len; if (c == c1) continue; ubi_err("paranoid check failed for PEB %d:%d, len %d", pnum, offset, len); ubi_msg("data differ at position %d", i); dump_len = max_t(int, 128, len - i); ubi_msg("hex dump of the original buffer from %d to %d", i, i + dump_len); print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, buf + i, dump_len, 1); ubi_msg("hex dump of the read buffer from %d to %d", i, i + dump_len); print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, ubi->dbg_peb_buf + i, dump_len, 1); ubi_dbg_dump_stack(); err = -EINVAL; goto out_unlock; } mutex_unlock(&ubi->dbg_buf_mutex); return 0; out_unlock: mutex_unlock(&ubi->dbg_buf_mutex); return err; }
int ubispl_load_volumes(struct ubispl_info *info, struct ubispl_load *lvols, int nrvols) { struct ubi_scan_info *ubi = info->ubi; int res, i, fastmap = info->fastmap; u32 fsize; retry: /* * We do a partial initializiation of @ubi. Cleaning fm_buf is * not necessary. */ memset(ubi, 0, offsetof(struct ubi_scan_info, fm_buf)); ubi->read = info->read; /* Precalculate the offsets */ ubi->vid_offset = info->vid_offset; ubi->leb_start = info->leb_start; ubi->leb_size = info->peb_size - ubi->leb_start; ubi->peb_count = info->peb_count; ubi->peb_offset = info->peb_offset; fsize = info->peb_size * info->peb_count; ubi->fsize_mb = fsize >> 20; /* Fastmap init */ ubi->fm_size = ubi_calc_fm_size(ubi); ubi->fm_enabled = fastmap; for (i = 0; i < nrvols; i++) { struct ubispl_load *lv = lvols + i; generic_set_bit(lv->vol_id, ubi->toload); } ipl_scan(ubi); for (i = 0; i < nrvols; i++) { struct ubispl_load *lv = lvols + i; ubi_msg("Loading VolId #%d", lv->vol_id); res = ipl_load(ubi, lv->vol_id, lv->load_addr); if (res < 0) { if (fastmap) { fastmap = 0; goto retry; } ubi_warn("Failed"); return res; } } return 0; }
/** * ubi_io_read - read data from a physical eraseblock. * @ubi: UBI device description object * @buf: buffer where to store the read data * @pnum: physical eraseblock number to read from * @offset: offset within the physical eraseblock from where to read * @len: how many bytes to read * * This function reads data from offset @offset of physical eraseblock @pnum * and stores the read data in the @buf buffer. The following return codes are * possible: * * o %0 if all the requested data were successfully read; * o %UBI_IO_BITFLIPS if all the requested data were successfully read, but * correctable bit-flips were detected; this is harmless but may indicate * that this eraseblock may become bad soon (but do not have to); * o %-EBADMSG if the MTD subsystem reported about data integrity problems, for * example it can be an ECC error in case of NAND; this most probably means * that the data is corrupted; * o %-EIO if some I/O error occurred; * o other negative error codes in case of other errors. */ int ubi_io_read(const struct ubi_device *ubi, void *buf, int pnum, int offset, int len) { int err, retries = 0; size_t read; loff_t addr; dbg_io("read %d bytes from PEB %d:%d", len, pnum, offset); ubi_assert(pnum >= 0 && pnum < ubi->peb_count); ubi_assert(offset >= 0 && offset + len <= ubi->peb_size); ubi_assert(len > 0); err = paranoid_check_not_bad(ubi, pnum); if (err) return err > 0 ? -EINVAL : err; addr = (loff_t)pnum * ubi->peb_size + offset; retry: err = ubi->mtd->read(ubi->mtd, addr, len, &read, buf); if (err) { if (err == -EUCLEAN) { /* * -EUCLEAN is reported if there was a bit-flip which * was corrected, so this is harmless. */ ubi_msg("fixable bit-flip detected at PEB %d", pnum); ubi_assert(len == read); return UBI_IO_BITFLIPS; } if (read != len && retries++ < UBI_IO_RETRIES) { dbg_io("error %d while reading %d bytes from PEB %d:%d, " "read only %zd bytes, retry", err, len, pnum, offset, read); yield(); goto retry; } ubi_err("error %d while reading %d bytes from PEB %d:%d, " "read %zd bytes", err, len, pnum, offset, read); ubi_dbg_dump_stack(); } else { ubi_assert(len == read); if (ubi_dbg_is_bitflip()) { dbg_msg("bit-flip (emulated)"); err = UBI_IO_BITFLIPS; } } return err; }
/** * ubi_detach_mtd_dev - detach an MTD device. * @ubi_num: UBI device number to detach from * @anyway: detach MTD even if device reference count is not zero * * This function destroys an UBI device number @ubi_num and detaches the * underlying MTD device. Returns zero in case of success and %-EBUSY if the * UBI device is busy and cannot be destroyed, and %-EINVAL if it does not * exist. * * Note, the invocations of this function has to be serialized by the * @ubi_devices_mutex. */ int ubi_detach_mtd_dev(int ubi_num, int anyway) { struct ubi_device *ubi; if (ubi_num < 0 || ubi_num >= UBI_MAX_DEVICES) return -EINVAL; ubi = ubi_get_device(ubi_num); if (!ubi) return -EINVAL; ubi->ref_count--; if (ubi->ref_count) return -EBUSY; ubi_devices[ubi_num] = NULL; ubi_assert(ubi_num == ubi->ubi_num); ubi_msg("detaching mtd%d from ubi%d", ubi->mtd->index, ubi_num); #ifdef CONFIG_MTD_UBI_FASTMAP /* If we don't write a new fastmap at detach time we lose all * EC updates that have been made since the last written fastmap. */ ubi_update_fastmap(ubi); ubi_free_fastmap(ubi); #endif uif_close(ubi); ubi_wl_close(ubi); ubi_free_internal_volumes(ubi); vfree(ubi->vtbl); vfree(ubi->peb_buf); vfree(ubi->fm_buf); ubi_msg("mtd%d is detached from ubi%d", ubi->mtd->index, ubi->ubi_num); kfree(ubi); return 0; }
int ubi_cdev_add(struct ubi_device *ubi) { struct cdev *cdev = &ubi->cdev; int ret; cdev->ops = &ubi_fops; cdev->name = basprintf("%s.ubi", ubi->mtd->cdev.name); cdev->priv = ubi; cdev->size = 0; ubi_msg(ubi, "registering /dev/%s", cdev->name); ret = devfs_create(cdev); if (ret) kfree(cdev->name); return ret; }
/** * autoresize - re-size the volume which has the "auto-resize" flag set. * @ubi: UBI device description object * @vol_id: ID of the volume to re-size * * This function re-sizes the volume marked by the %UBI_VTBL_AUTORESIZE_FLG in * the volume table to the largest possible size. See comments in ubi-header.h * for more description of the flag. Returns zero in case of success and a * negative error code in case of failure. */ static int autoresize(struct ubi_device *ubi, int vol_id) { struct ubi_volume_desc desc; struct ubi_volume *vol = ubi->volumes[vol_id]; int err, old_reserved_pebs = vol->reserved_pebs; if (ubi->ro_mode) { ubi_warn("skip auto-resize because of R/O mode"); return 0; } /* * Clear the auto-resize flag in the volume in-memory copy of the * volume table, and 'ubi_resize_volume()' will propagate this change * to the flash. */ ubi->vtbl[vol_id].flags &= ~UBI_VTBL_AUTORESIZE_FLG; if (ubi->avail_pebs == 0) { struct ubi_vtbl_record vtbl_rec; /* * No available PEBs to re-size the volume, clear the flag on * flash and exit. */ vtbl_rec = ubi->vtbl[vol_id]; err = ubi_change_vtbl_record(ubi, vol_id, &vtbl_rec); if (err) ubi_err("cannot clean auto-resize flag for volume %d", vol_id); } else { desc.vol = vol; err = ubi_resize_volume(&desc, old_reserved_pebs + ubi->avail_pebs); if (err) ubi_err("cannot auto-resize volume %d", vol_id); } if (err) return err; ubi_msg("volume %d (\"%s\") re-sized from %d to %d LEBs", vol_id, vol->name, old_reserved_pebs, vol->reserved_pebs); return 0; }
/** * ubi_self_check_all_ff - check that a region of flash is empty. * @ubi: UBI device description object * @pnum: the physical eraseblock number to check * @offset: the starting offset within the physical eraseblock to check * @len: the length of the region to check * * This function returns zero if only 0xFF bytes are present at offset * @offset of the physical eraseblock @pnum, and a negative error code if not * or if an error occurred. */ int ubi_self_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; if (!ubi_dbg_chk_io(ubi)) return 0; buf = __vmalloc(len, GFP_NOFS, PAGE_KERNEL); if (!buf) { ubi_err(ubi, "cannot allocate memory to check for 0xFFs"); return 0; } err = mtd_read(ubi->mtd, addr, len, &read, buf); if (err && !mtd_is_bitflip(err)) { ubi_err(ubi, "err %d while reading %d bytes from PEB %d:%d, read %zd bytes", err, len, pnum, offset, read); goto error; } err = ubi_check_pattern(buf, 0xFF, len); if (err == 0) { ubi_err(ubi, "flash region at PEB %d:%d, length %d does not contain all 0xFF bytes", pnum, offset, len); goto fail; } vfree(buf); return 0; fail: ubi_err(ubi, "self-check failed for PEB %d", pnum); ubi_msg(ubi, "hex dump of the %d-%d region", offset, offset + len); print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, buf, len, 1); err = -EINVAL; error: dump_stack(); vfree(buf); return err; }
/** * ubi_dump_flash - dump a region of flash. * @ubi: UBI device description object * @pnum: the physical eraseblock number to dump * @offset: the starting offset within the physical eraseblock to dump * @len: the length of the region to dump */ void ubi_dump_flash(struct ubi_device *ubi, int pnum, int offset, int len) { int err; size_t read; void *buf; loff_t addr = (loff_t)pnum * ubi->peb_size + offset; buf = vmalloc(len); if (!buf) return; err = mtd_read(ubi->mtd, addr, len, &read, 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 out; } ubi_msg("dumping %d bytes of data from PEB %d, offset %d", len, pnum, offset); print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, buf, len, 1); out: vfree(buf); return; }
static void display_volume_info_wide(struct ubi_device *ubi) { int i; ubi_msg(UBI_LAYOUT_HEAD_FMT, "vol_id", "reserved_pebs", "alignment", "data_pad", "vol_type", "usable_leb_size", "used_ebs", "used_bytes", "last_eb_bytes", "corrupted", "upd_marker", "name_len", "name"); for (i = 0; i < (ubi->vtbl_slots + 1); i++) { if (!ubi->volumes[i]) continue; /* Empty record */ ubi_dump_vol_info_wide(ubi->volumes[i]); } }
static void display_ubi_info(struct ubi_device *ubi) { ubi_msg("MTD device name: \"%s\"", ubi->mtd->name); ubi_msg("MTD device size: %llu MiB", ubi->flash_size >> 20); ubi_msg("physical eraseblock size: %d bytes (%d KiB)", ubi->peb_size, ubi->peb_size >> 10); ubi_msg("logical eraseblock size: %d bytes", ubi->leb_size); ubi_msg("number of good PEBs: %d", ubi->good_peb_count); ubi_msg("number of bad PEBs: %d", ubi->bad_peb_count); ubi_msg("smallest flash I/O unit: %d", ubi->min_io_size); ubi_msg("VID header offset: %d (aligned %d)", ubi->vid_hdr_offset, ubi->vid_hdr_aloffset); ubi_msg("data offset: %d", ubi->leb_start); ubi_msg("max. allowed volumes: %d", ubi->vtbl_slots); ubi_msg("wear-leveling threshold: %d", CONFIG_MTD_UBI_WL_THRESHOLD); ubi_msg("number of internal volumes: %d", UBI_INT_VOL_COUNT); ubi_msg("number of user volumes: %d", ubi->vol_count - UBI_INT_VOL_COUNT); ubi_msg("available PEBs: %d", ubi->avail_pebs); ubi_msg("total number of reserved PEBs: %d", ubi->rsvd_pebs); ubi_msg("number of PEBs reserved for bad PEB handling: %d", ubi->beb_rsvd_pebs); ubi_msg("max/mean erase counter: %d/%d", ubi->max_ec, ubi->mean_ec); }
/** * torture_peb - test a supposedly bad physical eraseblock. * @ubi: UBI device description object * @pnum: the physical eraseblock number to test * * This function returns %-EIO if the physical eraseblock did not pass the * 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(struct ubi_device *ubi, int pnum) { int err, i, patt_count; ubi_msg(ubi, "run torture test for PEB %d", pnum); 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, ubi->peb_buf, pnum, 0, ubi->peb_size); if (err) goto out; err = ubi_check_pattern(ubi->peb_buf, 0xFF, ubi->peb_size); if (err == 0) { ubi_err(ubi, "erased PEB %d, but a non-0xFF byte found", pnum); err = -EIO; goto out; } /* Write a pattern and check it */ memset(ubi->peb_buf, patterns[i], ubi->peb_size); err = ubi_io_write(ubi, ubi->peb_buf, pnum, 0, ubi->peb_size); if (err) goto out; memset(ubi->peb_buf, ~patterns[i], ubi->peb_size); err = ubi_io_read(ubi, ubi->peb_buf, pnum, 0, ubi->peb_size); if (err) goto out; err = ubi_check_pattern(ubi->peb_buf, patterns[i], ubi->peb_size); if (err == 0) { ubi_err(ubi, "pattern %x checking failed for PEB %d", patterns[i], pnum); err = -EIO; goto out; } } err = patt_count; ubi_msg(ubi, "PEB %d passed torture test, do not mark it as bad", pnum); out: mutex_unlock(&ubi->buf_mutex); if (err == UBI_IO_BITFLIPS || mtd_is_eccerr(err)) { /* * 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(ubi, "read problems on freshly erased PEB %d, must be bad", pnum); err = -EIO; } return err; }
/** * ubi_io_read - read data from a physical eraseblock. * @ubi: UBI device description object * @buf: buffer where to store the read data * @pnum: physical eraseblock number to read from * @offset: offset within the physical eraseblock from where to read * @len: how many bytes to read * * This function reads data from offset @offset of physical eraseblock @pnum * and stores the read data in the @buf buffer. The following return codes are * possible: * * o %0 if all the requested data were successfully read; * o %UBI_IO_BITFLIPS if all the requested data were successfully read, but * correctable bit-flips were detected; this is harmless but may indicate * that this eraseblock may become bad soon (but do not have to); * o %-EBADMSG if the MTD subsystem reported about data integrity problems, for * example it can be an ECC error in case of NAND; this most probably means * that the data is corrupted; * o %-EIO if some I/O error occurred; * o other negative error codes in case of other errors. */ int ubi_io_read(const struct ubi_device *ubi, void *buf, int pnum, int offset, int len) { int err, retries = 0; size_t read; loff_t addr; dbg_io("read %d bytes from PEB %d:%d", len, pnum, offset); ubi_assert(pnum >= 0 && pnum < ubi->peb_count); ubi_assert(offset >= 0 && offset + len <= ubi->peb_size); ubi_assert(len > 0); err = self_check_not_bad(ubi, pnum); if (err) return err; /* * Deliberately corrupt the buffer to improve robustness. Indeed, if we * do not do this, the following may happen: * 1. The buffer contains data from previous operation, e.g., read from * another PEB previously. The data looks like expected, e.g., if we * just do not read anything and return - the caller would not * notice this. E.g., if we are reading a VID header, the buffer may * contain a valid VID header from another PEB. * 2. The driver is buggy and returns us success or -EBADMSG or * -EUCLEAN, but it does not actually put any data to the buffer. * * This may confuse UBI or upper layers - they may think the buffer * contains valid data while in fact it is just old data. This is * especially possible because UBI (and UBIFS) relies on CRC, and * treats data as correct even in case of ECC errors if the CRC is * correct. * * Try to prevent this situation by changing the first byte of the * buffer. */ *((uint8_t *)buf) ^= 0xFF; addr = (loff_t)pnum * ubi->peb_size + offset; retry: err = mtd_read(ubi->mtd, addr, len, &read, buf); if (err) { const char *errstr = mtd_is_eccerr(err) ? " (ECC error)" : ""; if (mtd_is_bitflip(err)) { /* * -EUCLEAN is reported if there was a bit-flip which * was corrected, so this is harmless. * * We do not report about it here unless debugging is * enabled. A corresponding message will be printed * later, when it is has been scrubbed. */ ubi_msg(ubi, "fixable bit-flip detected at PEB %d", pnum); ubi_assert(len == read); return UBI_IO_BITFLIPS; } if (retries++ < UBI_IO_RETRIES) { ubi_warn(ubi, "error %d%s while reading %d bytes from PEB %d:%d, read only %zd bytes, retry", err, errstr, len, pnum, offset, read); yield(); goto retry; } ubi_err(ubi, "error %d%s while reading %d bytes from PEB %d:%d, read %zd bytes", err, errstr, len, pnum, offset, read); dump_stack(); /* * The driver should never return -EBADMSG if it failed to read * all the requested data. But some buggy drivers might do * this, so we change it to -EIO. */ if (read != len && mtd_is_eccerr(err)) { ubi_assert(0); err = -EIO; } } else { ubi_assert(len == read); if (ubi_dbg_is_bitflip(ubi)) { dbg_gen("bit-flip (emulated)"); err = UBI_IO_BITFLIPS; } } return err; }
static int ubi_remove_vol(char *volume) { int i, err, reserved_pebs; int found = 0, vol_id = 0; struct ubi_volume *vol; for (i = 0; i < ubi->vtbl_slots; i++) { vol = ubi->volumes[i]; if (vol && !strcmp(vol->name, volume)) { printf("Volume %s found at valid %d\n", volume, i); vol_id = i; found = 1; break; } } if (!found) { printf("%s volume not found\n", volume); return -ENODEV; } printf("remove UBI volume %s (id %d)\n", vol->name, vol->vol_id); if (ubi->ro_mode) { printf("It's read-only mode\n"); err = -EROFS; goto out_err; } err = ubi_change_vtbl_record(ubi, vol_id, NULL); if (err) { printf("Error changing Vol tabel record err=%x\n", err); goto out_err; } reserved_pebs = vol->reserved_pebs; for (i = 0; i < vol->reserved_pebs; i++) { err = ubi_eba_unmap_leb(ubi, vol, i); if (err) goto out_err; } kfree(vol->eba_tbl); ubi->volumes[vol_id]->eba_tbl = NULL; ubi->volumes[vol_id] = NULL; ubi->rsvd_pebs -= reserved_pebs; ubi->avail_pebs += reserved_pebs; i = ubi->beb_rsvd_level - ubi->beb_rsvd_pebs; if (i > 0) { i = ubi->avail_pebs >= i ? i : ubi->avail_pebs; ubi->avail_pebs -= i; ubi->rsvd_pebs += i; ubi->beb_rsvd_pebs += i; if (i > 0) ubi_msg("reserve more %d PEBs", i); } ubi->vol_count -= 1; return 0; out_err: ubi_err("cannot remove volume %d, error %d", vol_id, err); return err; }
/** * io_init - initialize I/O sub-system for a given UBI device. * @ubi: UBI device description object * @max_beb_per1024: maximum expected number of bad PEB per 1024 PEBs * * If @ubi->vid_hdr_offset or @ubi->leb_start is zero, default offsets are * assumed: * o EC header is always at offset zero - this cannot be changed; * o VID header starts just after the EC header at the closest address * aligned to @io->hdrs_min_io_size; * o data starts just after the VID header at the closest address aligned to * @io->min_io_size * * This function returns zero in case of success and a negative error code in * case of failure. */ static int io_init(struct ubi_device *ubi, int max_beb_per1024) { dbg_gen("sizeof(struct ubi_ainf_peb) %zu", sizeof(struct ubi_ainf_peb)); dbg_gen("sizeof(struct ubi_wl_entry) %zu", sizeof(struct ubi_wl_entry)); if (ubi->mtd->numeraseregions != 0) { /* * Some flashes have several erase regions. Different regions * may have different eraseblock size and other * characteristics. It looks like mostly multi-region flashes * have one "main" region and one or more small regions to * store boot loader code or boot parameters or whatever. I * guess we should just pick the largest region. But this is * not implemented. */ ubi_err("multiple regions, not implemented"); return -EINVAL; } if (ubi->vid_hdr_offset < 0) return -EINVAL; /* * Note, in this implementation we support MTD devices with 0x7FFFFFFF * physical eraseblocks maximum. */ ubi->peb_size = ubi->mtd->erasesize; ubi->peb_count = mtd_div_by_eb(ubi->mtd->size, ubi->mtd); ubi->flash_size = ubi->mtd->size; if (mtd_can_have_bb(ubi->mtd)) { ubi->bad_allowed = 1; ubi->bad_peb_limit = get_bad_peb_limit(ubi, max_beb_per1024); } if (ubi->mtd->type == MTD_NORFLASH) { ubi_assert(ubi->mtd->writesize == 1); ubi->nor_flash = 1; } ubi->min_io_size = ubi->mtd->writesize; ubi->hdrs_min_io_size = ubi->mtd->writesize >> ubi->mtd->subpage_sft; /* * Make sure minimal I/O unit is power of 2. Note, there is no * fundamental reason for this assumption. It is just an optimization * which allows us to avoid costly division operations. */ if (!is_power_of_2(ubi->min_io_size)) { ubi_err("min. I/O unit (%d) is not power of 2", ubi->min_io_size); return -EINVAL; } ubi_assert(ubi->hdrs_min_io_size > 0); ubi_assert(ubi->hdrs_min_io_size <= ubi->min_io_size); ubi_assert(ubi->min_io_size % ubi->hdrs_min_io_size == 0); ubi->max_write_size = ubi->mtd->writesize; /* FIXME: writebufsize */ /* * Maximum write size has to be greater or equivalent to min. I/O * size, and be multiple of min. I/O size. */ if (ubi->max_write_size < ubi->min_io_size || ubi->max_write_size % ubi->min_io_size || !is_power_of_2(ubi->max_write_size)) { ubi_err("bad write buffer size %d for %d min. I/O unit", ubi->max_write_size, ubi->min_io_size); return -EINVAL; } /* Calculate default aligned sizes of EC and VID headers */ ubi->ec_hdr_alsize = ALIGN(UBI_EC_HDR_SIZE, ubi->hdrs_min_io_size); ubi->vid_hdr_alsize = ALIGN(UBI_VID_HDR_SIZE, ubi->hdrs_min_io_size); dbg_gen("min_io_size %d", ubi->min_io_size); dbg_gen("max_write_size %d", ubi->max_write_size); dbg_gen("hdrs_min_io_size %d", ubi->hdrs_min_io_size); dbg_gen("ec_hdr_alsize %d", ubi->ec_hdr_alsize); dbg_gen("vid_hdr_alsize %d", ubi->vid_hdr_alsize); if (ubi->vid_hdr_offset == 0) /* Default offset */ ubi->vid_hdr_offset = ubi->vid_hdr_aloffset = ubi->ec_hdr_alsize; else { ubi->vid_hdr_aloffset = ubi->vid_hdr_offset & ~(ubi->hdrs_min_io_size - 1); ubi->vid_hdr_shift = ubi->vid_hdr_offset - ubi->vid_hdr_aloffset; } /* Similar for the data offset */ ubi->leb_start = ubi->vid_hdr_offset + UBI_VID_HDR_SIZE; ubi->leb_start = ALIGN(ubi->leb_start, ubi->min_io_size); dbg_gen("vid_hdr_offset %d", ubi->vid_hdr_offset); dbg_gen("vid_hdr_aloffset %d", ubi->vid_hdr_aloffset); dbg_gen("vid_hdr_shift %d", ubi->vid_hdr_shift); dbg_gen("leb_start %d", ubi->leb_start); /* The shift must be aligned to 32-bit boundary */ if (ubi->vid_hdr_shift % 4) { ubi_err("unaligned VID header shift %d", ubi->vid_hdr_shift); return -EINVAL; } /* Check sanity */ if (ubi->vid_hdr_offset < UBI_EC_HDR_SIZE || ubi->leb_start < ubi->vid_hdr_offset + UBI_VID_HDR_SIZE || ubi->leb_start > ubi->peb_size - UBI_VID_HDR_SIZE || ubi->leb_start & (ubi->min_io_size - 1)) { ubi_err("bad VID header (%d) or data offsets (%d)", ubi->vid_hdr_offset, ubi->leb_start); return -EINVAL; } /* * Set maximum amount of physical erroneous eraseblocks to be 10%. * Erroneous PEB are those which have read errors. */ ubi->max_erroneous = ubi->peb_count / 10; if (ubi->max_erroneous < 16) ubi->max_erroneous = 16; dbg_gen("max_erroneous %d", ubi->max_erroneous); /* * It may happen that EC and VID headers are situated in one minimal * I/O unit. In this case we can only accept this UBI image in * read-only mode. */ if (ubi->vid_hdr_offset + UBI_VID_HDR_SIZE <= ubi->hdrs_min_io_size) { ubi_warn("EC and VID headers are in the same minimal I/O unit, switch to read-only mode"); ubi->ro_mode = 1; } ubi->leb_size = ubi->peb_size - ubi->leb_start; if (!(ubi->mtd->flags & MTD_WRITEABLE)) { ubi_msg("MTD device %d is write-protected, attach in read-only mode", ubi->mtd->index); ubi->ro_mode = 1; } /* * Note, ideally, we have to initialize @ubi->bad_peb_count here. But * unfortunately, MTD does not provide this information. We should loop * over all physical eraseblocks and invoke mtd->block_is_bad() for * each physical eraseblock. So, we leave @ubi->bad_peb_count * uninitialized so far. */ return 0; }
static int ubi_scan_fastmap(struct ubi_scan_info *ubi, struct ubi_attach_info *ai, int fm_anchor) { struct ubi_fm_sb *fmsb, *fmsb2; struct ubi_vid_hdr *vh; struct ubi_fastmap_layout *fm; int i, used_blocks, pnum, ret = 0; size_t fm_size; __be32 crc, tmp_crc; unsigned long long sqnum = 0; fmsb = &ubi->fm_sb; fm = &ubi->fm_layout; ret = ubi_io_read(ubi, fmsb, fm_anchor, ubi->leb_start, sizeof(*fmsb)); if (ret && ret != UBI_IO_BITFLIPS) goto free_fm_sb; else if (ret == UBI_IO_BITFLIPS) fm->to_be_tortured[0] = 1; if (be32_to_cpu(fmsb->magic) != UBI_FM_SB_MAGIC) { ubi_err("bad super block magic: 0x%x, expected: 0x%x", be32_to_cpu(fmsb->magic), UBI_FM_SB_MAGIC); ret = UBI_BAD_FASTMAP; goto free_fm_sb; } if (fmsb->version != UBI_FM_FMT_VERSION) { ubi_err("bad fastmap version: %i, expected: %i", fmsb->version, UBI_FM_FMT_VERSION); ret = UBI_BAD_FASTMAP; goto free_fm_sb; } used_blocks = be32_to_cpu(fmsb->used_blocks); if (used_blocks > UBI_FM_MAX_BLOCKS || used_blocks < 1) { ubi_err("number of fastmap blocks is invalid: %i", used_blocks); ret = UBI_BAD_FASTMAP; goto free_fm_sb; } fm_size = ubi->leb_size * used_blocks; if (fm_size != ubi->fm_size) { ubi_err("bad fastmap size: %zi, expected: %zi", fm_size, ubi->fm_size); ret = UBI_BAD_FASTMAP; goto free_fm_sb; } vh = &ubi->fm_vh; for (i = 0; i < used_blocks; i++) { pnum = be32_to_cpu(fmsb->block_loc[i]); if (ubi_io_is_bad(ubi, pnum)) { ret = UBI_BAD_FASTMAP; goto free_hdr; } #ifdef LATER int image_seq; ret = ubi_io_read_ec_hdr(ubi, pnum, ech, 0); if (ret && ret != UBI_IO_BITFLIPS) { ubi_err("unable to read fastmap block# %i EC (PEB: %i)", i, pnum); if (ret > 0) ret = UBI_BAD_FASTMAP; goto free_hdr; } else if (ret == UBI_IO_BITFLIPS) fm->to_be_tortured[i] = 1; image_seq = be32_to_cpu(ech->image_seq); if (!ubi->image_seq) ubi->image_seq = image_seq; /* * Older UBI implementations have image_seq set to zero, so * we shouldn't fail if image_seq == 0. */ if (image_seq && (image_seq != ubi->image_seq)) { ubi_err("wrong image seq:%d instead of %d", be32_to_cpu(ech->image_seq), ubi->image_seq); ret = UBI_BAD_FASTMAP; goto free_hdr; } #endif ret = ubi_io_read_vid_hdr(ubi, pnum, vh, 0); if (ret && ret != UBI_IO_BITFLIPS) { ubi_err("unable to read fastmap block# %i (PEB: %i)", i, pnum); goto free_hdr; } /* * Mainline code rescans the anchor header. We've done * that already so we merily copy it over. */ if (pnum == fm_anchor) memcpy(vh, ubi->blockinfo + pnum, sizeof(*fm)); if (i == 0) { if (be32_to_cpu(vh->vol_id) != UBI_FM_SB_VOLUME_ID) { ubi_err("bad fastmap anchor vol_id: 0x%x," \ " expected: 0x%x", be32_to_cpu(vh->vol_id), UBI_FM_SB_VOLUME_ID); ret = UBI_BAD_FASTMAP; goto free_hdr; } } else { if (be32_to_cpu(vh->vol_id) != UBI_FM_DATA_VOLUME_ID) { ubi_err("bad fastmap data vol_id: 0x%x," \ " expected: 0x%x", be32_to_cpu(vh->vol_id), UBI_FM_DATA_VOLUME_ID); ret = UBI_BAD_FASTMAP; goto free_hdr; } } if (sqnum < be64_to_cpu(vh->sqnum)) sqnum = be64_to_cpu(vh->sqnum); ret = ubi_io_read(ubi, ubi->fm_buf + (ubi->leb_size * i), pnum, ubi->leb_start, ubi->leb_size); if (ret && ret != UBI_IO_BITFLIPS) { ubi_err("unable to read fastmap block# %i (PEB: %i, " \ "err: %i)", i, pnum, ret); goto free_hdr; } } fmsb2 = (struct ubi_fm_sb *)(ubi->fm_buf); tmp_crc = be32_to_cpu(fmsb2->data_crc); fmsb2->data_crc = 0; crc = crc32(UBI_CRC32_INIT, ubi->fm_buf, fm_size); if (crc != tmp_crc) { ubi_err("fastmap data CRC is invalid"); ubi_err("CRC should be: 0x%x, calc: 0x%x", tmp_crc, crc); ret = UBI_BAD_FASTMAP; goto free_hdr; } fmsb2->sqnum = sqnum; fm->used_blocks = used_blocks; ret = ubi_attach_fastmap(ubi, ai, fm); if (ret) { if (ret > 0) ret = UBI_BAD_FASTMAP; goto free_hdr; } ubi->fm = fm; ubi->fm_pool.max_size = ubi->fm->max_pool_size; ubi->fm_wl_pool.max_size = ubi->fm->max_wl_pool_size; ubi_msg("attached by fastmap %uMB %u blocks", ubi->fsize_mb, ubi->peb_count); ubi_dbg("fastmap pool size: %d", ubi->fm_pool.max_size); ubi_dbg("fastmap WL pool size: %d", ubi->fm_wl_pool.max_size); out: if (ret) ubi_err("Attach by fastmap failed, doing a full scan!"); return ret; free_hdr: free_fm_sb: goto out; }
static void ubi_dump_vol_info(const struct ubi_volume *vol) { ubi_msg("volume information dump:"); ubi_msg("vol_id %d", vol->vol_id); ubi_msg("reserved_pebs %d", vol->reserved_pebs); ubi_msg("alignment %d", vol->alignment); ubi_msg("data_pad %d", vol->data_pad); ubi_msg("vol_type %d", vol->vol_type); ubi_msg("name_len %d", vol->name_len); ubi_msg("usable_leb_size %d", vol->usable_leb_size); ubi_msg("used_ebs %d", vol->used_ebs); ubi_msg("used_bytes %lld", vol->used_bytes); ubi_msg("last_eb_bytes %d", vol->last_eb_bytes); ubi_msg("corrupted %d", vol->corrupted); ubi_msg("upd_marker %d", vol->upd_marker); if (vol->name_len <= UBI_VOL_NAME_MAX && strnlen(vol->name, vol->name_len + 1) == vol->name_len) { ubi_msg("name %s", vol->name); } else { ubi_msg("the 1st 5 characters of the name: %c%c%c%c%c", vol->name[0], vol->name[1], vol->name[2], vol->name[3], vol->name[4]); } printf("\n"); }
/** * ubi_io_read - read data from a physical eraseblock. * @ubi: UBI device description object * @buf: buffer where to store the read data * @pnum: physical eraseblock number to read from * @offset: offset within the physical eraseblock from where to read * @len: how many bytes to read * * This function reads data from offset @offset of physical eraseblock @pnum * and stores the read data in the @buf buffer. The following return codes are * possible: * * o %0 if all the requested data were successfully read; * o %UBI_IO_BITFLIPS if all the requested data were successfully read, but * correctable bit-flips were detected; this is harmless but may indicate * that this eraseblock may become bad soon (but do not have to); * o %-EBADMSG if the MTD subsystem reported about data integrity problems, for * example it can be an ECC error in case of NAND; this most probably means * that the data is corrupted; * o %-EIO if some I/O error occurred; * o other negative error codes in case of other errors. */ int ubi_io_read(const struct ubi_device *ubi, void *buf, int pnum, int offset, int len) { int err, retries = 0; size_t read; loff_t addr; dbg_io("read %d bytes from PEB %d:%d", len, pnum, offset); ubi_assert(pnum >= 0 && pnum < ubi->peb_count); ubi_assert(offset >= 0 && offset + len <= ubi->peb_size); ubi_assert(len > 0); err = paranoid_check_not_bad(ubi, pnum); if (err) return err > 0 ? -EINVAL : err; addr = (loff_t)pnum * ubi->peb_size + offset; retry: err = ubi->mtd->read(ubi->mtd, addr, len, &read, buf); if (err) { if (err == -EUCLEAN) { /* * -EUCLEAN is reported if there was a bit-flip which * was corrected, so this is harmless. */ ubi_msg("fixable bit-flip detected at PEB %d", pnum); ubi_assert(len == read); return UBI_IO_BITFLIPS; } if (read != len && retries++ < UBI_IO_RETRIES) { dbg_io("error %d while reading %d bytes from PEB %d:%d, " "read only %zd bytes, retry", err, len, pnum, offset, read); yield(); goto retry; } ubi_err("error %d while reading %d bytes from PEB %d:%d, " "read %zd bytes", err, len, pnum, offset, read); ubi_dbg_dump_stack(); /* * The driver should never return -EBADMSG if it failed to read * all the requested data. But some buggy drivers might do * this, so we change it to -EIO. */ if (read != len && err == -EBADMSG) { ubi_assert(0); printk("%s[%d] not here\n", __func__, __LINE__); /* err = -EIO; */ } } else { ubi_assert(len == read); if (ubi_dbg_is_bitflip()) { dbg_msg("bit-flip (emulated)"); err = UBI_IO_BITFLIPS; } } return err; }
/** * ubi_attach_mtd_dev - attach an MTD device. * @mtd: MTD device description object * @ubi_num: number to assign to the new UBI device * @vid_hdr_offset: VID header offset * @max_beb_per1024: maximum expected number of bad PEB per 1024 PEBs * * This function attaches MTD device @mtd_dev to UBI and assign @ubi_num number * to the newly created UBI device, unless @ubi_num is %UBI_DEV_NUM_AUTO, in * which case this function finds a vacant device number and assigns it * automatically. Returns the new UBI device number in case of success and a * negative error code in case of failure. * * Note, the invocations of this function has to be serialized by the * @ubi_devices_mutex. */ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset, int max_beb_per1024) { struct ubi_device *ubi; int i, err, ref = 0; if (max_beb_per1024 < 0 || max_beb_per1024 > MAX_MTD_UBI_BEB_LIMIT) return -EINVAL; if (!max_beb_per1024) max_beb_per1024 = CONFIG_MTD_UBI_BEB_LIMIT; /* * Check if we already have the same MTD device attached. * * Note, this function assumes that UBI devices creations and deletions * are serialized, so it does not take the &ubi_devices_lock. */ for (i = 0; i < UBI_MAX_DEVICES; i++) { ubi = ubi_devices[i]; if (ubi && mtd == ubi->mtd) { ubi_err("mtd%d is already attached to ubi%d", mtd->index, i); return -EEXIST; } } /* * Make sure this MTD device is not emulated on top of an UBI volume * already. Well, generally this recursion works fine, but there are * different problems like the UBI module takes a reference to itself * by attaching (and thus, opening) the emulated MTD device. This * results in inability to unload the module. And in general it makes * no sense to attach emulated MTD devices, so we prohibit this. */ if (mtd->type == MTD_UBIVOLUME) { ubi_err("refuse attaching mtd%d - it is already emulated on top of UBI", mtd->index); return -EINVAL; } if (ubi_num == UBI_DEV_NUM_AUTO) { /* Search for an empty slot in the @ubi_devices array */ for (ubi_num = 0; ubi_num < UBI_MAX_DEVICES; ubi_num++) if (!ubi_devices[ubi_num]) break; if (ubi_num == UBI_MAX_DEVICES) { ubi_err("only %d UBI devices may be created", UBI_MAX_DEVICES); return -ENFILE; } } else { if (ubi_num >= UBI_MAX_DEVICES) return -EINVAL; /* Make sure ubi_num is not busy */ if (ubi_devices[ubi_num]) { ubi_err("ubi%d already exists", ubi_num); return -EEXIST; } } ubi = kzalloc(sizeof(struct ubi_device), GFP_KERNEL); if (!ubi) return -ENOMEM; ubi->mtd = mtd; ubi->ubi_num = ubi_num; ubi->vid_hdr_offset = vid_hdr_offset; ubi->autoresize_vol_id = -1; #ifdef CONFIG_MTD_UBI_FASTMAP ubi->fm_pool.used = ubi->fm_pool.size = 0; ubi->fm_wl_pool.used = ubi->fm_wl_pool.size = 0; /* * fm_pool.max_size is 5% of the total number of PEBs but it's also * between UBI_FM_MAX_POOL_SIZE and UBI_FM_MIN_POOL_SIZE. */ ubi->fm_pool.max_size = min(((int)mtd_div_by_eb(ubi->mtd->size, ubi->mtd) / 100) * 5, UBI_FM_MAX_POOL_SIZE); if (ubi->fm_pool.max_size < UBI_FM_MIN_POOL_SIZE) ubi->fm_pool.max_size = UBI_FM_MIN_POOL_SIZE; ubi->fm_wl_pool.max_size = UBI_FM_WL_POOL_SIZE; ubi->fm_disabled = !fm_autoconvert; if (!ubi->fm_disabled && (int)mtd_div_by_eb(ubi->mtd->size, ubi->mtd) <= UBI_FM_MAX_START) { ubi_err("More than %i PEBs are needed for fastmap, sorry.", UBI_FM_MAX_START); ubi->fm_disabled = 1; } ubi_debug("default fastmap pool size: %d", ubi->fm_pool.max_size); ubi_debug("default fastmap WL pool size: %d", ubi->fm_wl_pool.max_size); #else ubi->fm_disabled = 1; #endif ubi_msg("attaching mtd%d to ubi%d", mtd->index, ubi_num); err = io_init(ubi, max_beb_per1024); if (err) goto out_free; err = -ENOMEM; ubi->peb_buf = vmalloc(ubi->peb_size); if (!ubi->peb_buf) goto out_free; #ifdef CONFIG_MTD_UBI_FASTMAP ubi->fm_size = ubi_calc_fm_size(ubi); ubi->fm_buf = kzalloc(ubi->fm_size, GFP_KERNEL); if (!ubi->fm_buf) goto out_free; #endif err = ubi_attach(ubi, 0); if (err) { ubi_err("failed to attach mtd%d, error %d", mtd->index, err); goto out_free; } if (ubi->autoresize_vol_id != -1) { err = autoresize(ubi, ubi->autoresize_vol_id); if (err) goto out_detach; } err = uif_init(ubi, &ref); if (err) goto out_detach; ubi_msg("attached mtd%d (name \"%s\", size %llu MiB) to ubi%d", mtd->index, mtd->name, ubi->flash_size >> 20, ubi_num); ubi_debug("PEB size: %d bytes (%d KiB), LEB size: %d bytes", ubi->peb_size, ubi->peb_size >> 10, ubi->leb_size); ubi_debug("min./max. I/O unit sizes: %d/%d, sub-page size %d", ubi->min_io_size, ubi->max_write_size, ubi->hdrs_min_io_size); ubi_debug("VID header offset: %d (aligned %d), data offset: %d", ubi->vid_hdr_offset, ubi->vid_hdr_aloffset, ubi->leb_start); ubi_debug("good PEBs: %d, bad PEBs: %d, corrupted PEBs: %d", ubi->good_peb_count, ubi->bad_peb_count, ubi->corr_peb_count); ubi_debug("user volume: %d, internal volumes: %d, max. volumes count: %d", ubi->vol_count - UBI_INT_VOL_COUNT, UBI_INT_VOL_COUNT, ubi->vtbl_slots); ubi_debug("max/mean erase counter: %d/%d, WL threshold: %d, image sequence number: %u", ubi->max_ec, ubi->mean_ec, CONFIG_MTD_UBI_WL_THRESHOLD, ubi->image_seq); ubi_debug("available PEBs: %d, total reserved PEBs: %d, PEBs reserved for bad PEB handling: %d", ubi->avail_pebs, ubi->rsvd_pebs, ubi->beb_rsvd_pebs); dev_add_param_int_ro(&ubi->dev, "peb_size", ubi->peb_size, "%d"); dev_add_param_int_ro(&ubi->dev, "leb_size", ubi->leb_size, "%d"); dev_add_param_int_ro(&ubi->dev, "vid_header_offset", ubi->vid_hdr_offset, "%d"); dev_add_param_int_ro(&ubi->dev, "min_io_size", ubi->min_io_size, "%d"); dev_add_param_int_ro(&ubi->dev, "sub_page_size", ubi->hdrs_min_io_size, "%d"); dev_add_param_int_ro(&ubi->dev, "good_peb_count", ubi->good_peb_count, "%d"); dev_add_param_int_ro(&ubi->dev, "bad_peb_count", ubi->bad_peb_count, "%d"); dev_add_param_int_ro(&ubi->dev, "max_erase_counter", ubi->max_ec, "%d"); dev_add_param_int_ro(&ubi->dev, "mean_erase_counter", ubi->mean_ec, "%d"); dev_add_param_int_ro(&ubi->dev, "available_pebs", ubi->avail_pebs, "%d"); dev_add_param_int_ro(&ubi->dev, "reserved_pebs", ubi->rsvd_pebs, "%d"); /* * The below lock makes sure we do not race with 'ubi_thread()' which * checks @ubi->thread_enabled. Otherwise we may fail to wake it up. */ ubi->thread_enabled = 1; wake_up_process(ubi->bgt_thread); ubi_devices[ubi_num] = ubi; return ubi_num; out_detach: ubi_wl_close(ubi); ubi_free_internal_volumes(ubi); vfree(ubi->vtbl); out_free: vfree(ubi->peb_buf); vfree(ubi->fm_buf); kfree(ubi); return err; }