summaryrefslogtreecommitdiffstats
path: root/patches/mtd-utils-2.0.2/0001-nandmarkbad-new-util-to-mark-blocks-as-bad.patch
blob: 1cea5f238e20a7133fcd5ad351ba7a3973dc5c0f (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= <u.kleine-koenig@pengutronix.de>
Date: Wed, 30 Aug 2017 13:31:46 +0200
Subject: [PATCH] nandmarkbad: new util to mark blocks as bad

---
 nand-utils/Makemodule.am |   5 +-
 nand-utils/nandmarkbad.c | 119 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 123 insertions(+), 1 deletion(-)
 create mode 100644 nand-utils/nandmarkbad.c

diff --git a/nand-utils/Makemodule.am b/nand-utils/Makemodule.am
index d75b0cb3e36c..c31dcb01f06e 100644
--- a/nand-utils/Makemodule.am
+++ b/nand-utils/Makemodule.am
@@ -7,6 +7,9 @@ nandwrite_LDADD = libmtd.a
 nandtest_SOURCES = nand-utils/nandtest.c
 nandtest_LDADD = libmtd.a
 
+nandmarkbad_SOURCES = nand-utils/nandmarkbad.c
+nandmarkbad_LDADD = libmtd.a
+
 nftldump_SOURCES = nand-utils/nftldump.c
 nftldump_LDADD = libmtd.a
 
@@ -14,7 +17,7 @@ nftl_format_SOURCES = nand-utils/nftl_format.c
 nftl_format_LDADD = libmtd.a
 
 NAND_BINS = \
-	nanddump nandwrite nandtest nftldump nftl_format
+	nanddump nandwrite nandtest nandmarkbad nftldump nftl_format
 
 NAND_SH = \
 	nand-utils/load_nandsim.sh
diff --git a/nand-utils/nandmarkbad.c b/nand-utils/nandmarkbad.c
new file mode 100644
index 000000000000..cf05698c3609
--- /dev/null
+++ b/nand-utils/nandmarkbad.c
@@ -0,0 +1,119 @@
+#define PROGRAM_NAME "nandmarkbad"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <getopt.h>
+
+#include "common.h"
+#include <libmtd.h>
+
+static void usage(int status)
+{
+	fprintf(status ? stderr : stdout,
+		"usage: %s [OPTIONS] <device>\n\n"
+		"  -b, --markbad=blockno        Mark block bad\n"
+		"  -h, --help                   Display this help and exit\n"
+		"  -V, --version                Output version information and exit\n"
+		"  -y, --i-know-what-i-do       really do mark blocks as bad\n",
+		PROGRAM_NAME);
+	exit(status);
+}
+
+/*
+ * Main program
+ */
+int main(int argc, char **argv)
+{
+	loff_t mark_bad[32];
+	unsigned cnt_bad = 0;
+	struct mtd_dev_info mtd;
+	libmtd_t mtd_desc;
+	int fd;
+	int error = 0;
+	int ret;
+	unsigned int i;
+	int iknowwhatido = 0;
+
+	for (;;) {
+		static const char short_options[] = "b:hVy";
+		static const struct option long_options[] = {
+			{ "help", no_argument, 0, 'h' },
+			{ "markbad", required_argument, 0, 'b' },
+			{ "version", no_argument, 0, 'V'},
+			{ "i-know-what-i-do", no_argument, 0, 'y' },
+			{0, 0, 0, 0},
+		};
+		int option_index = 0;
+		int c = getopt_long(argc, argv, short_options, long_options,
+				    &option_index);
+		if (c == EOF)
+			break;
+
+		switch (c) {
+		case '?':
+			usage(EXIT_FAILURE);
+			break;
+
+		case 'b':
+			if (cnt_bad < ARRAY_SIZE(mark_bad)) {
+				mark_bad[cnt_bad] =
+					simple_strtoll(optarg, &error);
+				++cnt_bad;
+			} else {
+				errmsg_die("Can't handle so many bad blocks\n");
+			}
+
+			break;
+
+		case 'h':
+			usage(EXIT_SUCCESS);
+			break;
+
+		case 'V':
+			common_print_version();
+			return EXIT_SUCCESS;
+
+		case 'y':
+			iknowwhatido = 1;
+			break;
+		}
+	}
+
+	argc -= optind;
+	argv += optind;
+
+	if (error)
+		usage(EXIT_FAILURE);
+
+	if (argc != 1)
+		errmsg_die("You must specify a device to operate on\n");
+
+	if (!cnt_bad)
+		errmsg_die("You must specify at least one block to mark bad\n");
+
+	if (!iknowwhatido)
+		errmsg_die(PROGRAM_NAME " does things that are hard to undo.\n"
+			   "\tPlease convince yourself you understand the risks,\n"
+			   "\tthen add --i-know-what-i-do to the options.\n");
+
+	fd = open(argv[0], O_RDWR);
+	if (fd < 0)
+		sys_errmsg_die("Failed to open mtd device\n");
+
+	mtd_desc = libmtd_open();
+	if (!mtd_desc)
+		errmsg_die("Can't initialize libmtd");
+
+	if (mtd_get_dev_info(mtd_desc, argv[0], &mtd) < 0)
+		errmsg_die("mtd_get_dev_info failed");
+
+	for (i = 0; i < cnt_bad; ++i) {
+		ret = mtd_mark_bad(&mtd, fd, mark_bad[i]);
+		if (ret)
+			sys_errmsg_die("%s: MTD Mark bad block failure",
+				       argv[0]);
+	}
+
+	return EXIT_SUCCESS;
+}