blob: 36f38478bc481a7f4023c8f353744ceda1db9f90 [file] [log] [blame]
Robert Menesf83fc362008-09-27 16:37:16 +00001/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2008 by William Poetra Yoga Hadisoeseno and Frank Gevaerts
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
Frank Gevaertse645ced2008-08-29 18:53:52 +000021#include <stdio.h>
22#include <stdlib.h>
23#include <stdint.h>
24#include <string.h>
25#include <sys/types.h>
26#include <sys/stat.h>
27#include <fcntl.h>
28#include <unistd.h>
29#include <libgen.h>
Bertrik Sikken79642ea2009-06-28 09:52:24 +000030#include <arpa/inet.h>
Frank Gevaertse645ced2008-08-29 18:53:52 +000031
32#include <usb.h>
33
Frank Gevaertsc487c012008-09-13 16:23:01 +000034#define bswap_16(value) \
35 ((((value) & 0xff) << 8) | ((value) >> 8))
36
37#define bswap_32(value) \
38 (((uint32_t)bswap_16((uint16_t)((value) & 0xffff)) << 16) | \
39 (uint32_t)bswap_16((uint16_t)((value) >> 16)))
40
41#define host_to_le32(_x) bswap_32(htonl(_x))
42#define host_to_le16(_x) bswap_16(htons(_x))
43
Frank Gevaertse645ced2008-08-29 18:53:52 +000044void usage()
45{
Rafaël Carré811c3592010-06-08 23:04:17 +000046 fprintf(stderr, "usage: meizu_dfu m3 [SST39VF800.dfu] <M3.EBN>\n");
47 fprintf(stderr, " meizu_dfu m6 [SST39VF800.dfu] <M6.EBN>\n");
48 fprintf(stderr, " meizu_dfu m6sl [updateNAND_BE_070831.dfu] <M6SL.EBN>\n");
Frank Gevaertse645ced2008-08-29 18:53:52 +000049 exit(1);
50}
51
52uint32_t crc32(char *data, int len, uint32_t poly, uint32_t init)
53{
54 uint32_t crc_table[256];
55 uint32_t crc, t;
56 int i, j;
57
58 // generate the table
59 for (i = 0; i < 256; ++i) {
60 t = i;
61 for (j = 0; j < 8; ++j)
62 if (t & 1)
63 t = (t >> 1) ^ poly;
64 else
65 t >>= 1;
66 crc_table[i] = t;
67 }
68
69 // calculate the crc
70 crc = init;
71 for (i = 0; i < len; ++i)
72 crc = (crc >> 8) ^ crc_table[(crc^data[i]) & 0xff];
73
74 return crc;
75}
76
Frank Gevaertse645ced2008-08-29 18:53:52 +000077typedef struct {
78 char *name;
79 char *data;
80 int len;
81} image_data_t;
82
83typedef struct {
84 int delay;
85 int pre_off;
86 uint32_t pre_sig;
87 uint16_t suf_dev;
88 uint16_t suf_prod;
89 uint16_t suf_ven;
90 uint16_t suf_dfu;
91 char suf_sig[3];
92 uint8_t suf_len;
93} image_attr_t;
94
Frank Gevaerts3409e9d2008-08-31 21:36:04 +000095#define BLOCK_SIZE 2048
96#define DFU_TIMEOUT 0xa000
Frank Gevaertse645ced2008-08-29 18:53:52 +000097#define DFU_CRC_POLY 0xedb88320
98#define DFU_INIT_CRC 0xffffffff
99
Frank Gevaerts3409e9d2008-08-31 21:36:04 +0000100#define USB_VID_SAMSUNG 0x0419
Robert Menes063d37b2008-09-27 16:51:46 +0000101#define USB_PID_M6SL 0x0145
102#define USB_PID_M3_M6 0x0141
Frank Gevaerts3409e9d2008-08-31 21:36:04 +0000103
Frank Gevaertse645ced2008-08-29 18:53:52 +0000104void init_img(image_data_t *img, const char *filename, image_attr_t *attr)
105{
106 int fd, len, i, readlen;
107 struct stat statbuf;
108 char buf[BLOCK_SIZE];
109 uint32_t dfu_crc;
Frank Gevaertsc487c012008-09-13 16:23:01 +0000110 uint32_t le_len;
Frank Gevaertse645ced2008-08-29 18:53:52 +0000111
112 printf("Reading %s...", filename);
113
Bertrik Sikken79642ea2009-06-28 09:52:24 +0000114 if (stat(filename, &statbuf) < 0) {
115 printf("\nCould not stat file, exiting.\n");
116 exit(1);
117 }
Frank Gevaertse645ced2008-08-29 18:53:52 +0000118 len = statbuf.st_size;
119
120 img->name = basename(strdup(filename));
121 img->data = malloc(len + 16);
122 img->len = len + 16;
123
124 fd = open(filename, O_RDONLY);
125 for (i = 0; i < len; i += BLOCK_SIZE) {
126 readlen = ((len - i) < BLOCK_SIZE) ? (len - i) : BLOCK_SIZE;
127 read(fd, buf, readlen);
128 memcpy(img->data + i, buf, readlen);
129 }
130 close(fd);
131
Frank Gevaertsc487c012008-09-13 16:23:01 +0000132 le_len = host_to_le32(img->len);
Frank Gevaertse645ced2008-08-29 18:53:52 +0000133 // patch the data size in after the signature
Frank Gevaertsc487c012008-09-13 16:23:01 +0000134 memcpy(img->data + attr->pre_off + 4, &le_len, 4);
135
136 /* convert to little endian */
137 attr->suf_dev = host_to_le16(attr->suf_dev);
138 attr->suf_prod = host_to_le16(attr->suf_prod);
139 attr->suf_ven = host_to_le16(attr->suf_ven);
140 attr->suf_dfu = host_to_le16(attr->suf_dfu);
Frank Gevaertse645ced2008-08-29 18:53:52 +0000141
142 // append the suffix (excluding the checksum)
143 memcpy(img->data + len, &attr->suf_dev, 2);
144 memcpy(img->data + len + 2, &attr->suf_prod, 2);
145 memcpy(img->data + len + 4, &attr->suf_ven, 2);
146 memcpy(img->data + len + 6, &attr->suf_dfu, 2);
147 memcpy(img->data + len + 8, &attr->suf_sig, 3);
148 memcpy(img->data + len + 11, &attr->suf_len, 1);
149
Frank Gevaertsc487c012008-09-13 16:23:01 +0000150 dfu_crc = host_to_le32(crc32(img->data, len + 12, DFU_CRC_POLY, DFU_INIT_CRC));
Frank Gevaertse645ced2008-08-29 18:53:52 +0000151 memcpy(img->data + len + 12, &dfu_crc, 4);
152
153#if 0
154 FILE *f = fopen(img->name, "w");
155 fwrite(img->data, len + 16, 1, f);
156 fclose(f);
157#endif
158
159 printf("OK\n");
160}
161
Frank Gevaerts3409e9d2008-08-31 21:36:04 +0000162usb_dev_handle *usb_dev_open(uint16_t dfu_vid, uint16_t dfu_pid)
Frank Gevaertse645ced2008-08-29 18:53:52 +0000163{
164 struct usb_bus *bus;
165 struct usb_device *dev;
Frank Gevaerts3409e9d2008-08-31 21:36:04 +0000166 usb_dev_handle *device;
Frank Gevaertse645ced2008-08-29 18:53:52 +0000167
168 printf("USB initialization...");
Frank Gevaertse645ced2008-08-29 18:53:52 +0000169
170 usb_init();
171 usb_find_busses();
172 usb_find_devices();
173
174 for (bus = usb_get_busses(); bus != NULL; bus = bus->next)
175 for (dev = bus->devices; dev != NULL; dev = dev->next)
Frank Gevaerts3409e9d2008-08-31 21:36:04 +0000176 if (dev->descriptor.idVendor == dfu_vid
177 && dev->descriptor.idProduct == dfu_pid)
Frank Gevaertse645ced2008-08-29 18:53:52 +0000178 goto found;
179
180 printf("\nNo device found, exiting.\n");
181 exit(1);
182
183found:
184 printf(" Device found.\n");
185 device = usb_open(dev);
186 usb_claim_interface(device, 0);
Frank Gevaerts3409e9d2008-08-31 21:36:04 +0000187 return device;
Frank Gevaertse645ced2008-08-29 18:53:52 +0000188}
189
Frank Gevaerts3409e9d2008-08-31 21:36:04 +0000190void usb_mimic_windows(usb_dev_handle *device)
Frank Gevaertse645ced2008-08-29 18:53:52 +0000191{
192 char data[1024];
193
Frank Gevaerts3409e9d2008-08-31 21:36:04 +0000194 usb_control_msg(device, 0x80, 0x06, 0x0100, 0x0000, data, 0x0012, DFU_TIMEOUT);
195 usb_control_msg(device, 0x80, 0x06, 0x0200, 0x0000, data, 0x0009, DFU_TIMEOUT);
196 usb_control_msg(device, 0x80, 0x06, 0x0200, 0x0000, data, 0x001b, DFU_TIMEOUT);
197 usb_control_msg(device, 0x80, 0x06, 0x0100, 0x0000, data, 0x0040, DFU_TIMEOUT);
198 usb_control_msg(device, 0x80, 0x06, 0x0100, 0x0000, data, 0x0012, DFU_TIMEOUT);
199 usb_control_msg(device, 0x80, 0x06, 0x0200, 0x0000, data, 0x0009, DFU_TIMEOUT);
200 usb_control_msg(device, 0x80, 0x06, 0x0300, 0x0000, data, 0x00ff, DFU_TIMEOUT);
201 usb_control_msg(device, 0x80, 0x06, 0x0303, 0x0409, data, 0x00ff, DFU_TIMEOUT);
202 usb_control_msg(device, 0x80, 0x06, 0x0200, 0x0000, data, 0x00ff, DFU_TIMEOUT);
203 usb_control_msg(device, 0x80, 0x06, 0x0300, 0x0000, data, 0x00ff, DFU_TIMEOUT);
204 usb_control_msg(device, 0x80, 0x06, 0x0302, 0x0409, data, 0x00ff, DFU_TIMEOUT);
205 usb_control_msg(device, 0x80, 0x06, 0x0300, 0x0000, data, 0x00ff, DFU_TIMEOUT);
206 usb_control_msg(device, 0x80, 0x06, 0x0302, 0x0409, data, 0x00ff, DFU_TIMEOUT);
207 usb_control_msg(device, 0x80, 0x06, 0x0100, 0x0000, data, 0x0012, DFU_TIMEOUT);
208 usb_control_msg(device, 0x80, 0x06, 0x0200, 0x0000, data, 0x0209, DFU_TIMEOUT);
Frank Gevaertse645ced2008-08-29 18:53:52 +0000209}
210
Frank Gevaerts3409e9d2008-08-31 21:36:04 +0000211void usb_dev_close(usb_dev_handle *device)
Frank Gevaertse645ced2008-08-29 18:53:52 +0000212{
213 printf("Releasing interface...");
Frank Gevaertse645ced2008-08-29 18:53:52 +0000214
215 usb_release_interface(device, 0);
216
217 printf(" OK\n");
218}
219
Frank Gevaerts3409e9d2008-08-31 21:36:04 +0000220enum DFU_REQUEST {
221 DFU_DETACH = 0,
222 DFU_DOWNLOAD,
223 DFU_UPLOAD,
224 DFU_GETSTATUS,
225 DFU_CLRSTATUS,
226 DFU_GETSTATE,
227 DFU_ABORT
228};
Frank Gevaertse645ced2008-08-29 18:53:52 +0000229
Frank Gevaerts3409e9d2008-08-31 21:36:04 +0000230void get_cpu(usb_dev_handle *device)
Frank Gevaertse645ced2008-08-29 18:53:52 +0000231{
232 char data[64];
233 int req_out_if = USB_ENDPOINT_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
234 int len;
235
236 printf("GET CPU");
Frank Gevaertse645ced2008-08-29 18:53:52 +0000237
238 // check for "S5L8700 Rev.1"
Frank Gevaerts3409e9d2008-08-31 21:36:04 +0000239 len = usb_control_msg(device, req_out_if, 0xff, 0x0002, 0, data, 0x003f, DFU_TIMEOUT);
Frank Gevaertse645ced2008-08-29 18:53:52 +0000240 if (len < 0) {
241 printf("\nError trying to get CPU model, exiting.\n");
242 exit(1);
243 }
244
245 memset(data + len, 0, 64 - len);
246 printf(", got: %s\n", data);
247}
248
Frank Gevaerts3409e9d2008-08-31 21:36:04 +0000249void send_file(usb_dev_handle *device, image_data_t *img)
Frank Gevaertse645ced2008-08-29 18:53:52 +0000250{
251 char dfu_ret[6];
252 char *data;
253 int req_out_if = USB_ENDPOINT_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
254 int req_in_if = USB_ENDPOINT_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
255 int len, idx, writelen, i;
256
257 printf("Sending %s... ", img->name);
Frank Gevaertse645ced2008-08-29 18:53:52 +0000258
259 len = img->len;
260 data = img->data;
261
262 // loop for the file
263 for (i = 0, idx = 0; i < len; i += BLOCK_SIZE, ++idx) {
264 writelen = ((len - i) < BLOCK_SIZE) ? (len - i) : BLOCK_SIZE;
Frank Gevaerts3409e9d2008-08-31 21:36:04 +0000265 usb_control_msg(device, req_out_if, DFU_DOWNLOAD, idx, 0, data + i, writelen, DFU_TIMEOUT);
Frank Gevaertse645ced2008-08-29 18:53:52 +0000266 dfu_ret[4] = 0x00;
267 while (dfu_ret[4] != 0x05)
Frank Gevaerts3409e9d2008-08-31 21:36:04 +0000268 usb_control_msg(device, req_in_if, DFU_GETSTATUS, 0, 0, dfu_ret, 6, DFU_TIMEOUT);
Frank Gevaertse645ced2008-08-29 18:53:52 +0000269 printf("#");
Frank Gevaertse645ced2008-08-29 18:53:52 +0000270 }
271
Frank Gevaerts3409e9d2008-08-31 21:36:04 +0000272 usb_control_msg(device, req_out_if, DFU_DOWNLOAD, idx, 0, NULL, 0, DFU_TIMEOUT);
Frank Gevaertse645ced2008-08-29 18:53:52 +0000273 dfu_ret[4] = 0x00;
274 while (dfu_ret[4] != 0x07)
Frank Gevaerts3409e9d2008-08-31 21:36:04 +0000275 usb_control_msg(device, req_in_if, DFU_GETSTATUS, 0, 0, dfu_ret, 6, DFU_TIMEOUT);
Frank Gevaertse645ced2008-08-29 18:53:52 +0000276
277 printf(" OK\n");
Frank Gevaertse645ced2008-08-29 18:53:52 +0000278}
279
Frank Gevaerts3409e9d2008-08-31 21:36:04 +0000280void clear_status(usb_dev_handle *device)
Frank Gevaertse645ced2008-08-29 18:53:52 +0000281{
282 char dfu_ret[6];
283 int usb_in_if = USB_ENDPOINT_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
284 int usb_out_if = USB_ENDPOINT_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
285
286 printf("Clearing status...");
Frank Gevaertse645ced2008-08-29 18:53:52 +0000287
288 dfu_ret[4] = 0x00;
289 while (dfu_ret[4] != 0x08)
Frank Gevaerts3409e9d2008-08-31 21:36:04 +0000290 usb_control_msg(device, usb_in_if, DFU_GETSTATUS, 0, 0, dfu_ret, 6, DFU_TIMEOUT);
291 usb_control_msg(device, usb_out_if, DFU_CLRSTATUS, 0, 0, NULL, 0, DFU_TIMEOUT);
Frank Gevaertse645ced2008-08-29 18:53:52 +0000292
293 printf(" OK\n");
294}
295
Frank Gevaerts3409e9d2008-08-31 21:36:04 +0000296void dfu_detach(usb_dev_handle *device)
Frank Gevaertse645ced2008-08-29 18:53:52 +0000297{
298 char usb_ret[4];
299 int usb_in_oth = USB_ENDPOINT_IN | USB_TYPE_CLASS | USB_RECIP_OTHER;
300 int usb_out_oth = USB_ENDPOINT_OUT | USB_TYPE_CLASS | USB_RECIP_OTHER;
301
302 printf("Detaching...");
Frank Gevaertse645ced2008-08-29 18:53:52 +0000303
Frank Gevaerts3409e9d2008-08-31 21:36:04 +0000304 usb_control_msg(device, usb_in_oth, DFU_DETACH, 0x0000, 3, usb_ret, 4, DFU_TIMEOUT);
305 usb_control_msg(device, usb_out_oth, DFU_DOWNLOAD, 0x0010, 3, NULL, 0, DFU_TIMEOUT);
306 usb_control_msg(device, usb_in_oth, DFU_DETACH, 0x0000, 3, usb_ret, 4, DFU_TIMEOUT);
307 usb_control_msg(device, usb_in_oth, DFU_DETACH, 0x0000, 3, usb_ret, 4, DFU_TIMEOUT);
308 usb_control_msg(device, usb_in_oth, DFU_DETACH, 0x0000, 3, usb_ret, 4, DFU_TIMEOUT);
309 usb_control_msg(device, usb_in_oth, DFU_DETACH, 0x0000, 3, usb_ret, 4, DFU_TIMEOUT);
310 usb_control_msg(device, usb_in_oth, DFU_DETACH, 0x0000, 3, usb_ret, 4, DFU_TIMEOUT);
Frank Gevaertse645ced2008-08-29 18:53:52 +0000311
312 printf(" OK\n");
313}
314
315void dfu_m3_m6(char *file1, char *file2)
316{
317 image_data_t img1, img2;
318 image_attr_t attr1, attr2;
Frank Gevaerts3409e9d2008-08-31 21:36:04 +0000319 usb_dev_handle *device;
Frank Gevaertse645ced2008-08-29 18:53:52 +0000320
321 attr1.delay = 1000;
322 attr1.pre_off = 0x20;
323 attr1.pre_sig = 0x44465543;
324 attr1.suf_dev = 0x0100;
325 attr1.suf_prod = 0x0140;
326 attr1.suf_ven = 0x0419;
327 attr1.suf_dfu = 0x0100;
328 memcpy(attr1.suf_sig, "RON", 3);
329 attr1.suf_len = 0x10;
330
Frank Gevaertse645ced2008-08-29 18:53:52 +0000331 init_img(&img1, file1, &attr1);
Rafaël Carré811c3592010-06-08 23:04:17 +0000332
333 if (file2) {
334 attr2.delay = 1000;
335 attr2.pre_off = 0x20;
336 attr2.pre_sig = 0x44465543;
337 attr2.suf_dev = 0x0100;
338 attr2.suf_prod = 0x0140;
339 attr2.suf_ven = 0x0419;
340 attr2.suf_dfu = 0x0100;
341 memcpy(attr2.suf_sig, "UFD", 3);
342 attr2.suf_len = 0x10;
343
344 init_img(&img2, file2, &attr2);
345 }
Frank Gevaertse645ced2008-08-29 18:53:52 +0000346
Frank Gevaerts903156d2008-09-01 08:56:54 +0000347 device = usb_dev_open(USB_VID_SAMSUNG, USB_PID_M3_M6);
Frank Gevaertse645ced2008-08-29 18:53:52 +0000348// usb_mimic_windows();
Frank Gevaerts3409e9d2008-08-31 21:36:04 +0000349 get_cpu(device);
350 get_cpu(device);
351 send_file(device, &img1);
Frank Gevaertse645ced2008-08-29 18:53:52 +0000352
Rafaël Carré811c3592010-06-08 23:04:17 +0000353 if (file2) {
354 printf("Wait a sec (literally)...");
355 sleep(1);
356 printf(" OK\n");
Frank Gevaertse645ced2008-08-29 18:53:52 +0000357
Rafaël Carré811c3592010-06-08 23:04:17 +0000358 clear_status(device);
359 get_cpu(device);
360 send_file(device, &img2);
361 dfu_detach(device);
362 }
363
Frank Gevaerts3409e9d2008-08-31 21:36:04 +0000364 usb_dev_close(device);
Frank Gevaertse645ced2008-08-29 18:53:52 +0000365}
366
367void dfu_m6sl(char *file1, char *file2)
368{
369 image_data_t img1, img2;
370 image_attr_t attr1, attr2;
Frank Gevaerts3409e9d2008-08-31 21:36:04 +0000371 usb_dev_handle *device;
Frank Gevaertse645ced2008-08-29 18:53:52 +0000372
373 attr1.delay = 1000;
374 attr1.pre_off = 0x20;
375 attr1.pre_sig = 0x44465543;
376 attr1.suf_dev = 0x0100;
377 attr1.suf_prod = 0x0140;
378 attr1.suf_ven = 0x0419;
379 attr1.suf_dfu = 0x0100;
380 memcpy(attr1.suf_sig, "UFD", 3);
381 attr1.suf_len = 0x10;
382
Frank Gevaertse645ced2008-08-29 18:53:52 +0000383 init_img(&img1, file1, &attr1);
Rafaël Carré811c3592010-06-08 23:04:17 +0000384
385 if (file2) {
386 attr2.delay = 1000;
387 attr2.pre_off = 0x20;
388 attr2.pre_sig = 0x44465543;
389 attr2.suf_dev = 0x0100;
390 attr2.suf_prod = 0x0140;
391 attr2.suf_ven = 0x0419;
392 attr2.suf_dfu = 0x0100;
393 memcpy(attr2.suf_sig, "UFD", 3);
394 attr2.suf_len = 0x10;
395
396 init_img(&img2, file2, &attr2);
397 }
Frank Gevaertse645ced2008-08-29 18:53:52 +0000398
Frank Gevaerts3409e9d2008-08-31 21:36:04 +0000399 device = usb_dev_open(USB_VID_SAMSUNG, USB_PID_M6SL);
400 get_cpu(device);
401 get_cpu(device);
402 send_file(device, &img1);
Frank Gevaertse645ced2008-08-29 18:53:52 +0000403
Rafaël Carré811c3592010-06-08 23:04:17 +0000404 if (file2) {
405 printf("Wait a sec (literally)...");
406 sleep(1);
407 printf(" OK\n");
408 usb_dev_close(device);
Frank Gevaertse645ced2008-08-29 18:53:52 +0000409
Rafaël Carré811c3592010-06-08 23:04:17 +0000410 device = usb_dev_open(USB_VID_SAMSUNG, USB_PID_M6SL);
411 get_cpu(device);
412 get_cpu(device);
413 send_file(device, &img2);
414 dfu_detach(device);
415 }
416
Frank Gevaerts3409e9d2008-08-31 21:36:04 +0000417 usb_dev_close(device);
Frank Gevaertse645ced2008-08-29 18:53:52 +0000418}
419
420
421int main(int argc, char **argv)
422{
Rafaël Carré811c3592010-06-08 23:04:17 +0000423 if (argc < 3 || argc > 4)
Frank Gevaertse645ced2008-08-29 18:53:52 +0000424 usage();
425
Frank Gevaerts903156d2008-09-01 08:56:54 +0000426 setvbuf(stdout, NULL, _IONBF, 0);
427
Rafaël Carré811c3592010-06-08 23:04:17 +0000428 char *second_file = (argc == 4) ? argv[3] : NULL;
429
Frank Gevaertse645ced2008-08-29 18:53:52 +0000430 if (!strcmp(argv[1], "m3"))
Rafaël Carré811c3592010-06-08 23:04:17 +0000431 dfu_m3_m6(argv[2], second_file);
Frank Gevaertse645ced2008-08-29 18:53:52 +0000432 else if (!strcmp(argv[1], "m6"))
Rafaël Carré811c3592010-06-08 23:04:17 +0000433 dfu_m3_m6(argv[2], second_file);
Frank Gevaertse645ced2008-08-29 18:53:52 +0000434 else if (!strcmp(argv[1], "m6sl"))
Rafaël Carré811c3592010-06-08 23:04:17 +0000435 dfu_m6sl(argv[2], second_file);
Frank Gevaertse645ced2008-08-29 18:53:52 +0000436 else
437 usage();
438
439 return 0;
440}
441