/** * nor_erase_prepare - prepare a NOR flash PEB for erasure. * @ubi: UBI device description object * @pnum: physical eraseblock number to prepare * * NOR flash, or at least some of them, have peculiar embedded PEB erasure * algorithm: the PEB is first filled with zeroes, then it is erased. And * filling with zeroes starts from the end of the PEB. This was observed with * Spansion S29GL512N NOR flash. * * This means that in case of a power cut we may end up with intact data at the * beginning of the PEB, and all zeroes at the end of PEB. In other words, the * EC and VID headers are OK, but a large chunk of data at the end of PEB is * zeroed. This makes UBI mistakenly treat this PEB as used and associate it * with an LEB, which leads to subsequent failures (e.g., UBIFS fails). * * This function is called before erasing NOR PEBs and it zeroes out EC and VID * magic numbers in order to invalidate them and prevent the failures. Returns * zero in case of success and a negative error code in case of failure. */ static int nor_erase_prepare(struct ubi_device *ubi, int pnum) { int err, err1; size_t written; loff_t addr; uint32_t data = 0; struct ubi_vid_hdr vid_hdr; addr = (loff_t)pnum * ubi->peb_size + ubi->vid_hdr_aloffset; err = ubi->mtd->write(ubi->mtd, addr, 4, &written, (void *)&data); if (!err) { addr -= ubi->vid_hdr_aloffset; err = ubi->mtd->write(ubi->mtd, addr, 4, &written, (void *)&data); if (!err) return 0; } /* * We failed to write to the media. This was observed with Spansion * S29GL512N NOR flash. Most probably the eraseblock erasure was * interrupted at a very inappropriate moment, so it became unwritable. * In this case we probably anyway have garbage in this PEB. */ err1 = ubi_io_read_vid_hdr(ubi, pnum, &vid_hdr, 0); if (err1 == UBI_IO_BAD_VID_HDR) /* * The VID header is corrupted, so we can safely erase this * PEB and not afraid that it will be treated as a valid PEB in * case of an unclean reboot. */ return 0; /* * The PEB contains a valid VID header, but we cannot invalidate it. * Supposedly the flash media or the driver is screwed up, so return an * error. */ ubi_err("cannot invalidate PEB %d, write returned %d read returned %d", pnum, err, err1); ubi_dbg_dump_flash(ubi, pnum, 0, ubi->peb_size); return -EIO; }
/** * ubi_io_write - write data to a physical eraseblock. * @ubi: UBI device description object * @buf: buffer with the data to write * @pnum: physical eraseblock number to write to * @offset: offset within the physical eraseblock where to write * @len: how many bytes to write * * This function writes @len bytes of data from buffer @buf to offset @offset * of physical eraseblock @pnum. If all the data were successfully written, * zero is returned. If an error occurred, this function returns a negative * error code. If %-EIO is returned, the physical eraseblock most probably went * bad. * * 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(struct ubi_device *ubi, const void *buf, int pnum, int offset, int len) { int err; size_t written; loff_t addr; #ifdef CONFIG_MTD_MSM_NAND void *buf_new; #endif dbg_io("write %d bytes to 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(offset % ubi->hdrs_min_io_size == 0); ubi_assert(len > 0 && len % ubi->hdrs_min_io_size == 0); if (ubi->ro_mode) { ubi_err("read-only mode"); return -EROFS; } /* The below has to be compiled out if paranoid checks are disabled */ err = paranoid_check_not_bad(ubi, pnum); if (err) return err > 0 ? -EINVAL : err; /* The area we are writing to has to contain all 0xFF bytes */ err = ubi_dbg_check_all_ff(ubi, pnum, offset, len); if (err) return err > 0 ? -EINVAL : err; if (offset >= ubi->leb_start) { /* * We write to the data area of the physical eraseblock. Make * sure it has valid EC and VID headers. */ err = paranoid_check_peb_ec_hdr(ubi, pnum); if (err) return err > 0 ? -EINVAL : err; err = paranoid_check_peb_vid_hdr(ubi, pnum); if (err) return err > 0 ? -EINVAL : err; } if (ubi_dbg_is_write_failure()) { dbg_err("cannot write %d bytes to PEB %d:%d " "(emulated)", len, pnum, offset); ubi_dbg_dump_stack(); return -EIO; } addr = (loff_t)pnum * ubi->peb_size + offset; #ifdef CONFIG_MTD_MSM_NAND if(!(buf_new = kmalloc(len, GFP_KERNEL | __GFP_NOFAIL))) return -ENOMEM; memcpy(buf_new, buf, len); err = ubi->mtd->write(ubi->mtd, addr, len, &written, buf_new); #else err = ubi->mtd->write(ubi->mtd, addr, len, &written, buf); #endif if (err) { ubi_err("error %d while writing %d bytes to PEB %d:%d, written " "%zd bytes", err, len, pnum, offset, written); ubi_dbg_dump_stack(); ubi_dbg_dump_flash(ubi, pnum, offset, len); } else ubi_assert(written == len); #ifdef CONFIG_MTD_MSM_NAND kfree(buf_new); #endif return err; }
/** * ubi_io_write - write data to a physical eraseblock. * @ubi: UBI device description object * @buf: buffer with the data to write * @pnum: physical eraseblock number to write to * @offset: offset within the physical eraseblock where to write * @len: how many bytes to write * * This function writes @len bytes of data from buffer @buf to offset @offset * of physical eraseblock @pnum. If all the data were successfully written, * zero is returned. If an error occurred, this function returns a negative * error code. If %-EIO is returned, the physical eraseblock most probably went * bad. * * 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(struct ubi_device *ubi, const void *buf, int pnum, int offset, int len) { int err; size_t written; loff_t addr; dbg_io("write %d bytes to 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(offset % ubi->hdrs_min_io_size == 0); ubi_assert(len > 0 && len % ubi->hdrs_min_io_size == 0); if (ubi->ro_mode) { ubi_err("read-only mode"); return -EROFS; } /* The below has to be compiled out if paranoid checks are disabled */ err = paranoid_check_not_bad(ubi, pnum); if (err) return err; /* The area we are writing to has to contain all 0xFF bytes */ err = ubi_dbg_check_all_ff(ubi, pnum, offset, len); if (err) return err; if (offset >= ubi->leb_start) { /* * We write to the data area of the physical eraseblock. Make * sure it has valid EC and VID headers. */ err = paranoid_check_peb_ec_hdr(ubi, pnum); if (err) return err; err = paranoid_check_peb_vid_hdr(ubi, pnum); if (err) return err; } if (ubi_dbg_is_write_failure()) { dbg_err("cannot write %d bytes to PEB %d:%d " "(emulated)", len, pnum, offset); ubi_dbg_dump_stack(); return -EIO; } addr = (loff_t)pnum * ubi->peb_size + offset; err = ubi->mtd->write(ubi->mtd, addr, len, &written, buf); if (err) { ubi_err("error %d while writing %d bytes to PEB %d:%d, written " "%zd bytes", err, len, pnum, offset, written); ubi_dbg_dump_stack(); ubi_dbg_dump_flash(ubi, pnum, offset, len); } else ubi_assert(written == len); if (!err) { err = ubi_dbg_check_write(ubi, buf, pnum, offset, len); if (err) return err; /* * Since we always write sequentially, the rest of the PEB has * to contain only 0xFF bytes. */ offset += len; len = ubi->peb_size - offset; if (len) err = ubi_dbg_check_all_ff(ubi, pnum, offset, len); } return err; }
/** * nor_erase_prepare - prepare a NOR flash PEB for erasure. * @ubi: UBI device description object * @pnum: physical eraseblock number to prepare * * NOR flash, or at least some of them, have peculiar embedded PEB erasure * algorithm: the PEB is first filled with zeroes, then it is erased. And * filling with zeroes starts from the end of the PEB. This was observed with * Spansion S29GL512N NOR flash. * * This means that in case of a power cut we may end up with intact data at the * beginning of the PEB, and all zeroes at the end of PEB. In other words, the * EC and VID headers are OK, but a large chunk of data at the end of PEB is * zeroed. This makes UBI mistakenly treat this PEB as used and associate it * with an LEB, which leads to subsequent failures (e.g., UBIFS fails). * * This function is called before erasing NOR PEBs and it zeroes out EC and VID * magic numbers in order to invalidate them and prevent the failures. Returns * zero in case of success and a negative error code in case of failure. */ static int nor_erase_prepare(struct ubi_device *ubi, int pnum) { int err, err1; size_t written; loff_t addr; uint32_t data = 0; /* * Note, we cannot generally define VID header buffers on stack, * because of the way we deal with these buffers (see the header * comment in this file). But we know this is a NOR-specific piece of * code, so we can do this. But yes, this is error-prone and we should * (pre-)allocate VID header buffer instead. */ struct ubi_vid_hdr vid_hdr; /* * It is important to first invalidate the EC header, and then the VID * header. Otherwise a power cut may lead to valid EC header and * invalid VID header, in which case UBI will treat this PEB as * corrupted and will try to preserve it, and print scary warnings (see * the header comment in scan.c for more information). */ addr = (loff_t)pnum * ubi->peb_size; err = mtd_write(ubi->mtd, addr, 4, &written, (void *)&data); if (!err) { addr += ubi->vid_hdr_aloffset; err = mtd_write(ubi->mtd, addr, 4, &written, (void *)&data); if (!err) return 0; } /* * We failed to write to the media. This was observed with Spansion * S29GL512N NOR flash. Most probably the previously eraseblock erasure * was interrupted at a very inappropriate moment, so it became * unwritable. In this case we probably anyway have garbage in this * PEB. */ err1 = ubi_io_read_vid_hdr(ubi, pnum, &vid_hdr, 0); if (err1 == UBI_IO_BAD_HDR_EBADMSG || err1 == UBI_IO_BAD_HDR || err1 == UBI_IO_FF) { struct ubi_ec_hdr ec_hdr; err1 = ubi_io_read_ec_hdr(ubi, pnum, &ec_hdr, 0); if (err1 == UBI_IO_BAD_HDR_EBADMSG || err1 == UBI_IO_BAD_HDR || err1 == UBI_IO_FF) /* * Both VID and EC headers are corrupted, so we can * safely erase this PEB and not afraid that it will be * treated as a valid PEB in case of an unclean reboot. */ return 0; } /* * The PEB contains a valid VID header, but we cannot invalidate it. * Supposedly the flash media or the driver is screwed up, so return an * error. */ ubi_err("cannot invalidate PEB %d, write returned %d read returned %d", pnum, err, err1); ubi_dbg_dump_flash(ubi, pnum, 0, ubi->peb_size); return -EIO; }