From patchwork Mon Jul 30 15:46:53 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 951086 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 41fPWp4klxz9ryt for ; Tue, 31 Jul 2018 02:04:06 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id 51ECAC21F7F; Mon, 30 Jul 2018 15:58:26 +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 35E4EC22093; Mon, 30 Jul 2018 15:48:06 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 5A3E0C21FB0; Mon, 30 Jul 2018 15:47:41 +0000 (UTC) Received: from mail.bootlin.com (mail.bootlin.com [62.4.15.54]) by lists.denx.de (Postfix) with ESMTP id C9DB5C21FE1 for ; Mon, 30 Jul 2018 15:47:30 +0000 (UTC) Received: by mail.bootlin.com (Postfix, from userid 110) id 90D962093A; Mon, 30 Jul 2018 17:47:29 +0200 (CEST) Received: from localhost.localdomain (AAubervilliers-681-1-89-120.w90-88.abo.wanadoo.fr [90.88.30.120]) by mail.bootlin.com (Postfix) with ESMTPSA id 0ADC820996; Mon, 30 Jul 2018 17:47:06 +0200 (CEST) From: Miquel Raynal To: Tom Rini , Daniel Schwierzeck Date: Mon, 30 Jul 2018 17:46:53 +0200 Message-Id: <20180730154657.20738-24-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20180730154657.20738-1-miquel.raynal@bootlin.com> References: <20180730154657.20738-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 v5 23/27] 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 f26a761c99..27e84db0e4 100644 --- a/cmd/mtdparts.c +++ b/cmd/mtdparts.c @@ -78,6 +78,7 @@ #include #include #include +#include #if defined(CONFIG_CMD_NAND) #include @@ -705,6 +706,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