aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/generic/backport-4.9/065-v4.13-0008-mtd-extract-TRX-parser-out-of-bcm47xxpart-into-a-sep.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/generic/backport-4.9/065-v4.13-0008-mtd-extract-TRX-parser-out-of-bcm47xxpart-into-a-sep.patch')
-rw-r--r--target/linux/generic/backport-4.9/065-v4.13-0008-mtd-extract-TRX-parser-out-of-bcm47xxpart-into-a-sep.patch320
1 files changed, 320 insertions, 0 deletions
diff --git a/target/linux/generic/backport-4.9/065-v4.13-0008-mtd-extract-TRX-parser-out-of-bcm47xxpart-into-a-sep.patch b/target/linux/generic/backport-4.9/065-v4.13-0008-mtd-extract-TRX-parser-out-of-bcm47xxpart-into-a-sep.patch
new file mode 100644
index 0000000000..3761a46610
--- /dev/null
+++ b/target/linux/generic/backport-4.9/065-v4.13-0008-mtd-extract-TRX-parser-out-of-bcm47xxpart-into-a-sep.patch
@@ -0,0 +1,320 @@
+From 99352afe8f169c95b294b6b9a8d0e18cd9e3c2a0 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
+Date: Wed, 21 Jun 2017 08:26:47 +0200
+Subject: [PATCH] mtd: extract TRX parser out of bcm47xxpart into a separated
+ module
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This makes TRX parsing code reusable with other platforms and parsers.
+
+Please note this patch doesn't really change anything in the existing
+code, just moves it. There is still some place for improvement (e.g.
+working on non-hacky method of checking rootfs format) but it's not
+really a subject of this change.
+
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+Signed-off-by: Brian Norris <computersforpeace@gmail.com>
+---
+ drivers/mtd/Kconfig | 4 ++
+ drivers/mtd/Makefile | 1 +
+ drivers/mtd/bcm47xxpart.c | 99 ++----------------------------
+ drivers/mtd/parsers/Kconfig | 8 +++
+ drivers/mtd/parsers/Makefile | 1 +
+ drivers/mtd/parsers/parser_trx.c | 126 +++++++++++++++++++++++++++++++++++++++
+ 6 files changed, 145 insertions(+), 94 deletions(-)
+ create mode 100644 drivers/mtd/parsers/Kconfig
+ create mode 100644 drivers/mtd/parsers/Makefile
+ create mode 100644 drivers/mtd/parsers/parser_trx.c
+
+--- a/drivers/mtd/Kconfig
++++ b/drivers/mtd/Kconfig
+@@ -155,6 +155,10 @@ config MTD_BCM47XX_PARTS
+ This provides partitions parser for devices based on BCM47xx
+ boards.
+
++menu "Partition parsers"
++source "drivers/mtd/parsers/Kconfig"
++endmenu
++
+ comment "User Modules And Translation Layers"
+
+ #
+--- a/drivers/mtd/Makefile
++++ b/drivers/mtd/Makefile
+@@ -13,6 +13,7 @@ obj-$(CONFIG_MTD_AFS_PARTS) += afs.o
+ obj-$(CONFIG_MTD_AR7_PARTS) += ar7part.o
+ obj-$(CONFIG_MTD_BCM63XX_PARTS) += bcm63xxpart.o
+ obj-$(CONFIG_MTD_BCM47XX_PARTS) += bcm47xxpart.o
++obj-y += parsers/
+
+ # 'Users' - code which presents functionality to userspace.
+ obj-$(CONFIG_MTD_BLKDEVS) += mtd_blkdevs.o
+--- a/drivers/mtd/bcm47xxpart.c
++++ b/drivers/mtd/bcm47xxpart.c
+@@ -43,7 +43,8 @@
+ #define ML_MAGIC2 0x26594131
+ #define TRX_MAGIC 0x30524448
+ #define SHSQ_MAGIC 0x71736873 /* shsq (weird ZTE H218N endianness) */
+-#define UBI_EC_MAGIC 0x23494255 /* UBI# */
++
++static const char * const trx_types[] = { "trx", NULL };
+
+ struct trx_header {
+ uint32_t magic;
+@@ -62,89 +63,6 @@ static void bcm47xxpart_add_part(struct
+ part->mask_flags = mask_flags;
+ }
+
+-static const char *bcm47xxpart_trx_data_part_name(struct mtd_info *master,
+- size_t offset)
+-{
+- uint32_t buf;
+- size_t bytes_read;
+- int err;
+-
+- err = mtd_read(master, offset, sizeof(buf), &bytes_read,
+- (uint8_t *)&buf);
+- if (err && !mtd_is_bitflip(err)) {
+- pr_err("mtd_read error while parsing (offset: 0x%X): %d\n",
+- offset, err);
+- goto out_default;
+- }
+-
+- if (buf == UBI_EC_MAGIC)
+- return "ubi";
+-
+-out_default:
+- return "rootfs";
+-}
+-
+-static int bcm47xxpart_parse_trx(struct mtd_info *master,
+- struct mtd_partition *trx,
+- struct mtd_partition *parts,
+- size_t parts_len)
+-{
+- struct trx_header header;
+- size_t bytes_read;
+- int curr_part = 0;
+- int i, err;
+-
+- if (parts_len < 3) {
+- pr_warn("No enough space to add TRX partitions!\n");
+- return -ENOMEM;
+- }
+-
+- err = mtd_read(master, trx->offset, sizeof(header), &bytes_read,
+- (uint8_t *)&header);
+- if (err && !mtd_is_bitflip(err)) {
+- pr_err("mtd_read error while reading TRX header: %d\n", err);
+- return err;
+- }
+-
+- i = 0;
+-
+- /* We have LZMA loader if offset[2] points to sth */
+- if (header.offset[2]) {
+- bcm47xxpart_add_part(&parts[curr_part++], "loader",
+- trx->offset + header.offset[i], 0);
+- i++;
+- }
+-
+- if (header.offset[i]) {
+- bcm47xxpart_add_part(&parts[curr_part++], "linux",
+- trx->offset + header.offset[i], 0);
+- i++;
+- }
+-
+- if (header.offset[i]) {
+- size_t offset = trx->offset + header.offset[i];
+- const char *name = bcm47xxpart_trx_data_part_name(master,
+- offset);
+-
+- bcm47xxpart_add_part(&parts[curr_part++], name, offset, 0);
+- i++;
+- }
+-
+- /*
+- * Assume that every partition ends at the beginning of the one it is
+- * followed by.
+- */
+- for (i = 0; i < curr_part; i++) {
+- u64 next_part_offset = (i < curr_part - 1) ?
+- parts[i + 1].offset :
+- trx->offset + trx->size;
+-
+- parts[i].size = next_part_offset - parts[i].offset;
+- }
+-
+- return curr_part;
+-}
+-
+ /**
+ * bcm47xxpart_bootpartition - gets index of TRX partition used by bootloader
+ *
+@@ -362,17 +280,10 @@ static int bcm47xxpart_parse(struct mtd_
+ for (i = 0; i < trx_num; i++) {
+ struct mtd_partition *trx = &parts[trx_parts[i]];
+
+- if (i == bcm47xxpart_bootpartition()) {
+- int num_parts;
+-
+- num_parts = bcm47xxpart_parse_trx(master, trx,
+- parts + curr_part,
+- BCM47XXPART_MAX_PARTS - curr_part);
+- if (num_parts > 0)
+- curr_part += num_parts;
+- } else {
++ if (i == bcm47xxpart_bootpartition())
++ trx->types = trx_types;
++ else
+ trx->name = "failsafe";
+- }
+ }
+
+ *pparts = parts;
+--- /dev/null
++++ b/drivers/mtd/parsers/Kconfig
+@@ -0,0 +1,8 @@
++config MTD_PARSER_TRX
++ tristate "Parser for TRX format partitions"
++ depends on MTD && (BCM47XX || ARCH_BCM_5301X || COMPILE_TEST)
++ help
++ TRX is a firmware format used by Broadcom on their devices. It
++ may contain up to 3/4 partitions (depending on the version).
++ This driver will parse TRX header and report at least two partitions:
++ kernel and rootfs.
+--- /dev/null
++++ b/drivers/mtd/parsers/Makefile
+@@ -0,0 +1 @@
++obj-$(CONFIG_MTD_PARSER_TRX) += parser_trx.o
+--- /dev/null
++++ b/drivers/mtd/parsers/parser_trx.c
+@@ -0,0 +1,126 @@
++/*
++ * Parser for TRX format partitions
++ *
++ * Copyright (C) 2012 - 2017 Rafał Miłecki <rafal@milecki.pl>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ */
++
++#include <linux/module.h>
++#include <linux/slab.h>
++#include <linux/mtd/mtd.h>
++#include <linux/mtd/partitions.h>
++
++#define TRX_PARSER_MAX_PARTS 4
++
++/* Magics */
++#define TRX_MAGIC 0x30524448
++#define UBI_EC_MAGIC 0x23494255 /* UBI# */
++
++struct trx_header {
++ uint32_t magic;
++ uint32_t length;
++ uint32_t crc32;
++ uint16_t flags;
++ uint16_t version;
++ uint32_t offset[3];
++} __packed;
++
++static const char *parser_trx_data_part_name(struct mtd_info *master,
++ size_t offset)
++{
++ uint32_t buf;
++ size_t bytes_read;
++ int err;
++
++ err = mtd_read(master, offset, sizeof(buf), &bytes_read,
++ (uint8_t *)&buf);
++ if (err && !mtd_is_bitflip(err)) {
++ pr_err("mtd_read error while parsing (offset: 0x%X): %d\n",
++ offset, err);
++ goto out_default;
++ }
++
++ if (buf == UBI_EC_MAGIC)
++ return "ubi";
++
++out_default:
++ return "rootfs";
++}
++
++static int parser_trx_parse(struct mtd_info *mtd,
++ const struct mtd_partition **pparts,
++ struct mtd_part_parser_data *data)
++{
++ struct mtd_partition *parts;
++ struct mtd_partition *part;
++ struct trx_header trx;
++ size_t bytes_read;
++ uint8_t curr_part = 0, i = 0;
++ int err;
++
++ parts = kzalloc(sizeof(struct mtd_partition) * TRX_PARSER_MAX_PARTS,
++ GFP_KERNEL);
++ if (!parts)
++ return -ENOMEM;
++
++ err = mtd_read(mtd, 0, sizeof(trx), &bytes_read, (uint8_t *)&trx);
++ if (err) {
++ pr_err("MTD reading error: %d\n", err);
++ kfree(parts);
++ return err;
++ }
++
++ if (trx.magic != TRX_MAGIC) {
++ kfree(parts);
++ return -ENOENT;
++ }
++
++ /* We have LZMA loader if there is address in offset[2] */
++ if (trx.offset[2]) {
++ part = &parts[curr_part++];
++ part->name = "loader";
++ part->offset = trx.offset[i];
++ i++;
++ }
++
++ if (trx.offset[i]) {
++ part = &parts[curr_part++];
++ part->name = "linux";
++ part->offset = trx.offset[i];
++ i++;
++ }
++
++ if (trx.offset[i]) {
++ part = &parts[curr_part++];
++ part->name = parser_trx_data_part_name(mtd, trx.offset[i]);
++ part->offset = trx.offset[i];
++ i++;
++ }
++
++ /*
++ * Assume that every partition ends at the beginning of the one it is
++ * followed by.
++ */
++ for (i = 0; i < curr_part; i++) {
++ u64 next_part_offset = (i < curr_part - 1) ?
++ parts[i + 1].offset : mtd->size;
++
++ parts[i].size = next_part_offset - parts[i].offset;
++ }
++
++ *pparts = parts;
++ return i;
++};
++
++static struct mtd_part_parser mtd_parser_trx = {
++ .parse_fn = parser_trx_parse,
++ .name = "trx",
++};
++module_mtd_part_parser(mtd_parser_trx);
++
++MODULE_LICENSE("GPL v2");
++MODULE_DESCRIPTION("Parser for TRX format partitions");