mtd: partitions: add module_mtd_part_parser() helper
[cascardo/linux.git] / drivers / mtd / mtdpart.c
index cafdb88..1fa3ca9 100644 (file)
@@ -596,11 +596,10 @@ int mtd_add_partition(struct mtd_info *master, const char *name,
        if (length <= 0)
                return -EINVAL;
 
+       memset(&part, 0, sizeof(part));
        part.name = name;
        part.size = length;
        part.offset = offset;
-       part.mask_flags = 0;
-       part.ecclayout = NULL;
 
        new = allocate_partition(master, &part, -1, offset);
        if (IS_ERR(new))
@@ -664,8 +663,10 @@ int add_mtd_partitions(struct mtd_info *master,
 
        for (i = 0; i < nbparts; i++) {
                slave = allocate_partition(master, parts + i, i, cur_offset);
-               if (IS_ERR(slave))
+               if (IS_ERR(slave)) {
+                       del_mtd_partitions(master);
                        return PTR_ERR(slave);
+               }
 
                mutex_lock(&mtd_partitions_mutex);
                list_add(&slave->list, &mtd_partitions);
@@ -702,13 +703,17 @@ static struct mtd_part_parser *get_partition_parser(const char *name)
 
 #define put_partition_parser(p) do { module_put((p)->owner); } while (0)
 
-void register_mtd_parser(struct mtd_part_parser *p)
+int __register_mtd_parser(struct mtd_part_parser *p, struct module *owner)
 {
+       p->owner = owner;
+
        spin_lock(&part_parser_lock);
        list_add(&p->list, &part_parsers);
        spin_unlock(&part_parser_lock);
+
+       return 0;
 }
-EXPORT_SYMBOL_GPL(register_mtd_parser);
+EXPORT_SYMBOL_GPL(__register_mtd_parser);
 
 void deregister_mtd_parser(struct mtd_part_parser *p)
 {
@@ -753,26 +758,37 @@ int parse_mtd_partitions(struct mtd_info *master, const char *const *types,
                         struct mtd_part_parser_data *data)
 {
        struct mtd_part_parser *parser;
-       int ret = 0;
+       int ret, err = 0;
 
        if (!types)
                types = default_mtd_part_types;
 
-       for ( ; ret <= 0 && *types; types++) {
+       for ( ; *types; types++) {
+               pr_debug("%s: parsing partitions %s\n", master->name, *types);
                parser = get_partition_parser(*types);
                if (!parser && !request_module("%s", *types))
                        parser = get_partition_parser(*types);
+               pr_debug("%s: got parser %s\n", master->name,
+                        parser ? parser->name : NULL);
                if (!parser)
                        continue;
                ret = (*parser->parse_fn)(master, pparts, data);
+               pr_debug("%s: parser %s: %i\n",
+                        master->name, parser->name, ret);
                put_partition_parser(parser);
                if (ret > 0) {
                        printk(KERN_NOTICE "%d %s partitions found on MTD device %s\n",
                               ret, parser->name, master->name);
-                       break;
+                       return ret;
                }
+               /*
+                * Stash the first error we see; only report it if no parser
+                * succeeds
+                */
+               if (ret < 0 && !err)
+                       err = ret;
        }
-       return ret;
+       return err;
 }
 
 int mtd_is_partition(const struct mtd_info *mtd)