9 #include <linux/module.h>
14 #include <linux/list.h>
19 #include <linux/slab.h>
21 #define ERROR(fmt, args...) printk(KERN_ERR "block2mtd: " fmt "\n" , ## args)
22 #define INFO(fmt, args...) printk(KERN_INFO "block2mtd: " fmt "\n" , ## args)
40 return read_mapping_page(mapping, index,
NULL);
44 static int _block2mtd_erase(
struct block2mtd_dev *
dev, loff_t to,
size_t len)
54 page = page_read(mapping, index);
78 size_t len = instr->
len;
83 err = _block2mtd_erase(dev, from, len);
86 ERROR(
"erase failed err = %d", err);
96 static int block2mtd_read(
struct mtd_info *mtd, loff_t from,
size_t len,
112 page = page_read(dev->
blkdev->bd_inode->i_mapping, index);
114 return PTR_ERR(page);
131 loff_t to,
size_t len,
size_t *retlen)
146 page = page_read(mapping, index);
148 return PTR_ERR(page);
169 static int block2mtd_write(
struct mtd_info *mtd, loff_t to,
size_t len,
170 size_t *retlen,
const u_char *buf)
176 err = _block2mtd_write(dev, buf, to, len, retlen);
185 static void block2mtd_sync(
struct mtd_info *mtd)
211 static struct block2mtd_dev *add_device(
char *devname,
int erase_size)
240 ERROR(
"error: cannot open device %s", devname);
246 ERROR(
"attempting to use an MTD device as a block device");
261 dev->
mtd.erasesize = erase_size;
262 dev->
mtd.writesize = 1;
266 dev->
mtd._erase = block2mtd_erase;
267 dev->
mtd._write = block2mtd_write;
268 dev->
mtd._sync = block2mtd_sync;
269 dev->
mtd._read = block2mtd_read;
277 list_add(&dev->
list, &blkmtd_device_list);
278 INFO(
"mtd%d: [%s] erase_size = %dKiB [%d]", dev->
mtd.index,
280 dev->
mtd.erasesize >> 10, dev->
mtd.erasesize);
284 block2mtd_free_device(dev);
295 static int ustrtoul(
const char *
cp,
char **endp,
unsigned int base)
307 if ((*endp)[1] ==
'i') {
308 if ((*endp)[2] ==
'B')
318 static int parse_num(
size_t *num,
const char *
token)
323 n = (
size_t) ustrtoul(token, &endp, 0);
332 static inline void kill_final_newline(
char *
str)
334 char *newline =
strrchr(str,
'\n');
335 if (newline && !newline[1])
340 #define parse_err(fmt, args...) do { \
341 ERROR(fmt, ## args); \
346 static int block2mtd_init_called = 0;
347 static char block2mtd_paramline[80 + 12];
351 static int block2mtd_setup2(
const char *
val)
360 if (
strnlen(val,
sizeof(buf)) >=
sizeof(buf))
364 kill_final_newline(str);
366 for (i = 0; i < 2; i++)
367 token[i] =
strsep(&str,
",");
376 if (
strlen(name) + 1 > 80)
380 ret = parse_num(&erase_size, token[1]);
386 add_device(name, erase_size);
395 return block2mtd_setup2(val);
402 if (block2mtd_init_called)
403 return block2mtd_setup2(val);
412 strlcpy(block2mtd_paramline, val,
sizeof(block2mtd_paramline));
420 MODULE_PARM_DESC(block2mtd,
"Device to use. \"block2mtd=<dev>[,<erasesize>]\"");
422 static int __init block2mtd_init(
void)
427 if (
strlen(block2mtd_paramline))
428 ret = block2mtd_setup2(block2mtd_paramline);
429 block2mtd_init_called = 1;
436 static void __devexit block2mtd_exit(
void)
443 block2mtd_sync(&dev->
mtd);
445 INFO(
"mtd%d: [%s] removed", dev->
mtd.index,
448 block2mtd_free_device(dev);