예제 #1
0
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;
}
예제 #2
0
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;
}