aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/ubi
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2012-12-20 18:49:14 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2012-12-20 18:49:14 -0500
commit21e89c0c48bb799beb09181740796fc80c9676e2 (patch)
treebd5aef34a980f189ad41c75e881d225bc854bf44 /drivers/mtd/ubi
parentb911a6bdeef5848c468597d040e3407e0aee04ce (diff)
parent91c7fbbf63f33c77d8d28de624834a21888842bb (diff)
Merge branch 'fscache' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs into for-linus
Diffstat (limited to 'drivers/mtd/ubi')
-rw-r--r--drivers/mtd/ubi/attach.c23
-rw-r--r--drivers/mtd/ubi/build.c12
-rw-r--r--drivers/mtd/ubi/debug.c34
-rw-r--r--drivers/mtd/ubi/debug.h57
-rw-r--r--drivers/mtd/ubi/fastmap.c6
-rw-r--r--drivers/mtd/ubi/gluebi.c28
-rw-r--r--drivers/mtd/ubi/io.c14
-rw-r--r--drivers/mtd/ubi/ubi.h40
-rw-r--r--drivers/mtd/ubi/upd.c6
-rw-r--r--drivers/mtd/ubi/vmt.c4
-rw-r--r--drivers/mtd/ubi/vtbl.c2
-rw-r--r--drivers/mtd/ubi/wl.c7
12 files changed, 98 insertions, 135 deletions
diff --git a/drivers/mtd/ubi/attach.c b/drivers/mtd/ubi/attach.c
index fec406b4553d..c071d410488f 100644
--- a/drivers/mtd/ubi/attach.c
+++ b/drivers/mtd/ubi/attach.c
@@ -322,7 +322,6 @@ static struct ubi_ainf_volume *add_volume(struct ubi_attach_info *ai,
322int ubi_compare_lebs(struct ubi_device *ubi, const struct ubi_ainf_peb *aeb, 322int ubi_compare_lebs(struct ubi_device *ubi, const struct ubi_ainf_peb *aeb,
323 int pnum, const struct ubi_vid_hdr *vid_hdr) 323 int pnum, const struct ubi_vid_hdr *vid_hdr)
324{ 324{
325 void *buf;
326 int len, err, second_is_newer, bitflips = 0, corrupted = 0; 325 int len, err, second_is_newer, bitflips = 0, corrupted = 0;
327 uint32_t data_crc, crc; 326 uint32_t data_crc, crc;
328 struct ubi_vid_hdr *vh = NULL; 327 struct ubi_vid_hdr *vh = NULL;
@@ -393,18 +392,14 @@ int ubi_compare_lebs(struct ubi_device *ubi, const struct ubi_ainf_peb *aeb,
393 /* Read the data of the copy and check the CRC */ 392 /* Read the data of the copy and check the CRC */
394 393
395 len = be32_to_cpu(vid_hdr->data_size); 394 len = be32_to_cpu(vid_hdr->data_size);
396 buf = vmalloc(len);
397 if (!buf) {
398 err = -ENOMEM;
399 goto out_free_vidh;
400 }
401 395
402 err = ubi_io_read_data(ubi, buf, pnum, 0, len); 396 mutex_lock(&ubi->buf_mutex);
397 err = ubi_io_read_data(ubi, ubi->peb_buf, pnum, 0, len);
403 if (err && err != UBI_IO_BITFLIPS && !mtd_is_eccerr(err)) 398 if (err && err != UBI_IO_BITFLIPS && !mtd_is_eccerr(err))
404 goto out_free_buf; 399 goto out_unlock;
405 400
406 data_crc = be32_to_cpu(vid_hdr->data_crc); 401 data_crc = be32_to_cpu(vid_hdr->data_crc);
407 crc = crc32(UBI_CRC32_INIT, buf, len); 402 crc = crc32(UBI_CRC32_INIT, ubi->peb_buf, len);
408 if (crc != data_crc) { 403 if (crc != data_crc) {
409 dbg_bld("PEB %d CRC error: calculated %#08x, must be %#08x", 404 dbg_bld("PEB %d CRC error: calculated %#08x, must be %#08x",
410 pnum, crc, data_crc); 405 pnum, crc, data_crc);
@@ -415,8 +410,8 @@ int ubi_compare_lebs(struct ubi_device *ubi, const struct ubi_ainf_peb *aeb,
415 dbg_bld("PEB %d CRC is OK", pnum); 410 dbg_bld("PEB %d CRC is OK", pnum);
416 bitflips = !!err; 411 bitflips = !!err;
417 } 412 }
413 mutex_unlock(&ubi->buf_mutex);
418 414
419 vfree(buf);
420 ubi_free_vid_hdr(ubi, vh); 415 ubi_free_vid_hdr(ubi, vh);
421 416
422 if (second_is_newer) 417 if (second_is_newer)
@@ -426,8 +421,8 @@ int ubi_compare_lebs(struct ubi_device *ubi, const struct ubi_ainf_peb *aeb,
426 421
427 return second_is_newer | (bitflips << 1) | (corrupted << 2); 422 return second_is_newer | (bitflips << 1) | (corrupted << 2);
428 423
429out_free_buf: 424out_unlock:
430 vfree(buf); 425 mutex_unlock(&ubi->buf_mutex);
431out_free_vidh: 426out_free_vidh:
432 ubi_free_vid_hdr(ubi, vh); 427 ubi_free_vid_hdr(ubi, vh);
433 return err; 428 return err;
@@ -1453,7 +1448,7 @@ int ubi_attach(struct ubi_device *ubi, int force_scan)
1453 goto out_wl; 1448 goto out_wl;
1454 1449
1455#ifdef CONFIG_MTD_UBI_FASTMAP 1450#ifdef CONFIG_MTD_UBI_FASTMAP
1456 if (ubi->fm && ubi->dbg->chk_gen) { 1451 if (ubi->fm && ubi_dbg_chk_gen(ubi)) {
1457 struct ubi_attach_info *scan_ai; 1452 struct ubi_attach_info *scan_ai;
1458 1453
1459 scan_ai = alloc_ai("ubi_ckh_aeb_slab_cache"); 1454 scan_ai = alloc_ai("ubi_ckh_aeb_slab_cache");
@@ -1503,7 +1498,7 @@ static int self_check_ai(struct ubi_device *ubi, struct ubi_attach_info *ai)
1503 struct ubi_ainf_peb *aeb, *last_aeb; 1498 struct ubi_ainf_peb *aeb, *last_aeb;
1504 uint8_t *buf; 1499 uint8_t *buf;
1505 1500
1506 if (!ubi->dbg->chk_gen) 1501 if (!ubi_dbg_chk_gen(ubi))
1507 return 0; 1502 return 0;
1508 1503
1509 /* 1504 /*
diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c
index 344b4cb49d4e..a56133585e92 100644
--- a/drivers/mtd/ubi/build.c
+++ b/drivers/mtd/ubi/build.c
@@ -825,8 +825,7 @@ static int autoresize(struct ubi_device *ubi, int vol_id)
825 * No available PEBs to re-size the volume, clear the flag on 825 * No available PEBs to re-size the volume, clear the flag on
826 * flash and exit. 826 * flash and exit.
827 */ 827 */
828 memcpy(&vtbl_rec, &ubi->vtbl[vol_id], 828 vtbl_rec = ubi->vtbl[vol_id];
829 sizeof(struct ubi_vtbl_record));
830 err = ubi_change_vtbl_record(ubi, vol_id, &vtbl_rec); 829 err = ubi_change_vtbl_record(ubi, vol_id, &vtbl_rec);
831 if (err) 830 if (err)
832 ubi_err("cannot clean auto-resize flag for volume %d", 831 ubi_err("cannot clean auto-resize flag for volume %d",
@@ -986,14 +985,10 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num,
986 if (!ubi->fm_buf) 985 if (!ubi->fm_buf)
987 goto out_free; 986 goto out_free;
988#endif 987#endif
989 err = ubi_debugging_init_dev(ubi);
990 if (err)
991 goto out_free;
992
993 err = ubi_attach(ubi, 0); 988 err = ubi_attach(ubi, 0);
994 if (err) { 989 if (err) {
995 ubi_err("failed to attach mtd%d, error %d", mtd->index, err); 990 ubi_err("failed to attach mtd%d, error %d", mtd->index, err);
996 goto out_debugging; 991 goto out_free;
997 } 992 }
998 993
999 if (ubi->autoresize_vol_id != -1) { 994 if (ubi->autoresize_vol_id != -1) {
@@ -1060,8 +1055,6 @@ out_detach:
1060 ubi_wl_close(ubi); 1055 ubi_wl_close(ubi);
1061 ubi_free_internal_volumes(ubi); 1056 ubi_free_internal_volumes(ubi);
1062 vfree(ubi->vtbl); 1057 vfree(ubi->vtbl);
1063out_debugging:
1064 ubi_debugging_exit_dev(ubi);
1065out_free: 1058out_free:
1066 vfree(ubi->peb_buf); 1059 vfree(ubi->peb_buf);
1067 vfree(ubi->fm_buf); 1060 vfree(ubi->fm_buf);
@@ -1139,7 +1132,6 @@ int ubi_detach_mtd_dev(int ubi_num, int anyway)
1139 ubi_free_internal_volumes(ubi); 1132 ubi_free_internal_volumes(ubi);
1140 vfree(ubi->vtbl); 1133 vfree(ubi->vtbl);
1141 put_mtd_device(ubi->mtd); 1134 put_mtd_device(ubi->mtd);
1142 ubi_debugging_exit_dev(ubi);
1143 vfree(ubi->peb_buf); 1135 vfree(ubi->peb_buf);
1144 vfree(ubi->fm_buf); 1136 vfree(ubi->fm_buf);
1145 ubi_msg("mtd%d is detached from ubi%d", ubi->mtd->index, ubi->ubi_num); 1137 ubi_msg("mtd%d is detached from ubi%d", ubi->mtd->index, ubi->ubi_num);
diff --git a/drivers/mtd/ubi/debug.c b/drivers/mtd/ubi/debug.c
index 26908a59506b..63cb1d7236ce 100644
--- a/drivers/mtd/ubi/debug.c
+++ b/drivers/mtd/ubi/debug.c
@@ -217,32 +217,6 @@ void ubi_dump_mkvol_req(const struct ubi_mkvol_req *req)
217 pr_err("\t1st 16 characters of name: %s\n", nm); 217 pr_err("\t1st 16 characters of name: %s\n", nm);
218} 218}
219 219
220/**
221 * ubi_debugging_init_dev - initialize debugging for an UBI device.
222 * @ubi: UBI device description object
223 *
224 * This function initializes debugging-related data for UBI device @ubi.
225 * Returns zero in case of success and a negative error code in case of
226 * failure.
227 */
228int ubi_debugging_init_dev(struct ubi_device *ubi)
229{
230 ubi->dbg = kzalloc(sizeof(struct ubi_debug_info), GFP_KERNEL);
231 if (!ubi->dbg)
232 return -ENOMEM;
233
234 return 0;
235}
236
237/**
238 * ubi_debugging_exit_dev - free debugging data for an UBI device.
239 * @ubi: UBI device description object
240 */
241void ubi_debugging_exit_dev(struct ubi_device *ubi)
242{
243 kfree(ubi->dbg);
244}
245
246/* 220/*
247 * Root directory for UBI stuff in debugfs. Contains sub-directories which 221 * Root directory for UBI stuff in debugfs. Contains sub-directories which
248 * contain the stuff specific to particular UBI devices. 222 * contain the stuff specific to particular UBI devices.
@@ -295,7 +269,7 @@ static ssize_t dfs_file_read(struct file *file, char __user *user_buf,
295 ubi = ubi_get_device(ubi_num); 269 ubi = ubi_get_device(ubi_num);
296 if (!ubi) 270 if (!ubi)
297 return -ENODEV; 271 return -ENODEV;
298 d = ubi->dbg; 272 d = &ubi->dbg;
299 273
300 if (dent == d->dfs_chk_gen) 274 if (dent == d->dfs_chk_gen)
301 val = d->chk_gen; 275 val = d->chk_gen;
@@ -341,7 +315,7 @@ static ssize_t dfs_file_write(struct file *file, const char __user *user_buf,
341 ubi = ubi_get_device(ubi_num); 315 ubi = ubi_get_device(ubi_num);
342 if (!ubi) 316 if (!ubi)
343 return -ENODEV; 317 return -ENODEV;
344 d = ubi->dbg; 318 d = &ubi->dbg;
345 319
346 buf_size = min_t(size_t, count, (sizeof(buf) - 1)); 320 buf_size = min_t(size_t, count, (sizeof(buf) - 1));
347 if (copy_from_user(buf, user_buf, buf_size)) { 321 if (copy_from_user(buf, user_buf, buf_size)) {
@@ -398,7 +372,7 @@ int ubi_debugfs_init_dev(struct ubi_device *ubi)
398 unsigned long ubi_num = ubi->ubi_num; 372 unsigned long ubi_num = ubi->ubi_num;
399 const char *fname; 373 const char *fname;
400 struct dentry *dent; 374 struct dentry *dent;
401 struct ubi_debug_info *d = ubi->dbg; 375 struct ubi_debug_info *d = &ubi->dbg;
402 376
403 if (!IS_ENABLED(CONFIG_DEBUG_FS)) 377 if (!IS_ENABLED(CONFIG_DEBUG_FS))
404 return 0; 378 return 0;
@@ -471,5 +445,5 @@ out:
471void ubi_debugfs_exit_dev(struct ubi_device *ubi) 445void ubi_debugfs_exit_dev(struct ubi_device *ubi)
472{ 446{
473 if (IS_ENABLED(CONFIG_DEBUG_FS)) 447 if (IS_ENABLED(CONFIG_DEBUG_FS))
474 debugfs_remove_recursive(ubi->dbg->dfs_dir); 448 debugfs_remove_recursive(ubi->dbg.dfs_dir);
475} 449}
diff --git a/drivers/mtd/ubi/debug.h b/drivers/mtd/ubi/debug.h
index 3dbc877d9663..33f8f3b2c9b2 100644
--- a/drivers/mtd/ubi/debug.h
+++ b/drivers/mtd/ubi/debug.h
@@ -60,51 +60,11 @@ void ubi_dump_aeb(const struct ubi_ainf_peb *aeb, int type);
60void ubi_dump_mkvol_req(const struct ubi_mkvol_req *req); 60void ubi_dump_mkvol_req(const struct ubi_mkvol_req *req);
61int ubi_self_check_all_ff(struct ubi_device *ubi, int pnum, int offset, 61int ubi_self_check_all_ff(struct ubi_device *ubi, int pnum, int offset,
62 int len); 62 int len);
63int ubi_debugging_init_dev(struct ubi_device *ubi);
64void ubi_debugging_exit_dev(struct ubi_device *ubi);
65int ubi_debugfs_init(void); 63int ubi_debugfs_init(void);
66void ubi_debugfs_exit(void); 64void ubi_debugfs_exit(void);
67int ubi_debugfs_init_dev(struct ubi_device *ubi); 65int ubi_debugfs_init_dev(struct ubi_device *ubi);
68void ubi_debugfs_exit_dev(struct ubi_device *ubi); 66void ubi_debugfs_exit_dev(struct ubi_device *ubi);
69 67
70/*
71 * The UBI debugfs directory name pattern and maximum name length (3 for "ubi"
72 * + 2 for the number plus 1 for the trailing zero byte.
73 */
74#define UBI_DFS_DIR_NAME "ubi%d"
75#define UBI_DFS_DIR_LEN (3 + 2 + 1)
76
77/**
78 * struct ubi_debug_info - debugging information for an UBI device.
79 *
80 * @chk_gen: if UBI general extra checks are enabled
81 * @chk_io: if UBI I/O extra checks are enabled
82 * @disable_bgt: disable the background task for testing purposes
83 * @emulate_bitflips: emulate bit-flips for testing purposes
84 * @emulate_io_failures: emulate write/erase failures for testing purposes
85 * @dfs_dir_name: name of debugfs directory containing files of this UBI device
86 * @dfs_dir: direntry object of the UBI device debugfs directory
87 * @dfs_chk_gen: debugfs knob to enable UBI general extra checks
88 * @dfs_chk_io: debugfs knob to enable UBI I/O extra checks
89 * @dfs_disable_bgt: debugfs knob to disable the background task
90 * @dfs_emulate_bitflips: debugfs knob to emulate bit-flips
91 * @dfs_emulate_io_failures: debugfs knob to emulate write/erase failures
92 */
93struct ubi_debug_info {
94 unsigned int chk_gen:1;
95 unsigned int chk_io:1;
96 unsigned int disable_bgt:1;
97 unsigned int emulate_bitflips:1;
98 unsigned int emulate_io_failures:1;
99 char dfs_dir_name[UBI_DFS_DIR_LEN + 1];
100 struct dentry *dfs_dir;
101 struct dentry *dfs_chk_gen;
102 struct dentry *dfs_chk_io;
103 struct dentry *dfs_disable_bgt;
104 struct dentry *dfs_emulate_bitflips;
105 struct dentry *dfs_emulate_io_failures;
106};
107
108/** 68/**
109 * ubi_dbg_is_bgt_disabled - if the background thread is disabled. 69 * ubi_dbg_is_bgt_disabled - if the background thread is disabled.
110 * @ubi: UBI device description object 70 * @ubi: UBI device description object
@@ -114,7 +74,7 @@ struct ubi_debug_info {
114 */ 74 */
115static inline int ubi_dbg_is_bgt_disabled(const struct ubi_device *ubi) 75static inline int ubi_dbg_is_bgt_disabled(const struct ubi_device *ubi)
116{ 76{
117 return ubi->dbg->disable_bgt; 77 return ubi->dbg.disable_bgt;
118} 78}
119 79
120/** 80/**
@@ -125,7 +85,7 @@ static inline int ubi_dbg_is_bgt_disabled(const struct ubi_device *ubi)
125 */ 85 */
126static inline int ubi_dbg_is_bitflip(const struct ubi_device *ubi) 86static inline int ubi_dbg_is_bitflip(const struct ubi_device *ubi)
127{ 87{
128 if (ubi->dbg->emulate_bitflips) 88 if (ubi->dbg.emulate_bitflips)
129 return !(random32() % 200); 89 return !(random32() % 200);
130 return 0; 90 return 0;
131} 91}
@@ -139,7 +99,7 @@ static inline int ubi_dbg_is_bitflip(const struct ubi_device *ubi)
139 */ 99 */
140static inline int ubi_dbg_is_write_failure(const struct ubi_device *ubi) 100static inline int ubi_dbg_is_write_failure(const struct ubi_device *ubi)
141{ 101{
142 if (ubi->dbg->emulate_io_failures) 102 if (ubi->dbg.emulate_io_failures)
143 return !(random32() % 500); 103 return !(random32() % 500);
144 return 0; 104 return 0;
145} 105}
@@ -153,9 +113,18 @@ static inline int ubi_dbg_is_write_failure(const struct ubi_device *ubi)
153 */ 113 */
154static inline int ubi_dbg_is_erase_failure(const struct ubi_device *ubi) 114static inline int ubi_dbg_is_erase_failure(const struct ubi_device *ubi)
155{ 115{
156 if (ubi->dbg->emulate_io_failures) 116 if (ubi->dbg.emulate_io_failures)
157 return !(random32() % 400); 117 return !(random32() % 400);
158 return 0; 118 return 0;
159} 119}
160 120
121static inline int ubi_dbg_chk_io(const struct ubi_device *ubi)
122{
123 return ubi->dbg.chk_io;
124}
125
126static inline int ubi_dbg_chk_gen(const struct ubi_device *ubi)
127{
128 return ubi->dbg.chk_gen;
129}
161#endif /* !__UBI_DEBUG_H__ */ 130#endif /* !__UBI_DEBUG_H__ */
diff --git a/drivers/mtd/ubi/fastmap.c b/drivers/mtd/ubi/fastmap.c
index 1a5f53c090d4..0648c6996d43 100644
--- a/drivers/mtd/ubi/fastmap.c
+++ b/drivers/mtd/ubi/fastmap.c
@@ -814,10 +814,8 @@ static int ubi_attach_fastmap(struct ubi_device *ubi,
814 if (max_sqnum > ai->max_sqnum) 814 if (max_sqnum > ai->max_sqnum)
815 ai->max_sqnum = max_sqnum; 815 ai->max_sqnum = max_sqnum;
816 816
817 list_for_each_entry_safe(tmp_aeb, _tmp_aeb, &free, u.list) { 817 list_for_each_entry_safe(tmp_aeb, _tmp_aeb, &free, u.list)
818 list_del(&tmp_aeb->u.list); 818 list_move_tail(&tmp_aeb->u.list, &ai->free);
819 list_add_tail(&tmp_aeb->u.list, &ai->free);
820 }
821 819
822 /* 820 /*
823 * If fastmap is leaking PEBs (must not happen), raise a 821 * If fastmap is leaking PEBs (must not happen), raise a
diff --git a/drivers/mtd/ubi/gluebi.c b/drivers/mtd/ubi/gluebi.c
index 4bd4db8c84c9..b93807b4c459 100644
--- a/drivers/mtd/ubi/gluebi.c
+++ b/drivers/mtd/ubi/gluebi.c
@@ -171,17 +171,17 @@ static void gluebi_put_device(struct mtd_info *mtd)
171static int gluebi_read(struct mtd_info *mtd, loff_t from, size_t len, 171static int gluebi_read(struct mtd_info *mtd, loff_t from, size_t len,
172 size_t *retlen, unsigned char *buf) 172 size_t *retlen, unsigned char *buf)
173{ 173{
174 int err = 0, lnum, offs, total_read; 174 int err = 0, lnum, offs, bytes_left;
175 struct gluebi_device *gluebi; 175 struct gluebi_device *gluebi;
176 176
177 gluebi = container_of(mtd, struct gluebi_device, mtd); 177 gluebi = container_of(mtd, struct gluebi_device, mtd);
178 lnum = div_u64_rem(from, mtd->erasesize, &offs); 178 lnum = div_u64_rem(from, mtd->erasesize, &offs);
179 total_read = len; 179 bytes_left = len;
180 while (total_read) { 180 while (bytes_left) {
181 size_t to_read = mtd->erasesize - offs; 181 size_t to_read = mtd->erasesize - offs;
182 182
183 if (to_read > total_read) 183 if (to_read > bytes_left)
184 to_read = total_read; 184 to_read = bytes_left;
185 185
186 err = ubi_read(gluebi->desc, lnum, buf, offs, to_read); 186 err = ubi_read(gluebi->desc, lnum, buf, offs, to_read);
187 if (err) 187 if (err)
@@ -189,11 +189,11 @@ static int gluebi_read(struct mtd_info *mtd, loff_t from, size_t len,
189 189
190 lnum += 1; 190 lnum += 1;
191 offs = 0; 191 offs = 0;
192 total_read -= to_read; 192 bytes_left -= to_read;
193 buf += to_read; 193 buf += to_read;
194 } 194 }
195 195
196 *retlen = len - total_read; 196 *retlen = len - bytes_left;
197 return err; 197 return err;
198} 198}
199 199
@@ -211,7 +211,7 @@ static int gluebi_read(struct mtd_info *mtd, loff_t from, size_t len,
211static int gluebi_write(struct mtd_info *mtd, loff_t to, size_t len, 211static int gluebi_write(struct mtd_info *mtd, loff_t to, size_t len,
212 size_t *retlen, const u_char *buf) 212 size_t *retlen, const u_char *buf)
213{ 213{
214 int err = 0, lnum, offs, total_written; 214 int err = 0, lnum, offs, bytes_left;
215 struct gluebi_device *gluebi; 215 struct gluebi_device *gluebi;
216 216
217 gluebi = container_of(mtd, struct gluebi_device, mtd); 217 gluebi = container_of(mtd, struct gluebi_device, mtd);
@@ -220,12 +220,12 @@ static int gluebi_write(struct mtd_info *mtd, loff_t to, size_t len,
220 if (len % mtd->writesize || offs % mtd->writesize) 220 if (len % mtd->writesize || offs % mtd->writesize)
221 return -EINVAL; 221 return -EINVAL;
222 222
223 total_written = len; 223 bytes_left = len;
224 while (total_written) { 224 while (bytes_left) {
225 size_t to_write = mtd->erasesize - offs; 225 size_t to_write = mtd->erasesize - offs;
226 226
227 if (to_write > total_written) 227 if (to_write > bytes_left)
228 to_write = total_written; 228 to_write = bytes_left;
229 229
230 err = ubi_leb_write(gluebi->desc, lnum, buf, offs, to_write); 230 err = ubi_leb_write(gluebi->desc, lnum, buf, offs, to_write);
231 if (err) 231 if (err)
@@ -233,11 +233,11 @@ static int gluebi_write(struct mtd_info *mtd, loff_t to, size_t len,
233 233
234 lnum += 1; 234 lnum += 1;
235 offs = 0; 235 offs = 0;
236 total_written -= to_write; 236 bytes_left -= to_write;
237 buf += to_write; 237 buf += to_write;
238 } 238 }
239 239
240 *retlen = len - total_written; 240 *retlen = len - bytes_left;
241 return err; 241 return err;
242} 242}
243 243
diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c
index 78a1dcbf2107..bf79def40126 100644
--- a/drivers/mtd/ubi/io.c
+++ b/drivers/mtd/ubi/io.c
@@ -1132,7 +1132,7 @@ static int self_check_not_bad(const struct ubi_device *ubi, int pnum)
1132{ 1132{
1133 int err; 1133 int err;
1134 1134
1135 if (!ubi->dbg->chk_io) 1135 if (!ubi_dbg_chk_io(ubi))
1136 return 0; 1136 return 0;
1137 1137
1138 err = ubi_io_is_bad(ubi, pnum); 1138 err = ubi_io_is_bad(ubi, pnum);
@@ -1159,7 +1159,7 @@ static int self_check_ec_hdr(const struct ubi_device *ubi, int pnum,
1159 int err; 1159 int err;
1160 uint32_t magic; 1160 uint32_t magic;
1161 1161
1162 if (!ubi->dbg->chk_io) 1162 if (!ubi_dbg_chk_io(ubi))
1163 return 0; 1163 return 0;
1164 1164
1165 magic = be32_to_cpu(ec_hdr->magic); 1165 magic = be32_to_cpu(ec_hdr->magic);
@@ -1197,7 +1197,7 @@ static int self_check_peb_ec_hdr(const struct ubi_device *ubi, int pnum)
1197 uint32_t crc, hdr_crc; 1197 uint32_t crc, hdr_crc;
1198 struct ubi_ec_hdr *ec_hdr; 1198 struct ubi_ec_hdr *ec_hdr;
1199 1199
1200 if (!ubi->dbg->chk_io) 1200 if (!ubi_dbg_chk_io(ubi))
1201 return 0; 1201 return 0;
1202 1202
1203 ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_NOFS); 1203 ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_NOFS);
@@ -1241,7 +1241,7 @@ static int self_check_vid_hdr(const struct ubi_device *ubi, int pnum,
1241 int err; 1241 int err;
1242 uint32_t magic; 1242 uint32_t magic;
1243 1243
1244 if (!ubi->dbg->chk_io) 1244 if (!ubi_dbg_chk_io(ubi))
1245 return 0; 1245 return 0;
1246 1246
1247 magic = be32_to_cpu(vid_hdr->magic); 1247 magic = be32_to_cpu(vid_hdr->magic);
@@ -1282,7 +1282,7 @@ static int self_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum)
1282 struct ubi_vid_hdr *vid_hdr; 1282 struct ubi_vid_hdr *vid_hdr;
1283 void *p; 1283 void *p;
1284 1284
1285 if (!ubi->dbg->chk_io) 1285 if (!ubi_dbg_chk_io(ubi))
1286 return 0; 1286 return 0;
1287 1287
1288 vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); 1288 vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS);
@@ -1334,7 +1334,7 @@ static int self_check_write(struct ubi_device *ubi, const void *buf, int pnum,
1334 void *buf1; 1334 void *buf1;
1335 loff_t addr = (loff_t)pnum * ubi->peb_size + offset; 1335 loff_t addr = (loff_t)pnum * ubi->peb_size + offset;
1336 1336
1337 if (!ubi->dbg->chk_io) 1337 if (!ubi_dbg_chk_io(ubi))
1338 return 0; 1338 return 0;
1339 1339
1340 buf1 = __vmalloc(len, GFP_NOFS, PAGE_KERNEL); 1340 buf1 = __vmalloc(len, GFP_NOFS, PAGE_KERNEL);
@@ -1398,7 +1398,7 @@ int ubi_self_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len)
1398 void *buf; 1398 void *buf;
1399 loff_t addr = (loff_t)pnum * ubi->peb_size + offset; 1399 loff_t addr = (loff_t)pnum * ubi->peb_size + offset;
1400 1400
1401 if (!ubi->dbg->chk_io) 1401 if (!ubi_dbg_chk_io(ubi))
1402 return 0; 1402 return 0;
1403 1403
1404 buf = __vmalloc(len, GFP_NOFS, PAGE_KERNEL); 1404 buf = __vmalloc(len, GFP_NOFS, PAGE_KERNEL);
diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h
index 7d57469723cf..8ea6297a208f 100644
--- a/drivers/mtd/ubi/ubi.h
+++ b/drivers/mtd/ubi/ubi.h
@@ -85,6 +85,13 @@
85#define UBI_UNKNOWN -1 85#define UBI_UNKNOWN -1
86 86
87/* 87/*
88 * The UBI debugfs directory name pattern and maximum name length (3 for "ubi"
89 * + 2 for the number plus 1 for the trailing zero byte.
90 */
91#define UBI_DFS_DIR_NAME "ubi%d"
92#define UBI_DFS_DIR_LEN (3 + 2 + 1)
93
94/*
88 * Error codes returned by the I/O sub-system. 95 * Error codes returned by the I/O sub-system.
89 * 96 *
90 * UBI_IO_FF: the read region of flash contains only 0xFFs 97 * UBI_IO_FF: the read region of flash contains only 0xFFs
@@ -342,6 +349,37 @@ struct ubi_volume_desc {
342struct ubi_wl_entry; 349struct ubi_wl_entry;
343 350
344/** 351/**
352 * struct ubi_debug_info - debugging information for an UBI device.
353 *
354 * @chk_gen: if UBI general extra checks are enabled
355 * @chk_io: if UBI I/O extra checks are enabled
356 * @disable_bgt: disable the background task for testing purposes
357 * @emulate_bitflips: emulate bit-flips for testing purposes
358 * @emulate_io_failures: emulate write/erase failures for testing purposes
359 * @dfs_dir_name: name of debugfs directory containing files of this UBI device
360 * @dfs_dir: direntry object of the UBI device debugfs directory
361 * @dfs_chk_gen: debugfs knob to enable UBI general extra checks
362 * @dfs_chk_io: debugfs knob to enable UBI I/O extra checks
363 * @dfs_disable_bgt: debugfs knob to disable the background task
364 * @dfs_emulate_bitflips: debugfs knob to emulate bit-flips
365 * @dfs_emulate_io_failures: debugfs knob to emulate write/erase failures
366 */
367struct ubi_debug_info {
368 unsigned int chk_gen:1;
369 unsigned int chk_io:1;
370 unsigned int disable_bgt:1;
371 unsigned int emulate_bitflips:1;
372 unsigned int emulate_io_failures:1;
373 char dfs_dir_name[UBI_DFS_DIR_LEN + 1];
374 struct dentry *dfs_dir;
375 struct dentry *dfs_chk_gen;
376 struct dentry *dfs_chk_io;
377 struct dentry *dfs_disable_bgt;
378 struct dentry *dfs_emulate_bitflips;
379 struct dentry *dfs_emulate_io_failures;
380};
381
382/**
345 * struct ubi_device - UBI device description structure 383 * struct ubi_device - UBI device description structure
346 * @dev: UBI device object to use the the Linux device model 384 * @dev: UBI device object to use the the Linux device model
347 * @cdev: character device object to create character device 385 * @cdev: character device object to create character device
@@ -545,7 +583,7 @@ struct ubi_device {
545 struct mutex buf_mutex; 583 struct mutex buf_mutex;
546 struct mutex ckvol_mutex; 584 struct mutex ckvol_mutex;
547 585
548 struct ubi_debug_info *dbg; 586 struct ubi_debug_info dbg;
549}; 587};
550 588
551/** 589/**
diff --git a/drivers/mtd/ubi/upd.c b/drivers/mtd/ubi/upd.c
index 9f2ebd8750e7..ec2c2dc1c1ca 100644
--- a/drivers/mtd/ubi/upd.c
+++ b/drivers/mtd/ubi/upd.c
@@ -64,8 +64,7 @@ static int set_update_marker(struct ubi_device *ubi, struct ubi_volume *vol)
64 return 0; 64 return 0;
65 } 65 }
66 66
67 memcpy(&vtbl_rec, &ubi->vtbl[vol->vol_id], 67 vtbl_rec = ubi->vtbl[vol->vol_id];
68 sizeof(struct ubi_vtbl_record));
69 vtbl_rec.upd_marker = 1; 68 vtbl_rec.upd_marker = 1;
70 69
71 mutex_lock(&ubi->device_mutex); 70 mutex_lock(&ubi->device_mutex);
@@ -93,8 +92,7 @@ static int clear_update_marker(struct ubi_device *ubi, struct ubi_volume *vol,
93 92
94 dbg_gen("clear update marker for volume %d", vol->vol_id); 93 dbg_gen("clear update marker for volume %d", vol->vol_id);
95 94
96 memcpy(&vtbl_rec, &ubi->vtbl[vol->vol_id], 95 vtbl_rec = ubi->vtbl[vol->vol_id];
97 sizeof(struct ubi_vtbl_record));
98 ubi_assert(vol->upd_marker && vtbl_rec.upd_marker); 96 ubi_assert(vol->upd_marker && vtbl_rec.upd_marker);
99 vtbl_rec.upd_marker = 0; 97 vtbl_rec.upd_marker = 0;
100 98
diff --git a/drivers/mtd/ubi/vmt.c b/drivers/mtd/ubi/vmt.c
index 9169e58c262e..8330703c098f 100644
--- a/drivers/mtd/ubi/vmt.c
+++ b/drivers/mtd/ubi/vmt.c
@@ -535,7 +535,7 @@ int ubi_resize_volume(struct ubi_volume_desc *desc, int reserved_pebs)
535 } 535 }
536 536
537 /* Change volume table record */ 537 /* Change volume table record */
538 memcpy(&vtbl_rec, &ubi->vtbl[vol_id], sizeof(struct ubi_vtbl_record)); 538 vtbl_rec = ubi->vtbl[vol_id];
539 vtbl_rec.reserved_pebs = cpu_to_be32(reserved_pebs); 539 vtbl_rec.reserved_pebs = cpu_to_be32(reserved_pebs);
540 err = ubi_change_vtbl_record(ubi, vol_id, &vtbl_rec); 540 err = ubi_change_vtbl_record(ubi, vol_id, &vtbl_rec);
541 if (err) 541 if (err)
@@ -847,7 +847,7 @@ static int self_check_volumes(struct ubi_device *ubi)
847{ 847{
848 int i, err = 0; 848 int i, err = 0;
849 849
850 if (!ubi->dbg->chk_gen) 850 if (!ubi_dbg_chk_gen(ubi))
851 return 0; 851 return 0;
852 852
853 for (i = 0; i < ubi->vtbl_slots; i++) { 853 for (i = 0; i < ubi->vtbl_slots; i++) {
diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c
index 926e3df14fb2..d77b1c1d7c72 100644
--- a/drivers/mtd/ubi/vtbl.c
+++ b/drivers/mtd/ubi/vtbl.c
@@ -858,7 +858,7 @@ out_free:
858 */ 858 */
859static void self_vtbl_check(const struct ubi_device *ubi) 859static void self_vtbl_check(const struct ubi_device *ubi)
860{ 860{
861 if (!ubi->dbg->chk_gen) 861 if (!ubi_dbg_chk_gen(ubi))
862 return; 862 return;
863 863
864 if (vtbl_check(ubi, ubi->vtbl)) { 864 if (vtbl_check(ubi, ubi->vtbl)) {
diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c
index 2144f611196e..5df49d3cb5c7 100644
--- a/drivers/mtd/ubi/wl.c
+++ b/drivers/mtd/ubi/wl.c
@@ -1,5 +1,4 @@
1/* 1/*
2 * @ubi: UBI device description object
3 * Copyright (c) International Business Machines Corp., 2006 2 * Copyright (c) International Business Machines Corp., 2006
4 * 3 *
5 * This program is free software; you can redistribute it and/or modify 4 * This program is free software; you can redistribute it and/or modify
@@ -2050,7 +2049,7 @@ static int self_check_ec(struct ubi_device *ubi, int pnum, int ec)
2050 long long read_ec; 2049 long long read_ec;
2051 struct ubi_ec_hdr *ec_hdr; 2050 struct ubi_ec_hdr *ec_hdr;
2052 2051
2053 if (!ubi->dbg->chk_gen) 2052 if (!ubi_dbg_chk_gen(ubi))
2054 return 0; 2053 return 0;
2055 2054
2056 ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_NOFS); 2055 ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_NOFS);
@@ -2090,7 +2089,7 @@ out_free:
2090static int self_check_in_wl_tree(const struct ubi_device *ubi, 2089static int self_check_in_wl_tree(const struct ubi_device *ubi,
2091 struct ubi_wl_entry *e, struct rb_root *root) 2090 struct ubi_wl_entry *e, struct rb_root *root)
2092{ 2091{
2093 if (!ubi->dbg->chk_gen) 2092 if (!ubi_dbg_chk_gen(ubi))
2094 return 0; 2093 return 0;
2095 2094
2096 if (in_wl_tree(e, root)) 2095 if (in_wl_tree(e, root))
@@ -2116,7 +2115,7 @@ static int self_check_in_pq(const struct ubi_device *ubi,
2116 struct ubi_wl_entry *p; 2115 struct ubi_wl_entry *p;
2117 int i; 2116 int i;
2118 2117
2119 if (!ubi->dbg->chk_gen) 2118 if (!ubi_dbg_chk_gen(ubi))
2120 return 0; 2119 return 0;
2121 2120
2122 for (i = 0; i < UBI_PROT_QUEUE_LEN; ++i) 2121 for (i = 0; i < UBI_PROT_QUEUE_LEN; ++i)