From patchwork Thu Aug 16 15:30:23 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 958431 X-Patchwork-Delegate: jagannadh.teki@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=bootlin.com Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 41rrNX2KHfz9s3Z for ; Fri, 17 Aug 2018 01:49:00 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id 13A2EC21DEC; Thu, 16 Aug 2018 15:45:10 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=KHOP_BIG_TO_CC autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 4BD4EC21E08; Thu, 16 Aug 2018 15:31:34 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 3B22EC21E7E; Thu, 16 Aug 2018 15:31:17 +0000 (UTC) Received: from mail.bootlin.com (mail.bootlin.com [62.4.15.54]) by lists.denx.de (Postfix) with ESMTP id 390EBC21E96 for ; Thu, 16 Aug 2018 15:31:02 +0000 (UTC) Received: by mail.bootlin.com (Postfix, from userid 110) id 57D68212C4; Thu, 16 Aug 2018 17:31:01 +0200 (CEST) Received: from localhost.localdomain (AAubervilliers-681-1-43-114.w90-88.abo.wanadoo.fr [90.88.161.114]) by mail.bootlin.com (Postfix) with ESMTPSA id E4F422158C; Thu, 16 Aug 2018 17:30:37 +0200 (CEST) From: Miquel Raynal To: Tom Rini , Daniel Schwierzeck Date: Thu, 16 Aug 2018 17:30:23 +0200 Message-Id: <20180816153029.15521-26-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180816153029.15521-1-miquel.raynal@bootlin.com> References: <20180816153029.15521-1-miquel.raynal@bootlin.com> Cc: Scott Wood , Alexandre Belloni , Boris Brezillon , Antoine Tenart , Allan Nielsen , u-boot@lists.denx.de, Miquel Raynal , Stefan Roese , Jagan Teki Subject: [U-Boot] [PATCH v6 25/31] cmd: mtdparts: add a generic 'mtdparts' parser X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" The current parser is very specific to U-Boot mtdparts implementation. It does not use MTD structures like mtd_info and mtd_partition. Write some kind of a wrapper around the current implementation to allow other commands to benefit from this parsing in a user-friendly way. This new command will allocate an mtd_partition array for each successful call. This array must be freed after use by the caller. The given 'mtdparts' buffer pointer will be moved forward to the next MTD device (if any, it will point towards a '\0' character otherwise). Signed-off-by: Miquel Raynal Acked-by: Jagan Teki --- cmd/mtdparts.c | 71 ++++++++++++++++++++++++++++++++++ include/linux/mtd/partitions.h | 3 ++ 2 files changed, 74 insertions(+) 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 #include #include +#include #if defined(CONFIG_CMD_NAND) #include @@ -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