}
static int mtd_add_device_partitions(struct mtd_info *mtd,
- const struct mtd_partition *real_parts,
- int nbparts)
+ struct mtd_partitions *parts)
{
+ const struct mtd_partition *real_parts = parts->parts;
+ int nbparts = parts->nr_parts;
int ret;
if (nbparts == 0 || IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER)) {
const struct mtd_partition *parts,
int nr_parts)
{
+ struct mtd_partitions parsed;
int ret;
- const struct mtd_partition *real_parts = NULL;
- ret = parse_mtd_partitions(mtd, types, &real_parts, parser_data);
- if (ret <= 0 && nr_parts && parts) {
- real_parts = parts;
- ret = nr_parts;
- }
- /* Didn't come up with either parsed OR fallback partitions */
- if (ret < 0) {
+ memset(&parsed, 0, sizeof(parsed));
+
+ ret = parse_mtd_partitions(mtd, types, &parsed, parser_data);
+ if ((ret < 0 || parsed.nr_parts == 0) && parts && nr_parts) {
+ /* Fall back to driver-provided partitions */
+ parsed = (struct mtd_partitions){
+ .parts = parts,
+ .nr_parts = nr_parts,
+ };
+ } else if (ret < 0) {
+ /* Didn't come up with parsed OR fallback partitions */
pr_info("mtd: failed to find partitions; one or more parsers reports errors (%d)\n",
ret);
/* Don't abort on errors; we can still use unpartitioned MTD */
- ret = 0;
+ memset(&parsed, 0, sizeof(parsed));
}
- ret = mtd_add_device_partitions(mtd, real_parts, ret);
+ ret = mtd_add_device_partitions(mtd, &parsed);
if (ret)
goto out;
out:
/* Cleanup any parsed partitions */
- if (real_parts != parts)
- kfree(real_parts);
+ if (parsed.parser)
+ kfree(parsed.parts);
return ret;
}
EXPORT_SYMBOL_GPL(mtd_device_parse_register);
int del_mtd_device(struct mtd_info *mtd);
int add_mtd_partitions(struct mtd_info *, const struct mtd_partition *, int);
int del_mtd_partitions(struct mtd_info *);
+
+struct mtd_partitions;
+
int parse_mtd_partitions(struct mtd_info *master, const char * const *types,
- const struct mtd_partition **pparts,
+ struct mtd_partitions *pparts,
struct mtd_part_parser_data *data);
int __init init_mtdchar(void);
* parse_mtd_partitions - parse MTD partitions
* @master: the master partition (describes whole MTD device)
* @types: names of partition parsers to try or %NULL
- * @pparts: array of partitions found is returned here
+ * @pparts: info about partitions found is returned here
* @data: MTD partition parser-specific data
*
* This function tries to find partition on MTD device @master. It uses MTD
*
* This function may return:
* o a negative error code in case of failure
- * o zero if no partitions were found
- * o a positive number of found partitions, in which case on exit @pparts will
- * point to an array containing this number of &struct mtd_info objects.
+ * o zero otherwise, and @pparts will describe the partitions, number of
+ * partitions, and the parser which parsed them
*/
int parse_mtd_partitions(struct mtd_info *master, const char *const *types,
- const struct mtd_partition **pparts,
+ struct mtd_partitions *pparts,
struct mtd_part_parser_data *data)
{
struct mtd_part_parser *parser;
parser ? parser->name : NULL);
if (!parser)
continue;
- ret = (*parser->parse_fn)(master, pparts, data);
+ ret = (*parser->parse_fn)(master, &pparts->parts, data);
pr_debug("%s: parser %s: %i\n",
master->name, parser->name, ret);
mtd_part_parser_put(parser);
if (ret > 0) {
printk(KERN_NOTICE "%d %s partitions found on MTD device %s\n",
ret, parser->name, master->name);
- return ret;
+ pparts->nr_parts = ret;
+ pparts->parser = parser;
+ return 0;
}
/*
* Stash the first error we see; only report it if no parser
struct mtd_part_parser_data *);
};
+/* Container for passing around a set of parsed partitions */
+struct mtd_partitions {
+ const struct mtd_partition *parts;
+ int nr_parts;
+ const struct mtd_part_parser *parser;
+};
+
extern int __register_mtd_parser(struct mtd_part_parser *parser,
struct module *owner);
#define register_mtd_parser(parser) __register_mtd_parser(parser, THIS_MODULE)