ssb: Workaround: Need subsys_initcall to be able to register a PCI bus.
[openwrt.git] / target / linux / generic-2.6 / patches / 060-rootfs_split.patch
index e2e52f6..adafdaa 100644 (file)
@@ -1,21 +1,28 @@
-diff -ur linux.old/drivers/mtd/Kconfig linux.dev/drivers/mtd/Kconfig
---- linux.old/drivers/mtd/Kconfig      2007-01-10 20:10:37.000000000 +0100
-+++ linux.dev/drivers/mtd/Kconfig      2007-02-19 23:00:53.739457000 +0100
-@@ -49,6 +49,11 @@
+Index: linux/drivers/mtd/Kconfig
+===================================================================
+--- linux.orig/drivers/mtd/Kconfig
++++ linux/drivers/mtd/Kconfig
+@@ -49,6 +49,16 @@ config MTD_PARTITIONS
          devices. Partitioning on NFTL 'devices' is a different - that's the
          'normal' form of partitioning used on a block device.
  
-+config MTD_SPLIT_ROOTFS
-+      bool "Automatically split rootfs partition for squashfs"
++config MTD_ROOTFS_ROOT_DEV
++      bool "Automatically set 'rootfs' partition to be root filesystem"
++      depends on MTD_PARTITIONS
++      default y
++
++config MTD_ROOTFS_SPLIT
++      bool "Automatically split 'rootfs' partition for squashfs"
 +      depends on MTD_PARTITIONS
 +      default y
 +
  config MTD_REDBOOT_PARTS
        tristate "RedBoot partition table parsing"
        depends on MTD_PARTITIONS
-diff -ur linux.old/drivers/mtd/mtdpart.c linux.dev/drivers/mtd/mtdpart.c
---- linux.old/drivers/mtd/mtdpart.c    2007-01-10 20:10:37.000000000 +0100
-+++ linux.dev/drivers/mtd/mtdpart.c    2007-02-20 00:01:38.587355896 +0100
+Index: linux/drivers/mtd/mtdpart.c
+===================================================================
+--- linux.orig/drivers/mtd/mtdpart.c
++++ linux/drivers/mtd/mtdpart.c
 @@ -20,6 +20,8 @@
  #include <linux/mtd/mtd.h>
  #include <linux/mtd/partitions.h>
@@ -25,24 +32,24 @@ diff -ur linux.old/drivers/mtd/mtdpart.c linux.dev/drivers/mtd/mtdpart.c
  
  /* Our partition linked list */
  static LIST_HEAD(mtd_partitions);
-@@ -303,6 +305,173 @@
+@@ -308,6 +310,266 @@ int del_mtd_partitions(struct mtd_info *
        return 0;
  }
  
 +static u_int32_t cur_offset = 0;
-+static int add_mtd_partition(struct mtd_info *master, const struct mtd_partition *part, int i)
++static int add_one_partition(struct mtd_info *master, const struct mtd_partition *part,
++              int i, struct mtd_part **slp)
 +{
 +      struct mtd_part *slave;
-+      
++
 +      /* allocate the partition structure */
-+      slave = kmalloc (sizeof(*slave), GFP_KERNEL);
++      slave = kzalloc (sizeof(*slave), GFP_KERNEL);
 +      if (!slave) {
 +              printk ("memory allocation error while creating partitions for \"%s\"\n",
 +                      master->name);
 +              del_mtd_partitions(master);
 +              return -ENOMEM;
 +      }
-+      memset(slave, 0, sizeof(*slave));
 +      list_add(&slave->list, &mtd_partitions);
 +
 +      /* set up the MTD object for this partition */
@@ -51,8 +58,8 @@ diff -ur linux.old/drivers/mtd/mtdpart.c linux.dev/drivers/mtd/mtdpart.c
 +      slave->mtd.size = part->size;
 +      slave->mtd.writesize = master->writesize;
 +      slave->mtd.oobsize = master->oobsize;
-+      slave->mtd.ecctype = master->ecctype;
-+      slave->mtd.eccsize = master->eccsize;
++      slave->mtd.oobavail = master->oobavail;
++      slave->mtd.subpage_sft = master->subpage_sft;
 +
 +      slave->mtd.name = part->name;
 +      slave->mtd.bank_size = master->bank_size;
@@ -193,71 +200,126 @@ diff -ur linux.old/drivers/mtd/mtdpart.c linux.dev/drivers/mtd/mtdpart.c
 +              slave->registered = 1;
 +      }
 +
++      if (slp)
++              *slp = slave;
++
 +      return 0;
 +}
++
++#ifdef CONFIG_MTD_ROOTFS_SPLIT
++#define ROOTFS_SPLIT_NAME "rootfs_data"
++static int split_squashfs(struct mtd_info *master, struct mtd_partition *old,
++              struct mtd_partition **new)
++{
++      struct mtd_partition *part = NULL;
++      int len;
++      char buf[512];
++      struct squashfs_super_block *sb = (struct squashfs_super_block *) buf;
++      int ret;
++
++      ret = master->read(master, old->offset, sizeof(*sb), &len, buf);
++      if (ret) {
++              printk(KERN_ALERT "split_squashfs: error occured while reading "
++                      "from \"%s\"\n", master->name);
++              goto out;
++      }
++
++      if (len != sizeof(*sb)) {
++              printk(KERN_ALERT "split_squashfs: unable to read superblock "
++                      "from \"%s\"\n", master->name);
++              ret=-1;
++              goto out;
++      }
++
++      if (*((u32 *) buf) != SQUASHFS_MAGIC) {
++              printk(KERN_ALERT "split_squasfs: no squashfs found in \"%s\"\n",
++                      master->name);
++              ret=0;
++              goto out;
++      }
++
++      if (sb->bytes_used <= 0) {
++              printk(KERN_ALERT "split_squashfs: squashfs is empty in \"%s\"\n",
++                      master->name);
++              ret=0;
++              goto out;
++      }
++
++      part = kmalloc(sizeof(*part)+sizeof(ROOTFS_SPLIT_NAME)+1, GFP_KERNEL);
++      if (part == NULL) {
++              printk(KERN_INFO "split_squashfs: no memory for partition \"%s\"\n",
++                      ROOTFS_SPLIT_NAME);
++              ret = -ENOMEM;
++              goto out;
++      }
++
++      memcpy(part, old, sizeof(*part));
++      part->name = (unsigned char *)&part[1];
++      strcpy(part->name, ROOTFS_SPLIT_NAME);
++
++      len = (u32) sb->bytes_used;
++      len += (part->offset & 0x000fffff);
++      len +=  (master->erasesize - 1);
++      len &= ~(master->erasesize - 1);
++      len -= (part->offset & 0x000fffff);
++      part->offset += len;
++      part->size -= len;
++
++      ret = 0;
++
++out:
++      *new = part;
++      return ret;
++}
++
++static int split_rootfs_data(struct mtd_info *master, struct mtd_partition *part,
++              int index)
++{
++      struct mtd_partition *dpart;
++      int ret;
++
++      ret = split_squashfs(master, part, &dpart);
++      if (ret)
++              return ret;
++
++      if (dpart == NULL)
++              return 1;
++
++      printk(KERN_INFO "mtd: partition \"%s\" created automatically, ofs=%X, len=%X \n",
++              ROOTFS_SPLIT_NAME, dpart->offset, dpart->size);
++
++      ret = add_one_partition(master, dpart, index, NULL);
++      if (ret)
++              kfree(dpart);
++
++      return ret;
++}
++#endif /* CONFIG_MTD_ROOTFS_SPLIT */
 +
  /*
   * This function, given a master MTD object and a partition table, creates
   * and registers slave MTD objects which are bound to the master according to
-@@ -314,171 +483,53 @@
-                      const struct mtd_partition *parts,
+@@ -320,169 +582,31 @@ int add_mtd_partitions(struct mtd_info *
                       int nbparts)
  {
--      struct mtd_part *slave;
+       struct mtd_part *slave;
 -      u_int32_t cur_offset = 0;
 -      int i;
 +      struct mtd_partition *part;
-+      int i, ret = 0;
++      int i, j, ret = 0;
  
        printk (KERN_NOTICE "Creating %d MTD partitions on \"%s\":\n", nbparts, master->name);
  
-       for (i = 0; i < nbparts; i++) {
-+              part = (struct mtd_partition *) &parts[i];
-+              ret = add_mtd_partition(master, part, i);
-+              if (ret)
-+                      return ret;
-+              if (strcmp(part->name, "rootfs") == 0) {
-+#ifdef CONFIG_MTD_SPLIT_ROOTFS
-+                      int len;
-+                      char buf[512];
-+                      struct squashfs_super_block *sb = (struct squashfs_super_block *) buf;
-+#define ROOTFS_SPLIT_NAME "rootfs_data"
-+                      if ((master->read(master, part->offset, sizeof(struct squashfs_super_block), &len, buf) == 0) &&
-+                                      (len == sizeof(struct squashfs_super_block)) &&
-+                                      (*((u32 *) buf) == SQUASHFS_MAGIC) &&
-+                                      (sb->bytes_used > 0)) {
-+
-+                              
-+                              part = kmalloc(sizeof(struct mtd_partition), GFP_KERNEL);
-+                              memcpy(part, &parts[i], sizeof(struct mtd_partition));
-+                              
-+                              part->name = kmalloc(sizeof(ROOTFS_SPLIT_NAME) + 1, GFP_KERNEL);
-+                              strcpy(part->name, ROOTFS_SPLIT_NAME);
-+
-+                              len = (u32) sb->bytes_used;
-+                              len += (part->offset & 0x000fffff);
-+                              len +=  (master->erasesize - 1);
-+                              len &= ~(master->erasesize - 1);
-+                              len -= (part->offset & 0x000fffff);
-+                              part->offset += len;
-+                              part->size -= len;
-+                      
-+                              if (len + master->erasesize < part->size)
-+                                      ret = add_mtd_partition(master, part, i + 1);
-+                              else
-+                                      kfree(part->name);
-+                              if (ret)
-+                                      return ret;
+-      for (i = 0; i < nbparts; i++) {
+-
 -              /* allocate the partition structure */
--              slave = kmalloc (sizeof(*slave), GFP_KERNEL);
+-              slave = kzalloc (sizeof(*slave), GFP_KERNEL);
 -              if (!slave) {
 -                      printk ("memory allocation error while creating partitions for \"%s\"\n",
 -                              master->name);
 -                      del_mtd_partitions(master);
 -                      return -ENOMEM;
 -              }
--              memset(slave, 0, sizeof(*slave));
 -              list_add(&slave->list, &mtd_partitions);
 -
 -              /* set up the MTD object for this partition */
@@ -266,8 +328,8 @@ diff -ur linux.old/drivers/mtd/mtdpart.c linux.dev/drivers/mtd/mtdpart.c
 -              slave->mtd.size = parts[i].size;
 -              slave->mtd.writesize = master->writesize;
 -              slave->mtd.oobsize = master->oobsize;
--              slave->mtd.ecctype = master->ecctype;
--              slave->mtd.eccsize = master->eccsize;
+-              slave->mtd.oobavail = master->oobavail;
+-              slave->mtd.subpage_sft = master->subpage_sft;
 -
 -              slave->mtd.name = parts[i].name;
 -              slave->mtd.bank_size = master->bank_size;
@@ -328,8 +390,7 @@ diff -ur linux.old/drivers/mtd/mtdpart.c linux.dev/drivers/mtd/mtdpart.c
 -                              printk(KERN_NOTICE "Moving partition %d: "
 -                                     "0x%08x -> 0x%08x\n", i,
 -                                     cur_offset, slave->offset);
-+                              kfree(part);
-                       }
+-                      }
 -              }
 -              if (slave->mtd.size == MTDPART_SIZ_FULL)
 -                      slave->mtd.size = master->size - slave->offset;
@@ -394,7 +455,20 @@ diff -ur linux.old/drivers/mtd/mtdpart.c linux.dev/drivers/mtd/mtdpart.c
 -                                                      offs + slave->offset))
 -                                      slave->mtd.ecc_stats.badblocks++;
 -                              offs += slave->mtd.erasesize;
--                      }
++      for (i = 0, j = 0; i < nbparts; i++) {
++              part = (struct mtd_partition *) &parts[i];
++              ret = add_one_partition(master, part, j, &slave);
++              if (ret)
++                      return ret;
++              j++;
++
++              if (strcmp(part->name, "rootfs") == 0 && slave->registered) {
++#ifdef CONFIG_MTD_ROOTFS_ROOT_DEV
++                      if (ROOT_DEV == 0) {
++                              printk(KERN_NOTICE "mtd: partition \"rootfs\" "
++                                      "set to be root filesystem\n");
++                              ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, slave->mtd.index);
+                       }
 -              }
 -
 -              if(parts[i].mtdp)
@@ -407,8 +481,12 @@ diff -ur linux.old/drivers/mtd/mtdpart.c linux.dev/drivers/mtd/mtdpart.c
 -                      /* register our partition */
 -                      add_mtd_device(&slave->mtd);
 -                      slave->registered = 1;
-+#endif /* CONFIG_MTD_SPLIT_ROOTFS */
-+                      ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, i);
++#endif
++#ifdef CONFIG_MTD_ROOTFS_SPLIT
++                      ret = split_rootfs_data(master, part, j);
++                      if (ret == 0)
++                              j++;
++#endif
                }
        }
  
This page took 0.031304 seconds and 4 git commands to generate.