2 * USB Downloader for SAMSUNG Platform
4 * Copyright (C) 2007-2008 Samsung Electronics
5 * Minkyu Kang <mk7.kang@samsung.com>
11 #include <asm/errno.h>
14 /* version of USB Downloader Application */
15 #define APP_VERSION "1.6.0"
20 #ifdef CONFIG_CMD_MTDPARTS
21 #include <jffs2/load_kernel.h>
22 static struct part_info *parts[16];
25 #ifdef CONFIG_UBIFS_MK
26 #include <mkfs.ubifs.h>
35 static const char pszMe[] = "usbd: ";
37 static struct usbd_ops usbd_ops;
39 static unsigned int part_id;
40 static unsigned int write_part = 0;
41 static unsigned int fs_offset = 0x0;
43 #define NAND_PAGE_SIZE 2048
45 static unsigned long down_ram_addr;
49 /* cpu/${CPU} dependent */
50 extern void do_reset(void);
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[]);
56 int mtdparts_init(void);
57 int find_dev_and_part(const char*, struct mtd_device**, u8*, struct part_info**);
59 /* common/cmd_jffs2.c */
60 extern struct list_head devices;
62 static u8 count_mtdparts(void)
64 struct list_head *dentry, *pentry;
65 struct mtd_device *dev;
68 list_for_each(dentry, &devices) {
69 dev = list_entry(dentry, struct mtd_device, link);
71 /* list partitions for given device */
72 list_for_each(pentry, &dev->parts)
80 static int check_ubi_mode(void)
85 env_ubifs = getenv("ubi");
86 ubi_mode = !strcmp(env_ubifs, "enabled");
91 #define check_ubi_mode() 0
94 #ifdef CONFIG_MTD_PARTITIONS
95 static int get_part_info(void)
97 struct mtd_device *dev;
105 #if defined(CONFIG_CMD_NAND)
106 sprintf(nand_name, "nand0");
107 #elif defined(CONFIG_CMD_ONENAND)
108 sprintf(nand_name, "onenand0");
110 printf("Configure your NAND sub-system\n");
117 ubi_mode = check_ubi_mode();
119 part_num = count_mtdparts();
120 for (i = 0; i < part_num; i++) {
121 sprintf(part_name, "%s,%d", nand_name, i);
123 if (find_dev_and_part(part_name, &dev, &out_partnum, &parts[i]))
130 static int get_part_id(char *name)
132 int nparts = count_mtdparts();
135 for (i = 0; i < nparts; i++) {
136 if (strcmp(parts[i]->name, name) == 0)
140 printf("Error: Unknown partition -> %s\n", name);
144 static int get_part_info(void)
146 printf("Error: Can't get patition information\n");
150 static int get_part_id(char *name)
156 static void boot_cmd(char *addr)
158 char *argv[] = { "bootm", addr };
159 do_bootm(NULL, 0, 2, argv);
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[]);
168 /* NAND erase and write using nand command */
169 static int nand_cmd(int type, char *p1, char *p2, char *p3)
173 int (*nand_func) (cmd_tbl_t *, int, int, char **);
175 #if defined(CONFIG_CMD_NAND)
176 sprintf(nand_name, "nand");
178 #elif defined(CONFIG_CMD_ONENAND)
179 sprintf(nand_name, "onenand");
180 nand_func = do_onenand;
182 printf("Configure your NAND sub-system\n");
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],
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],
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);
207 printf("Error: NAND Command\n");
212 #ifdef CONFIG_CMD_UBI
213 int do_ubi(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
215 int ubi_cmd(int part, char *p1, char *p2, char *p3)
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);
240 #ifdef CONFIG_CMD_MMC
244 static struct mmc *mmc;
246 static int mmc_cmd(int ops, int dev_num, ulong start, lbaint_t cnt, void *addr)
251 printf("mmc write 0x%x 0x%x\n", start, cnt);
252 ret = mmc->block_dev.block_write(dev_num, start, cnt, addr);
254 printf("mmc read 0x%x 0x%x\n", start, cnt);
255 ret = mmc->block_dev.block_read(dev_num, start, cnt, addr);
266 #define NORMAL_PARTITION 0
267 #define EXTEND_PARTITION 1
269 #define EXTEND_PART_TYPE 5
271 #define EXTEND_MAX_PART 32
273 static unsigned int cur_blk_offset;
274 static unsigned int cur_part_size;
275 static unsigned int cur_part;
277 static unsigned int mmc_parts;
278 static unsigned int mmc_part_write;
280 static u8 part_mode = 0;
282 struct partition_info {
286 } __attribute__((packed));
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));
294 struct mul_partition_info {
295 u32 lba_begin; /* absolute address from 0 block */
297 } __attribute__((packed));
299 #define MBR_OFFSET 0x10
301 struct partition_header part_info;
303 struct mul_partition_info mul_info[EXTEND_MAX_PART];
305 static int write_mmc_partition(struct usbd_ops *usbd, u32 *ram_addr, u32 len)
313 if (cur_part_size > len) {
314 blocks = len / usbd->mmc_blk;
317 blocks = cur_part_size / usbd->mmc_blk;
318 ret = len - cur_part_size;
321 if (len % usbd->mmc_blk)
324 loop = blocks / usbd->mmc_max;
325 if (blocks % usbd->mmc_max)
328 for (i = 0; i < loop; i++) {
330 cnt = blocks % usbd->mmc_max;
337 mmc_cmd(OPS_WRITE, usbd->mmc_dev, cur_blk_offset,
338 cnt, (void *)*ram_addr);
340 cur_blk_offset += cnt;
342 *ram_addr += (cnt * usbd->mmc_blk);
348 static int write_file_mmc(struct usbd_ops *usbd, u32 len)
355 if (!usbd->mmc_total) {
356 printf("MMC is not supported!\n");
360 ram_addr = (u32)down_ram_addr;
362 if (cur_blk_offset == 0) {
366 memcpy(&part_info, (void *)ram_addr,
367 sizeof(struct partition_header));
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;
374 if (mbr->parts[0].partition_type != EXTEND_PART_TYPE) {
375 part_mode = NORMAL_PARTITION;
377 /* modify sectors of p1 */
378 mbr->parts[0].nsectors = usbd->mmc_total -
380 mbr->parts[1].nsectors +
381 mbr->parts[2].nsectors +
382 mbr->parts[3].nsectors);
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)
393 mbr->parts[i - 1].lba +
394 mbr->parts[i - 1].nsectors;
398 memcpy(&mbr_info, mbr, sizeof(struct mbr));
400 printf("Total Size: 0x%08x #parts %d\n",
401 (unsigned int)usbd->mmc_total,
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);
410 mmc_cmd(OPS_WRITE, usbd->mmc_dev, 0,
411 mbr_blk_size, (void *)ram_addr);
413 ram_addr += mbr_blk_size * usbd->mmc_blk;
414 len -= mbr_blk_size * usbd->mmc_blk;
416 cur_blk_offset = mbr_blk_size;
418 cur_part_size = part_info.partition[0].size;
420 /* modify p1's total sector */
421 bs = (boot_sector *)ram_addr;
422 bs->total_sect = mbr_info.parts[0].nsectors;
424 printf("\nWrite Partition %d.. %d blocks\n",
426 part_info.partition[cur_part].size /
429 part_mode = EXTEND_PARTITION;
431 for (i = 0; i < EXTEND_MAX_PART; i++) {
432 if (part_info.partition[i].size == 0)
440 printf("found %d partitions\n", mmc_parts);
442 /* build partition table */
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 */
452 for (i = 1; i < mmc_parts; i++) {
453 mul_info[0].num_sectors -=
454 mul_info[i].num_sectors;
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;
464 /* modify MBR of extended partition: p1 */
465 mbr->parts[0].nsectors =
466 usbd->mmc_total - mbr_blk_size;
468 /* modify MBR of first logical partition: p5 */
470 (ram_addr + mbr_blk_size * usbd->mmc_blk);
472 mbr->parts[0].nsectors =
473 mul_info[0].num_sectors - mbr_blk_size;
475 mul_info[1].lba_begin - mbr_blk_size;
477 /* modify BPB data of p5 */
479 ((u32)mbr + mbr_blk_size * usbd->mmc_blk);
480 memset(&bs->sectors, 0, 2);
481 bs->total_sect = mbr->parts[0].nsectors;
483 printf("Total Size: 0x%08x #parts %d\n",
484 (unsigned int)usbd->mmc_total,
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);
494 cur_part_size = part_info.partition[0].size;
496 printf("\nWrite Partition %d.. %d blocks\n",
498 part_info.partition[cur_part].size /
503 for (i = cur_part; i < mmc_parts; i++) {
504 ret = write_mmc_partition(usbd, &ram_addr, len);
507 cur_part_size -= len;
512 part_info.partition[cur_part].size;
514 if (part_mode == NORMAL_PARTITION) {
516 mbr_info.parts[cur_part].lba;
519 mul_info[cur_part].lba_begin;
521 if (cur_part < mmc_parts) {
522 mbr = (struct mbr *)ram_addr;
524 mul_info[cur_part+1].lba_begin -
534 printf("\nWrite Partition %d.. %d blocks\n",
536 part_info.partition[cur_part].size /
544 static int write_file_mmc_part(struct usbd_ops *usbd, u32 len)
552 ram_addr = (u32)down_ram_addr;
555 if (cur_blk_offset == 0) {
557 mmc_cmd(OPS_READ, usbd->mmc_dev, 0,
558 sizeof(struct mbr)/usbd->mmc_blk, (void *)mbr);
560 mbr_blk_size = mbr->parts[0].lba;
562 if (mbr->parts[0].partition_type != EXTEND_PART_TYPE) {
563 part_mode = NORMAL_PARTITION;
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);
572 mbr->parts[mmc_part_write - 1].lba;
573 cur_part = mmc_part_write - 1;
576 mbr->parts[mmc_part_write - 1].nsectors;
578 if (mmc_part_write == 1) {
579 ram_addr += sizeof(struct mbr);
580 cur_blk_offset += sizeof(struct mbr) /
582 len -= sizeof(struct mbr);
585 part_mode = EXTEND_PARTITION;
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),
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);
600 ofs += mbr_blk_size; /* skip MBR */
601 cur_blk_offset = ofs;
602 cur_part = mmc_part_write - 1;
605 mbr->parts[1].nsectors;
607 if (mmc_part_write == 1) {
610 /* modify BPB data of p1 */
611 mmc_cmd(OPS_READ, usbd->mmc_dev, cur_blk_offset,
612 (sizeof(struct mbr) / usbd->mmc_blk),
615 bs = (boot_sector *)mbr;
616 total_sect = bs->total_sect;
618 bs = (boot_sector *)ram_addr;
619 memset(&bs->sectors, 0, 2);
620 bs->total_sect = total_sect;
625 printf("\nWrite Partition %d.. %d blocks\n",
627 len / (int)usbd->mmc_blk);
629 write_mmc_partition(usbd, &ram_addr, len);
635 static unsigned int mbr_offset[16];
636 static int mbr_parts = 0;
638 static unsigned long memsize_parse (const char *const ptr, const char **retptr)
640 unsigned long ret = simple_strtoul(ptr, (char **)retptr, 0);
660 static void set_mbr_info(struct usbd_ops *usbd, char *ramaddr, u32 len)
666 unsigned int size[16];
669 strncpy(mbr_str, ramaddr, len);
672 for (i = 0; ; i++, p = NULL) {
673 tok = strtok(p, ",");
676 strcpy(save[i], tok);
677 printf("part%d: %s\n", i, save[i]);
681 printf("find %d partitions\n", mbr_parts);
683 for (i = 0; i < mbr_parts; i++) {
685 size[i] = memsize_parse(p, (const char **)&p) / 512;
688 puts("save the MBR Table...\n");
689 set_mbr_table(0x800, mbr_parts, size, mbr_offset);
692 static int write_mmc_image(struct usbd_ops *usbd, unsigned int len, int part_num)
696 if (mbr_parts <= part_num) {
697 printf("Error: MBR table have %d partitions (request %d)\n",
698 mbr_parts, part_num);
703 /* modify size of UMS partition */
704 if (part_num == 4 && fs_offset == 0) {
706 bs = (boot_sector *)down_ram_addr;
707 memset(&bs->sectors, 0, 2);
708 bs->total_sect = usbd->mmc_total - mbr_offset[part_num];
711 ret = mmc_cmd(OPS_WRITE, usbd->mmc_dev,
712 mbr_offset[part_num] + fs_offset,
714 (void *)down_ram_addr);
716 fs_offset += (len / usbd->mmc_blk);
721 static int write_fat_file(struct usbd_ops *usbd, char *file_name,
722 int part_id, int len)
724 #ifdef CONFIG_FAT_WRITE
727 ret = fat_register_device(&mmc->block_dev, part_id);
729 printf("error : fat_register_divce\n");
733 ret = file_fat_write(file_name, (void *)down_ram_addr, len);
735 printf("error : writing uImage\n");
739 printf("error: doesn't support fat_write\n");
745 static int ubi_update = 0;
747 static int write_file_system(char *ramaddr, ulong len, char *offset,
748 char *length, int part_num)
752 #ifdef CONFIG_CMD_UBI
755 sprintf(length, "0x%x", (uint)len);
756 ret = ubi_cmd(part_id, ramaddr, length, "cont");
761 /* Erase entire partition at the first writing */
762 if (write_part == 0 && ubi_update == 0) {
763 sprintf(offset, "0x%x", (uint)parts[part_num]->offset);
764 sprintf(length, "0x%x", (uint)parts[part_num]->size);
765 nand_cmd(0, offset, length, NULL);
768 sprintf(offset, "0x%x", (uint)(parts[part_num]->offset + fs_offset));
769 sprintf(length, "0x%x", (uint)len);
772 ret = nand_cmd(1, ramaddr, offset, length);
777 static int qboot_erase = 0;
779 /* Erase the qboot */
780 static void erase_qboot_area(void)
782 char offset[12], length[12];
788 qboot_id = get_part_id("qboot");
790 if (qboot_id != -1) {
791 printf("\nCOMMAND_ERASE_QBOOT\n");
792 sprintf(offset, "%x", parts[qboot_id]->offset);
793 sprintf(length, "%x", parts[qboot_id]->size);
794 nand_cmd(0, offset, length, NULL);
799 /* Erase the environment */
800 static void erase_env_area(struct usbd_ops *usbd)
802 #if defined(CONFIG_ENV_IS_IN_NAND) || defined(CONFIG_ENV_IS_IN_ONENAND)
804 char offset[12], length[12];
806 param_id = get_part_id("params");
808 if (param_id == -1) {
809 sprintf(offset, "%x", CONFIG_ENV_ADDR);
810 sprintf(length, "%x", CONFIG_ENV_SIZE);
812 sprintf(offset, "%x", parts[param_id]->offset);
813 sprintf(length, "%x", parts[param_id]->size);
815 nand_cmd(0, offset, length, NULL);
816 #elif defined(CONFIG_ENV_IS_IN_MMC)
817 char buf[usbd->mmc_blk];
819 memset(buf, 0x0, usbd->mmc_blk);
820 mmc_cmd(OPS_WRITE, CONFIG_SYS_MMC_ENV_DEV,
821 CONFIG_ENV_OFFSET / usbd->mmc_blk,
826 static inline void send_ack(struct usbd_ops *usbd, int data)
828 *((ulong *) usbd->tx_data) = data;
829 usbd->send_data(usbd->tx_data, usbd->tx_len);
832 static inline int check_mmc_device(struct usbd_ops *usbd)
837 printf("\nError: Couldn't find the MMC device\n");
841 static int write_mtd_image(struct usbd_ops *usbd, int img_type,
842 unsigned int len, unsigned int arg)
844 unsigned int ofs = 0;
845 char offset[12], length[12], ramaddr[12];
848 sprintf(ramaddr, "0x%x", (uint) down_ram_addr);
850 /* Erase and Write to NAND */
853 ofs = parts[part_id]->offset;
854 #ifdef CONFIG_S5PC1XX
855 /* Workaround: for prevent revision mismatch */
856 if (cpu_is_s5pc110() && (down_mode != MODE_FORCE)) {
858 long *img_header = (long *)down_ram_addr;
860 if (*img_header == 0xea000012)
862 else if (*(img_header + 0x400) == 0xea000012)
865 if (img_rev != s5p_get_cpu_rev()) {
866 printf("CPU revision mismatch!\n"
867 "bootloader is %s%s\n"
868 "download image is %s%s\n",
869 s5p_get_cpu_rev() ? "EVT1" : "EVT0",
870 s5p_get_cpu_rev() == 2 ? "-Fused" : "",
871 img_rev ? "EVT1" : "EVT0",
872 img_rev == 2 ? "-Fused" : "");
878 /* Only u-boot.bin is allowed */
880 long *img_header = (long *)down_ram_addr;
882 if (*img_header != 0xea000018) {
883 printf("\n!!! ERROR !!!\n"
884 "Please download the u-boot.bin.\n"
885 "Other images are not allowed.\n\n");
891 erase_env_area(usbd);
893 sprintf(offset, "%x", (uint)ofs);
895 sprintf(length, "%x", parts[part_id]->size - (uint)ofs);
897 sprintf(length, "%x", parts[part_id]->size);
900 nand_cmd(0, offset, length, NULL);
902 sprintf(length, "%x", (unsigned int) len);
903 ret = nand_cmd(1, ramaddr, offset, length);
907 sprintf(offset, "%x", parts[part_id]->offset);
908 sprintf(length, "%x", parts[part_id]->size);
911 nand_cmd(0, offset, length, NULL);
913 sprintf(length, "%x", (unsigned int) len);
914 ret = nand_cmd(1, ramaddr, offset, length);
921 ret = write_file_system(ramaddr, len, offset, length, part_id);
927 sprintf(offset, "%x", parts[part_id]->offset);
928 sprintf(length, "%x", parts[part_id]->size);
932 nand_cmd(0, offset, length, NULL);
934 printf("CSA Clear will be skipped temporary\n");
936 /* Check ubi image, 0x23494255 is UBI# */
938 long *img_header = (long *)down_ram_addr;
940 if (*img_header == 0x23494255)
944 #ifdef CONFIG_UBIFS_MK
945 void *dest_addr = (void *) down_ram_addr + 0xc00000;
946 void *src_addr = (void *) down_ram_addr;
947 int leb_size, max_leb_cnt, mkfs_min_io_size;
948 unsigned long ubifs_dest_size, ubi_dest_size;
949 #ifdef CONFIG_S5PC110
950 mkfs_min_io_size = 4096;
951 leb_size = 248 * 1024;
954 mkfs_min_io_size = 2048;
955 leb_size = 126 * 1024;
958 printf("Start making ubifs\n");
959 ret = mkfs(src_addr, len, dest_addr, &ubifs_dest_size,
960 mkfs_min_io_size, leb_size, max_leb_cnt);
962 printf("Error : making ubifs failed\n");
965 printf("Complete making ubifs\n");
968 #ifdef CONFIG_UBINIZE
969 int peb_size, ubi_min_io_size, subpage_size, vid_hdr_offs;
970 #ifdef CONFIG_S5PC110
971 ubi_min_io_size = 4096;
972 peb_size = 256 * 1024;
976 ubi_min_io_size = 2048;
977 peb_size = 128 * 1024;
981 printf("Start ubinizing\n");
982 ret = ubinize(dest_addr, ubifs_dest_size,
983 src_addr, &ubi_dest_size,
984 peb_size, ubi_min_io_size,
985 subpage_size, vid_hdr_offs);
987 printf("Error : ubinizing failed\n");
990 printf("Complete ubinizing\n");
992 len = (unsigned int) ubi_dest_size;
996 /* Write : arg (0 Modem) / (1 CSA) */
998 sprintf(length, "%x", (unsigned int) len);
999 ret = nand_cmd(1, ramaddr, offset, length);
1004 #ifdef CONFIG_CMD_MMC
1006 if (check_mmc_device(usbd))
1010 ret = write_file_mmc_part(usbd, len);
1012 ret = write_file_mmc(usbd, len);
1025 static int write_v2_image(struct usbd_ops *usbd, int img_type,
1026 unsigned int len, unsigned int arg)
1030 if (check_mmc_device(usbd))
1035 ret = write_mmc_image(usbd, len, part_id);
1039 #ifdef CONFIG_CMD_MBR
1040 set_mbr_info(usbd, (char *)down_ram_addr, len);
1044 case IMG_BOOTLOADER:
1045 #ifdef CONFIG_BOOTLOADER_SECTOR
1046 erase_env_area(usbd);
1048 ret = mmc_cmd(OPS_WRITE, usbd->mmc_dev,
1049 CONFIG_BOOTLOADER_SECTOR,
1050 len / usbd->mmc_blk + 1,
1051 (void *)down_ram_addr);
1056 ret = write_fat_file(usbd, "uImage", part_id, len);
1060 ret = write_fat_file(usbd, "modem.bin", part_id, len);
1071 /* Parsing received data packet and Process data */
1072 static int process_data(struct usbd_ops *usbd)
1074 unsigned int cmd = 0, arg = 0, len = 0, flag = 0;
1077 unsigned int blocks = 0;
1082 sprintf(ramaddr, "0x%x", (uint) down_ram_addr);
1085 cmd = *((ulong *) usbd->rx_data + 0);
1086 arg = *((ulong *) usbd->rx_data + 1);
1087 len = *((ulong *) usbd->rx_data + 2);
1088 flag = *((ulong *) usbd->rx_data + 3);
1090 /* Reset tx buffer */
1091 memset(usbd->tx_data, 0, sizeof(usbd->tx_data));
1093 ubi_mode = check_ubi_mode();
1096 case COMMAND_DOWNLOAD_IMAGE:
1097 printf("\nCOMMAND_DOWNLOAD_IMAGE\n");
1100 down_ram_addr = usbd->ram_addr + 0x1000000;
1102 down_ram_addr = usbd->ram_addr;
1104 usbd->recv_setup((char *)down_ram_addr, (int)len);
1105 printf("Download to 0x%08x, %d bytes\n",
1106 (uint)down_ram_addr, (int)len);
1109 send_ack(usbd, STATUS_DONE);
1111 /* Receive image by using dma */
1112 recvlen = usbd->recv_data();
1114 send_ack(usbd, STATUS_ERROR);
1116 } else if (recvlen < len) {
1117 printf("Error: wrong image size -> %d/%d\n",
1118 (int)recvlen, (int)len);
1120 /* Retry this commad */
1121 send_ack(usbd, STATUS_RETRY);
1123 send_ack(usbd, STATUS_DONE);
1127 case COMMAND_DOWNLOAD_SPMODE:
1128 printf("\nCOMMAND_DOWNLOAD_SPMODE\n");
1130 down_ram_addr = usbd->ram_addr + 0x2008000;
1132 usbd->recv_setup((char *)down_ram_addr, (int)len);
1133 printf("Download to 0x%08x, %d bytes\n",
1134 (uint)down_ram_addr, (int)len);
1137 send_ack(usbd, STATUS_DONE);
1139 /* Receive image by using dma */
1140 recvlen = usbd->recv_data();
1141 send_ack(usbd, STATUS_DONE);
1145 /* Report partition info */
1146 case COMMAND_PARTITION_SYNC:
1149 #ifdef CONFIG_CMD_UBI
1151 if (part_id == RAMDISK_PART_ID ||
1152 part_id == FILESYSTEM_PART_ID ||
1153 part_id == FILESYSTEM2_PART_ID) {
1154 /* change to yaffs style */
1158 if (part_id == FILESYSTEM3_PART_ID) {
1159 /* change ubi style */
1165 if (part_id == FILESYSTEM3_PART_ID)
1166 part_id = get_part_id("UBI");
1167 else if (part_id == MODEM_PART_ID)
1168 part_id = get_part_id("modem");
1169 else if (part_id == KERNEL_PART_ID)
1170 part_id = get_part_id("kernel");
1171 else if (part_id == BOOT_PART_ID)
1172 part_id = get_part_id("bootloader");
1173 #ifdef CONFIG_MIRAGE
1177 printf("COMMAND_PARTITION_SYNC - Part%d\n", part_id);
1179 blocks = parts[part_id]->size / 1024 / 128;
1180 printf("COMMAND_PARTITION_SYNC - Part%d, %d blocks\n",
1183 send_ack(usbd, blocks);
1186 case COMMAND_WRITE_PART_0:
1188 printf("COMMAND_WRITE_PART_0\n");
1191 case COMMAND_WRITE_PART_1:
1192 printf("COMMAND_WRITE_PART_BOOT\n");
1193 part_id = get_part_id("bootloader");
1194 img_type = IMG_BOOT;
1197 case COMMAND_WRITE_PART_2:
1198 case COMMAND_ERASE_PARAMETER:
1199 printf("COMMAND_PARAMETER - not support!\n");
1202 case COMMAND_WRITE_PART_3:
1203 printf("COMMAND_WRITE_KERNEL\n");
1204 part_id = get_part_id("kernel");
1205 img_type = IMG_KERNEL;
1208 case COMMAND_WRITE_PART_4:
1209 printf("COMMAND_WRITE_ROOTFS\n");
1210 part_id = get_part_id("Root");
1211 img_type = IMG_FILESYSTEM;
1215 case COMMAND_WRITE_PART_5:
1216 printf("COMMAND_WRITE_FACTORYFS\n");
1217 part_id = get_part_id("Fact");
1218 img_type = IMG_FILESYSTEM;
1222 case COMMAND_WRITE_PART_6:
1223 printf("COMMAND_WRITE_DATAFS\n");
1224 part_id = get_part_id("Data");
1225 img_type = IMG_FILESYSTEM;
1229 case COMMAND_WRITE_PART_7:
1230 printf("COMMAND_WRITE_UBI\n");
1231 part_id = get_part_id("UBI");
1232 img_type = IMG_FILESYSTEM;
1234 /* someday, it will be deleted */
1238 case COMMAND_WRITE_PART_8:
1239 printf("COMMAND_WRITE_MODEM\n");
1240 part_id = get_part_id("modem");
1241 img_type = IMG_MODEM;
1244 #ifdef CONFIG_CMD_MMC
1245 case COMMAND_WRITE_PART_9:
1246 printf("COMMAND_WRITE_MMC\n");
1248 mmc_part_write = arg;
1252 case COMMAND_WRITE_IMG_0:
1253 printf("COMMAND_WRITE_MBR\n");
1257 case COMMAND_WRITE_IMG_1:
1258 printf("COMMAND_WRITE_BOOTLOADER\n");
1259 img_type = IMG_BOOTLOADER;
1262 case COMMAND_WRITE_IMG_2:
1263 printf("COMMAND_WRITE_KERNEL\n");
1264 img_type = IMG_KERNEL_V2;
1268 case COMMAND_WRITE_IMG_3:
1269 printf("COMMAND_WRITE_MODEM\n");
1270 img_type = IMG_MODEM_V2;
1274 case COMMAND_WRITE_IMG_4:
1275 printf("COMMAND_WRITE_BOOT_PART\n");
1280 case COMMAND_WRITE_IMG_5:
1281 printf("COMMAND_WRITE_SYSTEM_PART\n");
1286 case COMMAND_WRITE_IMG_6:
1287 printf("COMMAND_WRITE_UMS_PART\n");
1292 case COMMAND_WRITE_UBI_INFO:
1293 printf("COMMAND_WRITE_UBI_INFO\n");
1296 #ifdef CONFIG_CMD_UBI
1298 sprintf(length, "0x%x", (uint)len);
1299 ret = ubi_cmd(part_id, ramaddr, length, "begin");
1302 printf("Error: Not UBI mode\n");
1306 /* Write image success -> Report status */
1307 send_ack(usbd, ret);
1310 /* Download complete -> reset */
1311 case COMMAND_RESET_PDA:
1312 printf("\nDownload finished and Auto reset!\nWait........\n");
1317 if (usbd->cpu_reset)
1325 case COMMAND_RESET_USB:
1326 printf("\nError is occured!(maybe previous step)->\
1327 Turn off and restart!\n");
1333 case COMMAND_RAM_BOOT:
1338 case COMMAND_RAMDISK_MODE:
1339 printf("COMMAND_RAMDISK_MODE\n");
1340 #ifdef CONFIG_RAMDISK_ADDR
1342 down_ram_addr = usbd->ram_addr;
1344 down_ram_addr = CONFIG_RAMDISK_ADDR;
1345 run_command("run ramboot", 0);
1350 #ifdef CONFIG_DOWN_PHONE
1351 case COMMAND_DOWN_PHONE:
1352 printf("COMMAND_RESET_PHONE\n");
1356 send_ack(usbd, STATUS_DONE);
1359 case COMMAND_CHANGE_USB:
1360 printf("COMMAND_CHANGE_USB\n");
1370 case COMMAND_CSA_CLEAR:
1371 printf("COMMAND_CSA_CLEAR\n");
1372 part_id = get_part_id("csa");
1373 img_type = IMG_MODEM;
1376 case COMMAND_PROGRESS:
1377 if (usbd->set_progress)
1378 usbd->set_progress(arg);
1382 printf("Error: Unknown command -> (%d)\n", (int)cmd);
1386 if (img_type < IMG_V2)
1387 ret = write_mtd_image(usbd, img_type, len, arg);
1389 ret = write_v2_image(usbd, img_type, len, arg);
1392 send_ack(usbd, STATUS_ERROR);
1395 /* Retry this commad */
1396 send_ack(usbd, STATUS_RETRY);
1399 send_ack(usbd, STATUS_DONE);
1403 /* Reset write count for another image */
1412 static const char *recv_key = "SAMSUNG";
1413 static const char *tx_key = "MPL";
1415 int do_usbd_down(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
1417 struct usbd_ops *usbd;
1422 down_mode = simple_strtoul(argv[1], NULL, 10);
1424 down_mode = MODE_NORMAL;
1426 printf("USB Downloader v%s\n", APP_VERSION);
1428 /* get partition info */
1429 err = get_part_info();
1433 /* interface setting */
1434 usbd = usbd_set_interface(&usbd_ops);
1435 down_ram_addr = usbd->ram_addr;
1437 #ifdef CONFIG_CMD_MBR
1439 mbr_parts = get_mbr_table(mbr_offset);
1443 puts("using default MBR\n");
1445 mbrparts = getenv("mbrparts");
1446 set_mbr_info(usbd, mbrparts, strlen(mbrparts));
1450 /* init the usb controller */
1451 if (!usbd->usb_init()) {
1452 usbd->down_cancel(0);
1455 mmc = find_mmc_device(usbd->mmc_dev);
1458 /* receive setting */
1459 usbd->recv_setup(usbd->rx_data, usbd->rx_len);
1461 /* detect the download request from Host PC */
1462 ret = usbd->recv_data();
1464 if (strncmp(usbd->rx_data, recv_key, strlen(recv_key)) == 0) {
1465 printf("Download request from the Host PC\n");
1468 strcpy(usbd->tx_data, tx_key);
1469 usbd->send_data(usbd->tx_data, usbd->tx_len);
1471 printf("No download request from the Host PC!! 1\n");
1474 } else if (ret < 0) {
1475 usbd->down_cancel(1);
1478 usbd->down_cancel(0);
1483 printf("Receive the packet\n");
1485 /* receive the data from Host PC */
1487 usbd->recv_setup(usbd->rx_data, usbd->rx_len);
1489 ret = usbd->recv_data();
1491 if (process_data(usbd) == 0) {
1492 usbd->down_cancel(1);
1495 } else if (ret < 0) {
1496 usbd->down_cancel(1);
1499 usbd->down_cancel(0);
1507 U_BOOT_CMD(usbdown, CONFIG_SYS_MAXARGS, 1, do_usbd_down,
1508 "Initialize USB device and Run USB Downloader (specific)",
1510 "usbdown mode - specific mode (0: NORAML, 1: FORCE)"