summaryrefslogtreecommitdiff
path: root/target/linux/lantiq/patches-3.10/0100-mtd-split.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/lantiq/patches-3.10/0100-mtd-split.patch')
-rw-r--r--target/linux/lantiq/patches-3.10/0100-mtd-split.patch218
1 files changed, 218 insertions, 0 deletions
diff --git a/target/linux/lantiq/patches-3.10/0100-mtd-split.patch b/target/linux/lantiq/patches-3.10/0100-mtd-split.patch
new file mode 100644
index 0000000..12f6345
--- /dev/null
+++ b/target/linux/lantiq/patches-3.10/0100-mtd-split.patch
@@ -0,0 +1,218 @@
+Index: linux-3.10.12/arch/mips/lantiq/xway/Makefile
+===================================================================
+--- linux-3.10.12.orig/arch/mips/lantiq/xway/Makefile 2013-09-17 22:32:50.389021711 +0200
++++ linux-3.10.12/arch/mips/lantiq/xway/Makefile 2013-09-17 23:04:39.829103336 +0200
+@@ -1,6 +1,6 @@
+ obj-y := prom.o sysctrl.o clk.o reset.o dma.o gptu.o dcdc.o
+
+-obj-y += vmmc.o
++obj-y += vmmc.o mtd_split.o
+
+ obj-$(CONFIG_PCI) += ath_eep.o rt_eep.o pci-ath-fixup.o
+
+Index: linux-3.10.12/arch/mips/lantiq/xway/mtd_split.c
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ linux-3.10.12/arch/mips/lantiq/xway/mtd_split.c 2013-09-17 22:42:28.485046424 +0200
+@@ -0,0 +1,151 @@
++#include <linux/magic.h>
++#include <linux/root_dev.h>
++#include <linux/mtd/mtd.h>
++#include <linux/mtd/partitions.h>
++
++#define ROOTFS_SPLIT_NAME "rootfs_data"
++
++struct squashfs_super_block {
++ __le32 s_magic;
++ __le32 pad0[9];
++ __le64 bytes_used;
++};
++
++static void split_brnimage_kernel(struct mtd_info *master, const char *name,
++ int offset, int size)
++{
++ unsigned long buf[4];
++ // Assume at most 2MB of kernel image
++ unsigned long end = offset + (2 << 20);
++ unsigned long part_size = offset + 0x400 - 12;
++ size_t len;
++ int ret;
++
++ if (strcmp(name, "rootfs") != 0)
++ return;
++ while (part_size < end) {
++ long size_min = part_size - 0x400 - 12 - offset;
++ long size_max = part_size + 12 - offset;
++ ret = mtd_read(master, part_size, 16, &len, (void *)buf);
++ if (ret || len != 16)
++ return;
++
++ if (le32_to_cpu(buf[0]) < size_min ||
++ le32_to_cpu(buf[0]) > size_max) {
++ part_size += 0x400;
++ continue;
++ }
++
++ if (le32_to_cpu(buf[3]) == SQUASHFS_MAGIC) {
++ part_size += 12 - offset;
++ __mtd_add_partition(master, "rootfs", offset + part_size,
++ size - part_size, false);
++ return;
++ }
++ part_size += 0x400;
++ }
++}
++
++static void split_eva_kernel(struct mtd_info *master, const char *name,
++ int offset, int size)
++{
++#define EVA_MAGIC 0xfeed1281
++ unsigned long magic = 0;
++ unsigned long part_size = 0;
++ size_t len;
++ int ret;
++
++ if (strcmp(name, CONFIG_MTD_SPLIT_FIRMWARE_NAME) != 0)
++ return;
++
++ ret = mtd_read(master, offset, 4, &len, (void *)&magic);
++ if (ret || len != sizeof(magic))
++ return;
++
++ if (le32_to_cpu(magic) != EVA_MAGIC)
++ return;
++
++ ret = mtd_read(master, offset + 4, 4, &len, (void *)&part_size);
++ if (ret || len != sizeof(part_size))
++ return;
++
++ part_size = le32_to_cpu(part_size) + 0x18;
++ part_size = mtd_pad_erasesize(master, offset, len);
++ if (part_size + master->erasesize > size)
++ return;
++
++ __mtd_add_partition(master, "rootfs", offset + part_size,
++ size - part_size, false);
++}
++
++static void split_tplink_kernel(struct mtd_info *master, const char *name,
++ int offset, int size)
++{
++#define TPLINK_MAGIC 0x00000002
++ unsigned long magic = 0;
++ unsigned long part_size = 0;
++ size_t len;
++ int ret;
++
++ if (strcmp(name, CONFIG_MTD_SPLIT_FIRMWARE_NAME) != 0)
++ return;
++
++ ret = mtd_read(master, offset, 4, &len, (void *)&magic);
++ if (ret || len != sizeof(magic))
++ return;
++
++ if (le32_to_cpu(magic) != TPLINK_MAGIC)
++ return;
++
++ ret = mtd_read(master, offset + 0x78, 4, &len, (void *)&part_size);
++ if (ret || len != sizeof(part_size))
++ return;
++
++ part_size = be32_to_cpu(part_size) + 0x200;
++ if (part_size + master->erasesize > size)
++ return;
++
++ __mtd_add_partition(master, "rootfs", offset + part_size,
++ size - part_size, false);
++}
++
++static void split_squashfs(struct mtd_info *master, const char *name,
++ int offset, int size)
++{
++ struct squashfs_super_block sb;
++ int len, ret;
++
++ offset += 0x100;
++ size -= 0x100;
++
++ ret = mtd_read(master, offset, sizeof(sb), &len, (void *) &sb);
++ if (ret || (len != sizeof(sb)))
++ return;
++
++ if (SQUASHFS_MAGIC != le32_to_cpu(sb.s_magic) )
++ return;
++
++ if (le64_to_cpu((sb.bytes_used)) <= 0)
++ printk(KERN_ALERT "split_squashfs: squashfs is empty in \"%s\"\n",
++ master->name);
++ return;
++
++ len = (u32) le64_to_cpu(sb.bytes_used);
++ len = mtd_pad_erasesize(master, offset, len);
++ offset += len;
++ size -= len ;
++ printk(KERN_INFO "mtd: partition \"%s\" created automatically, ofs=0x%x, len=0x%x\n",
++ ROOTFS_SPLIT_NAME, offset, size);
++
++ __mtd_add_partition(master, ROOTFS_SPLIT_NAME, offset,
++ size, false);
++}
++
++void arch_split_mtd_part(struct mtd_info *master, const char *name,
++ int offset, int size)
++{
++ split_tplink_kernel(master, name, offset, size);
++ split_eva_kernel(master, name, offset, size);
++ split_brnimage_kernel(master, name, offset, size);
++ split_squashfs(master, name, offset, size);
++}
+Index: linux-3.10.12/include/linux/mtd/partitions.h
+===================================================================
+--- linux-3.10.12.orig/include/linux/mtd/partitions.h 2013-09-17 22:32:46.925021563 +0200
++++ linux-3.10.12/include/linux/mtd/partitions.h 2013-09-17 22:32:51.049021740 +0200
+@@ -82,9 +82,14 @@
+ int mtd_is_partition(const struct mtd_info *mtd);
+ int mtd_add_partition(struct mtd_info *master, char *name,
+ long long offset, long long length);
++int __mtd_add_partition(struct mtd_info *master, char *name,
++ long long offset, long long length, bool dup_check);
++
+ int mtd_del_partition(struct mtd_info *master, int partno);
+ uint64_t mtd_get_device_size(const struct mtd_info *mtd);
+-extern void __weak arch_split_mtd_part(struct mtd_info *master,
++void __weak arch_split_mtd_part(struct mtd_info *master,
+ const char *name, int offset, int size);
++unsigned long
++mtd_pad_erasesize(struct mtd_info *mtd, int offset, int len);
+
+ #endif
+Index: linux-3.10.12/drivers/mtd/mtdpart.c
+===================================================================
+--- linux-3.10.12.orig/drivers/mtd/mtdpart.c 2013-09-17 22:32:46.973021565 +0200
++++ linux-3.10.12/drivers/mtd/mtdpart.c 2013-09-17 22:32:51.049021740 +0200
+@@ -617,7 +617,7 @@
+ }
+
+
+-static int
++int
+ __mtd_add_partition(struct mtd_info *master, char *name,
+ long long offset, long long length, bool dup_check)
+ {
+@@ -707,7 +707,7 @@
+ }
+ EXPORT_SYMBOL_GPL(mtd_del_partition);
+
+-static inline unsigned long
++unsigned long
+ mtd_pad_erasesize(struct mtd_info *mtd, int offset, int len)
+ {
+ unsigned long mask = mtd->erasesize - 1;
+@@ -799,7 +799,6 @@
+ return;
+
+ len = be32_to_cpu(hdr.size) + 0x40;
+- len = mtd_pad_erasesize(master, part->offset, len);
+ if (len + master->erasesize > part->mtd.size)
+ return;
+