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