It is needed for creating emulated devices suitable for using in UBI layer and with UBIFS.
Signed-off-by: Pali Rohár <[email protected]> --- drivers/mtd/devices/block2mtd.c | 55 ++++++++++++++++++++++++++++++--------- 1 file changed, 42 insertions(+), 13 deletions(-) diff --git a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c index ee47cdd..5ba5fad 100644 --- a/drivers/mtd/devices/block2mtd.c +++ b/drivers/mtd/devices/block2mtd.c @@ -3,6 +3,7 @@ * * Copyright (C) 2001,2002 Simon Evans <[email protected]> * Copyright (C) 2004-2006 Joern Engel <[email protected]> + * Copyright (C) 2012-2017 Pali Rohár <[email protected]> * * Licence: GPL */ @@ -218,8 +219,8 @@ static void block2mtd_free_device(struct block2mtd_dev *dev) } -static struct block2mtd_dev *add_device(char *devname, int erase_size, - int timeout) +static struct block2mtd_dev *add_device(char *devname, uint32_t erase_size, + uint32_t write_size, int subpage_sft, int timeout) { #ifndef MODULE int i; @@ -279,6 +280,11 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size, goto err_free_block2mtd; } + if ((long)dev->blkdev->bd_inode->i_size % write_size) { + pr_err("writesize must be divisor of device size\n"); + goto err_free_block2mtd; + } + mutex_init(&dev->write_mutex); /* Setup the MTD structure */ @@ -291,7 +297,8 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size, dev->mtd.size = dev->blkdev->bd_inode->i_size & PAGE_MASK; dev->mtd.erasesize = erase_size; - dev->mtd.writesize = 1; + dev->mtd.writesize = write_size; + dev->mtd.subpage_sft = subpage_sft; dev->mtd.writebufsize = PAGE_SIZE; dev->mtd.type = MTD_RAM; dev->mtd.flags = MTD_CAP_RAM; @@ -308,10 +315,12 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size, } list_add(&dev->list, &blkmtd_device_list); - pr_info("mtd%d: [%s] erase_size = %dKiB [%d]\n", + pr_info("mtd%d: [%s] erase_size = %dKiB [%d], write_size = %dKiB [%d], subpage_sft = %d\n", dev->mtd.index, dev->mtd.name + strlen("block2mtd: "), - dev->mtd.erasesize >> 10, dev->mtd.erasesize); + dev->mtd.erasesize >> 10, dev->mtd.erasesize, + dev->mtd.writesize >> 10, dev->mtd.writesize, + dev->mtd.subpage_sft); return dev; err_destroy_mutex: @@ -375,18 +384,20 @@ static inline void kill_final_newline(char *str) #ifndef MODULE static int block2mtd_init_called = 0; -/* 80 for device, 12 for erase size */ -static char block2mtd_paramline[80 + 12]; +/* 80 for device, 12 for erase size, 12 for write size, 3 for subpage_sft */ +static char block2mtd_paramline[80 + 12 + 12 + 3]; #endif static int block2mtd_setup2(const char *val) { - /* 80 for device, 12 for erase size, 80 for name, 8 for timeout */ - char buf[80 + 12 + 80 + 8]; + /* 80 for name, 80 for device, 12 for erase size, 12 for write size, 3 for subpage_sft */ + char buf[80 + 12 + 80 + 12 + 3]; char *str = buf; - char *token[2]; + char *token[4]; char *name; size_t erase_size = PAGE_SIZE; + size_t write_size = 1; + size_t subpage_sft = 0; unsigned long timeout = MTD_DEFAULT_TIMEOUT; int i, ret; @@ -398,7 +409,7 @@ static int block2mtd_setup2(const char *val) strcpy(str, val); kill_final_newline(str); - for (i = 0; i < 2; i++) + for (i = 0; i < 4; i++) token[i] = strsep(&str, ","); if (str) { @@ -425,7 +436,23 @@ static int block2mtd_setup2(const char *val) } } - add_device(name, erase_size, timeout); + if (token[2]) { + ret = parse_num(&write_size, token[2]); + if (ret || write_size > U32_MAX) { + pr_err("illegal write size"); + return 0; + } + } + + if (token[3]) { + ret = parse_num(&subpage_sft, token[3]); + if (ret || subpage_sft > INT_MAX) { + pr_err("illegal subpage_sft"); + return 0; + } + } + + add_device(name, erase_size, write_size, subpage_sft, timeout); return 0; } @@ -459,7 +486,9 @@ static int block2mtd_setup(const char *val, struct kernel_param *kp) module_param_call(block2mtd, block2mtd_setup, NULL, NULL, 0200); -MODULE_PARM_DESC(block2mtd, "Device to use. \"block2mtd=<dev>[,<erasesize>]\""); +MODULE_PARM_DESC(block2mtd, "Block device, erase size (default page size), " + "write size (default 1), nand subpage shift (default 0) " + "\"block2mtd=<dev>[,<erasesize>[,<writesize>[,<subpage_sft>]]]\""); static int __init block2mtd_init(void) { -- 1.7.9.5

