hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/drivers/mtd/mtdcore.c
....@@ -1,24 +1,10 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Core registration and callback routines for MTD
34 * drivers and users.
45 *
56 * Copyright © 1999-2010 David Woodhouse <dwmw2@infradead.org>
67 * Copyright © 2006 Red Hat UK Limited
7
- *
8
- * This program is free software; you can redistribute it and/or modify
9
- * it under the terms of the GNU General Public License as published by
10
- * the Free Software Foundation; either version 2 of the License, or
11
- * (at your option) any later version.
12
- *
13
- * This program is distributed in the hope that it will be useful,
14
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
- * GNU General Public License for more details.
17
- *
18
- * You should have received a copy of the GNU General Public License
19
- * along with this program; if not, write to the Free Software
20
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21
- *
228 */
239
2410 #include <linux/module.h>
....@@ -41,6 +27,7 @@
4127 #include <linux/reboot.h>
4228 #include <linux/leds.h>
4329 #include <linux/debugfs.h>
30
+#include <linux/nvmem-provider.h>
4431
4532 #include <linux/mtd/mtd.h>
4633 #include <linux/mtd/partitions.h>
....@@ -154,7 +141,6 @@
154141 struct mtd_info *mtd = dev_get_drvdata(dev);
155142
156143 return snprintf(buf, PAGE_SIZE, "0x%lx\n", (unsigned long)mtd->flags);
157
-
158144 }
159145 static DEVICE_ATTR(flags, S_IRUGO, mtd_flags_show, NULL);
160146
....@@ -165,7 +151,6 @@
165151
166152 return snprintf(buf, PAGE_SIZE, "%llu\n",
167153 (unsigned long long)mtd->size);
168
-
169154 }
170155 static DEVICE_ATTR(size, S_IRUGO, mtd_size_show, NULL);
171156
....@@ -175,7 +160,6 @@
175160 struct mtd_info *mtd = dev_get_drvdata(dev);
176161
177162 return snprintf(buf, PAGE_SIZE, "%lu\n", (unsigned long)mtd->erasesize);
178
-
179163 }
180164 static DEVICE_ATTR(erasesize, S_IRUGO, mtd_erasesize_show, NULL);
181165
....@@ -185,7 +169,6 @@
185169 struct mtd_info *mtd = dev_get_drvdata(dev);
186170
187171 return snprintf(buf, PAGE_SIZE, "%lu\n", (unsigned long)mtd->writesize);
188
-
189172 }
190173 static DEVICE_ATTR(writesize, S_IRUGO, mtd_writesize_show, NULL);
191174
....@@ -196,7 +179,6 @@
196179 unsigned int subpagesize = mtd->writesize >> mtd->subpage_sft;
197180
198181 return snprintf(buf, PAGE_SIZE, "%u\n", subpagesize);
199
-
200182 }
201183 static DEVICE_ATTR(subpagesize, S_IRUGO, mtd_subpagesize_show, NULL);
202184
....@@ -206,7 +188,6 @@
206188 struct mtd_info *mtd = dev_get_drvdata(dev);
207189
208190 return snprintf(buf, PAGE_SIZE, "%lu\n", (unsigned long)mtd->oobsize);
209
-
210191 }
211192 static DEVICE_ATTR(oobsize, S_IRUGO, mtd_oobsize_show, NULL);
212193
....@@ -225,7 +206,6 @@
225206 struct mtd_info *mtd = dev_get_drvdata(dev);
226207
227208 return snprintf(buf, PAGE_SIZE, "%u\n", mtd->numeraseregions);
228
-
229209 }
230210 static DEVICE_ATTR(numeraseregions, S_IRUGO, mtd_numeraseregions_show,
231211 NULL);
....@@ -236,7 +216,6 @@
236216 struct mtd_info *mtd = dev_get_drvdata(dev);
237217
238218 return snprintf(buf, PAGE_SIZE, "%s\n", mtd->name);
239
-
240219 }
241220 static DEVICE_ATTR(name, S_IRUGO, mtd_name_show, NULL);
242221
....@@ -356,6 +335,50 @@
356335 .release = mtd_release,
357336 };
358337
338
+static int mtd_partid_debug_show(struct seq_file *s, void *p)
339
+{
340
+ struct mtd_info *mtd = s->private;
341
+
342
+ seq_printf(s, "%s\n", mtd->dbg.partid);
343
+
344
+ return 0;
345
+}
346
+
347
+DEFINE_SHOW_ATTRIBUTE(mtd_partid_debug);
348
+
349
+static int mtd_partname_debug_show(struct seq_file *s, void *p)
350
+{
351
+ struct mtd_info *mtd = s->private;
352
+
353
+ seq_printf(s, "%s\n", mtd->dbg.partname);
354
+
355
+ return 0;
356
+}
357
+
358
+DEFINE_SHOW_ATTRIBUTE(mtd_partname_debug);
359
+
360
+static struct dentry *dfs_dir_mtd;
361
+
362
+static void mtd_debugfs_populate(struct mtd_info *mtd)
363
+{
364
+ struct device *dev = &mtd->dev;
365
+ struct dentry *root;
366
+
367
+ if (IS_ERR_OR_NULL(dfs_dir_mtd))
368
+ return;
369
+
370
+ root = debugfs_create_dir(dev_name(dev), dfs_dir_mtd);
371
+ mtd->dbg.dfs_dir = root;
372
+
373
+ if (mtd->dbg.partid)
374
+ debugfs_create_file("partid", 0400, root, mtd,
375
+ &mtd_partid_debug_fops);
376
+
377
+ if (mtd->dbg.partname)
378
+ debugfs_create_file("partname", 0400, root, mtd,
379
+ &mtd_partname_debug_fops);
380
+}
381
+
359382 #ifndef CONFIG_MMU
360383 unsigned mtd_mmap_capabilities(struct mtd_info *mtd)
361384 {
....@@ -413,13 +436,14 @@
413436 int mtd_wunit_to_pairing_info(struct mtd_info *mtd, int wunit,
414437 struct mtd_pairing_info *info)
415438 {
416
- int npairs = mtd_wunit_per_eb(mtd) / mtd_pairing_groups(mtd);
439
+ struct mtd_info *master = mtd_get_master(mtd);
440
+ int npairs = mtd_wunit_per_eb(master) / mtd_pairing_groups(master);
417441
418442 if (wunit < 0 || wunit >= npairs)
419443 return -EINVAL;
420444
421
- if (mtd->pairing && mtd->pairing->get_info)
422
- return mtd->pairing->get_info(mtd, wunit, info);
445
+ if (master->pairing && master->pairing->get_info)
446
+ return master->pairing->get_info(master, wunit, info);
423447
424448 info->group = 0;
425449 info->pair = wunit;
....@@ -455,15 +479,16 @@
455479 int mtd_pairing_info_to_wunit(struct mtd_info *mtd,
456480 const struct mtd_pairing_info *info)
457481 {
458
- int ngroups = mtd_pairing_groups(mtd);
459
- int npairs = mtd_wunit_per_eb(mtd) / ngroups;
482
+ struct mtd_info *master = mtd_get_master(mtd);
483
+ int ngroups = mtd_pairing_groups(master);
484
+ int npairs = mtd_wunit_per_eb(master) / ngroups;
460485
461486 if (!info || info->pair < 0 || info->pair >= npairs ||
462487 info->group < 0 || info->group >= ngroups)
463488 return -EINVAL;
464489
465
- if (mtd->pairing && mtd->pairing->get_wunit)
466
- return mtd->pairing->get_wunit(mtd, info);
490
+ if (master->pairing && master->pairing->get_wunit)
491
+ return mtd->pairing->get_wunit(master, info);
467492
468493 return info->pair;
469494 }
....@@ -481,14 +506,59 @@
481506 */
482507 int mtd_pairing_groups(struct mtd_info *mtd)
483508 {
484
- if (!mtd->pairing || !mtd->pairing->ngroups)
509
+ struct mtd_info *master = mtd_get_master(mtd);
510
+
511
+ if (!master->pairing || !master->pairing->ngroups)
485512 return 1;
486513
487
- return mtd->pairing->ngroups;
514
+ return master->pairing->ngroups;
488515 }
489516 EXPORT_SYMBOL_GPL(mtd_pairing_groups);
490517
491
-static struct dentry *dfs_dir_mtd;
518
+static int mtd_nvmem_reg_read(void *priv, unsigned int offset,
519
+ void *val, size_t bytes)
520
+{
521
+ struct mtd_info *mtd = priv;
522
+ size_t retlen;
523
+ int err;
524
+
525
+ err = mtd_read(mtd, offset, bytes, &retlen, val);
526
+ if (err && err != -EUCLEAN)
527
+ return err;
528
+
529
+ return retlen == bytes ? 0 : -EIO;
530
+}
531
+
532
+static int mtd_nvmem_add(struct mtd_info *mtd)
533
+{
534
+ struct nvmem_config config = {};
535
+
536
+ config.id = -1;
537
+ config.dev = &mtd->dev;
538
+ config.name = dev_name(&mtd->dev);
539
+ config.owner = THIS_MODULE;
540
+ config.reg_read = mtd_nvmem_reg_read;
541
+ config.size = mtd->size;
542
+ config.word_size = 1;
543
+ config.stride = 1;
544
+ config.read_only = true;
545
+ config.root_only = true;
546
+ config.no_of_node = true;
547
+ config.priv = mtd;
548
+
549
+ mtd->nvmem = nvmem_register(&config);
550
+ if (IS_ERR(mtd->nvmem)) {
551
+ /* Just ignore if there is no NVMEM support in the kernel */
552
+ if (PTR_ERR(mtd->nvmem) == -EOPNOTSUPP) {
553
+ mtd->nvmem = NULL;
554
+ } else {
555
+ dev_err(&mtd->dev, "Failed to register NVMEM device\n");
556
+ return PTR_ERR(mtd->nvmem);
557
+ }
558
+ }
559
+
560
+ return 0;
561
+}
492562
493563 /**
494564 * add_mtd_device - register an MTD device
....@@ -501,6 +571,7 @@
501571
502572 int add_mtd_device(struct mtd_info *mtd)
503573 {
574
+ struct mtd_info *master = mtd_get_master(mtd);
504575 struct mtd_notifier *not;
505576 int i, error;
506577
....@@ -514,8 +585,29 @@
514585
515586 BUG_ON(mtd->writesize == 0);
516587
517
- if (WARN_ON((!mtd->erasesize || !mtd->_erase) &&
588
+ /*
589
+ * MTD drivers should implement ->_{write,read}() or
590
+ * ->_{write,read}_oob(), but not both.
591
+ */
592
+ if (WARN_ON((mtd->_write && mtd->_write_oob) ||
593
+ (mtd->_read && mtd->_read_oob)))
594
+ return -EINVAL;
595
+
596
+ if (WARN_ON((!mtd->erasesize || !master->_erase) &&
518597 !(mtd->flags & MTD_NO_ERASE)))
598
+ return -EINVAL;
599
+
600
+ /*
601
+ * MTD_SLC_ON_MLC_EMULATION can only be set on partitions, when the
602
+ * master is an MLC NAND and has a proper pairing scheme defined.
603
+ * We also reject masters that implement ->_writev() for now, because
604
+ * NAND controller drivers don't implement this hook, and adding the
605
+ * SLC -> MLC address/length conversion to this path is useless if we
606
+ * don't have a user.
607
+ */
608
+ if (mtd->flags & MTD_SLC_ON_MLC_EMULATION &&
609
+ (!mtd_is_partition(mtd) || master->type != MTD_MLCNANDFLASH ||
610
+ !master->pairing || master->_writev))
519611 return -EINVAL;
520612
521613 mutex_lock(&mtd_table_mutex);
....@@ -532,6 +624,14 @@
532624 /* default value if not set by driver */
533625 if (mtd->bitflip_threshold == 0)
534626 mtd->bitflip_threshold = mtd->ecc_strength;
627
+
628
+ if (mtd->flags & MTD_SLC_ON_MLC_EMULATION) {
629
+ int ngroups = mtd_pairing_groups(master);
630
+
631
+ mtd->erasesize /= ngroups;
632
+ mtd->size = (u64)mtd_div_by_eb(mtd->size, master) *
633
+ mtd->erasesize;
634
+ }
535635
536636 if (is_power_of_2(mtd->erasesize))
537637 mtd->erasesize_shift = ffs(mtd->erasesize) - 1;
....@@ -567,16 +667,17 @@
567667 dev_set_drvdata(&mtd->dev, mtd);
568668 of_node_get(mtd_get_of_node(mtd));
569669 error = device_register(&mtd->dev);
570
- if (error)
670
+ if (error) {
671
+ put_device(&mtd->dev);
571672 goto fail_added;
572
-
573
- if (!IS_ERR_OR_NULL(dfs_dir_mtd)) {
574
- mtd->dbg.dfs_dir = debugfs_create_dir(dev_name(&mtd->dev), dfs_dir_mtd);
575
- if (IS_ERR_OR_NULL(mtd->dbg.dfs_dir)) {
576
- pr_debug("mtd device %s won't show data in debugfs\n",
577
- dev_name(&mtd->dev));
578
- }
579673 }
674
+
675
+ /* Add the nvmem provider */
676
+ error = mtd_nvmem_add(mtd);
677
+ if (error)
678
+ goto fail_nvmem_add;
679
+
680
+ mtd_debugfs_populate(mtd);
580681
581682 device_create(&mtd_class, mtd->dev.parent, MTD_DEVT(i) + 1, NULL,
582683 "mtd%dro", i);
....@@ -595,6 +696,8 @@
595696 __module_get(THIS_MODULE);
596697 return 0;
597698
699
+fail_nvmem_add:
700
+ device_unregister(&mtd->dev);
598701 fail_added:
599702 of_node_put(mtd_get_of_node(mtd));
600703 idr_remove(&mtd_idr, i);
....@@ -620,8 +723,6 @@
620723
621724 mutex_lock(&mtd_table_mutex);
622725
623
- debugfs_remove_recursive(mtd->dbg.dfs_dir);
624
-
625726 if (idr_find(&mtd_idr, mtd->index) != mtd) {
626727 ret = -ENODEV;
627728 goto out_error;
....@@ -637,6 +738,12 @@
637738 mtd->index, mtd->name, mtd->usecount);
638739 ret = -EBUSY;
639740 } else {
741
+ debugfs_remove_recursive(mtd->dbg.dfs_dir);
742
+
743
+ /* Try to remove the NVMEM provider */
744
+ if (mtd->nvmem)
745
+ nvmem_unregister(mtd->nvmem);
746
+
640747 device_unregister(&mtd->dev);
641748
642749 idr_remove(&mtd_idr, mtd->index);
....@@ -665,6 +772,9 @@
665772 } else {
666773 pr_debug("mtd device won't show a device symlink in sysfs\n");
667774 }
775
+
776
+ INIT_LIST_HEAD(&mtd->partitions);
777
+ mutex_init(&mtd->master.partitions_lock);
668778 }
669779
670780 /**
....@@ -873,20 +983,28 @@
873983
874984 int __get_mtd_device(struct mtd_info *mtd)
875985 {
986
+ struct mtd_info *master = mtd_get_master(mtd);
876987 int err;
877988
878
- if (!try_module_get(mtd->owner))
989
+ if (!try_module_get(master->owner))
879990 return -ENODEV;
880991
881
- if (mtd->_get_device) {
882
- err = mtd->_get_device(mtd);
992
+ if (master->_get_device) {
993
+ err = master->_get_device(mtd);
883994
884995 if (err) {
885
- module_put(mtd->owner);
996
+ module_put(master->owner);
886997 return err;
887998 }
888999 }
889
- mtd->usecount++;
1000
+
1001
+ master->usecount++;
1002
+
1003
+ while (mtd->parent) {
1004
+ mtd->usecount++;
1005
+ mtd = mtd->parent;
1006
+ }
1007
+
8901008 return 0;
8911009 }
8921010 EXPORT_SYMBOL_GPL(__get_mtd_device);
....@@ -940,13 +1058,20 @@
9401058
9411059 void __put_mtd_device(struct mtd_info *mtd)
9421060 {
943
- --mtd->usecount;
944
- BUG_ON(mtd->usecount < 0);
1061
+ struct mtd_info *master = mtd_get_master(mtd);
9451062
946
- if (mtd->_put_device)
947
- mtd->_put_device(mtd);
1063
+ while (mtd->parent) {
1064
+ --mtd->usecount;
1065
+ BUG_ON(mtd->usecount < 0);
1066
+ mtd = mtd->parent;
1067
+ }
9481068
949
- module_put(mtd->owner);
1069
+ master->usecount--;
1070
+
1071
+ if (master->_put_device)
1072
+ master->_put_device(master);
1073
+
1074
+ module_put(master->owner);
9501075 }
9511076 EXPORT_SYMBOL_GPL(__put_mtd_device);
9521077
....@@ -957,9 +1082,15 @@
9571082 */
9581083 int mtd_erase(struct mtd_info *mtd, struct erase_info *instr)
9591084 {
960
- instr->fail_addr = MTD_FAIL_ADDR_UNKNOWN;
1085
+ struct mtd_info *master = mtd_get_master(mtd);
1086
+ u64 mst_ofs = mtd_get_master_ofs(mtd, 0);
1087
+ struct erase_info adjinstr;
1088
+ int ret;
9611089
962
- if (!mtd->erasesize || !mtd->_erase)
1090
+ instr->fail_addr = MTD_FAIL_ADDR_UNKNOWN;
1091
+ adjinstr = *instr;
1092
+
1093
+ if (!mtd->erasesize || !master->_erase)
9631094 return -ENOTSUPP;
9641095
9651096 if (instr->addr >= mtd->size || instr->len > mtd->size - instr->addr)
....@@ -971,7 +1102,29 @@
9711102 return 0;
9721103
9731104 ledtrig_mtd_activity();
974
- return mtd->_erase(mtd, instr);
1105
+
1106
+ if (mtd->flags & MTD_SLC_ON_MLC_EMULATION) {
1107
+ adjinstr.addr = (loff_t)mtd_div_by_eb(instr->addr, mtd) *
1108
+ master->erasesize;
1109
+ adjinstr.len = ((u64)mtd_div_by_eb(instr->addr + instr->len, mtd) *
1110
+ master->erasesize) -
1111
+ adjinstr.addr;
1112
+ }
1113
+
1114
+ adjinstr.addr += mst_ofs;
1115
+
1116
+ ret = master->_erase(master, &adjinstr);
1117
+
1118
+ if (adjinstr.fail_addr != MTD_FAIL_ADDR_UNKNOWN) {
1119
+ instr->fail_addr = adjinstr.fail_addr - mst_ofs;
1120
+ if (mtd->flags & MTD_SLC_ON_MLC_EMULATION) {
1121
+ instr->fail_addr = mtd_div_by_eb(instr->fail_addr,
1122
+ master);
1123
+ instr->fail_addr *= mtd->erasesize;
1124
+ }
1125
+ }
1126
+
1127
+ return ret;
9751128 }
9761129 EXPORT_SYMBOL_GPL(mtd_erase);
9771130
....@@ -981,30 +1134,36 @@
9811134 int mtd_point(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen,
9821135 void **virt, resource_size_t *phys)
9831136 {
1137
+ struct mtd_info *master = mtd_get_master(mtd);
1138
+
9841139 *retlen = 0;
9851140 *virt = NULL;
9861141 if (phys)
9871142 *phys = 0;
988
- if (!mtd->_point)
1143
+ if (!master->_point)
9891144 return -EOPNOTSUPP;
9901145 if (from < 0 || from >= mtd->size || len > mtd->size - from)
9911146 return -EINVAL;
9921147 if (!len)
9931148 return 0;
994
- return mtd->_point(mtd, from, len, retlen, virt, phys);
1149
+
1150
+ from = mtd_get_master_ofs(mtd, from);
1151
+ return master->_point(master, from, len, retlen, virt, phys);
9951152 }
9961153 EXPORT_SYMBOL_GPL(mtd_point);
9971154
9981155 /* We probably shouldn't allow XIP if the unpoint isn't a NULL */
9991156 int mtd_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
10001157 {
1001
- if (!mtd->_unpoint)
1158
+ struct mtd_info *master = mtd_get_master(mtd);
1159
+
1160
+ if (!master->_unpoint)
10021161 return -EOPNOTSUPP;
10031162 if (from < 0 || from >= mtd->size || len > mtd->size - from)
10041163 return -EINVAL;
10051164 if (!len)
10061165 return 0;
1007
- return mtd->_unpoint(mtd, from, len);
1166
+ return master->_unpoint(master, mtd_get_master_ofs(mtd, from), len);
10081167 }
10091168 EXPORT_SYMBOL_GPL(mtd_unpoint);
10101169
....@@ -1031,70 +1190,54 @@
10311190 }
10321191 EXPORT_SYMBOL_GPL(mtd_get_unmapped_area);
10331192
1193
+static void mtd_update_ecc_stats(struct mtd_info *mtd, struct mtd_info *master,
1194
+ const struct mtd_ecc_stats *old_stats)
1195
+{
1196
+ struct mtd_ecc_stats diff;
1197
+
1198
+ if (master == mtd)
1199
+ return;
1200
+
1201
+ diff = master->ecc_stats;
1202
+ diff.failed -= old_stats->failed;
1203
+ diff.corrected -= old_stats->corrected;
1204
+
1205
+ while (mtd->parent) {
1206
+ mtd->ecc_stats.failed += diff.failed;
1207
+ mtd->ecc_stats.corrected += diff.corrected;
1208
+ mtd = mtd->parent;
1209
+ }
1210
+}
1211
+
10341212 int mtd_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen,
10351213 u_char *buf)
10361214 {
1037
- int ret_code;
1038
- *retlen = 0;
1039
- if (from < 0 || from >= mtd->size || len > mtd->size - from)
1040
- return -EINVAL;
1041
- if (!len)
1042
- return 0;
1215
+ struct mtd_oob_ops ops = {
1216
+ .len = len,
1217
+ .datbuf = buf,
1218
+ };
1219
+ int ret;
10431220
1044
- ledtrig_mtd_activity();
1045
- /*
1046
- * In the absence of an error, drivers return a non-negative integer
1047
- * representing the maximum number of bitflips that were corrected on
1048
- * any one ecc region (if applicable; zero otherwise).
1049
- */
1050
- if (mtd->_read) {
1051
- ret_code = mtd->_read(mtd, from, len, retlen, buf);
1052
- } else if (mtd->_read_oob) {
1053
- struct mtd_oob_ops ops = {
1054
- .len = len,
1055
- .datbuf = buf,
1056
- };
1221
+ ret = mtd_read_oob(mtd, from, &ops);
1222
+ *retlen = ops.retlen;
10571223
1058
- ret_code = mtd->_read_oob(mtd, from, &ops);
1059
- *retlen = ops.retlen;
1060
- } else {
1061
- return -ENOTSUPP;
1062
- }
1063
-
1064
- if (unlikely(ret_code < 0))
1065
- return ret_code;
1066
- if (mtd->ecc_strength == 0)
1067
- return 0; /* device lacks ecc */
1068
- return ret_code >= mtd->bitflip_threshold ? -EUCLEAN : 0;
1224
+ return ret;
10691225 }
10701226 EXPORT_SYMBOL_GPL(mtd_read);
10711227
10721228 int mtd_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen,
10731229 const u_char *buf)
10741230 {
1075
- *retlen = 0;
1076
- if (to < 0 || to >= mtd->size || len > mtd->size - to)
1077
- return -EINVAL;
1078
- if ((!mtd->_write && !mtd->_write_oob) ||
1079
- !(mtd->flags & MTD_WRITEABLE))
1080
- return -EROFS;
1081
- if (!len)
1082
- return 0;
1083
- ledtrig_mtd_activity();
1231
+ struct mtd_oob_ops ops = {
1232
+ .len = len,
1233
+ .datbuf = (u8 *)buf,
1234
+ };
1235
+ int ret;
10841236
1085
- if (!mtd->_write) {
1086
- struct mtd_oob_ops ops = {
1087
- .len = len,
1088
- .datbuf = (u8 *)buf,
1089
- };
1090
- int ret;
1237
+ ret = mtd_write_oob(mtd, to, &ops);
1238
+ *retlen = ops.retlen;
10911239
1092
- ret = mtd->_write_oob(mtd, to, &ops);
1093
- *retlen = ops.retlen;
1094
- return ret;
1095
- }
1096
-
1097
- return mtd->_write(mtd, to, len, retlen, buf);
1240
+ return ret;
10981241 }
10991242 EXPORT_SYMBOL_GPL(mtd_write);
11001243
....@@ -1108,8 +1251,10 @@
11081251 int mtd_panic_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen,
11091252 const u_char *buf)
11101253 {
1254
+ struct mtd_info *master = mtd_get_master(mtd);
1255
+
11111256 *retlen = 0;
1112
- if (!mtd->_panic_write)
1257
+ if (!master->_panic_write)
11131258 return -EOPNOTSUPP;
11141259 if (to < 0 || to >= mtd->size || len > mtd->size - to)
11151260 return -EINVAL;
....@@ -1117,7 +1262,11 @@
11171262 return -EROFS;
11181263 if (!len)
11191264 return 0;
1120
- return mtd->_panic_write(mtd, to, len, retlen, buf);
1265
+ if (!master->oops_panic_write)
1266
+ master->oops_panic_write = true;
1267
+
1268
+ return master->_panic_write(master, mtd_get_master_ofs(mtd, to), len,
1269
+ retlen, buf);
11211270 }
11221271 EXPORT_SYMBOL_GPL(mtd_panic_write);
11231272
....@@ -1139,13 +1288,13 @@
11391288 return -EINVAL;
11401289
11411290 if (ops->ooblen) {
1142
- u64 maxooblen;
1291
+ size_t maxooblen;
11431292
11441293 if (ops->ooboffs >= mtd_oobavail(mtd, ops))
11451294 return -EINVAL;
11461295
1147
- maxooblen = ((mtd_div_by_ws(mtd->size, mtd) -
1148
- mtd_div_by_ws(offs, mtd)) *
1296
+ maxooblen = ((size_t)(mtd_div_by_ws(mtd->size, mtd) -
1297
+ mtd_div_by_ws(offs, mtd)) *
11491298 mtd_oobavail(mtd, ops)) - ops->ooboffs;
11501299 if (ops->ooblen > maxooblen)
11511300 return -EINVAL;
....@@ -1154,9 +1303,107 @@
11541303 return 0;
11551304 }
11561305
1306
+static int mtd_read_oob_std(struct mtd_info *mtd, loff_t from,
1307
+ struct mtd_oob_ops *ops)
1308
+{
1309
+ struct mtd_info *master = mtd_get_master(mtd);
1310
+ int ret;
1311
+
1312
+ from = mtd_get_master_ofs(mtd, from);
1313
+ if (master->_read_oob)
1314
+ ret = master->_read_oob(master, from, ops);
1315
+ else
1316
+ ret = master->_read(master, from, ops->len, &ops->retlen,
1317
+ ops->datbuf);
1318
+
1319
+ return ret;
1320
+}
1321
+
1322
+static int mtd_write_oob_std(struct mtd_info *mtd, loff_t to,
1323
+ struct mtd_oob_ops *ops)
1324
+{
1325
+ struct mtd_info *master = mtd_get_master(mtd);
1326
+ int ret;
1327
+
1328
+ to = mtd_get_master_ofs(mtd, to);
1329
+ if (master->_write_oob)
1330
+ ret = master->_write_oob(master, to, ops);
1331
+ else
1332
+ ret = master->_write(master, to, ops->len, &ops->retlen,
1333
+ ops->datbuf);
1334
+
1335
+ return ret;
1336
+}
1337
+
1338
+static int mtd_io_emulated_slc(struct mtd_info *mtd, loff_t start, bool read,
1339
+ struct mtd_oob_ops *ops)
1340
+{
1341
+ struct mtd_info *master = mtd_get_master(mtd);
1342
+ int ngroups = mtd_pairing_groups(master);
1343
+ int npairs = mtd_wunit_per_eb(master) / ngroups;
1344
+ struct mtd_oob_ops adjops = *ops;
1345
+ unsigned int wunit, oobavail;
1346
+ struct mtd_pairing_info info;
1347
+ int max_bitflips = 0;
1348
+ u32 ebofs, pageofs;
1349
+ loff_t base, pos;
1350
+
1351
+ ebofs = mtd_mod_by_eb(start, mtd);
1352
+ base = (loff_t)mtd_div_by_eb(start, mtd) * master->erasesize;
1353
+ info.group = 0;
1354
+ info.pair = mtd_div_by_ws(ebofs, mtd);
1355
+ pageofs = mtd_mod_by_ws(ebofs, mtd);
1356
+ oobavail = mtd_oobavail(mtd, ops);
1357
+
1358
+ while (ops->retlen < ops->len || ops->oobretlen < ops->ooblen) {
1359
+ int ret;
1360
+
1361
+ if (info.pair >= npairs) {
1362
+ info.pair = 0;
1363
+ base += master->erasesize;
1364
+ }
1365
+
1366
+ wunit = mtd_pairing_info_to_wunit(master, &info);
1367
+ pos = mtd_wunit_to_offset(mtd, base, wunit);
1368
+
1369
+ adjops.len = ops->len - ops->retlen;
1370
+ if (adjops.len > mtd->writesize - pageofs)
1371
+ adjops.len = mtd->writesize - pageofs;
1372
+
1373
+ adjops.ooblen = ops->ooblen - ops->oobretlen;
1374
+ if (adjops.ooblen > oobavail - adjops.ooboffs)
1375
+ adjops.ooblen = oobavail - adjops.ooboffs;
1376
+
1377
+ if (read) {
1378
+ ret = mtd_read_oob_std(mtd, pos + pageofs, &adjops);
1379
+ if (ret > 0)
1380
+ max_bitflips = max(max_bitflips, ret);
1381
+ } else {
1382
+ ret = mtd_write_oob_std(mtd, pos + pageofs, &adjops);
1383
+ }
1384
+
1385
+ if (ret < 0)
1386
+ return ret;
1387
+
1388
+ max_bitflips = max(max_bitflips, ret);
1389
+ ops->retlen += adjops.retlen;
1390
+ ops->oobretlen += adjops.oobretlen;
1391
+ adjops.datbuf += adjops.retlen;
1392
+ adjops.oobbuf += adjops.oobretlen;
1393
+ adjops.ooboffs = 0;
1394
+ pageofs = 0;
1395
+ info.pair++;
1396
+ }
1397
+
1398
+ return max_bitflips;
1399
+}
1400
+
11571401 int mtd_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops)
11581402 {
1403
+ struct mtd_info *master = mtd_get_master(mtd);
1404
+ struct mtd_ecc_stats old_stats = master->ecc_stats;
11591405 int ret_code;
1406
+
11601407 ops->retlen = ops->oobretlen = 0;
11611408
11621409 ret_code = mtd_check_oob_ops(mtd, from, ops);
....@@ -1166,14 +1413,15 @@
11661413 ledtrig_mtd_activity();
11671414
11681415 /* Check the validity of a potential fallback on mtd->_read */
1169
- if (!mtd->_read_oob && (!mtd->_read || ops->oobbuf))
1416
+ if (!master->_read_oob && (!master->_read || ops->oobbuf))
11701417 return -EOPNOTSUPP;
11711418
1172
- if (mtd->_read_oob)
1173
- ret_code = mtd->_read_oob(mtd, from, ops);
1419
+ if (mtd->flags & MTD_SLC_ON_MLC_EMULATION)
1420
+ ret_code = mtd_io_emulated_slc(mtd, from, true, ops);
11741421 else
1175
- ret_code = mtd->_read(mtd, from, ops->len, &ops->retlen,
1176
- ops->datbuf);
1422
+ ret_code = mtd_read_oob_std(mtd, from, ops);
1423
+
1424
+ mtd_update_ecc_stats(mtd, master, &old_stats);
11771425
11781426 /*
11791427 * In cases where ops->datbuf != NULL, mtd->_read_oob() has semantics
....@@ -1192,6 +1440,7 @@
11921440 int mtd_write_oob(struct mtd_info *mtd, loff_t to,
11931441 struct mtd_oob_ops *ops)
11941442 {
1443
+ struct mtd_info *master = mtd_get_master(mtd);
11951444 int ret;
11961445
11971446 ops->retlen = ops->oobretlen = 0;
....@@ -1206,14 +1455,13 @@
12061455 ledtrig_mtd_activity();
12071456
12081457 /* Check the validity of a potential fallback on mtd->_write */
1209
- if (!mtd->_write_oob && (!mtd->_write || ops->oobbuf))
1458
+ if (!master->_write_oob && (!master->_write || ops->oobbuf))
12101459 return -EOPNOTSUPP;
12111460
1212
- if (mtd->_write_oob)
1213
- return mtd->_write_oob(mtd, to, ops);
1214
- else
1215
- return mtd->_write(mtd, to, ops->len, &ops->retlen,
1216
- ops->datbuf);
1461
+ if (mtd->flags & MTD_SLC_ON_MLC_EMULATION)
1462
+ return mtd_io_emulated_slc(mtd, to, false, ops);
1463
+
1464
+ return mtd_write_oob_std(mtd, to, ops);
12171465 }
12181466 EXPORT_SYMBOL_GPL(mtd_write_oob);
12191467
....@@ -1236,15 +1484,17 @@
12361484 int mtd_ooblayout_ecc(struct mtd_info *mtd, int section,
12371485 struct mtd_oob_region *oobecc)
12381486 {
1487
+ struct mtd_info *master = mtd_get_master(mtd);
1488
+
12391489 memset(oobecc, 0, sizeof(*oobecc));
12401490
1241
- if (!mtd || section < 0)
1491
+ if (!master || section < 0)
12421492 return -EINVAL;
12431493
1244
- if (!mtd->ooblayout || !mtd->ooblayout->ecc)
1494
+ if (!master->ooblayout || !master->ooblayout->ecc)
12451495 return -ENOTSUPP;
12461496
1247
- return mtd->ooblayout->ecc(mtd, section, oobecc);
1497
+ return master->ooblayout->ecc(master, section, oobecc);
12481498 }
12491499 EXPORT_SYMBOL_GPL(mtd_ooblayout_ecc);
12501500
....@@ -1268,15 +1518,17 @@
12681518 int mtd_ooblayout_free(struct mtd_info *mtd, int section,
12691519 struct mtd_oob_region *oobfree)
12701520 {
1521
+ struct mtd_info *master = mtd_get_master(mtd);
1522
+
12711523 memset(oobfree, 0, sizeof(*oobfree));
12721524
1273
- if (!mtd || section < 0)
1525
+ if (!master || section < 0)
12741526 return -EINVAL;
12751527
1276
- if (!mtd->ooblayout || !mtd->ooblayout->free)
1528
+ if (!master->ooblayout || !master->ooblayout->free)
12771529 return -ENOTSUPP;
12781530
1279
- return mtd->ooblayout->free(mtd, section, oobfree);
1531
+ return master->ooblayout->free(master, section, oobfree);
12801532 }
12811533 EXPORT_SYMBOL_GPL(mtd_ooblayout_free);
12821534
....@@ -1537,7 +1789,7 @@
15371789 * @start: first ECC byte to set
15381790 * @nbytes: number of ECC bytes to set
15391791 *
1540
- * Works like mtd_ooblayout_get_bytes(), except it acts on free bytes.
1792
+ * Works like mtd_ooblayout_set_bytes(), except it acts on free bytes.
15411793 *
15421794 * Returns zero on success, a negative error code otherwise.
15431795 */
....@@ -1585,60 +1837,69 @@
15851837 int mtd_get_fact_prot_info(struct mtd_info *mtd, size_t len, size_t *retlen,
15861838 struct otp_info *buf)
15871839 {
1588
- if (!mtd->_get_fact_prot_info)
1840
+ struct mtd_info *master = mtd_get_master(mtd);
1841
+
1842
+ if (!master->_get_fact_prot_info)
15891843 return -EOPNOTSUPP;
15901844 if (!len)
15911845 return 0;
1592
- return mtd->_get_fact_prot_info(mtd, len, retlen, buf);
1846
+ return master->_get_fact_prot_info(master, len, retlen, buf);
15931847 }
15941848 EXPORT_SYMBOL_GPL(mtd_get_fact_prot_info);
15951849
15961850 int mtd_read_fact_prot_reg(struct mtd_info *mtd, loff_t from, size_t len,
15971851 size_t *retlen, u_char *buf)
15981852 {
1853
+ struct mtd_info *master = mtd_get_master(mtd);
1854
+
15991855 *retlen = 0;
1600
- if (!mtd->_read_fact_prot_reg)
1856
+ if (!master->_read_fact_prot_reg)
16011857 return -EOPNOTSUPP;
16021858 if (!len)
16031859 return 0;
1604
- return mtd->_read_fact_prot_reg(mtd, from, len, retlen, buf);
1860
+ return master->_read_fact_prot_reg(master, from, len, retlen, buf);
16051861 }
16061862 EXPORT_SYMBOL_GPL(mtd_read_fact_prot_reg);
16071863
16081864 int mtd_get_user_prot_info(struct mtd_info *mtd, size_t len, size_t *retlen,
16091865 struct otp_info *buf)
16101866 {
1611
- if (!mtd->_get_user_prot_info)
1867
+ struct mtd_info *master = mtd_get_master(mtd);
1868
+
1869
+ if (!master->_get_user_prot_info)
16121870 return -EOPNOTSUPP;
16131871 if (!len)
16141872 return 0;
1615
- return mtd->_get_user_prot_info(mtd, len, retlen, buf);
1873
+ return master->_get_user_prot_info(master, len, retlen, buf);
16161874 }
16171875 EXPORT_SYMBOL_GPL(mtd_get_user_prot_info);
16181876
16191877 int mtd_read_user_prot_reg(struct mtd_info *mtd, loff_t from, size_t len,
16201878 size_t *retlen, u_char *buf)
16211879 {
1880
+ struct mtd_info *master = mtd_get_master(mtd);
1881
+
16221882 *retlen = 0;
1623
- if (!mtd->_read_user_prot_reg)
1883
+ if (!master->_read_user_prot_reg)
16241884 return -EOPNOTSUPP;
16251885 if (!len)
16261886 return 0;
1627
- return mtd->_read_user_prot_reg(mtd, from, len, retlen, buf);
1887
+ return master->_read_user_prot_reg(master, from, len, retlen, buf);
16281888 }
16291889 EXPORT_SYMBOL_GPL(mtd_read_user_prot_reg);
16301890
16311891 int mtd_write_user_prot_reg(struct mtd_info *mtd, loff_t to, size_t len,
16321892 size_t *retlen, u_char *buf)
16331893 {
1894
+ struct mtd_info *master = mtd_get_master(mtd);
16341895 int ret;
16351896
16361897 *retlen = 0;
1637
- if (!mtd->_write_user_prot_reg)
1898
+ if (!master->_write_user_prot_reg)
16381899 return -EOPNOTSUPP;
16391900 if (!len)
16401901 return 0;
1641
- ret = mtd->_write_user_prot_reg(mtd, to, len, retlen, buf);
1902
+ ret = master->_write_user_prot_reg(master, to, len, retlen, buf);
16421903 if (ret)
16431904 return ret;
16441905
....@@ -1652,80 +1913,134 @@
16521913
16531914 int mtd_lock_user_prot_reg(struct mtd_info *mtd, loff_t from, size_t len)
16541915 {
1655
- if (!mtd->_lock_user_prot_reg)
1916
+ struct mtd_info *master = mtd_get_master(mtd);
1917
+
1918
+ if (!master->_lock_user_prot_reg)
16561919 return -EOPNOTSUPP;
16571920 if (!len)
16581921 return 0;
1659
- return mtd->_lock_user_prot_reg(mtd, from, len);
1922
+ return master->_lock_user_prot_reg(master, from, len);
16601923 }
16611924 EXPORT_SYMBOL_GPL(mtd_lock_user_prot_reg);
16621925
16631926 /* Chip-supported device locking */
16641927 int mtd_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
16651928 {
1666
- if (!mtd->_lock)
1929
+ struct mtd_info *master = mtd_get_master(mtd);
1930
+
1931
+ if (!master->_lock)
16671932 return -EOPNOTSUPP;
16681933 if (ofs < 0 || ofs >= mtd->size || len > mtd->size - ofs)
16691934 return -EINVAL;
16701935 if (!len)
16711936 return 0;
1672
- return mtd->_lock(mtd, ofs, len);
1937
+
1938
+ if (mtd->flags & MTD_SLC_ON_MLC_EMULATION) {
1939
+ ofs = (loff_t)mtd_div_by_eb(ofs, mtd) * master->erasesize;
1940
+ len = (u64)mtd_div_by_eb(len, mtd) * master->erasesize;
1941
+ }
1942
+
1943
+ return master->_lock(master, mtd_get_master_ofs(mtd, ofs), len);
16731944 }
16741945 EXPORT_SYMBOL_GPL(mtd_lock);
16751946
16761947 int mtd_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
16771948 {
1678
- if (!mtd->_unlock)
1949
+ struct mtd_info *master = mtd_get_master(mtd);
1950
+
1951
+ if (!master->_unlock)
16791952 return -EOPNOTSUPP;
16801953 if (ofs < 0 || ofs >= mtd->size || len > mtd->size - ofs)
16811954 return -EINVAL;
16821955 if (!len)
16831956 return 0;
1684
- return mtd->_unlock(mtd, ofs, len);
1957
+
1958
+ if (mtd->flags & MTD_SLC_ON_MLC_EMULATION) {
1959
+ ofs = (loff_t)mtd_div_by_eb(ofs, mtd) * master->erasesize;
1960
+ len = (u64)mtd_div_by_eb(len, mtd) * master->erasesize;
1961
+ }
1962
+
1963
+ return master->_unlock(master, mtd_get_master_ofs(mtd, ofs), len);
16851964 }
16861965 EXPORT_SYMBOL_GPL(mtd_unlock);
16871966
16881967 int mtd_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len)
16891968 {
1690
- if (!mtd->_is_locked)
1969
+ struct mtd_info *master = mtd_get_master(mtd);
1970
+
1971
+ if (!master->_is_locked)
16911972 return -EOPNOTSUPP;
16921973 if (ofs < 0 || ofs >= mtd->size || len > mtd->size - ofs)
16931974 return -EINVAL;
16941975 if (!len)
16951976 return 0;
1696
- return mtd->_is_locked(mtd, ofs, len);
1977
+
1978
+ if (mtd->flags & MTD_SLC_ON_MLC_EMULATION) {
1979
+ ofs = (loff_t)mtd_div_by_eb(ofs, mtd) * master->erasesize;
1980
+ len = (u64)mtd_div_by_eb(len, mtd) * master->erasesize;
1981
+ }
1982
+
1983
+ return master->_is_locked(master, mtd_get_master_ofs(mtd, ofs), len);
16971984 }
16981985 EXPORT_SYMBOL_GPL(mtd_is_locked);
16991986
17001987 int mtd_block_isreserved(struct mtd_info *mtd, loff_t ofs)
17011988 {
1989
+ struct mtd_info *master = mtd_get_master(mtd);
1990
+
17021991 if (ofs < 0 || ofs >= mtd->size)
17031992 return -EINVAL;
1704
- if (!mtd->_block_isreserved)
1993
+ if (!master->_block_isreserved)
17051994 return 0;
1706
- return mtd->_block_isreserved(mtd, ofs);
1995
+
1996
+ if (mtd->flags & MTD_SLC_ON_MLC_EMULATION)
1997
+ ofs = (loff_t)mtd_div_by_eb(ofs, mtd) * master->erasesize;
1998
+
1999
+ return master->_block_isreserved(master, mtd_get_master_ofs(mtd, ofs));
17072000 }
17082001 EXPORT_SYMBOL_GPL(mtd_block_isreserved);
17092002
17102003 int mtd_block_isbad(struct mtd_info *mtd, loff_t ofs)
17112004 {
2005
+ struct mtd_info *master = mtd_get_master(mtd);
2006
+
17122007 if (ofs < 0 || ofs >= mtd->size)
17132008 return -EINVAL;
1714
- if (!mtd->_block_isbad)
2009
+ if (!master->_block_isbad)
17152010 return 0;
1716
- return mtd->_block_isbad(mtd, ofs);
2011
+
2012
+ if (mtd->flags & MTD_SLC_ON_MLC_EMULATION)
2013
+ ofs = (loff_t)mtd_div_by_eb(ofs, mtd) * master->erasesize;
2014
+
2015
+ return master->_block_isbad(master, mtd_get_master_ofs(mtd, ofs));
17172016 }
17182017 EXPORT_SYMBOL_GPL(mtd_block_isbad);
17192018
17202019 int mtd_block_markbad(struct mtd_info *mtd, loff_t ofs)
17212020 {
1722
- if (!mtd->_block_markbad)
2021
+ struct mtd_info *master = mtd_get_master(mtd);
2022
+ int ret;
2023
+
2024
+ if (!master->_block_markbad)
17232025 return -EOPNOTSUPP;
17242026 if (ofs < 0 || ofs >= mtd->size)
17252027 return -EINVAL;
17262028 if (!(mtd->flags & MTD_WRITEABLE))
17272029 return -EROFS;
1728
- return mtd->_block_markbad(mtd, ofs);
2030
+
2031
+ if (mtd->flags & MTD_SLC_ON_MLC_EMULATION)
2032
+ ofs = (loff_t)mtd_div_by_eb(ofs, mtd) * master->erasesize;
2033
+
2034
+ ret = master->_block_markbad(master, mtd_get_master_ofs(mtd, ofs));
2035
+ if (ret)
2036
+ return ret;
2037
+
2038
+ while (mtd->parent) {
2039
+ mtd->ecc_stats.badblocks++;
2040
+ mtd = mtd->parent;
2041
+ }
2042
+
2043
+ return 0;
17292044 }
17302045 EXPORT_SYMBOL_GPL(mtd_block_markbad);
17312046
....@@ -1775,12 +2090,17 @@
17752090 int mtd_writev(struct mtd_info *mtd, const struct kvec *vecs,
17762091 unsigned long count, loff_t to, size_t *retlen)
17772092 {
2093
+ struct mtd_info *master = mtd_get_master(mtd);
2094
+
17782095 *retlen = 0;
17792096 if (!(mtd->flags & MTD_WRITEABLE))
17802097 return -EROFS;
1781
- if (!mtd->_writev)
2098
+
2099
+ if (!master->_writev)
17822100 return default_mtd_writev(mtd, vecs, count, to, retlen);
1783
- return mtd->_writev(mtd, vecs, count, to, retlen);
2101
+
2102
+ return master->_writev(master, vecs, count,
2103
+ mtd_get_master_ofs(mtd, to), retlen);
17842104 }
17852105 EXPORT_SYMBOL_GPL(mtd_writev);
17862106
....@@ -1862,11 +2182,12 @@
18622182 struct backing_dev_info *bdi;
18632183 int ret;
18642184
1865
- bdi = bdi_alloc(GFP_KERNEL);
2185
+ bdi = bdi_alloc(NUMA_NO_NODE);
18662186 if (!bdi)
18672187 return ERR_PTR(-ENOMEM);
2188
+ bdi->ra_pages = 0;
2189
+ bdi->io_pages = 0;
18682190
1869
- bdi->name = name;
18702191 /*
18712192 * We put '-0' suffix to the name to get the same name format as we
18722193 * used to get. Since this is called only once, we get a unique name.