x86: try harder to attach block2mtd to fix boot issues on devices with longer delays
[openwrt/svn-archive/archive.git] / target / linux / generic / patches-3.14 / 441-block2mtd_probe.patch
index 0b2e80cdac8d7ee15ce4ecbf4ad1ab26ed72ea8c..3ab9d1a3fc9c0c00389a4178cdeedbea36b25fca 100644 (file)
 --- a/drivers/mtd/devices/block2mtd.c
 +++ b/drivers/mtd/devices/block2mtd.c
-@@ -234,6 +234,7 @@ static struct block2mtd_dev *add_device(
-               /* We might not have rootfs mounted at this point. Try
-                  to resolve the device name by other means. */
+@@ -10,6 +10,7 @@
+ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  
+ #include <linux/module.h>
++#include <linux/delay.h>
+ #include <linux/fs.h>
+ #include <linux/blkdev.h>
+ #include <linux/bio.h>
+@@ -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();
-               dev_t devt = name_to_dev_t(devname);
-               if (devt)
-                       bdev = blkdev_get_by_dev(devt, mode, dev);
++
++              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
+@@ -355,11 +362,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)) {
+@@ -370,7 +378,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) {
+@@ -399,7 +407,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;
+ }
+@@ -433,7 +444,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=<dev>[,<erasesize>[,<name>]]\"");
++MODULE_PARM_DESC(block2mtd, "Device to use. \"block2mtd=<dev>[,<erasesize>[,<name>[,<timeout>]]]\"");
+ static int __init block2mtd_init(void)
+ {
+@@ -467,7 +478,7 @@ static void block2mtd_exit(void)
+ }
+-module_init(block2mtd_init);
++late_initcall(block2mtd_init);
+ module_exit(block2mtd_exit);
+ MODULE_LICENSE("GPL");