diff options
Diffstat (limited to 'drivers/mtd/cmdlinepart.c')
-rw-r--r-- | drivers/mtd/cmdlinepart.c | 47 |
1 files changed, 35 insertions, 12 deletions
diff --git a/drivers/mtd/cmdlinepart.c b/drivers/mtd/cmdlinepart.c index c533f27d863f..721caebbc5cc 100644 --- a/drivers/mtd/cmdlinepart.c +++ b/drivers/mtd/cmdlinepart.c | |||
@@ -22,11 +22,22 @@ | |||
22 | * | 22 | * |
23 | * mtdparts=<mtddef>[;<mtddef] | 23 | * mtdparts=<mtddef>[;<mtddef] |
24 | * <mtddef> := <mtd-id>:<partdef>[,<partdef>] | 24 | * <mtddef> := <mtd-id>:<partdef>[,<partdef>] |
25 | * where <mtd-id> is the name from the "cat /proc/mtd" command | 25 | * <partdef> := <size>[@<offset>][<name>][ro][lk] |
26 | * <partdef> := <size>[@offset][<name>][ro][lk] | ||
27 | * <mtd-id> := unique name used in mapping driver/device (mtd->name) | 26 | * <mtd-id> := unique name used in mapping driver/device (mtd->name) |
28 | * <size> := standard linux memsize OR "-" to denote all remaining space | 27 | * <size> := standard linux memsize OR "-" to denote all remaining space |
28 | * size is automatically truncated at end of device | ||
29 | * if specified or trucated size is 0 the part is skipped | ||
30 | * <offset> := standard linux memsize | ||
31 | * if omitted the part will immediately follow the previous part | ||
32 | * or 0 if the first part | ||
29 | * <name> := '(' NAME ')' | 33 | * <name> := '(' NAME ')' |
34 | * NAME will appear in /proc/mtd | ||
35 | * | ||
36 | * <size> and <offset> can be specified such that the parts are out of order | ||
37 | * in physical memory and may even overlap. | ||
38 | * | ||
39 | * The parts are assigned MTD numbers in the order they are specified in the | ||
40 | * command line regardless of their order in physical memory. | ||
30 | * | 41 | * |
31 | * Examples: | 42 | * Examples: |
32 | * | 43 | * |
@@ -70,6 +81,7 @@ struct cmdline_mtd_partition { | |||
70 | static struct cmdline_mtd_partition *partitions; | 81 | static struct cmdline_mtd_partition *partitions; |
71 | 82 | ||
72 | /* the command line passed to mtdpart_setup() */ | 83 | /* the command line passed to mtdpart_setup() */ |
84 | static char *mtdparts; | ||
73 | static char *cmdline; | 85 | static char *cmdline; |
74 | static int cmdline_parsed; | 86 | static int cmdline_parsed; |
75 | 87 | ||
@@ -330,6 +342,14 @@ static int parse_cmdline_partitions(struct mtd_info *master, | |||
330 | if (part->parts[i].size == SIZE_REMAINING) | 342 | if (part->parts[i].size == SIZE_REMAINING) |
331 | part->parts[i].size = master->size - offset; | 343 | part->parts[i].size = master->size - offset; |
332 | 344 | ||
345 | if (offset + part->parts[i].size > master->size) { | ||
346 | printk(KERN_WARNING ERRP | ||
347 | "%s: partitioning exceeds flash size, truncating\n", | ||
348 | part->mtd_id); | ||
349 | part->parts[i].size = master->size - offset; | ||
350 | } | ||
351 | offset += part->parts[i].size; | ||
352 | |||
333 | if (part->parts[i].size == 0) { | 353 | if (part->parts[i].size == 0) { |
334 | printk(KERN_WARNING ERRP | 354 | printk(KERN_WARNING ERRP |
335 | "%s: skipping zero sized partition\n", | 355 | "%s: skipping zero sized partition\n", |
@@ -337,16 +357,8 @@ static int parse_cmdline_partitions(struct mtd_info *master, | |||
337 | part->num_parts--; | 357 | part->num_parts--; |
338 | memmove(&part->parts[i], &part->parts[i + 1], | 358 | memmove(&part->parts[i], &part->parts[i + 1], |
339 | sizeof(*part->parts) * (part->num_parts - i)); | 359 | sizeof(*part->parts) * (part->num_parts - i)); |
340 | continue; | 360 | i--; |
341 | } | ||
342 | |||
343 | if (offset + part->parts[i].size > master->size) { | ||
344 | printk(KERN_WARNING ERRP | ||
345 | "%s: partitioning exceeds flash size, truncating\n", | ||
346 | part->mtd_id); | ||
347 | part->parts[i].size = master->size - offset; | ||
348 | } | 361 | } |
349 | offset += part->parts[i].size; | ||
350 | } | 362 | } |
351 | 363 | ||
352 | *pparts = kmemdup(part->parts, sizeof(*part->parts) * part->num_parts, | 364 | *pparts = kmemdup(part->parts, sizeof(*part->parts) * part->num_parts, |
@@ -365,7 +377,7 @@ static int parse_cmdline_partitions(struct mtd_info *master, | |||
365 | * | 377 | * |
366 | * This function needs to be visible for bootloaders. | 378 | * This function needs to be visible for bootloaders. |
367 | */ | 379 | */ |
368 | static int mtdpart_setup(char *s) | 380 | static int __init mtdpart_setup(char *s) |
369 | { | 381 | { |
370 | cmdline = s; | 382 | cmdline = s; |
371 | return 1; | 383 | return 1; |
@@ -381,10 +393,21 @@ static struct mtd_part_parser cmdline_parser = { | |||
381 | 393 | ||
382 | static int __init cmdline_parser_init(void) | 394 | static int __init cmdline_parser_init(void) |
383 | { | 395 | { |
396 | if (mtdparts) | ||
397 | mtdpart_setup(mtdparts); | ||
384 | return register_mtd_parser(&cmdline_parser); | 398 | return register_mtd_parser(&cmdline_parser); |
385 | } | 399 | } |
386 | 400 | ||
401 | static void __exit cmdline_parser_exit(void) | ||
402 | { | ||
403 | deregister_mtd_parser(&cmdline_parser); | ||
404 | } | ||
405 | |||
387 | module_init(cmdline_parser_init); | 406 | module_init(cmdline_parser_init); |
407 | module_exit(cmdline_parser_exit); | ||
408 | |||
409 | MODULE_PARM_DESC(mtdparts, "Partitioning specification"); | ||
410 | module_param(mtdparts, charp, 0); | ||
388 | 411 | ||
389 | MODULE_LICENSE("GPL"); | 412 | MODULE_LICENSE("GPL"); |
390 | MODULE_AUTHOR("Marius Groeger <mag@sysgo.de>"); | 413 | MODULE_AUTHOR("Marius Groeger <mag@sysgo.de>"); |