/*-----------------------------------*/ static int ReadSectors(void * DriveData, DWORD Sector, UINT Sectors, void * Buffer) { MSP_STATUS status; kal_uint8 retry = 0; kal_uint16 read; gMSDC_Handle->timeout_count = 0; start: if(!gMSDC_Handle->mIsInitialized) { //dbg_print("Read but not Initialized \r\n"); MSDC_PDNControl(KAL_TRUE); return FS_MSDC_READ_SECTOR_ERROR; } MSDC_PDNControl(KAL_FALSE); status = MSP_CMD_ReadWriteData(Sector,Sectors,(kal_uint32*)Buffer,&read,MSP_READ); if(status != MSP_NOERROR) goto err_exit; MSDC_PDNControl(KAL_TRUE); return FS_NO_ERROR; err_exit: if(retry++ <= MAX_TRY && kal_query_systemInit()== KAL_FALSE) { gMSP.is_failed = KAL_TRUE; if(status == MSP_ERR_TIMEOUT || status == MSDC_GPT_TIMEOUT_ERR) gMSDC_Handle->timeout_count++; if(gMSDC_Handle->timeout_count == 3 && gMSDC_Handle->mIsPresent == KAL_TRUE) { kal_print("[MSDC]:re-mount(read fail)"); gMSDC_Handle->mIsInitialized = KAL_FALSE; retry = 0; if(MSP_Initialize() != MSP_NOERROR) return FS_MSDC_READ_SECTOR_ERROR; } //dbg_print("read sector failed! retry: %d \r\n",retry); goto start; } MSDC_PDNControl(KAL_TRUE); return FS_MSDC_READ_SECTOR_ERROR ; }
void EmPingStartAct(kal_char *serv_addr) { kal_uint32 acc_id = 5;//account id kal_uint16 i, j = 0; kal_char str_buff[50]; kal_uint8 val = 1; PING_CONTEXT_INFO(state) = PING_ACTIVE; /* Clean all the statistics for the previous session */ PING_CONTEXT_INFO(maxRspMS) = 0; PING_CONTEXT_INFO(minRspMS) = 0; PING_CONTEXT_INFO(avgRspMS) = 0; PING_CONTEXT_INFO(rcvdCounter) = 0; PING_CONTEXT_INFO(lostCounter) = 0; if(PING_CONTEXT_INFO(echo_req) != NULL) { OslMfree(PING_CONTEXT_INFO(echo_req)); } if(PING_CONTEXT_INFO(echo_rsp) != NULL) { OslMfree(PING_CONTEXT_INFO(echo_rsp)); } //PING_CONTEXT_INFO(socketId) = soc_create(PF_INET, SOCK_RAW, IPPROTO_ICMP, MOD_PING, acc_id); PING_CONTEXT_INFO(socketId) = soc_create(PF_INET, SOCK_RAW, IPPROTO_ICMP, MOD_MMI, acc_id); if(PING_CONTEXT_INFO(socketId) >= 0) { if(soc_setsockopt(PING_CONTEXT_INFO(socketId), SOC_NBIO, &val, sizeof(val)) < 0) { kal_print("Set socket to nonblock mode error !!"); return ; } val = SOC_READ | SOC_WRITE; if(soc_setsockopt(PING_CONTEXT_INFO(socketId), SOC_ASYNC, &val, sizeof(val)) < 0) { kal_print("Set socket to nonblock mode error !!"); return ; } PING_CONTEXT_INFO(echo_req) = (kal_uint8*)OslMalloc(PING_CONTEXT_INFO(pingSize)+8); PING_CONTEXT_INFO(echo_rsp) = (kal_uint8*)OslMalloc(PING_CONTEXT_INFO(pingSize)+8); PING_CONTEXT_INFO(seqNo) = 0; PING_CONTEXT_INFO(currCount) = 0; PING_CONTEXT_INFO(pingSrvAddr.port) = 100;//identifier PING_CONTEXT_INFO(pingSrvAddr.addr_len) = 4;//any PING_CONTEXT_INFO(pingSrvAddr.addr[0])=0; PING_CONTEXT_INFO(pingSrvAddr.addr[1])=0; PING_CONTEXT_INFO(pingSrvAddr.addr[2])=0; PING_CONTEXT_INFO(pingSrvAddr.addr[3])=0; #ifdef MMI_ON_HARDWARE_P if(soc_bind(PING_CONTEXT_INFO(socketId), &PING_CONTEXT_INFO(pingSrvAddr)) != 0) { soc_close(PING_CONTEXT_INFO(socketId)); if(PING_CONTEXT_INFO(echo_req) != NULL) { OslMfree(PING_CONTEXT_INFO(echo_req)); } if(PING_CONTEXT_INFO(echo_rsp) != NULL) { OslMfree(PING_CONTEXT_INFO(echo_rsp)); } PING_CONTEXT_INFO(echo_req) = NULL; PING_CONTEXT_INFO(echo_rsp) = NULL; kal_print("bind error"); } #endif PING_CONTEXT_INFO(pingSrvAddr.addr[0]) = atoi(strtok(serv_addr, "."));//ip string: "140.112.1.1" to integer PING_CONTEXT_INFO(pingSrvAddr.addr[1]) = atoi(strtok(NULL, ".")); PING_CONTEXT_INFO(pingSrvAddr.addr[2]) = atoi(strtok(NULL, ".")); PING_CONTEXT_INFO(pingSrvAddr.addr[3]) = atoi(strtok(NULL, ".")); PING_CONTEXT_INFO(pingSrvAddr.addr_len) = 4; kal_sprintf(str_buff, "Pinging %d.%d.%d.%d with %d bytes of data", PING_CONTEXT_INFO(pingSrvAddr.addr[0]) , PING_CONTEXT_INFO(pingSrvAddr.addr[1]) , PING_CONTEXT_INFO(pingSrvAddr.addr[2]) , PING_CONTEXT_INFO(pingSrvAddr.addr[3]) , PING_CONTEXT_INFO(pingSize)); kal_print(str_buff); EmPingUpdateScreen(EM_PING_START, -1); EmPingSendPkt(); } //if(s >= 0) else { ASSERT(PING_CONTEXT_INFO(socketId) >= 0); } }
kal_bool EmPingRecvPkt(void) { kal_int32 ret_val = -1; kal_uint16 i = 0; kal_uint32 duration = 0; sockaddr_struct *addr = NULL; kal_char str_buff[100]; addr = &PING_CONTEXT_INFO(pingSrvAddr); ret_val = soc_recv(PING_CONTEXT_INFO(socketId), PING_CONTEXT_INFO(echo_rsp), (PING_CONTEXT_INFO(pingSize)+8), 0); kal_sprintf(str_buff, "Rcvd !seqNO: %d, currCounterL: %d", PING_CONTEXT_INFO(seqNo), PING_CONTEXT_INFO(currCount)); kal_print(str_buff); if(ret_val > 0) { if((PING_CONTEXT_INFO(echo_rsp[6]) *256+PING_CONTEXT_INFO(echo_rsp[7])) < PING_CONTEXT_INFO(currCount)) { /* The is a invalid RSP for the waittime of this PING packet had been expiry, just ignore it */ kal_print("Received a timed out response"); return KAL_FALSE; } PING_CONTEXT_INFO(pingEndFN) = TMD_System_Clock; /* Stop timer */ EmPingStopTimer(); PING_CONTEXT_INFO(currCount)++; //check identifier if((PING_CONTEXT_INFO(echo_rsp[4]) *256+ PING_CONTEXT_INFO(echo_rsp[5])) != 100) { PING_CONTEXT_INFO(lostCounter)++; kal_print("Ping identifier wrong"); } else { //check seq no if((PING_CONTEXT_INFO(echo_rsp[6]) *256+PING_CONTEXT_INFO(echo_rsp[7])) != (PING_CONTEXT_INFO(seqNo)-1)) { PING_CONTEXT_INFO(lostCounter)++; kal_print("Ping seq no wrong"); } else { //check ping data for(i=8;i<PING_CONTEXT_INFO(pingSize);i++) { if(PING_CONTEXT_INFO(echo_rsp[i]) != (kal_uint8)PING_CONTEXT_INFO(currCount)) { PING_CONTEXT_INFO(lostCounter)++; kal_print("Ping data is wrong"); break; } } if(i==PING_CONTEXT_INFO(pingSize)) { /* Pass all check */ /* Calculate the time period */ if(PING_CONTEXT_INFO(pingEndFN) >= PING_CONTEXT_INFO(pingStartFN) ) { duration = (((PING_CONTEXT_INFO(pingEndFN) - PING_CONTEXT_INFO(pingStartFN)) * 462) / 100); } else { duration = (((2715647 + PING_CONTEXT_INFO(pingEndFN) - PING_CONTEXT_INFO(pingStartFN)) * 462) / 100); } /* Update statistics */ if(PING_CONTEXT_INFO(maxRspMS) < duration) PING_CONTEXT_INFO(maxRspMS) = duration; if((PING_CONTEXT_INFO(minRspMS) == 0) || (PING_CONTEXT_INFO(minRspMS) > duration)) PING_CONTEXT_INFO(minRspMS) = duration; PING_CONTEXT_INFO(avgRspMS) += duration; PING_CONTEXT_INFO(rcvdCounter)++; /* Output the result */ kal_sprintf(str_buff,"Reply from %d.%d.%d.%d: bytes=%d time=%dms", addr->addr[0], addr->addr[1], addr->addr[2], addr->addr[3], PING_CONTEXT_INFO(pingSize), duration); kal_print(str_buff); EmPingUpdateScreen(EM_PING_RECV, duration); if(PING_CONTEXT_INFO(pingCount) == PING_CONTEXT_INFO(currCount)) { soc_close(PING_CONTEXT_INFO(socketId)); if(PING_CONTEXT_INFO(echo_req) != NULL) { OslMfree(PING_CONTEXT_INFO(echo_req)); } if(PING_CONTEXT_INFO(echo_rsp) != NULL) { OslMfree(PING_CONTEXT_INFO(echo_rsp)); } PING_CONTEXT_INFO(echo_req) = NULL; PING_CONTEXT_INFO(echo_rsp) = NULL; PING_CONTEXT_INFO(state) = PING_INACTIVE; /* Output the statistics */ kal_mem_set(&str_buff[0], 0, 100); kal_sprintf(str_buff,"Ping statstics for %d.%d.%d.%d:", addr->addr[0], addr->addr[1], addr->addr[2], addr->addr[3], PING_CONTEXT_INFO(pingSize), duration); kal_print(str_buff); kal_mem_set(&str_buff[0], 0, 100); kal_sprintf(str_buff, " Packets: Sent = %d, Received = %d, Lost = %d (%d%c loss)", PING_CONTEXT_INFO(pingCount), PING_CONTEXT_INFO(rcvdCounter), PING_CONTEXT_INFO(lostCounter), ((PING_CONTEXT_INFO(lostCounter)*100)/PING_CONTEXT_INFO(pingCount)), '%'); kal_print(str_buff); kal_mem_set(&str_buff[0], 0, 100); kal_sprintf(str_buff, " Min: %dms, Max: %dms, Avg: %dms", PING_CONTEXT_INFO(minRspMS), PING_CONTEXT_INFO(maxRspMS), (PING_CONTEXT_INFO(avgRspMS)/PING_CONTEXT_INFO(rcvdCounter))); kal_print(str_buff); EmPingUpdateScreen(EM_PING_FIN, (PING_CONTEXT_INFO(avgRspMS)/PING_CONTEXT_INFO(rcvdCounter)) ); } } } //PING_CONTEXT_INFO(seqNo)++; } return KAL_TRUE; } else if(ret_val == SOC_WOULDBLOCK) { /* return KAL_FALSE to break out the for loop and wait for notification or timeout message */ return KAL_FALSE; } else { /* If happen, ask Kavien to have a look */ ASSERT(ret_val > 0); } return KAL_TRUE; }
void EmPingSendPkt(void) { kal_uint16 i = 0; kal_uint16 j = 0; kal_bool ret_val = KAL_FALSE; kal_int16 ret = 0; for(j = PING_CONTEXT_INFO(currCount); j < PING_CONTEXT_INFO(pingCount);j++) { PING_CONTEXT_INFO(pingStartFN) = 0; PING_CONTEXT_INFO(pingEndFN) = 0; kal_mem_set(PING_CONTEXT_INFO(echo_req), 0, PING_CONTEXT_INFO(pingSize)+8); PING_CONTEXT_INFO(echo_req[0]) = 8;//echo req PING_CONTEXT_INFO(echo_req[4]) = 0;//identifier PING_CONTEXT_INFO(echo_req[5]) = 100; PING_CONTEXT_INFO(echo_req[6]) = (kal_uint8)(PING_CONTEXT_INFO(seqNo) >> 8);//seq no PING_CONTEXT_INFO(echo_req[7]) = (kal_uint8)(PING_CONTEXT_INFO(seqNo) & 0x00ff); for(i=8;i<PING_CONTEXT_INFO(pingSize);i++)//dummy data PING_CONTEXT_INFO(echo_req[i])= (kal_uint8)(j+1); //there are two choices: connect->send or sendto //where addr specifies the destionation of ping //sendto directly ret = soc_sendto(PING_CONTEXT_INFO(socketId),PING_CONTEXT_INFO(echo_req), (PING_CONTEXT_INFO(pingSize)+8), 0, &PING_CONTEXT_INFO(pingSrvAddr)); if(ret != (PING_CONTEXT_INFO(pingSize)+8)) { if(ret == SOC_WOULDBLOCK) { kal_print("Socket said send it later"); return; } kal_print("send ping error"); soc_close(PING_CONTEXT_INFO(socketId)); if(PING_CONTEXT_INFO(echo_req) != NULL) { OslMfree(PING_CONTEXT_INFO(echo_req)); } if(PING_CONTEXT_INFO(echo_rsp) != NULL) { OslMfree(PING_CONTEXT_INFO(echo_rsp)); } PING_CONTEXT_INFO(echo_req) = NULL; PING_CONTEXT_INFO(echo_rsp) = NULL; PING_CONTEXT_INFO(state) = PING_INACTIVE; return; } else { EmPingStartTimer(PING_CONTEXT_INFO(seqNo)); //PING_CONTEXT_INFO(currCount)++; PING_CONTEXT_INFO(seqNo)++; PING_CONTEXT_INFO(pingStartFN) = TMD_System_Clock; } ret_val = EmPingRecvPkt(); if(ret_val == KAL_FALSE) { break; } } return; }
//========================================== //=== Ping Lib //========================================== void EmPingTimeourHandler(void) { kal_char str_buff[100]; kal_uint32 duration = 0; kal_uint32 avgRspMS = 0; sockaddr_struct *addr = NULL; addr = &PING_CONTEXT_INFO(pingSrvAddr); PING_CONTEXT_INFO(currCount)++; kal_sprintf(str_buff, "Timedout !seqNO: %d, currCounterL: %d", PING_CONTEXT_INFO(seqNo), PING_CONTEXT_INFO(currCount)); kal_print(str_buff); if(PING_CONTEXT_INFO(pingCount) == PING_CONTEXT_INFO(currCount)) { kal_print("Request timed out"); EmPingUpdateScreen( EM_PING_TIMEOUT, -1 ); PING_CONTEXT_INFO(lostCounter)++; soc_close(PING_CONTEXT_INFO(socketId)); if(PING_CONTEXT_INFO(echo_req) != NULL) { OslMfree(PING_CONTEXT_INFO(echo_req)); } if(PING_CONTEXT_INFO(echo_rsp) != NULL) { OslMfree(PING_CONTEXT_INFO(echo_rsp)); } PING_CONTEXT_INFO(echo_req) = NULL; PING_CONTEXT_INFO(echo_rsp) = NULL; PING_CONTEXT_INFO(state) = PING_INACTIVE; if(PING_CONTEXT_INFO(avgRspMS) == 0) { avgRspMS = 0; } else { avgRspMS = PING_CONTEXT_INFO(avgRspMS)/PING_CONTEXT_INFO(rcvdCounter); } /* Output the statistics */ kal_mem_set(&str_buff[0], 0, 100); kal_sprintf(str_buff,"Ping statstics for %d.%d.%d.%d:", addr->addr[0], addr->addr[1], addr->addr[2], addr->addr[3], PING_CONTEXT_INFO(pingSize), duration); kal_print(str_buff); kal_mem_set(&str_buff[0], 0, 100); kal_sprintf(str_buff, " Packets: Sent = %d, Received = %d, Lost = %d (%d%c loss)", PING_CONTEXT_INFO(pingCount), PING_CONTEXT_INFO(rcvdCounter), PING_CONTEXT_INFO(lostCounter), ((PING_CONTEXT_INFO(lostCounter)*100)/PING_CONTEXT_INFO(pingCount)), '%'); kal_print(str_buff); kal_mem_set(&str_buff[0], 0, 100); kal_sprintf(str_buff, " Min: %dms, Max: %dms, Avg: %dms", PING_CONTEXT_INFO(minRspMS), PING_CONTEXT_INFO(maxRspMS), avgRspMS); kal_print(str_buff); EmPingUpdateScreen( EM_PING_FIN, avgRspMS ); } else { if(PING_CONTEXT_INFO(state) == PING_ACTIVE) { PING_CONTEXT_INFO(lostCounter)++; kal_print("Request timed out"); EmPingUpdateScreen( EM_PING_TIMEOUT, -1 ); EmPingSendPkt(); } } return; }
/* only allow two case: case 1: Sectors == 1 case 2: Sectors == gMS.PagesPerBlk */ static int WriteSectors(void * DriveData, DWORD Sector, UINT Sectors, void * Buffer) { MS_STATUS status; kal_uint8 PagesPerBlk,page,pages,extra[4],owflag,len; kal_uint32 lba,pba,i,spareblk; kal_uint8 *p = NULL,*ptr; kal_uint16 *LPTable,*FreeTable; kal_uint8 retry = 0; gMSDC_Handle->timeout_count = 0; START: if(!gMSDC_Handle->mIsInitialized) { //dbg_print("Write but not Initialized \r\n"); MSDC_PDNControl(KAL_TRUE); return FS_MSDC_WRITE_SECTOR_ERROR; } gMS.is_write = KAL_TRUE; LPTable = gMS.pLPTbl; FreeTable = gMS.pFreeTbl; PagesPerBlk = gMS.PagesPerBlk; ptr = (kal_uint8*)Buffer; p = (kal_uint8 * )MS_buffer; // get physical block address from sector lba = Sector/PagesPerBlk; len = page = Sector%PagesPerBlk; MSDC_PDNControl(KAL_FALSE); while(1) { if(PagesPerBlk - page < Sectors) len = PagesPerBlk - page; else len = Sectors; ASSERT(len >= 1 && len <= 32); status = MS_API_LogToPhy(LPTable,lba,&pba); if(status != MS_NOERROR) goto ERR_EXIT; // set update status to 0 MS_API_ReadExtraData(pba, 0, (kal_uint32 *)extra); owflag = extra[0]; extra[0] &= ~MS_OVFLG_UDST; MS_API_WriteOWF(pba, 0, extra[0]); // read the entire block status = MS_API_ReadBlock(pba,(kal_uint32*)p, (kal_uint32 *)extra, 0, PagesPerBlk, &pages); if(status != MS_NOERROR) { goto ERR_EXIT; } if(gMS.uc_pages != 0) { MS_API_LogToPhy(LPTable,lba,&pba); MS_API_ReadExtraData(pba, 0, (kal_uint32 *)extra); owflag = extra[0]; extra[0] &= ~MS_OVFLG_UDST; status = MS_API_WriteExtraData(pba, 0, (kal_uint32 *)extra); } // update the page in the memory kal_mem_cpy((kal_uint8*)(p+page*MS_PAGE_SIZE), (kal_uint8*)ptr, MS_PAGE_SIZE*len); // find a unused block from FreeTable, erase it and write updated info into it i = 0; while((FreeTable[i++] == 0xFFFF) && (i < MS_FREETABLE_SIZE)); spareblk = FreeTable[i-1]; status = MS_API_EraseBlock(spareblk); if(status != MS_NOERROR) goto ERR_EXIT; extra[0] = (owflag|MS_OVFLG_UDST); status = MS_API_WriteBlock(spareblk, (kal_uint32*)p, (kal_uint32*)extra, 0, PagesPerBlk, &pages); if(status != MS_NOERROR) goto ERR_EXIT; // update the LPTable and FreeTable LPTable[MS_GetLPIndex(lba)] = spareblk; FreeTable[i-1] = pba; // erase original block status = MS_API_EraseBlock(pba); if(status != MS_NOERROR) goto ERR_EXIT; if(gMS.uc_pages || gMS.de_pages) { kal_uint32 pages; if(gMS.uc_pages) pages = gMS.uc_pages; else pages = gMS.de_pages; for(i=0;i<32;i++) { if(pages & (1<<i)) { MS_API_ReadExtraData(spareblk, i, (kal_uint32 *)extra); extra[0] &= ~MS_OVFLG_PGST; MS_API_WriteExtraData(spareblk, i, (kal_uint32 *)extra); } } } MS_API_ReadExtraData(spareblk, 0x18, (kal_uint32 *)extra); Sectors -= len; if(Sectors == 0) break; ptr += MS_PAGE_SIZE*len; page = 0; lba++; } // end of while MSDC_PDNControl(KAL_TRUE); return FS_NO_ERROR; ERR_EXIT: //dbg_print("W: fail %d\r\n",retry); if(retry++ <= MAX_TRY && kal_query_systemInit()== KAL_FALSE) { if(status == MS_ERR_TIMEOUT || status == MSDC_GPT_TIMEOUT_ERR) gMSDC_Handle->timeout_count++; if(gMSDC_Handle->timeout_count == 3 && gMSDC_Handle->mIsPresent == KAL_TRUE) { kal_print("[MSDC]:re-mount(write fail)"); gMSDC_Handle->mIsInitialized = KAL_FALSE; retry = 0; if(MS_Initialize() != NO_ERROR) return FS_MSDC_READ_SECTOR_ERROR; } //dbg_print("W: fail retry:%d adrs:%d sectors: %d \r\n",retry,Sector, Sectors); goto START; } MSDC_PDNControl(KAL_TRUE); return FS_MSDC_WRITE_SECTOR_ERROR; }
/*-----------------------------------*/ static int ReadSectors(void * DriveData, DWORD Sector, UINT Sectors, void * Buffer) { MS_STATUS status; kal_uint8 PagesPerBlk,page,readpage,len,*ptr, extra[4]; kal_uint32 lba,pba; kal_uint8 retry = 0; gMSDC_Handle->timeout_count = 0; START: if(!gMSDC_Handle->mIsInitialized) { //dbg_print("Read but not Initialized \r\n"); MSDC_PDNControl(KAL_TRUE); return FS_MSDC_READ_SECTOR_ERROR; } gMS.is_write = KAL_FALSE; PagesPerBlk = gMS.PagesPerBlk; lba = Sector/PagesPerBlk; page = Sector%PagesPerBlk; ptr = (kal_uint8*) Buffer; MSDC_PDNControl(KAL_FALSE); while(1) { if(PagesPerBlk - page < Sectors) len = PagesPerBlk - page; else len = Sectors; ASSERT(len >= 1 && len <= 32); status = MS_API_LogToPhy(gMS.pLPTbl,lba,&pba); if(status != MS_NOERROR) goto ERR_EXIT;//return FS_MSDC_READ_SECTOR_ERROR; if(len == 1) status = MS_API_ReadSinglePage(pba,page,(kal_uint32*)ptr,NULL); else status = MS_API_ReadBlock(pba, (kal_uint32*)ptr, NULL, page, len, &readpage); if(status != MS_NOERROR) goto ERR_EXIT;//return FS_MSDC_READ_SECTOR_ERROR; //============ change the update status ====================// MS_API_ReadExtraData(pba, 0, (kal_uint32*)extra); if(MS_UPDATE_STATUS(extra[OVERWRITE_FLAG]) == 0) { kal_uint32 i; kal_uint16 *FreeTable, *LPTable, spareblk; kal_uint8 readpage; // find a unused block from FreeTable, erase it and write updated info into it LPTable = gMS.pLPTbl; FreeTable = gMS.pFreeTbl; i = 0; while((FreeTable[i++] == 0xFFFF) && (i < MS_FREETABLE_SIZE)); spareblk = FreeTable[i-1]; MS_API_ReadBlock(pba,(kal_uint32*)MS_buffer, (kal_uint32 *)extra, 0, PagesPerBlk, &readpage); extra[0] |= MS_OVFLG_UDST; MS_API_WriteExtraData(spareblk, 0, (kal_uint32 *)extra); MS_API_WriteBlock(spareblk,(kal_uint32*)MS_buffer, (kal_uint32 *)extra, 0, PagesPerBlk, &readpage); MS_API_EraseBlock(pba); // update the LPTable and FreeTable LPTable[MS_GetLPIndex(lba)] = spareblk; FreeTable[i-1] = pba; } //================================// Sectors -= len; if(Sectors == 0) break; page = 0; ptr += MS_PAGE_SIZE*len; lba++; } MSDC_PDNControl(KAL_TRUE); return FS_NO_ERROR; ERR_EXIT: if(retry++ <= MAX_TRY && kal_query_systemInit()== KAL_FALSE) { if(status == MS_ERR_TIMEOUT || status == MSDC_GPT_TIMEOUT_ERR) gMSDC_Handle->timeout_count++; if(gMSDC_Handle->timeout_count == 3 && gMSDC_Handle->mIsPresent == KAL_TRUE) { kal_print("[MSDC]:re-mount(read fail)"); gMSDC_Handle->mIsInitialized = KAL_FALSE; retry = 0; if(MS_Initialize() != NO_ERROR) return FS_MSDC_READ_SECTOR_ERROR; } //dbg_print("R: fail retry:%d adrs:%d sectors: %d \r\n",retry,Sector, Sectors); goto START; } MSDC_PDNControl(KAL_TRUE); return FS_MSDC_READ_SECTOR_ERROR; }
/*-----------------------------------*/ static int WriteSectors(void * DriveData, DWORD Sector, UINT Sectors, void * Buffer) { SDC_CMD_STATUS status; kal_uint8 retry = 0; kal_uint32 adrs; #if defined(__SIM_PLUS__) sd_select_enum sel; if((MSDC_HANDLE *)DriveData == &MSDC_Blk[0]) sel = SD_EXT; else sel = SD_SIM; MSDC_Switch_Card(sel); #endif #if defined(SD_MMC_HIGH_DENSITY_SUPPORT) if(gSD->flags & SD_FLAG_HCS_SUPPORT) adrs = Sector; else #endif adrs = Sector * SECTOR_SIZE; gMSDC_Handle->timeout_count = 0; start: if(!gMSDC_Handle->mIsInitialized) { //dbg_print("Write but not Initialized \r\n"); MSDC_PDNControl(KAL_TRUE); return FS_MSDC_WRITE_SECTOR_ERROR; } retry++; MSDC_PDNControl(KAL_FALSE); #ifndef LSD_SINGLE_WRITE if(Sectors > 1) { if(gMSDC_Handle->mMSDC_type == SD_CARD) SD_SetPreEraseBlk(Sectors); status = SD_WriteMultiBlock((kal_uint32)adrs,(kal_uint32*)Buffer,(kal_uint32)Sectors); } else status = SD_WriteSingleBlock((kal_uint32)adrs,(kal_uint32*)Buffer); #else while(Sectors) { status = SD_WriteSingleBlock((kal_uint32)adrs,(kal_uint32*)Buffer); if(status != NO_ERROR ) break; (kal_uint8 *)Buffer += SECTOR_SIZE; Sector ++; #if defined(SD_MMC_HIGH_DENSITY_SUPPORT) if(gSD->flags & SD_FLAG_HCS_SUPPORT) adrs = Sector; else #endif adrs = Sector * SECTOR_SIZE; Sectors--; } #endif if(status != NO_ERROR) { sd_w++; if(kal_query_systemInit()== KAL_TRUE) { MSDC_PDNControl(KAL_TRUE); return FS_MSDC_WRITE_SECTOR_ERROR; } //dbg_print("write retry:%d,status:%d,total %d\r\n",retry,status,sd_w); if(status == ERR_CMD_TIMEOUT || status == MSDC_GPT_TIMEOUT_ERR) gMSDC_Handle->timeout_count++; if(gMSDC_Handle->timeout_count++ == 3 && gMSDC_Handle->mIsPresent == KAL_TRUE) { kal_print("[MSDC]:SD re-mount (write fail)"); gMSDC_Handle->mIsInitialized = KAL_FALSE; retry = 0; if(SD_Initialize() != NO_ERROR) { MSDC_PDNControl(KAL_TRUE); return FS_MSDC_WRITE_SECTOR_ERROR; } } if(retry >= SD_MAX_RETRY) { MSDC_PDNControl(KAL_TRUE); return FS_MSDC_WRITE_SECTOR_ERROR; } else { // kal_prompt_trace(MOD_AUD,"CRC write Error retry %d",retry); goto start; } } MSDC_PDNControl(KAL_TRUE); return FS_NO_ERROR; }