Skip to content

Commit dd84cb0

Browse files
KanjiMonsterrichardweinberger
authored andcommitted
mtd: bcm63xxpart: move imagetag parsing to its own parser
Move the bcm963xx Image Tag parsing into its own partition parser. This Allows reusing the parser with different full flash parsers. While moving it, rename it to bcm963* to better reflect it isn't chip, but reference implementation specific. Reviewed-by: Rob Herring <robh@kernel.org> Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com> Reviewed-by: Florian Fainelli <f.fainelli@gmail.com> Signed-off-by: Richard Weinberger <richard@nod.at>
1 parent e651de4 commit dd84cb0

File tree

5 files changed

+235
-147
lines changed

5 files changed

+235
-147
lines changed

drivers/mtd/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ config MTD_BCM63XX_PARTS
9494
tristate "BCM63XX CFE partitioning support"
9595
depends on BCM63XX || BMIPS_GENERIC || COMPILE_TEST
9696
select CRC32
97+
select MTD_PARSER_IMAGETAG
9798
help
9899
This provides partition parsing for BCM63xx devices with CFE
99100
bootloaders.

drivers/mtd/bcm63xxpart.c

Lines changed: 8 additions & 147 deletions
Original file line numberDiff line numberDiff line change
@@ -94,51 +94,19 @@ static int bcm63xx_read_nvram(struct mtd_info *master,
9494
return 0;
9595
}
9696

97-
static int bcm63xx_read_image_tag(struct mtd_info *master, const char *name,
98-
loff_t tag_offset, struct bcm_tag *buf)
99-
{
100-
int ret;
101-
size_t retlen;
102-
u32 computed_crc;
103-
104-
ret = mtd_read(master, tag_offset, sizeof(*buf), &retlen, (void *)buf);
105-
if (ret)
106-
return ret;
107-
108-
if (retlen != sizeof(*buf))
109-
return -EIO;
110-
111-
computed_crc = crc32_le(IMAGETAG_CRC_START, (u8 *)buf,
112-
offsetof(struct bcm_tag, header_crc));
113-
if (computed_crc == buf->header_crc) {
114-
STR_NULL_TERMINATE(buf->board_id);
115-
STR_NULL_TERMINATE(buf->tag_version);
116-
117-
pr_info("%s: CFE image tag found at 0x%llx with version %s, board type %s\n",
118-
name, tag_offset, buf->tag_version, buf->board_id);
119-
120-
return 0;
121-
}
122-
123-
pr_warn("%s: CFE image tag at 0x%llx CRC invalid (expected %08x, actual %08x)\n",
124-
name, tag_offset, buf->header_crc, computed_crc);
125-
return 1;
126-
}
97+
static const char * const bcm63xx_cfe_part_types[] = {
98+
"bcm963xx-imagetag",
99+
NULL,
100+
};
127101

128102
static int bcm63xx_parse_cfe_nor_partitions(struct mtd_info *master,
129103
const struct mtd_partition **pparts, struct bcm963xx_nvram *nvram)
130104
{
131-
/* CFE, NVRAM and global Linux are always present */
132-
int nrparts = 3, curpart = 0;
133-
struct bcm_tag *buf = NULL;
134105
struct mtd_partition *parts;
135-
int ret;
136-
unsigned int rootfsaddr, kerneladdr, spareaddr;
137-
unsigned int rootfslen, kernellen, sparelen, totallen;
106+
int nrparts = 3, curpart = 0;
138107
unsigned int cfelen, nvramlen;
139108
unsigned int cfe_erasesize;
140109
int i;
141-
bool rootfs_first = false;
142110

143111
cfe_erasesize = max_t(uint32_t, master->erasesize,
144112
BCM963XX_CFE_BLOCK_SIZE);
@@ -147,114 +115,16 @@ static int bcm63xx_parse_cfe_nor_partitions(struct mtd_info *master,
147115
nvramlen = nvram->psi_size * SZ_1K;
148116
nvramlen = roundup(nvramlen, cfe_erasesize);
149117

150-
buf = vmalloc(sizeof(struct bcm_tag));
151-
if (!buf)
152-
return -ENOMEM;
153-
154-
/* Get the tag */
155-
ret = bcm63xx_read_image_tag(master, "rootfs", cfelen, buf);
156-
if (!ret) {
157-
STR_NULL_TERMINATE(buf->flash_image_start);
158-
if (kstrtouint(buf->flash_image_start, 10, &rootfsaddr) ||
159-
rootfsaddr < BCM963XX_EXTENDED_SIZE) {
160-
pr_err("invalid rootfs address: %*ph\n",
161-
(int)sizeof(buf->flash_image_start),
162-
buf->flash_image_start);
163-
goto invalid_tag;
164-
}
165-
166-
STR_NULL_TERMINATE(buf->kernel_address);
167-
if (kstrtouint(buf->kernel_address, 10, &kerneladdr) ||
168-
kerneladdr < BCM963XX_EXTENDED_SIZE) {
169-
pr_err("invalid kernel address: %*ph\n",
170-
(int)sizeof(buf->kernel_address),
171-
buf->kernel_address);
172-
goto invalid_tag;
173-
}
174-
175-
STR_NULL_TERMINATE(buf->kernel_length);
176-
if (kstrtouint(buf->kernel_length, 10, &kernellen)) {
177-
pr_err("invalid kernel length: %*ph\n",
178-
(int)sizeof(buf->kernel_length),
179-
buf->kernel_length);
180-
goto invalid_tag;
181-
}
182-
183-
STR_NULL_TERMINATE(buf->total_length);
184-
if (kstrtouint(buf->total_length, 10, &totallen)) {
185-
pr_err("invalid total length: %*ph\n",
186-
(int)sizeof(buf->total_length),
187-
buf->total_length);
188-
goto invalid_tag;
189-
}
190-
191-
kerneladdr = kerneladdr - BCM963XX_EXTENDED_SIZE;
192-
rootfsaddr = rootfsaddr - BCM963XX_EXTENDED_SIZE;
193-
spareaddr = roundup(totallen, master->erasesize) + cfelen;
194-
195-
if (rootfsaddr < kerneladdr) {
196-
/* default Broadcom layout */
197-
rootfslen = kerneladdr - rootfsaddr;
198-
rootfs_first = true;
199-
} else {
200-
/* OpenWrt layout */
201-
rootfsaddr = kerneladdr + kernellen;
202-
rootfslen = spareaddr - rootfsaddr;
203-
}
204-
} else if (ret > 0) {
205-
invalid_tag:
206-
kernellen = 0;
207-
rootfslen = 0;
208-
rootfsaddr = 0;
209-
spareaddr = cfelen;
210-
} else {
211-
goto out;
212-
}
213-
sparelen = master->size - spareaddr - nvramlen;
214-
215-
/* Determine number of partitions */
216-
if (rootfslen > 0)
217-
nrparts++;
218-
219-
if (kernellen > 0)
220-
nrparts++;
221-
222118
parts = kzalloc(sizeof(*parts) * nrparts + 10 * nrparts, GFP_KERNEL);
223-
if (!parts) {
224-
ret = -ENOMEM;
225-
goto out;
226-
}
119+
if (!parts)
120+
return -ENOMEM;
227121

228122
/* Start building partition list */
229123
parts[curpart].name = "CFE";
230124
parts[curpart].offset = 0;
231125
parts[curpart].size = cfelen;
232126
curpart++;
233127

234-
if (kernellen > 0) {
235-
int kernelpart = curpart;
236-
237-
if (rootfslen > 0 && rootfs_first)
238-
kernelpart++;
239-
parts[kernelpart].name = "kernel";
240-
parts[kernelpart].offset = kerneladdr;
241-
parts[kernelpart].size = kernellen;
242-
curpart++;
243-
}
244-
245-
if (rootfslen > 0) {
246-
int rootfspart = curpart;
247-
248-
if (kernellen > 0 && rootfs_first)
249-
rootfspart--;
250-
parts[rootfspart].name = "rootfs";
251-
parts[rootfspart].offset = rootfsaddr;
252-
parts[rootfspart].size = rootfslen;
253-
if (sparelen > 0 && !rootfs_first)
254-
parts[rootfspart].size += sparelen;
255-
curpart++;
256-
}
257-
258128
parts[curpart].name = "nvram";
259129
parts[curpart].offset = master->size - nvramlen;
260130
parts[curpart].size = nvramlen;
@@ -264,22 +134,13 @@ static int bcm63xx_parse_cfe_nor_partitions(struct mtd_info *master,
264134
parts[curpart].name = "linux";
265135
parts[curpart].offset = cfelen;
266136
parts[curpart].size = master->size - cfelen - nvramlen;
137+
parts[curpart].types = bcm63xx_cfe_part_types;
267138

268139
for (i = 0; i < nrparts; i++)
269140
pr_info("Partition %d is %s offset %llx and length %llx\n", i,
270141
parts[i].name, parts[i].offset, parts[i].size);
271142

272-
pr_info("Spare partition is offset %x and length %x\n", spareaddr,
273-
sparelen);
274-
275143
*pparts = parts;
276-
ret = 0;
277-
278-
out:
279-
vfree(buf);
280-
281-
if (ret)
282-
return ret;
283144

284145
return nrparts;
285146
}

drivers/mtd/parsers/Kconfig

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
config MTD_PARSER_IMAGETAG
2+
tristate "Parser for BCM963XX Image Tag format partitions"
3+
depends on BCM63XX || BMIPS_GENERIC || COMPILE_TEST
4+
select CRC32
5+
help
6+
Image Tag is the firmware header used by broadcom on their xDSL line
7+
of devices. It is used to describe the offsets and lengths of kernel
8+
and rootfs partitions.
9+
This driver adds support for parsing a partition with an Image Tag
10+
header and creates up to two partitions, kernel and rootfs.
11+
112
config MTD_PARSER_TRX
213
tristate "Parser for TRX format partitions"
314
depends on MTD && (BCM47XX || ARCH_BCM_5301X || COMPILE_TEST)

drivers/mtd/parsers/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
obj-$(CONFIG_MTD_PARSER_IMAGETAG) += parser_imagetag.o
12
obj-$(CONFIG_MTD_PARSER_TRX) += parser_trx.o
23
obj-$(CONFIG_MTD_SHARPSL_PARTS) += sharpslpart.o
34
obj-$(CONFIG_MTD_REDBOOT_PARTS) += redboot.o

0 commit comments

Comments
 (0)