int new_part_tab(u8 * buf, struct mtd_info *mtd) { DM_PARTITION_INFO_PACKET *dm_part = (DM_PARTITION_INFO_PACKET *) buf; int part_num, change_index, i = 0; int retval; int pageoffset; int start_addr = (int)((mtd->size) + block_size); int current_addr = 0; struct mtd_oob_ops ops_pt; pi.pt_changed = 0; pi.tool_or_sd_update = 2; //tool download is 1. ops_pt.mode = MTD_OPS_AUTO_OOB; ops_pt.len = mtd->writesize; ops_pt.retlen = 0; ops_pt.ooblen = 16; ops_pt.oobretlen = 0; ops_pt.oobbuf = page_buf + page_size; ops_pt.ooboffs = 0; //the first image is ? #if 1 for (part_num = 0; part_num < PART_MAX_COUNT; part_num++) { memcpy(new_part[part_num].name, dm_part->part_info[part_num].part_name, MAX_PARTITION_NAME_LEN); new_part[part_num].offset = dm_part->part_info[part_num].start_addr; new_part[part_num].size = dm_part->part_info[part_num].part_len; new_part[part_num].mask_flags = 0; //MSG (INIT, "DM_PARTITION_INFO_PACKET %s size %x %x \n",dm_part->part_info[part_num].part_name,dm_part->part_info[part_num].part_len,part_num); printk(KERN_INFO "new_pt %s size %lx \n", new_part[part_num].name, new_part[part_num].size); if (dm_part->part_info[part_num].part_len == 0) { printk(KERN_INFO "new_pt last %x \n", part_num); break; } } #endif //++++++++++for test #if 0 part_num = 13; memcpy(&new_part[0], &lastest_part[0], sizeof(new_part)); MSG(INIT, "new_part %x size \n", sizeof(new_part)); for (i = 0; i < part_num; i++) { MSG(INIT, "npt partition %s size \n", new_part[i].name); //MSG (INIT, "npt %x size \n",new_part[i].offset); //MSG (INIT, "npt %x size \n",lastest_part[i].offset); //MSG (INIT, "npt %x size \n",new_part[i].size); dm_part->part_info[5].part_visibility = 1; dm_part->part_info[5].dl_selected = 1; new_part[5].size = lastest_part[5].size + 0x100000; } #endif //------------for test //Find the first changed partition, whether is visible for (change_index = 0; change_index <= part_num; change_index++) { if ((new_part[change_index].size != lastest_part[change_index].size) || (new_part[change_index].offset != lastest_part[change_index].offset)) { printk(KERN_INFO "new_pt %x size changed from %lx to %lx\n", change_index, lastest_part[change_index].size, new_part[change_index].size); pi.pt_changed = 1; break; } } if (pi.pt_changed == 1) { //Is valid image update for (i = change_index; i <= part_num; i++) { if (dm_part->part_info[i].dl_selected == 0 && dm_part->part_info[i].part_visibility == 1) { printk(KERN_INFO "Full download is need %x \n", i); retval = DM_ERR_NO_VALID_TABLE; return retval; } } pageoffset = find_empty_page_from_top(start_addr, mtd); //download partition used the new partition //write mirror at the same 2 page memset(page_buf, 0xFF, page_size + 64); *(int *)sig_buf = MPT_SIG; memcpy(page_buf, &sig_buf, PT_SIG_SIZE); memcpy(&page_buf[PT_SIG_SIZE], &new_part[0], sizeof(new_part)); memcpy(&page_buf[page_size], &sig_buf, PT_SIG_SIZE); pi.sequencenumber += 1; memcpy(&page_buf[page_size + PT_SIG_SIZE], &pi, PT_SIG_SIZE); if (pageoffset != 0xFFFF) { if ((pageoffset % 2) != 0) { printk(KERN_INFO "new_pt mirror block may destroy last time%x\n", pageoffset); pageoffset += 1; } for (i = 0; i < 2; i++) { current_addr = start_addr + (pageoffset + i) * page_size; ops_pt.datbuf = (uint8_t *) page_buf; if (mtd->_write_oob(mtd, (loff_t) current_addr, &ops_pt) != 0) { printk(KERN_INFO "new_pt write m first page failed %x\n", current_addr); } else { printk(KERN_INFO "new_pt write mirror at %x\n", current_addr); ops_pt.datbuf = (uint8_t *) page_readbuf; //read back verify if ((mtd->_read_oob(mtd, (loff_t) current_addr, &ops_pt) != 0) || memcmp(page_buf, page_readbuf, page_size)) { printk(KERN_INFO "new_pt read or verify first mirror page failed %x \n", current_addr); ops_pt.datbuf = (uint8_t *) page_buf; memset(page_buf, 0, PT_SIG_SIZE); if (mtd->_read_oob(mtd, (loff_t) current_addr, &ops_pt) != 0) { printk(KERN_INFO "new_pt mark failed %x\n", current_addr); } } else { printk(KERN_INFO "new_pt write mirror ok %x\n", i); //any one success set this flag? pi.mirror_pt_dl = 1; } } } } } else { printk(KERN_INFO "new_part_tab no pt change %x\n", i); } retval = DM_ERR_OK; return retval; }
int new_part_tab(u8 *buf) { DM_PARTITION_INFO_PACKET *dm_part= (DM_PARTITION_INFO_PACKET *)buf; int part_num,change_index,i; int retval; int pageoffset; int start_addr=total_size+BLOCK_SIZE; int current_addr=0; pi.pt_changed =0; pi.tool_or_sd_update = 1; MSG (INIT, "new_pt par_nub enter \n"); //the first image is ? for(part_num=0;part_num<PART_MAX_COUNT;part_num++) { memcpy(new_part[part_num].name,dm_part->part_info[part_num].part_name,MAX_PARTITION_NAME_LEN); new_part[part_num].offset=dm_part->part_info[part_num].start_addr; new_part[part_num].size=dm_part->part_info[part_num].part_len; new_part[part_num].mask_flags=0; //MSG (INIT, "DM_PARTITION_INFO_PACKET %s size %x %x \n",dm_part->part_info[part_num].part_name,dm_part->part_info[part_num].part_len,part_num); MSG (INIT, "new_pt %s size %x \n",new_part[part_num].name,new_part[part_num].size); if(dm_part->part_info[part_num].part_len ==0) { MSG (INIT, "new_pt last %x \n",part_num); break; } } MSG (INIT, "new_pt par_nub %x \n",part_num); #if 1 //++++++++++for test #if 0 part_num=13; memcpy(&new_part[0],&lastest_part[0],sizeof(new_part)); MSG (INIT, "new_part %x size \n",sizeof(new_part)); for(i=0;i<part_num;i++) { MSG (INIT, "npt partition %s size \n",new_part[i].name); //MSG (INIT, "npt %x size \n",new_part[i].offset); //MSG (INIT, "npt %x size \n",lastest_part[i].offset); //MSG (INIT, "npt %x size \n",new_part[i].size); dm_part->part_info[5].part_visibility =1; dm_part->part_info[5].dl_selected =1; new_part[5].size = lastest_part[5].size+0x100000; } #endif //------------for test //Find the first changed partition, whether is visible for(change_index=0;change_index<=part_num;change_index++) { if((new_part[change_index].size!=lastest_part[change_index].size)||(new_part[change_index].offset!=lastest_part[change_index].offset)) { MSG (INIT, "new_pt %x size changed from %x to %x\n",change_index,lastest_part[change_index].size,new_part[change_index].size); pi.pt_changed =1; break; } } if(pi.pt_changed==1) { //Is valid image update for(i=change_index;i<=part_num;i++) { if(dm_part->part_info[i].dl_selected==0&&dm_part->part_info[i].part_visibility==1) { MSG (INIT, "Full download is need %x \n",i); retval=DM_ERR_NO_VALID_TABLE; return retval; } } pageoffset=find_empty_page_from_top(start_addr); //download partition used the new partition //write mirror at the same 2 page memset(page_buf,0xFF,PAGE_SIZE+64); *(int *)sig_buf = MPT_SIG; memcpy(page_buf,&sig_buf,PT_SIG_SIZE); memcpy(&page_buf[PT_SIG_SIZE],&new_part[0],sizeof(new_part)); memcpy(&page_buf[PAGE_SIZE],&sig_buf,PT_SIG_SIZE); pi.sequencenumber+=1; memcpy(&page_buf[PAGE_SIZE+PT_SIG_SIZE],&pi,PT_SIG_SIZE); #if 0 for(i=0;i<8;i++) { MSG (INIT, "%x\n",page_buf[i]); } #endif if(pageoffset!=0xFFFF) { if((pageoffset%2)!=0) { MSG (INIT, "new_pt mirror block may destroy last time%x\n",pageoffset); pageoffset+=1; } for(i=0;i<2;i++) { current_addr=start_addr+(pageoffset+i)*PAGE_SIZE; if(!mtk_nand_write_page_hwecc(current_addr, page_buf)) { MSG (INIT, "new_pt write m first page failed %x\n",current_addr); } else { MSG (INIT, "new_pt w_mpt at %x\n",current_addr); //read back verify if((!mtk_nand_read_page_hwecc(current_addr, page_readbuf))||memcmp(page_buf,page_readbuf,PAGE_SIZE)) { MSG (INIT, "new_pt read or verify first mirror page failed %x \n",current_addr); memcpy(page_buf,0,PT_SIG_SIZE); if(mtk_nand_write_page_hwecc(current_addr,page_buf)) { MSG (INIT, "new_pt mark failed %x\n",current_addr); } } else { MSG (INIT, "new_pt w_mpt ok %x\n",i); //any one success set this flag? pi.mirror_pt_dl=1; } } } } } else { MSG (INIT, "new_part_tab no pt change %x\n",i); } #endif retval=DM_ERR_OK; //for test // retval=DM_ERR_NO_VALID_TABLE; return retval; }