0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/init.h>
0009 #include <linux/slab.h>
0010 #include <linux/mtd/mtd.h>
0011 #include <linux/mtd/blktrans.h>
0012 #include <linux/module.h>
0013 #include <linux/major.h>
0014
0015 static int mtdblock_readsect(struct mtd_blktrans_dev *dev,
0016 unsigned long block, char *buf)
0017 {
0018 size_t retlen;
0019
0020 if (mtd_read(dev->mtd, (block * 512), 512, &retlen, buf))
0021 return 1;
0022 return 0;
0023 }
0024
0025 static int mtdblock_writesect(struct mtd_blktrans_dev *dev,
0026 unsigned long block, char *buf)
0027 {
0028 size_t retlen;
0029
0030 if (mtd_write(dev->mtd, (block * 512), 512, &retlen, buf))
0031 return 1;
0032 return 0;
0033 }
0034
0035 static void mtdblock_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
0036 {
0037 struct mtd_blktrans_dev *dev = kzalloc(sizeof(*dev), GFP_KERNEL);
0038
0039 if (!dev)
0040 return;
0041
0042 dev->mtd = mtd;
0043 dev->devnum = mtd->index;
0044
0045 dev->size = mtd->size >> 9;
0046 dev->tr = tr;
0047 dev->readonly = 1;
0048
0049 if (mtd_type_is_nand(mtd))
0050 pr_warn("%s: MTD device '%s' is NAND, please consider using UBI block devices instead.\n",
0051 tr->name, mtd->name);
0052
0053 if (add_mtd_blktrans_dev(dev))
0054 kfree(dev);
0055 }
0056
0057 static void mtdblock_remove_dev(struct mtd_blktrans_dev *dev)
0058 {
0059 del_mtd_blktrans_dev(dev);
0060 }
0061
0062 static struct mtd_blktrans_ops mtdblock_tr = {
0063 .name = "mtdblock",
0064 .major = MTD_BLOCK_MAJOR,
0065 .part_bits = 0,
0066 .blksize = 512,
0067 .readsect = mtdblock_readsect,
0068 .writesect = mtdblock_writesect,
0069 .add_mtd = mtdblock_add_mtd,
0070 .remove_dev = mtdblock_remove_dev,
0071 .owner = THIS_MODULE,
0072 };
0073
0074 module_mtd_blktrans(mtdblock_tr);
0075
0076 MODULE_LICENSE("GPL");
0077 MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
0078 MODULE_DESCRIPTION("Simple read-only block device emulation access to MTD devices");