0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0011
0012
0013
0014
0015
0016
0017 #define MTD_DEFAULT_TIMEOUT 3
0018
0019 #include <linux/module.h>
0020 #include <linux/delay.h>
0021 #include <linux/fs.h>
0022 #include <linux/blkdev.h>
0023 #include <linux/backing-dev.h>
0024 #include <linux/bio.h>
0025 #include <linux/pagemap.h>
0026 #include <linux/list.h>
0027 #include <linux/init.h>
0028 #include <linux/mtd/mtd.h>
0029 #include <linux/mutex.h>
0030 #include <linux/mount.h>
0031 #include <linux/slab.h>
0032 #include <linux/major.h>
0033
0034
0035 #define BLOCK2MTD_PARAM_MAX_COUNT 3
0036
0037
0038 struct block2mtd_dev {
0039 struct list_head list;
0040 struct block_device *blkdev;
0041 struct mtd_info mtd;
0042 struct mutex write_mutex;
0043 };
0044
0045
0046
0047 static LIST_HEAD(blkmtd_device_list);
0048
0049
0050 static struct page *page_read(struct address_space *mapping, pgoff_t index)
0051 {
0052 return read_mapping_page(mapping, index, NULL);
0053 }
0054
0055
0056 static int _block2mtd_erase(struct block2mtd_dev *dev, loff_t to, size_t len)
0057 {
0058 struct address_space *mapping = dev->blkdev->bd_inode->i_mapping;
0059 struct page *page;
0060 pgoff_t index = to >> PAGE_SHIFT;
0061 int pages = len >> PAGE_SHIFT;
0062 u_long *p;
0063 u_long *max;
0064
0065 while (pages) {
0066 page = page_read(mapping, index);
0067 if (IS_ERR(page))
0068 return PTR_ERR(page);
0069
0070 max = page_address(page) + PAGE_SIZE;
0071 for (p=page_address(page); p<max; p++)
0072 if (*p != -1UL) {
0073 lock_page(page);
0074 memset(page_address(page), 0xff, PAGE_SIZE);
0075 set_page_dirty(page);
0076 unlock_page(page);
0077 balance_dirty_pages_ratelimited(mapping);
0078 break;
0079 }
0080
0081 put_page(page);
0082 pages--;
0083 index++;
0084 }
0085 return 0;
0086 }
0087 static int block2mtd_erase(struct mtd_info *mtd, struct erase_info *instr)
0088 {
0089 struct block2mtd_dev *dev = mtd->priv;
0090 size_t from = instr->addr;
0091 size_t len = instr->len;
0092 int err;
0093
0094 mutex_lock(&dev->write_mutex);
0095 err = _block2mtd_erase(dev, from, len);
0096 mutex_unlock(&dev->write_mutex);
0097 if (err)
0098 pr_err("erase failed err = %d\n", err);
0099
0100 return err;
0101 }
0102
0103
0104 static int block2mtd_read(struct mtd_info *mtd, loff_t from, size_t len,
0105 size_t *retlen, u_char *buf)
0106 {
0107 struct block2mtd_dev *dev = mtd->priv;
0108 struct page *page;
0109 pgoff_t index = from >> PAGE_SHIFT;
0110 int offset = from & (PAGE_SIZE-1);
0111 int cpylen;
0112
0113 while (len) {
0114 if ((offset + len) > PAGE_SIZE)
0115 cpylen = PAGE_SIZE - offset;
0116 else
0117 cpylen = len;
0118 len = len - cpylen;
0119
0120 page = page_read(dev->blkdev->bd_inode->i_mapping, index);
0121 if (IS_ERR(page))
0122 return PTR_ERR(page);
0123
0124 memcpy(buf, page_address(page) + offset, cpylen);
0125 put_page(page);
0126
0127 if (retlen)
0128 *retlen += cpylen;
0129 buf += cpylen;
0130 offset = 0;
0131 index++;
0132 }
0133 return 0;
0134 }
0135
0136
0137
0138 static int _block2mtd_write(struct block2mtd_dev *dev, const u_char *buf,
0139 loff_t to, size_t len, size_t *retlen)
0140 {
0141 struct page *page;
0142 struct address_space *mapping = dev->blkdev->bd_inode->i_mapping;
0143 pgoff_t index = to >> PAGE_SHIFT;
0144 int offset = to & ~PAGE_MASK;
0145 int cpylen;
0146
0147 while (len) {
0148 if ((offset+len) > PAGE_SIZE)
0149 cpylen = PAGE_SIZE - offset;
0150 else
0151 cpylen = len;
0152 len = len - cpylen;
0153
0154 page = page_read(mapping, index);
0155 if (IS_ERR(page))
0156 return PTR_ERR(page);
0157
0158 if (memcmp(page_address(page)+offset, buf, cpylen)) {
0159 lock_page(page);
0160 memcpy(page_address(page) + offset, buf, cpylen);
0161 set_page_dirty(page);
0162 unlock_page(page);
0163 balance_dirty_pages_ratelimited(mapping);
0164 }
0165 put_page(page);
0166
0167 if (retlen)
0168 *retlen += cpylen;
0169
0170 buf += cpylen;
0171 offset = 0;
0172 index++;
0173 }
0174 return 0;
0175 }
0176
0177
0178 static int block2mtd_write(struct mtd_info *mtd, loff_t to, size_t len,
0179 size_t *retlen, const u_char *buf)
0180 {
0181 struct block2mtd_dev *dev = mtd->priv;
0182 int err;
0183
0184 mutex_lock(&dev->write_mutex);
0185 err = _block2mtd_write(dev, buf, to, len, retlen);
0186 mutex_unlock(&dev->write_mutex);
0187 if (err > 0)
0188 err = 0;
0189 return err;
0190 }
0191
0192
0193
0194 static void block2mtd_sync(struct mtd_info *mtd)
0195 {
0196 struct block2mtd_dev *dev = mtd->priv;
0197 sync_blockdev(dev->blkdev);
0198 return;
0199 }
0200
0201
0202 static void block2mtd_free_device(struct block2mtd_dev *dev)
0203 {
0204 if (!dev)
0205 return;
0206
0207 kfree(dev->mtd.name);
0208
0209 if (dev->blkdev) {
0210 invalidate_mapping_pages(dev->blkdev->bd_inode->i_mapping,
0211 0, -1);
0212 blkdev_put(dev->blkdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
0213 }
0214
0215 kfree(dev);
0216 }
0217
0218
0219 static struct block2mtd_dev *add_device(char *devname, int erase_size,
0220 char *label, int timeout)
0221 {
0222 #ifndef MODULE
0223 int i;
0224 #endif
0225 const fmode_t mode = FMODE_READ | FMODE_WRITE | FMODE_EXCL;
0226 struct block_device *bdev;
0227 struct block2mtd_dev *dev;
0228 char *name;
0229
0230 if (!devname)
0231 return NULL;
0232
0233 dev = kzalloc(sizeof(struct block2mtd_dev), GFP_KERNEL);
0234 if (!dev)
0235 return NULL;
0236
0237
0238 bdev = blkdev_get_by_path(devname, mode, dev);
0239
0240 #ifndef MODULE
0241
0242
0243
0244
0245 for (i = 0; IS_ERR(bdev) && i <= timeout; i++) {
0246 dev_t devt;
0247
0248 if (i)
0249
0250
0251
0252
0253
0254 msleep(1000);
0255 wait_for_device_probe();
0256
0257 devt = name_to_dev_t(devname);
0258 if (!devt)
0259 continue;
0260 bdev = blkdev_get_by_dev(devt, mode, dev);
0261 }
0262 #endif
0263
0264 if (IS_ERR(bdev)) {
0265 pr_err("error: cannot open device %s\n", devname);
0266 goto err_free_block2mtd;
0267 }
0268 dev->blkdev = bdev;
0269
0270 if (MAJOR(bdev->bd_dev) == MTD_BLOCK_MAJOR) {
0271 pr_err("attempting to use an MTD device as a block device\n");
0272 goto err_free_block2mtd;
0273 }
0274
0275 if ((long)dev->blkdev->bd_inode->i_size % erase_size) {
0276 pr_err("erasesize must be a divisor of device size\n");
0277 goto err_free_block2mtd;
0278 }
0279
0280 mutex_init(&dev->write_mutex);
0281
0282
0283
0284 if (!label)
0285 name = kasprintf(GFP_KERNEL, "block2mtd: %s", devname);
0286 else
0287 name = kstrdup(label, GFP_KERNEL);
0288 if (!name)
0289 goto err_destroy_mutex;
0290
0291 dev->mtd.name = name;
0292
0293 dev->mtd.size = dev->blkdev->bd_inode->i_size & PAGE_MASK;
0294 dev->mtd.erasesize = erase_size;
0295 dev->mtd.writesize = 1;
0296 dev->mtd.writebufsize = PAGE_SIZE;
0297 dev->mtd.type = MTD_RAM;
0298 dev->mtd.flags = MTD_CAP_RAM;
0299 dev->mtd._erase = block2mtd_erase;
0300 dev->mtd._write = block2mtd_write;
0301 dev->mtd._sync = block2mtd_sync;
0302 dev->mtd._read = block2mtd_read;
0303 dev->mtd.priv = dev;
0304 dev->mtd.owner = THIS_MODULE;
0305
0306 if (mtd_device_register(&dev->mtd, NULL, 0)) {
0307
0308 goto err_destroy_mutex;
0309 }
0310
0311 list_add(&dev->list, &blkmtd_device_list);
0312 pr_info("mtd%d: [%s] erase_size = %dKiB [%d]\n",
0313 dev->mtd.index,
0314 label ? label : dev->mtd.name + strlen("block2mtd: "),
0315 dev->mtd.erasesize >> 10, dev->mtd.erasesize);
0316 return dev;
0317
0318 err_destroy_mutex:
0319 mutex_destroy(&dev->write_mutex);
0320 err_free_block2mtd:
0321 block2mtd_free_device(dev);
0322 return NULL;
0323 }
0324
0325
0326
0327
0328
0329
0330
0331
0332 static int ustrtoul(const char *cp, char **endp, unsigned int base)
0333 {
0334 unsigned long result = simple_strtoul(cp, endp, base);
0335 switch (**endp) {
0336 case 'G' :
0337 result *= 1024;
0338 fallthrough;
0339 case 'M':
0340 result *= 1024;
0341 fallthrough;
0342 case 'K':
0343 case 'k':
0344 result *= 1024;
0345
0346 if ((*endp)[1] == 'i') {
0347 if ((*endp)[2] == 'B')
0348 (*endp) += 3;
0349 else
0350 (*endp) += 2;
0351 }
0352 }
0353 return result;
0354 }
0355
0356
0357 static int parse_num(size_t *num, const char *token)
0358 {
0359 char *endp;
0360 size_t n;
0361
0362 n = (size_t) ustrtoul(token, &endp, 0);
0363 if (*endp)
0364 return -EINVAL;
0365
0366 *num = n;
0367 return 0;
0368 }
0369
0370
0371 static inline void kill_final_newline(char *str)
0372 {
0373 char *newline = strrchr(str, '\n');
0374 if (newline && !newline[1])
0375 *newline = 0;
0376 }
0377
0378
0379 #ifndef MODULE
0380 static int block2mtd_init_called = 0;
0381
0382 static char block2mtd_paramline[80 + 12];
0383 #endif
0384
0385 static int block2mtd_setup2(const char *val)
0386 {
0387
0388 char buf[80 + 12 + 80 + 8];
0389 char *str = buf;
0390 char *token[BLOCK2MTD_PARAM_MAX_COUNT];
0391 char *name;
0392 char *label = NULL;
0393 size_t erase_size = PAGE_SIZE;
0394 unsigned long timeout = MTD_DEFAULT_TIMEOUT;
0395 int i, ret;
0396
0397 if (strnlen(val, sizeof(buf)) >= sizeof(buf)) {
0398 pr_err("parameter too long\n");
0399 return 0;
0400 }
0401
0402 strcpy(str, val);
0403 kill_final_newline(str);
0404
0405 for (i = 0; i < BLOCK2MTD_PARAM_MAX_COUNT; i++)
0406 token[i] = strsep(&str, ",");
0407
0408 if (str) {
0409 pr_err("too many arguments\n");
0410 return 0;
0411 }
0412
0413 if (!token[0]) {
0414 pr_err("no argument\n");
0415 return 0;
0416 }
0417
0418 name = token[0];
0419 if (strlen(name) + 1 > 80) {
0420 pr_err("device name too long\n");
0421 return 0;
0422 }
0423
0424
0425 if (token[1] && strlen(token[1])) {
0426 ret = parse_num(&erase_size, token[1]);
0427 if (ret) {
0428 pr_err("illegal erase size\n");
0429 return 0;
0430 }
0431 }
0432
0433 if (token[2]) {
0434 label = token[2];
0435 pr_info("Using custom MTD label '%s' for dev %s\n", label, name);
0436 }
0437
0438 add_device(name, erase_size, label, timeout);
0439
0440 return 0;
0441 }
0442
0443
0444 static int block2mtd_setup(const char *val, const struct kernel_param *kp)
0445 {
0446 #ifdef MODULE
0447 return block2mtd_setup2(val);
0448 #else
0449
0450
0451
0452
0453
0454 if (block2mtd_init_called)
0455 return block2mtd_setup2(val);
0456
0457
0458
0459
0460
0461
0462
0463
0464 strlcpy(block2mtd_paramline, val, sizeof(block2mtd_paramline));
0465
0466 return 0;
0467 #endif
0468 }
0469
0470
0471 module_param_call(block2mtd, block2mtd_setup, NULL, NULL, 0200);
0472 MODULE_PARM_DESC(block2mtd, "Device to use. \"block2mtd=<dev>[,[<erasesize>][,<label>]]\"");
0473
0474 static int __init block2mtd_init(void)
0475 {
0476 int ret = 0;
0477
0478 #ifndef MODULE
0479 if (strlen(block2mtd_paramline))
0480 ret = block2mtd_setup2(block2mtd_paramline);
0481 block2mtd_init_called = 1;
0482 #endif
0483
0484 return ret;
0485 }
0486
0487
0488 static void block2mtd_exit(void)
0489 {
0490 struct list_head *pos, *next;
0491
0492
0493 list_for_each_safe(pos, next, &blkmtd_device_list) {
0494 struct block2mtd_dev *dev = list_entry(pos, typeof(*dev), list);
0495 block2mtd_sync(&dev->mtd);
0496 mtd_device_unregister(&dev->mtd);
0497 mutex_destroy(&dev->write_mutex);
0498 pr_info("mtd%d: [%s] removed\n",
0499 dev->mtd.index,
0500 dev->mtd.name + strlen("block2mtd: "));
0501 list_del(&dev->list);
0502 block2mtd_free_device(dev);
0503 }
0504 }
0505
0506 late_initcall(block2mtd_init);
0507 module_exit(block2mtd_exit);
0508
0509 MODULE_LICENSE("GPL");
0510 MODULE_AUTHOR("Joern Engel <joern@lazybastard.org>");
0511 MODULE_DESCRIPTION("Emulate an MTD using a block device");