Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * block2mtd.c - create an mtd from a block device
0003  *
0004  * Copyright (C) 2001,2002  Simon Evans <spse@secret.org.uk>
0005  * Copyright (C) 2004-2006  Joern Engel <joern@wh.fh-wedel.de>
0006  *
0007  * Licence: GPL
0008  */
0009 
0010 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0011 
0012 /*
0013  * When the first attempt at device initialization fails, we may need to
0014  * wait a little bit and retry. This timeout, by default 3 seconds, gives
0015  * device time to start up. Required on BCM2708 and a few other chipsets.
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 /* Maximum number of comma-separated items in the 'block2mtd=' parameter */
0035 #define BLOCK2MTD_PARAM_MAX_COUNT 3
0036 
0037 /* Info for the block device */
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 /* Static info about the MTD, used in cleanup_module */
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 /* erase a specified part of the device */
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;   // page index
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;    // multiple pages
0116         else
0117             cpylen = len;   // this page
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 /* write data to the underlying device */
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;   // page index
0144     int offset = to & ~PAGE_MASK;   // page offset
0145     int cpylen;
0146 
0147     while (len) {
0148         if ((offset+len) > PAGE_SIZE)
0149             cpylen = PAGE_SIZE - offset;    // multiple pages
0150         else
0151             cpylen = len;           // this page
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 /* sync the device - wait until the write queue is empty */
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     /* Get a handle on the device */
0238     bdev = blkdev_get_by_path(devname, mode, dev);
0239 
0240 #ifndef MODULE
0241     /*
0242      * We might not have the root device mounted at this point.
0243      * Try to resolve the device name by other means.
0244      */
0245     for (i = 0; IS_ERR(bdev) && i <= timeout; i++) {
0246         dev_t devt;
0247 
0248         if (i)
0249             /*
0250              * Calling wait_for_device_probe in the first loop
0251              * was not enough, sleep for a bit in subsequent
0252              * go-arounds.
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     /* Setup the MTD structure */
0283     /* make the name contain the block device in */
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         /* Device didn't get added, so free the entry */
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 /* This function works similar to reguler strtoul.  In addition, it
0327  * allows some suffixes for a more human-readable number format:
0328  * ki, Ki, kiB, KiB - multiply result with 1024
0329  * Mi, MiB      - multiply result with 1024^2
0330  * Gi, GiB      - multiply result with 1024^3
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     /* By dwmw2 editorial decree, "ki", "Mi" or "Gi" are to be used. */
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 /* 80 for device, 12 for erase size */
0382 static char block2mtd_paramline[80 + 12];
0383 #endif
0384 
0385 static int block2mtd_setup2(const char *val)
0386 {
0387     /* 80 for device, 12 for erase size, 80 for name, 8 for timeout */
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     /* Optional argument when custom label is used */
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     /* If more parameters are later passed in via
0450        /sys/module/block2mtd/parameters/block2mtd
0451        and block2mtd_init() has already been called,
0452        we can parse the argument now. */
0453 
0454     if (block2mtd_init_called)
0455         return block2mtd_setup2(val);
0456 
0457     /* During early boot stage, we only save the parameters
0458        here. We must parse them later: if the param passed
0459        from kernel boot command line, block2mtd_setup() is
0460        called so early that it is not possible to resolve
0461        the device (even kmalloc() fails). Deter that work to
0462        block2mtd_setup2(). */
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     /* Remove the MTD devices */
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");