int msdc_get_info(STORAGE_TPYE storage_type,GET_STORAGE_INFO info_type,struct storage_info* info) { struct msdc_host *host = NULL; int host_function = 0; bool boot = 0; switch (storage_type){ case EMMC_CARD_BOOT : host_function = MSDC_EMMC; boot = MSDC_BOOT_EN; break; case EMMC_CARD : host_function = MSDC_EMMC; break; case SD_CARD_BOOT : host_function = MSDC_SD; boot = MSDC_BOOT_EN; break; case SD_CARD : host_function = MSDC_SD; break; default : printk(KERN_ERR "No supported storage type!"); return 0; break; } host = msdc_get_host(host_function,boot,0); switch (info_type){ case CARD_INFO : if(host->mmc && host->mmc->card) info->card = host->mmc->card; else{ printk(KERN_ERR "CARD was not ready<get card>!"); return 0; } break; case DISK_INFO : if(host->mmc && host->mmc->card) info->disk = mmc_get_disk(host->mmc->card); else{ printk(KERN_ERR "CARD was not ready<get disk>!"); return 0; } break; case EMMC_USER_CAPACITY : info->emmc_user_capacity = msdc_get_capacity(0); break; case EMMC_CAPACITY: info->emmc_capacity = msdc_get_capacity(1); break; case EMMC_RESERVE: #ifdef MTK_EMMC_SUPPORT info->emmc_reserve = msdc_get_reserve(); #endif break; default : printk(KERN_ERR "Please check INFO_TYPE"); return 0; } return 1; }
static int sd_upgrade_proc_write(struct file*file, const char*buffer,unsigned long count,void *data) { DM_PARTITION_INFO_PACKET_x *pmtctl; pt_resident *new_part; int part_num,change_index,i; int ret=0; int pt_change = 0; int pt_change_tb[PART_MAX_COUNT]; memset(&pt_change_tb,0x00,PART_MAX_COUNT*sizeof(int)); pmtctl = kmalloc(sizeof(DM_PARTITION_INFO_PACKET_x),GFP_KERNEL); if (!pmtctl) { ret = -ENOMEM; printk("sd_upgrade_proc_write: malloc pmtctl fail\n"); goto fail_malloc; } memset(pmtctl,0x00,sizeof(DM_PARTITION_INFO_PACKET_x)); new_part = kmalloc(PART_MAX_COUNT*sizeof(pt_resident),GFP_KERNEL); if (!new_part) { ret = -ENOMEM; printk("sd_upgrade_proc_write: malloc new_part fail\n"); goto fail_malloc; } memset(new_part,0x00,PART_MAX_COUNT*sizeof(pt_resident)); if(copy_from_user(pmtctl,buffer,sizeof(DM_PARTITION_INFO_PACKET_x))){ ret = -EFAULT; goto end; } //1. copy new part for(i=0;i<PART_MAX_COUNT;i++) { memcpy(new_part[i].name,pmtctl->part_info[i].part_name,MAX_PARTITION_NAME_LEN); new_part[i].offset=pmtctl->part_info[i].start_addr; new_part[i].size=pmtctl->part_info[i].part_len; new_part[i].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 ("[SD_UPGRADE]new_pt %s size %llx \n",new_part[i].name,new_part[i].size); if(pmtctl->part_info[i].part_len ==0) { printk ("[SD_UPGRADE]new_pt last %d \n",i); break; } } part_num = i+1; printk("[SD_UPGRADE]table size %d\n",part_num); //2. compare new part and lastest part. 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 ("[SD_UPGRADE]new_pt %d size changed from %llx to %llx\n",change_index,lastest_part[change_index].size,new_part[change_index].size); pt_change =1; pt_change_tb[change_index]=1; if((pmtctl->part_info[change_index].dl_selected == 0) && (pmtctl->part_info[change_index].part_visibility == 1)) { printk("[SD_UPGRADE]please download all image\n"); ret = -1; goto end; } } } if(!pt_change) { printk("[SD_UPGRADE]layout can not change,skip update PMT/MBR\n"); goto end; } //3. update PMT ret = new_pmt(new_part,part_num); if(ret){ printk("[SD_UPGRADE] update m-pt fail\n"); goto end; } ret = update_pmt(new_part,part_num); if(ret){ printk("[SD_UPGRADE] update pt fail\n"); goto end; } printk("[SD_UPGRADE] update PMT sucess\n"); // for(i=0;i<=part_num;i++){ if((pt_change_tb[i]==1) &&(new_part[i].size == 0)){ new_part[i].size = User_Region_Size_Byte - new_part[i].offset + MBR_START_ADDR - msdc_get_reserve()*512; } } //4. update MBR/EBR for(i=0;i<=part_num;i++){ if(pt_change_tb[i]==1){ if(PartInfo[i].partition_idx!=0){ printk("update p %d %llx %llx\n",PartInfo[i].partition_idx,new_part[i].offset-MBR_START_ADDR,new_part[i].size); ret = update_MBR_or_EBR(PartInfo[i].partition_idx,new_part[i].offset-MBR_START_ADDR,new_part[i].size); if(ret){ printk("[SD_UPGRADE]update_MBR_or_EBR fail\n"); goto end; } } } } printk("[SD_UPGRADE] update MBR/EBR sucess\n"); //5. change part device offset and size. for(i=0;i<=part_num;i++){ if(pt_change_tb[i]==1){ if(PartInfo[i].partition_idx!=0){ printk("update p %d %llx %llx\n",PartInfo[i].partition_idx,new_part[i].offset-MBR_START_ADDR,new_part[i].size); ret = mt65xx_mmc_change_disk_info(PartInfo[i].partition_idx,(u32)((new_part[i].offset-MBR_START_ADDR)/512),(u32)((new_part[i].size)/512)); if(ret){ printk("[SD_UPGRADE]update part device offset and size fail\n"); goto end; } } } } printk("[SD_UPGRADE] update part device offset and size sucess\n"); end: kfree(pmtctl); kfree(new_part); fail_malloc: if(ret) return ret; else return count; }