24 #include <linux/module.h>
25 #include <linux/kernel.h>
26 #include <linux/ptrace.h>
28 #include <linux/string.h>
74 static int mtd_cls_resume(
struct device *
dev);
76 static struct class mtd_class = {
79 .suspend = mtd_cls_suspend,
80 .resume = mtd_cls_resume,
99 #if defined(CONFIG_MTD_CHAR) || defined(CONFIG_MTD_CHAR_MODULE)
100 #define MTD_DEVT(index) MKDEV(MTD_CHAR_MAJOR, (index)*2)
102 #define MTD_DEVT(index) 0
108 static void mtd_release(
struct device *
dev)
122 return mtd ? mtd_suspend(mtd) : 0;
125 static int mtd_cls_resume(
struct device *dev)
186 (
unsigned long long)mtd->
size);
262 static ssize_t mtd_bitflip_threshold_show(
struct device *dev,
271 static ssize_t mtd_bitflip_threshold_store(
struct device *dev,
273 const char *buf,
size_t count)
279 retval =
kstrtouint(buf, 0, &bitflip_threshold);
287 mtd_bitflip_threshold_show,
288 mtd_bitflip_threshold_store);
292 &dev_attr_flags.attr,
294 &dev_attr_erasesize.attr,
295 &dev_attr_writesize.attr,
296 &dev_attr_subpagesize.attr,
297 &dev_attr_oobsize.attr,
298 &dev_attr_numeraseregions.attr,
300 &dev_attr_ecc_strength.attr,
301 &dev_attr_bitflip_threshold.attr,
316 .groups = mtd_groups,
317 .release = mtd_release,
356 }
while (error == -
EAGAIN);
386 "%s: unlock failed, writes may not work\n",
393 mtd->
dev.type = &mtd_devtype;
394 mtd->
dev.class = &mtd_class;
406 pr_debug(
"mtd: Giving out device %d to %s\n", i, mtd->
name);
509 if (err <= 0 && nr_parts && parts) {
510 real_parts =
kmemdup(parts,
sizeof(*parts) * nr_parts,
521 }
else if (err == 0) {
545 if (!device_is_registered(&master->
dev))
566 list_add(&new->list, &mtd_notifiers);
628 }
else if (num >= 0) {
630 if (mtd && mtd != ret)
653 if (!try_module_get(mtd->
owner))
660 module_put(mtd->
owner);
685 if (!
strcmp(name, other->name)) {
724 module_put(mtd->
owner);
747 return mtd->
_erase(mtd, instr);
763 if (from < 0 || from > mtd->
size || len > mtd->
size - from)
767 return mtd->
_point(mtd, from, len, retlen, virt, phys);
776 if (from < 0 || from > mtd->
size || len > mtd->
size - from)
780 return mtd->
_unpoint(mtd, from, len);
794 if (offset > mtd->
size || len > mtd->
size - offset)
805 if (from < 0 || from > mtd->
size || len > mtd->
size - from)
815 ret_code = mtd->
_read(mtd, from, len, retlen, buf);
828 if (to < 0 || to > mtd->
size || len > mtd->
size - to)
834 return mtd->
_write(mtd, to, len, retlen, buf);
851 if (to < 0 || to > mtd->
size || len > mtd->
size - to)
873 ret_code = mtd->
_read_oob(mtd, from, ops);
899 size_t *retlen,
u_char *buf)
922 size_t *retlen,
u_char *buf)
934 size_t *retlen,
u_char *buf)
960 if (ofs < 0 || ofs > mtd->
size || len > mtd->
size - ofs)
964 return mtd->
_lock(mtd, ofs, len);
972 if (ofs < 0 || ofs > mtd->
size || len > mtd->
size - ofs)
976 return mtd->
_unlock(mtd, ofs, len);
984 if (ofs < 0 || ofs > mtd->
size || len > mtd->
size - ofs)
996 if (ofs < 0 || ofs > mtd->
size)
1006 if (ofs < 0 || ofs > mtd->
size)
1025 static int default_mtd_writev(
struct mtd_info *mtd,
const struct kvec *vecs,
1026 unsigned long count, loff_t to,
size_t *retlen)
1029 size_t totlen = 0, thislen;
1032 for (i = 0; i <
count; i++) {
1033 if (!vecs[i].iov_len)
1035 ret =
mtd_write(mtd, to, vecs[i].iov_len, &thislen,
1038 if (ret || thislen != vecs[i].iov_len)
1058 unsigned long count, loff_t to,
size_t *retlen)
1064 return default_mtd_writev(mtd, vecs, count, to, retlen);
1065 return mtd->
_writev(mtd, vecs, count, to, retlen);
1102 while (*size > min_alloc) {
1119 #ifdef CONFIG_PROC_FS
1126 static int mtd_proc_show(
struct seq_file *
m,
void *
v)
1130 seq_puts(m,
"dev: size erasesize name\n");
1133 seq_printf(m,
"mtd%d: %8.8llx %8.8x \"%s\"\n",
1134 mtd->
index, (
unsigned long long)mtd->
size,
1147 .
open = mtd_proc_open,
1171 static int __init init_mtd(
void)
1179 ret = mtd_bdi_init(&mtd_bdi_unmappable,
"mtd-unmap");
1183 ret = mtd_bdi_init(&mtd_bdi_ro_mappable,
"mtd-romap");
1187 ret = mtd_bdi_init(&mtd_bdi_rw_mappable,
"mtd-rwmap");
1191 #ifdef CONFIG_PROC_FS
1192 proc_mtd = proc_create(
"mtd", 0,
NULL, &mtd_proc_ops);
1203 pr_err(
"Error registering mtd class or bdi: %d\n", ret);
1207 static void __exit cleanup_mtd(
void)
1209 #ifdef CONFIG_PROC_FS