Example #1
0
/*-----------------------------------*/
static int  MountDevice(void * DriveData, int DeviceNumber, int DeviceType, DWORD Flags)
{		  
	if(gMSDC_Handle->mIsInitialized)
		return SECTOR_SIZE;
	gMSP.is_failed = KAL_FALSE;

start:		
	if(!gMSDC_Handle->mIsPresent)
	{
		MSDC_PDNControl(KAL_TRUE);
		return FS_MSDC_MOUNT_ERROR;
	}	
	MSDC_PDNControl(KAL_FALSE);
	MSP_POWER_ON();
	if(MSP_Initialize() != MSP_NOERROR)
	{		
		goto err_exit;
	}	
		
	MSDC_PDNControl(KAL_TRUE);
   return SECTOR_SIZE;
   
err_exit:
	MSP_POWER_OFF();
	/*
	if(retry++ <= 1)
	{		
		gMSP.is_failed = KAL_TRUE;
		goto start;
	}
	*/
	gMSP.is_failed = KAL_TRUE;
	MSDC_PDNControl(KAL_TRUE);
	return FS_MSDC_MOUNT_ERROR;   
}
Example #2
0
static int  HighLevelFormat(void * DriveData)
{
	MSDC_PDNControl(KAL_FALSE);
	MS_API_CheckLogicalAdrsValid();
	MSDC_PDNControl(KAL_TRUE);	
	
	return FS_NO_ERROR;
}
Example #3
0
/*-----------------------------------*/
static int  MountDevice(void * DriveData, int DeviceNumber, int DeviceType, DWORD Flags)
{
	kal_uint8 retry = 0;

	//dbg_print("MountDevice_MS \r\n");
	
	if(gMSDC_Handle->mIsInitialized)
		return SECTOR_SIZE;		
	
START:	
	if(!gMSDC_Handle->mIsPresent)
	{
		//dbg_print("not present \r\n");
		MSDC_PDNControl(KAL_TRUE);
		return FS_MSDC_MOUNT_ERROR;
	}		
	MSDC_PDNControl(KAL_FALSE);
   if(MS_Initialize() != NO_ERROR)
   {   	
   	goto ERR_EXIT;
   }	
   #if defined(MS_FORMAT)
   if(MS_MountDevice(DeviceType) != FS_NO_ERROR)
   	goto ERR_EXIT;
	#endif
   // get total sector number
   {
	   int i = 0;
	  	FS_PartitionRecord *ptr;
	   kal_uint8 c = gMS.Capacity;
   		   
	   while((c >>= 1) != 2)
	   	i++;	   
		ptr = (FS_PartitionRecord*)MS_MBR[i];
		gMS.TotalSectors = ptr->Sectors;
   }
	   	
   MSDC_PDNControl(KAL_TRUE);
   return SECTOR_SIZE;
   
ERR_EXIT:	
	
	if(retry++ < MAX_TRY)
	{
		//dbg_print("Mount MS failed! retry: %d \r\n",retry);
		goto START;
	}
	MSDC_PDNControl(KAL_TRUE);
	return FS_MSDC_MOUNT_ERROR;
   
}
Example #4
0
static int  HighLevelFormat(void * DriveData)
{
	MSP_STATUS status;

	if(!gMSDC_Handle->mIsInitialized)
		return FS_MSDC_FORMAT_ERROR;
	MSDC_PDNControl(KAL_FALSE);
	status = MSP_CMD_Format(MSP_FULL,NULL);
	MSDC_PDNControl(KAL_TRUE);
	if(status)
		return FS_MSDC_FORMAT_ERROR;
	
	return FS_NO_ERROR;
}
Example #5
0
/*-----------------------------------*/
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   ;
}
Example #6
0
/*
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;
	
}
Example #7
0
/*-----------------------------------*/
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;
}
Example #8
0
/*-----------------------------------*/
static int  MountDevice(void * DriveData, int DeviceNumber, int DeviceType, DWORD Flags)
{
    kal_uint8 retry = 0;

#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


#ifdef DRV_LSD
    /*notifiedFMT may be modified by FMT and MMI tasks, but it is no need to protect this, FMT can't preempt MMI*/
    if(1 == notifiedFMT)/*in this state. we dont allow any access on memory card, we will return fail on any mount trial*/
    {
        return FS_MSDC_MOUNT_ERROR;
    }
#endif

    if(gMSDC_Handle->mIsInitialized)
        return SECTOR_SIZE;
    gMSDC_Handle->is_init_timeout = KAL_FALSE;
start:
    if(!gMSDC_Handle->mIsPresent)
    {
        //dbg_print("not present \r\n");

#if defined(_NAND_FLASH_BOOTING_)
        // add the following code for solving plug in or out the SD card during
        // NFB loading process. The card detection interruptwill disapperared
        // while interrupt controller is masked.
        IRQMask(IRQ_MSDC_CODE);
        if(*(volatile kal_uint16*)MSDC_PS & MSDC_PS_PIN0)
        {
            if(gMSDC_Handle->ins_level == MSDC_IOCTRL_PULL_UP)
                gMSDC_Handle->mIsPresent = KAL_FALSE;
            else
                gMSDC_Handle->mIsPresent = KAL_TRUE;
        }
        else
        {
            if(gMSDC_Handle->ins_level == MSDC_IOCTRL_PULL_UP)
                gMSDC_Handle->mIsPresent = KAL_TRUE;
            else
                gMSDC_Handle->mIsPresent = KAL_FALSE;
        }
        IRQUnmask(IRQ_MSDC_CODE);
#endif // _NAND_FLASH_BOOTING_

        if(!gMSDC_Handle->mIsPresent)
        {
            MSDC_PDNControl(KAL_TRUE);
            return FS_MSDC_MOUNT_ERROR;
        }
    }
    MSDC_PDNControl(KAL_FALSE);
    if(SD_Initialize() != NO_ERROR)
    {
        goto err_exit;
    }
    //if(SD_MountDevice(DeviceType) != FS_NO_ERROR)
    //return FS_MSDC_MOUNT_ERROR;

    //dbg_print("Mount success! \r\n");

#ifdef MSDC_SDMMC_NAND
    /*for SDMMC NAND, some manufacturs sale NAND with all sectors zero, we should format it first*/
    if(ReadSectors( DriveData, 0, 1, MSDC_Sector) != NO_ERROR)
        goto err_exit;
    if(0x55aa != (MSDC_Sector[128] & 0xffff0000)) { /*it doesn't have correct MBR*/
        SD_SelfFormat();
    }
    else {
        if(ReadSectors( DriveData, 1, 1, MSDC_Sector) != NO_ERROR)
            goto err_exit;
        if(0x55aa != (MSDC_Sector[128] & 0xffff0000)) { /*it doesn't have correct PBR*/
            SD_SelfFormat();
        }
    }
#endif

    MSDC_PDNControl(KAL_TRUE);

#ifdef DRV_LSD
    if(KAL_TRUE == kal_query_systemInit()) { /*we don't let access memory card before FMT get plug in message*/
        /*there is no task can access when system init*/
        notifiedFMT = 1;
        return FS_MSDC_MOUNT_ERROR;
    }
#endif

    return SECTOR_SIZE;

err_exit:
    if(retry++ <= SD_MAX_RETRY && gMSDC_Handle->is_init_timeout == KAL_FALSE)
    {
        //dbg_print("SD MountDevice failed! retry: %d \r\n",retry);
        goto start;
    }
#if defined(__MSDC_NOT_SUPPORT_HOT_PLUG__)
    gMSDC_Handle->mIsPresent = KAL_FALSE;
#endif

#if defined(__SIM_PLUS__)

    if(INT_USBBoot() == KAL_TRUE && current_card == SD_SIM)
    {
        gMSDC_Handle->mIsPresent = KAL_FALSE;
    }
#endif

    MSDC_PDNControl(KAL_TRUE);
    return FS_MSDC_MOUNT_ERROR;

}
Example #9
0
/*-----------------------------------*/
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;
}