Merge branch 'master' of git://git.denx.de/u-boot
[kernel/u-boot.git] / common / cmd_usbd.c
1 /*
2  * USB Downloader for SAMSUNG Platform
3  *
4  * Copyright (C) 2007-2008 Samsung Electronics
5  * Minkyu Kang <mk7.kang@samsung.com>
6  *
7  */
8
9 #include <common.h>
10 #include <usbd.h>
11 #include <asm/errno.h>
12 #include <malloc.h>
13
14 /* version of USB Downloader Application */
15 #define APP_VERSION     "1.6.0"
16
17 #define OPS_READ        0
18 #define OPS_WRITE       1
19
20 #ifdef CONFIG_CMD_MTDPARTS
21 #include <jffs2/load_kernel.h>
22 static struct part_info *parts[16];
23 #endif
24
25 #ifdef CONFIG_UBIFS_MK
26 #include <mkfs.ubifs.h>
27 #endif
28
29 #ifdef CONFIG_UBINIZE
30 #include <ubinize.h>
31 #endif
32
33 #include <mbr.h>
34
35 static const char pszMe[] = "usbd: ";
36
37 static struct usbd_ops usbd_ops;
38
39 static unsigned int part_id;
40 static unsigned int write_part = 0;
41 static unsigned int fs_offset = 0x0;
42
43 #define NAND_PAGE_SIZE 2048
44
45 static unsigned long down_ram_addr;
46
47 static int down_mode;
48
49 /* common commands */
50 extern int do_run(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]);
51
52 #ifdef CONFIG_CMD_UBI
53 static int check_ubi_mode(void)
54 {
55         char *env_ubifs;
56         int ubi_mode;
57
58         env_ubifs = getenv("ubi");
59         ubi_mode = !strcmp(env_ubifs, "enabled");
60
61         return ubi_mode;
62 }
63 #else
64 #define check_ubi_mode()                0
65 #endif
66
67 #ifdef CONFIG_CMD_MTDPARTS
68 int mtdparts_init(void);
69 int find_dev_and_part(const char*, struct mtd_device**, u8*, struct part_info**);
70
71 /* common/cmd_jffs2.c */
72 extern struct list_head devices;
73
74 static u8 count_mtdparts(void)
75 {
76         struct list_head *dentry, *pentry;
77         struct mtd_device *dev;
78         u8 part_num = 0;
79
80         list_for_each(dentry, &devices) {
81                 dev = list_entry(dentry, struct mtd_device, link);
82
83                 /* list partitions for given device */
84                 list_for_each(pentry, &dev->parts)
85                         part_num++;
86         }
87
88         return part_num;
89 }
90
91 static int get_part_info(void)
92 {
93         struct mtd_device *dev;
94         u8 out_partnum;
95         char part_name[12];
96         char nand_name[12];
97         int i;
98         int part_num;
99         int ubi_mode = 0;
100
101 #if defined(CONFIG_CMD_NAND)
102         sprintf(nand_name, "nand0");
103 #elif defined(CONFIG_CMD_ONENAND)
104         sprintf(nand_name, "onenand0");
105 #else
106         printf("Configure your NAND sub-system\n");
107         return 0;
108 #endif
109
110         if (mtdparts_init())
111                 return 0;
112
113         ubi_mode = check_ubi_mode();
114
115         part_num = count_mtdparts();
116         for (i = 0; i < part_num; i++) {
117                 sprintf(part_name, "%s,%d", nand_name, i);
118
119                 if (find_dev_and_part(part_name, &dev, &out_partnum, &parts[i]))
120                         return -EINVAL;
121         }
122
123         return 0;
124 }
125
126 static int get_part_id(char *name)
127 {
128         int nparts = count_mtdparts();
129         int i;
130
131         for (i = 0; i < nparts; i++) {
132                 if (strcmp(parts[i]->name, name) == 0)
133                         return i;
134         }
135
136         printf("Error: Unknown partition -> %s\n", name);
137         return -1;
138 }
139 #else
140 static int get_part_info(void)
141 {
142         printf("Error: Can't get patition information\n");
143         return -EINVAL;
144 }
145
146 static int get_part_id(char *name)
147 {
148         return 0;
149 }
150 #endif
151
152 static void boot_cmd(char *addr)
153 {
154         char *argv[] = { "bootm", addr };
155         do_bootm(NULL, 0, 2, argv);
156 }
157
158 #if defined(CONFIG_CMD_NAND)
159 extern int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
160 #elif defined(CONFIG_CMD_ONENAND)
161 extern int do_onenand(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
162 #endif
163
164 /* NAND erase and write using nand command */
165 static int nand_cmd(int type, char *p1, char *p2, char *p3)
166 {
167         int ret = 1;
168         char nand_name[12];
169         int (*nand_func) (cmd_tbl_t *, int, int, char **);
170
171 #if defined(CONFIG_CMD_NAND)
172         sprintf(nand_name, "nand");
173         nand_func = do_nand;
174 #elif defined(CONFIG_CMD_ONENAND)
175         sprintf(nand_name, "onenand");
176         nand_func = do_onenand;
177 #else
178         printf("Configure your NAND sub-system\n");
179         return 0;
180 #endif
181
182         if (type == 0) {
183                 char *argv[] = {nand_name, "erase", p1, p2};
184                 printf("%s %s %s %s\n", argv[0], argv[1], argv[2], argv[3]);
185                 ret = nand_func(NULL, 0, 4, argv);
186         } else if (type == 1) {
187                 char *argv[] = {nand_name, "write", p1, p2, p3};
188                 printf("%s %s %s %s %s\n", argv[0], argv[1], argv[2],
189                                 argv[3], argv[4]);
190                 ret = nand_func(NULL, 0, 5, argv);
191         } else if (type == 2) {
192                 char *argv[] = {nand_name, "write.yaffs", p1, p2, p3};
193                 printf("%s %s %s %s %s\n", argv[0], argv[1], argv[2],
194                                 argv[3], argv[4]);
195                 ret = nand_func(NULL, 0, 5, argv);
196         } else if (type == 3) {
197                 char *argv[] = {nand_name, "lock", p1, p2};
198                 printf("%s %s %s %s\n", argv[0], argv[1], argv[2], argv[3]);
199                 ret = nand_func(NULL, 0, 4, argv);
200         }
201
202         if (ret)
203                 printf("Error: NAND Command\n");
204
205         return ret;
206 }
207
208 #ifdef CONFIG_CMD_UBI
209 int do_ubi(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
210
211 int ubi_cmd(int part, char *p1, char *p2, char *p3)
212 {
213         int ret = 1;
214
215         if (part == RAMDISK_PART_ID) {
216                 char *argv[] = {"ubi", "write", p1, "rootfs.cramfs", p2, p3};
217                 printf("%s %s %s %s %s %s\n", argv[0], argv[1], argv[2],
218                                 argv[3], argv[4], argv[5]);
219                 ret = do_ubi(NULL, 0, 6, argv);
220         } else if (part == FILESYSTEM_PART_ID) {
221                 char *argv[] = {"ubi", "write", p1, "factoryfs.cramfs", p2, p3};
222                 printf("%s %s %s %s %s %s\n", argv[0], argv[1], argv[2],
223                                 argv[3], argv[4], argv[5]);
224                 ret = do_ubi(NULL, 0, 6, argv);
225         } else if (part == FILESYSTEM2_PART_ID) {
226                 char *argv[] = {"ubi", "write", p1, "datafs.ubifs", p2, p3};
227                 printf("%s %s %s %s %s %s\n", argv[0], argv[1], argv[2],
228                                 argv[3], argv[4], argv[5]);
229                 ret = do_ubi(NULL, 0, 6, argv);
230         }
231
232         return ret;
233 }
234 #endif
235
236 #ifdef CONFIG_CMD_MMC
237 #include <mmc.h>
238 #include <fat.h>
239
240 static struct mmc *mmc;
241
242 static int mmc_cmd(int ops, int dev_num, ulong start, lbaint_t cnt, void *addr)
243 {
244         int ret;
245
246         if (ops) {
247                 printf("mmc write 0x%x 0x%x\n", start, cnt);
248                 ret = mmc->block_dev.block_write(dev_num, start, cnt, addr);
249         } else {
250                 printf("mmc read 0x%x 0x%x\n", start, cnt);
251                 ret = mmc->block_dev.block_read(dev_num, start, cnt, addr);
252         }
253
254         if (ret > 0)
255                 ret = 0;
256         else
257                 ret = 1;
258
259         return ret;
260 }
261
262 #define NORMAL_PARTITION        0
263 #define EXTEND_PARTITION        1
264
265 #define EXTEND_PART_TYPE        5
266
267 #define EXTEND_MAX_PART         32
268
269 static unsigned int cur_blk_offset;
270 static unsigned int cur_part_size;
271 static unsigned int cur_part;
272
273 static unsigned int mmc_parts;
274 static unsigned int mmc_part_write;
275
276 static u8 part_mode = 0;
277
278 struct partition_info {
279         u32 size;
280         u32 checksum;
281         u32 res;
282 } __attribute__((packed));
283
284 struct partition_header {
285         u8                      fat32head[16];  /* RFSHEAD identifier */
286         struct partition_info   partition[EXTEND_MAX_PART];
287         u8                      res[112];       /* only data (without MBR) */
288 } __attribute__((packed));
289
290 struct mul_partition_info {
291         u32 lba_begin;          /* absolute address from 0 block */
292         u32 num_sectors;
293 } __attribute__((packed));
294
295 #define MBR_OFFSET      0x10
296
297 struct partition_header part_info;
298 struct mbr mbr_info;
299 struct mul_partition_info mul_info[EXTEND_MAX_PART];
300
301 static int write_mmc_partition(struct usbd_ops *usbd, u32 *ram_addr, u32 len)
302 {
303         unsigned int blocks;
304         int i;
305         int loop;
306         u32 cnt;
307         int ret;
308
309         if (cur_part_size > len) {
310                 blocks = len / usbd->mmc_blk;
311                 ret = -1;
312         } else {
313                 blocks = cur_part_size / usbd->mmc_blk;
314                 ret = len - cur_part_size;
315         }
316
317         if (len % usbd->mmc_blk)
318                 blocks++;
319
320         loop = blocks / usbd->mmc_max;
321         if (blocks % usbd->mmc_max)
322                 loop++;
323
324         for (i = 0; i < loop; i++) {
325                 if (i == 0) {
326                         cnt = blocks % usbd->mmc_max;
327                         if (cnt == 0)
328                                 cnt = usbd->mmc_max;
329                 } else {
330                         cnt = usbd->mmc_max;
331                 }
332
333                 mmc_cmd(OPS_WRITE, usbd->mmc_dev, cur_blk_offset,
334                                 cnt, (void *)*ram_addr);
335
336                 cur_blk_offset += cnt;
337
338                 *ram_addr += (cnt * usbd->mmc_blk);
339         }
340
341         return ret;
342 }
343
344 static int write_file_mmc(struct usbd_ops *usbd, u32 len)
345 {
346         u32 ram_addr;
347         int i;
348         int ret;
349         struct mbr *mbr;
350
351         if (!usbd->mmc_total) {
352                 printf("MMC is not supported!\n");
353                 return 0;
354         }
355
356         ram_addr = (u32)down_ram_addr;
357
358         if (cur_blk_offset == 0) {
359                 boot_sector *bs;
360                 u32 mbr_blk_size;
361
362                 memcpy(&part_info, (void *)ram_addr,
363                                 sizeof(struct partition_header));
364
365                 ram_addr += sizeof(struct partition_header);
366                 len -= sizeof(struct partition_header);
367                 mbr = (struct mbr *)ram_addr;
368                 mbr_blk_size = mbr->parts[0].lba;
369
370                 if (mbr->parts[0].partition_type != EXTEND_PART_TYPE) {
371                         part_mode = NORMAL_PARTITION;
372
373                         /* modify sectors of p1 */
374                         mbr->parts[0].nsectors = usbd->mmc_total -
375                                         (mbr_blk_size +
376                                         mbr->parts[1].nsectors +
377                                         mbr->parts[2].nsectors +
378                                         mbr->parts[3].nsectors);
379
380                         mmc_parts++;
381
382                         /* modify lba_begin of p2 and p3 and p4 */
383                         for (i = 1; i < 4; i++) {
384                                 if (part_info.partition[i].size == 0)
385                                         break;
386
387                                 mmc_parts++;
388                                 mbr->parts[i].lba =
389                                         mbr->parts[i - 1].lba +
390                                         mbr->parts[i - 1].nsectors;
391                         }
392
393                         /* copy MBR */
394                         memcpy(&mbr_info, mbr, sizeof(struct mbr));
395
396                         printf("Total Size: 0x%08x #parts %d\n",
397                                         (unsigned int)usbd->mmc_total,
398                                         mmc_parts);
399                         for (i = 0; i < mmc_parts; i++) {
400                                 printf("p%d\t0x%08x\t0x%08x\n", i + 1,
401                                         mbr_info.parts[i].lba,
402                                         mbr_info.parts[i].nsectors);
403                         }
404
405                         /* write MBR */
406                         mmc_cmd(OPS_WRITE, usbd->mmc_dev, 0,
407                                         mbr_blk_size, (void *)ram_addr);
408
409                         ram_addr += mbr_blk_size * usbd->mmc_blk;
410                         len -= mbr_blk_size * usbd->mmc_blk;
411
412                         cur_blk_offset = mbr_blk_size;
413                         cur_part = 0;
414                         cur_part_size = part_info.partition[0].size;
415
416                         /* modify p1's total sector */
417                         bs = (boot_sector *)ram_addr;
418                         bs->total_sect = mbr_info.parts[0].nsectors;
419
420                         printf("\nWrite Partition %d.. %d blocks\n",
421                                 cur_part + 1,
422                                 part_info.partition[cur_part].size /
423                                 (int)usbd->mmc_blk);
424                 } else {
425                         part_mode = EXTEND_PARTITION;
426
427                         for (i = 0; i < EXTEND_MAX_PART; i++) {
428                                 if (part_info.partition[i].size == 0)
429                                         break;
430                                 mmc_parts++;
431                         }
432
433                         if (mmc_parts == 0)
434                                 return -1;
435                         else
436                                 printf("found %d partitions\n", mmc_parts);
437
438                         /* build partition table */
439
440                         mul_info[0].num_sectors =
441                                 usbd->mmc_total - mbr_blk_size;
442                         for (i = 1; i < mmc_parts; i++) {
443                                 mul_info[i].num_sectors =
444                                         part_info.partition[i].res +
445                                         mbr_blk_size; /* add MBR */
446                         }
447
448                         for (i = 1; i < mmc_parts; i++) {
449                                 mul_info[0].num_sectors -=
450                                         mul_info[i].num_sectors;
451                         }
452
453                         mul_info[0].lba_begin = mbr_blk_size;
454                         for (i = 1; i < mmc_parts; i++) {
455                                 mul_info[i].lba_begin =
456                                         mul_info[i-1].lba_begin +
457                                         mul_info[i-1].num_sectors;
458                         }
459
460                         /* modify MBR of extended partition: p1 */
461                         mbr->parts[0].nsectors =
462                                 usbd->mmc_total - mbr_blk_size;
463
464                         /* modify MBR of first logical partition: p5 */
465                         mbr = (struct mbr *)
466                                 (ram_addr + mbr_blk_size * usbd->mmc_blk);
467
468                         mbr->parts[0].nsectors =
469                                 mul_info[0].num_sectors - mbr_blk_size;
470                         mbr->parts[1].lba=
471                                 mul_info[1].lba_begin - mbr_blk_size;
472
473                         /* modify BPB data of p5 */
474                         bs = (boot_sector *)
475                                 ((u32)mbr + mbr_blk_size * usbd->mmc_blk);
476                         memset(&bs->sectors, 0, 2);
477                         bs->total_sect = mbr->parts[0].nsectors;
478
479                         printf("Total Size: 0x%08x #parts %d\n",
480                                         (unsigned int)usbd->mmc_total,
481                                         mmc_parts);
482                         for (i = 0; i < mmc_parts; i++) {
483                                 printf("p%d\t0x%08x\t0x%08x\n", i + 1,
484                                         mul_info[i].lba_begin,
485                                         mul_info[i].num_sectors);
486                         }
487
488                         cur_blk_offset = 0;
489                         cur_part = 0;
490                         cur_part_size = part_info.partition[0].size;
491
492                         printf("\nWrite Partition %d.. %d blocks\n",
493                                 cur_part + 1,
494                                 part_info.partition[cur_part].size /
495                                 (int)usbd->mmc_blk);
496                 }
497         }
498
499         for (i = cur_part; i < mmc_parts; i++) {
500                 ret = write_mmc_partition(usbd, &ram_addr, len);
501
502                 if (ret < 0) {
503                         cur_part_size -= len;
504                         break;
505                 } else {
506                         cur_part++;
507                         cur_part_size =
508                                 part_info.partition[cur_part].size;
509
510                         if (part_mode == NORMAL_PARTITION) {
511                                 cur_blk_offset =
512                                         mbr_info.parts[cur_part].lba;
513                         } else {
514                                 cur_blk_offset =
515                                         mul_info[cur_part].lba_begin;
516                                 /* modify MBR */
517                                 if (cur_part < mmc_parts) {
518                                         mbr = (struct mbr *)ram_addr;
519                                         mbr->parts[1].lba=
520                                                 mul_info[cur_part+1].lba_begin -
521                                                 mbr->parts[0].lba;
522                                 }
523                         }
524
525                         if (ret == 0)
526                                 break;
527                         else
528                                 len = ret;
529
530                         printf("\nWrite Partition %d.. %d blocks\n",
531                                 cur_part + 1,
532                                 part_info.partition[cur_part].size /
533                                 (int)usbd->mmc_blk);
534                 }
535         }
536
537         return 0;
538 }
539
540 static int write_file_mmc_part(struct usbd_ops *usbd, u32 len)
541 {
542         u32 ram_addr;
543         u32 ofs;
544         int i;
545         struct mbr *mbr;
546         u32 mbr_blk_size;
547
548         ram_addr = (u32)down_ram_addr;
549         mbr = &mbr_info;
550
551         if (cur_blk_offset == 0) {
552                 /* read MBR */
553                 mmc_cmd(OPS_READ, usbd->mmc_dev, 0,
554                         sizeof(struct mbr)/usbd->mmc_blk, (void *)mbr);
555
556                 mbr_blk_size = mbr->parts[0].lba;
557
558                 if (mbr->parts[0].partition_type != EXTEND_PART_TYPE) {
559                         part_mode = NORMAL_PARTITION;
560
561                         for (i = 0; i < 4; i++) {
562                                 printf("p%d\t0x%08x\t0x%08x\n", i + 1,
563                                         mbr_info.parts[i].lba,
564                                         mbr_info.parts[i].nsectors);
565                         }
566
567                         cur_blk_offset =
568                                 mbr->parts[mmc_part_write - 1].lba;
569                         cur_part = mmc_part_write - 1;
570                         cur_part_size =
571                                 usbd->mmc_blk *
572                                 mbr->parts[mmc_part_write - 1].nsectors;
573
574                         if (mmc_part_write == 1) {
575                                 ram_addr += sizeof(struct mbr);
576                                 cur_blk_offset += sizeof(struct mbr) /
577                                         usbd->mmc_blk;
578                                 len -= sizeof(struct mbr);
579                         }
580                 } else {
581                         part_mode = EXTEND_PARTITION;
582
583                         for (i = 1; i < mmc_part_write; i++) {
584                                 ofs = mbr->parts[0].lba + mbr->parts[1].lba;
585                                 printf("P%d start blk: 0x%x, size: 0x%x\n", i,
586                                         ofs, mbr->parts[1].nsectors);
587                                 mmc_cmd(OPS_READ, usbd->mmc_dev, ofs,
588                                         (sizeof(struct mbr) / usbd->mmc_blk),
589                                         (void *)mbr);
590                         }
591
592                         ofs = mbr->parts[0].lba + mbr->parts[1].lba;
593                         printf("P%d start blk: 0x%x, size: 0x%x\n", i,
594                                 ofs, mbr->parts[1].nsectors);
595
596                         ofs += mbr_blk_size; /* skip MBR */
597                         cur_blk_offset = ofs;
598                         cur_part = mmc_part_write - 1;
599                         cur_part_size =
600                                 usbd->mmc_blk *
601                                 mbr->parts[1].nsectors;
602
603                         if (mmc_part_write == 1) {
604                                 boot_sector *bs;
605                                 u32 total_sect;
606                                 /* modify BPB data of p1 */
607                                 mmc_cmd(OPS_READ, usbd->mmc_dev, cur_blk_offset,
608                                         (sizeof(struct mbr) / usbd->mmc_blk),
609                                         mbr);
610
611                                 bs = (boot_sector *)mbr;
612                                 total_sect = bs->total_sect;
613
614                                 bs = (boot_sector *)ram_addr;
615                                 memset(&bs->sectors, 0, 2);
616                                 bs->total_sect = total_sect;
617                         }
618                 }
619         }
620
621         printf("\nWrite Partition %d.. %d blocks\n",
622                 cur_part + 1,
623                 len / (int)usbd->mmc_blk);
624
625         write_mmc_partition(usbd, &ram_addr, len);
626
627         return 0;
628 }
629 #endif
630
631 static unsigned int mbr_offset[16];
632 static int mbr_parts = 0;
633
634 static unsigned long memsize_parse (const char *const ptr, const char **retptr)
635 {
636         unsigned long ret = simple_strtoul(ptr, (char **)retptr, 0);
637
638         switch (**retptr) {
639                 case 'G':
640                 case 'g':
641                         ret <<= 10;
642                 case 'M':
643                 case 'm':
644                         ret <<= 10;
645                 case 'K':
646                 case 'k':
647                         ret <<= 10;
648                         (*retptr)++;
649                 default:
650                         break;
651         }
652
653         return ret;
654 }
655
656 static void set_mbr_info(struct usbd_ops *usbd, char *ramaddr, u32 len)
657 {
658         char mbr_str[256];
659         char save[16][16];
660         char *p;
661         char *tok;
662         unsigned int size[16];
663         int i = 0;
664
665         strncpy(mbr_str, ramaddr, len);
666         p = mbr_str;
667
668         for (i = 0; ; i++, p = NULL) {
669                 tok = strtok(p, ",");
670                 if (tok == NULL)
671                         break;
672                 strcpy(save[i], tok);
673                 printf("part%d: %s\n", i, save[i]);
674         }
675
676         mbr_parts = i;
677         printf("find %d partitions\n", mbr_parts);
678
679         for (i = 0; i < mbr_parts; i++) {
680                 p = save[i];
681                 size[i] = memsize_parse(p, (const char **)&p) / 512;
682         }
683
684         puts("save the MBR Table...\n");
685         set_mbr_table(0x800, mbr_parts, size, mbr_offset);
686 }
687
688 static int write_mmc_image(struct usbd_ops *usbd, unsigned int len, int part_num)
689 {
690         int ret = 0;
691
692         if (mbr_parts <= part_num) {
693                 printf("Error: MBR table have %d partitions (request %d)\n",
694                                 mbr_parts, part_num);
695                 return 1;
696         }
697
698 #if 0
699         /* modify size of UMS partition */
700         if (part_num == 4 && fs_offset == 0) {
701                 boot_sector *bs;
702                 bs = (boot_sector *)down_ram_addr;
703                 memset(&bs->sectors, 0, 2);
704                 bs->total_sect = usbd->mmc_total - mbr_offset[part_num];
705         }
706 #endif
707         ret = mmc_cmd(OPS_WRITE, usbd->mmc_dev,
708                         mbr_offset[part_num] + fs_offset,
709                         len / usbd->mmc_blk,
710                         (void *)down_ram_addr);
711
712         fs_offset += (len / usbd->mmc_blk);
713
714         return ret;
715 }
716
717 static int write_fat_file(struct usbd_ops *usbd, char *file_name,
718                         int part_id, int len)
719 {
720 #ifdef CONFIG_FAT_WRITE
721         int ret;
722
723         ret = fat_register_device(&mmc->block_dev, part_id);
724         if (ret < 0) {
725                 printf("error : fat_register_divce\n");
726                 return 0;
727         }
728
729         ret = file_fat_write(file_name, (void *)down_ram_addr, len);
730
731         /* format and write again */
732         if (ret == 1) {
733                 printf("formatting\n");
734                 if (mkfs_vfat(&mmc->block_dev, part_id)) {
735                         printf("error : format device\n");
736                         return 0;
737                 }
738                 ret = file_fat_write(file_name, (void *)down_ram_addr, len);
739         }
740
741         if (ret < 0) {
742                 printf("error : writing uImage\n");
743                 return 0;
744         }
745 #else
746         printf("error: doesn't support fat_write\n");
747 #endif
748         return 0;
749 }
750
751
752 static int ubi_update = 0;
753
754 static int write_file_system(char *ramaddr, ulong len, char *offset,
755                 char *length, int part_num)
756 {
757         int ret = 0;
758
759 #ifdef CONFIG_CMD_MTDPARTS
760 #ifdef CONFIG_CMD_UBI
761         /* UBI Update */
762         if (ubi_update) {
763                 sprintf(length, "0x%x", (uint)len);
764                 ret = ubi_cmd(part_id, ramaddr, length, "cont");
765                 return ret;
766         }
767 #endif
768
769         /* Erase entire partition at the first writing */
770         if (write_part == 0 && ubi_update == 0) {
771                 sprintf(offset, "0x%x", (uint)parts[part_num]->offset);
772                 sprintf(length, "0x%x", (uint)parts[part_num]->size);
773                 nand_cmd(0, offset, length, NULL);
774         }
775
776         sprintf(offset, "0x%x", (uint)(parts[part_num]->offset + fs_offset));
777         sprintf(length, "0x%x", (uint)len);
778
779         fs_offset += len;
780         ret = nand_cmd(1, ramaddr, offset, length);
781 #endif
782
783         return ret;
784 }
785
786 static int qboot_erase = 0;
787
788 /* Erase the qboot */
789 static void erase_qboot_area(void)
790 {
791 #ifdef CONFIG_CMD_MTDPARTS
792         char offset[12], length[12];
793         int qboot_id;
794
795         if (qboot_erase)
796                 return;
797
798         qboot_id = get_part_id("qboot");
799
800         if (qboot_id != -1) {
801                 printf("\nCOMMAND_ERASE_QBOOT\n");
802                 sprintf(offset, "%x", parts[qboot_id]->offset);
803                 sprintf(length, "%x", parts[qboot_id]->size);
804                 nand_cmd(0, offset, length, NULL);
805                 qboot_erase = 1;
806         }
807 #endif
808 }
809
810 /* Erase the environment */
811 static void erase_env_area(struct usbd_ops *usbd)
812 {
813 #if defined(CONFIG_ENV_IS_IN_NAND) || defined(CONFIG_ENV_IS_IN_ONENAND)
814         int param_id;
815         char offset[12], length[12];
816
817         param_id = get_part_id("params");
818
819         if (param_id == -1) {
820                 sprintf(offset, "%x", CONFIG_ENV_ADDR);
821                 sprintf(length, "%x", CONFIG_ENV_SIZE);
822         } else {
823                 sprintf(offset, "%x", parts[param_id]->offset);
824                 sprintf(length, "%x", parts[param_id]->size);
825         }
826         nand_cmd(0, offset, length, NULL);
827 #elif defined(CONFIG_ENV_IS_IN_MMC)
828         char buf[usbd->mmc_blk];
829
830         memset(buf, 0x0, usbd->mmc_blk);
831         mmc_cmd(OPS_WRITE, CONFIG_SYS_MMC_ENV_DEV,
832                         CONFIG_ENV_OFFSET / usbd->mmc_blk,
833                         1, (void *)buf);
834 #endif
835 }
836
837 static inline void send_ack(struct usbd_ops *usbd, int data)
838 {
839         *((ulong *) usbd->tx_data) = data;
840         usbd->send_data(usbd->tx_data, usbd->tx_len);
841 }
842
843 static inline int check_mmc_device(struct usbd_ops *usbd)
844 {
845         if (usbd->mmc_total)
846                 return 0;
847
848         printf("\nError: Couldn't find the MMC device\n");
849         return 1;
850 }
851
852 static int write_mtd_image(struct usbd_ops *usbd, int img_type,
853                 unsigned int len, unsigned int arg)
854 {
855         int ret = -1;
856 #ifdef CONFIG_CMD_MTDPARTS
857         unsigned int ofs = 0;
858         char offset[12], length[12], ramaddr[12];
859
860         sprintf(ramaddr, "0x%x", (uint) down_ram_addr);
861
862         /* Erase and Write to NAND */
863         switch (img_type) {
864         case IMG_BOOT:
865                 ofs = parts[part_id]->offset;
866 #ifdef CONFIG_S5PC1XX
867                 /* Workaround: for prevent revision mismatch */
868                 if (cpu_is_s5pc110() && (down_mode != MODE_FORCE)) {
869                         int img_rev = 1;
870                         long *img_header = (long *)down_ram_addr;
871
872                         if (*img_header == 0xea000012)
873                                 img_rev = 0;
874                         else if (*(img_header + 0x400) == 0xea000012)
875                                 img_rev = 2;
876
877                         if (img_rev != s5p_get_cpu_rev()) {
878                                 printf("CPU revision mismatch!\n"
879                                         "bootloader is %s%s\n"
880                                         "download image is %s%s\n",
881                                         s5p_get_cpu_rev() ? "EVT1" : "EVT0",
882                                         s5p_get_cpu_rev() == 2 ? "-Fused" : "",
883                                         img_rev ? "EVT1" : "EVT0",
884                                         img_rev == 2 ? "-Fused" : "");
885                                 return -1;
886                         }
887                 }
888 #endif
889 #ifdef CONFIG_SBOOT
890                 /* Only u-boot.bin is allowed */
891                 {
892                         long *img_header = (long *)down_ram_addr;
893
894                         if (*img_header != 0xea000018) {
895                                 printf("\n!!! ERROR !!!\n"
896                                         "Please download the u-boot.bin.\n"
897                                         "Other images are not allowed.\n\n");
898                                 return -1;
899                         }
900                 }
901 #endif
902
903                 erase_env_area(usbd);
904
905                 sprintf(offset, "%x", (uint)ofs);
906                 if (ofs != 0)
907                         sprintf(length, "%x", parts[part_id]->size - (uint)ofs);
908                 else
909                         sprintf(length, "%x", parts[part_id]->size);
910
911                 /* Erase */
912                 nand_cmd(0, offset, length, NULL);
913                 /* Write */
914                 sprintf(length, "%x", (unsigned int) len);
915                 ret = nand_cmd(1, ramaddr, offset, length);
916                 break;
917
918         case IMG_KERNEL:
919                 sprintf(offset, "%x", parts[part_id]->offset);
920                 sprintf(length, "%x", parts[part_id]->size);
921
922                 /* Erase */
923                 nand_cmd(0, offset, length, NULL);
924                 /* Write */
925                 sprintf(length, "%x", (unsigned int) len);
926                 ret = nand_cmd(1, ramaddr, offset, length);
927
928                 erase_qboot_area();
929                 break;
930
931         /* File Systems */
932         case IMG_FILESYSTEM:
933                 ret = write_file_system(ramaddr, len, offset, length, part_id);
934
935                 erase_qboot_area();
936                 break;
937
938         case IMG_MODEM:
939                 sprintf(offset, "%x", parts[part_id]->offset);
940                 sprintf(length, "%x", parts[part_id]->size);
941
942                 /* Erase */
943                 if (!arg)
944                         nand_cmd(0, offset, length, NULL);
945                 else
946                         printf("CSA Clear will be skipped temporary\n");
947
948                 /* Check ubi image, 0x23494255 is UBI# */
949                 {
950                         long *img_header = (long *)down_ram_addr;
951
952                         if (*img_header == 0x23494255)
953                                 goto ubi_img;
954                 }
955
956 #ifdef CONFIG_UBIFS_MK
957                 void *dest_addr = (void *) down_ram_addr + 0xc00000;
958                 void *src_addr = (void *) down_ram_addr;
959                 int leb_size, max_leb_cnt, mkfs_min_io_size;
960                 unsigned long ubifs_dest_size, ubi_dest_size;
961 #ifdef CONFIG_S5PC110
962                 mkfs_min_io_size = 4096;
963                 leb_size = 248 * 1024;
964                 max_leb_cnt = 4096;
965 #elif CONFIG_S5PC210
966                 mkfs_min_io_size = 2048;
967                 leb_size = 126 * 1024;
968                 max_leb_cnt = 4096;
969 #endif
970                 printf("Start making ubifs\n");
971                 ret = mkfs(src_addr, len, dest_addr, &ubifs_dest_size,
972                            mkfs_min_io_size, leb_size, max_leb_cnt);
973                 if (ret) {
974                         printf("Error : making ubifs failed\n");
975                         goto out;
976                 }
977                 printf("Complete making ubifs\n");
978 #endif
979
980 #ifdef CONFIG_UBINIZE
981                 int peb_size, ubi_min_io_size, subpage_size, vid_hdr_offs;
982 #ifdef CONFIG_S5PC110
983                 ubi_min_io_size = 4096;
984                 peb_size = 256 * 1024;
985                 subpage_size = 4096;
986                 vid_hdr_offs = 0;
987 #elif CONFIG_S5PC210
988                 ubi_min_io_size = 2048;
989                 peb_size = 128 * 1024;
990                 subpage_size = 512;
991                 vid_hdr_offs = 512;
992 #endif
993                 printf("Start ubinizing\n");
994                 ret = ubinize(dest_addr, ubifs_dest_size,
995                               src_addr, &ubi_dest_size,
996                               peb_size, ubi_min_io_size,
997                               subpage_size, vid_hdr_offs);
998                 if (ret) {
999                         printf("Error : ubinizing failed\n");
1000                         goto out;
1001                 }
1002                 printf("Complete ubinizing\n");
1003
1004                 len = (unsigned int) ubi_dest_size;
1005 #endif
1006
1007 ubi_img:
1008                 /* Write : arg (0 Modem) / (1 CSA) */
1009                 if (!arg) {
1010                         sprintf(length, "%x", (unsigned int) len);
1011                         ret = nand_cmd(1, ramaddr, offset, length);
1012                 }
1013 out:
1014                 break;
1015
1016 #ifdef CONFIG_CMD_MMC
1017         case IMG_MMC:
1018                 if (check_mmc_device(usbd))
1019                         return -1;
1020
1021                 if (mmc_part_write)
1022                         ret = write_file_mmc_part(usbd, len);
1023                 else
1024                         ret = write_file_mmc(usbd, len);
1025
1026                 erase_qboot_area();
1027                 break;
1028 #endif
1029         default:
1030                 /* Retry? */
1031                 write_part--;
1032         }
1033 #endif
1034         return ret;
1035 }
1036
1037 static int write_v2_image(struct usbd_ops *usbd, int img_type,
1038                 unsigned int len, unsigned int arg)
1039 {
1040         int ret;
1041
1042         if (check_mmc_device(usbd))
1043                 return -1;
1044
1045         switch (img_type) {
1046         case IMG_V2:
1047                 ret = write_mmc_image(usbd, len, part_id);
1048                 break;
1049
1050         case IMG_MBR:
1051 #ifdef CONFIG_CMD_MBR
1052                 set_mbr_info(usbd, (char *)down_ram_addr, len);
1053 #endif
1054                 break;
1055
1056         case IMG_BOOTLOADER:
1057 #ifdef CONFIG_BOOTLOADER_SECTOR
1058                 erase_env_area(usbd);
1059
1060                 ret = mmc_cmd(OPS_WRITE, usbd->mmc_dev,
1061                                 CONFIG_BOOTLOADER_SECTOR,
1062                                 len / usbd->mmc_blk + 1,
1063                                 (void *)down_ram_addr);
1064 #endif
1065                 break;
1066
1067         case IMG_KERNEL_V2:
1068                 ret = write_fat_file(usbd, "uImage", part_id, len);
1069                 break;
1070
1071         case IMG_MODEM_V2:
1072                 ret = write_fat_file(usbd, "modem.bin", part_id, len);
1073                 break;
1074
1075         default:
1076                 /* Retry? */
1077                 write_part--;
1078         }
1079
1080         return ret;
1081 }
1082
1083 /* Parsing received data packet and Process data */
1084 static int process_data(struct usbd_ops *usbd)
1085 {
1086         unsigned int cmd = 0, arg = 0, len = 0, flag = 0;
1087         char ramaddr[12];
1088         int recvlen = 0;
1089         unsigned int blocks = 0;
1090         int ret = 0;
1091         int ubi_mode = 0;
1092         int img_type = -1;
1093
1094         sprintf(ramaddr, "0x%x", (uint) down_ram_addr);
1095
1096         /* Parse command */
1097         cmd  = *((ulong *) usbd->rx_data + 0);
1098         arg  = *((ulong *) usbd->rx_data + 1);
1099         len  = *((ulong *) usbd->rx_data + 2);
1100         flag = *((ulong *) usbd->rx_data + 3);
1101
1102         /* Reset tx buffer */
1103         memset(usbd->tx_data, 0, sizeof(usbd->tx_data));
1104
1105         ubi_mode = check_ubi_mode();
1106
1107         switch (cmd) {
1108         case COMMAND_DOWNLOAD_IMAGE:
1109                 printf("\nCOMMAND_DOWNLOAD_IMAGE\n");
1110
1111                 if (arg)
1112                         down_ram_addr = usbd->ram_addr + 0x1000000;
1113                 else
1114                         down_ram_addr = usbd->ram_addr;
1115
1116                 usbd->recv_setup((char *)down_ram_addr, (int)len);
1117                 printf("Download to 0x%08x, %d bytes\n",
1118                                 (uint)down_ram_addr, (int)len);
1119
1120                 /* response */
1121                 send_ack(usbd, STATUS_DONE);
1122
1123                 /* Receive image by using dma */
1124                 recvlen = usbd->recv_data();
1125                 if (recvlen < 0) {
1126                         send_ack(usbd, STATUS_ERROR);
1127                         return -1;
1128                 } else if (recvlen < len) {
1129                         printf("Error: wrong image size -> %d/%d\n",
1130                                         (int)recvlen, (int)len);
1131
1132                         /* Retry this commad */
1133                         send_ack(usbd, STATUS_RETRY);
1134                 } else
1135                         send_ack(usbd, STATUS_DONE);
1136
1137                 return 1;
1138
1139         case COMMAND_DOWNLOAD_SPMODE:
1140                 printf("\nCOMMAND_DOWNLOAD_SPMODE\n");
1141
1142                 down_ram_addr = usbd->ram_addr + 0x2008000;
1143
1144                 usbd->recv_setup((char *)down_ram_addr, (int)len);
1145                 printf("Download to 0x%08x, %d bytes\n",
1146                                 (uint)down_ram_addr, (int)len);
1147
1148                 /* response */
1149                 send_ack(usbd, STATUS_DONE);
1150
1151                 /* Receive image by using dma */
1152                 recvlen = usbd->recv_data();
1153                 send_ack(usbd, STATUS_DONE);
1154
1155                 return 0;
1156
1157         /* Report partition info */
1158         case COMMAND_PARTITION_SYNC:
1159                 part_id = arg;
1160
1161 #ifdef CONFIG_CMD_UBI
1162                 if (ubi_mode) {
1163                         if (part_id == RAMDISK_PART_ID ||
1164                             part_id == FILESYSTEM_PART_ID ||
1165                             part_id == FILESYSTEM2_PART_ID) {
1166                                 /* change to yaffs style */
1167                                 get_part_info();
1168                         }
1169                 } else {
1170                         if (part_id == FILESYSTEM3_PART_ID) {
1171                                 /* change ubi style */
1172                                 get_part_info();
1173                         }
1174                 }
1175 #endif
1176
1177                 if (part_id == FILESYSTEM3_PART_ID)
1178                         part_id = get_part_id("UBI");
1179                 else if (part_id == MODEM_PART_ID)
1180                         part_id = get_part_id("modem");
1181                 else if (part_id == KERNEL_PART_ID)
1182                         part_id = get_part_id("kernel");
1183                 else if (part_id == BOOT_PART_ID)
1184                         part_id = get_part_id("bootloader");
1185 #ifdef CONFIG_MIRAGE
1186                 if (part_id)
1187                         part_id--;
1188 #endif
1189                 printf("COMMAND_PARTITION_SYNC - Part%d\n", part_id);
1190
1191 #ifdef CONFIG_CMD_MTDPARTS
1192                 blocks = parts[part_id]->size / 1024 / 128;
1193 #endif
1194                 printf("COMMAND_PARTITION_SYNC - Part%d, %d blocks\n",
1195                                 part_id, blocks);
1196
1197                 send_ack(usbd, blocks);
1198                 return 1;
1199
1200         case COMMAND_WRITE_PART_0:
1201                 /* Do nothing */
1202                 printf("COMMAND_WRITE_PART_0\n");
1203                 return 1;
1204
1205         case COMMAND_WRITE_PART_1:
1206                 printf("COMMAND_WRITE_PART_BOOT\n");
1207                 part_id = get_part_id("bootloader");
1208                 img_type = IMG_BOOT;
1209                 break;
1210
1211         case COMMAND_WRITE_PART_2:
1212         case COMMAND_ERASE_PARAMETER:
1213                 printf("COMMAND_PARAMETER - not support!\n");
1214                 break;
1215
1216         case COMMAND_WRITE_PART_3:
1217                 printf("COMMAND_WRITE_KERNEL\n");
1218                 part_id = get_part_id("kernel");
1219                 img_type = IMG_KERNEL;
1220                 break;
1221
1222         case COMMAND_WRITE_PART_4:
1223                 printf("COMMAND_WRITE_ROOTFS\n");
1224                 part_id = get_part_id("Root");
1225                 img_type = IMG_FILESYSTEM;
1226                 ubi_update = arg;
1227                 break;
1228
1229         case COMMAND_WRITE_PART_5:
1230                 printf("COMMAND_WRITE_FACTORYFS\n");
1231                 part_id = get_part_id("Fact");
1232                 img_type = IMG_FILESYSTEM;
1233                 ubi_update = arg;
1234                 break;
1235
1236         case COMMAND_WRITE_PART_6:
1237                 printf("COMMAND_WRITE_DATAFS\n");
1238                 part_id = get_part_id("Data");
1239                 img_type = IMG_FILESYSTEM;
1240                 ubi_update = arg;
1241                 break;
1242
1243         case COMMAND_WRITE_PART_7:
1244                 printf("COMMAND_WRITE_UBI\n");
1245                 part_id = get_part_id("UBI");
1246                 img_type = IMG_FILESYSTEM;
1247                 ubi_update = 0;
1248                 /* someday, it will be deleted */
1249                 get_part_info();
1250                 break;
1251
1252         case COMMAND_WRITE_PART_8:
1253                 printf("COMMAND_WRITE_MODEM\n");
1254                 part_id = get_part_id("modem");
1255                 img_type = IMG_MODEM;
1256                 break;
1257
1258 #ifdef CONFIG_CMD_MMC
1259         case COMMAND_WRITE_PART_9:
1260                 printf("COMMAND_WRITE_MMC\n");
1261                 img_type = IMG_MMC;
1262                 mmc_part_write = arg;
1263                 break;
1264 #endif
1265
1266         case COMMAND_WRITE_IMG_0:
1267                 printf("COMMAND_WRITE_MBR\n");
1268                 img_type = IMG_MBR;
1269                 break;
1270
1271         case COMMAND_WRITE_IMG_1:
1272                 printf("COMMAND_WRITE_BOOTLOADER\n");
1273                 img_type = IMG_BOOTLOADER;
1274                 break;
1275
1276         case COMMAND_WRITE_IMG_2:
1277                 printf("COMMAND_WRITE_KERNEL\n");
1278                 img_type = IMG_KERNEL_V2;
1279                 part_id = 2;
1280                 break;
1281
1282         case COMMAND_WRITE_IMG_3:
1283                 printf("COMMAND_WRITE_MODEM\n");
1284                 img_type = IMG_MODEM_V2;
1285                 part_id = 2;
1286                 break;
1287
1288         case COMMAND_WRITE_IMG_4:
1289                 printf("COMMAND_WRITE_BOOT_PART\n");
1290                 part_id = 1;
1291                 img_type = IMG_V2;
1292                 break;
1293
1294         case COMMAND_WRITE_IMG_5:
1295                 printf("COMMAND_WRITE_SYSTEM_PART\n");
1296                 part_id = 2;
1297                 img_type = IMG_V2;
1298                 break;
1299
1300         case COMMAND_WRITE_IMG_6:
1301                 printf("COMMAND_WRITE_UMS_PART\n");
1302                 part_id = 4;
1303                 img_type = IMG_V2;
1304                 break;
1305
1306         case COMMAND_WRITE_UBI_INFO:
1307                 printf("COMMAND_WRITE_UBI_INFO\n");
1308
1309                 if (ubi_mode) {
1310 #ifdef CONFIG_CMD_UBI
1311                         part_id = arg-1;
1312                         sprintf(length, "0x%x", (uint)len);
1313                         ret = ubi_cmd(part_id, ramaddr, length, "begin");
1314                 } else {
1315 #endif
1316                         printf("Error: Not UBI mode\n");
1317                         ret = 1;
1318                 }
1319
1320                 /* Write image success -> Report status */
1321                 send_ack(usbd, ret);
1322
1323                 return !ret;
1324         /* Download complete -> reset */
1325         case COMMAND_RESET_PDA:
1326                 printf("\nDownload finished and Auto reset!\nWait........\n");
1327
1328                 /* Stop USB */
1329                 usbd->usb_stop();
1330
1331                 if (usbd->cpu_reset)
1332                         usbd->cpu_reset();
1333                 else
1334                         run_command("reset", 0);
1335
1336                 return 0;
1337
1338         /* Error */
1339         case COMMAND_RESET_USB:
1340                 printf("\nError is occured!(maybe previous step)->\
1341                                 Turn off and restart!\n");
1342
1343                 /* Stop USB */
1344                 usbd->usb_stop();
1345                 return -1;
1346
1347         case COMMAND_RAM_BOOT:
1348                 usbd->usb_stop();
1349                 boot_cmd(ramaddr);
1350                 return 0;
1351
1352         case COMMAND_RAMDISK_MODE:
1353                 printf("COMMAND_RAMDISK_MODE\n");
1354 #ifdef CONFIG_RAMDISK_ADDR
1355                 if (arg) {
1356                         down_ram_addr = usbd->ram_addr;
1357                 } else {
1358                         down_ram_addr = CONFIG_RAMDISK_ADDR;
1359                         run_command("run ramboot", 0);
1360                 }
1361 #endif
1362                 return 1;
1363
1364 #ifdef CONFIG_DOWN_PHONE
1365         case COMMAND_DOWN_PHONE:
1366                 printf("COMMAND_RESET_PHONE\n");
1367
1368                 usbd_phone_down();
1369
1370                 send_ack(usbd, STATUS_DONE);
1371                 return 1;
1372
1373         case COMMAND_CHANGE_USB:
1374                 printf("COMMAND_CHANGE_USB\n");
1375
1376                 /* Stop USB */
1377                 usbd->usb_stop();
1378
1379                 usbd_path_change();
1380
1381                 run_command("reset", 0);
1382                 return 0;
1383 #endif
1384         case COMMAND_CSA_CLEAR:
1385                 printf("COMMAND_CSA_CLEAR\n");
1386                 part_id = get_part_id("csa");
1387                 img_type = IMG_MODEM;
1388                 break;
1389
1390         case COMMAND_PROGRESS:
1391                 if (usbd->set_progress)
1392                         usbd->set_progress(arg);
1393                 return 1;
1394
1395         default:
1396                 printf("Error: Unknown command -> (%d)\n", (int)cmd);
1397                 return 1;
1398         }
1399
1400         if (img_type < IMG_V2)
1401                 ret = write_mtd_image(usbd, img_type, len, arg);
1402         else
1403                 ret = write_v2_image(usbd, img_type, len, arg);
1404
1405         if (ret < 0) {
1406                 send_ack(usbd, STATUS_ERROR);
1407                 return -1;
1408         } else if (ret) {
1409                 /* Retry this commad */
1410                 send_ack(usbd, STATUS_RETRY);
1411                 return 1;
1412         } else
1413                 send_ack(usbd, STATUS_DONE);
1414
1415         write_part++;
1416
1417         /* Reset write count for another image */
1418         if (flag) {
1419                 write_part = 0;
1420                 fs_offset = 0;
1421         }
1422
1423         return 1;
1424 }
1425
1426 static const char *recv_key = "SAMSUNG";
1427 static const char *tx_key = "MPL";
1428
1429 int do_usbd_down(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
1430 {
1431         struct usbd_ops *usbd;
1432         int err;
1433         int ret;
1434
1435         if (argc > 1)
1436                 down_mode = simple_strtoul(argv[1], NULL, 10);
1437         else
1438                 down_mode = MODE_NORMAL;
1439
1440         printf("USB Downloader v%s\n", APP_VERSION);
1441
1442         /* get partition info */
1443         err = get_part_info();
1444         if (err)
1445                 return err;
1446
1447         /* interface setting */
1448         usbd = usbd_set_interface(&usbd_ops);
1449         down_ram_addr = usbd->ram_addr;
1450
1451 #ifdef CONFIG_CMD_MBR
1452         /* get mbr info */
1453         mbr_parts = get_mbr_table(mbr_offset);
1454         if (!mbr_parts) {
1455                 char *mbrparts;
1456
1457                 puts("using default MBR\n");
1458
1459                 mbrparts = getenv("mbrparts");
1460                 set_mbr_info(usbd, mbrparts, strlen(mbrparts));
1461         }
1462 #endif
1463
1464         /* init the usb controller */
1465         if (!usbd->usb_init()) {
1466                 usbd->down_cancel(END_BOOT);
1467                 return 0;
1468         }
1469         mmc = find_mmc_device(usbd->mmc_dev);
1470         mmc_init(mmc);
1471
1472         /* receive setting */
1473         usbd->recv_setup(usbd->rx_data, usbd->rx_len);
1474
1475         /* detect the download request from Host PC */
1476         ret = usbd->recv_data();
1477         if (ret > 0) {
1478                 if (strncmp(usbd->rx_data, recv_key, strlen(recv_key)) == 0) {
1479                         printf("Download request from the Host PC\n");
1480                         msleep(30);
1481
1482                         strcpy(usbd->tx_data, tx_key);
1483                         usbd->send_data(usbd->tx_data, usbd->tx_len);
1484                 } else {
1485                         printf("No download request from the Host PC!! 1\n");
1486                         return 0;
1487                 }
1488         } else if (ret < 0) {
1489                 usbd->down_cancel(END_RETRY);
1490                 return 0;
1491         } else {
1492                 usbd->down_cancel(END_BOOT);
1493                 return 0;
1494         }
1495
1496         usbd->down_start();
1497         printf("Receive the packet\n");
1498
1499         /* receive the data from Host PC */
1500         while (1) {
1501                 usbd->recv_setup(usbd->rx_data, usbd->rx_len);
1502
1503                 ret = usbd->recv_data();
1504                 if (ret > 0) {
1505                         ret = process_data(usbd);
1506                         if (ret < 0) {
1507                                 usbd->down_cancel(END_RETRY);
1508                                 return 0;
1509                         } else if (ret == 0) {
1510                                 usbd->down_cancel(END_NORMAL);
1511                                 return 0;
1512                         }
1513                 } else if (ret < 0) {
1514                         usbd->down_cancel(END_RETRY);
1515                         return 0;
1516                 } else {
1517                         usbd->down_cancel(END_BOOT);
1518                         return 0;
1519                 }
1520         }
1521
1522         return 0;
1523 }
1524
1525 U_BOOT_CMD(usbdown, CONFIG_SYS_MAXARGS, 1, do_usbd_down,
1526         "Initialize USB device and Run USB Downloader (specific)",
1527         "- normal mode\n"
1528         "usbdown mode - specific mode (0: NORAML, 1: FORCE)"
1529 );