1/* 2 * $Id: block2mtd.c,v 1.1.1.1 2007/08/03 18:52:43 Exp $ 3 * 4 * block2mtd.c - create an mtd from a block device 5 * 6 * Copyright (C) 2001,2002 Simon Evans <spse@secret.org.uk> 7 * Copyright (C) 2004-2006 J��rn Engel <joern@wh.fh-wedel.de> 8 * 9 * Licence: GPL 10 */ 11#include <linux/module.h> 12#include <linux/fs.h> 13#include <linux/blkdev.h> 14#include <linux/bio.h> 15#include <linux/pagemap.h> 16#include <linux/list.h> 17#include <linux/init.h> 18#include <linux/mtd/mtd.h> 19#include <linux/buffer_head.h> 20#include <linux/mutex.h> 21#include <linux/mount.h> 22 23#define VERSION "$Revision: 1.1.1.1 $" 24 25 26#define ERROR(fmt, args...) printk(KERN_ERR "block2mtd: " fmt "\n" , ## args) 27#define INFO(fmt, args...) printk(KERN_INFO "block2mtd: " fmt "\n" , ## args) 28 29 30/* Info for the block device */ 31struct block2mtd_dev { 32 struct list_head list; 33 struct block_device *blkdev; 34 struct mtd_info mtd; 35 struct mutex write_mutex; 36}; 37 38 39/* Static info about the MTD, used in cleanup_module */ 40static LIST_HEAD(blkmtd_device_list); 41 42 43static struct page *page_read(struct address_space *mapping, int index) 44{ 45 return read_mapping_page(mapping, index, NULL); 46} 47 48/* erase a specified part of the device */ 49static int _block2mtd_erase(struct block2mtd_dev *dev, loff_t to, size_t len) 50{ 51 struct address_space *mapping = dev->blkdev->bd_inode->i_mapping; 52 struct page *page; 53 int index = to >> PAGE_SHIFT; // page index 54 int pages = len >> PAGE_SHIFT; 55 u_long *p; 56 u_long *max; 57 58 while (pages) { 59 page = page_read(mapping, index); 60 if (!page) 61 return -ENOMEM; 62 if (IS_ERR(page)) 63 return PTR_ERR(page); 64 65 max = page_address(page) + PAGE_SIZE; 66 for (p=page_address(page); p<max; p++) 67 if (*p != -1UL) { 68 lock_page(page); 69 memset(page_address(page), 0xff, PAGE_SIZE); 70 set_page_dirty(page); 71 unlock_page(page); 72 break; 73 } 74 75 page_cache_release(page); 76 pages--; 77 index++; 78 } 79 return 0; 80} 81static int block2mtd_erase(struct mtd_info *mtd, struct erase_info *instr) 82{ 83 struct block2mtd_dev *dev = mtd->priv; 84 size_t from = instr->addr; 85 size_t len = instr->len; 86 int err; 87 88 instr->state = MTD_ERASING; 89 mutex_lock(&dev->write_mutex); 90 err = _block2mtd_erase(dev, from, len); 91 mutex_unlock(&dev->write_mutex); 92 if (err) { 93 ERROR("erase failed err = %d", err); 94 instr->state = MTD_ERASE_FAILED; 95 } else 96 instr->state = MTD_ERASE_DONE; 97 98 instr->state = MTD_ERASE_DONE; 99 mtd_erase_callback(instr); 100 return err; 101} 102 103 104static int block2mtd_read(struct mtd_info *mtd, loff_t from, size_t len, 105 size_t *retlen, u_char *buf) 106{ 107 struct block2mtd_dev *dev = mtd->priv; 108 struct page *page; 109 int index = from >> PAGE_SHIFT; 110 int offset = from & (PAGE_SIZE-1); 111 int cpylen; 112 113 if (from > mtd->size) 114 return -EINVAL; 115 if (from + len > mtd->size) 116 len = mtd->size - from; 117 118 if (retlen) 119 *retlen = 0; 120 121 while (len) { 122 if ((offset + len) > PAGE_SIZE) 123 cpylen = PAGE_SIZE - offset; // multiple pages 124 else 125 cpylen = len; // this page 126 len = len - cpylen; 127 128 page = page_read(dev->blkdev->bd_inode->i_mapping, index); 129 if (!page) 130 return -ENOMEM; 131 if (IS_ERR(page)) 132 return PTR_ERR(page); 133 134 memcpy(buf, page_address(page) + offset, cpylen); 135 page_cache_release(page); 136 137 if (retlen) 138 *retlen += cpylen; 139 buf += cpylen; 140 offset = 0; 141 index++; 142 } 143 return 0; 144} 145 146 147/* write data to the underlying device */ 148static int _block2mtd_write(struct block2mtd_dev *dev, const u_char *buf, 149 loff_t to, size_t len, size_t *retlen) 150{ 151 struct page *page; 152 struct address_space *mapping = dev->blkdev->bd_inode->i_mapping; 153 int index = to >> PAGE_SHIFT; // page index 154 int offset = to & ~PAGE_MASK; // page offset 155 int cpylen; 156 157 if (retlen) 158 *retlen = 0; 159 while (len) { 160 if ((offset+len) > PAGE_SIZE) 161 cpylen = PAGE_SIZE - offset; // multiple pages 162 else 163 cpylen = len; // this page 164 len = len - cpylen; 165 166 page = page_read(mapping, index); 167 if (!page) 168 return -ENOMEM; 169 if (IS_ERR(page)) 170 return PTR_ERR(page); 171 172 if (memcmp(page_address(page)+offset, buf, cpylen)) { 173 lock_page(page); 174 memcpy(page_address(page) + offset, buf, cpylen); 175 set_page_dirty(page); 176 unlock_page(page); 177 } 178 page_cache_release(page); 179 180 if (retlen) 181 *retlen += cpylen; 182 183 buf += cpylen; 184 offset = 0; 185 index++; 186 } 187 return 0; 188} 189 190 191static int block2mtd_write(struct mtd_info *mtd, loff_t to, size_t len, 192 size_t *retlen, const u_char *buf) 193{ 194 struct block2mtd_dev *dev = mtd->priv; 195 int err; 196 197 if (!len) 198 return 0; 199 if (to >= mtd->size) 200 return -ENOSPC; 201 if (to + len > mtd->size) 202 len = mtd->size - to; 203 204 mutex_lock(&dev->write_mutex); 205 err = _block2mtd_write(dev, buf, to, len, retlen); 206 mutex_unlock(&dev->write_mutex); 207 if (err > 0) 208 err = 0; 209 return err; 210} 211 212 213/* sync the device - wait until the write queue is empty */ 214static void block2mtd_sync(struct mtd_info *mtd) 215{ 216 struct block2mtd_dev *dev = mtd->priv; 217 sync_blockdev(dev->blkdev); 218 return; 219} 220 221 222static void block2mtd_free_device(struct block2mtd_dev *dev) 223{ 224 if (!dev) 225 return; 226 227 kfree(dev->mtd.name); 228 229 if (dev->blkdev) { 230 invalidate_mapping_pages(dev->blkdev->bd_inode->i_mapping, 231 0, -1); 232 close_bdev_excl(dev->blkdev); 233 } 234 235 kfree(dev); 236} 237 238 239static struct block2mtd_dev *add_device(char *devname, int erase_size) 240{ 241 struct block_device *bdev; 242 struct block2mtd_dev *dev; 243 244 if (!devname) 245 return NULL; 246 247 dev = kzalloc(sizeof(struct block2mtd_dev), GFP_KERNEL); 248 if (!dev) 249 return NULL; 250 251 /* Get a handle on the device */ 252 bdev = open_bdev_excl(devname, O_RDWR, NULL); 253#ifndef MODULE 254 if (IS_ERR(bdev)) { 255 256 /* We might not have rootfs mounted at this point. Try 257 to resolve the device name by other means. */ 258 259 dev_t devt = name_to_dev_t(devname); 260 if (devt) { 261 bdev = open_by_devnum(devt, FMODE_WRITE | FMODE_READ); 262 } 263 } 264#endif 265 266 if (IS_ERR(bdev)) { 267 ERROR("error: cannot open device %s", devname); 268 goto devinit_err; 269 } 270 dev->blkdev = bdev; 271 272 if (MAJOR(bdev->bd_dev) == MTD_BLOCK_MAJOR) { 273 ERROR("attempting to use an MTD device as a block device"); 274 goto devinit_err; 275 } 276 277 mutex_init(&dev->write_mutex); 278 279 /* Setup the MTD structure */ 280 /* make the name contain the block device in */ 281 dev->mtd.name = kmalloc(sizeof("block2mtd: ") + strlen(devname), 282 GFP_KERNEL); 283 if (!dev->mtd.name) 284 goto devinit_err; 285 286 sprintf(dev->mtd.name, "block2mtd: %s", devname); 287 288 dev->mtd.size = dev->blkdev->bd_inode->i_size & PAGE_MASK; 289 dev->mtd.erasesize = erase_size; 290 dev->mtd.writesize = 1; 291 dev->mtd.type = MTD_RAM; 292 dev->mtd.flags = MTD_CAP_RAM; 293 dev->mtd.erase = block2mtd_erase; 294 dev->mtd.write = block2mtd_write; 295 dev->mtd.writev = default_mtd_writev; 296 dev->mtd.sync = block2mtd_sync; 297 dev->mtd.read = block2mtd_read; 298 dev->mtd.priv = dev; 299 dev->mtd.owner = THIS_MODULE; 300 301 if (add_mtd_device(&dev->mtd)) { 302 /* Device didnt get added, so free the entry */ 303 goto devinit_err; 304 } 305 list_add(&dev->list, &blkmtd_device_list); 306 INFO("mtd%d: [%s] erase_size = %dKiB [%d]", dev->mtd.index, 307 dev->mtd.name + strlen("blkmtd: "), 308 dev->mtd.erasesize >> 10, dev->mtd.erasesize); 309 return dev; 310 311devinit_err: 312 block2mtd_free_device(dev); 313 return NULL; 314} 315 316 317/* This function works similar to reguler strtoul. In addition, it 318 * allows some suffixes for a more human-readable number format: 319 * ki, Ki, kiB, KiB - multiply result with 1024 320 * Mi, MiB - multiply result with 1024^2 321 * Gi, GiB - multiply result with 1024^3 322 */ 323static int ustrtoul(const char *cp, char **endp, unsigned int base) 324{ 325 unsigned long result = simple_strtoul(cp, endp, base); 326 switch (**endp) { 327 case 'G' : 328 result *= 1024; 329 case 'M': 330 result *= 1024; 331 case 'K': 332 case 'k': 333 result *= 1024; 334 /* By dwmw2 editorial decree, "ki", "Mi" or "Gi" are to be used. */ 335 if ((*endp)[1] == 'i') { 336 if ((*endp)[2] == 'B') 337 (*endp) += 3; 338 else 339 (*endp) += 2; 340 } 341 } 342 return result; 343} 344 345 346static int parse_num(size_t *num, const char *token) 347{ 348 char *endp; 349 size_t n; 350 351 n = (size_t) ustrtoul(token, &endp, 0); 352 if (*endp) 353 return -EINVAL; 354 355 *num = n; 356 return 0; 357} 358 359 360static inline void kill_final_newline(char *str) 361{ 362 char *newline = strrchr(str, '\n'); 363 if (newline && !newline[1]) 364 *newline = 0; 365} 366 367 368#define parse_err(fmt, args...) do { \ 369 ERROR("block2mtd: " fmt "\n", ## args); \ 370 return 0; \ 371} while (0) 372 373#ifndef MODULE 374static int block2mtd_init_called = 0; 375static char block2mtd_paramline[80 + 12]; /* 80 for device, 12 for erase size */ 376#endif 377 378 379static int block2mtd_setup2(const char *val) 380{ 381 char buf[80 + 12]; /* 80 for device, 12 for erase size */ 382 char *str = buf; 383 char *token[2]; 384 char *name; 385 size_t erase_size = PAGE_SIZE; 386 int i, ret; 387 388 if (strnlen(val, sizeof(buf)) >= sizeof(buf)) 389 parse_err("parameter too long"); 390 391 strcpy(str, val); 392 kill_final_newline(str); 393 394 for (i = 0; i < 2; i++) 395 token[i] = strsep(&str, ","); 396 397 if (str) 398 parse_err("too many arguments"); 399 400 if (!token[0]) 401 parse_err("no argument"); 402 403 name = token[0]; 404 if (strlen(name) + 1 > 80) 405 parse_err("device name too long"); 406 407 if (token[1]) { 408 ret = parse_num(&erase_size, token[1]); 409 if (ret) { 410 kfree(name); 411 parse_err("illegal erase size"); 412 } 413 } 414 415 add_device(name, erase_size); 416 417 return 0; 418} 419 420 421static int block2mtd_setup(const char *val, struct kernel_param *kp) 422{ 423#ifdef MODULE 424 return block2mtd_setup2(val); 425#else 426 /* If more parameters are later passed in via 427 /sys/module/block2mtd/parameters/block2mtd 428 and block2mtd_init() has already been called, 429 we can parse the argument now. */ 430 431 if (block2mtd_init_called) 432 return block2mtd_setup2(val); 433 434 /* During early boot stage, we only save the parameters 435 here. We must parse them later: if the param passed 436 from kernel boot command line, block2mtd_setup() is 437 called so early that it is not possible to resolve 438 the device (even kmalloc() fails). Deter that work to 439 block2mtd_setup2(). */ 440 441 strlcpy(block2mtd_paramline, val, sizeof(block2mtd_paramline)); 442 443 return 0; 444#endif 445} 446 447 448module_param_call(block2mtd, block2mtd_setup, NULL, NULL, 0200); 449MODULE_PARM_DESC(block2mtd, "Device to use. \"block2mtd=<dev>[,<erasesize>]\""); 450 451static int __init block2mtd_init(void) 452{ 453 int ret = 0; 454 INFO("version " VERSION); 455 456#ifndef MODULE 457 if (strlen(block2mtd_paramline)) 458 ret = block2mtd_setup2(block2mtd_paramline); 459 block2mtd_init_called = 1; 460#endif 461 462 return ret; 463} 464 465 466static void __devexit block2mtd_exit(void) 467{ 468 struct list_head *pos, *next; 469 470 /* Remove the MTD devices */ 471 list_for_each_safe(pos, next, &blkmtd_device_list) { 472 struct block2mtd_dev *dev = list_entry(pos, typeof(*dev), list); 473 block2mtd_sync(&dev->mtd); 474 del_mtd_device(&dev->mtd); 475 INFO("mtd%d: [%s] removed", dev->mtd.index, 476 dev->mtd.name + strlen("blkmtd: ")); 477 list_del(&dev->list); 478 block2mtd_free_device(dev); 479 } 480} 481 482 483module_init(block2mtd_init); 484module_exit(block2mtd_exit); 485 486MODULE_LICENSE("GPL"); 487MODULE_AUTHOR("Simon Evans <spse@secret.org.uk> and others"); 488MODULE_DESCRIPTION("Emulate an MTD using a block device"); 489