OpenWrt – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | --- a/drivers/mtd/mtdpart.c |
2 | +++ b/drivers/mtd/mtdpart.c |
||
3 | @@ -30,11 +30,9 @@ |
||
4 | #include <linux/mtd/mtd.h> |
||
5 | #include <linux/mtd/partitions.h> |
||
6 | #include <linux/of.h> |
||
7 | -#include <linux/magic.h> |
||
8 | #include <linux/err.h> |
||
9 | |||
10 | #include "mtdcore.h" |
||
11 | -#include "mtdsplit/mtdsplit.h" |
||
12 | |||
13 | #define MTD_ERASE_PARTIAL 0x8000 /* partition only covers parts of an erase block */ |
||
14 | |||
15 | @@ -50,14 +48,13 @@ struct mtd_part { |
||
16 | struct list_head list; |
||
17 | }; |
||
18 | |||
19 | -static void mtd_partition_split(struct mtd_info *master, struct mtd_part *part); |
||
20 | - |
||
21 | /* |
||
22 | * Given a pointer to the MTD object in the mtd_part structure, we can retrieve |
||
23 | * the pointer to that structure with this macro. |
||
24 | */ |
||
25 | #define PART(x) ((struct mtd_part *)(x)) |
||
26 | |||
27 | + |
||
28 | /* |
||
29 | * MTD methods which simply translate the effective address and pass through |
||
30 | * to the _real_ device. |
||
31 | @@ -521,12 +518,14 @@ static struct mtd_part *allocate_partiti |
||
32 | if (slave->offset == MTDPART_OFS_APPEND) |
||
33 | slave->offset = cur_offset; |
||
34 | if (slave->offset == MTDPART_OFS_NXTBLK) { |
||
35 | - /* Round up to next erasesize */ |
||
36 | - slave->offset = mtd_roundup_to_eb(cur_offset, master); |
||
37 | - if (slave->offset != cur_offset) |
||
38 | + slave->offset = cur_offset; |
||
39 | + if (mtd_mod_by_eb(cur_offset, master) != 0) { |
||
40 | + /* Round up to next erasesize */ |
||
41 | + slave->offset = (mtd_div_by_eb(cur_offset, master) + 1) * master->erasesize; |
||
42 | printk(KERN_NOTICE "Moving partition %d: " |
||
43 | "0x%012llx -> 0x%012llx\n", partno, |
||
44 | (unsigned long long)cur_offset, (unsigned long long)slave->offset); |
||
45 | + } |
||
46 | } |
||
47 | if (slave->offset == MTDPART_OFS_RETAIN) { |
||
48 | slave->offset = cur_offset; |
||
49 | @@ -627,10 +626,8 @@ out_register: |
||
50 | return slave; |
||
51 | } |
||
52 | |||
53 | - |
||
54 | -static int |
||
55 | -__mtd_add_partition(struct mtd_info *master, const char *name, |
||
56 | - long long offset, long long length, bool dup_check) |
||
57 | +int mtd_add_partition(struct mtd_info *master, const char *name, |
||
58 | + long long offset, long long length) |
||
59 | { |
||
60 | struct mtd_partition part; |
||
61 | struct mtd_part *p, *new; |
||
62 | @@ -662,24 +659,21 @@ __mtd_add_partition(struct mtd_info *mas |
||
63 | end = offset + length; |
||
64 | |||
65 | mutex_lock(&mtd_partitions_mutex); |
||
66 | - if (dup_check) { |
||
67 | - list_for_each_entry(p, &mtd_partitions, list) |
||
68 | - if (p->master == master) { |
||
69 | - if ((start >= p->offset) && |
||
70 | - (start < (p->offset + p->mtd.size))) |
||
71 | - goto err_inv; |
||
72 | - |
||
73 | - if ((end >= p->offset) && |
||
74 | - (end < (p->offset + p->mtd.size))) |
||
75 | - goto err_inv; |
||
76 | - } |
||
77 | - } |
||
78 | + list_for_each_entry(p, &mtd_partitions, list) |
||
79 | + if (p->master == master) { |
||
80 | + if ((start >= p->offset) && |
||
81 | + (start < (p->offset + p->mtd.size))) |
||
82 | + goto err_inv; |
||
83 | + |
||
84 | + if ((end >= p->offset) && |
||
85 | + (end < (p->offset + p->mtd.size))) |
||
86 | + goto err_inv; |
||
87 | + } |
||
88 | |||
89 | list_add(&new->list, &mtd_partitions); |
||
90 | mutex_unlock(&mtd_partitions_mutex); |
||
91 | |||
92 | add_mtd_device(&new->mtd); |
||
93 | - mtd_partition_split(master, new); |
||
94 | |||
95 | return ret; |
||
96 | err_inv: |
||
97 | @@ -689,12 +683,6 @@ err_inv: |
||
98 | } |
||
99 | EXPORT_SYMBOL_GPL(mtd_add_partition); |
||
100 | |||
101 | -int mtd_add_partition(struct mtd_info *master, const char *name, |
||
102 | - long long offset, long long length) |
||
103 | -{ |
||
104 | - return __mtd_add_partition(master, name, offset, length, true); |
||
105 | -} |
||
106 | - |
||
107 | int mtd_del_partition(struct mtd_info *master, int partno) |
||
108 | { |
||
109 | struct mtd_part *slave, *next; |
||
110 | @@ -718,166 +706,6 @@ int mtd_del_partition(struct mtd_info *m |
||
111 | } |
||
112 | EXPORT_SYMBOL_GPL(mtd_del_partition); |
||
113 | |||
114 | -static int |
||
115 | -run_parsers_by_type(struct mtd_part *slave, enum mtd_parser_type type) |
||
116 | -{ |
||
117 | - struct mtd_partition *parts; |
||
118 | - int nr_parts; |
||
119 | - int i; |
||
120 | - |
||
121 | - nr_parts = parse_mtd_partitions_by_type(&slave->mtd, type, &parts, |
||
122 | - NULL); |
||
123 | - if (nr_parts <= 0) |
||
124 | - return nr_parts; |
||
125 | - |
||
126 | - if (WARN_ON(!parts)) |
||
127 | - return 0; |
||
128 | - |
||
129 | - for (i = 0; i < nr_parts; i++) { |
||
130 | - /* adjust partition offsets */ |
||
131 | - parts[i].offset += slave->offset; |
||
132 | - |
||
133 | - __mtd_add_partition(slave->master, |
||
134 | - parts[i].name, |
||
135 | - parts[i].offset, |
||
136 | - parts[i].size, |
||
137 | - false); |
||
138 | - } |
||
139 | - |
||
140 | - kfree(parts); |
||
141 | - |
||
142 | - return nr_parts; |
||
143 | -} |
||
144 | - |
||
145 | -static inline unsigned long |
||
146 | -mtd_pad_erasesize(struct mtd_info *mtd, int offset, int len) |
||
147 | -{ |
||
148 | - unsigned long mask = mtd->erasesize - 1; |
||
149 | - |
||
150 | - len += offset & mask; |
||
151 | - len = (len + mask) & ~mask; |
||
152 | - len -= offset & mask; |
||
153 | - return len; |
||
154 | -} |
||
155 | - |
||
156 | -static int split_squashfs(struct mtd_info *master, int offset, int *split_offset) |
||
157 | -{ |
||
158 | - size_t squashfs_len; |
||
159 | - int len, ret; |
||
160 | - |
||
161 | - ret = mtd_get_squashfs_len(master, offset, &squashfs_len); |
||
162 | - if (ret) |
||
163 | - return ret; |
||
164 | - |
||
165 | - len = mtd_pad_erasesize(master, offset, squashfs_len); |
||
166 | - *split_offset = offset + len; |
||
167 | - |
||
168 | - return 0; |
||
169 | -} |
||
170 | - |
||
171 | -static void split_rootfs_data(struct mtd_info *master, struct mtd_part *part) |
||
172 | -{ |
||
173 | - unsigned int split_offset = 0; |
||
174 | - unsigned int split_size; |
||
175 | - int ret; |
||
176 | - |
||
177 | - ret = split_squashfs(master, part->offset, &split_offset); |
||
178 | - if (ret) |
||
179 | - return; |
||
180 | - |
||
181 | - if (split_offset <= 0) |
||
182 | - return; |
||
183 | - |
||
184 | - if (config_enabled(CONFIG_MTD_SPLIT_SQUASHFS_ROOT)) |
||
185 | - pr_err("Dedicated partitioner didn't create \"rootfs_data\" partition, please fill a bug report!\n"); |
||
186 | - else |
||
187 | - pr_warn("Support for built-in \"rootfs_data\" splitter will be removed, please use CONFIG_MTD_SPLIT_SQUASHFS_ROOT\n"); |
||
188 | - |
||
189 | - split_size = part->mtd.size - (split_offset - part->offset); |
||
190 | - printk(KERN_INFO "mtd: partition \"%s\" created automatically, ofs=0x%x, len=0x%x\n", |
||
191 | - ROOTFS_SPLIT_NAME, split_offset, split_size); |
||
192 | - |
||
193 | - __mtd_add_partition(master, ROOTFS_SPLIT_NAME, split_offset, |
||
194 | - split_size, false); |
||
195 | -} |
||
196 | - |
||
197 | -#define UBOOT_MAGIC 0x27051956 |
||
198 | - |
||
199 | -static void split_uimage(struct mtd_info *master, struct mtd_part *part) |
||
200 | -{ |
||
201 | - struct { |
||
202 | - __be32 magic; |
||
203 | - __be32 pad[2]; |
||
204 | - __be32 size; |
||
205 | - } hdr; |
||
206 | - size_t len; |
||
207 | - |
||
208 | - if (mtd_read(master, part->offset, sizeof(hdr), &len, (void *) &hdr)) |
||
209 | - return; |
||
210 | - |
||
211 | - if (len != sizeof(hdr) || hdr.magic != cpu_to_be32(UBOOT_MAGIC)) |
||
212 | - return; |
||
213 | - |
||
214 | - len = be32_to_cpu(hdr.size) + 0x40; |
||
215 | - len = mtd_pad_erasesize(master, part->offset, len); |
||
216 | - if (len + master->erasesize > part->mtd.size) |
||
217 | - return; |
||
218 | - |
||
219 | - if (config_enabled(CONFIG_MTD_SPLIT_UIMAGE_FW)) |
||
220 | - pr_err("Dedicated partitioner didn't split firmware partition, please fill a bug report!\n"); |
||
221 | - else |
||
222 | - pr_warn("Support for built-in firmware splitter will be removed, please use CONFIG_MTD_SPLIT_UIMAGE_FW\n"); |
||
223 | - |
||
224 | - __mtd_add_partition(master, "rootfs", part->offset + len, |
||
225 | - part->mtd.size - len, false); |
||
226 | -} |
||
227 | - |
||
228 | -#ifdef CONFIG_MTD_SPLIT_FIRMWARE_NAME |
||
229 | -#define SPLIT_FIRMWARE_NAME CONFIG_MTD_SPLIT_FIRMWARE_NAME |
||
230 | -#else |
||
231 | -#define SPLIT_FIRMWARE_NAME "unused" |
||
232 | -#endif |
||
233 | - |
||
234 | -static void split_firmware(struct mtd_info *master, struct mtd_part *part) |
||
235 | -{ |
||
236 | - int ret; |
||
237 | - |
||
238 | - ret = run_parsers_by_type(part, MTD_PARSER_TYPE_FIRMWARE); |
||
239 | - if (ret > 0) |
||
240 | - return; |
||
241 | - |
||
242 | - if (config_enabled(CONFIG_MTD_UIMAGE_SPLIT)) |
||
243 | - split_uimage(master, part); |
||
244 | -} |
||
245 | - |
||
246 | -void __weak arch_split_mtd_part(struct mtd_info *master, const char *name, |
||
247 | - int offset, int size) |
||
248 | -{ |
||
249 | -} |
||
250 | - |
||
251 | -static void mtd_partition_split(struct mtd_info *master, struct mtd_part *part) |
||
252 | -{ |
||
253 | - static int rootfs_found = 0; |
||
254 | - |
||
255 | - if (rootfs_found) |
||
256 | - return; |
||
257 | - |
||
258 | - if (!strcmp(part->mtd.name, "rootfs")) { |
||
259 | - int num = run_parsers_by_type(part, MTD_PARSER_TYPE_ROOTFS); |
||
260 | - |
||
261 | - if (num <= 0 && config_enabled(CONFIG_MTD_ROOTFS_SPLIT)) |
||
262 | - split_rootfs_data(master, part); |
||
263 | - |
||
264 | - rootfs_found = 1; |
||
265 | - } |
||
266 | - |
||
267 | - if (!strcmp(part->mtd.name, SPLIT_FIRMWARE_NAME) && |
||
268 | - config_enabled(CONFIG_MTD_SPLIT_FIRMWARE)) |
||
269 | - split_firmware(master, part); |
||
270 | - |
||
271 | - arch_split_mtd_part(master, part->mtd.name, part->offset, |
||
272 | - part->mtd.size); |
||
273 | -} |
||
274 | /* |
||
275 | * This function, given a master MTD object and a partition table, creates |
||
276 | * and registers slave MTD objects which are bound to the master according to |
||
277 | @@ -907,7 +735,6 @@ int add_mtd_partitions(struct mtd_info * |
||
278 | mutex_unlock(&mtd_partitions_mutex); |
||
279 | |||
280 | add_mtd_device(&slave->mtd); |
||
281 | - mtd_partition_split(master, slave); |
||
282 | |||
283 | cur_offset = slave->offset + slave->mtd.size; |
||
284 | } |
||
285 | @@ -937,30 +764,6 @@ static struct mtd_part_parser *get_parti |
||
286 | |||
287 | #define put_partition_parser(p) do { module_put((p)->owner); } while (0) |
||
288 | |||
289 | -static struct mtd_part_parser * |
||
290 | -get_partition_parser_by_type(enum mtd_parser_type type, |
||
291 | - struct mtd_part_parser *start) |
||
292 | -{ |
||
293 | - struct mtd_part_parser *p, *ret = NULL; |
||
294 | - |
||
295 | - spin_lock(&part_parser_lock); |
||
296 | - |
||
297 | - p = list_prepare_entry(start, &part_parsers, list); |
||
298 | - if (start) |
||
299 | - put_partition_parser(start); |
||
300 | - |
||
301 | - list_for_each_entry_continue(p, &part_parsers, list) { |
||
302 | - if (p->type == type && try_module_get(p->owner)) { |
||
303 | - ret = p; |
||
304 | - break; |
||
305 | - } |
||
306 | - } |
||
307 | - |
||
308 | - spin_unlock(&part_parser_lock); |
||
309 | - |
||
310 | - return ret; |
||
311 | -} |
||
312 | - |
||
313 | void register_mtd_parser(struct mtd_part_parser *p) |
||
314 | { |
||
315 | spin_lock(&part_parser_lock); |
||
316 | @@ -1076,38 +879,6 @@ int parse_mtd_partitions(struct mtd_info |
||
317 | return ret; |
||
318 | } |
||
319 | |||
320 | -int parse_mtd_partitions_by_type(struct mtd_info *master, |
||
321 | - enum mtd_parser_type type, |
||
322 | - struct mtd_partition **pparts, |
||
323 | - struct mtd_part_parser_data *data) |
||
324 | -{ |
||
325 | - struct mtd_part_parser *prev = NULL; |
||
326 | - int ret = 0; |
||
327 | - |
||
328 | - while (1) { |
||
329 | - struct mtd_part_parser *parser; |
||
330 | - |
||
331 | - parser = get_partition_parser_by_type(type, prev); |
||
332 | - if (!parser) |
||
333 | - break; |
||
334 | - |
||
335 | - ret = (*parser->parse_fn)(master, pparts, data); |
||
336 | - |
||
337 | - if (ret > 0) { |
||
338 | - put_partition_parser(parser); |
||
339 | - printk(KERN_NOTICE |
||
340 | - "%d %s partitions found on MTD device %s\n", |
||
341 | - ret, parser->name, master->name); |
||
342 | - break; |
||
343 | - } |
||
344 | - |
||
345 | - prev = parser; |
||
346 | - } |
||
347 | - |
||
348 | - return ret; |
||
349 | -} |
||
350 | -EXPORT_SYMBOL_GPL(parse_mtd_partitions_by_type); |
||
351 | - |
||
352 | int mtd_is_partition(const struct mtd_info *mtd) |
||
353 | { |
||
354 | struct mtd_part *part; |