--- a/drivers/mtd/devices/block2mtd.c +++ b/drivers/mtd/devices/block2mtd.c @@ -7,6 +7,7 @@ * Licence: GPL */ #include +#include #include #include #include @@ -211,13 +212,14 @@ static void block2mtd_free_device(struct /* FIXME: ensure that mtd->size % erase_size == 0 */ -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; + int i; if (!devname) return NULL; @@ -228,15 +230,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 @@ -360,11 +367,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)) @@ -373,7 +381,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) @@ -395,7 +403,10 @@ static int block2mtd_setup2(const char * if (token[2] && (strlen(token[2]) + 1 > 80)) parse_err("mtd device name too long"); - add_device(name, erase_size, token[2]); + if (token[3] && kstrtoul(token[3], 0, &timeout)) + parse_err("invalid timeout"); + + add_device(name, erase_size, token[2], timeout); return 0; } @@ -429,7 +440,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) { @@ -462,7 +473,7 @@ static void block2mtd_exit(void) } -module_init(block2mtd_init); +late_initcall(block2mtd_init); module_exit(block2mtd_exit); MODULE_LICENSE("GPL");