Lines Matching +full:non +full:- +full:inverted

1 // SPDX-License-Identifier: GPL-2.0
5 * Copyright (C) 2006 by Weiss-Electronic GmbH.
10 * @references: borrowed heavily from Linux mtd-utils code:
16 * Artem Bityutskiy <dedekind1@gmail.com> from mtd-utils
41 * nand_erase_opts: - erase NAND flash with support for various options
58 int percent_complete = -1; in nand_erase_opts()
59 const char *mtd_device = mtd->name; in nand_erase_opts()
63 if ((opts->offset & (mtd->erasesize - 1)) != 0) { in nand_erase_opts()
64 printf("Attempt to erase non block-aligned data\n"); in nand_erase_opts()
65 return -1; in nand_erase_opts()
72 erase.len = mtd->erasesize; in nand_erase_opts()
73 erase.addr = opts->offset; in nand_erase_opts()
74 erase_length = lldiv(opts->length + mtd->erasesize - 1, in nand_erase_opts()
75 mtd->erasesize); in nand_erase_opts()
85 if (opts->scrub) { in nand_erase_opts()
86 erase.scrub = opts->scrub; in nand_erase_opts()
91 if (chip->bbt) { in nand_erase_opts()
92 kfree(chip->bbt); in nand_erase_opts()
94 chip->bbt = NULL; in nand_erase_opts()
95 chip->options &= ~NAND_BBT_SCANNED; in nand_erase_opts()
100 erase.addr += mtd->erasesize) { in nand_erase_opts()
104 if (opts->lim && (erase.addr >= (opts->offset + opts->lim))) { in nand_erase_opts()
106 return -EFBIG; in nand_erase_opts()
108 if (!opts->scrub) { in nand_erase_opts()
111 if (!opts->quiet) in nand_erase_opts()
117 if (!opts->spread) in nand_erase_opts()
126 return -1; in nand_erase_opts()
140 if (opts->jffs2 && chip->ecc.layout->oobavail >= 8) { in nand_erase_opts()
156 if (!opts->quiet) { in nand_erase_opts()
170 printf("\rErasing at 0x%llx -- %3d%% complete.", in nand_erase_opts()
173 if (opts->jffs2 && result == 0) in nand_erase_opts()
179 if (!opts->quiet) in nand_erase_opts()
195 * nand_lock: Set all pages of NAND flash chip to the LOCK or LOCK-TIGHT
201 * @return 0 on success, -1 in case of error
203 * The lock / lock-tight command only applies to the whole chip. To get some
206 * - Lock all pages of the chip using nand_lock(mtd, 0) (or the lockpre pin)
207 * - Call nand_unlock() once for each consecutive area to be unlocked
208 * - If desired: Bring the chip to the lock-tight state using nand_lock(mtd, 1)
210 * If the device is in lock-tight state software can't change the
212 * calls will fail. It is only posible to leave lock-tight state by
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()
228 ret = -1; in nand_lock()
232 chip->cmdfunc(mtd, in nand_lock()
234 -1, -1); in nand_lock()
237 status = chip->waitfunc(mtd, chip); in nand_lock()
241 ret = -1; in nand_lock()
245 /* de-select the NAND device */ in nand_lock()
246 chip->select_chip(mtd, -1); in nand_lock()
251 * nand_get_lock_status: - query current lock state from one page of NAND
255 * @param offset page address to query (must be page-aligned!)
257 * @return -1 in case of error
272 chipnr = (int)(offset >> chip->chip_shift); 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()
280 ret = -1; in nand_get_lock_status()
285 page = (int)(offset >> chip->page_shift); 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()
292 /* de-select the NAND device */ in nand_get_lock_status()
293 chip->select_chip(mtd, -1); in nand_get_lock_status()
298 * nand_unlock: - Unlock area of NAND pages
304 * page size mtd->writesize)
307 * @return 0 on success, -1 in case of error
322 chipnr = (int)(start >> chip->chip_shift); 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()
329 ret = -1; in nand_unlock()
334 page = (int)(start >> chip->page_shift); 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()
338 ret = -1; in nand_unlock()
342 if ((start & (mtd->erasesize - 1)) != 0) { in nand_unlock()
345 ret = -1; in nand_unlock()
349 if (length == 0 || (length & (mtd->erasesize - 1)) != 0) { in nand_unlock()
351 "size %08x!\n", mtd->erasesize); in nand_unlock()
352 ret = -1; in nand_unlock()
360 length -= mtd->erasesize; in nand_unlock()
363 chip->cmdfunc(mtd, NAND_CMD_UNLOCK1, -1, page & chip->pagemask); in nand_unlock()
366 page += (int)(length >> chip->page_shift); in nand_unlock()
369 * Page addresses for unlocking are supposed to be block-aligned. in nand_unlock()
371 * page range should be inverted. 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()
383 ret = -1; in nand_unlock()
388 /* de-select the NAND device */ in nand_unlock()
389 chip->select_chip(mtd, -1); in nand_unlock()
406 * -1 if the image does not fit
418 if (offset >= mtd->size) in check_skip_len()
419 return -1; 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()
436 *used -= (len_excl_bad - length); in check_skip_len()
448 for (i = l - 1; i >= 0; i--) in drop_ffs()
454 l = (l + mtd->writesize - 1) / mtd->writesize; in drop_ffs()
455 l *= mtd->writesize; in drop_ffs()
482 size_t verlen = mtd->writesize + mtd->oobsize; in nand_verify_page_oob()
489 return -ENOMEM; in nand_verify_page_oob()
491 vops.oobbuf = vops.datbuf + mtd->writesize; in nand_verify_page_oob()
495 rval = memcmp(ops->datbuf, vops.datbuf, vops.len); in nand_verify_page_oob()
497 rval = memcmp(ops->oobbuf, vops.oobbuf, vops.ooblen); in nand_verify_page_oob()
501 return rval ? -EIO : 0; in nand_verify_page_oob()
508 * Reads NAND in page-sized chunks and verifies the contents against
510 * page-aligned, and the function doesn't handle skipping bad blocks.
522 size_t verlen = mtd->writesize; in nand_verify()
526 return -ENOMEM; in nand_verify()
528 /* Read the NAND back in page-size groups to limit malloc size */ in nand_verify()
531 verlen = min(mtd->writesize, (uint32_t)(ofs + len - verofs)); in nand_verify()
533 if (!rval || (rval == -EUCLEAN)) in nand_verify()
542 return rval ? -EIO : 0; in nand_verify()
583 blocksize = mtd->erasesize; in nand_write_skip_bad()
596 if ((offset & (mtd->writesize - 1)) != 0) { in nand_write_skip_bad()
597 printf("Attempt to write non page-aligned data\n"); in nand_write_skip_bad()
599 return -EINVAL; in nand_write_skip_bad()
610 return -EINVAL; in nand_write_skip_bad()
616 return -EFBIG; 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()
647 if (left_to_write < (blocksize - block_offset)) in nand_write_skip_bad()
650 write_size = blocksize - block_offset; in nand_write_skip_bad()
672 *length -= left_to_write; in nand_write_skip_bad()
676 left_to_write -= write_size; in nand_write_skip_bad()
714 if ((offset & (mtd->writesize - 1)) != 0) { in nand_read_skip_bad()
715 printf("Attempt to read non page-aligned data\n"); in nand_read_skip_bad()
719 return -EINVAL; in nand_read_skip_bad()
730 return -EINVAL; in nand_read_skip_bad()
736 return -EFBIG; in nand_read_skip_bad()
741 if (!rval || rval == -EUCLEAN) 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()
769 if (rval && rval != -EUCLEAN) { in nand_read_skip_bad()
772 *length -= left_to_read; in nand_read_skip_bad()
776 left_to_read -= read_length; in nand_read_skip_bad()
824 .len = mtd->erasesize, in nand_torture()
827 int err, ret = -1, i, patt_count; in nand_torture()
830 if ((offset & (mtd->erasesize - 1)) != 0) { in nand_torture()
831 puts("Attempt to torture a block at a non block-aligned offset\n"); in nand_torture()
832 return -EINVAL; in nand_torture()
835 if (offset + mtd->erasesize > mtd->size) { in nand_torture()
837 return -EINVAL; in nand_torture()
842 buf = malloc_cache_aligned(mtd->erasesize); in nand_torture()
845 return -ENOMEM; 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()
866 printf("Erased block at 0x%llx, but a non-0xff byte was found\n", in nand_torture()
868 ret = -EIO; 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()
892 ret = -EIO; in nand_torture()