diff options
Diffstat (limited to 'utils/atj2137/atjboottool/atjboottool.c')
-rw-r--r-- | utils/atj2137/atjboottool/atjboottool.c | 416 |
1 files changed, 31 insertions, 385 deletions
diff --git a/utils/atj2137/atjboottool/atjboottool.c b/utils/atj2137/atjboottool/atjboottool.c index 676fdae199..d0ad1b468b 100644 --- a/utils/atj2137/atjboottool/atjboottool.c +++ b/utils/atj2137/atjboottool/atjboottool.c | |||
@@ -29,6 +29,8 @@ | |||
29 | #include <sys/stat.h> | 29 | #include <sys/stat.h> |
30 | #include "misc.h" | 30 | #include "misc.h" |
31 | #include "fwu.h" | 31 | #include "fwu.h" |
32 | #include "afi.h" | ||
33 | #include "fw.h" | ||
32 | 34 | ||
33 | bool g_debug = false; | 35 | bool g_debug = false; |
34 | char *g_out_prefix = NULL; | 36 | char *g_out_prefix = NULL; |
@@ -89,407 +91,51 @@ static int do_fwu(uint8_t *buf, size_t size, enum fwu_mode_t mode) | |||
89 | } | 91 | } |
90 | } | 92 | } |
91 | 93 | ||
92 | /** | 94 | static int unpack_afi_fw_cb(const char *filename, uint8_t *buf, size_t size) |
93 | * AFI | ||
94 | * | ||
95 | * part of this work comes from s1mp3/s1fwx | ||
96 | **/ | ||
97 | |||
98 | #define AFI_ENTRIES 126 | ||
99 | #define AFI_SIG_SIZE 4 | ||
100 | |||
101 | struct afi_hdr_t | ||
102 | { | ||
103 | uint8_t sig[AFI_SIG_SIZE]; | ||
104 | uint16_t vendor_id; | ||
105 | uint16_t product_id; | ||
106 | uint8_t ver_id[2]; | ||
107 | uint8_t ext_ver_id[2]; | ||
108 | uint8_t year[2]; | ||
109 | uint8_t month; | ||
110 | uint8_t day; | ||
111 | uint32_t afi_size; | ||
112 | uint32_t res[3]; | ||
113 | } __attribute__((packed)); | ||
114 | |||
115 | struct afi_entry_t | ||
116 | { | ||
117 | char name[8]; | ||
118 | char ext[3]; | ||
119 | char type; | ||
120 | uint32_t addr; | ||
121 | uint32_t offset; | ||
122 | uint32_t size; | ||
123 | char desc[4]; | ||
124 | uint32_t checksum; | ||
125 | } __attribute__((packed)); | ||
126 | |||
127 | struct afi_post_hdr_t | ||
128 | { | ||
129 | uint8_t res[28]; | ||
130 | uint32_t checksum; | ||
131 | } __attribute__((packed)); | ||
132 | |||
133 | struct afi_t | ||
134 | { | ||
135 | struct afi_hdr_t hdr; | ||
136 | struct afi_entry_t entry[AFI_ENTRIES]; | ||
137 | struct afi_post_hdr_t post; | ||
138 | }; | ||
139 | |||
140 | #define AFI_ENTRY_BREC 'B' | ||
141 | #define AFI_ENTRY_FWSC 'F' | ||
142 | #define AFI_ENTRY_ADFUS 'A' | ||
143 | #define AFI_ENTRY_FW 'I' | ||
144 | |||
145 | #define AFI_ENTRY_DLADR_BREC 0x00000006 // 'B' | ||
146 | #define AFI_ENTRY_DLADR_FWSC 0x00020008 // 'F' | ||
147 | #define AFI_ENTRY_DLADR_ADFUS 0x000C0008 // 'A' | ||
148 | #define AFI_ENTRY_DLADR_ADFU 0x00000000 // 'U' | ||
149 | #define AFI_ENTRY_DLADR_FW 0x00000011 // 'I' | ||
150 | |||
151 | const uint8_t g_afi_signature[AFI_SIG_SIZE] = | ||
152 | { | 95 | { |
153 | 'A', 'F', 'I', 0 | 96 | char *name = malloc(strlen(g_out_prefix) + strlen(filename) + 16); |
154 | }; | 97 | sprintf(name, "%s%s", g_out_prefix, filename); |
155 | 98 | ||
156 | static uint32_t afi_checksum(void *ptr, int size) | 99 | cprintf(GREY, "Unpacking to %s... ", name); |
157 | { | 100 | FILE *f = fopen(name, "wb"); |
158 | uint32_t crc = 0; | 101 | if(f) |
159 | uint32_t *cp = ptr; | ||
160 | for(; size >= 4; size -= 4) | ||
161 | crc += *cp++; | ||
162 | if(size == 1) | ||
163 | crc += *(uint8_t *)cp; | ||
164 | else if(size == 2) | ||
165 | crc += *(uint16_t *)cp; | ||
166 | else if(size == 3) | ||
167 | crc += *(uint16_t *)cp + ((*(uint8_t *)(cp + 2)) << 16); | ||
168 | return crc; | ||
169 | } | ||
170 | |||
171 | static void build_filename(char buf[16], struct afi_entry_t *ent) | ||
172 | { | ||
173 | int pos = 0; | ||
174 | for(int i = 0; i < 8 && ent->name[i] != ' '; i++) | ||
175 | buf[pos++] = ent->name[i]; | ||
176 | buf[pos++] = '.'; | ||
177 | for(int i = 0; i < 3 && ent->ext[i] != ' '; i++) | ||
178 | buf[pos++] = ent->ext[i]; | ||
179 | buf[pos] = 0; | ||
180 | } | ||
181 | |||
182 | static int do_afi(uint8_t *buf, int size) | ||
183 | { | ||
184 | struct afi_t *afi = (void *)buf; | ||
185 | |||
186 | if(size < (int)sizeof(struct afi_t)) | ||
187 | { | ||
188 | cprintf(GREY, "File too small\n"); | ||
189 | return 1; | ||
190 | } | ||
191 | cprintf(BLUE, "Header\n"); | ||
192 | cprintf(GREEN, " Signature:"); | ||
193 | for(int i = 0; i < AFI_SIG_SIZE; i++) | ||
194 | cprintf(YELLOW, " %02x", afi->hdr.sig[i]); | ||
195 | if(memcmp(afi->hdr.sig, g_afi_signature, AFI_SIG_SIZE) == 0) | ||
196 | cprintf(RED, " Ok\n"); | ||
197 | else | ||
198 | { | 102 | { |
199 | cprintf(RED, " Mismatch\n"); | 103 | fwrite(buf, size, 1, f); |
200 | return 1; | 104 | fclose(f); |
105 | cprintf(RED, "Ok\n"); | ||
106 | return 0; | ||
201 | } | 107 | } |
202 | |||
203 | cprintf_field(" Vendor ID: ", "0x%x\n", afi->hdr.vendor_id); | ||
204 | cprintf_field(" Product ID: ", "0x%x\n", afi->hdr.product_id); | ||
205 | cprintf_field(" Version: ", "%x.%x\n", afi->hdr.ver_id[0], afi->hdr.ver_id[1]); | ||
206 | cprintf_field(" Ext Version: ", "%x.%x\n", afi->hdr.ext_ver_id[0], | ||
207 | afi->hdr.ext_ver_id[1]); | ||
208 | cprintf_field(" Date: ", "%02x/%02x/%02x%02x\n", afi->hdr.day, afi->hdr.month, | ||
209 | afi->hdr.year[0], afi->hdr.year[1]); | ||
210 | |||
211 | cprintf_field(" AFI size: ", "%d ", afi->hdr.afi_size); | ||
212 | if((int)afi->hdr.afi_size == size) | ||
213 | cprintf(RED, " Ok\n"); | ||
214 | else if((int)afi->hdr.afi_size < size) | ||
215 | cprintf(RED, " Ok (file greater than archive)\n"); | ||
216 | else | 108 | else |
217 | { | 109 | { |
218 | cprintf(RED, " Error (file too small)\n"); | 110 | color(RED); |
111 | perror("Failed"); | ||
219 | return 1; | 112 | return 1; |
220 | } | 113 | } |
221 | |||
222 | cprintf_field(" Reserved: ", "%x %x %x\n", afi->hdr.res[0], | ||
223 | afi->hdr.res[1], afi->hdr.res[2]); | ||
224 | |||
225 | build_out_prefix(".fw", "", true); | ||
226 | |||
227 | cprintf(BLUE, "Entries\n"); | ||
228 | for(int i = 0; i < AFI_ENTRIES; i++) | ||
229 | { | ||
230 | if(afi->entry[i].name[0] == 0) | ||
231 | continue; | ||
232 | struct afi_entry_t *entry = &afi->entry[i]; | ||
233 | char filename[16]; | ||
234 | build_filename(filename, entry); | ||
235 | cprintf(RED, " %s\n", filename); | ||
236 | cprintf_field(" Type: ", "%02x", entry->type); | ||
237 | if(isprint(entry->type)) | ||
238 | cprintf(RED, " %c", entry->type); | ||
239 | printf("\n"); | ||
240 | cprintf_field(" Addr: ", "0x%x\n", entry->addr); | ||
241 | cprintf_field(" Offset: ", "0x%x\n", entry->offset); | ||
242 | cprintf_field(" Size: ", "0x%x\n", entry->size); | ||
243 | cprintf_field(" Desc: ", "%.4s\n", entry->desc); | ||
244 | cprintf_field(" Checksum: ", "0x%x ", entry->checksum); | ||
245 | uint32_t chk = afi_checksum(buf + entry->offset, entry->size); | ||
246 | cprintf(RED, "%s\n", chk == entry->checksum ? "Ok" : "Mismatch"); | ||
247 | |||
248 | char *name = malloc(strlen(g_out_prefix) + strlen(filename) + 16); | ||
249 | sprintf(name, "%s%s", g_out_prefix, filename); | ||
250 | |||
251 | cprintf(GREY, "Unpacking to %s... ", name); | ||
252 | FILE *f = fopen(name, "wb"); | ||
253 | if(f) | ||
254 | { | ||
255 | fwrite(buf + entry->offset, entry->size, 1, f); | ||
256 | fclose(f); | ||
257 | cprintf(RED, "Ok\n"); | ||
258 | } | ||
259 | else | ||
260 | cprintf(RED, "Failed: %m\n"); | ||
261 | } | ||
262 | |||
263 | cprintf(BLUE, "Post Header\n"); | ||
264 | cprintf_field(" Checksum: ", "%x ", afi->post.checksum); | ||
265 | uint32_t chk = afi_checksum(buf, sizeof(struct afi_t) - 4); | ||
266 | cprintf(RED, "%s\n", chk == afi->post.checksum ? "Ok" : "Mismatch"); | ||
267 | |||
268 | return 0; | ||
269 | } | 114 | } |
270 | 115 | ||
271 | bool afi_check(uint8_t *buf, int size) | 116 | static int do_afi(uint8_t *buf, size_t size) |
272 | { | 117 | { |
273 | struct afi_hdr_t *hdr = (void *)buf; | 118 | build_out_prefix(".fw", "", true); |
274 | 119 | return afi_unpack(buf, size, &unpack_afi_fw_cb); | |
275 | if(size < (int)sizeof(struct afi_hdr_t)) | ||
276 | return false; | ||
277 | return memcmp(hdr->sig, g_afi_signature, AFI_SIG_SIZE) == 0; | ||
278 | } | ||
279 | |||
280 | /** | ||
281 | * FW | ||
282 | **/ | ||
283 | |||
284 | #define FW_SIG_SIZE 4 | ||
285 | |||
286 | #define FW_ENTRIES 240 | ||
287 | |||
288 | struct fw_entry_t | ||
289 | { | ||
290 | char name[8]; | ||
291 | char ext[3]; | ||
292 | uint8_t attr; | ||
293 | uint8_t res[2]; | ||
294 | uint16_t version; | ||
295 | uint32_t block_offset; // offset shift by 9 | ||
296 | uint32_t size; | ||
297 | uint32_t unk; | ||
298 | uint32_t checksum; | ||
299 | } __attribute__((packed)); | ||
300 | |||
301 | struct fw_hdr_t | ||
302 | { | ||
303 | uint8_t sig[FW_SIG_SIZE]; | ||
304 | uint32_t res[4]; | ||
305 | uint8_t year[2]; | ||
306 | uint8_t month; | ||
307 | uint8_t day; | ||
308 | uint16_t usb_vid; | ||
309 | uint16_t usb_pid; | ||
310 | uint32_t checksum; | ||
311 | char productor[16]; | ||
312 | char str2[16]; | ||
313 | char str3[32]; | ||
314 | char dev_name[32]; | ||
315 | uint8_t res2[8 * 16]; | ||
316 | char usb_name1[8]; | ||
317 | char usb_name2[8]; | ||
318 | char res3[4 * 16 + 1]; | ||
319 | char mtp_name1[33]; | ||
320 | char mtp_name2[33]; | ||
321 | char mtp_ver[33]; | ||
322 | uint16_t mtp_vid; | ||
323 | uint16_t mtp_pid; | ||
324 | char fw_ver[64]; | ||
325 | uint32_t res4[2]; | ||
326 | |||
327 | struct fw_entry_t entry[FW_ENTRIES]; | ||
328 | } __attribute__((packed)); | ||
329 | |||
330 | /* the s1fwx source code has a layout but it does not make any sense for firmwares | ||
331 | * found in ATJ2127 for example. In doubt just don't do anything */ | ||
332 | struct fw_hdr_f0_t | ||
333 | { | ||
334 | uint8_t sig[FW_SIG_SIZE]; | ||
335 | uint8_t res[12]; | ||
336 | uint32_t checksum; | ||
337 | uint8_t res2[492]; | ||
338 | |||
339 | struct fw_entry_t entry[FW_ENTRIES]; | ||
340 | } __attribute__((packed)); | ||
341 | |||
342 | const uint8_t g_fw_signature_f2[FW_SIG_SIZE] = | ||
343 | { | ||
344 | 0x55, 0xaa, 0xf2, 0x0f | ||
345 | }; | ||
346 | |||
347 | const uint8_t g_fw_signature_f0[FW_SIG_SIZE] = | ||
348 | { | ||
349 | 0x55, 0xaa, 0xf0, 0x0f | ||
350 | }; | ||
351 | |||
352 | static void build_filename_fw(char buf[16], struct fw_entry_t *ent) | ||
353 | { | ||
354 | int pos = 0; | ||
355 | for(int i = 0; i < 8 && ent->name[i] != ' '; i++) | ||
356 | buf[pos++] = ent->name[i]; | ||
357 | buf[pos++] = '.'; | ||
358 | for(int i = 0; i < 3 && ent->ext[i] != ' '; i++) | ||
359 | buf[pos++] = ent->ext[i]; | ||
360 | buf[pos] = 0; | ||
361 | } | 120 | } |
362 | 121 | ||
363 | static int do_fw(uint8_t *buf, int size) | 122 | static int do_fw(uint8_t *buf, size_t size) |
364 | { | 123 | { |
365 | struct fw_hdr_t *hdr = (void *)buf; | ||
366 | |||
367 | if(size < (int)sizeof(struct fw_hdr_t)) | ||
368 | { | ||
369 | cprintf(GREY, "File too small\n"); | ||
370 | return 1; | ||
371 | } | ||
372 | cprintf(BLUE, "Header\n"); | ||
373 | cprintf(GREEN, " Signature:"); | ||
374 | for(int i = 0; i < FW_SIG_SIZE; i++) | ||
375 | cprintf(YELLOW, " %02x", hdr->sig[i]); | ||
376 | int variant = 0; | ||
377 | if(memcmp(hdr->sig, g_fw_signature_f2, FW_SIG_SIZE) == 0) | ||
378 | { | ||
379 | variant = 0xf2; | ||
380 | cprintf(RED, " Ok (f2 variant)\n"); | ||
381 | } | ||
382 | else if(memcmp(hdr->sig, g_fw_signature_f0, FW_SIG_SIZE) == 0) | ||
383 | { | ||
384 | variant = 0xf0; | ||
385 | cprintf(RED, " Ok (f0 variant)\n"); | ||
386 | } | ||
387 | else | ||
388 | { | ||
389 | cprintf(RED, " Mismatch\n"); | ||
390 | return 1; | ||
391 | } | ||
392 | |||
393 | /* both variants have the same header size, only the fields differ */ | ||
394 | if(variant == 0xf2) | ||
395 | { | ||
396 | cprintf_field(" USB VID: ", "0x%x\n", hdr->usb_vid); | ||
397 | cprintf_field(" USB PID: ", "0x%x\n", hdr->usb_pid); | ||
398 | cprintf_field(" Date: ", "%x/%x/%02x%02x\n", hdr->day, hdr->month, hdr->year[0], hdr->year[1]); | ||
399 | cprintf_field(" Checksum: ", "%x\n", hdr->checksum); | ||
400 | cprintf_field(" Productor: ", "%.16s\n", hdr->productor); | ||
401 | cprintf_field(" String 2: ", "%.16s\n", hdr->str2); | ||
402 | cprintf_field(" String 3: ", "%.32s\n", hdr->str3); | ||
403 | cprintf_field(" Device Name: ", "%.32s\n", hdr->dev_name); | ||
404 | cprintf(GREEN, " Unknown:\n"); | ||
405 | for(int i = 0; i < 8; i++) | ||
406 | { | ||
407 | cprintf(YELLOW, " "); | ||
408 | for(int j = 0; j < 16; j++) | ||
409 | cprintf(YELLOW, "%02x ", hdr->res2[i * 16 + j]); | ||
410 | cprintf(YELLOW, "\n"); | ||
411 | } | ||
412 | cprintf_field(" USB Name 1: ", "%.8s\n", hdr->usb_name1); | ||
413 | cprintf_field(" USB Name 2: ", "%.8s\n", hdr->usb_name2); | ||
414 | cprintf_field(" MTP Name 1: ", "%.32s\n", hdr->mtp_name1); | ||
415 | cprintf_field(" MTP Name 2: ", "%.32s\n", hdr->mtp_name2); | ||
416 | cprintf_field(" MTP Version: ", "%.32s\n", hdr->mtp_ver); | ||
417 | |||
418 | cprintf_field(" MTP VID: ", "0x%x\n", hdr->mtp_vid); | ||
419 | cprintf_field(" MTP PID: ", "0x%x\n", hdr->mtp_pid); | ||
420 | cprintf_field(" FW Version: ", "%.64s\n", hdr->fw_ver); | ||
421 | } | ||
422 | else | ||
423 | { | ||
424 | /* struct fw_hdr_f0_t *hdr_f0 = (void *)hdr; */ | ||
425 | cprintf(GREEN, " Header not dumped because format is unclear.\n"); | ||
426 | } | ||
427 | |||
428 | build_out_prefix(".unpack", "", true); | 124 | build_out_prefix(".unpack", "", true); |
429 | 125 | return fw_unpack(buf, size, &unpack_afi_fw_cb); | |
430 | cprintf(BLUE, "Entries\n"); | ||
431 | for(int i = 0; i < AFI_ENTRIES; i++) | ||
432 | { | ||
433 | if(hdr->entry[i].name[0] == 0) | ||
434 | continue; | ||
435 | struct fw_entry_t *entry = &hdr->entry[i]; | ||
436 | char filename[16]; | ||
437 | build_filename_fw(filename, entry); | ||
438 | cprintf(RED, " %s\n", filename); | ||
439 | cprintf_field(" Attr: ", "%02x\n", entry->attr); | ||
440 | cprintf_field(" Offset: ", "0x%x\n", entry->block_offset << 9); | ||
441 | cprintf_field(" Size: ", "0x%x\n", entry->size); | ||
442 | cprintf_field(" Unknown: ", "%x\n", entry->unk); | ||
443 | cprintf_field(" Checksum: ", "0x%x ", entry->checksum); | ||
444 | uint32_t chk = afi_checksum(buf + (entry->block_offset << 9), entry->size); | ||
445 | cprintf(RED, "%s\n", chk == entry->checksum ? "Ok" : "Mismatch"); | ||
446 | if(g_out_prefix) | ||
447 | { | ||
448 | char *name = malloc(strlen(g_out_prefix) + strlen(filename) + 16); | ||
449 | sprintf(name, "%s%s", g_out_prefix, filename); | ||
450 | |||
451 | cprintf(GREY, "Unpacking to %s... ", name); | ||
452 | FILE *f = fopen(name, "wb"); | ||
453 | if(f) | ||
454 | { | ||
455 | fwrite(buf + (entry->block_offset << 9), entry->size, 1, f); | ||
456 | fclose(f); | ||
457 | cprintf(RED, "Ok\n"); | ||
458 | } | ||
459 | else | ||
460 | cprintf(RED, "Failed: %m\n"); | ||
461 | } | ||
462 | } | ||
463 | |||
464 | return 0; | ||
465 | } | ||
466 | |||
467 | static bool check_fw(uint8_t *buf, int size) | ||
468 | { | ||
469 | struct fw_hdr_t *hdr = (void *)buf; | ||
470 | |||
471 | if(size < (int)sizeof(struct fw_hdr_t)) | ||
472 | return false; | ||
473 | if(memcmp(hdr->sig, g_fw_signature_f2, FW_SIG_SIZE) == 0) | ||
474 | return true; | ||
475 | if(memcmp(hdr->sig, g_fw_signature_f0, FW_SIG_SIZE) == 0) | ||
476 | return true; | ||
477 | return false; | ||
478 | } | 126 | } |
479 | |||
480 | static void usage(void) | 127 | static void usage(void) |
481 | { | 128 | { |
482 | printf("Usage: atjboottool [options] firmware\n"); | 129 | printf("Usage: atjboottool [options] firmware\n"); |
483 | printf("Options:\n"); | 130 | printf("Options:\n"); |
484 | printf(" -o <prefix>\tSet output prefix\n"); | 131 | printf(" -o <path> Set output file or output prefix\n"); |
485 | printf(" -f/--force\tForce to continue on errors\n"); | 132 | printf(" -h/--help Display this message\n"); |
486 | printf(" -?/--help\tDisplay this message\n"); | 133 | printf(" -d/--debug Display debug messages\n"); |
487 | printf(" -d/--debug\tDisplay debug messages\n"); | 134 | printf(" -c/--no-color Disable color output\n"); |
488 | printf(" -c/--no-color\tDisable color output\n"); | 135 | printf(" --fwu Unpack a FWU firmware file\n"); |
489 | printf(" --fwu\tUnpack a FWU firmware file\n"); | 136 | printf(" --afi Unpack a AFI archive file\n"); |
490 | printf(" --afi\tUnpack a AFI archive file\n"); | 137 | printf(" --fw Unpack a FW archive file\n"); |
491 | printf(" --fw\tUnpack a FW archive file\n"); | 138 | printf(" --atj2127 Force ATJ2127 decryption mode\n"); |
492 | printf(" --atj2127\tForce ATJ2127 decryption mode\n"); | ||
493 | printf("The default is to try to guess the format.\n"); | 139 | printf("The default is to try to guess the format.\n"); |
494 | printf("If several formats are specified, all are tried.\n"); | 140 | printf("If several formats are specified, all are tried.\n"); |
495 | printf("If no output prefix is specified, a default one is picked.\n"); | 141 | printf("If no output prefix is specified, a default one is picked.\n"); |
@@ -507,7 +153,7 @@ int main(int argc, char **argv) | |||
507 | { | 153 | { |
508 | static struct option long_options[] = | 154 | static struct option long_options[] = |
509 | { | 155 | { |
510 | {"help", no_argument, 0, '?'}, | 156 | {"help", no_argument, 0, 'h'}, |
511 | {"debug", no_argument, 0, 'd'}, | 157 | {"debug", no_argument, 0, 'd'}, |
512 | {"no-color", no_argument, 0, 'c'}, | 158 | {"no-color", no_argument, 0, 'c'}, |
513 | {"fwu", no_argument, 0, 'u'}, | 159 | {"fwu", no_argument, 0, 'u'}, |
@@ -517,7 +163,7 @@ int main(int argc, char **argv) | |||
517 | {0, 0, 0, 0} | 163 | {0, 0, 0, 0} |
518 | }; | 164 | }; |
519 | 165 | ||
520 | int c = getopt_long(argc, argv, "?dcfo:a1", long_options, NULL); | 166 | int c = getopt_long(argc, argv, "hdco:a2", long_options, NULL); |
521 | if(c == -1) | 167 | if(c == -1) |
522 | break; | 168 | break; |
523 | switch(c) | 169 | switch(c) |
@@ -531,7 +177,7 @@ int main(int argc, char **argv) | |||
531 | g_debug = true; | 177 | g_debug = true; |
532 | break; | 178 | break; |
533 | break; | 179 | break; |
534 | case '?': | 180 | case 'h': |
535 | usage(); | 181 | usage(); |
536 | break; | 182 | break; |
537 | case 'o': | 183 | case 'o': |
@@ -591,7 +237,7 @@ int main(int argc, char **argv) | |||
591 | ret = do_fwu(buf, size, fwu_mode); | 237 | ret = do_fwu(buf, size, fwu_mode); |
592 | else if(try_afi || afi_check(buf, size)) | 238 | else if(try_afi || afi_check(buf, size)) |
593 | ret = do_afi(buf, size); | 239 | ret = do_afi(buf, size); |
594 | else if(try_fw || check_fw(buf, size)) | 240 | else if(try_fw || fw_check(buf, size)) |
595 | ret = do_fw(buf, size); | 241 | ret = do_fw(buf, size); |
596 | else | 242 | else |
597 | { | 243 | { |