From: Rafał Miłecki Date: Fri, 10 Feb 2017 07:30:16 +0000 (+0100) Subject: kernel: move upstream accepted bcm47xxpart TRX cleanups X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=db866154fc5e3497e889eada74d3c09411bfafd1;p=openwrt%2Fstaging%2Fyousong.git kernel: move upstream accepted bcm47xxpart TRX cleanups Use 0xx prefix for accepted patches. Signed-off-by: Rafał Miłecki --- diff --git a/target/linux/generic/patches-4.4/042-0007-mtd-bcm47xxpart-move-TRX-parsing-code-to-separated-f.patch b/target/linux/generic/patches-4.4/042-0007-mtd-bcm47xxpart-move-TRX-parsing-code-to-separated-f.patch new file mode 100644 index 0000000000..4ef7e7f5d8 --- /dev/null +++ b/target/linux/generic/patches-4.4/042-0007-mtd-bcm47xxpart-move-TRX-parsing-code-to-separated-f.patch @@ -0,0 +1,180 @@ +From b522d7b0ebe3539340c2a6d46d787ae3d33bcb92 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Tue, 10 Jan 2017 23:15:24 +0100 +Subject: [PATCH] mtd: bcm47xxpart: move TRX parsing code to separated function +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This change simplifies main parsing loop logic a bit. In future it may +be useful for moving TRX support to separated module / parser (if we +implement support for them at some point). +Finally parsing TRX at the end puts us in a better position as we have +better flash layout knowledge. It may be useful e.g. if it appears there +is more than 1 TRX partition. + +Signed-off-by: Rafał Miłecki +Acked-by: Marek Vasut +Signed-off-by: Brian Norris +--- + drivers/mtd/bcm47xxpart.c | 121 ++++++++++++++++++++++++++++------------------ + 1 file changed, 74 insertions(+), 47 deletions(-) + +--- a/drivers/mtd/bcm47xxpart.c ++++ b/drivers/mtd/bcm47xxpart.c +@@ -83,6 +83,67 @@ 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; ++} ++ + static int bcm47xxpart_parse(struct mtd_info *master, + struct mtd_partition **pparts, + struct mtd_part_parser_data *data) +@@ -93,9 +154,7 @@ static int bcm47xxpart_parse(struct mtd_ + size_t bytes_read; + uint32_t offset; + uint32_t blocksize = master->erasesize; +- struct trx_header *trx; + int trx_part = -1; +- int last_trx_part = -1; + int possible_nvram_sizes[] = { 0x8000, 0xF000, 0x10000, }; + int err; + +@@ -182,54 +241,14 @@ static int bcm47xxpart_parse(struct mtd_ + + /* TRX */ + if (buf[0x000 / 4] == TRX_MAGIC) { +- if (BCM47XXPART_MAX_PARTS - curr_part < 4) { +- pr_warn("Not enough partitions left to register trx, scanning stopped!\n"); +- break; +- } +- +- trx = (struct trx_header *)buf; ++ struct trx_header *trx; + + trx_part = curr_part; + bcm47xxpart_add_part(&parts[curr_part++], "firmware", + offset, 0); + +- i = 0; +- /* We have LZMA loader if offset[2] points to sth */ +- if (trx->offset[2]) { +- bcm47xxpart_add_part(&parts[curr_part++], +- "loader", +- offset + trx->offset[i], +- 0); +- i++; +- } +- +- if (trx->offset[i]) { +- bcm47xxpart_add_part(&parts[curr_part++], +- "linux", +- offset + trx->offset[i], +- 0); +- i++; +- } +- +- /* +- * Pure rootfs size is known and can be calculated as: +- * trx->length - trx->offset[i]. We don't fill it as +- * we want to have jffs2 (overlay) in the same mtd. +- */ +- if (trx->offset[i]) { +- const char *name; +- +- name = bcm47xxpart_trx_data_part_name(master, offset + trx->offset[i]); +- bcm47xxpart_add_part(&parts[curr_part++], +- name, +- offset + trx->offset[i], +- 0); +- i++; +- } +- +- last_trx_part = curr_part - 1; +- + /* Jump to the end of TRX */ ++ trx = (struct trx_header *)buf; + offset = roundup(offset + trx->length, blocksize); + /* Next loop iteration will increase the offset */ + offset -= blocksize; +@@ -307,9 +326,17 @@ static int bcm47xxpart_parse(struct mtd_ + parts[i + 1].offset : master->size; + + parts[i].size = next_part_offset - parts[i].offset; +- if (i == last_trx_part && trx_part >= 0) +- parts[trx_part].size = next_part_offset - +- parts[trx_part].offset; ++ } ++ ++ /* If there was TRX parse it now */ ++ if (trx_part >= 0) { ++ int num_parts; ++ ++ num_parts = bcm47xxpart_parse_trx(master, &parts[trx_part], ++ parts + curr_part, ++ BCM47XXPART_MAX_PARTS - curr_part); ++ if (num_parts > 0) ++ curr_part += num_parts; + } + + *pparts = parts; diff --git a/target/linux/generic/patches-4.4/042-0008-mtd-bcm47xxpart-support-layouts-with-multiple-TRX-pa.patch b/target/linux/generic/patches-4.4/042-0008-mtd-bcm47xxpart-support-layouts-with-multiple-TRX-pa.patch new file mode 100644 index 0000000000..6c6c8397df --- /dev/null +++ b/target/linux/generic/patches-4.4/042-0008-mtd-bcm47xxpart-support-layouts-with-multiple-TRX-pa.patch @@ -0,0 +1,112 @@ +From 89a0d9a9f1941a086a82bc7cd73d275cec98ba14 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Tue, 10 Jan 2017 23:15:25 +0100 +Subject: [PATCH] mtd: bcm47xxpart: support layouts with multiple TRX + partitions +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Some devices may have an extra TRX partition used as failsafe one. If +we detect such partition we should set a proper name for it and don't +parse it. + +Signed-off-by: Rafał Miłecki +Acked-by: Marek Vasut +Signed-off-by: Brian Norris +--- + drivers/mtd/bcm47xxpart.c | 56 ++++++++++++++++++++++++++++++++++++++--------- + 1 file changed, 46 insertions(+), 10 deletions(-) + +--- a/drivers/mtd/bcm47xxpart.c ++++ b/drivers/mtd/bcm47xxpart.c +@@ -9,6 +9,7 @@ + * + */ + ++#include + #include + #include + #include +@@ -144,6 +145,30 @@ static int bcm47xxpart_parse_trx(struct + return curr_part; + } + ++/** ++ * bcm47xxpart_bootpartition - gets index of TRX partition used by bootloader ++ * ++ * Some devices may have more than one TRX partition. In such case one of them ++ * is the main one and another a failsafe one. Bootloader may fallback to the ++ * failsafe firmware if it detects corruption of the main image. ++ * ++ * This function provides info about currently used TRX partition. It's the one ++ * containing kernel started by the bootloader. ++ */ ++static int bcm47xxpart_bootpartition(void) ++{ ++ char buf[4]; ++ int bootpartition; ++ ++ /* Check CFE environment variable */ ++ if (bcm47xx_nvram_getenv("bootpartition", buf, sizeof(buf)) > 0) { ++ if (!kstrtoint(buf, 0, &bootpartition)) ++ return bootpartition; ++ } ++ ++ return 0; ++} ++ + static int bcm47xxpart_parse(struct mtd_info *master, + struct mtd_partition **pparts, + struct mtd_part_parser_data *data) +@@ -154,7 +179,8 @@ static int bcm47xxpart_parse(struct mtd_ + size_t bytes_read; + uint32_t offset; + uint32_t blocksize = master->erasesize; +- int trx_part = -1; ++ int trx_parts[2]; /* Array with indexes of TRX partitions */ ++ int trx_num = 0; /* Number of found TRX partitions */ + int possible_nvram_sizes[] = { 0x8000, 0xF000, 0x10000, }; + int err; + +@@ -243,7 +269,11 @@ static int bcm47xxpart_parse(struct mtd_ + if (buf[0x000 / 4] == TRX_MAGIC) { + struct trx_header *trx; + +- trx_part = curr_part; ++ if (trx_num >= ARRAY_SIZE(trx_parts)) ++ pr_warn("No enough space to store another TRX found at 0x%X\n", ++ offset); ++ else ++ trx_parts[trx_num++] = curr_part; + bcm47xxpart_add_part(&parts[curr_part++], "firmware", + offset, 0); + +@@ -329,14 +359,20 @@ static int bcm47xxpart_parse(struct mtd_ + } + + /* If there was TRX parse it now */ +- if (trx_part >= 0) { +- int num_parts; ++ for (i = 0; i < trx_num; i++) { ++ struct mtd_partition *trx = &parts[trx_parts[i]]; + +- num_parts = bcm47xxpart_parse_trx(master, &parts[trx_part], +- parts + curr_part, +- BCM47XXPART_MAX_PARTS - curr_part); +- if (num_parts > 0) +- curr_part += num_parts; ++ 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 { ++ trx->name = "failsafe"; ++ } + } + + *pparts = parts; diff --git a/target/linux/generic/patches-4.4/141-0001-mtd-bcm47xxpart-move-TRX-parsing-code-to-separated-f.patch b/target/linux/generic/patches-4.4/141-0001-mtd-bcm47xxpart-move-TRX-parsing-code-to-separated-f.patch deleted file mode 100644 index a204fe6625..0000000000 --- a/target/linux/generic/patches-4.4/141-0001-mtd-bcm47xxpart-move-TRX-parsing-code-to-separated-f.patch +++ /dev/null @@ -1,177 +0,0 @@ -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Subject: [PATCH 1/2] mtd: bcm47xxpart: move TRX parsing code to separated - function -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This change simplifies main parsing loop logic a bit. In future it may -be useful for moving TRX support to separated module / parser (if we -implement support for them at some point). -Finally parsing TRX at the end puts us in a better position as we have -better flash layout knowledge. It may be useful e.g. if it appears there -is more than 1 TRX partition. - -Signed-off-by: Rafał Miłecki ---- - drivers/mtd/bcm47xxpart.c | 121 ++++++++++++++++++++++++++++------------------ - 1 file changed, 74 insertions(+), 47 deletions(-) - ---- a/drivers/mtd/bcm47xxpart.c -+++ b/drivers/mtd/bcm47xxpart.c -@@ -83,6 +83,67 @@ 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; -+} -+ - static int bcm47xxpart_parse(struct mtd_info *master, - struct mtd_partition **pparts, - struct mtd_part_parser_data *data) -@@ -93,9 +154,7 @@ static int bcm47xxpart_parse(struct mtd_ - size_t bytes_read; - uint32_t offset; - uint32_t blocksize = master->erasesize; -- struct trx_header *trx; - int trx_part = -1; -- int last_trx_part = -1; - int possible_nvram_sizes[] = { 0x8000, 0xF000, 0x10000, }; - int err; - -@@ -182,54 +241,14 @@ static int bcm47xxpart_parse(struct mtd_ - - /* TRX */ - if (buf[0x000 / 4] == TRX_MAGIC) { -- if (BCM47XXPART_MAX_PARTS - curr_part < 4) { -- pr_warn("Not enough partitions left to register trx, scanning stopped!\n"); -- break; -- } -- -- trx = (struct trx_header *)buf; -+ struct trx_header *trx; - - trx_part = curr_part; - bcm47xxpart_add_part(&parts[curr_part++], "firmware", - offset, 0); - -- i = 0; -- /* We have LZMA loader if offset[2] points to sth */ -- if (trx->offset[2]) { -- bcm47xxpart_add_part(&parts[curr_part++], -- "loader", -- offset + trx->offset[i], -- 0); -- i++; -- } -- -- if (trx->offset[i]) { -- bcm47xxpart_add_part(&parts[curr_part++], -- "linux", -- offset + trx->offset[i], -- 0); -- i++; -- } -- -- /* -- * Pure rootfs size is known and can be calculated as: -- * trx->length - trx->offset[i]. We don't fill it as -- * we want to have jffs2 (overlay) in the same mtd. -- */ -- if (trx->offset[i]) { -- const char *name; -- -- name = bcm47xxpart_trx_data_part_name(master, offset + trx->offset[i]); -- bcm47xxpart_add_part(&parts[curr_part++], -- name, -- offset + trx->offset[i], -- 0); -- i++; -- } -- -- last_trx_part = curr_part - 1; -- - /* Jump to the end of TRX */ -+ trx = (struct trx_header *)buf; - offset = roundup(offset + trx->length, blocksize); - /* Next loop iteration will increase the offset */ - offset -= blocksize; -@@ -307,9 +326,17 @@ static int bcm47xxpart_parse(struct mtd_ - parts[i + 1].offset : master->size; - - parts[i].size = next_part_offset - parts[i].offset; -- if (i == last_trx_part && trx_part >= 0) -- parts[trx_part].size = next_part_offset - -- parts[trx_part].offset; -+ } -+ -+ /* If there was TRX parse it now */ -+ if (trx_part >= 0) { -+ int num_parts; -+ -+ num_parts = bcm47xxpart_parse_trx(master, &parts[trx_part], -+ parts + curr_part, -+ BCM47XXPART_MAX_PARTS - curr_part); -+ if (num_parts > 0) -+ curr_part += num_parts; - } - - *pparts = parts; diff --git a/target/linux/generic/patches-4.4/141-0002-mtd-bcm47xxpart-support-layouts-with-multiple-TRX-pa.patch b/target/linux/generic/patches-4.4/141-0002-mtd-bcm47xxpart-support-layouts-with-multiple-TRX-pa.patch deleted file mode 100644 index 2d97be7508..0000000000 --- a/target/linux/generic/patches-4.4/141-0002-mtd-bcm47xxpart-support-layouts-with-multiple-TRX-pa.patch +++ /dev/null @@ -1,108 +0,0 @@ -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Subject: [PATCH 2/2] mtd: bcm47xxpart: support layouts with multiple TRX - partitions -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Some devices may have an extra TRX partition used as failsafe one. If -we detect such partition we should set a proper name for it and don't -parse it. - -Signed-off-by: Rafał Miłecki ---- - drivers/mtd/bcm47xxpart.c | 56 ++++++++++++++++++++++++++++++++++++++--------- - 1 file changed, 46 insertions(+), 10 deletions(-) - ---- a/drivers/mtd/bcm47xxpart.c -+++ b/drivers/mtd/bcm47xxpart.c -@@ -9,6 +9,7 @@ - * - */ - -+#include - #include - #include - #include -@@ -144,6 +145,30 @@ static int bcm47xxpart_parse_trx(struct - return curr_part; - } - -+/** -+ * bcm47xxpart_bootpartition - gets index of TRX partition used by bootloader -+ * -+ * Some devices may have more than one TRX partition. In such case one of them -+ * is the main one and another a failsafe one. Bootloader may fallback to the -+ * failsafe firmware if it detects corruption of the main image. -+ * -+ * This function provides info about currently used TRX partition. It's the one -+ * containing kernel started by the bootloader. -+ */ -+static int bcm47xxpart_bootpartition(void) -+{ -+ char buf[4]; -+ int bootpartition; -+ -+ /* Check CFE environment variable */ -+ if (bcm47xx_nvram_getenv("bootpartition", buf, sizeof(buf)) > 0) { -+ if (!kstrtoint(buf, 0, &bootpartition)) -+ return bootpartition; -+ } -+ -+ return 0; -+} -+ - static int bcm47xxpart_parse(struct mtd_info *master, - struct mtd_partition **pparts, - struct mtd_part_parser_data *data) -@@ -154,7 +179,8 @@ static int bcm47xxpart_parse(struct mtd_ - size_t bytes_read; - uint32_t offset; - uint32_t blocksize = master->erasesize; -- int trx_part = -1; -+ int trx_parts[2]; /* Array with indexes of TRX partitions */ -+ int trx_num = 0; /* Number of found TRX partitions */ - int possible_nvram_sizes[] = { 0x8000, 0xF000, 0x10000, }; - int err; - -@@ -243,7 +269,11 @@ static int bcm47xxpart_parse(struct mtd_ - if (buf[0x000 / 4] == TRX_MAGIC) { - struct trx_header *trx; - -- trx_part = curr_part; -+ if (trx_num >= ARRAY_SIZE(trx_parts)) -+ pr_warn("No enough space to store another TRX found at 0x%X\n", -+ offset); -+ else -+ trx_parts[trx_num++] = curr_part; - bcm47xxpart_add_part(&parts[curr_part++], "firmware", - offset, 0); - -@@ -329,14 +359,20 @@ static int bcm47xxpart_parse(struct mtd_ - } - - /* If there was TRX parse it now */ -- if (trx_part >= 0) { -- int num_parts; -+ for (i = 0; i < trx_num; i++) { -+ struct mtd_partition *trx = &parts[trx_parts[i]]; - -- num_parts = bcm47xxpart_parse_trx(master, &parts[trx_part], -- parts + curr_part, -- BCM47XXPART_MAX_PARTS - curr_part); -- if (num_parts > 0) -- curr_part += num_parts; -+ 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 { -+ trx->name = "failsafe"; -+ } - } - - *pparts = parts; diff --git a/target/linux/generic/patches-4.9/060-0004-mtd-bcm47xxpart-move-TRX-parsing-code-to-separated-f.patch b/target/linux/generic/patches-4.9/060-0004-mtd-bcm47xxpart-move-TRX-parsing-code-to-separated-f.patch new file mode 100644 index 0000000000..999f544d3b --- /dev/null +++ b/target/linux/generic/patches-4.9/060-0004-mtd-bcm47xxpart-move-TRX-parsing-code-to-separated-f.patch @@ -0,0 +1,180 @@ +From b522d7b0ebe3539340c2a6d46d787ae3d33bcb92 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Tue, 10 Jan 2017 23:15:24 +0100 +Subject: [PATCH] mtd: bcm47xxpart: move TRX parsing code to separated function +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This change simplifies main parsing loop logic a bit. In future it may +be useful for moving TRX support to separated module / parser (if we +implement support for them at some point). +Finally parsing TRX at the end puts us in a better position as we have +better flash layout knowledge. It may be useful e.g. if it appears there +is more than 1 TRX partition. + +Signed-off-by: Rafał Miłecki +Acked-by: Marek Vasut +Signed-off-by: Brian Norris +--- + drivers/mtd/bcm47xxpart.c | 121 ++++++++++++++++++++++++++++------------------ + 1 file changed, 74 insertions(+), 47 deletions(-) + +--- a/drivers/mtd/bcm47xxpart.c ++++ b/drivers/mtd/bcm47xxpart.c +@@ -83,6 +83,67 @@ 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; ++} ++ + static int bcm47xxpart_parse(struct mtd_info *master, + const struct mtd_partition **pparts, + struct mtd_part_parser_data *data) +@@ -93,9 +154,7 @@ static int bcm47xxpart_parse(struct mtd_ + size_t bytes_read; + uint32_t offset; + uint32_t blocksize = master->erasesize; +- struct trx_header *trx; + int trx_part = -1; +- int last_trx_part = -1; + int possible_nvram_sizes[] = { 0x8000, 0xF000, 0x10000, }; + int err; + +@@ -182,54 +241,14 @@ static int bcm47xxpart_parse(struct mtd_ + + /* TRX */ + if (buf[0x000 / 4] == TRX_MAGIC) { +- if (BCM47XXPART_MAX_PARTS - curr_part < 4) { +- pr_warn("Not enough partitions left to register trx, scanning stopped!\n"); +- break; +- } +- +- trx = (struct trx_header *)buf; ++ struct trx_header *trx; + + trx_part = curr_part; + bcm47xxpart_add_part(&parts[curr_part++], "firmware", + offset, 0); + +- i = 0; +- /* We have LZMA loader if offset[2] points to sth */ +- if (trx->offset[2]) { +- bcm47xxpart_add_part(&parts[curr_part++], +- "loader", +- offset + trx->offset[i], +- 0); +- i++; +- } +- +- if (trx->offset[i]) { +- bcm47xxpart_add_part(&parts[curr_part++], +- "linux", +- offset + trx->offset[i], +- 0); +- i++; +- } +- +- /* +- * Pure rootfs size is known and can be calculated as: +- * trx->length - trx->offset[i]. We don't fill it as +- * we want to have jffs2 (overlay) in the same mtd. +- */ +- if (trx->offset[i]) { +- const char *name; +- +- name = bcm47xxpart_trx_data_part_name(master, offset + trx->offset[i]); +- bcm47xxpart_add_part(&parts[curr_part++], +- name, +- offset + trx->offset[i], +- 0); +- i++; +- } +- +- last_trx_part = curr_part - 1; +- + /* Jump to the end of TRX */ ++ trx = (struct trx_header *)buf; + offset = roundup(offset + trx->length, blocksize); + /* Next loop iteration will increase the offset */ + offset -= blocksize; +@@ -307,9 +326,17 @@ static int bcm47xxpart_parse(struct mtd_ + parts[i + 1].offset : master->size; + + parts[i].size = next_part_offset - parts[i].offset; +- if (i == last_trx_part && trx_part >= 0) +- parts[trx_part].size = next_part_offset - +- parts[trx_part].offset; ++ } ++ ++ /* If there was TRX parse it now */ ++ if (trx_part >= 0) { ++ int num_parts; ++ ++ num_parts = bcm47xxpart_parse_trx(master, &parts[trx_part], ++ parts + curr_part, ++ BCM47XXPART_MAX_PARTS - curr_part); ++ if (num_parts > 0) ++ curr_part += num_parts; + } + + *pparts = parts; diff --git a/target/linux/generic/patches-4.9/060-0005-mtd-bcm47xxpart-support-layouts-with-multiple-TRX-pa.patch b/target/linux/generic/patches-4.9/060-0005-mtd-bcm47xxpart-support-layouts-with-multiple-TRX-pa.patch new file mode 100644 index 0000000000..bcefee8e87 --- /dev/null +++ b/target/linux/generic/patches-4.9/060-0005-mtd-bcm47xxpart-support-layouts-with-multiple-TRX-pa.patch @@ -0,0 +1,112 @@ +From 89a0d9a9f1941a086a82bc7cd73d275cec98ba14 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Tue, 10 Jan 2017 23:15:25 +0100 +Subject: [PATCH] mtd: bcm47xxpart: support layouts with multiple TRX + partitions +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Some devices may have an extra TRX partition used as failsafe one. If +we detect such partition we should set a proper name for it and don't +parse it. + +Signed-off-by: Rafał Miłecki +Acked-by: Marek Vasut +Signed-off-by: Brian Norris +--- + drivers/mtd/bcm47xxpart.c | 56 ++++++++++++++++++++++++++++++++++++++--------- + 1 file changed, 46 insertions(+), 10 deletions(-) + +--- a/drivers/mtd/bcm47xxpart.c ++++ b/drivers/mtd/bcm47xxpart.c +@@ -9,6 +9,7 @@ + * + */ + ++#include + #include + #include + #include +@@ -144,6 +145,30 @@ static int bcm47xxpart_parse_trx(struct + return curr_part; + } + ++/** ++ * bcm47xxpart_bootpartition - gets index of TRX partition used by bootloader ++ * ++ * Some devices may have more than one TRX partition. In such case one of them ++ * is the main one and another a failsafe one. Bootloader may fallback to the ++ * failsafe firmware if it detects corruption of the main image. ++ * ++ * This function provides info about currently used TRX partition. It's the one ++ * containing kernel started by the bootloader. ++ */ ++static int bcm47xxpart_bootpartition(void) ++{ ++ char buf[4]; ++ int bootpartition; ++ ++ /* Check CFE environment variable */ ++ if (bcm47xx_nvram_getenv("bootpartition", buf, sizeof(buf)) > 0) { ++ if (!kstrtoint(buf, 0, &bootpartition)) ++ return bootpartition; ++ } ++ ++ return 0; ++} ++ + static int bcm47xxpart_parse(struct mtd_info *master, + const struct mtd_partition **pparts, + struct mtd_part_parser_data *data) +@@ -154,7 +179,8 @@ static int bcm47xxpart_parse(struct mtd_ + size_t bytes_read; + uint32_t offset; + uint32_t blocksize = master->erasesize; +- int trx_part = -1; ++ int trx_parts[2]; /* Array with indexes of TRX partitions */ ++ int trx_num = 0; /* Number of found TRX partitions */ + int possible_nvram_sizes[] = { 0x8000, 0xF000, 0x10000, }; + int err; + +@@ -243,7 +269,11 @@ static int bcm47xxpart_parse(struct mtd_ + if (buf[0x000 / 4] == TRX_MAGIC) { + struct trx_header *trx; + +- trx_part = curr_part; ++ if (trx_num >= ARRAY_SIZE(trx_parts)) ++ pr_warn("No enough space to store another TRX found at 0x%X\n", ++ offset); ++ else ++ trx_parts[trx_num++] = curr_part; + bcm47xxpart_add_part(&parts[curr_part++], "firmware", + offset, 0); + +@@ -329,14 +359,20 @@ static int bcm47xxpart_parse(struct mtd_ + } + + /* If there was TRX parse it now */ +- if (trx_part >= 0) { +- int num_parts; ++ for (i = 0; i < trx_num; i++) { ++ struct mtd_partition *trx = &parts[trx_parts[i]]; + +- num_parts = bcm47xxpart_parse_trx(master, &parts[trx_part], +- parts + curr_part, +- BCM47XXPART_MAX_PARTS - curr_part); +- if (num_parts > 0) +- curr_part += num_parts; ++ 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 { ++ trx->name = "failsafe"; ++ } + } + + *pparts = parts; diff --git a/target/linux/generic/patches-4.9/161-01-mtd-bcm47xxpart-move-TRX-parsing-code-to-separated-f.patch b/target/linux/generic/patches-4.9/161-01-mtd-bcm47xxpart-move-TRX-parsing-code-to-separated-f.patch deleted file mode 100644 index 73f30f3216..0000000000 --- a/target/linux/generic/patches-4.9/161-01-mtd-bcm47xxpart-move-TRX-parsing-code-to-separated-f.patch +++ /dev/null @@ -1,177 +0,0 @@ -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Subject: [PATCH 1/2] mtd: bcm47xxpart: move TRX parsing code to separated - function -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This change simplifies main parsing loop logic a bit. In future it may -be useful for moving TRX support to separated module / parser (if we -implement support for them at some point). -Finally parsing TRX at the end puts us in a better position as we have -better flash layout knowledge. It may be useful e.g. if it appears there -is more than 1 TRX partition. - -Signed-off-by: Rafał Miłecki ---- - drivers/mtd/bcm47xxpart.c | 121 ++++++++++++++++++++++++++++------------------ - 1 file changed, 74 insertions(+), 47 deletions(-) - ---- a/drivers/mtd/bcm47xxpart.c -+++ b/drivers/mtd/bcm47xxpart.c -@@ -83,6 +83,67 @@ 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; -+} -+ - static int bcm47xxpart_parse(struct mtd_info *master, - const struct mtd_partition **pparts, - struct mtd_part_parser_data *data) -@@ -93,9 +154,7 @@ static int bcm47xxpart_parse(struct mtd_ - size_t bytes_read; - uint32_t offset; - uint32_t blocksize = master->erasesize; -- struct trx_header *trx; - int trx_part = -1; -- int last_trx_part = -1; - int possible_nvram_sizes[] = { 0x8000, 0xF000, 0x10000, }; - int err; - -@@ -182,54 +241,14 @@ static int bcm47xxpart_parse(struct mtd_ - - /* TRX */ - if (buf[0x000 / 4] == TRX_MAGIC) { -- if (BCM47XXPART_MAX_PARTS - curr_part < 4) { -- pr_warn("Not enough partitions left to register trx, scanning stopped!\n"); -- break; -- } -- -- trx = (struct trx_header *)buf; -+ struct trx_header *trx; - - trx_part = curr_part; - bcm47xxpart_add_part(&parts[curr_part++], "firmware", - offset, 0); - -- i = 0; -- /* We have LZMA loader if offset[2] points to sth */ -- if (trx->offset[2]) { -- bcm47xxpart_add_part(&parts[curr_part++], -- "loader", -- offset + trx->offset[i], -- 0); -- i++; -- } -- -- if (trx->offset[i]) { -- bcm47xxpart_add_part(&parts[curr_part++], -- "linux", -- offset + trx->offset[i], -- 0); -- i++; -- } -- -- /* -- * Pure rootfs size is known and can be calculated as: -- * trx->length - trx->offset[i]. We don't fill it as -- * we want to have jffs2 (overlay) in the same mtd. -- */ -- if (trx->offset[i]) { -- const char *name; -- -- name = bcm47xxpart_trx_data_part_name(master, offset + trx->offset[i]); -- bcm47xxpart_add_part(&parts[curr_part++], -- name, -- offset + trx->offset[i], -- 0); -- i++; -- } -- -- last_trx_part = curr_part - 1; -- - /* Jump to the end of TRX */ -+ trx = (struct trx_header *)buf; - offset = roundup(offset + trx->length, blocksize); - /* Next loop iteration will increase the offset */ - offset -= blocksize; -@@ -307,9 +326,17 @@ static int bcm47xxpart_parse(struct mtd_ - parts[i + 1].offset : master->size; - - parts[i].size = next_part_offset - parts[i].offset; -- if (i == last_trx_part && trx_part >= 0) -- parts[trx_part].size = next_part_offset - -- parts[trx_part].offset; -+ } -+ -+ /* If there was TRX parse it now */ -+ if (trx_part >= 0) { -+ int num_parts; -+ -+ num_parts = bcm47xxpart_parse_trx(master, &parts[trx_part], -+ parts + curr_part, -+ BCM47XXPART_MAX_PARTS - curr_part); -+ if (num_parts > 0) -+ curr_part += num_parts; - } - - *pparts = parts; diff --git a/target/linux/generic/patches-4.9/161-02-mtd-bcm47xxpart-support-layouts-with-multiple-TRX-pa.patch b/target/linux/generic/patches-4.9/161-02-mtd-bcm47xxpart-support-layouts-with-multiple-TRX-pa.patch deleted file mode 100644 index afcd454949..0000000000 --- a/target/linux/generic/patches-4.9/161-02-mtd-bcm47xxpart-support-layouts-with-multiple-TRX-pa.patch +++ /dev/null @@ -1,108 +0,0 @@ -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Subject: [PATCH 2/2] mtd: bcm47xxpart: support layouts with multiple TRX - partitions -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Some devices may have an extra TRX partition used as failsafe one. If -we detect such partition we should set a proper name for it and don't -parse it. - -Signed-off-by: Rafał Miłecki ---- - drivers/mtd/bcm47xxpart.c | 56 ++++++++++++++++++++++++++++++++++++++--------- - 1 file changed, 46 insertions(+), 10 deletions(-) - ---- a/drivers/mtd/bcm47xxpart.c -+++ b/drivers/mtd/bcm47xxpart.c -@@ -9,6 +9,7 @@ - * - */ - -+#include - #include - #include - #include -@@ -144,6 +145,30 @@ static int bcm47xxpart_parse_trx(struct - return curr_part; - } - -+/** -+ * bcm47xxpart_bootpartition - gets index of TRX partition used by bootloader -+ * -+ * Some devices may have more than one TRX partition. In such case one of them -+ * is the main one and another a failsafe one. Bootloader may fallback to the -+ * failsafe firmware if it detects corruption of the main image. -+ * -+ * This function provides info about currently used TRX partition. It's the one -+ * containing kernel started by the bootloader. -+ */ -+static int bcm47xxpart_bootpartition(void) -+{ -+ char buf[4]; -+ int bootpartition; -+ -+ /* Check CFE environment variable */ -+ if (bcm47xx_nvram_getenv("bootpartition", buf, sizeof(buf)) > 0) { -+ if (!kstrtoint(buf, 0, &bootpartition)) -+ return bootpartition; -+ } -+ -+ return 0; -+} -+ - static int bcm47xxpart_parse(struct mtd_info *master, - const struct mtd_partition **pparts, - struct mtd_part_parser_data *data) -@@ -154,7 +179,8 @@ static int bcm47xxpart_parse(struct mtd_ - size_t bytes_read; - uint32_t offset; - uint32_t blocksize = master->erasesize; -- int trx_part = -1; -+ int trx_parts[2]; /* Array with indexes of TRX partitions */ -+ int trx_num = 0; /* Number of found TRX partitions */ - int possible_nvram_sizes[] = { 0x8000, 0xF000, 0x10000, }; - int err; - -@@ -243,7 +269,11 @@ static int bcm47xxpart_parse(struct mtd_ - if (buf[0x000 / 4] == TRX_MAGIC) { - struct trx_header *trx; - -- trx_part = curr_part; -+ if (trx_num >= ARRAY_SIZE(trx_parts)) -+ pr_warn("No enough space to store another TRX found at 0x%X\n", -+ offset); -+ else -+ trx_parts[trx_num++] = curr_part; - bcm47xxpart_add_part(&parts[curr_part++], "firmware", - offset, 0); - -@@ -329,14 +359,20 @@ static int bcm47xxpart_parse(struct mtd_ - } - - /* If there was TRX parse it now */ -- if (trx_part >= 0) { -- int num_parts; -+ for (i = 0; i < trx_num; i++) { -+ struct mtd_partition *trx = &parts[trx_parts[i]]; - -- num_parts = bcm47xxpart_parse_trx(master, &parts[trx_part], -- parts + curr_part, -- BCM47XXPART_MAX_PARTS - curr_part); -- if (num_parts > 0) -- curr_part += num_parts; -+ 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 { -+ trx->name = "failsafe"; -+ } - } - - *pparts = parts;