summaryrefslogtreecommitdiff
path: root/ubi-utils/src/ubiformat.c
diff options
context:
space:
mode:
Diffstat (limited to 'ubi-utils/src/ubiformat.c')
-rw-r--r--ubi-utils/src/ubiformat.c103
1 files changed, 70 insertions, 33 deletions
diff --git a/ubi-utils/src/ubiformat.c b/ubi-utils/src/ubiformat.c
index 1c201a6..b9d3f79 100644
--- a/ubi-utils/src/ubiformat.c
+++ b/ubi-utils/src/ubiformat.c
@@ -45,7 +45,7 @@
#include "crc32.h"
#include "common.h"
-#define PROGRAM_VERSION "1.2"
+#define PROGRAM_VERSION "1.3"
#define PROGRAM_NAME "ubiformat"
/* The variables below are set by command line arguments */
@@ -55,6 +55,7 @@ struct args {
unsigned int verbose:1;
unsigned int override_ec:1;
unsigned int novtbl:1;
+ unsigned int manual_subpage;
int subpage_size;
int vid_hdr_offs;
int ubi_ver;
@@ -633,9 +634,9 @@ static int format(const struct mtd_dev_info *mtd, const struct ubigen_info *ui,
write_size, eb);
if (errno != EIO) {
- if (args.subpage_size != mtd->min_io_size)
- normsg("may be %d is incorrect?",
- args.subpage_size);
+ if (!args.subpage_size != mtd->min_io_size)
+ normsg("may be sub-page size is "
+ "incorrect?");
goto out_free;
}
@@ -682,59 +683,91 @@ out_free:
int main(int argc, char * const argv[])
{
int err, verbose;
+ libmtd_t libmtd;
+ struct mtd_info mtd_info;
struct mtd_dev_info mtd;
libubi_t libubi;
struct ubigen_info ui;
struct ubi_scan_info *si;
+ libmtd = libmtd_open();
+ if (!libmtd)
+ return errmsg("MTD subsystem is not present");
+
err = parse_opt(argc, argv);
if (err)
- return -1;
+ goto out_close_mtd;
- err = mtd_get_dev_info(args.node, &mtd);
- if (err)
- return errmsg("cannot get information about \"%s\"", args.node);
+ err = mtd_get_info(libmtd, &mtd_info);
+ if (err) {
+ if (errno == ENODEV)
+ errmsg("MTD is not present");
+ sys_errmsg("cannot get MTD information");
+ goto out_close_mtd;
+ }
- args.node_fd = open(args.node, O_RDWR);
- if (args.node_fd == -1)
- return sys_errmsg("cannot open \"%s\"", args.node);
+ err = mtd_get_dev_info(libmtd, args.node, &mtd);
+ if (err) {
+ sys_errmsg("cannot get information about \"%s\"", args.node);
+ goto out_close_mtd;
+ }
+
+ if (!mtd_info.sysfs_supported) {
+ /*
+ * Linux kernels older than 2.6.30 did not support sysfs
+ * interface, and it is impossible to find out sub-page
+ * size in these kernels. This is why users should
+ * provide -s option.
+ */
+ if (args.subpage_size == 0) {
+ warnmsg("your MTD system is old and it is impossible "
+ "to detect sub-page size. Use -s to get rid "
+ "of this warning");
+ normsg("assume sub-page to be %d", mtd.subpage_size);
+ } else {
+ mtd.subpage_size = args.subpage_size;
+ args.manual_subpage = 1;
+ }
+ } else if (args.subpage_size && args.subpage_size != mtd.subpage_size) {
+ mtd.subpage_size = args.subpage_size;
+ args.manual_subpage = 1;
+ }
- if (args.subpage_size == 0)
- args.subpage_size = mtd.min_io_size;
- else {
+ if (args.manual_subpage) {
+ /* Do some sanity check */
if (args.subpage_size > mtd.min_io_size) {
errmsg("sub-page cannot be larger than min. I/O unit");
- goto out;
+ goto out_close;
}
if (mtd.min_io_size % args.subpage_size) {
- errmsg("min. I/O unit size should be multiple of sub-page size");
- goto out;
+ errmsg("min. I/O unit size should be multiple of "
+ "sub-page size");
+ goto out_close;
}
}
+ args.node_fd = open(args.node, O_RDWR);
+ if (args.node_fd == -1) {
+ sys_errmsg("cannot open \"%s\"", args.node);
+ goto out_close_mtd;
+ }
+
/* Validate VID header offset if it was specified */
if (args.vid_hdr_offs != 0) {
if (args.vid_hdr_offs % 8) {
errmsg("VID header offset has to be multiple of min. I/O unit size");
- goto out;
+ goto out_close;
}
if (args.vid_hdr_offs + (int)UBI_VID_HDR_SIZE > mtd.eb_size) {
errmsg("bad VID header offset");
- goto out;
+ goto out_close;
}
}
- /*
- * Because of MTD interface limitations 'mtd_get_dev_info()' cannot get
- * sub-page so we force the user to pass it via the command line. Let's
- * hope the user passed us something sane.
- */
- mtd.subpage_size = args.subpage_size;
-
if (!mtd.writable) {
errmsg("mtd%d (%s) is a read-only device", mtd.dev_num, args.node);
- goto out;
+ goto out_close;
}
/* Make sure this MTD device is not attached to UBI */
@@ -747,14 +780,14 @@ int main(int argc, char * const argv[])
if (!err) {
errmsg("please, first detach mtd%d (%s) from ubi%d",
mtd.dev_num, args.node, ubi_dev_num);
- goto out;
+ goto out_close;
}
}
if (!args.quiet) {
normsg_cont("mtd%d (%s), size ", mtd.dev_num, mtd.type_str);
ubiutils_print_bytes(mtd.size, 1);
- printf(", %d eraseblocks of ", mtd.eb_size);
+ printf(", %d eraseblocks of ", mtd.eb_cnt);
ubiutils_print_bytes(mtd.eb_size, 1);
printf(", min. I/O size %d bytes\n", mtd.min_io_size);
}
@@ -768,7 +801,7 @@ int main(int argc, char * const argv[])
err = ubi_scan(&mtd, args.node_fd, &si, verbose);
if (err) {
errmsg("failed to scan mtd%d (%s)", mtd.dev_num, args.node);
- goto out;
+ goto out_close;
}
if (si->good_cnt == 0) {
@@ -777,7 +810,8 @@ int main(int argc, char * const argv[])
}
if (si->good_cnt < 2 && (!args.novtbl || args.image)) {
- errmsg("too few non-bad eraseblocks (%d) on mtd%d", si->good_cnt, mtd.dev_num);
+ errmsg("too few non-bad eraseblocks (%d) on mtd%d",
+ si->good_cnt, mtd.dev_num);
goto out_free;
}
@@ -842,7 +876,7 @@ int main(int argc, char * const argv[])
if (!args.quiet && args.override_ec)
normsg("use erase counter %lld for all eraseblocks", args.ec);
- ubigen_info_init(&ui, mtd.eb_size, mtd.min_io_size, args.subpage_size,
+ ubigen_info_init(&ui, mtd.eb_size, mtd.min_io_size, mtd.subpage_size,
args.vid_hdr_offs, args.ubi_ver);
if (si->vid_hdr_offs != -1 && ui.vid_hdr_offs != si->vid_hdr_offs) {
@@ -883,11 +917,14 @@ int main(int argc, char * const argv[])
ubi_scan_free(si);
close(args.node_fd);
+ libmtd_close(libmtd);
return 0;
out_free:
ubi_scan_free(si);
-out:
+out_close:
close(args.node_fd);
+out_close_mtd:
+ libmtd_close(libmtd);
return -1;
}