Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1290738 > unrolled thread

[PATCH linux-next v4 00/11] mtd: bcm63xxpart: Add NAND partitioning support

Started bySimon Arlott <simon@fire.lp0.eu>
First post2015-12-13 23:50 +0100
Last post2015-12-14 00:00 +0100
Articles 6 — 1 participant

Back to article view | Back to linux.kernel


Contents

  [PATCH linux-next v4 00/11] mtd: bcm63xxpart: Add NAND partitioning  support Simon Arlott <simon@fire.lp0.eu> - 2015-12-13 23:50 +0100
    [PATCH linux-next v4 10/11] mtd: bcm63xxpart: Move NOR flash layout  to a separate function Simon Arlott <simon@fire.lp0.eu> - 2015-12-14 00:00 +0100
    [PATCH linux-next v4 08/11] mtd: bcm63xxpart: Extract read of image  tag to separate function Simon Arlott <simon@fire.lp0.eu> - 2015-12-14 00:00 +0100
    [PATCH linux-next v4 11/11] mtd: bcm63xxpart: Add NAND partitioning  support Simon Arlott <simon@fire.lp0.eu> - 2015-12-14 00:00 +0100
    [PATCH linux-next v4 07/11] MIPS: bcm63xx: nvram: Remove unused  bcm63xx_nvram_get_psi_size() function Simon Arlott <simon@fire.lp0.eu> - 2015-12-14 00:00 +0100
    [PATCH linux-next v4 09/11] mtd: bcm63xxpart: Null terminate and  validate conversion of flash strings Simon Arlott <simon@fire.lp0.eu> - 2015-12-14 00:00 +0100

#1290738 — [PATCH linux-next v4 00/11] mtd: bcm63xxpart: Add NAND partitioning support

FromSimon Arlott <simon@fire.lp0.eu>
Date2015-12-13 23:50 +0100
Subject[PATCH linux-next v4 00/11] mtd: bcm63xxpart: Add NAND partitioning support
Message-ID<qFnCN-5ZR-3@gated-at.bofh.it>
The BCM963xx NAND flash boards have a different handling of the
partition layout from the NOR flash boards. For NAND there are offsets
for the partitions in nvram. Both types of boards use the same CFE
bootloader, nvram format and image tag in their rootfs partitions.

This patch series:
1-4:  Creates separate header files for bcm963xx_nvram and bcm_tag structures
5:    Updates the bcm_tag field image_sequence
6:    Removes the dependency on mach-bcm63xx from the bcm63xxpart parser
7:    Removes unused mach-bcm63xx nvram function
8-10: Cleanup and move NOR flash layout to a separate function
11:   Add NAND flash layout support

Patches 1-2 tested on BCM63XX with a BCM963168 (NAND) board.
Patches 3-11 compile tested on BCM63XX.
Patches 6-11 tested on BMIPS with a BCM963168 (NAND) board.
---
v4: Move struct bcm_tag to include/linux/.

    Modify bcm63xx parser to read nvram from NOR flash and handle the
    NAND flash layout in the same parser.

v3: Fix includes/type names, add comments explaining the nvram struct.

    Use COMPILE_TEST.

    Ensure that strings read from flash are null terminated and validate
    bcm_tag integer values (this also moves reporting of rootfs sequence
    numbers to later on).

v2: Use external struct bcm963xx_nvram definition for bcm963268part.

    Removed support for the nand partition number field, it's not a
    standard Broadcom field (was added by MitraStar Technology Corp.).

-- 
Simon Arlott
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [next] | [standalone]


#1290739 — [PATCH linux-next v4 10/11] mtd: bcm63xxpart: Move NOR flash layout to a separate function

FromSimon Arlott <simon@fire.lp0.eu>
Date2015-12-14 00:00 +0100
Subject[PATCH linux-next v4 10/11] mtd: bcm63xxpart: Move NOR flash layout to a separate function
Message-ID<qFnMu-638-5@gated-at.bofh.it>
In reply to#1290738
Move the NOR flash layout to a separate function to allow the NAND flash
layout to be supported.

Signed-off-by: Simon Arlott <simon@fire.lp0.eu>
---
v4: New patch.

 drivers/mtd/bcm63xxpart.c | 54 ++++++++++++++++++++++++++++-------------------
 1 file changed, 32 insertions(+), 22 deletions(-)

diff --git a/drivers/mtd/bcm63xxpart.c b/drivers/mtd/bcm63xxpart.c
index 41aa202..26c38a1 100644
--- a/drivers/mtd/bcm63xxpart.c
+++ b/drivers/mtd/bcm63xxpart.c
@@ -124,13 +124,11 @@ static int bcm63xx_read_image_tag(struct mtd_info *master, const char *name,
 	return 1;
 }
 
-static int bcm63xx_parse_cfe_partitions(struct mtd_info *master,
-					const struct mtd_partition **pparts,
-					struct mtd_part_parser_data *data)
+static int bcm63xx_parse_cfe_nor_partitions(struct mtd_info *master,
+	const struct mtd_partition **pparts, struct bcm963xx_nvram *nvram)
 {
 	/* CFE, NVRAM and global Linux are always present */
 	int nrparts = 3, curpart = 0;
-	struct bcm963xx_nvram *nvram = NULL;
 	struct bcm_tag *buf = NULL;
 	struct mtd_partition *parts;
 	int ret;
@@ -141,17 +139,6 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master,
 	int i;
 	bool rootfs_first = false;
 
-	if (bcm63xx_detect_cfe(master))
-		return -EINVAL;
-
-	nvram = vzalloc(sizeof(*nvram));
-	if (!nvram)
-		return -ENOMEM;
-
-	ret = bcm63xx_read_nvram(master, nvram);
-	if (ret)
-		goto out;
-
 	cfe_erasesize = max_t(uint32_t, master->erasesize,
 			      BCM963XX_CFE_BLOCK_SIZE);
 
@@ -159,12 +146,9 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master,
 	nvramlen = nvram->psi_size * SZ_1K;
 	nvramlen = roundup(nvramlen, cfe_erasesize);
 
-	/* Allocate memory for buffer */
 	buf = vmalloc(sizeof(struct bcm_tag));
-	if (!buf) {
-		ret = -ENOMEM;
-		goto out;
-	}
+	if (!buf)
+		return -ENOMEM;
 
 	/* Get the tag */
 	ret = bcm63xx_read_image_tag(master, "rootfs", cfelen, buf);
@@ -234,7 +218,6 @@ invalid_tag:
 	if (kernellen > 0)
 		nrparts++;
 
-	/* Ask kernel for more memory */
 	parts = kzalloc(sizeof(*parts) * nrparts + 10 * nrparts, GFP_KERNEL);
 	if (!parts) {
 		ret = -ENOMEM;
@@ -292,13 +275,40 @@ invalid_tag:
 	ret = 0;
 
 out:
-	vfree(nvram);
 	vfree(buf);
 
 	if (ret)
 		return ret;
 
 	return nrparts;
+}
+
+static int bcm63xx_parse_cfe_partitions(struct mtd_info *master,
+					const struct mtd_partition **pparts,
+					struct mtd_part_parser_data *data)
+{
+	struct bcm963xx_nvram *nvram = NULL;
+	int ret;
+
+	if (bcm63xx_detect_cfe(master))
+		return -EINVAL;
+
+	nvram = vzalloc(sizeof(*nvram));
+	if (!nvram)
+		return -ENOMEM;
+
+	ret = bcm63xx_read_nvram(master, nvram);
+	if (ret)
+		goto out;
+
+	if (!mtd_type_is_nand(master))
+		ret = bcm63xx_parse_cfe_nor_partitions(master, pparts, nvram);
+	else
+		ret = -EINVAL;
+
+out:
+	vfree(nvram);
+	return ret;
 };
 
 static struct mtd_part_parser bcm63xx_cfe_parser = {
-- 
2.1.4

-- 
Simon Arlott
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1290740 — [PATCH linux-next v4 08/11] mtd: bcm63xxpart: Extract read of image tag to separate function

FromSimon Arlott <simon@fire.lp0.eu>
Date2015-12-14 00:00 +0100
Subject[PATCH linux-next v4 08/11] mtd: bcm63xxpart: Extract read of image tag to separate function
Message-ID<qFnMu-638-7@gated-at.bofh.it>
In reply to#1290738
Extract image tag reading and CRC check to a separate function.

Signed-off-by: Simon Arlott <simon@fire.lp0.eu>
---
v4: New patch.

 drivers/mtd/bcm63xxpart.c | 62 ++++++++++++++++++++++++++++++-----------------
 1 file changed, 40 insertions(+), 22 deletions(-)

diff --git a/drivers/mtd/bcm63xxpart.c b/drivers/mtd/bcm63xxpart.c
index 1eea8b6..eafbf52 100644
--- a/drivers/mtd/bcm63xxpart.c
+++ b/drivers/mtd/bcm63xxpart.c
@@ -41,6 +41,10 @@
 #define BCM963XX_CFE_VERSION_OFFSET	0x570
 #define BCM963XX_NVRAM_OFFSET		0x580
 
+/* Ensure strings read from flash structs are null terminated */
+#define STR_NULL_TERMINATE(x) \
+	do { char *_str = (x); _str[sizeof(x) - 1] = 0; } while (0)
+
 static int bcm63xx_detect_cfe(struct mtd_info *master)
 {
 	char buf[9];
@@ -89,6 +93,37 @@ static int bcm63xx_read_nvram(struct mtd_info *master,
 	return 0;
 }
 
+static int bcm63xx_read_image_tag(struct mtd_info *master, const char *name,
+	loff_t tag_offset, struct bcm_tag *buf)
+{
+	int ret;
+	size_t retlen;
+	u32 computed_crc;
+
+	ret = mtd_read(master, tag_offset, sizeof(*buf), &retlen, (void *)buf);
+	if (ret)
+		return ret;
+
+	if (retlen != sizeof(*buf))
+		return -EIO;
+
+	computed_crc = crc32_le(IMAGETAG_CRC_START, (u8 *)buf,
+				offsetof(struct bcm_tag, header_crc));
+	if (computed_crc == buf->header_crc) {
+		STR_NULL_TERMINATE(buf->board_id);
+		STR_NULL_TERMINATE(buf->tag_version);
+
+		pr_info("%s: CFE image tag found at 0x%llx with version %s, board type %s\n",
+			name, tag_offset, buf->tag_version, buf->board_id);
+
+		return 0;
+	}
+
+	pr_warn("%s: CFE image tag at 0x%llx CRC invalid (expected %08x, actual %08x)\n",
+		name, tag_offset, buf->header_crc, computed_crc);
+	return 1;
+}
+
 static int bcm63xx_parse_cfe_partitions(struct mtd_info *master,
 					const struct mtd_partition **pparts,
 					struct mtd_part_parser_data *data)
@@ -99,13 +134,11 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master,
 	struct bcm_tag *buf = NULL;
 	struct mtd_partition *parts;
 	int ret;
-	size_t retlen;
 	unsigned int rootfsaddr, kerneladdr, spareaddr;
 	unsigned int rootfslen, kernellen, sparelen, totallen;
 	unsigned int cfelen, nvramlen;
 	unsigned int cfe_erasesize;
 	int i;
-	u32 computed_crc;
 	bool rootfs_first = false;
 
 	if (bcm63xx_detect_cfe(master))
@@ -134,28 +167,13 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master,
 	}
 
 	/* Get the tag */
-	ret = mtd_read(master, cfelen, sizeof(struct bcm_tag), &retlen,
-		       (void *)buf);
-
-	if (retlen != sizeof(struct bcm_tag)) {
-		ret = -EIO;
-		goto out;
-	}
-
-	computed_crc = crc32_le(IMAGETAG_CRC_START, (u8 *)buf,
-				offsetof(struct bcm_tag, header_crc));
-	if (computed_crc == buf->header_crc) {
-		char *boardid = &(buf->board_id[0]);
-		char *tagversion = &(buf->tag_version[0]);
-
+	ret = bcm63xx_read_image_tag(master, "rootfs", cfelen, buf);
+	if (!ret) {
 		sscanf(buf->flash_image_start, "%u", &rootfsaddr);
 		sscanf(buf->kernel_address, "%u", &kerneladdr);
 		sscanf(buf->kernel_length, "%u", &kernellen);
 		sscanf(buf->total_length, "%u", &totallen);
 
-		pr_info("CFE boot tag found with version %s and board type %s\n",
-			tagversion, boardid);
-
 		kerneladdr = kerneladdr - BCM963XX_EXTENDED_SIZE;
 		rootfsaddr = rootfsaddr - BCM963XX_EXTENDED_SIZE;
 		spareaddr = roundup(totallen, master->erasesize) + cfelen;
@@ -169,13 +187,13 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master,
 			rootfsaddr = kerneladdr + kernellen;
 			rootfslen = spareaddr - rootfsaddr;
 		}
-	} else {
-		pr_warn("CFE boot tag CRC invalid (expected %08x, actual %08x)\n",
-			buf->header_crc, computed_crc);
+	} else if (ret > 0) {
 		kernellen = 0;
 		rootfslen = 0;
 		rootfsaddr = 0;
 		spareaddr = cfelen;
+	} else {
+		goto out;
 	}
 	sparelen = master->size - spareaddr - nvramlen;
 
-- 
2.1.4

-- 
Simon Arlott
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1290741 — [PATCH linux-next v4 11/11] mtd: bcm63xxpart: Add NAND partitioning support

FromSimon Arlott <simon@fire.lp0.eu>
Date2015-12-14 00:00 +0100
Subject[PATCH linux-next v4 11/11] mtd: bcm63xxpart: Add NAND partitioning support
Message-ID<qFnMu-638-15@gated-at.bofh.it>
In reply to#1290738
Add partitioning support for BCM963xx boards with NAND flash.

The following partitions are defined:
  "boot":           CFE and nvram data
  "rootfs":         Currently selected rootfs
  "data":           Configuration data
  "rootfs1_update": Container for the whole flash area used
                    for the first rootfs to allow it to be
                    updated
  "rootfs2_update": Container for the whole flash area used
                    for the second rootfs to allow it to be
                    updated
  "rootfs_other":   The other (not currently selected) rootfs

Example:
[    2.157094] nand: device found, Manufacturer ID: 0xc2, Chip ID: 0xf1
[    2.163796] nand: Macronix NAND 128MiB 3,3V 8-bit
[    2.168648] nand: 128 MiB, SLC, erase size: 128 KiB, page size: 2048, OOB size: 64
[    2.176588] bcm6368_nand 10000200.nand: detected 128MiB total, 128KiB blocks, 2KiB pages, 16B OOB, 8-bit, Hamming ECC
[    2.189782] Bad block table found at page 65472, version 0x01
[    2.196910] Bad block table found at page 65408, version 0x01
[    2.204003] nand_read_bbt: bad block at 0x000007480000
[    2.225220] bcm63xxpart: rootfs1: CFE image tag found at 0x20000 with version 6, board type 963168VX
[    2.236188] bcm63xxpart: rootfs2: CFE image tag found at 0x4000000 with version 6, board type 963168VX
[    2.246165] bcm63xxpart: CFE bootline selected latest image rootfs1 (rootfs1_seq=2, rootfs2_seq=1)
[    2.255800] 6 bcm63xxpart partitions found on MTD device brcmnand.0
[    2.275360] Creating 6 MTD partitions on "brcmnand.0":
[    2.280804] 0x000000000000-0x000000020000 : "boot"
[    2.294609] 0x000000040000-0x000001120000 : "rootfs"
[    2.310078] 0x000007b00000-0x000007f00000 : "data"
[    2.324052] 0x000000020000-0x000003ac0000 : "rootfs1_update"
[    2.339190] 0x000004000000-0x000007ac0000 : "rootfs2_update"
[    2.354290] 0x000004020000-0x000005060000 : "rootfs_other"

The nvram contains the offset and size of the boot, rootfs1, rootfs2
and data partitions. The presence of CFE and nvram is already verified
by reading from the boot partition which is assumed to be at offset 0
and the NAND process aborts if the nvram read indicates that this is
not the case.

There is bcm_tag information at the start of each rootfs that is used
to determine which rootfs is newer and what its real offset/size is.

The CFE bootline is used to select a rootfs.

Signed-off-by: Simon Arlott <simon@fire.lp0.eu>
---
v4: Reorganised functions based on earlier new patches in the series,
    no real logic changes other than having to check for nvram->version
    >= 6 within the nand function instead of the nvram read function.

    Renamed "curpart" to "i" because it allows the partition layout
    lines to be under 80 characters.

v3: Use COMPILE_TEST.

    Ensure that strings read from flash are null terminated and validate
    bcm_tag integer values (this also moves reporting of rootfs sequence
    numbers to later on).

v2: Use external struct bcm963xx_nvram definition for bcm963268part.

    Removed support for the nand partition number field, it's not a
    standard Broadcom field (was added by MitraStar Technology Corp.).

 drivers/mtd/bcm63xxpart.c | 196 ++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 190 insertions(+), 6 deletions(-)

diff --git a/drivers/mtd/bcm63xxpart.c b/drivers/mtd/bcm63xxpart.c
index 26c38a1..4576b78 100644
--- a/drivers/mtd/bcm63xxpart.c
+++ b/drivers/mtd/bcm63xxpart.c
@@ -16,10 +16,9 @@
  * 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
- *
+ * NAND flash layout derived from bcm963xx_4.12L.06B_consumer/bcmdrivers/opensource/char/board/bcm963xx/impl1/board.c,
+ *	bcm963xx_4.12L.06B_consumer/shared/opensource/include/bcm963xx/bcm_hwdefs.h:
+ * Copyright (c) 2002 Broadcom Corporation
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
@@ -124,6 +123,25 @@ static int bcm63xx_read_image_tag(struct mtd_info *master, const char *name,
 	return 1;
 }
 
+static bool bcm63xx_boot_latest(struct bcm963xx_nvram *nvram)
+{
+	char *p;
+
+	STR_NULL_TERMINATE(nvram->bootline);
+
+	/* Find previous image parameter "p" */
+	if (!strncmp(nvram->bootline, "p=", 2))
+		p = nvram->bootline;
+	else
+		p = strstr(nvram->bootline, " p=");
+
+	if (p == NULL)
+		return true;
+
+	p += 2;
+	return *p != '0';
+}
+
 static int bcm63xx_parse_cfe_nor_partitions(struct mtd_info *master,
 	const struct mtd_partition **pparts, struct bcm963xx_nvram *nvram)
 {
@@ -283,6 +301,171 @@ out:
 	return nrparts;
 }
 
+static bool bcm63xx_parse_nand_image_tag(struct mtd_info *master,
+	const char *name, loff_t tag_offset, u64 *rootfs_offset,
+	u64 *rootfs_size, unsigned int *rootfs_sequence)
+{
+	struct bcm_tag *buf;
+	int ret;
+	bool rootfs_ok = false;
+
+	*rootfs_offset = 0;
+	*rootfs_size = 0;
+	*rootfs_sequence = 0;
+
+	buf = vmalloc(sizeof(struct bcm_tag));
+	if (!buf)
+		goto out;
+
+	ret = bcm63xx_read_image_tag(master, name, tag_offset, buf);
+	if (!ret) {
+		/* Get rootfs offset and size from tag data */
+		STR_NULL_TERMINATE(buf->flash_image_start);
+		if (kstrtou64(buf->flash_image_start, 10, rootfs_offset) ||
+				*rootfs_offset < BCM963XX_EXTENDED_SIZE) {
+			pr_err("%s: invalid rootfs offset: %*ph\n", name,
+				sizeof(buf->flash_image_start),
+				buf->flash_image_start);
+			goto out;
+		}
+
+		STR_NULL_TERMINATE(buf->root_length);
+		if (kstrtou64(buf->root_length, 10, rootfs_size) ||
+				rootfs_size == 0) {
+			pr_err("%s: invalid rootfs size: %*ph\n", name,
+				sizeof(buf->root_length), buf->root_length);
+			goto out;
+		}
+
+		/* Adjust for flash offset */
+		*rootfs_offset -= BCM963XX_EXTENDED_SIZE;
+
+		/* Remove bcm_tag data from length */
+		*rootfs_size -= *rootfs_offset - tag_offset;
+
+		/* Get image sequence number to determine which one is newer */
+		STR_NULL_TERMINATE(buf->image_sequence);
+		if (kstrtouint(buf->image_sequence, 10, rootfs_sequence)) {
+			pr_err("%s: invalid rootfs sequence: %*ph\n", name,
+				sizeof(buf->image_sequence),
+				buf->image_sequence);
+			goto out;
+		}
+
+		rootfs_ok = true;
+	}
+
+out:
+	vfree(buf);
+	return rootfs_ok;
+}
+
+static int bcm63xx_parse_cfe_nand_partitions(struct mtd_info *master,
+	const struct mtd_partition **pparts,
+	struct bcm963xx_nvram *nvram)
+{
+	int nrparts, i;
+	struct mtd_partition *parts;
+	u64 rootfs1_off, rootfs1_size;
+	unsigned int rootfs1_seq;
+	u64 rootfs2_off, rootfs2_size;
+	unsigned int rootfs2_seq;
+	bool rootfs1, rootfs2;
+	bool use_first;
+
+	if (nvram->version < 6) {
+		pr_warn("nvram version %u not supported\n", nvram->version);
+		return -EINVAL;
+	}
+
+	/* We've just read the nvram from offset 0,
+	 * so it must be located there.
+	 */
+	if (BCM963XX_NVRAM_NAND_PART_OFFSET(nvram, BOOT) != 0)
+		return -EINVAL;
+
+	/* Get the rootfs partition locations */
+	rootfs1 = bcm63xx_parse_nand_image_tag(master, "rootfs1",
+		BCM963XX_NVRAM_NAND_PART_OFFSET(nvram, ROOTFS_1),
+		&rootfs1_off, &rootfs1_size, &rootfs1_seq);
+	rootfs2 = bcm63xx_parse_nand_image_tag(master, "rootfs2",
+		BCM963XX_NVRAM_NAND_PART_OFFSET(nvram, ROOTFS_2),
+		&rootfs2_off, &rootfs2_size, &rootfs2_seq);
+
+	/* Determine primary rootfs partition */
+	if (rootfs1 && rootfs2) {
+		bool use_latest = bcm63xx_boot_latest(nvram);
+
+		/* Compare sequence numbers */
+		if (use_latest)
+			use_first = rootfs1_seq > rootfs2_seq;
+		else
+			use_first = rootfs1_seq < rootfs2_seq;
+
+		pr_info("CFE bootline selected %s image rootfs%u (rootfs1_seq=%u, rootfs2_seq=%u)\n",
+			use_latest ? "latest" : "previous",
+			use_first ? 1 : 2,
+			rootfs1_seq, rootfs2_seq);
+	} else {
+		use_first = rootfs1;
+	}
+
+	/* Partitions:
+	 * 1 boot
+	 * 2 rootfs
+	 * 3 data
+	 * 4 rootfs1_update
+	 * 5 rootfs2_update
+	 * 6 rootfs_other
+	 */
+	nrparts = 6;
+	i = 0;
+
+	parts = kcalloc(nrparts, sizeof(*parts), GFP_KERNEL);
+	if (!parts)
+		return -ENOMEM;
+
+	parts[i].name = "boot";
+	parts[i].offset = BCM963XX_NVRAM_NAND_PART_OFFSET(nvram, BOOT);
+	parts[i].size = BCM963XX_NVRAM_NAND_PART_SIZE(nvram, BOOT);
+	i++;
+
+	/* Primary rootfs if either is available */
+	if (rootfs1 || rootfs2) {
+		parts[i].name = "rootfs";
+		parts[i].offset = use_first ? rootfs1_off : rootfs2_off;
+		parts[i].size = use_first ? rootfs1_size : rootfs2_size;
+		i++;
+	}
+
+	parts[i].name = "data";
+	parts[i].offset = BCM963XX_NVRAM_NAND_PART_OFFSET(nvram, DATA);
+	parts[i].size = BCM963XX_NVRAM_NAND_PART_SIZE(nvram, DATA);
+	i++;
+
+	/* Full rootfs partitions for updates */
+	parts[i].name = "rootfs1_update";
+	parts[i].offset = BCM963XX_NVRAM_NAND_PART_OFFSET(nvram, ROOTFS_1);
+	parts[i].size = BCM963XX_NVRAM_NAND_PART_SIZE(nvram, ROOTFS_1);
+	i++;
+
+	parts[i].name = "rootfs2_update";
+	parts[i].offset = BCM963XX_NVRAM_NAND_PART_OFFSET(nvram, ROOTFS_2);
+	parts[i].size = BCM963XX_NVRAM_NAND_PART_SIZE(nvram, ROOTFS_2);
+	i++;
+
+	/* Other rootfs if both are available */
+	if (rootfs1 && rootfs2) {
+		parts[i].name = "rootfs_other";
+		parts[i].offset = use_first ? rootfs2_off : rootfs1_off;
+		parts[i].size = use_first ? rootfs2_size : rootfs1_size;
+		i++;
+	}
+
+	*pparts = parts;
+	return nrparts;
+}
+
 static int bcm63xx_parse_cfe_partitions(struct mtd_info *master,
 					const struct mtd_partition **pparts,
 					struct mtd_part_parser_data *data)
@@ -304,7 +487,7 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master,
 	if (!mtd_type_is_nand(master))
 		ret = bcm63xx_parse_cfe_nor_partitions(master, pparts, nvram);
 	else
-		ret = -EINVAL;
+		ret = bcm63xx_parse_cfe_nand_partitions(master, pparts, nvram);
 
 out:
 	vfree(nvram);
@@ -321,5 +504,6 @@ MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Daniel Dickinson <openwrt@cshore.neomailbox.net>");
 MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>");
 MODULE_AUTHOR("Mike Albon <malbon@openwrt.org>");
-MODULE_AUTHOR("Jonas Gorski <jonas.gorski@gmail.com");
+MODULE_AUTHOR("Jonas Gorski <jonas.gorski@gmail.com>");
+MODULE_AUTHOR("Simon Arlott");
 MODULE_DESCRIPTION("MTD partitioning for BCM63XX CFE bootloaders");
-- 
2.1.4

-- 
Simon Arlott
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1290742 — [PATCH linux-next v4 07/11] MIPS: bcm63xx: nvram: Remove unused bcm63xx_nvram_get_psi_size() function

FromSimon Arlott <simon@fire.lp0.eu>
Date2015-12-14 00:00 +0100
Subject[PATCH linux-next v4 07/11] MIPS: bcm63xx: nvram: Remove unused bcm63xx_nvram_get_psi_size() function
Message-ID<qFnMu-638-17@gated-at.bofh.it>
In reply to#1290738
Remove bcm63xx_nvram_get_psi_size() as it now has no users.

Signed-off-by: Simon Arlott <simon@fire.lp0.eu>
---
v4: New patch.

 arch/mips/bcm63xx/nvram.c                          | 11 -----------
 arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h |  2 --
 2 files changed, 13 deletions(-)

diff --git a/arch/mips/bcm63xx/nvram.c b/arch/mips/bcm63xx/nvram.c
index 05757ae..5f2bc1e 100644
--- a/arch/mips/bcm63xx/nvram.c
+++ b/arch/mips/bcm63xx/nvram.c
@@ -19,8 +19,6 @@
 
 #include <bcm63xx_nvram.h>
 
-#define BCM63XX_DEFAULT_PSI_SIZE	64
-
 static struct bcm963xx_nvram nvram;
 static int mac_addr_used;
 
@@ -87,12 +85,3 @@ int bcm63xx_nvram_get_mac_address(u8 *mac)
 	return 0;
 }
 EXPORT_SYMBOL(bcm63xx_nvram_get_mac_address);
-
-int bcm63xx_nvram_get_psi_size(void)
-{
-	if (nvram.psi_size > 0)
-		return nvram.psi_size;
-
-	return BCM63XX_DEFAULT_PSI_SIZE;
-}
-EXPORT_SYMBOL(bcm63xx_nvram_get_psi_size);
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h
index 348df49..4e0b6bc 100644
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h
@@ -30,6 +30,4 @@ u8 *bcm63xx_nvram_get_name(void);
  */
 int bcm63xx_nvram_get_mac_address(u8 *mac);
 
-int bcm63xx_nvram_get_psi_size(void);
-
 #endif /* BCM63XX_NVRAM_H */
-- 
2.1.4

-- 
Simon Arlott
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1290743 — [PATCH linux-next v4 09/11] mtd: bcm63xxpart: Null terminate and validate conversion of flash strings

FromSimon Arlott <simon@fire.lp0.eu>
Date2015-12-14 00:00 +0100
Subject[PATCH linux-next v4 09/11] mtd: bcm63xxpart: Null terminate and validate conversion of flash strings
Message-ID<qFnMu-638-19@gated-at.bofh.it>
In reply to#1290738
Strings read from flash could be missing null termination characters, or
not contain valid integers.

Null terminate the strings and check for errors when converting them to
integers.

Also validate that the addresses are at least BCM963XX_EXTENDED_SIZE
because this will be subtracted from them.

Signed-off-by: Simon Arlott <simon@fire.lp0.eu>
---
v4: New patch.

 drivers/mtd/bcm63xxpart.c | 38 ++++++++++++++++++++++++++++++++++----
 1 file changed, 34 insertions(+), 4 deletions(-)

diff --git a/drivers/mtd/bcm63xxpart.c b/drivers/mtd/bcm63xxpart.c
index eafbf52..41aa202 100644
--- a/drivers/mtd/bcm63xxpart.c
+++ b/drivers/mtd/bcm63xxpart.c
@@ -169,10 +169,39 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master,
 	/* Get the tag */
 	ret = bcm63xx_read_image_tag(master, "rootfs", cfelen, buf);
 	if (!ret) {
-		sscanf(buf->flash_image_start, "%u", &rootfsaddr);
-		sscanf(buf->kernel_address, "%u", &kerneladdr);
-		sscanf(buf->kernel_length, "%u", &kernellen);
-		sscanf(buf->total_length, "%u", &totallen);
+		STR_NULL_TERMINATE(buf->flash_image_start);
+		if (kstrtouint(buf->flash_image_start, 10, &rootfsaddr) ||
+				rootfsaddr < BCM963XX_EXTENDED_SIZE) {
+			pr_err("invalid rootfs address: %*ph\n",
+				sizeof(buf->flash_image_start),
+				buf->flash_image_start);
+			goto invalid_tag;
+		}
+
+		STR_NULL_TERMINATE(buf->kernel_address);
+		if (kstrtouint(buf->kernel_address, 10, &kerneladdr) ||
+				kerneladdr < BCM963XX_EXTENDED_SIZE) {
+			pr_err("invalid kernel address: %*ph\n",
+				sizeof(buf->kernel_address),
+				buf->kernel_address);
+			goto invalid_tag;
+		}
+
+		STR_NULL_TERMINATE(buf->kernel_length);
+		if (kstrtouint(buf->kernel_length, 10, &kernellen)) {
+			pr_err("invalid kernel length: %*ph\n",
+				sizeof(buf->kernel_length),
+				buf->kernel_length);
+			goto invalid_tag;
+		}
+
+		STR_NULL_TERMINATE(buf->total_length);
+		if (kstrtouint(buf->total_length, 10, &totallen)) {
+			pr_err("invalid total length: %*ph\n",
+				sizeof(buf->total_length),
+				buf->total_length);
+			goto invalid_tag;
+		}
 
 		kerneladdr = kerneladdr - BCM963XX_EXTENDED_SIZE;
 		rootfsaddr = rootfsaddr - BCM963XX_EXTENDED_SIZE;
@@ -188,6 +217,7 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master,
 			rootfslen = spareaddr - rootfsaddr;
 		}
 	} else if (ret > 0) {
+invalid_tag:
 		kernellen = 0;
 		rootfslen = 0;
 		rootfsaddr = 0;
-- 
2.1.4

-- 
Simon Arlott
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web