diff options
author | Simon Arlott <simon@fire.lp0.eu> | 2015-12-13 17:51:02 -0500 |
---|---|---|
committer | Brian Norris <computersforpeace@gmail.com> | 2016-02-12 13:34:15 -0500 |
commit | 7fffa694a8917af0c553ab48290a57e3674aa5d3 (patch) | |
tree | 4e5a867fcc8fdd8cb4363f3666463af0b609fa8a /drivers/mtd/bcm63xxpart.c | |
parent | 436e94a6fbcdca133a2546769db4ac0a84265ad1 (diff) |
mtd: bcm63xxpart: Extract read of image tag to separate function
Extract image tag reading and CRC check to a separate function.
Signed-off-by: Simon Arlott <simon@fire.lp0.eu>
Signed-off-by: Brian Norris <computersforpeace@gmail.com>
Diffstat (limited to 'drivers/mtd/bcm63xxpart.c')
-rw-r--r-- | drivers/mtd/bcm63xxpart.c | 62 |
1 files changed, 40 insertions, 22 deletions
diff --git a/drivers/mtd/bcm63xxpart.c b/drivers/mtd/bcm63xxpart.c index 1eea8b6bc66a..eafbf521a547 100644 --- a/drivers/mtd/bcm63xxpart.c +++ b/drivers/mtd/bcm63xxpart.c | |||
@@ -41,6 +41,10 @@ | |||
41 | #define BCM963XX_CFE_VERSION_OFFSET 0x570 | 41 | #define BCM963XX_CFE_VERSION_OFFSET 0x570 |
42 | #define BCM963XX_NVRAM_OFFSET 0x580 | 42 | #define BCM963XX_NVRAM_OFFSET 0x580 |
43 | 43 | ||
44 | /* Ensure strings read from flash structs are null terminated */ | ||
45 | #define STR_NULL_TERMINATE(x) \ | ||
46 | do { char *_str = (x); _str[sizeof(x) - 1] = 0; } while (0) | ||
47 | |||
44 | static int bcm63xx_detect_cfe(struct mtd_info *master) | 48 | static int bcm63xx_detect_cfe(struct mtd_info *master) |
45 | { | 49 | { |
46 | char buf[9]; | 50 | char buf[9]; |
@@ -89,6 +93,37 @@ static int bcm63xx_read_nvram(struct mtd_info *master, | |||
89 | return 0; | 93 | return 0; |
90 | } | 94 | } |
91 | 95 | ||
96 | static int bcm63xx_read_image_tag(struct mtd_info *master, const char *name, | ||
97 | loff_t tag_offset, struct bcm_tag *buf) | ||
98 | { | ||
99 | int ret; | ||
100 | size_t retlen; | ||
101 | u32 computed_crc; | ||
102 | |||
103 | ret = mtd_read(master, tag_offset, sizeof(*buf), &retlen, (void *)buf); | ||
104 | if (ret) | ||
105 | return ret; | ||
106 | |||
107 | if (retlen != sizeof(*buf)) | ||
108 | return -EIO; | ||
109 | |||
110 | computed_crc = crc32_le(IMAGETAG_CRC_START, (u8 *)buf, | ||
111 | offsetof(struct bcm_tag, header_crc)); | ||
112 | if (computed_crc == buf->header_crc) { | ||
113 | STR_NULL_TERMINATE(buf->board_id); | ||
114 | STR_NULL_TERMINATE(buf->tag_version); | ||
115 | |||
116 | pr_info("%s: CFE image tag found at 0x%llx with version %s, board type %s\n", | ||
117 | name, tag_offset, buf->tag_version, buf->board_id); | ||
118 | |||
119 | return 0; | ||
120 | } | ||
121 | |||
122 | pr_warn("%s: CFE image tag at 0x%llx CRC invalid (expected %08x, actual %08x)\n", | ||
123 | name, tag_offset, buf->header_crc, computed_crc); | ||
124 | return 1; | ||
125 | } | ||
126 | |||
92 | static int bcm63xx_parse_cfe_partitions(struct mtd_info *master, | 127 | static int bcm63xx_parse_cfe_partitions(struct mtd_info *master, |
93 | const struct mtd_partition **pparts, | 128 | const struct mtd_partition **pparts, |
94 | struct mtd_part_parser_data *data) | 129 | struct mtd_part_parser_data *data) |
@@ -99,13 +134,11 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master, | |||
99 | struct bcm_tag *buf = NULL; | 134 | struct bcm_tag *buf = NULL; |
100 | struct mtd_partition *parts; | 135 | struct mtd_partition *parts; |
101 | int ret; | 136 | int ret; |
102 | size_t retlen; | ||
103 | unsigned int rootfsaddr, kerneladdr, spareaddr; | 137 | unsigned int rootfsaddr, kerneladdr, spareaddr; |
104 | unsigned int rootfslen, kernellen, sparelen, totallen; | 138 | unsigned int rootfslen, kernellen, sparelen, totallen; |
105 | unsigned int cfelen, nvramlen; | 139 | unsigned int cfelen, nvramlen; |
106 | unsigned int cfe_erasesize; | 140 | unsigned int cfe_erasesize; |
107 | int i; | 141 | int i; |
108 | u32 computed_crc; | ||
109 | bool rootfs_first = false; | 142 | bool rootfs_first = false; |
110 | 143 | ||
111 | if (bcm63xx_detect_cfe(master)) | 144 | if (bcm63xx_detect_cfe(master)) |
@@ -134,28 +167,13 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master, | |||
134 | } | 167 | } |
135 | 168 | ||
136 | /* Get the tag */ | 169 | /* Get the tag */ |
137 | ret = mtd_read(master, cfelen, sizeof(struct bcm_tag), &retlen, | 170 | ret = bcm63xx_read_image_tag(master, "rootfs", cfelen, buf); |
138 | (void *)buf); | 171 | if (!ret) { |
139 | |||
140 | if (retlen != sizeof(struct bcm_tag)) { | ||
141 | ret = -EIO; | ||
142 | goto out; | ||
143 | } | ||
144 | |||
145 | computed_crc = crc32_le(IMAGETAG_CRC_START, (u8 *)buf, | ||
146 | offsetof(struct bcm_tag, header_crc)); | ||
147 | if (computed_crc == buf->header_crc) { | ||
148 | char *boardid = &(buf->board_id[0]); | ||
149 | char *tagversion = &(buf->tag_version[0]); | ||
150 | |||
151 | sscanf(buf->flash_image_start, "%u", &rootfsaddr); | 172 | sscanf(buf->flash_image_start, "%u", &rootfsaddr); |
152 | sscanf(buf->kernel_address, "%u", &kerneladdr); | 173 | sscanf(buf->kernel_address, "%u", &kerneladdr); |
153 | sscanf(buf->kernel_length, "%u", &kernellen); | 174 | sscanf(buf->kernel_length, "%u", &kernellen); |
154 | sscanf(buf->total_length, "%u", &totallen); | 175 | sscanf(buf->total_length, "%u", &totallen); |
155 | 176 | ||
156 | pr_info("CFE boot tag found with version %s and board type %s\n", | ||
157 | tagversion, boardid); | ||
158 | |||
159 | kerneladdr = kerneladdr - BCM963XX_EXTENDED_SIZE; | 177 | kerneladdr = kerneladdr - BCM963XX_EXTENDED_SIZE; |
160 | rootfsaddr = rootfsaddr - BCM963XX_EXTENDED_SIZE; | 178 | rootfsaddr = rootfsaddr - BCM963XX_EXTENDED_SIZE; |
161 | spareaddr = roundup(totallen, master->erasesize) + cfelen; | 179 | spareaddr = roundup(totallen, master->erasesize) + cfelen; |
@@ -169,13 +187,13 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master, | |||
169 | rootfsaddr = kerneladdr + kernellen; | 187 | rootfsaddr = kerneladdr + kernellen; |
170 | rootfslen = spareaddr - rootfsaddr; | 188 | rootfslen = spareaddr - rootfsaddr; |
171 | } | 189 | } |
172 | } else { | 190 | } else if (ret > 0) { |
173 | pr_warn("CFE boot tag CRC invalid (expected %08x, actual %08x)\n", | ||
174 | buf->header_crc, computed_crc); | ||
175 | kernellen = 0; | 191 | kernellen = 0; |
176 | rootfslen = 0; | 192 | rootfslen = 0; |
177 | rootfsaddr = 0; | 193 | rootfsaddr = 0; |
178 | spareaddr = cfelen; | 194 | spareaddr = cfelen; |
195 | } else { | ||
196 | goto out; | ||
179 | } | 197 | } |
180 | sparelen = master->size - spareaddr - nvramlen; | 198 | sparelen = master->size - spareaddr - nvramlen; |
181 | 199 | ||