--- a/drivers/mtd/devices/block2mtd.c +++ b/drivers/mtd/devices/block2mtd.c @@ -10,6 +10,7 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include +#include #include #include #include @@ -210,13 +211,16 @@ static void block2mtd_free_device(struct } -static struct block2mtd_dev *add_device(char *devname, int erase_size, const char *mtdname) +static struct block2mtd_dev *add_device(char *devname, int erase_size, const char *mtdname, int timeout) { const fmode_t mode = FMODE_READ | FMODE_WRITE | FMODE_EXCL; - struct block_device *bdev; + struct block_device *bdev = ERR_PTR(-ENODEV); struct block2mtd_dev *dev; struct mtd_partition *part; char *name; +#ifndef MODULE + int i; +#endif if (!devname) return NULL; @@ -227,15 +231,20 @@ static struct block2mtd_dev *add_device( /* Get a handle on the device */ bdev = blkdev_get_by_path(devname, mode, dev); + #ifndef MODULE - if (IS_ERR(bdev)) { + for (i = 0; IS_ERR(bdev) && i <= timeout; i++) { + dev_t devt; - /* We might not have rootfs mounted at this point. Try - to resolve the device name by other means. */ + if (i) + msleep(1000); + wait_for_device_probe(); + + devt = name_to_dev_t(devname); + if (!devt) + continue; - dev_t devt = name_to_dev_t(devname); - if (devt) - bdev = blkdev_get_by_dev(devt, mode, dev); + bdev = blkdev_get_by_dev(devt, mode, dev); } #endif @@ -361,11 +370,12 @@ static char block2mtd_paramline[80 + 12] static int block2mtd_setup2(const char *val) { - char buf[80 + 12 + 80]; /* 80 for device, 12 for erase size, 80 for name */ + char buf[80 + 12 + 80 + 8]; /* 80 for device, 12 for erase size, 80 for name, 8 for timeout */ char *str = buf; - char *token[3]; + char *token[4]; char *name; size_t erase_size = PAGE_SIZE; + unsigned long timeout = 0; int i, ret; if (strnlen(val, sizeof(buf)) >= sizeof(buf)) { @@ -376,7 +386,7 @@ static int block2mtd_setup2(const char * strcpy(str, val); kill_final_newline(str); - for (i = 0; i < 3; i++) + for (i = 0; i < 4; i++) token[i] = strsep(&str, ","); if (str) { @@ -405,7 +415,10 @@ static int block2mtd_setup2(const char * if (token[2] && (strlen(token[2]) + 1 > 80)) pr_err("mtd device name too long\n"); - add_device(name, erase_size, token[2]); + if (token[3] && kstrtoul(token[3], 0, &timeout)) + pr_err("invalid timeout\n"); + + add_device(name, erase_size, token[2], timeout); return 0; } @@ -439,7 +452,7 @@ static int block2mtd_setup(const char *v module_param_call(block2mtd, block2mtd_setup, NULL, NULL, 0200); -MODULE_PARM_DESC(block2mtd, "Device to use. \"block2mtd=[,[,]]\""); +MODULE_PARM_DESC(block2mtd, "Device to use. \"block2mtd=[,[,[,]]]\""); static int __init block2mtd_init(void) { @@ -474,7 +487,7 @@ static void block2mtd_exit(void) } -module_init(block2mtd_init); +late_initcall(block2mtd_init); module_exit(block2mtd_exit); MODULE_LICENSE("GPL");