Add w32 mountpoint resolving based on disc number correctly this time.
[Rockbox.git] / utils / jz4740_tools / jz4740_usbtool.c
blob6d670254e4938a8a1ca2a44a6a2883b0e20124df
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2008 by Maurus Cuelenaere
12 * based on tcctool.c by Dave Chapman
14 * USB code based on ifp-line - http://ifp-driver.sourceforge.net
16 * ifp-line is (C) Pavel Kriz, Jun Yamishiro and Joe Roback and
17 * licensed under the GPL (v2)
20 * This program is free software; you can redistribute it and/or
21 * modify it under the terms of the GNU General Public License
22 * as published by the Free Software Foundation; either version 2
23 * of the License, or (at your option) any later version.
25 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
26 * KIND, either express or implied.
28 ****************************************************************************/
30 #include <stdio.h>
31 #include <inttypes.h>
32 #include <usb.h>
33 #include <string.h>
34 #include <sys/types.h>
35 #include <sys/stat.h>
36 #include <unistd.h>
37 #include <fcntl.h>
38 #include "jz4740.h"
39 #include <stdbool.h>
40 #include <unistd.h>
42 #define VERSION "0.3"
44 #define MAX_FIRMWARESIZE (64*1024*1024) /* Arbitrary limit (for safety) */
46 /* For win32 compatibility: */
47 #ifndef O_BINARY
48 #define O_BINARY 0
49 #endif
51 /* USB IDs for USB Boot Mode */
52 #define VID 0x601A
53 #define PID 0x4740
55 #define EP_BULK_TO 0x01
56 #define TOUT 5000
58 enum USB_JZ4740_REQUEST
60 VR_GET_CPU_INFO = 0,
61 VR_SET_DATA_ADDRESS,
62 VR_SET_DATA_LENGTH,
63 VR_FLUSH_CACHES,
64 VR_PROGRAM_START1,
65 VR_PROGRAM_START2,
66 VR_NOR_OPS,
67 VR_NAND_OPS,
68 VR_SDRAM_OPS,
69 VR_CONFIGURATION
72 enum NOR_OPS_TYPE
74 NOR_INIT = 0,
75 NOR_QUERY,
76 NOR_WRITE,
77 NOR_ERASE_CHIP,
78 NOR_ERASE_SECTOR
81 enum NOR_FLASH_TYPE
83 NOR_AM29 = 0,
84 NOR_SST28,
85 NOR_SST39x16,
86 NOR_SST39x8
89 enum NAND_OPS_TYPE
91 NAND_QUERY = 0,
92 NAND_INIT,
93 NAND_MARK_BAD,
94 NAND_READ_OOB,
95 NAND_READ_RAW,
96 NAND_ERASE,
97 NAND_READ,
98 NAND_PROGRAM,
99 NAND_READ_TO_RAM
102 enum SDRAM_OPS_TYPE
104 SDRAM_LOAD,
108 enum DATA_STRUCTURE_OB
110 DS_flash_info ,
111 DS_hand
114 enum OPTION
116 OOB_ECC,
117 OOB_NO_ECC,
118 NO_OOB,
121 int filesize(FILE* fd)
123 int tmp;
124 fseek(fd, 0, SEEK_END);
125 tmp = ftell(fd);
126 fseek(fd, 0, SEEK_SET);
127 return tmp;
130 #define SEND_COMMAND(cmd, arg) err = usb_control_msg(dh, USB_ENDPOINT_OUT | USB_TYPE_VENDOR, cmd, arg>>16, arg&0xFFFF, NULL, 0, TOUT);\
131 if (err < 0) \
133 fprintf(stderr,"\n[ERR] Error sending control message (%d, %s)\n", err, usb_strerror()); \
134 return -1; \
137 #define GET_CPU_INFO(s) err = usb_control_msg(dh, USB_ENDPOINT_IN | USB_TYPE_VENDOR, VR_GET_CPU_INFO, 0, 0, s, 8, TOUT); \
138 if (err < 0) \
140 fprintf(stderr,"\n[ERR] Error sending control message (%d, %s)\n", err, usb_strerror()); \
141 return -1; \
144 #define SEND_DATA(ptr, size) err = usb_bulk_write(dh, USB_ENDPOINT_OUT | EP_BULK_TO, ptr, size, TOUT); \
145 if (err != size) \
147 fprintf(stderr,"\n[ERR] Error writing data\n"); \
148 fprintf(stderr,"[ERR] Bulk write error (%d, %s)\n", err, strerror(-err)); \
149 return -1; \
152 #define GET_DATA(ptr, size) err = usb_bulk_read(dh, USB_ENDPOINT_IN | EP_BULK_TO, ptr, size, TOUT); \
153 if (err != size) \
155 fprintf(stderr,"\n[ERR] Error writing data\n"); \
156 fprintf(stderr,"[ERR] Bulk write error (%d, %s)\n", err, strerror(-err)); \
157 return -1; \
160 int upload_app(usb_dev_handle* dh, int address, unsigned char* p, int len, bool stage2)
162 int err;
163 char buf[8];
164 unsigned char* tmp_buf;
166 fprintf(stderr, "[INFO] GET_CPU_INFO: ");
167 GET_CPU_INFO(buf);
168 buf[8] = 0;
169 fprintf(stderr, "%s\n", buf);
170 #if 0
171 fprintf(stderr, "[INFO] Flushing cache...");
172 SEND_COMMAND(VR_FLUSH_CACHES, 0);
173 fprintf(stderr, " Done!\n");
174 #endif
176 fprintf(stderr, "[INFO] SET_DATA_ADDRESS to 0x%x...", address);
177 SEND_COMMAND(VR_SET_DATA_ADDRESS, address);
178 fprintf(stderr, " Done!\n");
180 fprintf(stderr, "[INFO] Sending data...");
181 /* Must not split the file in several packages! */
182 SEND_DATA(p, len);
183 fprintf(stderr, " Done!\n");
185 fprintf(stderr, "[INFO] Verifying data...");
186 SEND_COMMAND(VR_SET_DATA_ADDRESS, address);
187 SEND_COMMAND(VR_SET_DATA_LENGTH, len);
188 tmp_buf = malloc(len);
189 if (tmp_buf == NULL)
191 fprintf(stderr, "\n[ERR] Could not allocate memory.\n");
192 return -1;
194 GET_DATA(tmp_buf, len);
195 if (memcmp(tmp_buf, p, len) != 0)
196 fprintf(stderr, "\n[WARN] Sent data isn't the same as received data...\n");
197 else
198 fprintf(stderr, " Done!\n");
199 free(tmp_buf);
201 fprintf(stderr, "[INFO] Booting device [STAGE%d]...", (stage2 ? 2 : 1));
202 SEND_COMMAND((stage2 ? VR_PROGRAM_START2 : VR_PROGRAM_START1), (address+(stage2 ? 8 : 0)) );
203 fprintf(stderr, " Done!\n");
205 return 0;
208 int read_data(usb_dev_handle* dh, int address, unsigned char *p, int len)
210 int err;
211 char buf[8];
213 fprintf(stderr, "[INFO] GET_CPU_INFO: ");
214 GET_CPU_INFO(buf);
215 buf[8] = 0;
216 fprintf(stderr, "%s\n", buf);
218 fprintf(stderr, "[INFO] Reading data...");
219 SEND_COMMAND(VR_SET_DATA_ADDRESS, address);
220 SEND_COMMAND(VR_SET_DATA_LENGTH, len);
221 GET_DATA(p, len);
222 fprintf(stderr, " Done!\n");
223 return 0;
226 unsigned int read_reg(usb_dev_handle* dh, int address, int size)
228 int err;
229 unsigned char buf[4];
231 SEND_COMMAND(VR_SET_DATA_ADDRESS, address);
232 SEND_COMMAND(VR_SET_DATA_LENGTH, size);
233 GET_DATA(buf, size);
235 if(size == 1)
236 return buf[0];
237 else if(size == 2)
238 return (buf[1] << 8) | buf[0];
239 else if(size == 4)
240 return (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
241 else
242 return 0;
245 int set_reg(usb_dev_handle* dh, int address, unsigned int val, int size)
247 int err, i;
248 unsigned char buf[4];
250 buf[0] = val & 0xff;
251 if(i > 1)
253 buf[1] = (val >> 8) & 0xff;
254 if(i > 2)
256 buf[2] = (val >> 16) & 0xff;
257 buf[3] = (val >> 24) & 0xff;
261 SEND_COMMAND(VR_SET_DATA_ADDRESS, address);
262 SEND_DATA(buf, size);
264 return 0;
266 #define or_reg(dh, adr, val, size) set_reg(dh, adr, (read_reg(dh, adr, size) | (val)), size);
267 #define and_reg(dh, adr, val, size) set_reg(dh, adr, (read_reg(dh, adr, size) & (val)), size);
268 #define bc_reg(dh, adr, val, size) set_reg(dh, adr, (read_reg(dh, adr, size) & ~(val)), size);
269 #define xor_reg(dh, adr, val, size) set_reg(dh, adr, (read_reg(dh, adr, size) ^ (val)), size);
271 #define TEST(m, size) fprintf(stderr, "%s -> %x\n", #m, read_reg(dh, m, size));
272 int test_device(usb_dev_handle* dh)
274 TEST(INTC_ISR, 4);
275 TEST(INTC_IMR, 4);
276 TEST(INTC_IMSR, 4);
277 TEST(INTC_IMCR, 4);
278 TEST(INTC_IPR, 4);
280 fprintf(stderr, "\n");
281 TEST(RTC_RCR, 4);
282 TEST(RTC_RSR, 4);
283 TEST(RTC_RSAR, 4);
284 TEST(RTC_RGR, 4);
285 TEST(RTC_HCR, 4);
286 TEST(RTC_RCR, 4);
287 TEST(RTC_HWFCR, 4);
288 TEST(RTC_HRCR, 4);
289 TEST(RTC_HWCR, 4);
290 TEST(RTC_HWSR, 4);
292 fprintf(stderr, "\n");
293 TEST(GPIO_PXPIN(0), 4);
294 TEST(GPIO_PXPIN(1), 4);
295 TEST(GPIO_PXPIN(2), 4);
296 TEST(GPIO_PXPIN(3), 4);
298 fprintf(stderr, "\n");
299 TEST(CPM_CLKGR, 4);
301 fprintf(stderr, "\n");
302 //or_reg(dh, SADC_ENA, SADC_ENA_TSEN, 1);
303 TEST(SADC_ENA, 1);
304 TEST(SADC_CTRL, 1);
305 TEST(SADC_TSDAT, 4);
306 TEST(SADC_BATDAT, 2);
307 TEST(SADC_STATE, 1);
309 fprintf(stderr, "\n");
311 TEST(SLCD_CFG, 4);
312 TEST(SLCD_CTRL, 1);
313 TEST(SLCD_STATE, 1);
315 return 0;
318 #define VOL_DOWN (1 << 27)
319 #define VOL_UP (1 << 0)
320 #define MENU (1 << 1)
321 #define HOLD (1 << 16)
322 #define OFF (1 << 29)
323 #define MASK (VOL_DOWN|VOL_UP|MENU|HOLD|OFF)
324 #define TS_MASK (SADC_STATE_PEND|SADC_STATE_PENU|SADC_STATE_TSRDY)
325 int probe_device(usb_dev_handle* dh)
327 int tmp;
329 //or_reg(dh, SADC_ENA, SADC_ENA_TSEN, 1);
330 while(1)
332 if(read_reg(dh, SADC_STATE, 1) & SADC_STATE_TSRDY)
334 printf("%x\n", read_reg(dh, SADC_TSDAT, 4));
335 or_reg(dh, SADC_CTRL, read_reg(dh, SADC_STATE, 1) & TS_MASK, 1);
338 tmp = read_reg(dh, GPIO_PXPIN(3), 4);
339 if(tmp < 0)
340 return tmp;
341 if(tmp ^ MASK)
343 if(!(tmp & VOL_DOWN))
344 printf("VOL_DOWN\t");
345 if(!(tmp & VOL_UP))
346 printf("VOL_UP\t");
347 if(!(tmp & MENU))
348 printf("MENU\t");
349 if(!(tmp & OFF))
350 printf("OFF\t");
351 if(!(tmp & HOLD))
352 printf("HOLD\t");
353 printf("\n");
356 return 0;
359 unsigned int read_file(const char *name, unsigned char **buffer)
361 FILE *fd;
362 int len, n;
364 fd = fopen(name, "rb");
365 if (fd < 0)
367 fprintf(stderr, "[ERR] Could not open %s\n", name);
368 return 0;
371 len = filesize(fd);
373 *buffer = (unsigned char*)malloc(len);
374 if (*buffer == NULL)
376 fprintf(stderr, "[ERR] Could not allocate memory.\n");
377 fclose(fd);
378 return 0;
381 n = fread(*buffer, 1, len, fd);
382 if (n != len)
384 fprintf(stderr, "[ERR] Short read.\n");
385 fclose(fd);
386 return 0;
388 fclose(fd);
390 return len;
392 #define _GET_CPU fprintf(stderr, "[INFO] GET_CPU_INFO:"); \
393 GET_CPU_INFO(cpu); \
394 cpu[8] = 0; \
395 fprintf(stderr, " %s\n", cpu);
396 #define _SET_ADDR(a) fprintf(stderr, "[INFO] Set address to 0x%x...", a); \
397 SEND_COMMAND(VR_SET_DATA_ADDRESS, a); \
398 fprintf(stderr, " Done!\n");
399 #define _SEND_FILE(a) fsize = read_file(a, &buffer); \
400 fprintf(stderr, "[INFO] Sending file %s: %d bytes...", a, fsize); \
401 SEND_DATA(buffer, fsize); \
402 free(buffer); \
403 fprintf(stderr, " Done!\n");
404 #define _VERIFY_DATA(a,c) fprintf(stderr, "[INFO] Verifying data (%s)...", a); \
405 fsize = read_file(a, &buffer); \
406 buffer2 = (unsigned char*)malloc(fsize); \
407 SEND_COMMAND(VR_SET_DATA_ADDRESS, c); \
408 SEND_COMMAND(VR_SET_DATA_LENGTH, fsize); \
409 GET_DATA(buffer2, fsize); \
410 if(memcmp(buffer, buffer2, fsize) != 0) \
411 fprintf(stderr, "\n[WARN] Sent data isn't the same as received data...\n"); \
412 else \
413 fprintf(stderr, " Done!\n"); \
414 free(buffer); \
415 free(buffer2);
416 #define _STAGE1(a) fprintf(stderr, "[INFO] Stage 1 at 0x%x\n", a); \
417 SEND_COMMAND(VR_PROGRAM_START1, a);
418 #define _STAGE2(a) fprintf(stderr, "[INFO] Stage 2 at 0x%x\n", a); \
419 SEND_COMMAND(VR_PROGRAM_START2, a);
420 #define _FLUSH fprintf(stderr, "[INFO] Flushing caches...\n"); \
421 SEND_COMMAND(VR_FLUSH_CACHES, 0);
422 #ifdef _WIN32
423 #define _SLEEP(x) Sleep(x*1000);
424 #else
425 #define _SLEEP(x) sleep(x);
426 #endif
427 int mimic_of(usb_dev_handle *dh)
429 int err, fsize;
430 unsigned char *buffer, *buffer2;
431 char cpu[8];
433 fprintf(stderr, "[INFO] Start!\n");
434 _GET_CPU;
435 _SET_ADDR(0x8000 << 16);
436 _SEND_FILE("1.bin");
437 _GET_CPU;
438 _VERIFY_DATA("1.bin", 0x8000 << 16);
439 _STAGE1(0x8000 << 16);
440 _SLEEP(3);
441 _VERIFY_DATA("2.bin", 0xB3020060);
442 _GET_CPU;
443 _GET_CPU;
444 _FLUSH;
445 _GET_CPU;
446 _GET_CPU;
447 _SET_ADDR(0x8000 << 16);
448 _SEND_FILE("3.bin");
449 _GET_CPU;
450 _VERIFY_DATA("3.bin", 0x8000 << 16);
451 _GET_CPU;
452 _FLUSH;
453 _GET_CPU;
454 _GET_CPU;
455 _SET_ADDR(0x80D0 << 16);
456 _SEND_FILE("4.bin");
457 _GET_CPU;
458 _VERIFY_DATA("4.bin", 0x80D0 << 16);
459 _GET_CPU;
460 _FLUSH;
461 _GET_CPU;
462 _GET_CPU;
463 _SET_ADDR(0x80E0 << 16);
464 _SEND_FILE("5.bin");
465 _GET_CPU;
466 _VERIFY_DATA("5.bin", 0x80E0 << 16);
467 _GET_CPU;
468 _FLUSH;
469 _GET_CPU;
470 _GET_CPU;
471 _SET_ADDR(0x80004000);
472 _SEND_FILE("6.bin");
473 _GET_CPU;
474 _VERIFY_DATA("6.bin", 0x80004000);
475 _GET_CPU;
476 _FLUSH;
477 _GET_CPU;
478 _GET_CPU;
479 _SET_ADDR(0x80FD << 16);
480 _SEND_FILE("7.bin");
481 _GET_CPU;
482 _VERIFY_DATA("7.bin", 0x80FD << 16);
483 _GET_CPU;
484 _FLUSH;
485 _GET_CPU;
486 _STAGE2(0x80FD0004);
487 _VERIFY_DATA("8.bin", 0x80004004);
488 _VERIFY_DATA("9.bin", 0x80004008);
489 _SLEEP(2);
490 _GET_CPU;
491 _SET_ADDR(0x80E0 << 16);
492 _SEND_FILE("10.bin");
493 _GET_CPU;
494 _VERIFY_DATA("10.bin", 0x80E0 << 16);
495 _GET_CPU;
496 _FLUSH;
497 _GET_CPU;
498 _STAGE2(0x80e00008);
499 fprintf(stderr, "[INFO] Done!\n");
500 return 0;
503 void jzconnect(int address, unsigned char* buf, int len, int func)
505 struct usb_bus *bus;
506 struct usb_device *tmp_dev;
507 struct usb_device *dev = NULL;
508 usb_dev_handle *dh;
509 int err;
511 fprintf(stderr,"[INFO] Searching for device...\n");
513 usb_init();
514 if(usb_find_busses() < 0)
516 fprintf(stderr, "[ERR] Could not find any USB busses.\n");
517 return;
520 if (usb_find_devices() < 0)
522 fprintf(stderr, "[ERR] USB devices not found(nor hubs!).\n");
523 return;
526 for (bus = usb_get_busses(); bus; bus = bus->next)
528 for (tmp_dev = bus->devices; tmp_dev; tmp_dev = tmp_dev->next)
530 //printf("Found Vendor %04x Product %04x\n",tmp_dev->descriptor.idVendor, tmp_dev->descriptor.idProduct);
531 if (tmp_dev->descriptor.idVendor == VID &&
532 tmp_dev->descriptor.idProduct == PID)
534 dev = tmp_dev;
535 goto found;
541 if (dev == NULL)
543 fprintf(stderr, "[ERR] Device not found.\n");
544 fprintf(stderr, "[ERR] Ensure your device is in USB boot mode and run usbtool again.\n");
545 return;
548 found:
549 if ( (dh = usb_open(dev)) == NULL)
551 fprintf(stderr,"[ERR] Unable to open device.\n");
552 return;
555 err = usb_set_configuration(dh, 1);
557 if (err < 0)
559 fprintf(stderr, "[ERR] usb_set_configuration failed (%d, %s)\n", err, usb_strerror());
560 usb_close(dh);
561 return;
564 /* "must be called" written in the libusb documentation */
565 err = usb_claim_interface(dh, 0);
566 if (err < 0)
568 fprintf(stderr, "[ERR] Unable to claim interface (%d, %s)\n", err, usb_strerror());
569 usb_close(dh);
570 return;
573 fprintf(stderr,"[INFO] Found device, uploading application.\n");
575 /* Now we can transfer the application to the device. */
577 switch(func)
579 case 1:
580 case 5:
581 err = upload_app(dh, address, buf, len, (func == 5));
582 break;
583 case 2:
584 err = read_data(dh, address, buf, len);
585 break;
586 case 3:
587 err = test_device(dh);
588 break;
589 case 4:
590 err = probe_device(dh);
591 break;
592 case 6:
593 err = mimic_of(dh);
594 break;
597 /* release claimed interface */
598 usb_release_interface(dh, 0);
600 usb_close(dh);
603 void print_usage(void)
605 #ifdef _WIN32
606 fprintf(stderr, "Usage: usbtool.exe [CMD] [FILE] [ADDRESS] [LEN]\n");
607 #else
608 fprintf(stderr, "Usage: usbtool [CMD] [FILE] [ADDRESS] [LEN]\n");
609 #endif
610 fprintf(stderr, "\t[ADDRESS] has to be in 0xHEXADECIMAL format\n");
611 fprintf(stderr, "\t[CMD]:\n\t\t1 -> upload file to specified address and boot from it\n\t\t2 -> read data from [ADDRESS] with length [LEN] to [FILE]\n");
612 fprintf(stderr, "\t\t3 -> read device status\n\t\t4 -> probe keys (only Onda VX747)\n");
613 fprintf(stderr, "\t\t5 -> same as 1 but do a stage 2 boot\n\t\t6 -> mimic OF fw recovery\n");
614 #ifdef _WIN32
615 fprintf(stderr, "\nExample:\n\t usbtool.exe 1 fw.bin 0x80000000");
616 fprintf(stderr, "\n\t usbtool.exe 2 save.bin 0x81000000 1024");
617 #else
618 fprintf(stderr, "\nExample:\n\t usbtool 1 fw.bin 0x80000000");
619 fprintf(stderr, "\n\t usbtool 2 save.bin 0x81000000 1024");
620 #endif
623 int main(int argc, char* argv[])
625 unsigned char* buf;
626 int n, len, address, cmd=0;
627 FILE* fd;
629 fprintf(stderr, "USBtool v" VERSION " - (C) 2008 Maurus Cuelenaere\n");
630 fprintf(stderr, "This is free software; see the source for copying conditions. There is NO\n");
631 fprintf(stderr, "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n");
633 if(argc > 1)
634 sscanf(argv[1], "%d", &cmd);
635 switch(cmd)
637 case 5:
638 case 1:
639 if (strcmp(argv[3], "-1") == 0)
640 address = 0x80000000;
641 else
643 if (sscanf(argv[3], "0x%x", &address) <= 0)
645 print_usage();
646 return -1;
650 fd = fopen(argv[2], "rb");
651 if (fd < 0)
653 fprintf(stderr, "[ERR] Could not open %s\n", argv[2]);
654 return 4;
657 len = filesize(fd);
659 if (len > MAX_FIRMWARESIZE)
661 fprintf(stderr, "[ERR] Firmware file too big\n");
662 fclose(fd);
663 return 5;
666 buf = malloc(len);
667 if (buf == NULL)
669 fprintf(stderr, "[ERR] Could not allocate memory.\n");
670 fclose(fd);
671 return 6;
674 n = fread(buf, 1, len, fd);
675 if (n != len)
677 fprintf(stderr, "[ERR] Short read.\n");
678 fclose(fd);
679 return 7;
681 fclose(fd);
683 fprintf(stderr, "[INFO] File size: %d bytes\n", n);
685 jzconnect(address, buf, len, cmd);
686 break;
687 case 2:
688 if (sscanf(argv[3], "0x%x", &address) <= 0)
690 print_usage();
691 return -1;
694 fd = fopen(argv[2], "wb");
695 if (fd < 0)
697 fprintf(stderr, "[ERR] Could not open %s\n", argv[2]);
698 return 4;
701 sscanf(argv[4], "%d", &len);
703 buf = malloc(len);
704 if (buf == NULL)
706 fprintf(stderr, "[ERR] Could not allocate memory.\n");
707 fclose(fd);
708 return 6;
711 jzconnect(address, buf, len, 2);
713 n = fwrite(buf, 1, len, fd);
714 if (n != len)
716 fprintf(stderr, "[ERR] Short write.\n");
717 fclose(fd);
718 return 7;
720 fclose(fd);
721 break;
722 case 3:
723 case 4:
724 case 6:
725 jzconnect(address, NULL, 0, cmd);
726 break;
727 default:
728 print_usage();
729 return 1;
730 break;
733 return 0;