1 #include <asm/arch/packet.h>
3 #include "parsemtdparts.h"
4 #include "asm/arch/nand_controller.h"
5 #include <linux/mtd/mtd.h>
6 #include <linux/mtd/ubi.h>
8 #include <linux/mtd/nand.h>
10 #include <ubi_uboot.h>
12 #include "fdl_common.h"
13 #include "fdl_nand_operate.h"
14 #ifdef CONFIG_SECURE_BOOT
15 #include "secure_verify.h"
24 char *name; //mtd partition name
25 unsigned long long size; //mtd part size
26 unsigned long long rw_point; //nand flash read/write offset point
30 struct ubi_device *dev;
33 struct ubi_volume_desc *cur_voldesc;
43 typedef struct fdl_download_status
46 dl_part_type part_type;
49 unsigned long total_dl_size; //size to be recvd
50 unsigned long recv_size; //recv size from tool
51 unsigned long unsv_size; //data unsaved in buf
52 char *buf; //buf for data received from tool
53 unsigned int bufsize; //max buf size
54 unsigned int rp; //read point of buf,no use now
55 unsigned int wp; //write point of buf
59 char name[UBI_VOL_NAME_MAX+1];
60 long long size;//size in byte
68 struct list_head list;
71 #define UBIFS_NODE_MAGIC 0x06101831
72 #define AUTO_RESIZE_FLAG 0xFFFFFFFF
73 #ifdef CONFIG_SECURE_BOOT
74 #define FDL_BUF_LEN (100*1024*1024)
76 #define FDL_BUF_LEN (1*1024*1024)
78 static dl_status_t dl_stat={0};
79 static char fdl_buf[FDL_BUF_LEN];
80 extern struct ubi_selected_dev cur_ubi;
81 static dl_nv_info_t s_nv_backup_cfg[]={
83 {"runtimenv1", "runtimenv2"},
84 {"tdfixnv1", "tdfixnv2"},
85 {"tdruntimenv1", "tdruntimenv2"},
86 {"wfixnv1", "wfixnv2"},
87 {"wruntimenv1", "wruntimenv2"},
88 {"wcnfixnv1", "wcnfixnv2"},
89 {"wcnruntimenv1", "wcnruntimenv2"},
93 #ifdef CONFIG_SECURE_BOOT
94 static int secure_image_flag = 0;
95 static int check_secure_flag = 0;
97 static char* const s_force_secure_check[]={
98 "spl","2ndbl","boot","recovery","tdmodem","tddsp","wmodem","wdsp","wcnmodem",NULL
101 static int _nand_check_secure_part(wchar_t *partition_name)
106 if(0 == strcmp(s_force_secure_check[i], partition_name))
109 }while(s_force_secure_check[i]!=0);
117 static __inline void _send_rsp(unsigned long err)
119 FDL_SendAckPacket(convert_err(err));
122 static struct mtd_info* _get_cur_nand(void)
124 if ((nand_curr_device < 0) || (nand_curr_device >= CONFIG_SYS_MAX_NAND_DEVICE))
126 printf("--->get current nand failed<---\n");
127 _send_rsp(NAND_UNKNOWN_DEVICE);
130 return &nand_info[nand_curr_device];
134 * check whether is a nv volume.
135 * return backup nv volume in case of true, otherwise null.
137 static char* _is_nv_volume(char *volume)
141 for(i=0; s_nv_backup_cfg[i].vol !=NULL; i++) {
142 if(0 == strcmp(volume, s_nv_backup_cfg[i].vol)) {
143 return s_nv_backup_cfg[i].bakvol;
150 * parse mtd partitions from a string.
152 static int _parse_mtd_partitions(void)
154 struct mtd_info *nand = NULL;
156 nand = _get_cur_nand();
159 parse_cmdline_partitions(nand->size);
164 * get mtd partition info from partition table parsed.
166 static int _get_mtd_partition_info(char *name, struct mtd_partition *part)
170 if(!_parse_mtd_partitions())
173 ret = parse_mtd_part_info(name, part);
181 * add volume info to change list.
183 static int _fdl2_add_to_list(char *name, long long size, int autoresize,
184 struct list_head *list)
186 fdl_ubi_cvol_t *cvol;
188 cvol = malloc(sizeof(fdl_ubi_cvol_t));
190 printf("%s: malloc failed.\n",__func__);
191 _send_rsp(NAND_SYSTEM_ERROR);
197 cvol->autoresize = autoresize;
198 list_add_tail(&cvol->list, list);
203 * parse volume table config, just compatible with dl tool.
205 static void _fdl2_parse_volume_cfg(unsigned short* vol_cfg, unsigned short total_num, fdl_ubi_vtbl_t *vtbl)
210 /*Decode String: Partition Name(72Byte)+SIZE(4Byte)+...*/
211 for(i=0;i<total_num;i++)
213 size = *(unsigned long *)(vol_cfg+38*(i+1)-2);
214 //the partition size received from tool is MByte.
215 if(AUTO_RESIZE_FLAG == size){
216 vtbl[i].size = 1024*1024;//just set size as 1M when autoresize flag enable
217 vtbl[i].autoresize = 1;
220 vtbl[i].size = 1024*1024*size;
224 //convert name wchar to char with violent
225 vtbl[i].name[j] = *(vol_cfg+38*i+j) & 0xFF;
228 printf("volume name:%s,size:0x%llx,autoresize flag:%d\n",vtbl[i].name,vtbl[i].size,vtbl[i].autoresize);
234 * update the nv volume with nv header.
236 static int _fdl2_update_nv(char *vol, char *bakvol, int size, char *data)
242 char tmp[NV_HEAD_LEN];
245 if(size>dl_stat.bufsize){
246 nvbuf = malloc(size+NV_HEAD_LEN);
248 printf("%s buf malloc failed.\n",__func__);
252 fdl_ubi_volume_read(dl_stat.ubi.dev, dl_stat.ubi.cur_volnm, buf, size, 0);
254 printf("%s read volume %s failed.\n",__func__,dl_stat.ubi.cur_volnm);
261 memset(tmp,0x0,NV_HEAD_LEN);
262 header = (nv_header_t *)tmp;
263 header->magic = NV_HEAD_MAGIC;
264 header->version = NV_VERSION;
266 header->checksum = fdl_calc_checksum(buf,size);
269 ret = fdl_ubi_volume_start_update(dl_stat.ubi.dev, curvol, size+NV_HEAD_LEN);
271 printf("%s: vol %s start update failed!\n",__func__,curvol);
274 ret = fdl_ubi_volume_write(dl_stat.ubi.dev, curvol, tmp, NV_HEAD_LEN);
276 printf("%s volume write error %d!\n",curvol,ret);
279 ret = fdl_ubi_volume_write(dl_stat.ubi.dev, curvol, buf, size);
281 printf("%s volume write error %d!\n",curvol,ret);
287 printf("update nv success!\n");
294 static int _fdl2_check_nv(char *vol)
296 char *buf = 0,*bakbuf = 0,*pbakvol = 0;
298 int ret = NAND_SYSTEM_ERROR;
299 int size = FIXNV_SIZE+NV_HEAD_LEN;
300 uint8 status_nand =0;
305 printf("%s buf malloc failed.\n",__func__);
308 ret = fdl_ubi_volume_read(dl_stat.ubi.dev,vol,buf,size,0);
310 printf("%s can read 0x%x data from vol %s ret %d!!\n",__func__,size,vol,ret);
313 header = (nv_header_t *)buf;
314 ret = fdl_check_crc(buf+NV_HEAD_LEN, header->len, header->checksum);
317 printf("%s org nv is ok.\n",__func__);
320 printf("%s org nv is damaged.\n",__func__);
325 bakbuf = malloc(size);
327 printf("%s bakbuf malloc failed.\n",__func__);
330 printf("%s bakbuf malloc succees.\n",__func__);
331 pbakvol=_is_nv_volume(vol);
335 ret = fdl_ubi_volume_read(dl_stat.ubi.dev, pbakvol,bakbuf,size,0);
337 printf("%s can read 0x%x data from bakup %s ret %d!!!\n",__func__,size,pbakvol,ret);
340 header = (nv_header_t *)bakbuf;
341 ret = fdl_check_crc(bakbuf+NV_HEAD_LEN, header->len, header->checksum);
344 printf("%s bak nv is ok.\n",__func__);
347 printf("%s bak nv is damaged.\n",__func__);
352 printf("%s both org and bak nv are damaged.\n",__func__);
356 printf("%s bak nv is damaged.\n",__func__);
357 fdl_ubi_volume_start_update(dl_stat.ubi.dev, pbakvol, size);
358 ret = fdl_ubi_volume_write(dl_stat.ubi.dev,pbakvol, buf, size);
360 printf("%s bak ubi volume write error %d!\n",__func__,ret);
366 printf("%s org nv is damaged.\n",__func__);
367 fdl_ubi_volume_start_update(dl_stat.ubi.dev, vol, size);
368 ret = fdl_ubi_volume_write(dl_stat.ubi.dev, vol, bakbuf, size);
370 printf("%s org ubi volume write error %d!\n",__func__,ret);
376 printf("%s both org and bak nv are ok.\n",__func__);
380 printf("%s: status_nand error!\n",__func__);
395 * check whether the new volumes table same with original.
396 * return 0 in case of diff and 1 in case of same.
398 static int _fdl2_vtbl_check(fdl_ubi_vtbl_t *vtbl, int total_vols, struct list_head *rm, struct list_head *mk)
403 struct ubi_volume *vol;
404 struct ubi_device *ubi = cur_ubi.dev;
406 if(!cur_ubi.ubi_initialized){
407 printf("%s:ubi init failed.\n",__FUNCTION__);
411 if(!(ubi->vol_count-UBI_INT_VOL_COUNT)){
412 printf("%s:empty ubi device.\n",__FUNCTION__);
416 if(total_vols != (ubi->vol_count-UBI_INT_VOL_COUNT)){
417 printf("%s:new vol count is %d,old vol count is %d.\n",
418 __FUNCTION__,total_vols,ubi->vol_count-UBI_INT_VOL_COUNT);
422 for(i=0;i<total_vols;i++){
424 for (j = 0; j < ubi->vtbl_slots; j++) {
425 vol = ubi->volumes[j];
426 if (vol && !strcmp(vol->name, vtbl[i].name)) {
427 printf("Volume \"%s\" found at volume id %d.\n", vtbl[i].name, j);
428 if(vtbl[i].autoresize){
429 //autoresize_vol_id flag will set -1 after ubi attach, so we can't get it.
434 uint64_t bytes = vtbl[i].size;
435 if (do_div(bytes, vol->usable_leb_size))
437 new_rsvd_pebs += bytes;
438 if(new_rsvd_pebs == vol->reserved_pebs)
441 printf("reserved pebs not same,new %d,old %d.\n",new_rsvd_pebs,vol->reserved_pebs);
443 printf("add volume \"%s\" to remove list.\n", vtbl[i].name);
444 _fdl2_add_to_list(vtbl[i].name,0,0,rm);
452 printf("add volume \"%s\" to create list.\n", vtbl[i].name);
453 _fdl2_add_to_list(vtbl[i].name,vtbl[i].size,vtbl[i].autoresize,mk);
457 for(i = 0; i < ubi->vtbl_slots; i++) {
459 vol = ubi->volumes[i];
462 printf("old volume slot: %d, name \"%s\"\n",i,vol->name);
463 for(j = 0; j < total_vols; j++) {
464 if(!strcmp(vol->name, vtbl[j].name)) {
471 printf("add volume \"%s\" to remove list.\n", vol->name);
472 _fdl2_add_to_list(vol->name,0,0,rm);
480 printf("add autoresize volume \"%s\" to rm/mk list.\n", vtbl[arid].name);
481 _fdl2_add_to_list(vtbl[arid].name,0,0,rm);
482 _fdl2_add_to_list(vtbl[arid].name,vtbl[arid].size,vtbl[arid].autoresize,mk);
488 * nand write and dl_stat update.
490 static void _fdl2_nand_write(nand_info_t *nand, unsigned long long offset, unsigned long length,
495 //printf("fdl_nand_write:offset:0x%llx,len:0x%x\n",offset,length);
497 //TODO:temp here for step 1 debug
498 if(strcmp(dl_stat.mtd.name, "spl")==0){
499 sprd_nand_write_spl(buffer, dl_stat.nand);
500 printf("write spl\n");
502 dl_stat.unsv_size =0;
506 switch(dl_stat.part_type){
508 ret = nand_write_skip_bad(nand, offset, &length, buffer);
509 dl_stat.unsv_size -= length;
510 memmove(dl_stat.buf, dl_stat.buf+length, dl_stat.unsv_size);
511 dl_stat.wp -= length;
512 dl_stat.mtd.rw_point += length;
514 //mark a block as badblock
515 printf("nand write error %d, mark bad block 0x%llx\n",ret,dl_stat.mtd.rw_point&~(nand->erasesize-1));
516 nand->block_markbad(nand,dl_stat.mtd.rw_point&~(nand->erasesize-1));
520 ret = fdl_ubi_volume_write(dl_stat.ubi.dev, dl_stat.ubi.cur_volnm, buffer, length);
522 printf("ubi volume write error %d!\n",ret);
523 _send_rsp(NAND_SYSTEM_ERROR);
525 dl_stat.unsv_size -= length;
526 memmove(dl_stat.buf, dl_stat.buf+length, dl_stat.unsv_size);
527 dl_stat.wp -= length;
530 printf("%s: part type error!\n",__FUNCTION__);
538 * erase the given mtd part.
539 * return 0 in case of success.
541 static int _fdl2_mtd_part_erase(char *name)
544 struct mtd_partition mtd_part;
545 nand_erase_options_t opts;
547 ret = _get_mtd_partition_info(name, &mtd_part);
549 memset(&opts, 0, sizeof(opts));
550 opts.offset = mtd_part.offset;
551 opts.length = mtd_part.size;
553 ret = nand_erase_opts(_get_cur_nand(), &opts);
556 printf("%s:nand erase %s failure %d\n",__FUNCTION__, name, ret);
558 printf("%s:Can't find part %s",__FUNCTION__,name);
563 * parse the given part is mtd partition or ubi volume.
565 static void _fdl2_part_info_parse(char *part)
568 struct mtd_partition mtd_part;
569 struct ubi_volume_desc *vol;
571 ret = _get_mtd_partition_info(part, &mtd_part);
573 dl_stat.mtd.name = part;
574 dl_stat.mtd.size = mtd_part.size;
575 dl_stat.mtd.rw_point = mtd_part.offset;
576 dl_stat.part_type = PART_TYPE_MTD;
580 vol = ubi_open_volume_nm(cur_ubi.dev_num, part, UBI_READWRITE);
582 printf("cannot open volume \"%s\", error %d\n",part, (int)PTR_ERR(vol));
584 dl_stat.ubi.dev = cur_ubi.dev;
585 dl_stat.ubi.dev_num = cur_ubi.dev_num;
586 dl_stat.ubi.cur_volnm = part;
587 dl_stat.ubi.cur_voldesc = vol;
588 dl_stat.part_type = PART_TYPE_UBI;
591 dl_stat.part_type = PART_TYPE_MAX;
592 printf("Can't find part %s.\n",part);
597 * fdl2_download_start
599 * Get download info from download start command which
600 * will used in next step
602 * @param part partition/volume name
603 * @param size total download size
604 * @param nv_checksum NA
608 int fdl2_download_start(char* name, unsigned long size, unsigned long nv_checksum)
613 #ifdef CONFIG_SECURE_BOOT
614 printf("fdl2_download_start(): check secure part. name:%s, size:%d.\n", name, size);
615 index = _nand_check_secure_part(name);
618 printf("fdl2_download_start(): the part should be checked. %s\n", name);
619 /*because there is no secure header flag in the spl image.*/
620 if (strcmp(name, "spl") == 0){
621 secure_image_flag = 1;
622 check_secure_flag = 0;
625 secure_image_flag = 0;
626 check_secure_flag = 1;
630 secure_image_flag = 0;
631 check_secure_flag = 0;
635 memset(&dl_stat, 0x0, sizeof(dl_status_t));
637 _fdl2_part_info_parse(name);
639 switch(dl_stat.part_type){
641 if(size > dl_stat.mtd.size){
642 printf("%s:dl size 0x%x > partition size 0x%llx\n",__FUNCTION__,size,dl_stat.mtd.size);
643 ret = NAND_INVALID_SIZE;
646 #ifdef CONFIG_SECURE_BOOT
647 if (!secure_image_flag && !check_secure_flag){
649 ret = _fdl2_mtd_part_erase(name);
651 printf("%s:mtd %d erase failed!\n",__FUNCTION__,name);
652 ret = NAND_SYSTEM_ERROR;
655 #ifdef CONFIG_SECURE_BOOT
661 if(size > dl_stat.ubi.cur_voldesc->vol->used_bytes){
662 printf("dl size > partition size!\n");
663 ret = NAND_INVALID_SIZE;
666 #ifdef CONFIG_SECURE_BOOT
667 if (!secure_image_flag && !check_secure_flag){
669 ret = fdl_ubi_volume_start_update(dl_stat.ubi.dev, name, size);
671 printf("%s: vol %s start update failed!\n",__FUNCTION__,name);
672 ret = NAND_SYSTEM_ERROR;
675 #ifdef CONFIG_SECURE_BOOT
681 ret = NAND_INCOMPATIBLE_PART;
685 dl_stat.nand = _get_cur_nand();
686 dl_stat.total_dl_size = size;
687 dl_stat.recv_size = 0;
688 dl_stat.unsv_size = 0;
689 dl_stat.buf = fdl_buf;
690 dl_stat.bufsize = FDL_BUF_LEN;
694 printf("fdl2_download_start:part:%s,size:0x%x\n",name,size);
696 _send_rsp(NAND_SUCCESS);
704 * fdl2_download_midst
706 * Save data to fdl buf and finally write it to nand flash
708 * @param size total download size
709 * @param buf data recvd
713 int fdl2_download_midst(unsigned short size, char *buf)
716 unsigned int cpy_len=0,unsv_len=0;
720 #ifdef CONFIG_SECURE_BOOT
721 if(check_secure_flag == 1)
723 check_secure_flag = 0;
724 if (secure_header_parser(buf) != 1)
726 secure_image_flag = 0;
727 _send_rsp(NAND_SYSTEM_ERROR);
731 secure_image_flag = 1;
735 if (secure_image_flag == 1){
736 dl_stat.recv_size += size;
738 memcpy(dl_stat.buf+dl_stat.wp, &buf[size-unsv_len], unsv_len);
739 dl_stat.wp += unsv_len;
740 dl_stat.unsv_size += unsv_len;
742 _send_rsp(NAND_SUCCESS);
748 dl_stat.recv_size += size;
750 while((dl_stat.unsv_size+unsv_len)> dl_stat.bufsize)
752 len = dl_stat.unsv_size;
753 len = len & ~(nand->erasesize - 1);
755 _fdl2_nand_write(nand, dl_stat.mtd.rw_point, len, dl_stat.buf);
757 cpy_len = dl_stat.bufsize - dl_stat.unsv_size;
758 cpy_len = (unsv_len>cpy_len)?cpy_len:unsv_len;
759 memcpy(dl_stat.buf+dl_stat.wp, &buf[size-unsv_len], cpy_len);
761 dl_stat.wp += cpy_len;
762 dl_stat.unsv_size += cpy_len;
765 //copy data to dl buf
766 memcpy(dl_stat.buf+dl_stat.wp, &buf[size-unsv_len], unsv_len);
767 dl_stat.wp += unsv_len;
768 dl_stat.unsv_size += unsv_len;
770 if(dl_stat.recv_size == dl_stat.total_dl_size){
771 len = dl_stat.unsv_size;
772 _fdl2_nand_write(nand, dl_stat.mtd.rw_point, len, dl_stat.buf);
775 _send_rsp(NAND_SUCCESS);
788 int fdl2_download_end(void)
793 int ret = NAND_SUCCESS;
795 #ifdef CONFIG_SECURE_BOOT
796 if (secure_image_flag){
797 if (dl_stat.part_type == PART_TYPE_MTD){
798 name = dl_stat.mtd.name;
800 else if (dl_stat.part_type == PART_TYPE_UBI){
801 name = dl_stat.ubi.cur_volnm;
804 _send_rsp(NAND_SYSTEM_ERROR);
808 if (strcmp(name, "spl") == 0){
809 secure_verify(L"splloader0", dl_stat.buf, 0);
811 else if (strcmp(name, "2ndbl") == 0){
812 secure_verify(L"splloader", dl_stat.buf, 0);
815 secure_verify(L"fdl2", dl_stat.buf, 0);
818 switch(dl_stat.part_type){
820 ret = _fdl2_mtd_part_erase(name);
822 printf("%s:mtd %d erase failed!\n",__FUNCTION__, name);
823 ret = NAND_SYSTEM_ERROR;
827 ret = fdl_ubi_volume_start_update(dl_stat.ubi.dev, name, dl_stat.total_dl_size);
829 printf("%s: vol %s start update failed!\n",__FUNCTION__, name);
830 ret = NAND_SYSTEM_ERROR;
836 if (ret != NAND_SUCCESS){
843 while(0 != dl_stat.unsv_size){
844 _fdl2_nand_write(dl_stat.nand, dl_stat.mtd.rw_point, dl_stat.unsv_size, dl_stat.buf);
846 printf("download end write error, try 2 times.\n");
847 _send_rsp(NAND_SYSTEM_ERROR);
851 //close opened ubi volume
852 if(PART_TYPE_UBI == dl_stat.part_type){
855 bakvol = _is_nv_volume(dl_stat.ubi.cur_volnm);
857 err = _fdl2_update_nv(dl_stat.ubi.cur_volnm,
859 dl_stat.total_dl_size,
862 ret = NAND_SYSTEM_ERROR;
864 ubi_close_volume(dl_stat.ubi.cur_voldesc);
867 #ifdef CONFIG_SECURE_BOOT
868 secure_image_flag = 0;
869 check_secure_flag = 0;
878 * Get partition/volume info from read start command which
879 * will used in next step
881 * @param part partition/volume name
882 * @param size total size
886 int fdl2_read_start(char* part, unsigned long size)
890 memset(&dl_stat, 0x0, sizeof(dl_status_t));
892 _fdl2_part_info_parse(part);
894 switch(dl_stat.part_type){
896 if(size > dl_stat.mtd.size){
897 printf("%s:read size 0x%x > partition size 0x%llx\n",__FUNCTION__,size,dl_stat.mtd.size);
898 ret = NAND_INVALID_SIZE;
903 if(size > dl_stat.ubi.cur_voldesc->vol->used_bytes){
904 printf("%s:read size 0x%x > partition size 0x%llx\n",__FUNCTION__,size,dl_stat.ubi.cur_voldesc->vol->used_bytes);
905 ret = NAND_INVALID_SIZE;
908 if(_is_nv_volume(dl_stat.ubi.cur_volnm)) {
909 _fdl2_check_nv(dl_stat.ubi.cur_volnm);
911 if(!strcmp(dl_stat.ubi.cur_volnm, "prodnv")) {
913 fdl_ubi_volume_read(dl_stat.ubi.dev,
914 dl_stat.ubi.cur_volnm,
918 if(magic != UBIFS_NODE_MAGIC) {
919 printf("bad ubifs node magic %#08x, expected %#08x\n",
920 magic, UBIFS_NODE_MAGIC);
921 ret = NAND_SYSTEM_ERROR;
927 printf("%s:Incompatible part %s!\n",__FUNCTION__,part);
928 ret = NAND_INCOMPATIBLE_PART;
932 dl_stat.nand = _get_cur_nand();
933 printf("fdl2_read_start:%s,size:0x%x\n",part,size);
935 _send_rsp(NAND_SUCCESS);
945 * Read partition/volume data
947 * @param size size to be read
948 * @param off offset of begin of part/vol
949 * @param buf data saved
953 int fdl2_read_midst(unsigned long size, unsigned long off, unsigned char *buf)
957 switch(dl_stat.part_type){
959 ret = nand_read_skip_bad(dl_stat.nand, dl_stat.mtd.rw_point+off, &size, buf);
964 if(_is_nv_volume(dl_stat.ubi.cur_volnm)) {
967 ret = fdl_ubi_volume_read(dl_stat.ubi.dev,
968 dl_stat.ubi.cur_volnm,
976 printf("%s:part type err!\n",__FUNCTION__);
982 printf("%s:read error %d!\n",__FUNCTION__, ret);
983 _send_rsp(NAND_SYSTEM_ERROR);
996 int fdl2_read_end(void)
998 //close opened ubi volume
999 if(PART_TYPE_UBI == dl_stat.part_type){
1000 ubi_close_volume(dl_stat.ubi.cur_voldesc);
1003 _send_rsp(NAND_SUCCESS);
1010 * Erase partition/volume
1012 * @param part partition/volume name
1013 * @param size size to be erased(no use now)
1017 int fdl2_erase(char* part, unsigned long size)
1022 if(!strcmp(part, "erase_all")){
1023 struct mtd_info *nand = NULL;
1024 nand_erase_options_t opts;
1026 memset(&opts, 0, sizeof(opts));
1027 nand = _get_cur_nand();
1029 opts.length = nand->size;
1031 ret = nand_erase_opts(nand, &opts);
1033 ret =NAND_SYSTEM_ERROR;
1036 //reinit after erase all
1041 _fdl2_part_info_parse(part);
1043 switch(dl_stat.part_type){
1045 ret = _fdl2_mtd_part_erase(part);
1047 printf("%s:mtd %d erase failed!\n",__FUNCTION__,part);
1048 ret = NAND_SYSTEM_ERROR;
1053 bak_vol = _is_nv_volume(dl_stat.ubi.cur_volnm);
1055 ret = fdl_ubi_volume_start_update(dl_stat.ubi.dev, bak_vol, 0);
1057 printf("backup %s: vol %s erase failed!\n",__FUNCTION__,part);
1058 ret = NAND_SYSTEM_ERROR;
1062 ret = fdl_ubi_volume_start_update(dl_stat.ubi.dev, part, 0);
1064 printf("%s: vol %s erase failed!\n",__FUNCTION__,part);
1065 ret = NAND_SYSTEM_ERROR;
1068 ubi_close_volume(dl_stat.ubi.cur_voldesc);
1071 printf("%s:Incompatible part %s!\n",__FUNCTION__,part);
1072 ret = NAND_INCOMPATIBLE_PART;
1076 _send_rsp(NAND_SUCCESS);
1086 * Resize/Add/Delete volumes
1088 * @param vol_cfg volume cfg
1089 * @param total_vol_num
1093 int fdl2_repartition(void* vol_cfg, unsigned short total_vol_num)
1095 int ret,i,vol_id,auto_resize_id=-1;
1096 fdl_ubi_vtbl_t *vtbl=NULL;
1097 fdl_ubi_cvol_t *cvol,*cvol_tmp;
1098 struct list_head remove;
1099 struct list_head create;
1101 INIT_LIST_HEAD(&remove);
1102 INIT_LIST_HEAD(&create);
1104 vtbl = malloc(total_vol_num * sizeof(fdl_ubi_vtbl_t));
1106 printf("%s:malloc vtbl failed!\n",__FUNCTION__);
1109 memset(vtbl,0x0,total_vol_num*sizeof(fdl_ubi_vtbl_t));
1110 _fdl2_parse_volume_cfg(vol_cfg, total_vol_num, vtbl);
1112 ret = _fdl2_vtbl_check(vtbl, total_vol_num, &remove, &create);
1114 printf("full repartition.\n");
1115 goto full_repartition;
1117 printf("partial repartition.\n");
1118 goto partial_repartition;
1120 printf("ubi volumes are same.\n");
1126 ret = _fdl2_mtd_part_erase(UBIPAC_PART);
1129 ret = fdl_ubi_dev_init();
1131 printf("attach ubi failed after erase!\n");
1135 for(i=0;i<total_vol_num;i++){
1136 ret = fdl_ubi_create_vol(cur_ubi.dev, vtbl[i].name, &vol_id, vtbl[i].size, 1);
1138 printf("ubi vol \"%s\" create err %d.\n",vtbl[i].name,ret);
1141 if(vtbl[i].autoresize){
1142 auto_resize_id = vol_id;
1147 partial_repartition:
1148 list_for_each_entry(cvol, &remove, list) {
1149 printf("partial_repartition remove vol \"%s\" \n",cvol->name);
1150 ret = fdl_ubi_remove_vol(cur_ubi.dev, cvol->name);
1152 printf("ubi vol \"%s\" remove err %d.\n",cvol->name,ret);
1156 list_for_each_entry(cvol, &create, list) {
1157 printf("partial_repartition create vol \"%s\" size:0x%llx atr-flag:%d\n",
1158 cvol->name,cvol->size,cvol->autoresize);
1159 ret = fdl_ubi_create_vol(cur_ubi.dev, cvol->name, &vol_id, cvol->size, 1);
1161 printf("ubi vol \"%s\" create err %d.\n",cvol->name,ret);
1164 if(cvol->autoresize){
1165 auto_resize_id = vol_id;
1170 //resize the autoresize volume
1171 if(-1 != auto_resize_id){
1172 ret = fdl_ubi_volume_autoresize(cur_ubi.dev, auto_resize_id);
1174 printf("volume auto resize failed %d.\n",ret);
1181 list_for_each_entry_safe(cvol, cvol_tmp, &remove, list) {
1182 list_del(&cvol->list);
1185 list_for_each_entry_safe(cvol, cvol_tmp, &create, list) {
1186 list_del(&cvol->list);
1193 ret = NAND_SYSTEM_ERROR;