diff options
-rw-r--r-- | drivers/mtd/mtdcore.c | 3 | ||||
-rw-r--r-- | drivers/mtd/mtdcore.h | 2 | ||||
-rw-r--r-- | drivers/mtd/mtdpart.c | 35 | ||||
-rw-r--r-- | include/linux/mtd/partitions.h | 1 |
4 files changed, 37 insertions, 4 deletions
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c index 20b2b38247b6..89d811e7b04a 100644 --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c | |||
@@ -630,8 +630,7 @@ int mtd_device_parse_register(struct mtd_info *mtd, const char * const *types, | |||
630 | 630 | ||
631 | out: | 631 | out: |
632 | /* Cleanup any parsed partitions */ | 632 | /* Cleanup any parsed partitions */ |
633 | if (parsed.parser) | 633 | mtd_part_parser_cleanup(&parsed); |
634 | kfree(parsed.parts); | ||
635 | return ret; | 634 | return ret; |
636 | } | 635 | } |
637 | EXPORT_SYMBOL_GPL(mtd_device_parse_register); | 636 | EXPORT_SYMBOL_GPL(mtd_device_parse_register); |
diff --git a/drivers/mtd/mtdcore.h b/drivers/mtd/mtdcore.h index ce81cc2002f4..55fdb8e1fd2a 100644 --- a/drivers/mtd/mtdcore.h +++ b/drivers/mtd/mtdcore.h | |||
@@ -17,6 +17,8 @@ int parse_mtd_partitions(struct mtd_info *master, const char * const *types, | |||
17 | struct mtd_partitions *pparts, | 17 | struct mtd_partitions *pparts, |
18 | struct mtd_part_parser_data *data); | 18 | struct mtd_part_parser_data *data); |
19 | 19 | ||
20 | void mtd_part_parser_cleanup(struct mtd_partitions *parts); | ||
21 | |||
20 | int __init init_mtdchar(void); | 22 | int __init init_mtdchar(void); |
21 | void __exit cleanup_mtdchar(void); | 23 | void __exit cleanup_mtdchar(void); |
22 | 24 | ||
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c index 53517d7653cb..10bf304027dd 100644 --- a/drivers/mtd/mtdpart.c +++ b/drivers/mtd/mtdpart.c | |||
@@ -709,10 +709,23 @@ static inline void mtd_part_parser_put(const struct mtd_part_parser *p) | |||
709 | module_put(p->owner); | 709 | module_put(p->owner); |
710 | } | 710 | } |
711 | 711 | ||
712 | /* | ||
713 | * Many partition parsers just expected the core to kfree() all their data in | ||
714 | * one chunk. Do that by default. | ||
715 | */ | ||
716 | static void mtd_part_parser_cleanup_default(const struct mtd_partition *pparts, | ||
717 | int nr_parts) | ||
718 | { | ||
719 | kfree(pparts); | ||
720 | } | ||
721 | |||
712 | int __register_mtd_parser(struct mtd_part_parser *p, struct module *owner) | 722 | int __register_mtd_parser(struct mtd_part_parser *p, struct module *owner) |
713 | { | 723 | { |
714 | p->owner = owner; | 724 | p->owner = owner; |
715 | 725 | ||
726 | if (!p->cleanup) | ||
727 | p->cleanup = &mtd_part_parser_cleanup_default; | ||
728 | |||
716 | spin_lock(&part_parser_lock); | 729 | spin_lock(&part_parser_lock); |
717 | list_add(&p->list, &part_parsers); | 730 | list_add(&p->list, &part_parsers); |
718 | spin_unlock(&part_parser_lock); | 731 | spin_unlock(&part_parser_lock); |
@@ -756,7 +769,9 @@ static const char * const default_mtd_part_types[] = { | |||
756 | * This function may return: | 769 | * This function may return: |
757 | * o a negative error code in case of failure | 770 | * o a negative error code in case of failure |
758 | * o zero otherwise, and @pparts will describe the partitions, number of | 771 | * o zero otherwise, and @pparts will describe the partitions, number of |
759 | * partitions, and the parser which parsed them | 772 | * partitions, and the parser which parsed them. Caller must release |
773 | * resources with mtd_part_parser_cleanup() when finished with the returned | ||
774 | * data. | ||
760 | */ | 775 | */ |
761 | int parse_mtd_partitions(struct mtd_info *master, const char *const *types, | 776 | int parse_mtd_partitions(struct mtd_info *master, const char *const *types, |
762 | struct mtd_partitions *pparts, | 777 | struct mtd_partitions *pparts, |
@@ -780,7 +795,6 @@ int parse_mtd_partitions(struct mtd_info *master, const char *const *types, | |||
780 | ret = (*parser->parse_fn)(master, &pparts->parts, data); | 795 | ret = (*parser->parse_fn)(master, &pparts->parts, data); |
781 | pr_debug("%s: parser %s: %i\n", | 796 | pr_debug("%s: parser %s: %i\n", |
782 | master->name, parser->name, ret); | 797 | master->name, parser->name, ret); |
783 | mtd_part_parser_put(parser); | ||
784 | if (ret > 0) { | 798 | if (ret > 0) { |
785 | printk(KERN_NOTICE "%d %s partitions found on MTD device %s\n", | 799 | printk(KERN_NOTICE "%d %s partitions found on MTD device %s\n", |
786 | ret, parser->name, master->name); | 800 | ret, parser->name, master->name); |
@@ -788,6 +802,7 @@ int parse_mtd_partitions(struct mtd_info *master, const char *const *types, | |||
788 | pparts->parser = parser; | 802 | pparts->parser = parser; |
789 | return 0; | 803 | return 0; |
790 | } | 804 | } |
805 | mtd_part_parser_put(parser); | ||
791 | /* | 806 | /* |
792 | * Stash the first error we see; only report it if no parser | 807 | * Stash the first error we see; only report it if no parser |
793 | * succeeds | 808 | * succeeds |
@@ -798,6 +813,22 @@ int parse_mtd_partitions(struct mtd_info *master, const char *const *types, | |||
798 | return err; | 813 | return err; |
799 | } | 814 | } |
800 | 815 | ||
816 | void mtd_part_parser_cleanup(struct mtd_partitions *parts) | ||
817 | { | ||
818 | const struct mtd_part_parser *parser; | ||
819 | |||
820 | if (!parts) | ||
821 | return; | ||
822 | |||
823 | parser = parts->parser; | ||
824 | if (parser) { | ||
825 | if (parser->cleanup) | ||
826 | parser->cleanup(parts->parts, parts->nr_parts); | ||
827 | |||
828 | mtd_part_parser_put(parser); | ||
829 | } | ||
830 | } | ||
831 | |||
801 | int mtd_is_partition(const struct mtd_info *mtd) | 832 | int mtd_is_partition(const struct mtd_info *mtd) |
802 | { | 833 | { |
803 | struct mtd_part *part; | 834 | struct mtd_part *part; |
diff --git a/include/linux/mtd/partitions.h b/include/linux/mtd/partitions.h index cceaf7bd1537..70736e1e6c8f 100644 --- a/include/linux/mtd/partitions.h +++ b/include/linux/mtd/partitions.h | |||
@@ -71,6 +71,7 @@ struct mtd_part_parser { | |||
71 | const char *name; | 71 | const char *name; |
72 | int (*parse_fn)(struct mtd_info *, const struct mtd_partition **, | 72 | int (*parse_fn)(struct mtd_info *, const struct mtd_partition **, |
73 | struct mtd_part_parser_data *); | 73 | struct mtd_part_parser_data *); |
74 | void (*cleanup)(const struct mtd_partition *pparts, int nr_parts); | ||
74 | }; | 75 | }; |
75 | 76 | ||
76 | /* Container for passing around a set of parsed partitions */ | 77 | /* Container for passing around a set of parsed partitions */ |