Message ID | 20180816153029.15521-26-miquel.raynal@bootlin.com |
---|---|
State | Superseded |
Delegated to: | Jagannadha Sutradharudu Teki |
Headers | show |
Series | SPI-NAND support | expand |
On Thu, 16 Aug 2018 17:30:23 +0200 Miquel Raynal <miquel.raynal@bootlin.com> wrote: > > +int mtdparts_parse_part(struct mtd_info *parent, const char **_mtdparts, > + struct mtd_partition **_parts, int *_nb_parts) > +{ > + const char *mtdparts = *_mtdparts; > + struct part_info *part_legacy; > + struct mtd_partition *parts; > + int cur_off = 0, cur_sz = 0; > + int nb_parts = 0; > + char *names; > + int ret, idx; > + > + *_parts = NULL; > + *_nb_parts = 0; > + > + /* First, iterate over the partitions until we know their number */ > + while (mtdparts[0] != '\0' && mtdparts[0] != ';') { > + ret = part_parse(mtdparts, &mtdparts, &part_legacy); > + if (ret) > + return ret; > + > + nb_parts++; > + free(part_legacy); > + } > + > + /* Allocate an array of partitions to give back to the caller */ > + parts = malloc((sizeof(*parts) + 20) * nb_parts); > + names = (char *)&parts[nb_parts]; > + if (!parts) { > + printf("Could not allocate enough space to save partitions meta-data\n"); > + return -ENOMEM; > + } > + > + /* Iterate again over each partition to save the data in our array */ > + for (idx = 0; idx < nb_parts; idx++) { > + char *name; > + > + ret = part_parse(*_mtdparts, _mtdparts, &part_legacy); > + if (ret) > + return ret; > + > + name = &names[idx * 20]; > + strncpy(name, part_legacy->name, 20); > + parts[idx].name = name; > + > + parts[idx].size = part_legacy->size; > + if (parts[idx].size == SIZE_REMAINING) > + parts[idx].size = parent->size - cur_sz; > + cur_sz += parts[idx].size; > + > + parts[idx].offset = part_legacy->offset; > + if (parts[idx].offset == OFFSET_NOT_SPECIFIED) > + parts[idx].offset = cur_off; > + cur_off += parts[idx].size; > + > + parts[idx].mask_flags = part_legacy->mask_flags; > + parts[idx].ecclayout = parent->ecclayout; > + > + free(part_legacy); > + } > + > + /* Offset by one mtdparts to point to the next device if needed */ > + if (*_mtdparts[0] == ';') > + _mtdparts++; > + > + *_parts = parts; > + *_nb_parts = nb_parts; > + > + return 0; > +} > I guess the CMD_MTD dependency on CMD_MTDPARTS comes from here. Can't we just move mtdparts_parse_part()+part_parse() somewhere in drivers/mtd/ and remove this dependency?
diff --git a/cmd/mtdparts.c b/cmd/mtdparts.c index 2e547894c6..7fd9e5cbdb 100644 --- a/cmd/mtdparts.c +++ b/cmd/mtdparts.c @@ -78,6 +78,7 @@ #include <linux/ctype.h> #include <linux/err.h> #include <linux/mtd/mtd.h> +#include <linux/mtd/partitions.h> #if defined(CONFIG_CMD_NAND) #include <linux/mtd/rawnand.h> @@ -708,6 +709,76 @@ static int part_parse(const char *const partdef, const char **ret, struct part_i return 0; } +int mtdparts_parse_part(struct mtd_info *parent, const char **_mtdparts, + struct mtd_partition **_parts, int *_nb_parts) +{ + const char *mtdparts = *_mtdparts; + struct part_info *part_legacy; + struct mtd_partition *parts; + int cur_off = 0, cur_sz = 0; + int nb_parts = 0; + char *names; + int ret, idx; + + *_parts = NULL; + *_nb_parts = 0; + + /* First, iterate over the partitions until we know their number */ + while (mtdparts[0] != '\0' && mtdparts[0] != ';') { + ret = part_parse(mtdparts, &mtdparts, &part_legacy); + if (ret) + return ret; + + nb_parts++; + free(part_legacy); + } + + /* Allocate an array of partitions to give back to the caller */ + parts = malloc((sizeof(*parts) + 20) * nb_parts); + names = (char *)&parts[nb_parts]; + if (!parts) { + printf("Could not allocate enough space to save partitions meta-data\n"); + return -ENOMEM; + } + + /* Iterate again over each partition to save the data in our array */ + for (idx = 0; idx < nb_parts; idx++) { + char *name; + + ret = part_parse(*_mtdparts, _mtdparts, &part_legacy); + if (ret) + return ret; + + name = &names[idx * 20]; + strncpy(name, part_legacy->name, 20); + parts[idx].name = name; + + parts[idx].size = part_legacy->size; + if (parts[idx].size == SIZE_REMAINING) + parts[idx].size = parent->size - cur_sz; + cur_sz += parts[idx].size; + + parts[idx].offset = part_legacy->offset; + if (parts[idx].offset == OFFSET_NOT_SPECIFIED) + parts[idx].offset = cur_off; + cur_off += parts[idx].size; + + parts[idx].mask_flags = part_legacy->mask_flags; + parts[idx].ecclayout = parent->ecclayout; + + free(part_legacy); + } + + /* Offset by one mtdparts to point to the next device if needed */ + if (*_mtdparts[0] == ';') + _mtdparts++; + + *_parts = parts; + *_nb_parts = nb_parts; + + return 0; +} + /** * Check device number to be within valid range for given device type. * diff --git a/include/linux/mtd/partitions.h b/include/linux/mtd/partitions.h index ce0e8dbee4..0cf26ca945 100644 --- a/include/linux/mtd/partitions.h +++ b/include/linux/mtd/partitions.h @@ -87,4 +87,7 @@ int mtd_add_partition(struct mtd_info *master, const char *name, int mtd_del_partition(struct mtd_info *master, int partno); uint64_t mtd_get_device_size(const struct mtd_info *mtd); +int mtdparts_parse_part(struct mtd_info *parent, const char **_mtdparts, + struct mtd_partition **_parts, int *_nb_parts); + #endif