f83600f199abd49428a78e6b931f362e79761ac1
[openwrt/svn-archive/archive.git] / target / linux / lantiq / patches-3.10 / 0100-mtd-split.patch
1 Index: linux-3.10.13/arch/mips/lantiq/xway/Makefile
2 ===================================================================
3 --- linux-3.10.13.orig/arch/mips/lantiq/xway/Makefile 2013-10-01 00:07:55.165279437 +0200
4 +++ linux-3.10.13/arch/mips/lantiq/xway/Makefile 2013-10-01 00:10:24.269285811 +0200
5 @@ -1,6 +1,6 @@
6 obj-y := prom.o sysctrl.o clk.o reset.o dma.o gptu.o dcdc.o
7
8 -obj-y += vmmc.o
9 +obj-y += vmmc.o mtd_split.o
10
11 obj-$(CONFIG_PCI) += ath_eep.o rt_eep.o pci-ath-fixup.o
12
13 Index: linux-3.10.13/arch/mips/lantiq/xway/mtd_split.c
14 ===================================================================
15 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
16 +++ linux-3.10.13/arch/mips/lantiq/xway/mtd_split.c 2013-10-01 00:11:28.745288566 +0200
17 @@ -0,0 +1,129 @@
18 +#include <linux/magic.h>
19 +#include <linux/root_dev.h>
20 +#include <linux/mtd/mtd.h>
21 +#include <linux/mtd/partitions.h>
22 +
23 +#define ROOTFS_SPLIT_NAME "rootfs_data"
24 +
25 +struct squashfs_super_block {
26 + __le32 s_magic;
27 + __le32 pad0[9];
28 + __le64 bytes_used;
29 +};
30 +
31 +static void split_brnimage_kernel(struct mtd_info *master, const char *name,
32 + int offset, int size)
33 +{
34 + unsigned long buf[4];
35 + // Assume at most 2MB of kernel image
36 + unsigned long end = offset + (2 << 20);
37 + unsigned long part_size = offset + 0x400 - 12;
38 + size_t len;
39 + int ret;
40 +
41 + if (strcmp(name, "rootfs") != 0)
42 + return;
43 + while (part_size < end) {
44 + long size_min = part_size - 0x400 - 12 - offset;
45 + long size_max = part_size + 12 - offset;
46 + ret = mtd_read(master, part_size, 16, &len, (void *)buf);
47 + if (ret || len != 16)
48 + return;
49 +
50 + if (le32_to_cpu(buf[0]) < size_min ||
51 + le32_to_cpu(buf[0]) > size_max) {
52 + part_size += 0x400;
53 + continue;
54 + }
55 +
56 + if (le32_to_cpu(buf[3]) == SQUASHFS_MAGIC) {
57 + part_size += 12 - offset;
58 + __mtd_add_partition(master, "rootfs", offset + part_size,
59 + size - part_size, false);
60 + return;
61 + }
62 + part_size += 0x400;
63 + }
64 +}
65 +
66 +static void split_eva_kernel(struct mtd_info *master, const char *name,
67 + int offset, int size)
68 +{
69 +#define EVA_MAGIC 0xfeed1281
70 + unsigned long magic = 0;
71 + unsigned long part_size = 0, p;
72 + size_t len;
73 + int ret;
74 +
75 + if (strcmp(name, CONFIG_MTD_SPLIT_FIRMWARE_NAME) != 0)
76 + return;
77 +
78 + ret = mtd_read(master, offset, 4, &len, (void *)&magic);
79 + if (ret || len != sizeof(magic))
80 + return;
81 +
82 + if (le32_to_cpu(magic) != EVA_MAGIC)
83 + return;
84 +
85 + ret = mtd_read(master, offset + 4, 4, &len, (void *)&part_size);
86 + if (ret || len != sizeof(part_size))
87 + return;
88 +
89 + p = part_size = le32_to_cpu(part_size) + 0x18;
90 + p &= ~0xffff;
91 + p += 0x10000;
92 +
93 + ret = mtd_read(master, offset + p, 4, &len, (void *)&magic);
94 + if (ret || len != sizeof(magic))
95 + return;
96 +
97 + if (magic == SQUASHFS_MAGIC)
98 + part_size = p + 0x100;
99 + else
100 + part_size = mtd_pad_erasesize(master, offset, len);
101 +
102 + if (part_size + master->erasesize > size)
103 + return;
104 +
105 + __mtd_add_partition(master, "rootfs", offset + part_size,
106 + size - part_size, false);
107 +}
108 +
109 +static void split_tplink_kernel(struct mtd_info *master, const char *name,
110 + int offset, int size)
111 +{
112 +#define TPLINK_MAGIC 0x00000002
113 + unsigned long magic = 0;
114 + unsigned long part_size = 0;
115 + size_t len;
116 + int ret;
117 +
118 + if (strcmp(name, CONFIG_MTD_SPLIT_FIRMWARE_NAME) != 0)
119 + return;
120 +
121 + ret = mtd_read(master, offset, 4, &len, (void *)&magic);
122 + if (ret || len != sizeof(magic))
123 + return;
124 +
125 + if (le32_to_cpu(magic) != TPLINK_MAGIC)
126 + return;
127 +
128 + ret = mtd_read(master, offset + 0x78, 4, &len, (void *)&part_size);
129 + if (ret || len != sizeof(part_size))
130 + return;
131 +
132 + part_size = be32_to_cpu(part_size) + 0x200;
133 + if (part_size + master->erasesize > size)
134 + return;
135 +
136 + __mtd_add_partition(master, "rootfs", offset + part_size,
137 + size - part_size, false);
138 +}
139 +
140 +void arch_split_mtd_part(struct mtd_info *master, const char *name,
141 + int offset, int size)
142 +{
143 + split_tplink_kernel(master, name, offset, size);
144 + split_eva_kernel(master, name, offset, size);
145 + split_brnimage_kernel(master, name, offset, size);
146 +}
147 Index: linux-3.10.13/include/linux/mtd/partitions.h
148 ===================================================================
149 --- linux-3.10.13.orig/include/linux/mtd/partitions.h 2013-10-01 00:07:55.165279437 +0200
150 +++ linux-3.10.13/include/linux/mtd/partitions.h 2013-10-01 00:08:03.889279810 +0200
151 @@ -89,12 +89,17 @@
152 int mtd_is_partition(const struct mtd_info *mtd);
153 int mtd_add_partition(struct mtd_info *master, char *name,
154 long long offset, long long length);
155 +int __mtd_add_partition(struct mtd_info *master, char *name,
156 + long long offset, long long length, bool dup_check);
157 +
158 int mtd_del_partition(struct mtd_info *master, int partno);
159 struct mtd_info *mtdpart_get_master(const struct mtd_info *mtd);
160 uint64_t mtdpart_get_offset(const struct mtd_info *mtd);
161 uint64_t mtd_get_device_size(const struct mtd_info *mtd);
162 -extern void __weak arch_split_mtd_part(struct mtd_info *master,
163 - const char *name, int offset, int size);
164 +void __weak arch_split_mtd_part(struct mtd_info *master,
165 + const char *name, int offset, int size);
166 +unsigned long
167 +mtd_pad_erasesize(struct mtd_info *mtd, int offset, int len);
168
169 int parse_mtd_partitions_by_type(struct mtd_info *master,
170 enum mtd_parser_type type,
171 Index: linux-3.10.13/drivers/mtd/mtdpart.c
172 ===================================================================
173 --- linux-3.10.13.orig/drivers/mtd/mtdpart.c 2013-10-01 00:07:55.165279437 +0200
174 +++ linux-3.10.13/drivers/mtd/mtdpart.c 2013-10-01 00:08:03.893279810 +0200
175 @@ -616,7 +616,7 @@
176 }
177
178
179 -static int
180 +int
181 __mtd_add_partition(struct mtd_info *master, char *name,
182 long long offset, long long length, bool dup_check)
183 {
184 @@ -737,7 +737,7 @@
185 return nr_parts;
186 }
187
188 -static inline unsigned long
189 +unsigned long
190 mtd_pad_erasesize(struct mtd_info *mtd, int offset, int len)
191 {
192 unsigned long mask = mtd->erasesize - 1;
193 @@ -806,7 +806,6 @@
194 return;
195
196 len = be32_to_cpu(hdr.size) + 0x40;
197 - len = mtd_pad_erasesize(master, part->offset, len);
198 if (len + master->erasesize > part->mtd.size)
199 return;
200