diff options
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.patch | 218 |
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; + |