1 From 99352afe8f169c95b294b6b9a8d0e18cd9e3c2a0 Mon Sep 17 00:00:00 2001
2 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
3 Date: Wed, 21 Jun 2017 08:26:47 +0200
4 Subject: [PATCH] mtd: extract TRX parser out of bcm47xxpart into a separated
7 Content-Type: text/plain; charset=UTF-8
8 Content-Transfer-Encoding: 8bit
10 This makes TRX parsing code reusable with other platforms and parsers.
12 Please note this patch doesn't really change anything in the existing
13 code, just moves it. There is still some place for improvement (e.g.
14 working on non-hacky method of checking rootfs format) but it's not
15 really a subject of this change.
17 Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
18 Signed-off-by: Brian Norris <computersforpeace@gmail.com>
20 drivers/mtd/Kconfig | 4 ++
21 drivers/mtd/Makefile | 1 +
22 drivers/mtd/bcm47xxpart.c | 99 ++----------------------------
23 drivers/mtd/parsers/Kconfig | 8 +++
24 drivers/mtd/parsers/Makefile | 1 +
25 drivers/mtd/parsers/parser_trx.c | 126 +++++++++++++++++++++++++++++++++++++++
26 6 files changed, 145 insertions(+), 94 deletions(-)
27 create mode 100644 drivers/mtd/parsers/Kconfig
28 create mode 100644 drivers/mtd/parsers/Makefile
29 create mode 100644 drivers/mtd/parsers/parser_trx.c
31 --- a/drivers/mtd/Kconfig
32 +++ b/drivers/mtd/Kconfig
33 @@ -155,6 +155,10 @@ config MTD_BCM47XX_PARTS
34 This provides partitions parser for devices based on BCM47xx
37 +menu "Partition parsers"
38 +source "drivers/mtd/parsers/Kconfig"
41 comment "User Modules And Translation Layers"
44 --- a/drivers/mtd/Makefile
45 +++ b/drivers/mtd/Makefile
46 @@ -13,6 +13,7 @@ obj-$(CONFIG_MTD_AFS_PARTS) += afs.o
47 obj-$(CONFIG_MTD_AR7_PARTS) += ar7part.o
48 obj-$(CONFIG_MTD_BCM63XX_PARTS) += bcm63xxpart.o
49 obj-$(CONFIG_MTD_BCM47XX_PARTS) += bcm47xxpart.o
52 # 'Users' - code which presents functionality to userspace.
53 obj-$(CONFIG_MTD_BLKDEVS) += mtd_blkdevs.o
54 --- a/drivers/mtd/bcm47xxpart.c
55 +++ b/drivers/mtd/bcm47xxpart.c
57 #define ML_MAGIC2 0x26594131
58 #define TRX_MAGIC 0x30524448
59 #define SHSQ_MAGIC 0x71736873 /* shsq (weird ZTE H218N endianness) */
60 -#define UBI_EC_MAGIC 0x23494255 /* UBI# */
62 +static const char * const trx_types[] = { "trx", NULL };
66 @@ -62,89 +63,6 @@ static void bcm47xxpart_add_part(struct
67 part->mask_flags = mask_flags;
70 -static const char *bcm47xxpart_trx_data_part_name(struct mtd_info *master,
77 - err = mtd_read(master, offset, sizeof(buf), &bytes_read,
79 - if (err && !mtd_is_bitflip(err)) {
80 - pr_err("mtd_read error while parsing (offset: 0x%X): %d\n",
85 - if (buf == UBI_EC_MAGIC)
92 -static int bcm47xxpart_parse_trx(struct mtd_info *master,
93 - struct mtd_partition *trx,
94 - struct mtd_partition *parts,
97 - struct trx_header header;
102 - if (parts_len < 3) {
103 - pr_warn("No enough space to add TRX partitions!\n");
107 - err = mtd_read(master, trx->offset, sizeof(header), &bytes_read,
108 - (uint8_t *)&header);
109 - if (err && !mtd_is_bitflip(err)) {
110 - pr_err("mtd_read error while reading TRX header: %d\n", err);
116 - /* We have LZMA loader if offset[2] points to sth */
117 - if (header.offset[2]) {
118 - bcm47xxpart_add_part(&parts[curr_part++], "loader",
119 - trx->offset + header.offset[i], 0);
123 - if (header.offset[i]) {
124 - bcm47xxpart_add_part(&parts[curr_part++], "linux",
125 - trx->offset + header.offset[i], 0);
129 - if (header.offset[i]) {
130 - size_t offset = trx->offset + header.offset[i];
131 - const char *name = bcm47xxpart_trx_data_part_name(master,
134 - bcm47xxpart_add_part(&parts[curr_part++], name, offset, 0);
139 - * Assume that every partition ends at the beginning of the one it is
142 - for (i = 0; i < curr_part; i++) {
143 - u64 next_part_offset = (i < curr_part - 1) ?
144 - parts[i + 1].offset :
145 - trx->offset + trx->size;
147 - parts[i].size = next_part_offset - parts[i].offset;
154 * bcm47xxpart_bootpartition - gets index of TRX partition used by bootloader
156 @@ -362,17 +280,10 @@ static int bcm47xxpart_parse(struct mtd_
157 for (i = 0; i < trx_num; i++) {
158 struct mtd_partition *trx = &parts[trx_parts[i]];
160 - if (i == bcm47xxpart_bootpartition()) {
163 - num_parts = bcm47xxpart_parse_trx(master, trx,
165 - BCM47XXPART_MAX_PARTS - curr_part);
167 - curr_part += num_parts;
169 + if (i == bcm47xxpart_bootpartition())
170 + trx->types = trx_types;
172 trx->name = "failsafe";
178 +++ b/drivers/mtd/parsers/Kconfig
180 +config MTD_PARSER_TRX
181 + tristate "Parser for TRX format partitions"
182 + depends on MTD && (BCM47XX || ARCH_BCM_5301X || COMPILE_TEST)
184 + TRX is a firmware format used by Broadcom on their devices. It
185 + may contain up to 3/4 partitions (depending on the version).
186 + This driver will parse TRX header and report at least two partitions:
189 +++ b/drivers/mtd/parsers/Makefile
191 +obj-$(CONFIG_MTD_PARSER_TRX) += parser_trx.o
193 +++ b/drivers/mtd/parsers/parser_trx.c
196 + * Parser for TRX format partitions
198 + * Copyright (C) 2012 - 2017 Rafał Miłecki <rafal@milecki.pl>
200 + * This program is free software; you can redistribute it and/or modify
201 + * it under the terms of the GNU General Public License version 2 as
202 + * published by the Free Software Foundation.
206 +#include <linux/module.h>
207 +#include <linux/slab.h>
208 +#include <linux/mtd/mtd.h>
209 +#include <linux/mtd/partitions.h>
211 +#define TRX_PARSER_MAX_PARTS 4
214 +#define TRX_MAGIC 0x30524448
215 +#define UBI_EC_MAGIC 0x23494255 /* UBI# */
223 + uint32_t offset[3];
226 +static const char *parser_trx_data_part_name(struct mtd_info *master,
233 + err = mtd_read(master, offset, sizeof(buf), &bytes_read,
235 + if (err && !mtd_is_bitflip(err)) {
236 + pr_err("mtd_read error while parsing (offset: 0x%X): %d\n",
241 + if (buf == UBI_EC_MAGIC)
248 +static int parser_trx_parse(struct mtd_info *mtd,
249 + const struct mtd_partition **pparts,
250 + struct mtd_part_parser_data *data)
252 + struct mtd_partition *parts;
253 + struct mtd_partition *part;
254 + struct trx_header trx;
256 + uint8_t curr_part = 0, i = 0;
259 + parts = kzalloc(sizeof(struct mtd_partition) * TRX_PARSER_MAX_PARTS,
264 + err = mtd_read(mtd, 0, sizeof(trx), &bytes_read, (uint8_t *)&trx);
266 + pr_err("MTD reading error: %d\n", err);
271 + if (trx.magic != TRX_MAGIC) {
276 + /* We have LZMA loader if there is address in offset[2] */
277 + if (trx.offset[2]) {
278 + part = &parts[curr_part++];
279 + part->name = "loader";
280 + part->offset = trx.offset[i];
284 + if (trx.offset[i]) {
285 + part = &parts[curr_part++];
286 + part->name = "linux";
287 + part->offset = trx.offset[i];
291 + if (trx.offset[i]) {
292 + part = &parts[curr_part++];
293 + part->name = parser_trx_data_part_name(mtd, trx.offset[i]);
294 + part->offset = trx.offset[i];
299 + * Assume that every partition ends at the beginning of the one it is
302 + for (i = 0; i < curr_part; i++) {
303 + u64 next_part_offset = (i < curr_part - 1) ?
304 + parts[i + 1].offset : mtd->size;
306 + parts[i].size = next_part_offset - parts[i].offset;
313 +static struct mtd_part_parser mtd_parser_trx = {
314 + .parse_fn = parser_trx_parse,
317 +module_mtd_part_parser(mtd_parser_trx);
319 +MODULE_LICENSE("GPL v2");
320 +MODULE_DESCRIPTION("Parser for TRX format partitions");