diff options
| author | Rafał Miłecki <rafal@milecki.pl> | 2017-01-10 17:15:24 -0500 |
|---|---|---|
| committer | Brian Norris <computersforpeace@gmail.com> | 2017-02-09 21:59:41 -0500 |
| commit | b522d7b0ebe3539340c2a6d46d787ae3d33bcb92 (patch) | |
| tree | 687a12908c5b8f4ecaea0906b00de944fa5b3c03 | |
| parent | ccc38234fdc70120be79e7fb2df5c27ca5cd4c8a (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.c | 121 |
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 | ||
| 86 | static 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 | |||
| 86 | static int bcm47xxpart_parse(struct mtd_info *master, | 147 | static 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; |
