hc
2023-12-11 6778948f9de86c3cfaf36725a7c87dcff9ba247f
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;
....@@ -570,13 +670,12 @@
570670 if (error)
571671 goto fail_added;
572672
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
- }
579
- }
673
+ /* Add the nvmem provider */
674
+ error = mtd_nvmem_add(mtd);
675
+ if (error)
676
+ goto fail_nvmem_add;
677
+
678
+ mtd_debugfs_populate(mtd);
580679
581680 device_create(&mtd_class, mtd->dev.parent, MTD_DEVT(i) + 1, NULL,
582681 "mtd%dro", i);
....@@ -595,6 +694,8 @@
595694 __module_get(THIS_MODULE);
596695 return 0;
597696
697
+fail_nvmem_add:
698
+ device_unregister(&mtd->dev);
598699 fail_added:
599700 of_node_put(mtd_get_of_node(mtd));
600701 idr_remove(&mtd_idr, i);
....@@ -620,8 +721,6 @@
620721
621722 mutex_lock(&mtd_table_mutex);
622723
623
- debugfs_remove_recursive(mtd->dbg.dfs_dir);
624
-
625724 if (idr_find(&mtd_idr, mtd->index) != mtd) {
626725 ret = -ENODEV;
627726 goto out_error;
....@@ -637,6 +736,12 @@
637736 mtd->index, mtd->name, mtd->usecount);
638737 ret = -EBUSY;
639738 } else {
739
+ debugfs_remove_recursive(mtd->dbg.dfs_dir);
740
+
741
+ /* Try to remove the NVMEM provider */
742
+ if (mtd->nvmem)
743
+ nvmem_unregister(mtd->nvmem);
744
+
640745 device_unregister(&mtd->dev);
641746
642747 idr_remove(&mtd_idr, mtd->index);
....@@ -665,6 +770,9 @@
665770 } else {
666771 pr_debug("mtd device won't show a device symlink in sysfs\n");
667772 }
773
+
774
+ INIT_LIST_HEAD(&mtd->partitions);
775
+ mutex_init(&mtd->master.partitions_lock);
668776 }
669777
670778 /**
....@@ -873,20 +981,28 @@
873981
874982 int __get_mtd_device(struct mtd_info *mtd)
875983 {
984
+ struct mtd_info *master = mtd_get_master(mtd);
876985 int err;
877986
878
- if (!try_module_get(mtd->owner))
987
+ if (!try_module_get(master->owner))
879988 return -ENODEV;
880989
881
- if (mtd->_get_device) {
882
- err = mtd->_get_device(mtd);
990
+ if (master->_get_device) {
991
+ err = master->_get_device(mtd);
883992
884993 if (err) {
885
- module_put(mtd->owner);
994
+ module_put(master->owner);
886995 return err;
887996 }
888997 }
889
- mtd->usecount++;
998
+
999
+ master->usecount++;
1000
+
1001
+ while (mtd->parent) {
1002
+ mtd->usecount++;
1003
+ mtd = mtd->parent;
1004
+ }
1005
+
8901006 return 0;
8911007 }
8921008 EXPORT_SYMBOL_GPL(__get_mtd_device);
....@@ -940,13 +1056,20 @@
9401056
9411057 void __put_mtd_device(struct mtd_info *mtd)
9421058 {
943
- --mtd->usecount;
944
- BUG_ON(mtd->usecount < 0);
1059
+ struct mtd_info *master = mtd_get_master(mtd);
9451060
946
- if (mtd->_put_device)
947
- mtd->_put_device(mtd);
1061
+ while (mtd->parent) {
1062
+ --mtd->usecount;
1063
+ BUG_ON(mtd->usecount < 0);
1064
+ mtd = mtd->parent;
1065
+ }
9481066
949
- module_put(mtd->owner);
1067
+ master->usecount--;
1068
+
1069
+ if (master->_put_device)
1070
+ master->_put_device(master);
1071
+
1072
+ module_put(master->owner);
9501073 }
9511074 EXPORT_SYMBOL_GPL(__put_mtd_device);
9521075
....@@ -957,9 +1080,15 @@
9571080 */
9581081 int mtd_erase(struct mtd_info *mtd, struct erase_info *instr)
9591082 {
960
- instr->fail_addr = MTD_FAIL_ADDR_UNKNOWN;
1083
+ struct mtd_info *master = mtd_get_master(mtd);
1084
+ u64 mst_ofs = mtd_get_master_ofs(mtd, 0);
1085
+ struct erase_info adjinstr;
1086
+ int ret;
9611087
962
- if (!mtd->erasesize || !mtd->_erase)
1088
+ instr->fail_addr = MTD_FAIL_ADDR_UNKNOWN;
1089
+ adjinstr = *instr;
1090
+
1091
+ if (!mtd->erasesize || !master->_erase)
9631092 return -ENOTSUPP;
9641093
9651094 if (instr->addr >= mtd->size || instr->len > mtd->size - instr->addr)
....@@ -971,7 +1100,29 @@
9711100 return 0;
9721101
9731102 ledtrig_mtd_activity();
974
- return mtd->_erase(mtd, instr);
1103
+
1104
+ if (mtd->flags & MTD_SLC_ON_MLC_EMULATION) {
1105
+ adjinstr.addr = (loff_t)mtd_div_by_eb(instr->addr, mtd) *
1106
+ master->erasesize;
1107
+ adjinstr.len = ((u64)mtd_div_by_eb(instr->addr + instr->len, mtd) *
1108
+ master->erasesize) -
1109
+ adjinstr.addr;
1110
+ }
1111
+
1112
+ adjinstr.addr += mst_ofs;
1113
+
1114
+ ret = master->_erase(master, &adjinstr);
1115
+
1116
+ if (adjinstr.fail_addr != MTD_FAIL_ADDR_UNKNOWN) {
1117
+ instr->fail_addr = adjinstr.fail_addr - mst_ofs;
1118
+ if (mtd->flags & MTD_SLC_ON_MLC_EMULATION) {
1119
+ instr->fail_addr = mtd_div_by_eb(instr->fail_addr,
1120
+ master);
1121
+ instr->fail_addr *= mtd->erasesize;
1122
+ }
1123
+ }
1124
+
1125
+ return ret;
9751126 }
9761127 EXPORT_SYMBOL_GPL(mtd_erase);
9771128
....@@ -981,30 +1132,36 @@
9811132 int mtd_point(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen,
9821133 void **virt, resource_size_t *phys)
9831134 {
1135
+ struct mtd_info *master = mtd_get_master(mtd);
1136
+
9841137 *retlen = 0;
9851138 *virt = NULL;
9861139 if (phys)
9871140 *phys = 0;
988
- if (!mtd->_point)
1141
+ if (!master->_point)
9891142 return -EOPNOTSUPP;
9901143 if (from < 0 || from >= mtd->size || len > mtd->size - from)
9911144 return -EINVAL;
9921145 if (!len)
9931146 return 0;
994
- return mtd->_point(mtd, from, len, retlen, virt, phys);
1147
+
1148
+ from = mtd_get_master_ofs(mtd, from);
1149
+ return master->_point(master, from, len, retlen, virt, phys);
9951150 }
9961151 EXPORT_SYMBOL_GPL(mtd_point);
9971152
9981153 /* We probably shouldn't allow XIP if the unpoint isn't a NULL */
9991154 int mtd_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
10001155 {
1001
- if (!mtd->_unpoint)
1156
+ struct mtd_info *master = mtd_get_master(mtd);
1157
+
1158
+ if (!master->_unpoint)
10021159 return -EOPNOTSUPP;
10031160 if (from < 0 || from >= mtd->size || len > mtd->size - from)
10041161 return -EINVAL;
10051162 if (!len)
10061163 return 0;
1007
- return mtd->_unpoint(mtd, from, len);
1164
+ return master->_unpoint(master, mtd_get_master_ofs(mtd, from), len);
10081165 }
10091166 EXPORT_SYMBOL_GPL(mtd_unpoint);
10101167
....@@ -1031,70 +1188,54 @@
10311188 }
10321189 EXPORT_SYMBOL_GPL(mtd_get_unmapped_area);
10331190
1191
+static void mtd_update_ecc_stats(struct mtd_info *mtd, struct mtd_info *master,
1192
+ const struct mtd_ecc_stats *old_stats)
1193
+{
1194
+ struct mtd_ecc_stats diff;
1195
+
1196
+ if (master == mtd)
1197
+ return;
1198
+
1199
+ diff = master->ecc_stats;
1200
+ diff.failed -= old_stats->failed;
1201
+ diff.corrected -= old_stats->corrected;
1202
+
1203
+ while (mtd->parent) {
1204
+ mtd->ecc_stats.failed += diff.failed;
1205
+ mtd->ecc_stats.corrected += diff.corrected;
1206
+ mtd = mtd->parent;
1207
+ }
1208
+}
1209
+
10341210 int mtd_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen,
10351211 u_char *buf)
10361212 {
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;
1213
+ struct mtd_oob_ops ops = {
1214
+ .len = len,
1215
+ .datbuf = buf,
1216
+ };
1217
+ int ret;
10431218
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
- };
1219
+ ret = mtd_read_oob(mtd, from, &ops);
1220
+ *retlen = ops.retlen;
10571221
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;
1222
+ return ret;
10691223 }
10701224 EXPORT_SYMBOL_GPL(mtd_read);
10711225
10721226 int mtd_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen,
10731227 const u_char *buf)
10741228 {
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();
1229
+ struct mtd_oob_ops ops = {
1230
+ .len = len,
1231
+ .datbuf = (u8 *)buf,
1232
+ };
1233
+ int ret;
10841234
1085
- if (!mtd->_write) {
1086
- struct mtd_oob_ops ops = {
1087
- .len = len,
1088
- .datbuf = (u8 *)buf,
1089
- };
1090
- int ret;
1235
+ ret = mtd_write_oob(mtd, to, &ops);
1236
+ *retlen = ops.retlen;
10911237
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);
1238
+ return ret;
10981239 }
10991240 EXPORT_SYMBOL_GPL(mtd_write);
11001241
....@@ -1108,8 +1249,10 @@
11081249 int mtd_panic_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen,
11091250 const u_char *buf)
11101251 {
1252
+ struct mtd_info *master = mtd_get_master(mtd);
1253
+
11111254 *retlen = 0;
1112
- if (!mtd->_panic_write)
1255
+ if (!master->_panic_write)
11131256 return -EOPNOTSUPP;
11141257 if (to < 0 || to >= mtd->size || len > mtd->size - to)
11151258 return -EINVAL;
....@@ -1117,7 +1260,11 @@
11171260 return -EROFS;
11181261 if (!len)
11191262 return 0;
1120
- return mtd->_panic_write(mtd, to, len, retlen, buf);
1263
+ if (!master->oops_panic_write)
1264
+ master->oops_panic_write = true;
1265
+
1266
+ return master->_panic_write(master, mtd_get_master_ofs(mtd, to), len,
1267
+ retlen, buf);
11211268 }
11221269 EXPORT_SYMBOL_GPL(mtd_panic_write);
11231270
....@@ -1139,13 +1286,13 @@
11391286 return -EINVAL;
11401287
11411288 if (ops->ooblen) {
1142
- u64 maxooblen;
1289
+ size_t maxooblen;
11431290
11441291 if (ops->ooboffs >= mtd_oobavail(mtd, ops))
11451292 return -EINVAL;
11461293
1147
- maxooblen = ((mtd_div_by_ws(mtd->size, mtd) -
1148
- mtd_div_by_ws(offs, mtd)) *
1294
+ maxooblen = ((size_t)(mtd_div_by_ws(mtd->size, mtd) -
1295
+ mtd_div_by_ws(offs, mtd)) *
11491296 mtd_oobavail(mtd, ops)) - ops->ooboffs;
11501297 if (ops->ooblen > maxooblen)
11511298 return -EINVAL;
....@@ -1154,9 +1301,107 @@
11541301 return 0;
11551302 }
11561303
1304
+static int mtd_read_oob_std(struct mtd_info *mtd, loff_t from,
1305
+ struct mtd_oob_ops *ops)
1306
+{
1307
+ struct mtd_info *master = mtd_get_master(mtd);
1308
+ int ret;
1309
+
1310
+ from = mtd_get_master_ofs(mtd, from);
1311
+ if (master->_read_oob)
1312
+ ret = master->_read_oob(master, from, ops);
1313
+ else
1314
+ ret = master->_read(master, from, ops->len, &ops->retlen,
1315
+ ops->datbuf);
1316
+
1317
+ return ret;
1318
+}
1319
+
1320
+static int mtd_write_oob_std(struct mtd_info *mtd, loff_t to,
1321
+ struct mtd_oob_ops *ops)
1322
+{
1323
+ struct mtd_info *master = mtd_get_master(mtd);
1324
+ int ret;
1325
+
1326
+ to = mtd_get_master_ofs(mtd, to);
1327
+ if (master->_write_oob)
1328
+ ret = master->_write_oob(master, to, ops);
1329
+ else
1330
+ ret = master->_write(master, to, ops->len, &ops->retlen,
1331
+ ops->datbuf);
1332
+
1333
+ return ret;
1334
+}
1335
+
1336
+static int mtd_io_emulated_slc(struct mtd_info *mtd, loff_t start, bool read,
1337
+ struct mtd_oob_ops *ops)
1338
+{
1339
+ struct mtd_info *master = mtd_get_master(mtd);
1340
+ int ngroups = mtd_pairing_groups(master);
1341
+ int npairs = mtd_wunit_per_eb(master) / ngroups;
1342
+ struct mtd_oob_ops adjops = *ops;
1343
+ unsigned int wunit, oobavail;
1344
+ struct mtd_pairing_info info;
1345
+ int max_bitflips = 0;
1346
+ u32 ebofs, pageofs;
1347
+ loff_t base, pos;
1348
+
1349
+ ebofs = mtd_mod_by_eb(start, mtd);
1350
+ base = (loff_t)mtd_div_by_eb(start, mtd) * master->erasesize;
1351
+ info.group = 0;
1352
+ info.pair = mtd_div_by_ws(ebofs, mtd);
1353
+ pageofs = mtd_mod_by_ws(ebofs, mtd);
1354
+ oobavail = mtd_oobavail(mtd, ops);
1355
+
1356
+ while (ops->retlen < ops->len || ops->oobretlen < ops->ooblen) {
1357
+ int ret;
1358
+
1359
+ if (info.pair >= npairs) {
1360
+ info.pair = 0;
1361
+ base += master->erasesize;
1362
+ }
1363
+
1364
+ wunit = mtd_pairing_info_to_wunit(master, &info);
1365
+ pos = mtd_wunit_to_offset(mtd, base, wunit);
1366
+
1367
+ adjops.len = ops->len - ops->retlen;
1368
+ if (adjops.len > mtd->writesize - pageofs)
1369
+ adjops.len = mtd->writesize - pageofs;
1370
+
1371
+ adjops.ooblen = ops->ooblen - ops->oobretlen;
1372
+ if (adjops.ooblen > oobavail - adjops.ooboffs)
1373
+ adjops.ooblen = oobavail - adjops.ooboffs;
1374
+
1375
+ if (read) {
1376
+ ret = mtd_read_oob_std(mtd, pos + pageofs, &adjops);
1377
+ if (ret > 0)
1378
+ max_bitflips = max(max_bitflips, ret);
1379
+ } else {
1380
+ ret = mtd_write_oob_std(mtd, pos + pageofs, &adjops);
1381
+ }
1382
+
1383
+ if (ret < 0)
1384
+ return ret;
1385
+
1386
+ max_bitflips = max(max_bitflips, ret);
1387
+ ops->retlen += adjops.retlen;
1388
+ ops->oobretlen += adjops.oobretlen;
1389
+ adjops.datbuf += adjops.retlen;
1390
+ adjops.oobbuf += adjops.oobretlen;
1391
+ adjops.ooboffs = 0;
1392
+ pageofs = 0;
1393
+ info.pair++;
1394
+ }
1395
+
1396
+ return max_bitflips;
1397
+}
1398
+
11571399 int mtd_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops)
11581400 {
1401
+ struct mtd_info *master = mtd_get_master(mtd);
1402
+ struct mtd_ecc_stats old_stats = master->ecc_stats;
11591403 int ret_code;
1404
+
11601405 ops->retlen = ops->oobretlen = 0;
11611406
11621407 ret_code = mtd_check_oob_ops(mtd, from, ops);
....@@ -1166,14 +1411,15 @@
11661411 ledtrig_mtd_activity();
11671412
11681413 /* Check the validity of a potential fallback on mtd->_read */
1169
- if (!mtd->_read_oob && (!mtd->_read || ops->oobbuf))
1414
+ if (!master->_read_oob && (!master->_read || ops->oobbuf))
11701415 return -EOPNOTSUPP;
11711416
1172
- if (mtd->_read_oob)
1173
- ret_code = mtd->_read_oob(mtd, from, ops);
1417
+ if (mtd->flags & MTD_SLC_ON_MLC_EMULATION)
1418
+ ret_code = mtd_io_emulated_slc(mtd, from, true, ops);
11741419 else
1175
- ret_code = mtd->_read(mtd, from, ops->len, &ops->retlen,
1176
- ops->datbuf);
1420
+ ret_code = mtd_read_oob_std(mtd, from, ops);
1421
+
1422
+ mtd_update_ecc_stats(mtd, master, &old_stats);
11771423
11781424 /*
11791425 * In cases where ops->datbuf != NULL, mtd->_read_oob() has semantics
....@@ -1192,6 +1438,7 @@
11921438 int mtd_write_oob(struct mtd_info *mtd, loff_t to,
11931439 struct mtd_oob_ops *ops)
11941440 {
1441
+ struct mtd_info *master = mtd_get_master(mtd);
11951442 int ret;
11961443
11971444 ops->retlen = ops->oobretlen = 0;
....@@ -1206,14 +1453,13 @@
12061453 ledtrig_mtd_activity();
12071454
12081455 /* Check the validity of a potential fallback on mtd->_write */
1209
- if (!mtd->_write_oob && (!mtd->_write || ops->oobbuf))
1456
+ if (!master->_write_oob && (!master->_write || ops->oobbuf))
12101457 return -EOPNOTSUPP;
12111458
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);
1459
+ if (mtd->flags & MTD_SLC_ON_MLC_EMULATION)
1460
+ return mtd_io_emulated_slc(mtd, to, false, ops);
1461
+
1462
+ return mtd_write_oob_std(mtd, to, ops);
12171463 }
12181464 EXPORT_SYMBOL_GPL(mtd_write_oob);
12191465
....@@ -1236,15 +1482,17 @@
12361482 int mtd_ooblayout_ecc(struct mtd_info *mtd, int section,
12371483 struct mtd_oob_region *oobecc)
12381484 {
1485
+ struct mtd_info *master = mtd_get_master(mtd);
1486
+
12391487 memset(oobecc, 0, sizeof(*oobecc));
12401488
1241
- if (!mtd || section < 0)
1489
+ if (!master || section < 0)
12421490 return -EINVAL;
12431491
1244
- if (!mtd->ooblayout || !mtd->ooblayout->ecc)
1492
+ if (!master->ooblayout || !master->ooblayout->ecc)
12451493 return -ENOTSUPP;
12461494
1247
- return mtd->ooblayout->ecc(mtd, section, oobecc);
1495
+ return master->ooblayout->ecc(master, section, oobecc);
12481496 }
12491497 EXPORT_SYMBOL_GPL(mtd_ooblayout_ecc);
12501498
....@@ -1268,15 +1516,17 @@
12681516 int mtd_ooblayout_free(struct mtd_info *mtd, int section,
12691517 struct mtd_oob_region *oobfree)
12701518 {
1519
+ struct mtd_info *master = mtd_get_master(mtd);
1520
+
12711521 memset(oobfree, 0, sizeof(*oobfree));
12721522
1273
- if (!mtd || section < 0)
1523
+ if (!master || section < 0)
12741524 return -EINVAL;
12751525
1276
- if (!mtd->ooblayout || !mtd->ooblayout->free)
1526
+ if (!master->ooblayout || !master->ooblayout->free)
12771527 return -ENOTSUPP;
12781528
1279
- return mtd->ooblayout->free(mtd, section, oobfree);
1529
+ return master->ooblayout->free(master, section, oobfree);
12801530 }
12811531 EXPORT_SYMBOL_GPL(mtd_ooblayout_free);
12821532
....@@ -1537,7 +1787,7 @@
15371787 * @start: first ECC byte to set
15381788 * @nbytes: number of ECC bytes to set
15391789 *
1540
- * Works like mtd_ooblayout_get_bytes(), except it acts on free bytes.
1790
+ * Works like mtd_ooblayout_set_bytes(), except it acts on free bytes.
15411791 *
15421792 * Returns zero on success, a negative error code otherwise.
15431793 */
....@@ -1585,60 +1835,69 @@
15851835 int mtd_get_fact_prot_info(struct mtd_info *mtd, size_t len, size_t *retlen,
15861836 struct otp_info *buf)
15871837 {
1588
- if (!mtd->_get_fact_prot_info)
1838
+ struct mtd_info *master = mtd_get_master(mtd);
1839
+
1840
+ if (!master->_get_fact_prot_info)
15891841 return -EOPNOTSUPP;
15901842 if (!len)
15911843 return 0;
1592
- return mtd->_get_fact_prot_info(mtd, len, retlen, buf);
1844
+ return master->_get_fact_prot_info(master, len, retlen, buf);
15931845 }
15941846 EXPORT_SYMBOL_GPL(mtd_get_fact_prot_info);
15951847
15961848 int mtd_read_fact_prot_reg(struct mtd_info *mtd, loff_t from, size_t len,
15971849 size_t *retlen, u_char *buf)
15981850 {
1851
+ struct mtd_info *master = mtd_get_master(mtd);
1852
+
15991853 *retlen = 0;
1600
- if (!mtd->_read_fact_prot_reg)
1854
+ if (!master->_read_fact_prot_reg)
16011855 return -EOPNOTSUPP;
16021856 if (!len)
16031857 return 0;
1604
- return mtd->_read_fact_prot_reg(mtd, from, len, retlen, buf);
1858
+ return master->_read_fact_prot_reg(master, from, len, retlen, buf);
16051859 }
16061860 EXPORT_SYMBOL_GPL(mtd_read_fact_prot_reg);
16071861
16081862 int mtd_get_user_prot_info(struct mtd_info *mtd, size_t len, size_t *retlen,
16091863 struct otp_info *buf)
16101864 {
1611
- if (!mtd->_get_user_prot_info)
1865
+ struct mtd_info *master = mtd_get_master(mtd);
1866
+
1867
+ if (!master->_get_user_prot_info)
16121868 return -EOPNOTSUPP;
16131869 if (!len)
16141870 return 0;
1615
- return mtd->_get_user_prot_info(mtd, len, retlen, buf);
1871
+ return master->_get_user_prot_info(master, len, retlen, buf);
16161872 }
16171873 EXPORT_SYMBOL_GPL(mtd_get_user_prot_info);
16181874
16191875 int mtd_read_user_prot_reg(struct mtd_info *mtd, loff_t from, size_t len,
16201876 size_t *retlen, u_char *buf)
16211877 {
1878
+ struct mtd_info *master = mtd_get_master(mtd);
1879
+
16221880 *retlen = 0;
1623
- if (!mtd->_read_user_prot_reg)
1881
+ if (!master->_read_user_prot_reg)
16241882 return -EOPNOTSUPP;
16251883 if (!len)
16261884 return 0;
1627
- return mtd->_read_user_prot_reg(mtd, from, len, retlen, buf);
1885
+ return master->_read_user_prot_reg(master, from, len, retlen, buf);
16281886 }
16291887 EXPORT_SYMBOL_GPL(mtd_read_user_prot_reg);
16301888
16311889 int mtd_write_user_prot_reg(struct mtd_info *mtd, loff_t to, size_t len,
16321890 size_t *retlen, u_char *buf)
16331891 {
1892
+ struct mtd_info *master = mtd_get_master(mtd);
16341893 int ret;
16351894
16361895 *retlen = 0;
1637
- if (!mtd->_write_user_prot_reg)
1896
+ if (!master->_write_user_prot_reg)
16381897 return -EOPNOTSUPP;
16391898 if (!len)
16401899 return 0;
1641
- ret = mtd->_write_user_prot_reg(mtd, to, len, retlen, buf);
1900
+ ret = master->_write_user_prot_reg(master, to, len, retlen, buf);
16421901 if (ret)
16431902 return ret;
16441903
....@@ -1652,80 +1911,134 @@
16521911
16531912 int mtd_lock_user_prot_reg(struct mtd_info *mtd, loff_t from, size_t len)
16541913 {
1655
- if (!mtd->_lock_user_prot_reg)
1914
+ struct mtd_info *master = mtd_get_master(mtd);
1915
+
1916
+ if (!master->_lock_user_prot_reg)
16561917 return -EOPNOTSUPP;
16571918 if (!len)
16581919 return 0;
1659
- return mtd->_lock_user_prot_reg(mtd, from, len);
1920
+ return master->_lock_user_prot_reg(master, from, len);
16601921 }
16611922 EXPORT_SYMBOL_GPL(mtd_lock_user_prot_reg);
16621923
16631924 /* Chip-supported device locking */
16641925 int mtd_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
16651926 {
1666
- if (!mtd->_lock)
1927
+ struct mtd_info *master = mtd_get_master(mtd);
1928
+
1929
+ if (!master->_lock)
16671930 return -EOPNOTSUPP;
16681931 if (ofs < 0 || ofs >= mtd->size || len > mtd->size - ofs)
16691932 return -EINVAL;
16701933 if (!len)
16711934 return 0;
1672
- return mtd->_lock(mtd, ofs, len);
1935
+
1936
+ if (mtd->flags & MTD_SLC_ON_MLC_EMULATION) {
1937
+ ofs = (loff_t)mtd_div_by_eb(ofs, mtd) * master->erasesize;
1938
+ len = (u64)mtd_div_by_eb(len, mtd) * master->erasesize;
1939
+ }
1940
+
1941
+ return master->_lock(master, mtd_get_master_ofs(mtd, ofs), len);
16731942 }
16741943 EXPORT_SYMBOL_GPL(mtd_lock);
16751944
16761945 int mtd_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
16771946 {
1678
- if (!mtd->_unlock)
1947
+ struct mtd_info *master = mtd_get_master(mtd);
1948
+
1949
+ if (!master->_unlock)
16791950 return -EOPNOTSUPP;
16801951 if (ofs < 0 || ofs >= mtd->size || len > mtd->size - ofs)
16811952 return -EINVAL;
16821953 if (!len)
16831954 return 0;
1684
- return mtd->_unlock(mtd, ofs, len);
1955
+
1956
+ if (mtd->flags & MTD_SLC_ON_MLC_EMULATION) {
1957
+ ofs = (loff_t)mtd_div_by_eb(ofs, mtd) * master->erasesize;
1958
+ len = (u64)mtd_div_by_eb(len, mtd) * master->erasesize;
1959
+ }
1960
+
1961
+ return master->_unlock(master, mtd_get_master_ofs(mtd, ofs), len);
16851962 }
16861963 EXPORT_SYMBOL_GPL(mtd_unlock);
16871964
16881965 int mtd_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len)
16891966 {
1690
- if (!mtd->_is_locked)
1967
+ struct mtd_info *master = mtd_get_master(mtd);
1968
+
1969
+ if (!master->_is_locked)
16911970 return -EOPNOTSUPP;
16921971 if (ofs < 0 || ofs >= mtd->size || len > mtd->size - ofs)
16931972 return -EINVAL;
16941973 if (!len)
16951974 return 0;
1696
- return mtd->_is_locked(mtd, ofs, len);
1975
+
1976
+ if (mtd->flags & MTD_SLC_ON_MLC_EMULATION) {
1977
+ ofs = (loff_t)mtd_div_by_eb(ofs, mtd) * master->erasesize;
1978
+ len = (u64)mtd_div_by_eb(len, mtd) * master->erasesize;
1979
+ }
1980
+
1981
+ return master->_is_locked(master, mtd_get_master_ofs(mtd, ofs), len);
16971982 }
16981983 EXPORT_SYMBOL_GPL(mtd_is_locked);
16991984
17001985 int mtd_block_isreserved(struct mtd_info *mtd, loff_t ofs)
17011986 {
1987
+ struct mtd_info *master = mtd_get_master(mtd);
1988
+
17021989 if (ofs < 0 || ofs >= mtd->size)
17031990 return -EINVAL;
1704
- if (!mtd->_block_isreserved)
1991
+ if (!master->_block_isreserved)
17051992 return 0;
1706
- return mtd->_block_isreserved(mtd, ofs);
1993
+
1994
+ if (mtd->flags & MTD_SLC_ON_MLC_EMULATION)
1995
+ ofs = (loff_t)mtd_div_by_eb(ofs, mtd) * master->erasesize;
1996
+
1997
+ return master->_block_isreserved(master, mtd_get_master_ofs(mtd, ofs));
17071998 }
17081999 EXPORT_SYMBOL_GPL(mtd_block_isreserved);
17092000
17102001 int mtd_block_isbad(struct mtd_info *mtd, loff_t ofs)
17112002 {
2003
+ struct mtd_info *master = mtd_get_master(mtd);
2004
+
17122005 if (ofs < 0 || ofs >= mtd->size)
17132006 return -EINVAL;
1714
- if (!mtd->_block_isbad)
2007
+ if (!master->_block_isbad)
17152008 return 0;
1716
- return mtd->_block_isbad(mtd, ofs);
2009
+
2010
+ if (mtd->flags & MTD_SLC_ON_MLC_EMULATION)
2011
+ ofs = (loff_t)mtd_div_by_eb(ofs, mtd) * master->erasesize;
2012
+
2013
+ return master->_block_isbad(master, mtd_get_master_ofs(mtd, ofs));
17172014 }
17182015 EXPORT_SYMBOL_GPL(mtd_block_isbad);
17192016
17202017 int mtd_block_markbad(struct mtd_info *mtd, loff_t ofs)
17212018 {
1722
- if (!mtd->_block_markbad)
2019
+ struct mtd_info *master = mtd_get_master(mtd);
2020
+ int ret;
2021
+
2022
+ if (!master->_block_markbad)
17232023 return -EOPNOTSUPP;
17242024 if (ofs < 0 || ofs >= mtd->size)
17252025 return -EINVAL;
17262026 if (!(mtd->flags & MTD_WRITEABLE))
17272027 return -EROFS;
1728
- return mtd->_block_markbad(mtd, ofs);
2028
+
2029
+ if (mtd->flags & MTD_SLC_ON_MLC_EMULATION)
2030
+ ofs = (loff_t)mtd_div_by_eb(ofs, mtd) * master->erasesize;
2031
+
2032
+ ret = master->_block_markbad(master, mtd_get_master_ofs(mtd, ofs));
2033
+ if (ret)
2034
+ return ret;
2035
+
2036
+ while (mtd->parent) {
2037
+ mtd->ecc_stats.badblocks++;
2038
+ mtd = mtd->parent;
2039
+ }
2040
+
2041
+ return 0;
17292042 }
17302043 EXPORT_SYMBOL_GPL(mtd_block_markbad);
17312044
....@@ -1775,12 +2088,17 @@
17752088 int mtd_writev(struct mtd_info *mtd, const struct kvec *vecs,
17762089 unsigned long count, loff_t to, size_t *retlen)
17772090 {
2091
+ struct mtd_info *master = mtd_get_master(mtd);
2092
+
17782093 *retlen = 0;
17792094 if (!(mtd->flags & MTD_WRITEABLE))
17802095 return -EROFS;
1781
- if (!mtd->_writev)
2096
+
2097
+ if (!master->_writev)
17822098 return default_mtd_writev(mtd, vecs, count, to, retlen);
1783
- return mtd->_writev(mtd, vecs, count, to, retlen);
2099
+
2100
+ return master->_writev(master, vecs, count,
2101
+ mtd_get_master_ofs(mtd, to), retlen);
17842102 }
17852103 EXPORT_SYMBOL_GPL(mtd_writev);
17862104
....@@ -1862,11 +2180,12 @@
18622180 struct backing_dev_info *bdi;
18632181 int ret;
18642182
1865
- bdi = bdi_alloc(GFP_KERNEL);
2183
+ bdi = bdi_alloc(NUMA_NO_NODE);
18662184 if (!bdi)
18672185 return ERR_PTR(-ENOMEM);
2186
+ bdi->ra_pages = 0;
2187
+ bdi->io_pages = 0;
18682188
1869
- bdi->name = name;
18702189 /*
18712190 * We put '-0' suffix to the name to get the same name format as we
18722191 * used to get. Since this is called only once, we get a unique name.