Lines Matching +full:mtd +full:- +full:name
1 // SPDX-License-Identifier: GPL-2.0+
3 * mtd.c
16 #include <mtd.h>
20 static struct mtd_info *get_mtd_by_name(const char *name) in get_mtd_by_name() argument
22 struct mtd_info *mtd; in get_mtd_by_name() local
26 mtd = get_mtd_device_nm(name); in get_mtd_by_name()
27 if (IS_ERR_OR_NULL(mtd)) in get_mtd_by_name()
28 printf("MTD device %s not found, ret %ld\n", name, in get_mtd_by_name()
29 PTR_ERR(mtd)); in get_mtd_by_name()
31 return mtd; in get_mtd_by_name()
34 static uint mtd_len_to_pages(struct mtd_info *mtd, u64 len) in mtd_len_to_pages() argument
36 do_div(len, mtd->writesize); in mtd_len_to_pages()
41 static bool mtd_is_aligned_with_min_io_size(struct mtd_info *mtd, u64 size) in mtd_is_aligned_with_min_io_size() argument
43 return !do_div(size, mtd->writesize); in mtd_is_aligned_with_min_io_size()
46 static bool mtd_is_aligned_with_block_size(struct mtd_info *mtd, u64 size) in mtd_is_aligned_with_block_size() argument
48 return !do_div(size, mtd->erasesize); in mtd_is_aligned_with_block_size()
68 static void mtd_dump_device_buf(struct mtd_info *mtd, u64 start_off, in mtd_dump_device_buf() argument
71 bool has_pages = mtd->type == MTD_NANDFLASH || in mtd_dump_device_buf()
72 mtd->type == MTD_MLCNANDFLASH; in mtd_dump_device_buf()
73 int npages = mtd_len_to_pages(mtd, len); in mtd_dump_device_buf()
78 u64 data_off = page * mtd->writesize; in mtd_dump_device_buf()
81 mtd->writesize, start_off + data_off); in mtd_dump_device_buf()
83 mtd->writesize, start_off + data_off); in mtd_dump_device_buf()
86 u64 oob_off = page * mtd->oobsize; in mtd_dump_device_buf()
89 mtd->oobsize, start_off + data_off); in mtd_dump_device_buf()
91 mtd->oobsize, 0); in mtd_dump_device_buf()
101 static void mtd_show_parts(struct mtd_info *mtd, int level) in mtd_show_parts() argument
106 list_for_each_entry(part, &mtd->partitions, node) { in mtd_show_parts()
109 printf(" - 0x%012llx-0x%012llx : \"%s\"\n", in mtd_show_parts()
110 part->offset, part->offset + part->size, part->name); in mtd_show_parts()
116 static void mtd_show_device(struct mtd_info *mtd) in mtd_show_device() argument
119 printf("* %s\n", mtd->name); in mtd_show_device()
121 if (mtd->dev) { in mtd_show_device()
122 printf(" - device: %s\n", mtd->dev->name); in mtd_show_device()
123 printf(" - parent: %s\n", mtd->dev->parent->name); in mtd_show_device()
124 printf(" - driver: %s\n", mtd->dev->driver->name); in mtd_show_device()
128 /* MTD device information */ in mtd_show_device()
129 printf(" - type: "); in mtd_show_device()
130 switch (mtd->type) { in mtd_show_device()
158 printf(" - block size: 0x%x bytes\n", mtd->erasesize); in mtd_show_device()
159 printf(" - min I/O: 0x%x bytes\n", mtd->writesize); in mtd_show_device()
161 if (mtd->oobsize) { in mtd_show_device()
162 printf(" - OOB size: %u bytes\n", mtd->oobsize); in mtd_show_device()
163 printf(" - OOB available: %u bytes\n", mtd->oobavail); in mtd_show_device()
166 if (mtd->ecc_strength) { in mtd_show_device()
167 printf(" - ECC strength: %u bits\n", mtd->ecc_strength); in mtd_show_device()
168 printf(" - ECC step size: %u bytes\n", mtd->ecc_step_size); in mtd_show_device()
169 printf(" - bitflip threshold: %u bits\n", in mtd_show_device()
170 mtd->bitflip_threshold); in mtd_show_device()
173 printf(" - 0x%012llx-0x%012llx : \"%s\"\n", in mtd_show_device()
174 mtd->offset, mtd->offset + mtd->size, mtd->name); in mtd_show_device()
176 /* MTD partitions, if any */ in mtd_show_device()
177 mtd_show_parts(mtd, 1); in mtd_show_device()
185 for (i = 0; i < op->len; i++) in mtd_oob_write_is_empty()
186 if (op->datbuf[i] != 0xff) in mtd_oob_write_is_empty()
189 for (i = 0; i < op->ooblen; i++) in mtd_oob_write_is_empty()
190 if (op->oobbuf[i] != 0xff) in mtd_oob_write_is_empty()
199 struct mtd_info *mtd; in do_mtd_list() local
205 printf("List of MTD devices:\n"); in do_mtd_list()
206 mtd_for_each_device(mtd) { in do_mtd_list()
207 if (!mtd_is_partition(mtd)) in do_mtd_list()
208 mtd_show_device(mtd); in do_mtd_list()
214 printf("No MTD device found\n"); in do_mtd_list()
221 static int mtd_special_write_oob(struct mtd_info *mtd, u64 off, in mtd_special_write_oob() argument
232 io_op->retlen = mtd->writesize; in mtd_special_write_oob()
233 io_op->oobretlen = woob ? mtd->oobsize : 0; in mtd_special_write_oob()
235 ret = mtd_write_oob(mtd, off, io_op); in mtd_special_write_oob()
248 struct mtd_info *mtd; in do_mtd_io() local
256 mtd = get_mtd_by_name(argv[1]); in do_mtd_io()
257 if (IS_ERR_OR_NULL(mtd)) in do_mtd_io()
260 if (mtd->type == MTD_NANDFLASH || mtd->type == MTD_MLCNANDFLASH) in do_mtd_io()
269 argc -= 2; in do_mtd_io()
279 argc--; in do_mtd_io()
284 if (!mtd_is_aligned_with_min_io_size(mtd, start_off)) { in do_mtd_io()
286 mtd->writesize); in do_mtd_io()
291 default_len = dump ? mtd->writesize : mtd->size; in do_mtd_io()
293 if (!mtd_is_aligned_with_min_io_size(mtd, len)) { in do_mtd_io()
294 len = round_up(len, mtd->writesize); in do_mtd_io()
296 mtd->writesize, len); in do_mtd_io()
300 npages = mtd_len_to_pages(mtd, len); in do_mtd_io()
301 oob_len = woob ? npages * mtd->oobsize : 0; in do_mtd_io()
324 io_op.len = has_pages ? mtd->writesize : len; in do_mtd_io()
325 io_op.ooblen = woob ? mtd->oobsize : 0; in do_mtd_io()
331 while (mtd_block_isbad(mtd, off)) in do_mtd_io()
332 off += mtd->erasesize; in do_mtd_io()
337 if (mtd_is_aligned_with_block_size(mtd, off) && in do_mtd_io()
338 mtd_block_isbad(mtd, off)) { in do_mtd_io()
339 off += mtd->erasesize; in do_mtd_io()
344 ret = mtd_read_oob(mtd, off, &io_op); in do_mtd_io()
346 ret = mtd_special_write_oob(mtd, off, &io_op, in do_mtd_io()
356 remaining -= io_op.retlen; in do_mtd_io()
362 mtd_dump_device_buf(mtd, start_off, buf, len, woob); in do_mtd_io()
371 read ? "Read" : "Write", mtd->name, ret); in do_mtd_io()
378 put_mtd_device(mtd); in do_mtd_io()
387 struct mtd_info *mtd; in do_mtd_erase() local
395 mtd = get_mtd_by_name(argv[1]); in do_mtd_erase()
396 if (IS_ERR_OR_NULL(mtd)) in do_mtd_erase()
401 argc -= 2; in do_mtd_erase()
405 len = argc > 1 ? simple_strtoul(argv[1], NULL, 16) : mtd->size; in do_mtd_erase()
407 if (!mtd_is_aligned_with_block_size(mtd, off)) { in do_mtd_erase()
409 mtd->erasesize); in do_mtd_erase()
414 if (!mtd_is_aligned_with_block_size(mtd, len)) { in do_mtd_erase()
416 mtd->erasesize); in do_mtd_erase()
422 off, off + len - 1, mtd_div_by_eb(len, mtd)); in do_mtd_erase()
424 erase_op.mtd = mtd; in do_mtd_erase()
430 ret = mtd_erase(mtd, &erase_op); in do_mtd_erase()
433 if (ret != -EIO) in do_mtd_erase()
439 erase_op.len -= erase_op.fail_addr - erase_op.addr; in do_mtd_erase()
440 erase_op.len -= mtd->erasesize; in do_mtd_erase()
441 erase_op.addr = erase_op.fail_addr + mtd->erasesize; in do_mtd_erase()
444 if (ret && ret != -EIO) in do_mtd_erase()
450 put_mtd_device(mtd); in do_mtd_erase()
458 struct mtd_info *mtd; in do_mtd_bad() local
464 mtd = get_mtd_by_name(argv[1]); in do_mtd_bad()
465 if (IS_ERR_OR_NULL(mtd)) in do_mtd_bad()
468 if (!mtd_can_have_bb(mtd)) { in do_mtd_bad()
469 printf("Only NAND-based devices can have bad blocks\n"); in do_mtd_bad()
473 printf("MTD device %s bad blocks list:\n", mtd->name); in do_mtd_bad()
474 for (off = 0; off < mtd->size; off += mtd->erasesize) { in do_mtd_bad()
475 if (mtd_block_isbad(mtd, off)) in do_mtd_bad()
480 put_mtd_device(mtd); in do_mtd_bad()
490 struct mtd_info *mtd; in mtd_name_complete() local
492 argc--; in mtd_name_complete()
502 mtd_for_each_device(mtd) { in mtd_name_complete()
504 (len > strlen(mtd->name) || in mtd_name_complete()
505 strncmp(argv[0], mtd->name, len))) in mtd_name_complete()
508 if (n_found >= maxv - 2) { in mtd_name_complete()
513 cmdv[n_found++] = mtd->name; in mtd_name_complete()
524 "- generic operations on memory technology devices\n\n"
525 "mtd list\n"
526 "mtd read[.raw][.oob] <name> <addr> [<off> [<size>]]\n"
527 "mtd dump[.raw][.oob] <name> [<off> [<size>]]\n"
528 "mtd write[.raw][.oob][.dontskipff] <name> <addr> [<off> [<size>]]\n"
529 "mtd erase[.dontskipbad] <name> [<off> [<size>]]\n"
532 "mtd bad <name>\n"
535 "\t<name>: NAND partition/chip name\n"
537 "\t<off>: offset in <name> in bytes (default: start of the part)\n"
538 "\t\t* must be block-aligned for erase\n"
539 "\t\t* must be page-aligned otherwise\n"
547 U_BOOT_CMD_WITH_SUBCMDS(mtd, "MTD utils", mtd_help_text,