[RFT PATCH] ramips: use partition table on Netgear NAND devices

Adrian Schmutzler mail at adrianschmutzler.de
Fri Jan 22 07:47:37 EST 2021


> -----Original Message-----
> From: openwrt-devel [mailto:openwrt-devel-bounces at lists.openwrt.org]
> On Behalf Of Jost Menke
> Sent: Freitag, 22. Januar 2021 13:25
> To: Jan Hoffmann <jan at 3e8.eu>; openwrt-devel at lists.openwrt.org
> Cc: drvlabo at gmail.com; mail at david-bauer.net
> Subject: Re: [RFT PATCH] ramips: use partition table on Netgear NAND
> devices
> 
> I successfully tested this patch on a Netgear R6800 with one bad eraseblock.
> Without the patch, the device is unable to correctly read the factory
> partition. It will generate random MAC addresses because the actual
> addresses are unreadable, and TX power will be limited to 6dBm, rendering it
> rather useless.
> With the patch, everything works as expected.

Thanks for the test.

If this patch is revived somehow, it would be a good idea to split it into two parts, first adding the parser changes and then separately implementing it for the devices (DTS).

Best

Adrian

> 
> 
> Regards
> 
> Jost
> 
> 
> Am 29.06.20 um 01:27 schrieb Jan Hoffmann:
> > There have been multiple reports of the partition table on these
> > devices being incorrect when there are bad blocks. This change should
> > fix this by parsing the partition table that is stored in the SC_PART_MAP
> partition.
> >
> > This is essentially the same code as proposed in the original pull
> > request for Netgear R6350 support by NOGUCHI Hiroshi
> <drvlabo at gmail.com>:
> > https://github.com/openwrt/openwrt/pull/1318
> >
> > At the time, it was rejected in favor of fixed partition offsets, as
> > it did not seem to work correctly. However, this was due the NAND
> > driver transparently shifting pages to hide bad blocks, which was
> > fixed in commit 527832e54bf3bc4d699a145ae66f34230246f0a9.
> >
> > Signed-off-by: Jan Hoffmann <jan at 3e8.eu>
> > ---
> >
> > So far this patch has only been tested on my own WAC124, which doesn't
> > have any bad blocks (i.e. the partition table that is read from flash
> > matches the existing fixed offsets).
> >
> > It needs further testing to verify that it actually fixes the issue on
> > devices that have bad blocks, and does not cause any additional issues.
> >
> > This change applies to the following devices:
> > R6260, R6350, R6850, WAC124 (CHJ)
> > R6800, R6700-v2, R7200, Nighthawk AC2400 (BZV)
> >
> >
> >   .../dts/mt7621_netgear_sercomm_bzv.dtsi       | 169 +++++++++++-
> >   .../dts/mt7621_netgear_sercomm_chj.dtsi       | 169 +++++++++++-
> >   .../ramips/files/drivers/mtd/parsers/scpart.c | 257
> ++++++++++++++++++
> >   target/linux/ramips/mt7621/config-5.4         |   1 +
> >   .../patches-5.4/303-mtd-scpart-parser.patch   |  19 ++
> >   5 files changed, 607 insertions(+), 8 deletions(-)
> >   create mode 100644
> target/linux/ramips/files/drivers/mtd/parsers/scpart.c
> >   create mode 100644
> > target/linux/ramips/patches-5.4/303-mtd-scpart-parser.patch
> >
> > diff --git a/target/linux/ramips/dts/mt7621_netgear_sercomm_bzv.dtsi
> > b/target/linux/ramips/dts/mt7621_netgear_sercomm_bzv.dtsi
> > index d2e5502e48..2ab0b75862 100644
> > --- a/target/linux/ramips/dts/mt7621_netgear_sercomm_bzv.dtsi
> > +++ b/target/linux/ramips/dts/mt7621_netgear_sercomm_bzv.dtsi
> > @@ -113,47 +113,208 @@
> >   	status = "okay";
> >
> >   	partitions {
> > -		compatible = "fixed-partitions";
> > +		compatible = "sercomm,sc-partitions", "fixed-partitions";
> >   		#address-cells = <1>;
> >   		#size-cells = <1>;
> >
> >   		partition at 0 {
> >   			label = "u-boot";
> >   			reg = <0x0 0x100000>;
> > +			scpart-id = <0>;
> >   			read-only;
> >   		};
> >
> >   		partition at 100000 {
> >   			label = "SC PART_MAP";
> >   			reg = <0x100000 0x100000>;
> > +			scpart-id = <1>;
> >   			read-only;
> >   		};
> >
> >   		partition at 200000 {
> >   			label = "kernel";
> >   			reg = <0x200000 0x400000>;
> > +			scpart-id = <2>;
> >   		};
> >
> >   		partition at 600000 {
> >   			label = "ubi";
> >   			reg = <0x600000 0x2800000>;
> > +			scpart-id = <3>;
> >   		};
> >
> >   		partition at 2e00000 {
> > -			label = "reserved0";
> > -			reg = <0x2e00000 0x1800000>;
> > +			label = "English UI";
> > +			reg = <0x2e00000 0x200000>;
> > +			scpart-id = <4>;
> > +			read-only;
> > +		};
> > +
> > +		partition at 3000000 {
> > +			label = "ML1";
> > +			reg = <0x3000000 0x200000>;
> > +			scpart-id = <5>;
> > +			read-only;
> > +		};
> > +
> > +		partition at 3200000 {
> > +			label = "ML2";
> > +			reg = <0x3200000 0x200000>;
> > +			scpart-id = <6>;
> > +			read-only;
> > +		};
> > +
> > +		partition at 3400000 {
> > +			label = "ML3";
> > +			reg = <0x3400000 0x200000>;
> > +			scpart-id = <7>;
> > +			read-only;
> > +		};
> > +
> > +		partition at 3600000 {
> > +			label = "ML4";
> > +			reg = <0x3600000 0x200000>;
> > +			scpart-id = <8>;
> > +			read-only;
> > +		};
> > +
> > +		partition at 3800000 {
> > +			label = "ML5";
> > +			reg = <0x3800000 0x200000>;
> > +			scpart-id = <9>;
> > +			read-only;
> > +		};
> > +
> > +		partition at 3a00000 {
> > +			label = "ML6";
> > +			reg = <0x3a00000 0x200000>;
> > +			scpart-id = <10>;
> > +			read-only;
> > +		};
> > +
> > +		partition at 3c00000 {
> > +			label = "ML7";
> > +			reg = <0x3c00000 0x200000>;
> > +			scpart-id = <11>;
> > +			read-only;
> > +		};
> > +
> > +		partition at 3e00000 {
> > +			label = "ML8";
> > +			reg = <0x3e00000 0x200000>;
> > +			scpart-id = <12>;
> > +			read-only;
> > +		};
> > +
> > +		partition at 4000000 {
> > +			label = "ML9";
> > +			reg = <0x4000000 0x200000>;
> > +			scpart-id = <13>;
> > +			read-only;
> > +		};
> > +
> > +		partition at 4200000 {
> > +			label = "ML10";
> > +			reg = <0x4200000 0x200000>;
> > +			scpart-id = <14>;
> > +			read-only;
> > +		};
> > +
> > +		partition at 4400000 {
> > +			label = "ML11";
> > +			reg = <0x4400000 0x200000>;
> > +			scpart-id = <15>;
> >   			read-only;
> >   		};
> >
> >   		factory: partition at 4600000 {
> >   			label = "factory";
> >   			reg = <0x4600000 0x200000>;
> > +			scpart-id = <16>;
> >   			read-only;
> >   		};
> >
> >   		partition at 4800000 {
> > +			label = "SC Private Data";
> > +			reg = <0x4800000 0x200000>;
> > +			scpart-id = <17>;
> > +			read-only;
> > +		};
> > +
> > +		partition at 4a00000 {
> > +			label = "POT";
> > +			reg = <0x4a00000 0x200000>;
> > +			scpart-id = <18>;
> > +			read-only;
> > +		};
> > +
> > +		partition at 4c00000 {
> > +			label = "Traffic Meter";
> > +			reg = <0x4c00000 0x200000>;
> > +			scpart-id = <19>;
> > +			read-only;
> > +		};
> > +
> > +		partition at 4e00000 {
> > +			label = "SC PID";
> > +			reg = <0x4e00000 0x200000>;
> > +			scpart-id = <20>;
> > +			read-only;
> > +		};
> > +
> > +		partition at 5000000 {
> > +			label = "SC Nvram";
> > +			reg = <0x5000000 0x200000>;
> > +			scpart-id = <21>;
> > +			read-only;
> > +		};
> > +
> > +		partition at 5200000 {
> > +			label = "Ralink Nvram";
> > +			reg = <0x5200000 0x200000>;
> > +			scpart-id = <22>;
> > +			read-only;
> > +		};
> > +
> > +		partition at 5400000 {
> > +			label = "reserved0";
> > +			reg = <0x5400000 0x200000>;
> > +			scpart-id = <23>;
> > +			read-only;
> > +		};
> > +
> > +		partition at 5600000 {
> >   			label = "reserved1";
> > -			reg = <0x4800000 0x3800000>;
> > +			reg = <0x5600000 0x200000>;
> > +			scpart-id = <24>;
> > +			read-only;
> > +		};
> > +
> > +		partition at 5800000 {
> > +			label = "reserved2";
> > +			reg = <0x5800000 0x200000>;
> > +			scpart-id = <25>;
> > +			read-only;
> > +		};
> > +
> > +		partition at 5a00000 {
> > +			label = "reserved3";
> > +			reg = <0x5a00000 0x200000>;
> > +			scpart-id = <26>;
> > +			read-only;
> > +		};
> > +
> > +		partition at 5c00000 {
> > +			label = "reserved4";
> > +			reg = <0x5c00000 0x200000>;
> > +			scpart-id = <27>;
> > +			read-only;
> > +		};
> > +
> > +		partition at 5e00000 {
> > +			label = "reserved5";
> > +			reg = <0x5e00000 0x2180000>;
> > +			scpart-id = <28>;
> >   			read-only;
> >   		};
> >   	};
> > diff --git a/target/linux/ramips/dts/mt7621_netgear_sercomm_chj.dtsi
> > b/target/linux/ramips/dts/mt7621_netgear_sercomm_chj.dtsi
> > index b781edf6be..b593ee0cd6 100644
> > --- a/target/linux/ramips/dts/mt7621_netgear_sercomm_chj.dtsi
> > +++ b/target/linux/ramips/dts/mt7621_netgear_sercomm_chj.dtsi
> > @@ -141,47 +141,208 @@
> >   	status = "okay";
> >
> >   	partitions {
> > -		compatible = "fixed-partitions";
> > +		compatible = "sercomm,sc-partitions", "fixed-partitions";
> >   		#address-cells = <1>;
> >   		#size-cells = <1>;
> >
> >   		partition at 0 {
> >   			label = "u-boot";
> >   			reg = <0x0 0x100000>;
> > +			scpart-id = <0>;
> >   			read-only;
> >   		};
> >
> >   		partition at 100000 {
> >   			label = "SC PART_MAP";
> >   			reg = <0x100000 0x100000>;
> > +			scpart-id = <1>;
> >   			read-only;
> >   		};
> >
> >   		partition at 200000 {
> >   			label = "kernel";
> >   			reg = <0x200000 0x400000>;
> > +			scpart-id = <2>;
> >   		};
> >
> >   		partition at 600000 {
> >   			label = "ubi";
> >   			reg = <0x600000 0x2800000>;
> > +			scpart-id = <3>;
> >   		};
> >
> >   		partition at 2e00000 {
> > -			label = "reserved0";
> > -			reg = <0x2e00000 0x1800000>;
> > +			label = "English UI";
> > +			reg = <0x2e00000 0x200000>;
> > +			scpart-id = <4>;
> > +			read-only;
> > +		};
> > +
> > +		partition at 3000000 {
> > +			label = "ML1";
> > +			reg = <0x3000000 0x200000>;
> > +			scpart-id = <5>;
> > +			read-only;
> > +		};
> > +
> > +		partition at 3200000 {
> > +			label = "ML2";
> > +			reg = <0x3200000 0x200000>;
> > +			scpart-id = <6>;
> > +			read-only;
> > +		};
> > +
> > +		partition at 3400000 {
> > +			label = "ML3";
> > +			reg = <0x3400000 0x200000>;
> > +			scpart-id = <7>;
> > +			read-only;
> > +		};
> > +
> > +		partition at 3600000 {
> > +			label = "ML4";
> > +			reg = <0x3600000 0x200000>;
> > +			scpart-id = <8>;
> > +			read-only;
> > +		};
> > +
> > +		partition at 3800000 {
> > +			label = "ML5";
> > +			reg = <0x3800000 0x200000>;
> > +			scpart-id = <9>;
> > +			read-only;
> > +		};
> > +
> > +		partition at 3a00000 {
> > +			label = "ML6";
> > +			reg = <0x3a00000 0x200000>;
> > +			scpart-id = <10>;
> > +			read-only;
> > +		};
> > +
> > +		partition at 3c00000 {
> > +			label = "ML7";
> > +			reg = <0x3c00000 0x200000>;
> > +			scpart-id = <11>;
> > +			read-only;
> > +		};
> > +
> > +		partition at 3e00000 {
> > +			label = "ML8";
> > +			reg = <0x3e00000 0x200000>;
> > +			scpart-id = <12>;
> > +			read-only;
> > +		};
> > +
> > +		partition at 4000000 {
> > +			label = "ML9";
> > +			reg = <0x4000000 0x200000>;
> > +			scpart-id = <13>;
> > +			read-only;
> > +		};
> > +
> > +		partition at 4200000 {
> > +			label = "ML10";
> > +			reg = <0x4200000 0x200000>;
> > +			scpart-id = <14>;
> > +			read-only;
> > +		};
> > +
> > +		partition at 4400000 {
> > +			label = "ML11";
> > +			reg = <0x4400000 0x200000>;
> > +			scpart-id = <15>;
> >   			read-only;
> >   		};
> >
> >   		factory: partition at 4600000 {
> >   			label = "factory";
> >   			reg = <0x4600000 0x200000>;
> > +			scpart-id = <16>;
> >   			read-only;
> >   		};
> >
> >   		partition at 4800000 {
> > +			label = "SC Private Data";
> > +			reg = <0x4800000 0x200000>;
> > +			scpart-id = <17>;
> > +			read-only;
> > +		};
> > +
> > +		partition at 4a00000 {
> > +			label = "POT";
> > +			reg = <0x4a00000 0x200000>;
> > +			scpart-id = <18>;
> > +			read-only;
> > +		};
> > +
> > +		partition at 4c00000 {
> > +			label = "Traffic Meter";
> > +			reg = <0x4c00000 0x200000>;
> > +			scpart-id = <19>;
> > +			read-only;
> > +		};
> > +
> > +		partition at 4e00000 {
> > +			label = "SC PID";
> > +			reg = <0x4e00000 0x200000>;
> > +			scpart-id = <20>;
> > +			read-only;
> > +		};
> > +
> > +		partition at 5000000 {
> > +			label = "SC Nvram";
> > +			reg = <0x5000000 0x200000>;
> > +			scpart-id = <21>;
> > +			read-only;
> > +		};
> > +
> > +		partition at 5200000 {
> > +			label = "Ralink Nvram";
> > +			reg = <0x5200000 0x200000>;
> > +			scpart-id = <22>;
> > +			read-only;
> > +		};
> > +
> > +		partition at 5400000 {
> > +			label = "reserved0";
> > +			reg = <0x5400000 0x200000>;
> > +			scpart-id = <23>;
> > +			read-only;
> > +		};
> > +
> > +		partition at 5600000 {
> >   			label = "reserved1";
> > -			reg = <0x4800000 0x3800000>;
> > +			reg = <0x5600000 0x200000>;
> > +			scpart-id = <24>;
> > +			read-only;
> > +		};
> > +
> > +		partition at 5800000 {
> > +			label = "reserved2";
> > +			reg = <0x5800000 0x200000>;
> > +			scpart-id = <25>;
> > +			read-only;
> > +		};
> > +
> > +		partition at 5a00000 {
> > +			label = "reserved3";
> > +			reg = <0x5a00000 0x200000>;
> > +			scpart-id = <26>;
> > +			read-only;
> > +		};
> > +
> > +		partition at 5c00000 {
> > +			label = "reserved4";
> > +			reg = <0x5c00000 0x200000>;
> > +			scpart-id = <27>;
> > +			read-only;
> > +		};
> > +
> > +		partition at 5e00000 {
> > +			label = "reserved5";
> > +			reg = <0x5e00000 0x2180000>;
> > +			scpart-id = <28>;
> >   			read-only;
> >   		};
> >   	};
> > diff --git a/target/linux/ramips/files/drivers/mtd/parsers/scpart.c
> > b/target/linux/ramips/files/drivers/mtd/parsers/scpart.c
> > new file mode 100644
> > index 0000000000..36c3c0bb36
> > --- /dev/null
> > +++ b/target/linux/ramips/files/drivers/mtd/parsers/scpart.c
> > @@ -0,0 +1,257 @@
> > +/*
> > + *
> > + * This program is free software; you can redistribute it and/or
> > +modify
> > + * it under the terms of the GNU General Public License as published
> > +by
> > + * the Free Software Foundation; either version 2 of the License, or
> > + * (at your option) any later version.
> > + *
> > + * This program is distributed in the hope that it will be useful,
> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> > + * GNU General Public License for more details.
> > + *
> > + * You should have received a copy of the GNU General Public License
> > + * along with this program; if not, write to the Free Software
> > + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
> > +02110-1301  USA
> > + *
> > + * Sercomm/Netgear FLASH partition table.
> > + */
> > +
> > +
> > +#include <linux/kernel.h>
> > +#include <linux/slab.h>
> > +#include <linux/mtd/mtd.h>
> > +#include <linux/mtd/partitions.h>
> > +#include <linux/module.h>
> > +
> > +
> > +#define	MOD_NAME	"scpart"
> > +
> > +static const char sc_part_magic[] = {
> > +	'S', 'C', 'F', 'L', 'M', 'A', 'P', 'O', 'K', '\0', };
> > +#define	PART_MAGIC_LEN	sizeof(sc_part_magic)
> > +
> > +/* assumes that all fields are set by CPU native endian */ struct
> > +sc_part_desc {
> > +	uint32_t	part_id;
> > +	uint32_t	part_offs;
> > +	uint32_t	part_bytes;
> > +};
> > +#define	ID_ALREADY_FOUND	(0xFFFFFFFFUL)
> > +
> > +#define	MAP_OFFS_IN_BLK	(0x800)
> > +
> > +#define	MAP_MIRROR_NUM	(2)
> > +
> > +static int scpart_desc_is_valid(struct sc_part_desc *pdesc) {
> > +	return !!((pdesc->part_id != 0xFFFFFFFFUL) &&
> > +			(pdesc->part_offs != 0xFFFFFFFFUL) &&
> > +			(pdesc->part_bytes != 0xFFFFFFFFUL)); }
> > +
> > +static int scpart_scan_partmap(struct mtd_info *master, loff_t
> partmap_offs,
> > +				struct sc_part_desc **ppdesc)
> > +{
> > +	uint8_t *buf;
> > +	loff_t offs;
> > +	size_t retlen;
> > +	struct sc_part_desc *pdesc = NULL;
> > +	struct sc_part_desc *tmpdesc;
> > +	int cnt = 0;
> > +	int res2;
> > +	int res = 0;
> > +
> > +	buf = kzalloc(master->erasesize, GFP_KERNEL);
> > +	if (!buf) {
> > +		res = -ENOMEM;
> > +		goto out;
> > +	}
> > +
> > +	res2 = mtd_read(master, partmap_offs, master->erasesize, &retlen,
> buf);
> > +	if (res2 || (retlen != master->erasesize)) {
> > +		res = -EIO;
> > +		goto free;
> > +	}
> > +
> > +	offs = MAP_OFFS_IN_BLK;
> > +	while((offs + sizeof(*tmpdesc)) < master->erasesize) {
> > +		tmpdesc = (struct sc_part_desc*)&(buf[offs]);
> > +		if (!scpart_desc_is_valid(tmpdesc))
> > +			break;
> > +		cnt++;
> > +		offs += sizeof(*tmpdesc);
> > +	}
> > +
> > +	if (cnt > 0) {
> > +		int bytes = cnt * sizeof(*pdesc);
> > +
> > +		pdesc = kzalloc(bytes, GFP_KERNEL);
> > +		if (!pdesc) {
> > +			res = -ENOMEM;
> > +			goto free;
> > +		}
> > +		memcpy(pdesc, &(buf[MAP_OFFS_IN_BLK]), bytes);
> > +
> > +		*ppdesc = pdesc;
> > +		res = cnt;
> > +	}
> > +
> > +  free:
> > +	kfree(buf);
> > +
> > +  out:
> > +	return res;
> > +}
> > +
> > +static int scpart_find_partmap(struct mtd_info *master,
> > +				struct sc_part_desc **ppdesc)
> > +{
> > +	loff_t offs;
> > +	uint8_t rdbuf[PART_MAGIC_LEN];
> > +	size_t retlen;
> > +	int magic_found = 0;
> > +	int res2;
> > +	int res = 0;
> > +
> > +	offs = 0;
> > +	while((magic_found < MAP_MIRROR_NUM) &&
> > +			(offs < master->size) && !mtd_block_isbad(master,
> offs)) {
> > +		res2 = mtd_read(master, offs, PART_MAGIC_LEN, &retlen,
> rdbuf);
> > +		if (res2 || (retlen != PART_MAGIC_LEN)) {
> > +			res = -EIO;
> > +			goto out;
> > +		}
> > +		if (!memcmp(rdbuf, sc_part_magic, PART_MAGIC_LEN)) {
> > +			pr_debug("%s: signature found at 0x%llx\n",
> MOD_NAME, offs);
> > +			magic_found++;
> > +			res = scpart_scan_partmap(master, offs, ppdesc);
> > +			if (res > 0)
> > +				goto out;
> > +		}
> > +		offs += master->erasesize;
> > +	}
> > +
> > +  out:
> > +	if (res > 0)
> > +		pr_info("%s: valid 'SC PART MAP' found (%d partitions)\n",
> MOD_NAME, res);
> > +	else
> > +		pr_info("%s: no valid 'SC PART MAP'\n", MOD_NAME);
> > +
> > +	return res;
> > +}
> > +
> > +static int scpart_parse(struct mtd_info *master,
> > +			const struct mtd_partition **pparts,
> > +			struct mtd_part_parser_data *data) {
> > +	struct sc_part_desc *scpart_map = NULL;
> > +	struct mtd_partition *parts = NULL;
> > +	struct device_node *mtd_node;
> > +	struct device_node *ofpart_node;
> > +	struct device_node *pp;
> > +	const char *partname;
> > +	int nr_scparts;
> > +	int nr_parts = 0;
> > +	int n;
> > +	int res = 0;
> > +
> > +	mtd_node = mtd_get_of_node(master);
> > +	if (!mtd_node)
> > +		goto out;
> > +
> > +	ofpart_node = of_get_child_by_name(mtd_node, "partitions");
> > +	if (!ofpart_node)
> > +		goto out;
> > +
> > +	nr_scparts = scpart_find_partmap(master, &scpart_map);
> > +	if (nr_scparts <= 0) {
> > +		res = nr_scparts;
> > +		goto free;
> > +	}
> > +
> > +	for_each_child_of_node(ofpart_node, pp) {
> > +		u32 scpart_id;
> > +		struct mtd_partition *parts_tmp;
> > +
> > +		if(of_property_read_u32(pp, "scpart-id", &scpart_id))
> > +			continue;
> > +
> > +		for (n = 0 ; n < nr_scparts ; n++)
> > +			if ((scpart_map[n].part_id != ID_ALREADY_FOUND)
> &&
> > +					(scpart_id == scpart_map[n].part_id))
> > +				break;
> > +		if (n >= nr_scparts)
> > +			/* not match */
> > +			continue;
> > +
> > +		/* add the partition found in OF into MTD partition array */
> > +
> > +		/* reallocate partition array */
> > +		parts_tmp = parts;
> > +		parts = kzalloc((nr_parts + 1) * sizeof(*parts), GFP_KERNEL);
> > +		if (!parts) {
> > +			kfree(parts_tmp);
> > +			res = -ENOMEM;
> > +			goto free;
> > +		}
> > +		if (parts_tmp) {
> > +			memcpy(parts, parts_tmp, nr_parts * sizeof(*parts));
> > +			kfree(parts_tmp);
> > +		}
> > +
> > +		parts[nr_parts].offset = scpart_map[n].part_offs;
> > +		parts[nr_parts].size = scpart_map[n].part_bytes;
> > +		parts[nr_parts].of_node = pp;
> > +
> > +		if (!of_property_read_string(pp, "label", &partname) ||
> > +				!of_property_read_string(pp, "name",
> &partname))
> > +			parts[nr_parts].name = partname;
> > +
> > +		if (of_property_read_bool(pp, "read-only"))
> > +			parts[nr_parts].mask_flags |= MTD_WRITEABLE;
> > +		if (of_property_read_bool(pp, "lock"))
> > +			parts[nr_parts].mask_flags |=
> MTD_POWERUP_LOCK;
> > +
> > +		/* mark as 'done' */
> > +		scpart_map[n].part_id = ID_ALREADY_FOUND;
> > +
> > +		nr_parts++;
> > +	}
> > +	if (nr_parts > 0) {
> > +		*pparts = parts;
> > +		res = nr_parts;
> > +	} else
> > +		pr_info("%s: No partition in OF matches partition ID with 'SC
> PART MAP'.\n",
> > +				MOD_NAME);
> > +
> > +	of_node_put(pp);
> > +
> > +  free:
> > +	kfree(scpart_map);
> > +	if (res <= 0)
> > +		kfree(parts);
> > +
> > +  out:
> > +	return res;
> > +}
> > +
> > +static const struct of_device_id scpart_parser_of_match_table[] = {
> > +	{ .compatible = "sercomm,sc-partitions" },
> > +	{},
> > +};
> > +MODULE_DEVICE_TABLE(of, scpart_parser_of_match_table);
> > +
> > +static struct mtd_part_parser scpart_parser = {
> > +	.parse_fn = scpart_parse,
> > +	.name = "scpart",
> > +	.of_match_table = scpart_parser_of_match_table, };
> > +module_mtd_part_parser(scpart_parser);
> > +
> > +/* mtd parsers will request the module by parser name */
> > +MODULE_ALIAS("scpart"); MODULE_LICENSE("GPL");
> MODULE_AUTHOR("NOGUCHI
> > +Hiroshi <drvlabo at gmail.com>"); MODULE_DESCRIPTION("Parsing code
> for
> > +Sercomm/Netgear partition table");
> > diff --git a/target/linux/ramips/mt7621/config-5.4
> > b/target/linux/ramips/mt7621/config-5.4
> > index b2c3ad5ba8..712ac388f1 100644
> > --- a/target/linux/ramips/mt7621/config-5.4
> > +++ b/target/linux/ramips/mt7621/config-5.4
> > @@ -203,6 +203,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_SERCOMM_PARTS=y
> >   CONFIG_MTD_NAND_CORE=y
> >   CONFIG_MTD_NAND_ECC_SW_HAMMING=y
> >   CONFIG_MTD_NAND_MT7621=y
> > diff --git
> > a/target/linux/ramips/patches-5.4/303-mtd-scpart-parser.patch
> > b/target/linux/ramips/patches-5.4/303-mtd-scpart-parser.patch
> > new file mode 100644
> > index 0000000000..f125d9c6af
> > --- /dev/null
> > +++ b/target/linux/ramips/patches-5.4/303-mtd-scpart-parser.patch
> > @@ -0,0 +1,19 @@
> > +--- a/drivers/mtd/parsers/Kconfig
> > ++++ b/drivers/mtd/parsers/Kconfig
> > +@@ -185,3 +185,9 @@ config MTD_ROUTERBOOT_PARTS
> > + 	 flash, some of which are fixed and some of which are located at
> > + 	 variable offsets. This parser handles both cases via properly
> > + 	 formatted DTS.
> > ++
> > ++config MTD_SERCOMM_PARTS
> > ++	tristate "SERCOMM partitioning information support"
> > ++	depends on MTD_OF_PARTS
> > ++	help
> > ++	  This provides partition table parser for SERCOMM partition map
> > +--- a/drivers/mtd/parsers/Makefile
> > ++++ b/drivers/mtd/parsers/Makefile
> > +@@ -11,3 +11,4 @@ obj-$(CONFIG_MTD_PARSER_TRX)		+=
> parser_
> > + obj-$(CONFIG_MTD_SHARPSL_PARTS)		+= sharpslpart.o
> > + obj-$(CONFIG_MTD_REDBOOT_PARTS)		+= redboot.o
> > + obj-$(CONFIG_MTD_ROUTERBOOT_PARTS)		+=
> routerbootpart.o
> > ++obj-$(CONFIG_MTD_SERCOMM_PARTS)		+= scpart.o
> 
> 
> _______________________________________________
> openwrt-devel mailing list
> openwrt-devel at lists.openwrt.org
> https://lists.openwrt.org/mailman/listinfo/openwrt-devel
-------------- next part --------------
A non-text attachment was scrubbed...
Name: openpgp-digital-signature.asc
Type: application/pgp-signature
Size: 834 bytes
Desc: not available
URL: <http://lists.openwrt.org/pipermail/openwrt-devel/attachments/20210122/275e18e3/attachment.sig>


More information about the openwrt-devel mailing list