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