Lines Matching full:mtd
3 * drivers/mtd/nand/raw/nand_util.c
10 * @references: borrowed heavily from Linux mtd-utils code:
16 * Artem Bityutskiy <dedekind1@gmail.com> from mtd-utils
29 #include <linux/mtd/mtd.h>
44 * @param mtd nand mtd instance to erase
48 * This code is ported from flash_eraseall.c from Linux mtd utils by
51 int nand_erase_opts(struct mtd_info *mtd, in nand_erase_opts() argument
59 const char *mtd_device = mtd->name; in nand_erase_opts()
61 struct nand_chip *chip = mtd_to_nand(mtd); in nand_erase_opts()
63 if ((opts->offset & (mtd->erasesize - 1)) != 0) { in nand_erase_opts()
71 erase.mtd = mtd; in nand_erase_opts()
72 erase.len = mtd->erasesize; in nand_erase_opts()
74 erase_length = lldiv(opts->length + mtd->erasesize - 1, in nand_erase_opts()
75 mtd->erasesize); in nand_erase_opts()
100 erase.addr += mtd->erasesize) { in nand_erase_opts()
109 int ret = mtd_block_isbad(mtd, erase.addr); in nand_erase_opts()
123 printf("\n%s: MTD get bad block failed: %d\n", in nand_erase_opts()
132 result = mtd_erase(mtd, &erase); in nand_erase_opts()
134 printf("\n%s: MTD Erase failure: %d\n", in nand_erase_opts()
148 result = mtd_write_oob(mtd, erase.addr, &ops); in nand_erase_opts()
150 printf("\n%s: MTD writeoob failure: %d\n", in nand_erase_opts()
198 * @param mtd nand mtd instance
206 * - Lock all pages of the chip using nand_lock(mtd, 0) (or the lockpre pin)
208 * - If desired: Bring the chip to the lock-tight state using nand_lock(mtd, 1)
215 int nand_lock(struct mtd_info *mtd, int tight) in nand_lock() argument
219 struct nand_chip *chip = mtd_to_nand(mtd); in nand_lock()
222 chip->select_chip(mtd, 0); in nand_lock()
225 chip->cmdfunc(mtd, NAND_CMD_LOCK_STATUS, -1, 0); in nand_lock()
226 if (chip->read_byte(mtd) & NAND_LOCK_STATUS_TIGHT) { in nand_lock()
232 chip->cmdfunc(mtd, in nand_lock()
237 status = chip->waitfunc(mtd, chip); in nand_lock()
246 chip->select_chip(mtd, -1); in nand_lock()
254 * @param mtd nand mtd instance
264 int nand_get_lock_status(struct mtd_info *mtd, loff_t offset) in nand_get_lock_status() argument
269 struct nand_chip *chip = mtd_to_nand(mtd); in nand_get_lock_status()
273 chip->select_chip(mtd, chipnr); in nand_get_lock_status()
276 if ((offset & (mtd->writesize - 1)) != 0) { in nand_get_lock_status()
286 chip->cmdfunc(mtd, NAND_CMD_LOCK_STATUS, -1, page & chip->pagemask); in nand_get_lock_status()
288 ret = chip->read_byte(mtd) & (NAND_LOCK_STATUS_TIGHT in nand_get_lock_status()
293 chip->select_chip(mtd, -1); in nand_get_lock_status()
301 * @param mtd nand mtd instance
304 * page size mtd->writesize)
309 int nand_unlock(struct mtd_info *mtd, loff_t start, size_t length, in nand_unlock() argument
316 struct nand_chip *chip = mtd_to_nand(mtd); in nand_unlock()
323 chip->select_chip(mtd, chipnr); in nand_unlock()
326 chip->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1); in nand_unlock()
327 if (!(chip->read_byte(mtd) & NAND_STATUS_WP)) { in nand_unlock()
335 chip->cmdfunc(mtd, NAND_CMD_LOCK_STATUS, -1, page & chip->pagemask); in nand_unlock()
336 if (chip->read_byte(mtd) & NAND_LOCK_STATUS_TIGHT) { in nand_unlock()
342 if ((start & (mtd->erasesize - 1)) != 0) { in nand_unlock()
349 if (length == 0 || (length & (mtd->erasesize - 1)) != 0) { in nand_unlock()
351 "size %08x!\n", mtd->erasesize); in nand_unlock()
360 length -= mtd->erasesize; in nand_unlock()
363 chip->cmdfunc(mtd, NAND_CMD_UNLOCK1, -1, page & chip->pagemask); in nand_unlock()
376 chip->cmdfunc(mtd, NAND_CMD_UNLOCK2, -1, page & chip->pagemask); in nand_unlock()
379 status = chip->waitfunc(mtd, chip); in nand_unlock()
389 chip->select_chip(mtd, -1); in nand_unlock()
400 * @param mtd nand mtd instance
408 static int check_skip_len(struct mtd_info *mtd, loff_t offset, size_t length, in check_skip_len() argument
418 if (offset >= mtd->size) in check_skip_len()
421 block_start = offset & ~(loff_t)(mtd->erasesize - 1); in check_skip_len()
422 block_off = offset & (mtd->erasesize - 1); in check_skip_len()
423 block_len = mtd->erasesize - block_off; in check_skip_len()
425 if (!nand_block_isbad(mtd, block_start)) in check_skip_len()
442 static size_t drop_ffs(const struct mtd_info *mtd, const u_char *buf, in drop_ffs() argument
454 l = (l + mtd->writesize - 1) / mtd->writesize; in drop_ffs()
455 l *= mtd->writesize; in drop_ffs()
472 * @param mtd nand mtd instance
473 * @param ops MTD operations, including data to verify
477 int nand_verify_page_oob(struct mtd_info *mtd, struct mtd_oob_ops *ops, in nand_verify_page_oob() argument
482 size_t verlen = mtd->writesize + mtd->oobsize; in nand_verify_page_oob()
491 vops.oobbuf = vops.datbuf + mtd->writesize; in nand_verify_page_oob()
493 rval = mtd_read_oob(mtd, ofs, &vops); in nand_verify_page_oob()
512 * @param mtd nand mtd instance
518 int nand_verify(struct mtd_info *mtd, loff_t ofs, size_t len, u_char *buf) in nand_verify() argument
522 size_t verlen = mtd->writesize; in nand_verify()
531 verlen = min(mtd->writesize, (uint32_t)(ofs + len - verofs)); in nand_verify()
532 rval = nand_read(mtd, verofs, &verlen, verbuf); in nand_verify()
560 * @param mtd nand mtd instance
571 int nand_write_skip_bad(struct mtd_info *mtd, loff_t offset, size_t *length, in nand_write_skip_bad() argument
583 blocksize = mtd->erasesize; in nand_write_skip_bad()
596 if ((offset & (mtd->writesize - 1)) != 0) { in nand_write_skip_bad()
602 need_skip = check_skip_len(mtd, offset, *length, &used_for_write); in nand_write_skip_bad()
620 rval = nand_write(mtd, offset, length, buffer); in nand_write_skip_bad()
623 rval = nand_verify(mtd, offset, *length, buffer); in nand_write_skip_bad()
635 size_t block_offset = offset & (mtd->erasesize - 1); in nand_write_skip_bad()
640 if (nand_block_isbad(mtd, offset & ~(mtd->erasesize - 1))) { in nand_write_skip_bad()
642 offset & ~(mtd->erasesize - 1)); in nand_write_skip_bad()
643 offset += mtd->erasesize - block_offset; in nand_write_skip_bad()
655 truncated_write_size = drop_ffs(mtd, p_buffer, in nand_write_skip_bad()
659 rval = nand_write(mtd, offset, &truncated_write_size, in nand_write_skip_bad()
663 rval = nand_verify(mtd, offset, in nand_write_skip_bad()
695 * @param mtd nand mtd instance
705 int nand_read_skip_bad(struct mtd_info *mtd, loff_t offset, size_t *length, in nand_read_skip_bad() argument
714 if ((offset & (mtd->writesize - 1)) != 0) { in nand_read_skip_bad()
722 need_skip = check_skip_len(mtd, offset, *length, &used_for_read); in nand_read_skip_bad()
740 rval = nand_read(mtd, offset, length, buffer); in nand_read_skip_bad()
751 size_t block_offset = offset & (mtd->erasesize - 1); in nand_read_skip_bad()
756 if (nand_block_isbad(mtd, offset & ~(mtd->erasesize - 1))) { in nand_read_skip_bad()
758 offset & ~(mtd->erasesize - 1)); in nand_read_skip_bad()
759 offset += mtd->erasesize - block_offset; in nand_read_skip_bad()
763 if (left_to_read < (mtd->erasesize - block_offset)) in nand_read_skip_bad()
766 read_length = mtd->erasesize - block_offset; in nand_read_skip_bad()
768 rval = nand_read(mtd, offset, &read_length, p_buffer); in nand_read_skip_bad()
814 * @param mtd nand mtd instance
818 int nand_torture(struct mtd_info *mtd, loff_t offset) in nand_torture() argument
822 .mtd = mtd, in nand_torture()
824 .len = mtd->erasesize, in nand_torture()
830 if ((offset & (mtd->erasesize - 1)) != 0) { in nand_torture()
835 if (offset + mtd->erasesize > mtd->size) { in nand_torture()
842 buf = malloc_cache_aligned(mtd->erasesize); in nand_torture()
849 err = mtd_erase(mtd, &instr); in nand_torture()
852 mtd->name, instr.addr, err); in nand_torture()
857 err = mtd_read(mtd, offset, mtd->erasesize, &retlen, buf); in nand_torture()
858 if ((err && err != -EUCLEAN) || retlen != mtd->erasesize) { in nand_torture()
860 mtd->name, instr.addr, err); in nand_torture()
864 err = check_pattern(buf, 0xff, mtd->erasesize); in nand_torture()
873 memset(buf, patterns[i], mtd->erasesize); in nand_torture()
874 err = mtd_write(mtd, offset, mtd->erasesize, &retlen, buf); in nand_torture()
875 if (err || retlen != mtd->erasesize) { in nand_torture()
877 mtd->name, instr.addr, err); in nand_torture()
881 err = mtd_read(mtd, offset, mtd->erasesize, &retlen, buf); in nand_torture()
882 if ((err && err != -EUCLEAN) || retlen != mtd->erasesize) { in nand_torture()
884 mtd->name, instr.addr, err); in nand_torture()
888 err = check_pattern(buf, patterns[i], mtd->erasesize); in nand_torture()