kernel: mtd: backport SafeLoader parser
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
This commit is contained in:
		| @@ -126,6 +126,7 @@ CONFIG_MTD_CMDLINE_PARTS=y | ||||
| # CONFIG_MTD_MAP_BANK_WIDTH_1 is not set | ||||
| # CONFIG_MTD_MAP_BANK_WIDTH_4 is not set | ||||
| CONFIG_MTD_PARSER_CYBERTAN=y | ||||
| # CONFIG_MTD_PARSER_TPLINK_SAFELOADER is not set | ||||
| CONFIG_MTD_PHYSMAP=y | ||||
| CONFIG_MTD_SPI_NOR=y | ||||
| CONFIG_MTD_SPLIT_ELF_FW=y | ||||
|   | ||||
| @@ -123,6 +123,7 @@ CONFIG_MTD_CMDLINE_PARTS=y | ||||
| # CONFIG_MTD_MAP_BANK_WIDTH_1 is not set | ||||
| # CONFIG_MTD_MAP_BANK_WIDTH_4 is not set | ||||
| CONFIG_MTD_PARSER_CYBERTAN=y | ||||
| # CONFIG_MTD_PARSER_TPLINK_SAFELOADER is not set | ||||
| CONFIG_MTD_PHYSMAP=y | ||||
| CONFIG_MTD_SPI_NOR=y | ||||
| CONFIG_MTD_SPLIT_ELF_FW=y | ||||
|   | ||||
| @@ -196,6 +196,7 @@ CONFIG_MTD_NAND_CORE=y | ||||
| CONFIG_MTD_NAND_ECC=y | ||||
| CONFIG_MTD_NAND_ECC_SW_HAMMING=y | ||||
| CONFIG_MTD_OF_PARTS_LINKSYS_NS=y | ||||
| CONFIG_MTD_PARSER_TPLINK_SAFELOADER=y | ||||
| CONFIG_MTD_PARSER_TRX=y | ||||
| CONFIG_MTD_RAW_NAND=y | ||||
| CONFIG_MTD_SPI_NOR=y | ||||
|   | ||||
| @@ -205,6 +205,7 @@ CONFIG_MTD_NAND_CORE=y | ||||
| CONFIG_MTD_NAND_ECC=y | ||||
| CONFIG_MTD_NAND_ECC_SW_HAMMING=y | ||||
| CONFIG_MTD_OF_PARTS_LINKSYS_NS=y | ||||
| CONFIG_MTD_PARSER_TPLINK_SAFELOADER=y | ||||
| CONFIG_MTD_PARSER_TRX=y | ||||
| CONFIG_MTD_RAW_NAND=y | ||||
| CONFIG_MTD_SPI_NOR=y | ||||
|   | ||||
| @@ -0,0 +1,229 @@ | ||||
| From aec4d5f5ffd0f0092bd9dc21ea90e0bc237d4b74 Mon Sep 17 00:00:00 2001 | ||||
| From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl> | ||||
| Date: Sat, 15 Oct 2022 11:29:50 +0200 | ||||
| Subject: [PATCH] mtd: parsers: add TP-Link SafeLoader partitions table parser | ||||
| MIME-Version: 1.0 | ||||
| Content-Type: text/plain; charset=UTF-8 | ||||
| Content-Transfer-Encoding: 8bit | ||||
|  | ||||
| This parser deals with most TP-Link home routers. It reads info about | ||||
| partitions and registers them in the MTD subsystem. | ||||
|  | ||||
| Example from TP-Link Archer C5 V2: | ||||
|  | ||||
| spi-nor spi0.0: s25fl128s1 (16384 Kbytes) | ||||
| 15 tplink-safeloader partitions found on MTD device spi0.0 | ||||
| Creating 15 MTD partitions on "spi0.0": | ||||
| 0x000000000000-0x000000040000 : "fs-uboot" | ||||
| 0x000000040000-0x000000440000 : "os-image" | ||||
| 0x000000440000-0x000000e40000 : "rootfs" | ||||
| 0x000000e40000-0x000000e40200 : "default-mac" | ||||
| 0x000000e40200-0x000000e40400 : "pin" | ||||
| 0x000000e40400-0x000000e40600 : "product-info" | ||||
| 0x000000e50000-0x000000e60000 : "partition-table" | ||||
| 0x000000e60000-0x000000e60200 : "soft-version" | ||||
| 0x000000e61000-0x000000e70000 : "support-list" | ||||
| 0x000000e70000-0x000000e80000 : "profile" | ||||
| 0x000000e80000-0x000000e90000 : "default-config" | ||||
| 0x000000e90000-0x000000ee0000 : "user-config" | ||||
| 0x000000ee0000-0x000000fe0000 : "log" | ||||
| 0x000000fe0000-0x000000ff0000 : "radio_bk" | ||||
| 0x000000ff0000-0x000001000000 : "radio" | ||||
|  | ||||
| Signed-off-by: Rafał Miłecki <rafal@milecki.pl> | ||||
| Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com> | ||||
| Link: https://lore.kernel.org/linux-mtd/20221015092950.27467-2-zajec5@gmail.com | ||||
| --- | ||||
|  drivers/mtd/parsers/Kconfig             |  15 +++ | ||||
|  drivers/mtd/parsers/Makefile            |   1 + | ||||
|  drivers/mtd/parsers/tplink_safeloader.c | 150 ++++++++++++++++++++++++ | ||||
|  3 files changed, 166 insertions(+) | ||||
|  create mode 100644 drivers/mtd/parsers/tplink_safeloader.c | ||||
|  | ||||
| --- a/drivers/mtd/parsers/Kconfig | ||||
| +++ b/drivers/mtd/parsers/Kconfig | ||||
| @@ -113,6 +113,21 @@ config MTD_AFS_PARTS | ||||
|  	  for your particular device. It won't happen automatically. The | ||||
|  	  'physmap' map driver (CONFIG_MTD_PHYSMAP) does this, for example. | ||||
|   | ||||
| +config MTD_PARSER_TPLINK_SAFELOADER | ||||
| +	tristate "TP-Link Safeloader partitions parser" | ||||
| +	depends on MTD && (ARCH_BCM_5301X || ATH79 || SOC_MT7620 || SOC_MT7621 || COMPILE_TEST) | ||||
| +	help | ||||
| +	  TP-Link home routers use flash partitions to store various data. Info | ||||
| +	  about flash space layout is stored in a partitions table using a | ||||
| +	  custom ASCII-based format. | ||||
| + | ||||
| +	  That format was first found in devices with SafeLoader bootloader and | ||||
| +	  was named after it. Later it was adapted to CFE and U-Boot | ||||
| +	  bootloaders. | ||||
| + | ||||
| +	  This driver reads partitions table, parses it and creates MTD | ||||
| +	  partitions. | ||||
| + | ||||
|  config MTD_PARSER_TRX | ||||
|  	tristate "Parser for TRX format partitions" | ||||
|  	depends on MTD && (BCM47XX || ARCH_BCM_5301X || ARCH_MEDIATEK || RALINK || COMPILE_TEST) | ||||
| --- a/drivers/mtd/parsers/Makefile | ||||
| +++ b/drivers/mtd/parsers/Makefile | ||||
| @@ -9,6 +9,7 @@ ofpart-$(CONFIG_MTD_OF_PARTS_BCM4908)	+= | ||||
|  ofpart-$(CONFIG_MTD_OF_PARTS_LINKSYS_NS)+= ofpart_linksys_ns.o | ||||
|  obj-$(CONFIG_MTD_PARSER_IMAGETAG)	+= parser_imagetag.o | ||||
|  obj-$(CONFIG_MTD_AFS_PARTS)		+= afs.o | ||||
| +obj-$(CONFIG_MTD_PARSER_TPLINK_SAFELOADER)	+= tplink_safeloader.o | ||||
|  obj-$(CONFIG_MTD_PARSER_TRX)		+= parser_trx.o | ||||
|  obj-$(CONFIG_MTD_SERCOMM_PARTS)		+= scpart.o | ||||
|  obj-$(CONFIG_MTD_SHARPSL_PARTS)		+= sharpslpart.o | ||||
| --- /dev/null | ||||
| +++ b/drivers/mtd/parsers/tplink_safeloader.c | ||||
| @@ -0,0 +1,150 @@ | ||||
| +// SPDX-License-Identifier: GPL-2.0-only | ||||
| +/* | ||||
| + * Copyright © 2022 Rafał Miłecki <rafal@milecki.pl> | ||||
| + */ | ||||
| + | ||||
| +#include <linux/kernel.h> | ||||
| +#include <linux/module.h> | ||||
| +#include <linux/mtd/mtd.h> | ||||
| +#include <linux/mtd/partitions.h> | ||||
| +#include <linux/of.h> | ||||
| +#include <linux/slab.h> | ||||
| + | ||||
| +#define TPLINK_SAFELOADER_DATA_OFFSET		4 | ||||
| +#define TPLINK_SAFELOADER_MAX_PARTS		32 | ||||
| + | ||||
| +struct safeloader_cmn_header { | ||||
| +	__be32 size; | ||||
| +	uint32_t unused; | ||||
| +} __packed; | ||||
| + | ||||
| +static void *mtd_parser_tplink_safeloader_read_table(struct mtd_info *mtd) | ||||
| +{ | ||||
| +	struct safeloader_cmn_header hdr; | ||||
| +	struct device_node *np; | ||||
| +	size_t bytes_read; | ||||
| +	size_t offset; | ||||
| +	size_t size; | ||||
| +	char *buf; | ||||
| +	int err; | ||||
| + | ||||
| +	np = mtd_get_of_node(mtd); | ||||
| +	if (mtd_is_partition(mtd)) | ||||
| +		of_node_get(np); | ||||
| +	else | ||||
| +		np = of_get_child_by_name(np, "partitions"); | ||||
| + | ||||
| +	if (of_property_read_u32(np, "partitions-table-offset", (u32 *)&offset)) { | ||||
| +		pr_err("Failed to get partitions table offset\n"); | ||||
| +		goto err_put; | ||||
| +	} | ||||
| + | ||||
| +	err = mtd_read(mtd, offset, sizeof(hdr), &bytes_read, (uint8_t *)&hdr); | ||||
| +	if (err && !mtd_is_bitflip(err)) { | ||||
| +		pr_err("Failed to read from %s at 0x%zx\n", mtd->name, offset); | ||||
| +		goto err_put; | ||||
| +	} | ||||
| + | ||||
| +	size = be32_to_cpu(hdr.size); | ||||
| + | ||||
| +	buf = kmalloc(size + 1, GFP_KERNEL); | ||||
| +	if (!buf) | ||||
| +		goto err_put; | ||||
| + | ||||
| +	err = mtd_read(mtd, offset + sizeof(hdr), size, &bytes_read, buf); | ||||
| +	if (err && !mtd_is_bitflip(err)) { | ||||
| +		pr_err("Failed to read from %s at 0x%zx\n", mtd->name, offset + sizeof(hdr)); | ||||
| +		goto err_kfree; | ||||
| +	} | ||||
| + | ||||
| +	buf[size] = '\0'; | ||||
| + | ||||
| +	of_node_put(np); | ||||
| + | ||||
| +	return buf; | ||||
| + | ||||
| +err_kfree: | ||||
| +	kfree(buf); | ||||
| +err_put: | ||||
| +	of_node_put(np); | ||||
| +	return NULL; | ||||
| +} | ||||
| + | ||||
| +static int mtd_parser_tplink_safeloader_parse(struct mtd_info *mtd, | ||||
| +					      const struct mtd_partition **pparts, | ||||
| +					      struct mtd_part_parser_data *data) | ||||
| +{ | ||||
| +	struct mtd_partition *parts; | ||||
| +	char name[65]; | ||||
| +	size_t offset; | ||||
| +	size_t bytes; | ||||
| +	char *buf; | ||||
| +	int idx; | ||||
| +	int err; | ||||
| + | ||||
| +	parts = kcalloc(TPLINK_SAFELOADER_MAX_PARTS, sizeof(*parts), GFP_KERNEL); | ||||
| +	if (!parts) { | ||||
| +		err = -ENOMEM; | ||||
| +		goto err_out; | ||||
| +	} | ||||
| + | ||||
| +	buf = mtd_parser_tplink_safeloader_read_table(mtd); | ||||
| +	if (!buf) { | ||||
| +		err = -ENOENT; | ||||
| +		goto err_out; | ||||
| +	} | ||||
| + | ||||
| +	for (idx = 0, offset = TPLINK_SAFELOADER_DATA_OFFSET; | ||||
| +	     idx < TPLINK_SAFELOADER_MAX_PARTS && | ||||
| +	     sscanf(buf + offset, "partition %64s base 0x%llx size 0x%llx%zn\n", | ||||
| +		    name, &parts[idx].offset, &parts[idx].size, &bytes) == 3; | ||||
| +	     idx++, offset += bytes + 1) { | ||||
| +		parts[idx].name = kstrdup(name, GFP_KERNEL); | ||||
| +		if (!parts[idx].name) { | ||||
| +			err = -ENOMEM; | ||||
| +			goto err_free; | ||||
| +		} | ||||
| +	} | ||||
| + | ||||
| +	if (idx == TPLINK_SAFELOADER_MAX_PARTS) | ||||
| +		pr_warn("Reached maximum number of partitions!\n"); | ||||
| + | ||||
| +	kfree(buf); | ||||
| + | ||||
| +	*pparts = parts; | ||||
| + | ||||
| +	return idx; | ||||
| + | ||||
| +err_free: | ||||
| +	for (idx -= 1; idx >= 0; idx--) | ||||
| +		kfree(parts[idx].name); | ||||
| +err_out: | ||||
| +	return err; | ||||
| +}; | ||||
| + | ||||
| +static void mtd_parser_tplink_safeloader_cleanup(const struct mtd_partition *pparts, | ||||
| +						 int nr_parts) | ||||
| +{ | ||||
| +	int i; | ||||
| + | ||||
| +	for (i = 0; i < nr_parts; i++) | ||||
| +		kfree(pparts[i].name); | ||||
| + | ||||
| +	kfree(pparts); | ||||
| +} | ||||
| + | ||||
| +static const struct of_device_id mtd_parser_tplink_safeloader_of_match_table[] = { | ||||
| +	{ .compatible = "tplink,safeloader-partitions" }, | ||||
| +	{}, | ||||
| +}; | ||||
| +MODULE_DEVICE_TABLE(of, mtd_parser_tplink_safeloader_of_match_table); | ||||
| + | ||||
| +static struct mtd_part_parser mtd_parser_tplink_safeloader = { | ||||
| +	.parse_fn = mtd_parser_tplink_safeloader_parse, | ||||
| +	.cleanup = mtd_parser_tplink_safeloader_cleanup, | ||||
| +	.name = "tplink-safeloader", | ||||
| +	.of_match_table = mtd_parser_tplink_safeloader_of_match_table, | ||||
| +}; | ||||
| +module_mtd_part_parser(mtd_parser_tplink_safeloader); | ||||
| + | ||||
| +MODULE_LICENSE("GPL"); | ||||
| @@ -0,0 +1,229 @@ | ||||
| From aec4d5f5ffd0f0092bd9dc21ea90e0bc237d4b74 Mon Sep 17 00:00:00 2001 | ||||
| From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl> | ||||
| Date: Sat, 15 Oct 2022 11:29:50 +0200 | ||||
| Subject: [PATCH] mtd: parsers: add TP-Link SafeLoader partitions table parser | ||||
| MIME-Version: 1.0 | ||||
| Content-Type: text/plain; charset=UTF-8 | ||||
| Content-Transfer-Encoding: 8bit | ||||
|  | ||||
| This parser deals with most TP-Link home routers. It reads info about | ||||
| partitions and registers them in the MTD subsystem. | ||||
|  | ||||
| Example from TP-Link Archer C5 V2: | ||||
|  | ||||
| spi-nor spi0.0: s25fl128s1 (16384 Kbytes) | ||||
| 15 tplink-safeloader partitions found on MTD device spi0.0 | ||||
| Creating 15 MTD partitions on "spi0.0": | ||||
| 0x000000000000-0x000000040000 : "fs-uboot" | ||||
| 0x000000040000-0x000000440000 : "os-image" | ||||
| 0x000000440000-0x000000e40000 : "rootfs" | ||||
| 0x000000e40000-0x000000e40200 : "default-mac" | ||||
| 0x000000e40200-0x000000e40400 : "pin" | ||||
| 0x000000e40400-0x000000e40600 : "product-info" | ||||
| 0x000000e50000-0x000000e60000 : "partition-table" | ||||
| 0x000000e60000-0x000000e60200 : "soft-version" | ||||
| 0x000000e61000-0x000000e70000 : "support-list" | ||||
| 0x000000e70000-0x000000e80000 : "profile" | ||||
| 0x000000e80000-0x000000e90000 : "default-config" | ||||
| 0x000000e90000-0x000000ee0000 : "user-config" | ||||
| 0x000000ee0000-0x000000fe0000 : "log" | ||||
| 0x000000fe0000-0x000000ff0000 : "radio_bk" | ||||
| 0x000000ff0000-0x000001000000 : "radio" | ||||
|  | ||||
| Signed-off-by: Rafał Miłecki <rafal@milecki.pl> | ||||
| Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com> | ||||
| Link: https://lore.kernel.org/linux-mtd/20221015092950.27467-2-zajec5@gmail.com | ||||
| --- | ||||
|  drivers/mtd/parsers/Kconfig             |  15 +++ | ||||
|  drivers/mtd/parsers/Makefile            |   1 + | ||||
|  drivers/mtd/parsers/tplink_safeloader.c | 150 ++++++++++++++++++++++++ | ||||
|  3 files changed, 166 insertions(+) | ||||
|  create mode 100644 drivers/mtd/parsers/tplink_safeloader.c | ||||
|  | ||||
| --- a/drivers/mtd/parsers/Kconfig | ||||
| +++ b/drivers/mtd/parsers/Kconfig | ||||
| @@ -113,6 +113,21 @@ config MTD_AFS_PARTS | ||||
|  	  for your particular device. It won't happen automatically. The | ||||
|  	  'physmap' map driver (CONFIG_MTD_PHYSMAP) does this, for example. | ||||
|   | ||||
| +config MTD_PARSER_TPLINK_SAFELOADER | ||||
| +	tristate "TP-Link Safeloader partitions parser" | ||||
| +	depends on MTD && (ARCH_BCM_5301X || ATH79 || SOC_MT7620 || SOC_MT7621 || COMPILE_TEST) | ||||
| +	help | ||||
| +	  TP-Link home routers use flash partitions to store various data. Info | ||||
| +	  about flash space layout is stored in a partitions table using a | ||||
| +	  custom ASCII-based format. | ||||
| + | ||||
| +	  That format was first found in devices with SafeLoader bootloader and | ||||
| +	  was named after it. Later it was adapted to CFE and U-Boot | ||||
| +	  bootloaders. | ||||
| + | ||||
| +	  This driver reads partitions table, parses it and creates MTD | ||||
| +	  partitions. | ||||
| + | ||||
|  config MTD_PARSER_TRX | ||||
|  	tristate "Parser for TRX format partitions" | ||||
|  	depends on MTD && (BCM47XX || ARCH_BCM_5301X || ARCH_MEDIATEK || RALINK || COMPILE_TEST) | ||||
| --- a/drivers/mtd/parsers/Makefile | ||||
| +++ b/drivers/mtd/parsers/Makefile | ||||
| @@ -9,6 +9,7 @@ ofpart-$(CONFIG_MTD_OF_PARTS_BCM4908)	+= | ||||
|  ofpart-$(CONFIG_MTD_OF_PARTS_LINKSYS_NS)+= ofpart_linksys_ns.o | ||||
|  obj-$(CONFIG_MTD_PARSER_IMAGETAG)	+= parser_imagetag.o | ||||
|  obj-$(CONFIG_MTD_AFS_PARTS)		+= afs.o | ||||
| +obj-$(CONFIG_MTD_PARSER_TPLINK_SAFELOADER)	+= tplink_safeloader.o | ||||
|  obj-$(CONFIG_MTD_PARSER_TRX)		+= parser_trx.o | ||||
|  obj-$(CONFIG_MTD_SERCOMM_PARTS)		+= scpart.o | ||||
|  obj-$(CONFIG_MTD_SHARPSL_PARTS)		+= sharpslpart.o | ||||
| --- /dev/null | ||||
| +++ b/drivers/mtd/parsers/tplink_safeloader.c | ||||
| @@ -0,0 +1,150 @@ | ||||
| +// SPDX-License-Identifier: GPL-2.0-only | ||||
| +/* | ||||
| + * Copyright © 2022 Rafał Miłecki <rafal@milecki.pl> | ||||
| + */ | ||||
| + | ||||
| +#include <linux/kernel.h> | ||||
| +#include <linux/module.h> | ||||
| +#include <linux/mtd/mtd.h> | ||||
| +#include <linux/mtd/partitions.h> | ||||
| +#include <linux/of.h> | ||||
| +#include <linux/slab.h> | ||||
| + | ||||
| +#define TPLINK_SAFELOADER_DATA_OFFSET		4 | ||||
| +#define TPLINK_SAFELOADER_MAX_PARTS		32 | ||||
| + | ||||
| +struct safeloader_cmn_header { | ||||
| +	__be32 size; | ||||
| +	uint32_t unused; | ||||
| +} __packed; | ||||
| + | ||||
| +static void *mtd_parser_tplink_safeloader_read_table(struct mtd_info *mtd) | ||||
| +{ | ||||
| +	struct safeloader_cmn_header hdr; | ||||
| +	struct device_node *np; | ||||
| +	size_t bytes_read; | ||||
| +	size_t offset; | ||||
| +	size_t size; | ||||
| +	char *buf; | ||||
| +	int err; | ||||
| + | ||||
| +	np = mtd_get_of_node(mtd); | ||||
| +	if (mtd_is_partition(mtd)) | ||||
| +		of_node_get(np); | ||||
| +	else | ||||
| +		np = of_get_child_by_name(np, "partitions"); | ||||
| + | ||||
| +	if (of_property_read_u32(np, "partitions-table-offset", (u32 *)&offset)) { | ||||
| +		pr_err("Failed to get partitions table offset\n"); | ||||
| +		goto err_put; | ||||
| +	} | ||||
| + | ||||
| +	err = mtd_read(mtd, offset, sizeof(hdr), &bytes_read, (uint8_t *)&hdr); | ||||
| +	if (err && !mtd_is_bitflip(err)) { | ||||
| +		pr_err("Failed to read from %s at 0x%zx\n", mtd->name, offset); | ||||
| +		goto err_put; | ||||
| +	} | ||||
| + | ||||
| +	size = be32_to_cpu(hdr.size); | ||||
| + | ||||
| +	buf = kmalloc(size + 1, GFP_KERNEL); | ||||
| +	if (!buf) | ||||
| +		goto err_put; | ||||
| + | ||||
| +	err = mtd_read(mtd, offset + sizeof(hdr), size, &bytes_read, buf); | ||||
| +	if (err && !mtd_is_bitflip(err)) { | ||||
| +		pr_err("Failed to read from %s at 0x%zx\n", mtd->name, offset + sizeof(hdr)); | ||||
| +		goto err_kfree; | ||||
| +	} | ||||
| + | ||||
| +	buf[size] = '\0'; | ||||
| + | ||||
| +	of_node_put(np); | ||||
| + | ||||
| +	return buf; | ||||
| + | ||||
| +err_kfree: | ||||
| +	kfree(buf); | ||||
| +err_put: | ||||
| +	of_node_put(np); | ||||
| +	return NULL; | ||||
| +} | ||||
| + | ||||
| +static int mtd_parser_tplink_safeloader_parse(struct mtd_info *mtd, | ||||
| +					      const struct mtd_partition **pparts, | ||||
| +					      struct mtd_part_parser_data *data) | ||||
| +{ | ||||
| +	struct mtd_partition *parts; | ||||
| +	char name[65]; | ||||
| +	size_t offset; | ||||
| +	size_t bytes; | ||||
| +	char *buf; | ||||
| +	int idx; | ||||
| +	int err; | ||||
| + | ||||
| +	parts = kcalloc(TPLINK_SAFELOADER_MAX_PARTS, sizeof(*parts), GFP_KERNEL); | ||||
| +	if (!parts) { | ||||
| +		err = -ENOMEM; | ||||
| +		goto err_out; | ||||
| +	} | ||||
| + | ||||
| +	buf = mtd_parser_tplink_safeloader_read_table(mtd); | ||||
| +	if (!buf) { | ||||
| +		err = -ENOENT; | ||||
| +		goto err_out; | ||||
| +	} | ||||
| + | ||||
| +	for (idx = 0, offset = TPLINK_SAFELOADER_DATA_OFFSET; | ||||
| +	     idx < TPLINK_SAFELOADER_MAX_PARTS && | ||||
| +	     sscanf(buf + offset, "partition %64s base 0x%llx size 0x%llx%zn\n", | ||||
| +		    name, &parts[idx].offset, &parts[idx].size, &bytes) == 3; | ||||
| +	     idx++, offset += bytes + 1) { | ||||
| +		parts[idx].name = kstrdup(name, GFP_KERNEL); | ||||
| +		if (!parts[idx].name) { | ||||
| +			err = -ENOMEM; | ||||
| +			goto err_free; | ||||
| +		} | ||||
| +	} | ||||
| + | ||||
| +	if (idx == TPLINK_SAFELOADER_MAX_PARTS) | ||||
| +		pr_warn("Reached maximum number of partitions!\n"); | ||||
| + | ||||
| +	kfree(buf); | ||||
| + | ||||
| +	*pparts = parts; | ||||
| + | ||||
| +	return idx; | ||||
| + | ||||
| +err_free: | ||||
| +	for (idx -= 1; idx >= 0; idx--) | ||||
| +		kfree(parts[idx].name); | ||||
| +err_out: | ||||
| +	return err; | ||||
| +}; | ||||
| + | ||||
| +static void mtd_parser_tplink_safeloader_cleanup(const struct mtd_partition *pparts, | ||||
| +						 int nr_parts) | ||||
| +{ | ||||
| +	int i; | ||||
| + | ||||
| +	for (i = 0; i < nr_parts; i++) | ||||
| +		kfree(pparts[i].name); | ||||
| + | ||||
| +	kfree(pparts); | ||||
| +} | ||||
| + | ||||
| +static const struct of_device_id mtd_parser_tplink_safeloader_of_match_table[] = { | ||||
| +	{ .compatible = "tplink,safeloader-partitions" }, | ||||
| +	{}, | ||||
| +}; | ||||
| +MODULE_DEVICE_TABLE(of, mtd_parser_tplink_safeloader_of_match_table); | ||||
| + | ||||
| +static struct mtd_part_parser mtd_parser_tplink_safeloader = { | ||||
| +	.parse_fn = mtd_parser_tplink_safeloader_parse, | ||||
| +	.cleanup = mtd_parser_tplink_safeloader_cleanup, | ||||
| +	.name = "tplink-safeloader", | ||||
| +	.of_match_table = mtd_parser_tplink_safeloader_of_match_table, | ||||
| +}; | ||||
| +module_mtd_part_parser(mtd_parser_tplink_safeloader); | ||||
| + | ||||
| +MODULE_LICENSE("GPL"); | ||||
| @@ -16,7 +16,7 @@ Signed-off-by: Thibaut VARÈNE <hacks@slashdirt.org> | ||||
|  | ||||
| --- a/drivers/mtd/parsers/Kconfig | ||||
| +++ b/drivers/mtd/parsers/Kconfig | ||||
| @@ -204,3 +204,12 @@ config MTD_SERCOMM_PARTS | ||||
| @@ -219,3 +219,12 @@ config MTD_SERCOMM_PARTS | ||||
|  	  partition map. This partition table contains real partition | ||||
|  	  offsets, which may differ from device to device depending on the | ||||
|  	  number and location of bad blocks on NAND. | ||||
| @@ -31,7 +31,7 @@ Signed-off-by: Thibaut VARÈNE <hacks@slashdirt.org> | ||||
| +	 formatted DTS. | ||||
| --- a/drivers/mtd/parsers/Makefile | ||||
| +++ b/drivers/mtd/parsers/Makefile | ||||
| @@ -14,3 +14,4 @@ obj-$(CONFIG_MTD_PARSER_TRX)		+= parser_ | ||||
| @@ -15,3 +15,4 @@ obj-$(CONFIG_MTD_PARSER_TRX)		+= parser_ | ||||
|  obj-$(CONFIG_MTD_SERCOMM_PARTS)		+= scpart.o | ||||
|  obj-$(CONFIG_MTD_SHARPSL_PARTS)		+= sharpslpart.o | ||||
|  obj-$(CONFIG_MTD_REDBOOT_PARTS)		+= redboot.o | ||||
|   | ||||
| @@ -16,7 +16,7 @@ Signed-off-by: Thibaut VARÈNE <hacks@slashdirt.org> | ||||
|  | ||||
| --- a/drivers/mtd/parsers/Kconfig | ||||
| +++ b/drivers/mtd/parsers/Kconfig | ||||
| @@ -211,3 +211,12 @@ config MTD_SERCOMM_PARTS | ||||
| @@ -226,3 +226,12 @@ config MTD_SERCOMM_PARTS | ||||
|  	  partition map. This partition table contains real partition | ||||
|  	  offsets, which may differ from device to device depending on the | ||||
|  	  number and location of bad blocks on NAND. | ||||
| @@ -31,7 +31,7 @@ Signed-off-by: Thibaut VARÈNE <hacks@slashdirt.org> | ||||
| +	 formatted DTS. | ||||
| --- a/drivers/mtd/parsers/Makefile | ||||
| +++ b/drivers/mtd/parsers/Makefile | ||||
| @@ -15,3 +15,4 @@ obj-$(CONFIG_MTD_SERCOMM_PARTS)		+= scpa | ||||
| @@ -16,3 +16,4 @@ obj-$(CONFIG_MTD_SERCOMM_PARTS)		+= scpa | ||||
|  obj-$(CONFIG_MTD_SHARPSL_PARTS)		+= sharpslpart.o | ||||
|  obj-$(CONFIG_MTD_REDBOOT_PARTS)		+= redboot.o | ||||
|  obj-$(CONFIG_MTD_QCOMSMEM_PARTS)	+= qcomsmempart.o | ||||
|   | ||||
| @@ -112,6 +112,7 @@ CONFIG_MODULES_USE_ELF_REL=y | ||||
| # CONFIG_MT7621_WDT is not set | ||||
| # CONFIG_MTD_CFI_INTELEXT is not set | ||||
| CONFIG_MTD_CMDLINE_PARTS=y | ||||
| # CONFIG_MTD_PARSER_TPLINK_SAFELOADER is not set | ||||
| CONFIG_MTD_PHYSMAP=y | ||||
| CONFIG_MTD_SPI_NOR=y | ||||
| CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y | ||||
|   | ||||
| @@ -113,6 +113,7 @@ CONFIG_MODULES_USE_ELF_REL=y | ||||
| # CONFIG_MT7621_WDT is not set | ||||
| # CONFIG_MTD_CFI_INTELEXT is not set | ||||
| CONFIG_MTD_CMDLINE_PARTS=y | ||||
| # CONFIG_MTD_PARSER_TPLINK_SAFELOADER is not set | ||||
| CONFIG_MTD_PHYSMAP=y | ||||
| CONFIG_MTD_SPI_NOR=y | ||||
| CONFIG_MTD_SPI_NOR_USE_VARIABLE_ERASE=y | ||||
|   | ||||
| @@ -159,6 +159,7 @@ CONFIG_MTD_NAND_ECC=y | ||||
| CONFIG_MTD_NAND_ECC_SW_HAMMING=y | ||||
| CONFIG_MTD_NAND_MT7621=y | ||||
| CONFIG_MTD_NAND_MTK_BMT=y | ||||
| # CONFIG_MTD_PARSER_TPLINK_SAFELOADER is not set | ||||
| CONFIG_MTD_PHYSMAP=y | ||||
| CONFIG_MTD_RAW_NAND=y | ||||
| CONFIG_MTD_ROUTERBOOT_PARTS=y | ||||
|   | ||||
| @@ -160,6 +160,7 @@ CONFIG_MTD_NAND_ECC=y | ||||
| CONFIG_MTD_NAND_ECC_SW_HAMMING=y | ||||
| CONFIG_MTD_NAND_MT7621=y | ||||
| CONFIG_MTD_NAND_MTK_BMT=y | ||||
| # CONFIG_MTD_PARSER_TPLINK_SAFELOADER is not set | ||||
| CONFIG_MTD_PHYSMAP=y | ||||
| CONFIG_MTD_RAW_NAND=y | ||||
| CONFIG_MTD_ROUTERBOOT_PARTS=y | ||||
|   | ||||
| @@ -110,6 +110,7 @@ CONFIG_MODULES_USE_ELF_REL=y | ||||
| CONFIG_MT7621_WDT=y | ||||
| # CONFIG_MTD_CFI_INTELEXT is not set | ||||
| CONFIG_MTD_CMDLINE_PARTS=y | ||||
| # CONFIG_MTD_PARSER_TPLINK_SAFELOADER is not set | ||||
| CONFIG_MTD_PARSER_TRX=y | ||||
| CONFIG_MTD_PHYSMAP=y | ||||
| CONFIG_MTD_SPI_NOR=y | ||||
|   | ||||
| @@ -111,6 +111,7 @@ CONFIG_MODULES_USE_ELF_REL=y | ||||
| CONFIG_MT7621_WDT=y | ||||
| # CONFIG_MTD_CFI_INTELEXT is not set | ||||
| CONFIG_MTD_CMDLINE_PARTS=y | ||||
| # CONFIG_MTD_PARSER_TPLINK_SAFELOADER is not set | ||||
| CONFIG_MTD_PARSER_TRX=y | ||||
| CONFIG_MTD_PHYSMAP=y | ||||
| CONFIG_MTD_SPI_NOR=y | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Rafał Miłecki
					Rafał Miłecki