aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafał Miłecki <rafal@milecki.pl>2017-01-10 17:15:24 -0500
committerBrian Norris <computersforpeace@gmail.com>2017-02-09 21:59:41 -0500
commitb522d7b0ebe3539340c2a6d46d787ae3d33bcb92 (patch)
tree687a12908c5b8f4ecaea0906b00de944fa5b3c03
parentccc38234fdc70120be79e7fb2df5c27ca5cd4c8a (diff)
mtd: bcm47xxpart: move TRX parsing code to separated function
This change simplifies main parsing loop logic a bit. In future it may be useful for moving TRX support to separated module / parser (if we implement support for them at some point). Finally parsing TRX at the end puts us in a better position as we have better flash layout knowledge. It may be useful e.g. if it appears there is more than 1 TRX partition. Signed-off-by: Rafał Miłecki <rafal@milecki.pl> Acked-by: Marek Vasut <marek.vasut@gmail.com> Signed-off-by: Brian Norris <computersforpeace@gmail.com>
-rw-r--r--drivers/mtd/bcm47xxpart.c121
1 files changed, 74 insertions, 47 deletions
diff --git a/drivers/mtd/bcm47xxpart.c b/drivers/mtd/bcm47xxpart.c
index 283ff7e17a0f..10930257c14c 100644
--- a/drivers/mtd/bcm47xxpart.c
+++ b/drivers/mtd/bcm47xxpart.c
@@ -83,6 +83,67 @@ out_default:
83 return "rootfs"; 83 return "rootfs";
84} 84}
85 85
86static int bcm47xxpart_parse_trx(struct mtd_info *master,
87 struct mtd_partition *trx,
88 struct mtd_partition *parts,
89 size_t parts_len)
90{
91 struct trx_header header;
92 size_t bytes_read;
93 int curr_part = 0;
94 int i, err;
95
96 if (parts_len < 3) {
97 pr_warn("No enough space to add TRX partitions!\n");
98 return -ENOMEM;
99 }
100
101 err = mtd_read(master, trx->offset, sizeof(header), &bytes_read,
102 (uint8_t *)&header);
103 if (err && !mtd_is_bitflip(err)) {
104 pr_err("mtd_read error while reading TRX header: %d\n", err);
105 return err;
106 }
107
108 i = 0;
109
110 /* We have LZMA loader if offset[2] points to sth */
111 if (header.offset[2]) {
112 bcm47xxpart_add_part(&parts[curr_part++], "loader",
113 trx->offset + header.offset[i], 0);
114 i++;
115 }
116
117 if (header.offset[i]) {
118 bcm47xxpart_add_part(&parts[curr_part++], "linux",
119 trx->offset + header.offset[i], 0);
120 i++;
121 }
122
123 if (header.offset[i]) {
124 size_t offset = trx->offset + header.offset[i];
125 const char *name = bcm47xxpart_trx_data_part_name(master,
126 offset);
127
128 bcm47xxpart_add_part(&parts[curr_part++], name, offset, 0);
129 i++;
130 }
131
132 /*
133 * Assume that every partition ends at the beginning of the one it is
134 * followed by.
135 */
136 for (i = 0; i < curr_part; i++) {
137 u64 next_part_offset = (i < curr_part - 1) ?
138 parts[i + 1].offset :
139 trx->offset + trx->size;
140
141 parts[i].size = next_part_offset - parts[i].offset;
142 }
143
144 return curr_part;
145}
146
86static int bcm47xxpart_parse(struct mtd_info *master, 147static int bcm47xxpart_parse(struct mtd_info *master,
87 const struct mtd_partition **pparts, 148 const struct mtd_partition **pparts,
88 struct mtd_part_parser_data *data) 149 struct mtd_part_parser_data *data)
@@ -93,9 +154,7 @@ static int bcm47xxpart_parse(struct mtd_info *master,
93 size_t bytes_read; 154 size_t bytes_read;
94 uint32_t offset; 155 uint32_t offset;
95 uint32_t blocksize = master->erasesize; 156 uint32_t blocksize = master->erasesize;
96 struct trx_header *trx;
97 int trx_part = -1; 157 int trx_part = -1;
98 int last_trx_part = -1;
99 int possible_nvram_sizes[] = { 0x8000, 0xF000, 0x10000, }; 158 int possible_nvram_sizes[] = { 0x8000, 0xF000, 0x10000, };
100 int err; 159 int err;
101 160
@@ -182,54 +241,14 @@ static int bcm47xxpart_parse(struct mtd_info *master,
182 241
183 /* TRX */ 242 /* TRX */
184 if (buf[0x000 / 4] == TRX_MAGIC) { 243 if (buf[0x000 / 4] == TRX_MAGIC) {
185 if (BCM47XXPART_MAX_PARTS - curr_part < 4) { 244 struct trx_header *trx;
186 pr_warn("Not enough partitions left to register trx, scanning stopped!\n");
187 break;
188 }
189
190 trx = (struct trx_header *)buf;
191 245
192 trx_part = curr_part; 246 trx_part = curr_part;
193 bcm47xxpart_add_part(&parts[curr_part++], "firmware", 247 bcm47xxpart_add_part(&parts[curr_part++], "firmware",
194 offset, 0); 248 offset, 0);
195 249
196 i = 0;
197 /* We have LZMA loader if offset[2] points to sth */
198 if (trx->offset[2]) {
199 bcm47xxpart_add_part(&parts[curr_part++],
200 "loader",
201 offset + trx->offset[i],
202 0);
203 i++;
204 }
205
206 if (trx->offset[i]) {
207 bcm47xxpart_add_part(&parts[curr_part++],
208 "linux",
209 offset + trx->offset[i],
210 0);
211 i++;
212 }
213
214 /*
215 * Pure rootfs size is known and can be calculated as:
216 * trx->length - trx->offset[i]. We don't fill it as
217 * we want to have jffs2 (overlay) in the same mtd.
218 */
219 if (trx->offset[i]) {
220 const char *name;
221
222 name = bcm47xxpart_trx_data_part_name(master, offset + trx->offset[i]);
223 bcm47xxpart_add_part(&parts[curr_part++],
224 name,
225 offset + trx->offset[i],
226 0);
227 i++;
228 }
229
230 last_trx_part = curr_part - 1;
231
232 /* Jump to the end of TRX */ 250 /* Jump to the end of TRX */
251 trx = (struct trx_header *)buf;
233 offset = roundup(offset + trx->length, blocksize); 252 offset = roundup(offset + trx->length, blocksize);
234 /* Next loop iteration will increase the offset */ 253 /* Next loop iteration will increase the offset */
235 offset -= blocksize; 254 offset -= blocksize;
@@ -307,9 +326,17 @@ static int bcm47xxpart_parse(struct mtd_info *master,
307 parts[i + 1].offset : master->size; 326 parts[i + 1].offset : master->size;
308 327
309 parts[i].size = next_part_offset - parts[i].offset; 328 parts[i].size = next_part_offset - parts[i].offset;
310 if (i == last_trx_part && trx_part >= 0) 329 }
311 parts[trx_part].size = next_part_offset - 330
312 parts[trx_part].offset; 331 /* If there was TRX parse it now */
332 if (trx_part >= 0) {
333 int num_parts;
334
335 num_parts = bcm47xxpart_parse_trx(master, &parts[trx_part],
336 parts + curr_part,
337 BCM47XXPART_MAX_PARTS - curr_part);
338 if (num_parts > 0)
339 curr_part += num_parts;
313 } 340 }
314 341
315 *pparts = parts; 342 *pparts = parts;