Home | History | Annotate | Download | only in oslib

Lines Matching refs:mtd

21  * MTD library.
24 /* Imported from mtd-utils by dehrenberg */
38 #include <mtd/mtd-user.h>
158 * dev_get_major - get major and minor numbers of an MTD device.
160 * @mtd_num: MTD device number
175 * dev_read_data - read data from an MTD device's sysfs file.
177 * @mtd_num: MTD device number
350 * dev_read_hex_int - read an hex 'int' value from an MTD device sysfs file.
352 * @mtd_num: MTD device number
366 * dev_read_pos_int - read a positive 'int' value from an MTD device sysfs file.
368 * @mtd_num: MTD device number
382 * dev_read_pos_ll - read a positive 'long long' value from an MTD device sysfs file.
384 * @mtd_num: MTD device number
398 * type_str2int - convert MTD device type to integer.
399 * @str: MTD device type string to convert
401 * This function converts MTD device type string @str, read from sysfs, into an
427 * @lib: MTD library descriptor
428 * @node: name of the MTD device node
429 * @mtd_num: MTD device number is returned here
478 * sysfs_is_supported - check whether the MTD sub-system supports MTD.
479 * @lib: MTD library descriptor
481 * The Linux kernel MTD subsystem gained MTD support starting from kernel
486 * Very old kernels did not have "/sys/class/mtd" directory. Not very old
487 * kernels (e.g., 2.6.29) did have "/sys/class/mtd/mtdX" directories, by there
489 * is to check for a "/sys/class/mtd/mtdX/name" file. But this is not a
490 * reliable check, because if this is a new system with no MTD devices - we'll
541 /* No mtd device, treat this as pre-sysfs system */
569 lib->mtd = mkpath(lib->sysfs_mtd, MTD_NAME_PATT);
570 if (!lib->mtd)
573 lib->mtd_name = mkpath(lib->mtd, MTD_NAME);
578 free(lib->mtd);
581 lib->mtd_name = lib->mtd = lib->sysfs_mtd = NULL;
585 lib->mtd_dev = mkpath(lib->mtd, MTD_DEV);
589 lib->mtd_type = mkpath(lib->mtd, MTD_TYPE);
593 lib->mtd_eb_size = mkpath(lib->mtd, MTD_EB_SIZE);
597 lib->mtd_size = mkpath(lib->mtd, MTD_SIZE);
601 lib->mtd_min_io_size = mkpath(lib->mtd, MTD_MIN_IO_SIZE);
605 lib->mtd_subpage_size = mkpath(lib->mtd, MTD_SUBPAGE_SIZE);
609 lib->mtd_oob_size = mkpath(lib->mtd, MTD_OOB_SIZE);
613 lib->mtd_region_cnt = mkpath(lib->mtd, MTD_REGION_CNT);
617 lib->mtd_flags = mkpath(lib->mtd, MTD_FLAGS);
643 free(lib->mtd);
655 char file[strlen(lib->mtd) + 10];
657 sprintf(file, lib->mtd, mtd_num);
676 * We have to scan the MTD sysfs directory to identify how many MTD
734 int mtd_get_dev_info1(libmtd_t desc, int mtd_num, struct mtd_dev_info *mtd)
739 memset(mtd, 0, sizeof(struct mtd_dev_info));
740 mtd->mtd_num = mtd_num;
746 return legacy_get_dev_info1(mtd_num, mtd);
748 if (dev_get_major(lib, mtd_num, &mtd->major, &mtd->minor))
751 ret = dev_read_data(lib->mtd_name, mtd_num, &mtd->name,
755 ((char *)mtd->name)[ret - 1] = '\0';
757 ret = dev_read_data(lib->mtd_type, mtd_num, &mtd->type_str,
761 ((char *)mtd->type_str)[ret - 1] = '\0';
763 if (dev_read_pos_int(lib->mtd_eb_size, mtd_num, &mtd->eb_size))
765 if (dev_read_pos_ll(lib->mtd_size, mtd_num, &mtd->size))
767 if (dev_read_pos_int(lib->mtd_min_io_size, mtd_num, &mtd->min_io_size))
769 if (dev_read_pos_int(lib->mtd_subpage_size, mtd_num, &mtd->subpage_size))
771 if (dev_read_pos_int(lib->mtd_oob_size, mtd_num, &mtd->oob_size))
773 if (dev_read_pos_int(lib->mtd_region_cnt, mtd_num, &mtd->region_cnt))
777 mtd->writable = !!(ret & MTD_WRITEABLE);
779 mtd->eb_cnt = mtd->size / mtd->eb_size;
780 mtd->type = type_str2int(mtd->type_str);
781 mtd->bb_allowed = !!(mtd->type == MTD_NANDFLASH ||
782 mtd->type == MTD_MLCNANDFLASH);
787 int mtd_get_dev_info(libmtd_t desc, const char *node, struct mtd_dev_info *mtd)
793 return legacy_get_dev_info(node, mtd);
798 return mtd_get_dev_info1(desc, mtd_num, mtd);
801 static inline int mtd_ioctl_error(const struct mtd_dev_info *mtd, int eb,
804 return sys_errmsg("%s ioctl failed for eraseblock %d (mtd%d)",
805 sreq, eb, mtd->mtd_num);
808 static int mtd_valid_erase_block(const struct mtd_dev_info *mtd, int eb)
810 if (eb < 0 || eb >= mtd->eb_cnt) {
811 errmsg("bad eraseblock number %d, mtd%d has %d eraseblocks",
812 eb, mtd->mtd_num, mtd->eb_cnt);
819 static int mtd_xlock(const struct mtd_dev_info *mtd, int fd, int eb, int req,
825 ret = mtd_valid_erase_block(mtd, eb);
829 ei.start = eb * mtd->eb_size;
830 ei.length = mtd->eb_size;
834 return mtd_ioctl_error(mtd, eb, sreq);
838 #define mtd_xlock(mtd, fd, eb, req) mtd_xlock(mtd, fd, eb, req, #req)
840 int mtd_lock(const struct mtd_dev_info *mtd, int fd, int eb)
842 return mtd_xlock(mtd, fd, eb, MEMLOCK);
845 int mtd_unlock(const struct mtd_dev_info *mtd, int fd, int eb)
847 return mtd_xlock(mtd, fd, eb, MEMUNLOCK);
850 int mtd_erase(libmtd_t desc, const struct mtd_dev_info *mtd, int fd, int eb)
857 ret = mtd_valid_erase_block(mtd, eb);
861 ei64.start = (__u64)eb * mtd->eb_size;
862 ei64.length = mtd->eb_size;
872 return mtd_ioctl_error(mtd, eb, "MEMERASE64");
884 0xFFFFFFFFU / mtd->eb_size);
893 return mtd_ioctl_error(mtd, eb, "MEMERASE");
916 int mtd_is_locked(const struct mtd_dev_info *mtd, int fd, int eb)
921 ei.start = eb * mtd->eb_size;
922 ei.length = mtd->eb_size;
927 return mtd_ioctl_error(mtd, eb, "MEMISLOCKED");
957 int mtd_torture(libmtd_t desc, const struct mtd_dev_info *mtd, int fd, int eb)
965 buf = xmalloc(mtd->eb_size);
968 err = mtd_erase(desc, mtd, fd, eb);
973 err = mtd_read(mtd, fd, eb, 0, buf, mtd->eb_size);
977 err = check_pattern(buf, 0xFF, mtd->eb_size);
985 memset(buf, patterns[i], mtd->eb_size);
986 err = mtd_write(desc, mtd, fd, eb, 0, buf, mtd->eb_size, NULL,
991 memset(buf, ~patterns[i], mtd->eb_size);
992 err = mtd_read(mtd, fd, eb, 0, buf, mtd->eb_size);
996 err = check_pattern(buf, patterns[i], mtd->eb_size);
1013 int mtd_is_bad(const struct mtd_dev_info *mtd, int fd, int eb)
1018 ret = mtd_valid_erase_block(mtd, eb);
1022 if (!mtd->bb_allowed)
1025 seek = (loff_t)eb * mtd->eb_size;
1028 return mtd_ioctl_error(mtd, eb, "MEMGETBADBLOCK");
1032 int mtd_mark_bad(const struct mtd_dev_info *mtd, int fd, int eb)
1037 if (!mtd->bb_allowed) {
1042 ret = mtd_valid_erase_block(mtd, eb);
1046 seek = (loff_t)eb * mtd->eb_size;
1049 return mtd_ioctl_error(mtd, eb, "MEMSETBADBLOCK");
1053 int mtd_read(const struct mtd_dev_info *mtd, int fd, int eb, int offs,
1059 ret = mtd_valid_erase_block(mtd, eb);
1063 if (offs < 0 || offs + len > mtd->eb_size) {
1064 errmsg("bad offset %d or length %d, mtd%d eraseblock size is %d",
1065 offs, len, mtd->mtd_num, mtd->eb_size);
1071 seek = (off_t)eb * mtd->eb_size + offs;
1073 return sys_errmsg("cannot seek mtd%d to offset %"PRIdoff_t,
1074 mtd->mtd_num, seek);
1079 return sys_errmsg("cannot read %d bytes from mtd%d (eraseblock %d, offset %d)",
1080 len, mtd->mtd_num, eb, offs);
1087 static int legacy_auto_oob_layout(const struct mtd_dev_info *mtd, int fd,
1116 len = mtd->oob_size - start;
1124 int mtd_write(libmtd_t desc, const struct mtd_dev_info *mtd, int fd, int eb,
1132 ret = mtd_valid_erase_block(mtd, eb);
1136 if (offs < 0 || offs + len > mtd->eb_size) {
1137 errmsg("bad offset %d or length %d, mtd%d eraseblock size is %d",
1138 offs, len, mtd->mtd_num, mtd->eb_size);
1142 if (offs % mtd->subpage_size) {
1143 errmsg("write offset %d is not aligned to mtd%d min. I/O size %d",
1144 offs, mtd->mtd_num, mtd->subpage_size);
1148 if (len % mtd->subpage_size) {
1149 errmsg("write length %d is not aligned to mtd%d min. I/O size %d",
1150 len, mtd->mtd_num, mtd->subpage_size);
1156 seek = (off_t)eb * mtd->eb_size + offs;
1170 return mtd_ioctl_error(mtd, eb, "MEMWRITE");
1174 if (legacy_auto_oob_layout(mtd, fd, ooblen, oob))
1176 if (mtd_write_oob(desc, mtd, fd, seek, ooblen, oob) < 0)
1182 return sys_errmsg("cannot seek mtd%d to offset %"PRIdoff_t,
1183 mtd->mtd_num, seek);
1186 return sys_errmsg("cannot write %d bytes to mtd%d "
1188 len, mtd->mtd_num, eb, offs);
1194 static int do_oob_op(libmtd_t desc, const struct mtd_dev_info *mtd, int fd,
1213 max_offs = (unsigned long long)mtd->eb_cnt * mtd->eb_size;
1215 errmsg("bad page address %" PRIu64 ", mtd%d has %d eraseblocks (%llu bytes)",
1216 start, mtd->mtd_num, mtd->eb_cnt, max_offs);
1221 oob_offs = start & (mtd->min_io_size - 1);
1222 if (oob_offs + length > mtd->oob_size || length == 0) {
1223 errmsg("Cannot write %" PRIu64 " OOB bytes to address %" PRIu64 " (OOB offset %u) - mtd%d OOB size is only %d bytes",
1224 length, start, oob_offs, mtd->mtd_num, mtd->oob_size);
1241 sys_errmsg("%s ioctl failed for mtd%d, offset %" PRIu64 " (eraseblock %" PRIu64 ")",
1242 cmd64_str, mtd->mtd_num, start, start / mtd->eb_size);
1266 sys_errmsg("%s ioctl failed for mtd%d, offset %" PRIu64 " (eraseblock %" PRIu64 ")",
1267 cmd_str, mtd->mtd_num, start, start / mtd->eb_size);
1271 int mtd_read_oob(libmtd_t desc, const struct mtd_dev_info *mtd, int fd,
1274 return do_oob_op(desc, mtd, fd, start, length, data,
1278 int mtd_write_oob(libmtd_t desc, const struct mtd_dev_info *mtd, int fd,
1281 return do_oob_op(desc, mtd, fd, start, length, data,
1285 int mtd_write_img(const struct mtd_dev_info *mtd, int fd, int eb, int offs,
1293 ret = mtd_valid_erase_block(mtd, eb);
1297 if (offs < 0 || offs >= mtd->eb_size) {
1298 errmsg("bad offset %d, mtd%d eraseblock size is %d",
1299 offs, mtd->mtd_num, mtd->eb_size);
1303 if (offs % mtd->subpage_size) {
1304 errmsg("write offset %d is not aligned to mtd%d min. I/O size %d",
1305 offs, mtd->mtd_num, mtd->subpage_size);
1320 if (len % mtd->subpage_size) {
1322 "mtd%d min. I/O size %d", img_name, len, mtd->mtd_num,
1323 mtd->subpage_size);
1327 tmp = (offs + len + mtd->eb_size - 1) / mtd->eb_size;
1328 if (eb + tmp > mtd->eb_cnt) {
1329 errmsg("\"%s\" image size is %d bytes, mtd%d size is %d "
1332 img_name, len, mtd->mtd_num, mtd->eb_cnt, eb, offs);
1338 seek = (off_t)eb * mtd->eb_size + offs;
1340 sys_errmsg("cannot seek mtd%d to offset %"PRIdoff_t,
1341 mtd->mtd_num, seek);
1345 buf = xmalloc(mtd->eb_size);
1351 ret = read(in_fd, buf, mtd->eb_size - offs - rd);
1357 } while (ret && rd < mtd->eb_size - offs);
1361 sys_errmsg("cannot write %d bytes to mtd%d (eraseblock %d, offset %d)",
1362 len, mtd->mtd_num, eb, offs);