aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/bcm47xxpart.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd/bcm47xxpart.c')
-rw-r--r--drivers/mtd/bcm47xxpart.c43
1 files changed, 37 insertions, 6 deletions
diff --git a/drivers/mtd/bcm47xxpart.c b/drivers/mtd/bcm47xxpart.c
index cc13ea5ce4d5..c0720c1ee4c9 100644
--- a/drivers/mtd/bcm47xxpart.c
+++ b/drivers/mtd/bcm47xxpart.c
@@ -15,6 +15,8 @@
15#include <linux/mtd/mtd.h> 15#include <linux/mtd/mtd.h>
16#include <linux/mtd/partitions.h> 16#include <linux/mtd/partitions.h>
17 17
18#include <uapi/linux/magic.h>
19
18/* 20/*
19 * NAND flash on Netgear R6250 was verified to contain 15 partitions. 21 * NAND flash on Netgear R6250 was verified to contain 15 partitions.
20 * This will result in allocating too big array for some old devices, but the 22 * This will result in allocating too big array for some old devices, but the
@@ -39,7 +41,8 @@
39#define ML_MAGIC1 0x39685a42 41#define ML_MAGIC1 0x39685a42
40#define ML_MAGIC2 0x26594131 42#define ML_MAGIC2 0x26594131
41#define TRX_MAGIC 0x30524448 43#define TRX_MAGIC 0x30524448
42#define SQSH_MAGIC 0x71736873 /* shsq */ 44#define SHSQ_MAGIC 0x71736873 /* shsq (weird ZTE H218N endianness) */
45#define UBI_EC_MAGIC 0x23494255 /* UBI# */
43 46
44struct trx_header { 47struct trx_header {
45 uint32_t magic; 48 uint32_t magic;
@@ -50,7 +53,7 @@ struct trx_header {
50 uint32_t offset[3]; 53 uint32_t offset[3];
51} __packed; 54} __packed;
52 55
53static void bcm47xxpart_add_part(struct mtd_partition *part, char *name, 56static void bcm47xxpart_add_part(struct mtd_partition *part, const char *name,
54 u64 offset, uint32_t mask_flags) 57 u64 offset, uint32_t mask_flags)
55{ 58{
56 part->name = name; 59 part->name = name;
@@ -58,6 +61,26 @@ static void bcm47xxpart_add_part(struct mtd_partition *part, char *name,
58 part->mask_flags = mask_flags; 61 part->mask_flags = mask_flags;
59} 62}
60 63
64static const char *bcm47xxpart_trx_data_part_name(struct mtd_info *master,
65 size_t offset)
66{
67 uint32_t buf;
68 size_t bytes_read;
69
70 if (mtd_read(master, offset, sizeof(buf), &bytes_read,
71 (uint8_t *)&buf) < 0) {
72 pr_err("mtd_read error while parsing (offset: 0x%X)!\n",
73 offset);
74 goto out_default;
75 }
76
77 if (buf == UBI_EC_MAGIC)
78 return "ubi";
79
80out_default:
81 return "rootfs";
82}
83
61static int bcm47xxpart_parse(struct mtd_info *master, 84static int bcm47xxpart_parse(struct mtd_info *master,
62 struct mtd_partition **pparts, 85 struct mtd_partition **pparts,
63 struct mtd_part_parser_data *data) 86 struct mtd_part_parser_data *data)
@@ -73,8 +96,12 @@ static int bcm47xxpart_parse(struct mtd_info *master,
73 int last_trx_part = -1; 96 int last_trx_part = -1;
74 int possible_nvram_sizes[] = { 0x8000, 0xF000, 0x10000, }; 97 int possible_nvram_sizes[] = { 0x8000, 0xF000, 0x10000, };
75 98
76 if (blocksize <= 0x10000) 99 /*
77 blocksize = 0x10000; 100 * Some really old flashes (like AT45DB*) had smaller erasesize-s, but
101 * partitions were aligned to at least 0x1000 anyway.
102 */
103 if (blocksize < 0x1000)
104 blocksize = 0x1000;
78 105
79 /* Alloc */ 106 /* Alloc */
80 parts = kzalloc(sizeof(struct mtd_partition) * BCM47XXPART_MAX_PARTS, 107 parts = kzalloc(sizeof(struct mtd_partition) * BCM47XXPART_MAX_PARTS,
@@ -186,8 +213,11 @@ static int bcm47xxpart_parse(struct mtd_info *master,
186 * we want to have jffs2 (overlay) in the same mtd. 213 * we want to have jffs2 (overlay) in the same mtd.
187 */ 214 */
188 if (trx->offset[i]) { 215 if (trx->offset[i]) {
216 const char *name;
217
218 name = bcm47xxpart_trx_data_part_name(master, offset + trx->offset[i]);
189 bcm47xxpart_add_part(&parts[curr_part++], 219 bcm47xxpart_add_part(&parts[curr_part++],
190 "rootfs", 220 name,
191 offset + trx->offset[i], 221 offset + trx->offset[i],
192 0); 222 0);
193 i++; 223 i++;
@@ -205,7 +235,8 @@ static int bcm47xxpart_parse(struct mtd_info *master,
205 } 235 }
206 236
207 /* Squashfs on devices not using TRX */ 237 /* Squashfs on devices not using TRX */
208 if (buf[0x000 / 4] == SQSH_MAGIC) { 238 if (le32_to_cpu(buf[0x000 / 4]) == SQUASHFS_MAGIC ||
239 buf[0x000 / 4] == SHSQ_MAGIC) {
209 bcm47xxpart_add_part(&parts[curr_part++], "rootfs", 240 bcm47xxpart_add_part(&parts[curr_part++], "rootfs",
210 offset, 0); 241 offset, 0);
211 continue; 242 continue;