diff options
Diffstat (limited to 'utils/meizu_dfu')
-rw-r--r-- | utils/meizu_dfu/meizu_dfu.c | 155 |
1 files changed, 79 insertions, 76 deletions
diff --git a/utils/meizu_dfu/meizu_dfu.c b/utils/meizu_dfu/meizu_dfu.c index d5e9ffb0b8..86c53c2d12 100644 --- a/utils/meizu_dfu/meizu_dfu.c +++ b/utils/meizu_dfu/meizu_dfu.c | |||
@@ -49,8 +49,6 @@ uint32_t crc32(char *data, int len, uint32_t poly, uint32_t init) | |||
49 | return crc; | 49 | return crc; |
50 | } | 50 | } |
51 | 51 | ||
52 | #define BLOCK_SIZE 2048 | ||
53 | |||
54 | typedef struct { | 52 | typedef struct { |
55 | char *name; | 53 | char *name; |
56 | char *data; | 54 | char *data; |
@@ -69,9 +67,15 @@ typedef struct { | |||
69 | uint8_t suf_len; | 67 | uint8_t suf_len; |
70 | } image_attr_t; | 68 | } image_attr_t; |
71 | 69 | ||
70 | #define BLOCK_SIZE 2048 | ||
71 | #define DFU_TIMEOUT 0xa000 | ||
72 | #define DFU_CRC_POLY 0xedb88320 | 72 | #define DFU_CRC_POLY 0xedb88320 |
73 | #define DFU_INIT_CRC 0xffffffff | 73 | #define DFU_INIT_CRC 0xffffffff |
74 | 74 | ||
75 | #define USB_VID_SAMSUNG 0x0419 | ||
76 | #define USB_PID_M6SL 0x0145 | ||
77 | #define USB_PID_M6 0x0141 | ||
78 | |||
75 | void init_img(image_data_t *img, const char *filename, image_attr_t *attr) | 79 | void init_img(image_data_t *img, const char *filename, image_attr_t *attr) |
76 | { | 80 | { |
77 | int fd, len, i, readlen; | 81 | int fd, len, i, readlen; |
@@ -119,16 +123,11 @@ void init_img(image_data_t *img, const char *filename, image_attr_t *attr) | |||
119 | printf("OK\n"); | 123 | printf("OK\n"); |
120 | } | 124 | } |
121 | 125 | ||
122 | #define DFU_VEN 0x0419 | 126 | usb_dev_handle *usb_dev_open(uint16_t dfu_vid, uint16_t dfu_pid) |
123 | #define DFU_DEV 0x0141 | ||
124 | #define DFU_DEV_M6SL 0x0145 | ||
125 | usb_dev_handle *device; | ||
126 | int timeout = 0xa0000; | ||
127 | |||
128 | void usb_dev_open() | ||
129 | { | 127 | { |
130 | struct usb_bus *bus; | 128 | struct usb_bus *bus; |
131 | struct usb_device *dev; | 129 | struct usb_device *dev; |
130 | usb_dev_handle *device; | ||
132 | 131 | ||
133 | printf("USB initialization..."); | 132 | printf("USB initialization..."); |
134 | fflush(stdout); | 133 | fflush(stdout); |
@@ -139,9 +138,8 @@ void usb_dev_open() | |||
139 | 138 | ||
140 | for (bus = usb_get_busses(); bus != NULL; bus = bus->next) | 139 | for (bus = usb_get_busses(); bus != NULL; bus = bus->next) |
141 | for (dev = bus->devices; dev != NULL; dev = dev->next) | 140 | for (dev = bus->devices; dev != NULL; dev = dev->next) |
142 | if (dev->descriptor.idVendor == DFU_VEN | 141 | if (dev->descriptor.idVendor == dfu_vid |
143 | && ( dev->descriptor.idProduct == DFU_DEV | 142 | && dev->descriptor.idProduct == dfu_pid) |
144 | || dev->descriptor.idProduct == DFU_DEV_M6SL)) | ||
145 | goto found; | 143 | goto found; |
146 | 144 | ||
147 | printf("\nNo device found, exiting.\n"); | 145 | printf("\nNo device found, exiting.\n"); |
@@ -151,30 +149,31 @@ found: | |||
151 | printf(" Device found.\n"); | 149 | printf(" Device found.\n"); |
152 | device = usb_open(dev); | 150 | device = usb_open(dev); |
153 | usb_claim_interface(device, 0); | 151 | usb_claim_interface(device, 0); |
152 | return device; | ||
154 | } | 153 | } |
155 | 154 | ||
156 | void usb_mimic_windows() | 155 | void usb_mimic_windows(usb_dev_handle *device) |
157 | { | 156 | { |
158 | char data[1024]; | 157 | char data[1024]; |
159 | 158 | ||
160 | usb_control_msg(device, 0x80, 0x06, 0x0100, 0x0000, data, 0x0012, timeout); | 159 | usb_control_msg(device, 0x80, 0x06, 0x0100, 0x0000, data, 0x0012, DFU_TIMEOUT); |
161 | usb_control_msg(device, 0x80, 0x06, 0x0200, 0x0000, data, 0x0009, timeout); | 160 | usb_control_msg(device, 0x80, 0x06, 0x0200, 0x0000, data, 0x0009, DFU_TIMEOUT); |
162 | usb_control_msg(device, 0x80, 0x06, 0x0200, 0x0000, data, 0x001b, timeout); | 161 | usb_control_msg(device, 0x80, 0x06, 0x0200, 0x0000, data, 0x001b, DFU_TIMEOUT); |
163 | usb_control_msg(device, 0x80, 0x06, 0x0100, 0x0000, data, 0x0040, timeout); | 162 | usb_control_msg(device, 0x80, 0x06, 0x0100, 0x0000, data, 0x0040, DFU_TIMEOUT); |
164 | usb_control_msg(device, 0x80, 0x06, 0x0100, 0x0000, data, 0x0012, timeout); | 163 | usb_control_msg(device, 0x80, 0x06, 0x0100, 0x0000, data, 0x0012, DFU_TIMEOUT); |
165 | usb_control_msg(device, 0x80, 0x06, 0x0200, 0x0000, data, 0x0009, timeout); | 164 | usb_control_msg(device, 0x80, 0x06, 0x0200, 0x0000, data, 0x0009, DFU_TIMEOUT); |
166 | usb_control_msg(device, 0x80, 0x06, 0x0300, 0x0000, data, 0x00ff, timeout); | 165 | usb_control_msg(device, 0x80, 0x06, 0x0300, 0x0000, data, 0x00ff, DFU_TIMEOUT); |
167 | usb_control_msg(device, 0x80, 0x06, 0x0303, 0x0409, data, 0x00ff, timeout); | 166 | usb_control_msg(device, 0x80, 0x06, 0x0303, 0x0409, data, 0x00ff, DFU_TIMEOUT); |
168 | usb_control_msg(device, 0x80, 0x06, 0x0200, 0x0000, data, 0x00ff, timeout); | 167 | usb_control_msg(device, 0x80, 0x06, 0x0200, 0x0000, data, 0x00ff, DFU_TIMEOUT); |
169 | usb_control_msg(device, 0x80, 0x06, 0x0300, 0x0000, data, 0x00ff, timeout); | 168 | usb_control_msg(device, 0x80, 0x06, 0x0300, 0x0000, data, 0x00ff, DFU_TIMEOUT); |
170 | usb_control_msg(device, 0x80, 0x06, 0x0302, 0x0409, data, 0x00ff, timeout); | 169 | usb_control_msg(device, 0x80, 0x06, 0x0302, 0x0409, data, 0x00ff, DFU_TIMEOUT); |
171 | usb_control_msg(device, 0x80, 0x06, 0x0300, 0x0000, data, 0x00ff, timeout); | 170 | usb_control_msg(device, 0x80, 0x06, 0x0300, 0x0000, data, 0x00ff, DFU_TIMEOUT); |
172 | usb_control_msg(device, 0x80, 0x06, 0x0302, 0x0409, data, 0x00ff, timeout); | 171 | usb_control_msg(device, 0x80, 0x06, 0x0302, 0x0409, data, 0x00ff, DFU_TIMEOUT); |
173 | usb_control_msg(device, 0x80, 0x06, 0x0100, 0x0000, data, 0x0012, timeout); | 172 | usb_control_msg(device, 0x80, 0x06, 0x0100, 0x0000, data, 0x0012, DFU_TIMEOUT); |
174 | usb_control_msg(device, 0x80, 0x06, 0x0200, 0x0000, data, 0x0209, timeout); | 173 | usb_control_msg(device, 0x80, 0x06, 0x0200, 0x0000, data, 0x0209, DFU_TIMEOUT); |
175 | } | 174 | } |
176 | 175 | ||
177 | void usb_dev_close() | 176 | void usb_dev_close(usb_dev_handle *device) |
178 | { | 177 | { |
179 | printf("Releasing interface..."); | 178 | printf("Releasing interface..."); |
180 | fflush(stdout); | 179 | fflush(stdout); |
@@ -184,15 +183,17 @@ void usb_dev_close() | |||
184 | printf(" OK\n"); | 183 | printf(" OK\n"); |
185 | } | 184 | } |
186 | 185 | ||
187 | #define DFU_DETACH 0 | 186 | enum DFU_REQUEST { |
188 | #define DFU_DOWNLOAD 1 | 187 | DFU_DETACH = 0, |
189 | #define DFU_UPLOAD 2 | 188 | DFU_DOWNLOAD, |
190 | #define DFU_GETSTATUS 3 | 189 | DFU_UPLOAD, |
191 | #define DFU_CLRSTATUS 4 | 190 | DFU_GETSTATUS, |
192 | #define DFU_GETSTATE 5 | 191 | DFU_CLRSTATUS, |
193 | #define DFU_ABORT 6 | 192 | DFU_GETSTATE, |
194 | 193 | DFU_ABORT | |
195 | void get_cpu() | 194 | }; |
195 | |||
196 | void get_cpu(usb_dev_handle *device) | ||
196 | { | 197 | { |
197 | char data[64]; | 198 | char data[64]; |
198 | int req_out_if = USB_ENDPOINT_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE; | 199 | int req_out_if = USB_ENDPOINT_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE; |
@@ -202,7 +203,7 @@ void get_cpu() | |||
202 | fflush(stdout); | 203 | fflush(stdout); |
203 | 204 | ||
204 | // check for "S5L8700 Rev.1" | 205 | // check for "S5L8700 Rev.1" |
205 | len = usb_control_msg(device, req_out_if, 0xff, 0x0002, 0, data, 0x003f, timeout); | 206 | len = usb_control_msg(device, req_out_if, 0xff, 0x0002, 0, data, 0x003f, DFU_TIMEOUT); |
206 | if (len < 0) { | 207 | if (len < 0) { |
207 | printf("\nError trying to get CPU model, exiting.\n"); | 208 | printf("\nError trying to get CPU model, exiting.\n"); |
208 | exit(1); | 209 | exit(1); |
@@ -212,7 +213,7 @@ void get_cpu() | |||
212 | printf(", got: %s\n", data); | 213 | printf(", got: %s\n", data); |
213 | } | 214 | } |
214 | 215 | ||
215 | void send_file(image_data_t *img) | 216 | void send_file(usb_dev_handle *device, image_data_t *img) |
216 | { | 217 | { |
217 | char dfu_ret[6]; | 218 | char dfu_ret[6]; |
218 | char *data; | 219 | char *data; |
@@ -229,24 +230,24 @@ void send_file(image_data_t *img) | |||
229 | // loop for the file | 230 | // loop for the file |
230 | for (i = 0, idx = 0; i < len; i += BLOCK_SIZE, ++idx) { | 231 | for (i = 0, idx = 0; i < len; i += BLOCK_SIZE, ++idx) { |
231 | writelen = ((len - i) < BLOCK_SIZE) ? (len - i) : BLOCK_SIZE; | 232 | writelen = ((len - i) < BLOCK_SIZE) ? (len - i) : BLOCK_SIZE; |
232 | usb_control_msg(device, req_out_if, DFU_DOWNLOAD, idx, 0, data + i, writelen, timeout); | 233 | usb_control_msg(device, req_out_if, DFU_DOWNLOAD, idx, 0, data + i, writelen, DFU_TIMEOUT); |
233 | dfu_ret[4] = 0x00; | 234 | dfu_ret[4] = 0x00; |
234 | while (dfu_ret[4] != 0x05) | 235 | while (dfu_ret[4] != 0x05) |
235 | usb_control_msg(device, req_in_if, DFU_GETSTATUS, 0, 0, dfu_ret, 6, timeout); | 236 | usb_control_msg(device, req_in_if, DFU_GETSTATUS, 0, 0, dfu_ret, 6, DFU_TIMEOUT); |
236 | printf("#"); | 237 | printf("#"); |
237 | fflush(stdout); | 238 | fflush(stdout); |
238 | } | 239 | } |
239 | 240 | ||
240 | usb_control_msg(device, req_out_if, DFU_DOWNLOAD, idx, 0, NULL, 0, timeout); | 241 | usb_control_msg(device, req_out_if, DFU_DOWNLOAD, idx, 0, NULL, 0, DFU_TIMEOUT); |
241 | dfu_ret[4] = 0x00; | 242 | dfu_ret[4] = 0x00; |
242 | while (dfu_ret[4] != 0x07) | 243 | while (dfu_ret[4] != 0x07) |
243 | usb_control_msg(device, req_in_if, DFU_GETSTATUS, 0, 0, dfu_ret, 6, timeout); | 244 | usb_control_msg(device, req_in_if, DFU_GETSTATUS, 0, 0, dfu_ret, 6, DFU_TIMEOUT); |
244 | 245 | ||
245 | printf(" OK\n"); | 246 | printf(" OK\n"); |
246 | fflush(stdout); | 247 | fflush(stdout); |
247 | } | 248 | } |
248 | 249 | ||
249 | void clear_status() | 250 | void clear_status(usb_dev_handle *device) |
250 | { | 251 | { |
251 | char dfu_ret[6]; | 252 | char dfu_ret[6]; |
252 | int usb_in_if = USB_ENDPOINT_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE; | 253 | int usb_in_if = USB_ENDPOINT_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE; |
@@ -257,13 +258,13 @@ void clear_status() | |||
257 | 258 | ||
258 | dfu_ret[4] = 0x00; | 259 | dfu_ret[4] = 0x00; |
259 | while (dfu_ret[4] != 0x08) | 260 | while (dfu_ret[4] != 0x08) |
260 | usb_control_msg(device, usb_in_if, DFU_GETSTATUS, 0, 0, dfu_ret, 6, timeout); | 261 | usb_control_msg(device, usb_in_if, DFU_GETSTATUS, 0, 0, dfu_ret, 6, DFU_TIMEOUT); |
261 | usb_control_msg(device, usb_out_if, DFU_CLRSTATUS, 0, 0, NULL, 0, timeout); | 262 | usb_control_msg(device, usb_out_if, DFU_CLRSTATUS, 0, 0, NULL, 0, DFU_TIMEOUT); |
262 | 263 | ||
263 | printf(" OK\n"); | 264 | printf(" OK\n"); |
264 | } | 265 | } |
265 | 266 | ||
266 | void dfu_detach() | 267 | void dfu_detach(usb_dev_handle *device) |
267 | { | 268 | { |
268 | char usb_ret[4]; | 269 | char usb_ret[4]; |
269 | int usb_in_oth = USB_ENDPOINT_IN | USB_TYPE_CLASS | USB_RECIP_OTHER; | 270 | int usb_in_oth = USB_ENDPOINT_IN | USB_TYPE_CLASS | USB_RECIP_OTHER; |
@@ -272,13 +273,13 @@ void dfu_detach() | |||
272 | printf("Detaching..."); | 273 | printf("Detaching..."); |
273 | fflush(stdout); | 274 | fflush(stdout); |
274 | 275 | ||
275 | usb_control_msg(device, usb_in_oth, DFU_DETACH, 0x0000, 3, usb_ret, 4, timeout); | 276 | usb_control_msg(device, usb_in_oth, DFU_DETACH, 0x0000, 3, usb_ret, 4, DFU_TIMEOUT); |
276 | usb_control_msg(device, usb_out_oth, DFU_DOWNLOAD, 0x0010, 3, NULL, 0, timeout); | 277 | usb_control_msg(device, usb_out_oth, DFU_DOWNLOAD, 0x0010, 3, NULL, 0, DFU_TIMEOUT); |
277 | usb_control_msg(device, usb_in_oth, DFU_DETACH, 0x0000, 3, usb_ret, 4, timeout); | 278 | usb_control_msg(device, usb_in_oth, DFU_DETACH, 0x0000, 3, usb_ret, 4, DFU_TIMEOUT); |
278 | usb_control_msg(device, usb_in_oth, DFU_DETACH, 0x0000, 3, usb_ret, 4, timeout); | 279 | usb_control_msg(device, usb_in_oth, DFU_DETACH, 0x0000, 3, usb_ret, 4, DFU_TIMEOUT); |
279 | usb_control_msg(device, usb_in_oth, DFU_DETACH, 0x0000, 3, usb_ret, 4, timeout); | 280 | usb_control_msg(device, usb_in_oth, DFU_DETACH, 0x0000, 3, usb_ret, 4, DFU_TIMEOUT); |
280 | usb_control_msg(device, usb_in_oth, DFU_DETACH, 0x0000, 3, usb_ret, 4, timeout); | 281 | usb_control_msg(device, usb_in_oth, DFU_DETACH, 0x0000, 3, usb_ret, 4, DFU_TIMEOUT); |
281 | usb_control_msg(device, usb_in_oth, DFU_DETACH, 0x0000, 3, usb_ret, 4, timeout); | 282 | usb_control_msg(device, usb_in_oth, DFU_DETACH, 0x0000, 3, usb_ret, 4, DFU_TIMEOUT); |
282 | 283 | ||
283 | printf(" OK\n"); | 284 | printf(" OK\n"); |
284 | } | 285 | } |
@@ -287,6 +288,7 @@ void dfu_m3_m6(char *file1, char *file2) | |||
287 | { | 288 | { |
288 | image_data_t img1, img2; | 289 | image_data_t img1, img2; |
289 | image_attr_t attr1, attr2; | 290 | image_attr_t attr1, attr2; |
291 | usb_dev_handle *device; | ||
290 | 292 | ||
291 | attr1.delay = 1000; | 293 | attr1.delay = 1000; |
292 | attr1.pre_off = 0x20; | 294 | attr1.pre_off = 0x20; |
@@ -311,28 +313,29 @@ void dfu_m3_m6(char *file1, char *file2) | |||
311 | init_img(&img1, file1, &attr1); | 313 | init_img(&img1, file1, &attr1); |
312 | init_img(&img2, file2, &attr2); | 314 | init_img(&img2, file2, &attr2); |
313 | 315 | ||
314 | usb_dev_open(); | 316 | device = usb_dev_open(USB_VID_SAMSUNG, USB_PID_M6); |
315 | // usb_mimic_windows(); | 317 | // usb_mimic_windows(); |
316 | get_cpu(); | 318 | get_cpu(device); |
317 | get_cpu(); | 319 | get_cpu(device); |
318 | send_file(&img1); | 320 | send_file(device, &img1); |
319 | 321 | ||
320 | printf("Wait a sec (literally)..."); | 322 | printf("Wait a sec (literally)..."); |
321 | fflush(stdout); | 323 | fflush(stdout); |
322 | sleep(1); | 324 | sleep(1); |
323 | printf(" OK\n"); | 325 | printf(" OK\n"); |
324 | 326 | ||
325 | clear_status(); | 327 | clear_status(device); |
326 | get_cpu(); | 328 | get_cpu(device); |
327 | send_file(&img2); | 329 | send_file(device, &img2); |
328 | dfu_detach(); | 330 | dfu_detach(device); |
329 | usb_dev_close(); | 331 | usb_dev_close(device); |
330 | } | 332 | } |
331 | 333 | ||
332 | void dfu_m6sl(char *file1, char *file2) | 334 | void dfu_m6sl(char *file1, char *file2) |
333 | { | 335 | { |
334 | image_data_t img1, img2; | 336 | image_data_t img1, img2; |
335 | image_attr_t attr1, attr2; | 337 | image_attr_t attr1, attr2; |
338 | usb_dev_handle *device; | ||
336 | 339 | ||
337 | attr1.delay = 1000; | 340 | attr1.delay = 1000; |
338 | attr1.pre_off = 0x20; | 341 | attr1.pre_off = 0x20; |
@@ -357,23 +360,23 @@ void dfu_m6sl(char *file1, char *file2) | |||
357 | init_img(&img1, file1, &attr1); | 360 | init_img(&img1, file1, &attr1); |
358 | init_img(&img2, file2, &attr2); | 361 | init_img(&img2, file2, &attr2); |
359 | 362 | ||
360 | usb_dev_open(); | 363 | device = usb_dev_open(USB_VID_SAMSUNG, USB_PID_M6SL); |
361 | get_cpu(); | 364 | get_cpu(device); |
362 | get_cpu(); | 365 | get_cpu(device); |
363 | send_file(&img1); | 366 | send_file(device, &img1); |
364 | 367 | ||
365 | printf("Wait a sec (literally)..."); | 368 | printf("Wait a sec (literally)..."); |
366 | fflush(stdout); | 369 | fflush(stdout); |
367 | sleep(1); | 370 | sleep(1); |
368 | printf(" OK\n"); | 371 | printf(" OK\n"); |
369 | usb_dev_close(); | 372 | usb_dev_close(device); |
370 | 373 | ||
371 | usb_dev_open(); | 374 | device = usb_dev_open(USB_VID_SAMSUNG, USB_PID_M6SL); |
372 | get_cpu(); | 375 | get_cpu(device); |
373 | get_cpu(); | 376 | get_cpu(device); |
374 | send_file(&img2); | 377 | send_file(device, &img2); |
375 | dfu_detach(); | 378 | dfu_detach(device); |
376 | usb_dev_close(); | 379 | usb_dev_close(device); |
377 | } | 380 | } |
378 | 381 | ||
379 | 382 | ||